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. TIA. Reed
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
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. > > -EliSo just read the DAG in the beginning of MIPS-specific call lowering before it gets modified?