Inline assembly question
Dibyendu Majumdar
d.majumdar at gmail.com
Sun Nov 12 12:17:51 UTC 2017
On Sunday, 12 November 2017 at 11:55:23 UTC, Eugene Wissner wrote:
> On Sunday, 12 November 2017 at 11:01:39 UTC, Dibyendu Majumdar
> wrote:
>> I have recently started work on building a VM for Lua
>> (actually a derivative of Lua) in X86-64 assembly. I am using
>> the dynasm tool that is part of LuaJIT. I was wondering
>> whether I could also write this in D's inline assembly
>> perhaps, but there is one aspect that I am not sure how to do.
>>
>> The assembly code uses static allocation of registers, but
>> because of the differences in how registers are used in Win64
>> versus Unix X64 - different registers are assigned depending
>> on the architecture. dynasm makes this easy to do using
>> macros; e.g. below.
>>
>> |.if X64WIN
>> |.define CARG1, rcx // x64/WIN64 C call arguments.
>> |.define CARG2, rdx
>> |.define CARG3, r8
>> |.define CARG4, r9
>> |.else
>> |.define CARG1, rdi // x64/POSIX C call arguments.
>> |.define CARG2, rsi
>> |.define CARG3, rdx
>> |.define CARG4, rcx
>> |.endif
>>
>> With above in place, the code can use the mnemonics to refer
>> to the registers rather than the registers themselves. This
>> allows the assembly code to be coded once for both
>> architectures.
>>
>> How would one do this in D inline assembly?
>>
>> Thanks and Regards
>> Dibyendu
>
> Here is an example with mixins:
>
> version (Windows)
> {
> enum Reg : string
> {
> CARG1 = "RCX",
> CARG2 = "RDX",
> }
> }
> else
> {
> enum Reg : string
> {
> CARG1 = "RDI",
> CARG2 = "RSI",
> }
> }
>
> template Instruction(string I, Reg target, Reg source)
> {
> enum string Instruction = "asm { mov " ~ target ~ ", " ~
> source ~ "; }";
> }
>
> void func()
> {
> mixin(Instruction!("mov", Reg.CARG1, Reg.CARG2));
> }
Thank you - I probably could use something like this. It is
uglier than the simpler approach in dynasm of course.
How about when I need to combine this with some struct/union
access? In dynasm I can write:
| mov BASE, CI->u.l.base // BASE =
ci->u.l.base (volatile)
| mov PC, CI->u.l.savedpc // PC =
CI->u.l.savedpc
How can I mix the mixin above and combine with struct offsets?
Thanks and Regards
Dibyendu
More information about the Digitalmars-d-learn
mailing list