c/507: Incorrect loading of addresses when compiling for PowerPC

martin@malibunetworks.com martin@malibunetworks.com
Tue Sep 5 14:26:00 GMT 2000

>Number:         507
>Category:       c
>Synopsis:       Incorrect loading of addresses when compiling for PowerPC
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 05 14:26:00 PDT 2000
>Originator:     Martin Usher
>Release:        2.9 (ecos), also 2.7.2 (version shipped with Wind River's "Tornado 2.0"
i586/NT4.0 cross compiling for PowerPC
When loading a register with a 32 bit literal such as an address the compiler emits this instruction sequence:-

	addis 9,0,sdata@ha
	addi 0,9,sdata@l

where 'sdata' is the address of a label. This will sometimes load the wrong address into r0 because addi sign extends the number - if bit 16 (NOTE - PowerPC uses 0 as LH/MSB so this is the MSB of the lower 16 bits) is set this will sign extend and decrement the high part that had already been loaded into r9.
This is very easy to repeat once you know it is there. Neither compiler options nor processor type affect the output. All you have to do is compile any arbitary piece of code with the -S option to see this all over the emitted code.
Use ori instead of addi as the second order.

Note that GCC uses the 'simplified' order, 'li', in the instruction code instead of addi, so expect the code sequence in the compiler to look like "li reg,value" instead of addi "reg,reg,value"

More information about the Gcc-bugs mailing list