[En-Nut-Discussion] Byte select macros

Ulrich Prinz uprinz2 at netscape.net
Tue Nov 23 14:20:10 CET 2010


Just for interest,


can you retry with 
uint8_t and uint_fast8_t instead of unsigned char?


and another trial with 

     res[0] = (uint8_t)input[0];
or 

     res[0] = (insigned char)input[0];

instead of 

     res[0] = input[0] & 0xFF;

Would be interesting where this compiler behavior comes from. Thanks for your effort!


And:
I am interested in those macros becaus they are pretty easy to handle for anything where byte orientation is important while architecture must be flexible. So you need only one point to declare those macros and nutconf takes care of selecting the right set of them for your platform.



Best Regards

Ulrich



-----Original Message-----
From: Bernd Walter <enut at cicely.de>
To: Ethernut User Chat (English) <en-nut-discussion at egnite.de>
Cc: ticso at cicely.de
Sent: Tue, Nov 23, 2010 11:15 am
Subject: Re: [En-Nut-Discussion] Byte select macros


On Mon, Nov 22, 2010 at 11:37:25PM +0100, Uwe Bonnes wrote:
> >>>>> "Bernd" == Bernd Walter <enut at cicely.de> writes:
> 
>     Bernd> On Mon, Nov 22, 2010 at 08:08:45PM +0100, Uwe Bonnes wrote:
>  
>     Bernd> Is any of your variables declared volatile?
> 
> Yes, that's part of the problem.
> 
> But try
> ==
> extern unsigned char *res;
> extern unsigned short *input;
> 
> void
> foo()
> {
>         res[0] = input[0] & 0xff;
>         res[1] = input[0] >> 8;
>         res[2] = input[1] & 0xff;
>         res[3] = input[1] >> 8;
> }
> ==
> with
> /tmp> avr-gcc -Os -Wall -c test.c
> /tmp> avr-objdump -S test.o | less

Yes - this test case results in inefficient code:
void
foo()
{
        res[0] = input[0] & 0xff;
   0:   a0 91 00 00     lds     r26, 0x0000
   4:   b0 91 00 00     lds     r27, 0x0000
   8:   e0 91 00 00     lds     r30, 0x0000
   c:   f0 91 00 00     lds     r31, 0x0000
  10:   80 81           ld      r24, Z
  12:   8c 93           st      X, r24
        res[1] = input[0] >> 8;
  14:   a0 91 00 00     lds     r26, 0x0000
  18:   b0 91 00 00     lds     r27, 0x0000
  1c:   e0 91 00 00     lds     r30, 0x0000
  20:   f0 91 00 00     lds     r31, 0x0000
  24:   81 81           ldd     r24, Z+1        ; 0x01
  26:   11 96           adiw    r26, 0x01       ; 1
  28:   8c 93           st      X, r24
        res[2] = input[1] & 0xff;
  2a:   a0 91 00 00     lds     r26, 0x0000
  2e:   b0 91 00 00     lds     r27, 0x0000
  32:   e0 91 00 00     lds     r30, 0x0000
  36:   f0 91 00 00     lds     r31, 0x0000
  3a:   82 81           ldd     r24, Z+2        ; 0x02
  3c:   12 96           adiw    r26, 0x02       ; 2
  3e:   8c 93           st      X, r24
        res[3] = input[1] >> 8;
  40:   a0 91 00 00     lds     r26, 0x0000
  44:   b0 91 00 00     lds     r27, 0x0000
  48:   e0 91 00 00     lds     r30, 0x0000
  4c:   f0 91 00 00     lds     r31, 0x0000
  50:   83 81           ldd     r24, Z+3        ; 0x03
  52:   13 96           adiw    r26, 0x03       ; 3
  54:   8c 93           st      X, r24
}
  56:   08 95           ret

I have no idea why it reloads all adress registers.

-- 
B.Walter <bernd at bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

 



More information about the En-Nut-Discussion mailing list