Inline assembler in D and LDC, round 2

Frits van Bommel fvbommel at REMwOVExCAPSs.nl
Sat Feb 7 03:15:43 PST 2009


Chad J wrote:
> Frits van Bommel wrote:
>> Lionello Lunesu wrote:
>>> "Frits van Bommel" <fvbommel at REMwOVExCAPSs.nl> wrote in message
>>> news:gmeqbr$1377$1 at digitalmars.com...
>>>> LDC on the other hand needs to emit LLVM asm, which requires it to
>>>> specify an explicit return value. My approach is a way to extract
>>>> that return value from the inline asm, allowing it to emulate DMD
>>>> behavior within the LLVM IR.
>>> Sorry, perhaps I'm missing something: Why should you have to deduct
>>> that from the asm? Doesn't the function prototype give enough
>>> information? If the function returns "int/uint/...", assume "eax"; if
>>> it returns "float/double/..." assume "st(0)", etc....
>> LLVM IR doesn't know about hardware registers, except when dealing with
>> inline asm. So if you need to know the value a hardware register has at
>> the end of some inline asm, you need to tell that asm to "return" it
>> into a virtual register that you can actually use in regular IR (such as
>> returning it from a function).
> 
> I think I might just sortof maybe kinda understand the problem now.
> 
<snip>
> 
> I hope I understand this correctly.  It seems like the problem at hand
> is difficult to communicate and thus stomps useful dialog :(

That seems to be a pretty good summary of what's wrong with most of the 
alternatives, yes.

You missed one though, that Lindquist mentioned: they could also return 
a special "undefined value" (which LLVM supports, and means "I don't 
care what it is") and the return value would (in practice) be whatever 
was in the relevant register at the time *if no optimizations are run*.
The problem is that optimizations can see "Hey, that function only ever 
returns one value (or returns either a normal value or an undefined 
value)" and change all places where the return value is used with that 
one value. This would break the asm + ret undef, yet be a perfectly 
valid optimization according the semantics of LLVM IR.

Luckily, inline asm is treated as a function literal in LLVM, and it can 
return one or more values to the caller if the constraints string 
specifies which registers will contain them. So if LDC just specifies 
(e.g.) EAX/EDX:EAX/ST(0) to contain the result of the inline asm, it can 
get the value in the register(s) in question as an LLVM value that can 
be returned without any problem.
The only really tricky bits are (a) figuring out how the constraints 
string works, exactly[1] and (b) figuring out which register(s) the 
return value should be in.


[1]: There's no documentation that I'm aware of (unless it was added 
very recently) other than the LLVM(-GCC) source and llvm-gcc output when 
compiling code containing extended asm (which is similar but not 
identical to LLVM-style inline asm, and documented pretty well at 
http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html). The similarity is 
not an accident as the main requirement in the inline asm design for 
LLVM was probably "support extended asm in llvm-gcc" :).



More information about the Digitalmars-d mailing list