[LLVMdev] mips16 hard float puzzle

Eli Friedman eli.friedman at gmail.com
Tue Jan 8 13:47:00 PST 2013

On Mon, Jan 7, 2013 at 4:16 PM, reed kotler <rkotler at mips.com> wrote:
> On 01/04/2013 07:45 PM, Eli Friedman wrote:
>> On Fri, Jan 4, 2013 at 6:28 PM, reed kotler <rkotler at mips.com> wrote:
>>> On 01/04/2013 06:08 PM, Eli Friedman wrote:
>>>> On Fri, Jan 4, 2013 at 4:08 PM, reed kotler <rkotler at mips.com> wrote:
>>>>> I'm working on mips16 hard float which at a first approximation is just
>>>>> soft
>>>>> float but calls different library routines. Those different library
>>>>> routines
>>>>> are just an implementation (in mips32 mode) of soft float using mips32
>>>>> hardware instructions. This part is already done. (mips16 mode has no
>>>>> floating point instructions).
>>>>> The next level of this that I am working on now is the ability to call
>>>>> mips32 mode functions from mips16. This is needed for example to call
>>>>> the
>>>>> math library (sin, cos), because those library
>>>>> routines are mips32 functions.
>>>>> This has an interesting problem.
>>>>> The mips16 functions do not know what they are calling when it's an
>>>>> external
>>>>> function; i.e. it could be a mips32 or mips16.
>>>>> On mips32, floating point arguments, if they are argument 1 and
>>>>> argument
>>>>> 2,
>>>>> are passed in floating point registers. If the return type is floating
>>>>> point, then it is returned in a floating point register.
>>>>> On mips 16, it is doing soft float essentially so the arguments are
>>>>> passed
>>>>> in integer registers.
>>>>> The way gcc mips16 does this is to call helper functions which do the
>>>>> actual
>>>>> call to the external function. The helper functions copy arg 1 and 2
>>>>> into
>>>>> fp
>>>>> arg 1 and fp arg 2 and then do the actual call. So whether you are
>>>>> calling
>>>>> mips16 or mips32 from that point on does not matter.
>>>>> I'm simplifiying this a bit and you have to think about the mips abi to
>>>>> understand how this all works but it does.
>>>>> The question I have is how to find the original prototype.
>>>>> In order to know if I need to call a helper function, and which helper
>>>>> function to call, I need to know the return type and type of arguments
>>>>> 1
>>>>> and
>>>>> 2. I need to know this pre soft float lowering.
>>>>>   From what I can see, in the beginning of ISelLowering code, the DAG
>>>>> will
>>>>> still reflect the original prototype. If I do a DAG.viewGraph() there
>>>>> in
>>>>> the
>>>>> debugger, it knows about the proper prototype (pre soft float
>>>>> lowering).
>>>>> It would have been cool to get the function class that corresponds to
>>>>> this
>>>>> call and get the arguments that way but I don't see how I can get it.
>>>>> Is looking at the DAG the only (or best) way to do find the function
>>>>> prototype?
>>>>> I would be happy to add something to lowering calls methods but it was
>>>>> not
>>>>> clear how to do this too.
>>>> You have to do this as part of call lowering: once the call is
>>>> lowered, the type information is lost permanently.  It's not
>>>> conceptually difficult to do as part of call lowering, though: in the
>>>> MIPS-specific call lowering code, if you detect that a call requires
>>>> an argument in an FP register, you just need to generate a call to the
>>>> relevant helper rather than the function itself.
>>>> -Eli
>>> So just read the DAG in the beginning of MIPS-specific call lowering
>>> before
>>> it gets modified?
>> Take a look at CCValAssign etc. in MipsTargetLowering::LowerCall.
>> (The DAG node for the callee doesn't have the necessary information in
>> the general case, even though it might appear to work in simple
>> cases.)
>> -Eli
> I'm not sure if I understood you.
> For Mips hard float, we also have the soft float option in llc.
> Right now we pass:
> -mips16-hard-float -soft-float
> To llc.
> So the call is going to get changed to use integer types but I need to be
> able to find what is was before that change takes place.

If you need to be able to put values into floating-point registers,
your architecture is not soft-float.  If the call expects the operand
in a floating-point register, the call analysis code needs to know
that we're dealing with a floating point value, and the code that
generates the call needs to correctly put it in that register; whether
there is a Mips16 instruction to perform that operation is irrelevant.
 If the CCValAssign thinks that a floating-point argument is actually
an integer, you can't recover at that point.  (It's possible that the
call analysis code needs to be enhanced to make this work.)


More information about the llvm-dev mailing list