[LLVMdev] FP emulation

Chris Lattner sabre at nondot.org
Sun Oct 15 19:31:29 PDT 2006

On Tue, 10 Oct 2006, Roman Levenstein wrote:
>> I don't understand.  If you are writing out the .o file directly, you
>> already know how to encode calls... can't you just encode it as the
>> right sort of call?
> Yes, sure. I simply overlooked it, because it is too simple and obvious
> ;) I was thinking about doing it at a higher level, but this can be
> done as well.
> But I think that Andrew's approach as used in the Alpha backend will do
> the job and it is rather easy to implement.


>> What facilities are you using to emit the machine
>> code, are  you using the llvm machine code emitter generator stuff
>> (like PPC)?
> At the moment, I do not emit real machine code. But I'm planning to do
> it. If possible, I'll try to use the code emitter stuff of tblgen. But


> I'm not sure if it can handle the insntruction encodings of my target.
> This target uses variable length instruction encoding, where 2 bytes
> are used for opcodes and encodings of memory references and some
> registers are put between these two bytes. Therefore, the bit offsets
> are not constant and depend on the type of instruction (e.g. rm, ri and
> so on). Do you think it would be easy to express such encoding for
> tblgen?

No.  Unfortunately, tblgen can only handle targets with 32-bit wide 
instruction words at the moment (alpha, ppc, sparc, etc).  You'll have to 
write a custom code emitter like the X86 backend has.

>> You should be able to handle this in the lowering stuff, you don't
>> need anything complex here.
> OK, I see. But I'd like to know how to introduce a new calling
> convention so that it is visible at the source level. Basically, there
> are some drivers existing for this system and I'd like to be able to
> call some functions defined there. But these drivers are using very
> custom calling convention. I thought that declaring functions like
> follows could be the most appropriate solution:
> extern __MySpecialDriverAttribute int read_from_device(int devid, int
> channel);
> But for doing this I need to define a custom attribute or a new calling
> convention. Or do you see any other opportunity?

I would suggest following the model of stdcall/fastcall in the windows x86 
world.  Specifically, this would require modifying llvm-gcc to recognize 
attributes on your target, then passing that on to llvm through its 
calling convention representation.  This will let you define stuff like:

void foo() __attribute__(((mycall))) {

You can then use a #define to hide the attribute syntax.

>> Depending on how you defined the aliases, they aren't necessarily
>> transitive.  I'd like at the <yourtarget>GenRegisterInfo.inc file,
>> and see
>> what it lists as the aliases for each reg.
> Done. And I looked into the tblgen code. Tarnsitivity is not ensured by
> tblgen in any form, since it does not compute it. What it ensures is
> the commutativity of aliases, i.e. if A aliases B, then B aliases A. I
> think it would make sense if tblgen would compute a transitive closure
> automatically for alias sets, because I can hardly imagine
> non-transitive aliasing semantics. If you think that this makes sense,
> I could probably write a patch for tblgen to do that.

Be careful.  On X86, "AL aliases AX" and "AH aliases AX" but "AL does not 
alias AH".

>> The right way would be to expose the fact that these really are
>> integer  registers, and just use integer registers for it.
> How and where can this fact be exposed? In register set descriptions?
> Or may be telling to use i32 register class when we assign the register
> class to f64 values?

It currently cannot be done without changes to the legalize pass.

>> This
>> would be no problem except that the legalizer doesn't know how to
>> convert f64 -> 2 x  i32 registers.  This could be added,
> Can you elaborate a bit more about how this can be added? Do you mean
> that legalizer would always create two new virtual i32 registers for
> each such f64 value, copy the parts of f64 into it and let the register
> allocator later allocate some physical registers for it?


> Would it require adaptations only in the target-specific legalizer or
> do you think that some changes in the common part (in Target directory)
> of the legalizer are required?

The target independent parts would need to know how to do this. 
Specifically it would need to know how to "expand" f64 to 2x i32.

>> but a simpler approach to get you running faster is to add the bogus 
>> register set.
> True. To get something that works as soon as possible, this is simpler.
> But to produce a faster code, a more complex approach described above
> could be a (big?) win.

That is possible.  I would try implementing the simple approach and seeing 
what cases are being missed.



More information about the llvm-dev mailing list