Bad MIPS address arithmetic

David Daney
Tue May 11 01:56:00 GMT 2010

On 05/10/2010 06:11 PM, Paul Koning wrote:
>> So I think it is working as it was intended.  For the default n32 ABI,
>> the ADDU is the proper instruction to use for pointer arithmetic.
> I don't agree.  Clearly it is flat out wrong in the test case.

You never said what your criteria for correctness were.  For your two 
line assembly file you are not getting the results you want for some 
specific values of $sp.

If you expand your horizons a little so that they include the code gcc 
will emit for all different types of n32 pointer arithmetic, then I 
think it is not so black and white.

>> Other
>> ABIs do different things.  If you want code for n64, you should
> specify
>> that when invoking the assembler.  You can also add '.set nomacro' if
>> you don't want it to do these weird things.
>> In MIPS assembly, what you think is an instruction often isn't, the
>> and other things have a big influence.
> Well, yes, that's an unfortunate and very serious design error dating
> back to day 1 of the MIPS assemblers.

They are what they are.  Knowing their limitations, it is possible to 
create a working system.

> The big problem for me is that the code sequence in question comes out
> of gcc (V3.3, which we're stuck with for now).  Essentially, what it
> means is that a program with a stack frame bigger than 32k may crash in
> bizarre ways.

... unless you restrict the virtual address range of valid pointers as I 
suggested that the Linux kernel does.

> Clearly addu is wrong here.  I believe the right answer is that daddu is
> correct for address arithmetic whenever 64 bit registers are used, i.e.,
> O64, N32, N64.  In other words, not only for N64 as appears to be the
> current assumption.

I dissagree, it has nothing to do with the width of the registers.  It 
is the width of the data type that is important.  If your pointers are 
32-bits wide, you should use the corresponding 32-bit instructions to 
manipulate them.  Doing otherwise can result in undefined behavior. 
This is what gcc and binutils are doing.  If you use daddu, you can 
generate register values where the upper 32-bits are non-uniform (not 
all 0 or all 1).  Once you do that, you enter into the world of truly 
undefined behavior.

> I need to do some analysis to see if that theory is correct for ksegx
> addresses.
> 	paul

More information about the Binutils mailing list