[En-Nut-Discussion] Byte select macros

Bernd Walter enut at cicely.de
Tue Nov 23 19:49:24 CET 2010


On Tue, Nov 23, 2010 at 03:33:09PM +0100, Bernard Fouché wrote:
> changing to:
> 
> extern unsigned char res[];
> 
> gives, with -Os:
> 
> 00000000<foo>:
>     0:	e0 91 00 00 	lds	r30, 0x0000
>     4:	f0 91 00 00 	lds	r31, 0x0000
>     8:	80 81       	ld	r24, Z
>     a:	80 93 00 00 	sts	0x0000, r24
>     e:	81 81       	ldd	r24, Z+1	; 0x01
>    10:	80 93 00 00 	sts	0x0000, r24
>    14:	82 81       	ldd	r24, Z+2	; 0x02
>    16:	80 93 00 00 	sts	0x0000, r24
>    1a:	83 81       	ldd	r24, Z+3	; 0x03
>    1c:	80 93 00 00 	sts	0x0000, r24
>    20:	08 95       	ret

This is different code however, since the compiler knows that the
adress of the first element is a compile time fixed one.

This one also gets optimized - but not so perfect:
[224]devel> cat test.c 
extern unsigned char * const res;
extern unsigned short * const input;

void
foo()
{
        res[0] = input[0] & 0xff;
        res[1] = input[0] >> 8;
        res[2] = input[1] & 0xff;
        res[3] = input[1] >> 8;
}

[225]devel> avr-objdump -S test.o

test.o:     file format elf32-avr


Disassembly of section .text:

00000000 <foo>:
extern unsigned short * const input;

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:   81 81           ldd     r24, Z+1        ; 0x01
  16:   11 96           adiw    r26, 0x01       ; 1
  18:   8c 93           st      X, r24
  1a:   11 97           sbiw    r26, 0x01       ; 1
        res[2] = input[1] & 0xff;
  1c:   82 81           ldd     r24, Z+2        ; 0x02
  1e:   12 96           adiw    r26, 0x02       ; 2
  20:   8c 93           st      X, r24
  22:   12 97           sbiw    r26, 0x02       ; 2
        res[3] = input[1] >> 8;
  24:   83 81           ldd     r24, Z+3        ; 0x03
  26:   13 96           adiw    r26, 0x03       ; 3
  28:   8c 93           st      X, r24
}
  2a:   08 95           ret

It seems that gcc considers the pointer address being volatile,
but this isn't explicitly defined as such.
If you declare it const it can't be volatile.
Of course it is possible to typecast the pointer, but it shouldn't
be required IMHO.
If you store the pointer localy you expliocitly state that a change
isn't allowed - if you run out of registers this could lead to stack
storage required to store the content and add different code.

> There are many bug reports about missed optimizations for avr-gcc 4.3.0. It seems that 4.6.0 could be better and it has also link time optimization.
> 
> However I did not experiment with versions later that 4.3.0.

I didn't either - compiler optimization change from version to version,
so it is some kind of Sisyphos work to tune for that and if you carefully
count the conditions where it really cares you will quickly notice that
it isn't worth in almost every case.

-- 
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