On 02/16/2011 02:32 PM, Paul Koning wrote:
On Feb 16, 2011, at 5:25 PM, David Daney wrote:

What is the state of your C0_Status[{KX,SX,UX}] bits?
0, 0, 0
It is not really a compiler bug, but rather a defect in the n32 ABI. When using 
32-bit pointers you can only do 32-bit operations on them. To do otherwise 
raises the possibility of generating addresses that fall outside of the allowed 
range.
Sure, I understand that.  Actually, I'm using O64, but the issue is the same as 
with N32.
??

The problem is that the machine is doing 64 bit arithmetic when applying an 
offset to a base register.  So what the compiler has to do is valid 64 bit 
operations from 32-bit sign extended memory and constant values.

But as you have found, there is this 64kb region centered on the split where 
behavior can become undefined.

The only real way to avoid it would be to prohibit GCC from generating non-zero 
offsets for load/store instructions, the resulting code would be slower and 
bigger than the current behavior of using the offsets in address calculations.
I don't think it needs to do anything slower.  As far as I can tell, the only 
change needed is that arithmetic on pointer values held in registers must be 
done with 64-bit operations.  That just changes the opcodes, but it doesn't 
make them any longer.
So to answer your question:

I think your 'compiler bug' is a false predicate.  And yes, I do suggest that 
you modify your kernel.
I don't have the option of modifying the kernel, since I'm dealing with data 
structures that are at hardwired addresses and moving them isn't an available 
option.

I guess I'll go beat on the code generator...

It might be easier to do something to force the base address into a 
register so that the offsetting doesn't happen.
Something like:

struct foo *v = (struct foo *)0x80007110UL;

v -= 2;
/* Clobber v so GCC forces the value into a register. */
asm("" : "+r" (v));

int bar = v->element;
.
.
.



Reply via email to