[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.)
-Eli
More information about the llvm-dev
mailing list