Pointer arithmetic vs structure size

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

winavr 080512, atmega32, optimization = 's'

index is signed char
sizeof(somestruct)= 16

    somestruct* rx = base + index;
    33b0:	80 91 de 02 	lds	r24, 0x02DE
    33b4:	e8 2e       	mov	r14, r24
    33b6:	ff 24       	eor	r15, r15
    33b8:	e7 fc       	sbrc	r14, 7
    33ba:	f0 94       	com	r15
    33bc:	74 e0       	ldi	r23, 0x04	; 4
    33be:	ee 0c       	add	r14, r14
    33c0:	ff 1c       	adc	r15, r15
    33c2:	7a 95       	dec	r23
    33c4:	e1 f7       	brne	.-8      	; 0x33be <_Z5somefunctionh+0x72>
    33c6:	8e e8       	ldi	r24, 0x8E	; 142
    33c8:	92 e0       	ldi	r25, 0x02	; 2
    33ca:	e8 0e       	add	r14, r24
    33cc:	f9 1e       	adc	r15, r25

sizeof(somestruct)= 17

    somestruct* rx = base + index;
    327e:	80 91 e3 02 	lds	r24, 0x02E3
    3282:	91 e1       	ldi	r25, 0x11	; 17
    3284:	89 02       	muls	r24, r25
    3286:	70 01       	movw	r14, r0
    3288:	11 24       	eor	r1, r1
    328a:	8e e8       	ldi	r24, 0x8E	; 142
    328c:	92 e0       	ldi	r25, 0x02	; 2
    328e:	e8 0e       	add	r14, r24
    3290:	f9 1e       	adc	r15, r25

Apparently on some stage compiler thinks it is still on 90s core without hardware multiply and decide to use shift instead for 'handy' sizes. Pad your structs for speed and size...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could you post your source code that generates the above assembly? I cannot reproduce the problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No explanation for why the compiler chooses shift instead of multiply. I know that when I do the same thing for pointer arithmatic, if the size of a structure is 2,4,8,16, etc the compiler will choose to do a shift rather than a multiply.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

complete sample:

#define SIZE 8
typedef struct { char raw[SIZE];} str1;
str1 qq[6];
char head;

void funct()
{
  str1 *ww = qq+head;
  if(ww->raw[0] & 2)
    ww->raw[1]=0;
}
main()
{
  funct();
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ashesman wrote:
No explanation for why the compiler chooses shift instead of multiply. I know that when I do the same thing for pointer arithmatic, if the size of a structure is 2,4,8,16, etc the compiler will choose to do a shift rather than a multiply.

Well, typically, multiplies using a power of 2 would be shorter using a shift. However, the AVR port of GCC is probably is not taking into account the MUL* instructions and the fact that it may be shorter than using shifts when it does its calculations on what code it should generate.

That's the reason I asked for a complete test case, so I can open up a bug report with GCC and notify the other AVR GCC developers about this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Posted now as GCC bug #36467:
http://gcc.gnu.org/bugzilla/show...