[En-Nut-Discussion] Byte select macros

Bernd Walter enut at cicely.de
Mon Nov 22 21:40:28 CET 2010


On Mon, Nov 22, 2010 at 08:08:45PM +0100, Uwe Bonnes wrote:
> >>>>> "Bernd" == Bernd Walter <enut at cicely.de> writes:
> 
> ...
>     Bernd> Sounds pretty useless to me, since it is something the compiler
>     Bernd> is expected to optimize.
> 
> This is also my opinion, but at least (avr-)gcc version 4.3.3 (GCC) with -Os
> works as described above.
> 
> Can you test with your avr-gcc and report your findings?

My testcase:
[139]devel> cat test.c 
extern unsigned char res1;
extern unsigned char res2;
extern unsigned short *input;

void
foo()
{
        res1 = input[0] >> 8;
        res2 = input[0] & 0xff;
}

[140]devel> avr-gcc -Os -Wall -c test.c
[141]devel> avr-objdump -S test.o | less

test.o:     file format elf32-avr


Disassembly of section .text:

00000000 <foo>:
   0:   e0 91 00 00     lds     r30, 0x0000
   4:   f0 91 00 00     lds     r31, 0x0000
   8:   81 81           ldd     r24, Z+1        ; 0x01
   a:   80 93 00 00     sts     0x0000, r24
   e:   80 81           ld      r24, Z
  10:   80 93 00 00     sts     0x0000, r24
  14:   08 95           ret

No double loading - r30/31 gets the base address and then only a
single byte is loaded, which then gets stored in a address, which is
0x0000 because it hadn't been setup by the linker yet.
It's a different usage pattern as in your casse, but in the end it
is not that easy to setup the same conditions without using the same
source.

Without optimization everything is awfull:
[142]devel> avr-gcc -Wall -c test.c
[143]devel> avr-objdump -S test.o | less

test.o:     file format elf32-avr


Disassembly of section .text:

00000000 <foo>:
   0:   df 93           push    r29
   2:   cf 93           push    r28
   4:   cd b7           in      r28, 0x3d       ; 61
   6:   de b7           in      r29, 0x3e       ; 62
   8:   e0 91 00 00     lds     r30, 0x0000
   c:   f0 91 00 00     lds     r31, 0x0000
  10:   80 81           ld      r24, Z
  12:   91 81           ldd     r25, Z+1        ; 0x01
  14:   89 2f           mov     r24, r25
  16:   99 27           eor     r25, r25
  18:   80 93 00 00     sts     0x0000, r24
  1c:   e0 91 00 00     lds     r30, 0x0000
  20:   f0 91 00 00     lds     r31, 0x0000
  24:   80 81           ld      r24, Z
  26:   91 81           ldd     r25, Z+1        ; 0x01
  28:   80 93 00 00     sts     0x0000, r24
  2c:   cf 91           pop     r28
  2e:   df 91           pop     r29
  30:   08 95           ret

Not only both bytes gets loaded - it also loads the address twice.
but even with -O1 everything is fine.

I'm using 4.3.2.

Is any of your variables declared volatile?

-- 
B.Walter <bernd at bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.



More information about the En-Nut-Discussion mailing list