This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bad MIPS address arithmetic


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]