patch for problem when mips16 hard float is linked as c++

reed kotler rkotler at mips.com
Wed Feb 12 11:48:52 PST 2014


On 02/12/2014 10:59 AM, Rafael EspĂ­ndola wrote:
> On 12 February 2014 13:03, reed kotler <rkotler at mips.com> wrote:
>> This patch has been rewritten to not use output raw text in MipsAsmPrinter
>> and so is being sent out to the list
>> before actual commit to make sure there are no further objections.
> Thanks!
>
>> This patch has two main functions:
>>
>> 1) Fix a specific bug when certain conversion functions are called in a
>> program compiled as mips16 with hard float and
>> the program is linked as c++. There are two libraries that are reversed in
>> the link order with gcc/g++ and clang/clang++ for
>> mips16 in this case and the proper stubs will then not be called. These
>> stubs are normally handled in the Mips16HardFloat pass
>> but in this case we don't know at that time that we need to generate the
>> stubs. This must all be handled later in code generation
>> and we have moved this functionality to MipsAsmPrinter. When linked as C
>> (gcc or clang) the proper stubs are linked in from libc.
> This is strange, but as long as it is local to the Mips backend that
> is probably fine. Can you share a bit more what the issue is? What
> stub that needs to be generated but currently is not? When can you
> find out that it is needed?
Richard Sandiford  who is on this list now (and is the supreme gcc Mips 
expert) can explain this latest wrinkle more fully.

LLVM Mips16 hard float matches the gcc implementation of that .

Mips16 is a processor mode ala thumb1 and thumb2 and so there is really 
a mips32 processor
executing.

There is no document on how gcc mips16 hard float works but there is 
some documentation in file mips16.S
(that is part of gcc). There are some big differences in how this works 
for pic and non pic and many other
surprising wrinkles that I could not anticipate until I just dug in and 
tried to implement this. I now need to really
go through and read some more parts of gcc, ld and libc to make sure 
there are no further issues (as well as read
through the 10 years of gcc developers email on the many issues of 
mips16 floating point.. dwarf and exception
handling was fun for mips16 too :))


At a first approximation, it's just soft float where the library 
routines are implemented as mips32 mode
routines (since mips16 mode has no floating point). This involves just 
compiling as soft float and remapping
the names of the usual soft float routines to use this special library.

Then they want for mips32 and mips16 code to interoperate seamlessly in 
such a way that mips32 code does
not have to have any idea that mips16 even exists as a processor mode.

This is a problem because the mips32 O32 abi has some parameters and 
return values being passed in floating point
registers and mips16 code cannot access those.

So you have to create stubs to smooth the transition to/from 
mips16/mips32 code when certain function signatures are present.

I do this analysis in the IR phase Mips16HardFloat because this info is 
not reliable later on in LLVM (after soft float processing) and I don't 
want to be messing in the target
independent parts of soft float to fix these issues if at all possible.

In general, all of this works for pic and non pic and I've passed all of 
test-suite for mips16 hard float ages ago.

We had our own version of test-suite that was modified and we just 
switched to the pristine one and in that case, some test cases
are linked with clang++ and that showed the bug.

It seems that these conversion functions which are needed library 
functions for both mips32 and mips16 (i.e. long long to float for example),
has a funny status. __floatdidf, __floatdisf, __floatundidf, ....

In libc, the stubs you would need are already there and in one of the 
other libraries, they are not. Depending on which order you have those,
you will get a different implementation linked in; one which will call 
the right stubs and other which does not. gcc/g++ and clang/clang++
reverse the order of these two libraries.

gcc knows about this problem and generates stubs for __floatdidf, etc.

These builtin functions are not something that can be seen early because 
there are no signatures in the source and therefore none in the IR.
I only know later when the compiler has generated calls to them that 
they are there.

There are some other cases too where waiting to evaluate things would be 
better done in a later phase.
For example, there are some library routines that have signatures but 
end of getting inlined by the compiler.
If I make stubs for those, then I will get a link error because they do 
not exist in the library. I've bandaided over this problem
but would rather fix it in a better way.

So in general, it's better to do analysis of function signatures in the 
IR phase, but delay all outputing of the stubs until asm printer.
Then all additional questions have been answered. And some additional 
functions will be known to be needed later and they can be added to the 
queue
of things to generate. This new mechanism to fix this problem works this 
way.



>> 2) Set up the infrastructure to handle 90% of what is in the Mips16HardFloat
>> pass in this new area of MipsAsmPrinter. This is a more
>> logical place to handle this and we have known for some time that we needed
>> to move the code later and not implement it using
>> inline asm as we do now but it was not clear exactly where to do this and
>> what mechanism should be used. Now it's clear to us
>> how to do this and this patch contains the infrastructure to move most of
>> this to MipsAsmPrinter but the actual moving will be done
>> in a follow on patch. The same infrastructure is used to fix this current
>> bug as described in #1. This change was requested by the list
>> during the original putback of the Mips16HardFloat pass but was not
>> practical for us do at that time.
> The patch includes some formatting only changes like
>
> -                 TII->get(SltOpc)).addReg(regX).addReg(regY);
> +          TII->get(SltOpc)).addReg(regX).addReg(regY);
>
> It would be easier to read without it. For the same reason, can you
> clang-format it?
>
> Looks like some functions (EmitJal for example) could be static
> helpers in the .cpp file. Also, please use the current naming
> convention (emitJal).
>
> +    (".mips16.call.fp."+std::string(Symbol)
>
> You can probably use a Twine.
Will take a look at these issues.
> I guess the main feedback is that this patch doesn't go against any of
> the current llvm designs like MC or what is and is not inline
> assembly, so I don't have any strong objections to it.
>
> Cheers,
> Rafael





More information about the llvm-commits mailing list