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