[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte
From: |
Vincent Trouilliez |
Subject: |
[avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ? |
Date: |
Fri, 04 Nov 2005 06:35:57 +0100 |
Hello list,
I just ran into a weird problem that I hardly expected.
I wrote a trivial routine that takes a 32bit unsigned int, which holds a
memory address, and shifts the lower 19 bits, out to a port pin (this
feeds cascaded shift registers, that in turn drive the 19 address lines
of a memory chip).
The 19th/MSbit is shifted first, so this is the bit I actually test.
But when I timed the routine, I discovered with much surprise and
horror, that instead of being very quick, it's massively slow to
execute ! About 3ms/3,000 cycles ! This makes it useless in the case at
hand sadly.
I looked at the disassembler output and discovered that instead of
testing directly the required (19th) bit of the address/integer, it
shifted the number 18 times to bring said bit on the far right, and then
only, test it.
So the routine takes about 20 times more time to execute than it should,
hence the 3ms horror figure I measured :-/
I tried various optimisation flags (-O, -Os, -O3) but all of them use
the same method, none of them manages to test the bit directly/quickly.
Looking at the AVR instruction set, there exist instructions by the
names of SBRC and SBRS, which should be able to test whatever bit in a
register, which is what is needed here: test the third bit of the third
byte of this 4 byte integer.
How should I re-word my bit test statement/expression, to cause the
compiler to use these lovely SBRS/C instructions at last ?
Regards,
--
Vince, puzzled...
static void log_address_set( uint32_t address )
{
...
...
if (address & 0x00040000)
PORTB |= LOG_SDA;
else
PORTB &= ~LOG_SDA;
...
}
static void log_address_set( uint32_t address )
{
...
...
if (address & 0x00040000)
24ec: da 01 movw r26, r20
24ee: c9 01 movw r24, r18
24f0: 72 e1 ldi r23, 0x12 ; 18
24f2: b6 95 lsr r27
24f4: a7 95 ror r26
24f6: 97 95 ror r25
24f8: 87 95 ror r24
24fa: 7a 95 dec r23
24fc: d1 f7 brne .-12 ; 0x24f2
24fe: 81 70 andi r24, 0x01 ; 1
2500: 90 70 andi r25, 0x00 ; 0
2502: 89 2b or r24, r25
2504: 11 f0 breq .+4 ; 0x250a
PORTB |= LOG_SDA;
2506: c0 9a sbi 0x18, 0 ; 24
2508: 01 c0 rjmp .+2 ; 0x250c
else
PORTB &= ~LOG_SDA;
250a: c0 98 cbi 0x18, 0 ; 24
- [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?,
Vincent Trouilliez <=
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?, Vincent Trouilliez, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?, Royce Pereira, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?, Vincent Trouilliez, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?, Ian Caddy, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within a multi-byte integer ?, Vincent Trouilliez, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within amulti-byte integer ?, Jurek Szczesiul, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit within amulti-byte integer ?, Vincent Trouilliez, 2005/11/04
- RE: [avr-gcc-list] How to (efficeiently !!!) test a bit withinamulti-byte integer ?, niklo, 2005/11/04
- RE: [avr-gcc-list] How to (efficeiently !!!) test a bit withinamulti-byte integer ?, Vincent Trouilliez, 2005/11/04
- Re: [avr-gcc-list] How to (efficeiently !!!) test a bit withinamulti-byte intege, Dave Hansen, 2005/11/04