I'm implementing this unusual gcc form of mips16 hard float. I ran into one unexpected wrinkle. It effects efficiency as opposed to correctness but I'd like to figure out the best way to resolve it. The signatures for the libcall routines have floating point arguments in at least some situations. I have not fully examined if it's all of them. So in callinfo while I'm lowering the call, the first argument for example will appear to be a float. For sure in the following situation: float f; ... printf("%f \n", f); So it generates a libcall to widen f to double. long int XXX_extendsfdf2(float); The problem for me is that the parameter should be int since this is a soft float routine. Probably nobody ever looks at this argument type in this situation. So I think this should look like: long int XXX_extendsfdf2(int); In my case the routine is called __mips16_extendsfdf2 . When I see the first parameter as float, I think that I need to generate a mips16 helper function. This is because in the abi that parameter would be passed in a floating point argument register but this is not possible in mips16 mode since there are no floating point instructions. For interoperability between mips16 and mips32, when I see an external call, I don't know if it's mips16 or mips32, so I automatically must generate a helper function so that the call works correctly whether the extern is in a module compiled as mips16 or mips32. What I was not expecting is to see such a signature from a routine which is already a routine generated for soft float. So I'm generating an unneeded call to a helper function. I could try and filter it out based on the name of the routine being called but it seems that this is just the result of a mistake in target independent code.
What happens here is that the code that is doing the "softening", generates a libcall On closer inspection, llvm is doing half of this correctly. The signature for the soft float function for extending a float to double is of the form: i64 xxx_extendsfdf2(float); But it should be i64 xxx_extendsfdf2(i32) This particular paradigm is duplicated many times in the the float type lowering. I'm not sure exactly how to change this and what effect if any that it might have. thoughts? In my case for mips16, it's important that I know the proper function signature, otherwise I'll generate an unnecessary helper function call. tia. Reed On 01/20/2013 06:28 AM, Reed Kotler wrote:> I'm implementing this unusual gcc form of mips16 hard float. > > I ran into one unexpected wrinkle. It effects efficiency as opposed to > correctness but I'd like to figure out the best way to resolve it. > > The signatures for the libcall routines have floating point arguments > in at least some situations. I have not fully examined > if it's all of them. So in callinfo while I'm lowering the call, the > first argument for example will appear to be a float. > > For sure in the following situation: > > float f; > ... > printf("%f \n", f); > > So it generates a libcall to widen f to double. > > long int XXX_extendsfdf2(float); > > The problem for me is that the parameter should be int since this is a > soft float routine. Probably nobody ever looks at this argument type in > this situation. > > So I think this should look like: > long int XXX_extendsfdf2(int); > > In my case the routine is called __mips16_extendsfdf2 . > > When I see the first parameter as float, I think that I need to generate > a mips16 helper function. This is because in the abi that parameter > would be passed in a floating point argument register but this is not > possible in mips16 mode since there are no floating point instructions. > > For interoperability between mips16 and mips32, when I see an external > call, I don't know if it's mips16 or mips32, so I automatically must > generate a helper function so that the call works correctly whether the > extern is in a module compiled as mips16 or mips32. > > What I was not expecting is to see such a signature from a routine which > is already a routine generated for soft float. > > So I'm generating an unneeded call to a helper function. > > I could try and filter it out based on the name of the routine being > called but it seems that this is just the result of a mistake in target > independent code.
I came up with a decent workaround to this problem but it still would be nice to fix it as described below. On 01/22/2013 02:20 PM, Reed Kotler wrote:> What happens here is that the code that is doing the "softening", > generates a libcall > > On closer inspection, llvm is doing half of this correctly. > > The signature for the soft float function for extending a float to > double is of the form: > > i64 xxx_extendsfdf2(float); > > But it should be > > i64 xxx_extendsfdf2(i32) > > This particular paradigm is duplicated many times in the the float type > lowering. > > I'm not sure exactly how to change this and what effect if any that it > might have. > > thoughts? > > In my case for mips16, it's important that I know the proper function > signature, otherwise I'll generate an unnecessary helper function call. > > tia. > > Reed > > On 01/20/2013 06:28 AM, Reed Kotler wrote: >> I'm implementing this unusual gcc form of mips16 hard float. >> >> I ran into one unexpected wrinkle. It effects efficiency as opposed to >> correctness but I'd like to figure out the best way to resolve it. >> >> The signatures for the libcall routines have floating point arguments >> in at least some situations. I have not fully examined >> if it's all of them. So in callinfo while I'm lowering the call, the >> first argument for example will appear to be a float. >> >> For sure in the following situation: >> >> float f; >> ... >> printf("%f \n", f); >> >> So it generates a libcall to widen f to double. >> >> long int XXX_extendsfdf2(float); >> >> The problem for me is that the parameter should be int since this is a >> soft float routine. Probably nobody ever looks at this argument type in >> this situation. >> >> So I think this should look like: >> long int XXX_extendsfdf2(int); >> >> In my case the routine is called __mips16_extendsfdf2 . >> >> When I see the first parameter as float, I think that I need to generate >> a mips16 helper function. This is because in the abi that parameter >> would be passed in a floating point argument register but this is not >> possible in mips16 mode since there are no floating point instructions. >> >> For interoperability between mips16 and mips32, when I see an external >> call, I don't know if it's mips16 or mips32, so I automatically must >> generate a helper function so that the call works correctly whether the >> extern is in a module compiled as mips16 or mips32. >> >> What I was not expecting is to see such a signature from a routine which >> is already a routine generated for soft float. >> >> So I'm generating an unneeded call to a helper function. >> >> I could try and filter it out based on the name of the routine being >> called but it seems that this is just the result of a mistake in target >> independent code.