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