digitalmars.D.ldc - LDC inline assembler
- Mike (58/58) May 05 2015 I'm trying to do a write a syscall in x86_64 Linux, but I'm
I'm trying to do a write a syscall in x86_64 Linux, but I'm having trouble with the LDC inline assembler syntax. Here's my cludgy implementation for DMD and GDC: extern(C) c_int sys_write(c_int arg1, in void* arg2, c_int arg3) nothrow { ssize_t result; version(D_LP64) { version(DigitalMars) { asm nothrow { mov RAX, 1; mov RDI, arg1; mov RSI, arg2; mov RDX, arg3; syscall; } } else version(GNU) { asm { "syscall" // make the request to the OS : "=a" result // return result in rax ("a") : "a" 1, // pass system call number in rax ("a") "D" arg1, // pass arg1 in rdi ("D") "S" arg2, // pass arg2 in rsi ("S") "m" arg2, // arg2 is a pointer to memory "d" arg3 // pass arg3 in rdx ("d") : "memory", "cc", "rcx", "r11"; // announce to the compiler that the memory and condition codes // have been modified, kernel may clopper rcx and r11 } } else { static assert(false, "sys_write only supports DMD and GDC"); } } else { static assert(false, "sys_write only supports 64-bit"); } // TODO: Not sure if this is right return result; } I've read through http://wiki.dlang.org/LDC_inline_assembly_expressions, but I'm just not understanding the syntax. Could you translate the above to LDC's syntax? If I can understand it, I'll document an example on the wiki in return. Thanks, Mike
May 05 2015
return __asm!long("syscall","=a,a,D,S,*m,d,~{memory},~{cc},~c,~{r11}", 1,arg1,arg2,arg2,arg3); Though I have no idea what I'm doing :)
May 06 2015
Hi Mike! This should do the trick: extern(C) ulong dosyscall(ulong a, ulong b, ulong c) { import ldc.llvmasm; ulong result = __asm!ulong("syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11}", 1, a, b, c); return result; } A named register must be surrounded with { }. If any register is ok then you can use simply r. As far as I know there is no way that to tell LLVM that a memory range is clobbered. Regardsm Kai
May 06 2015
On Wednesday, 6 May 2015 at 10:31:15 UTC, Kai Nacke wrote:As far as I know there is no way that to tell LLVM that a memory range is clobbered.Doesn't ~{memory} do it?
May 06 2015
On Wednesday, 6 May 2015 at 10:31:15 UTC, Kai Nacke wrote:Hi Mike! This should do the trick: extern(C) ulong dosyscall(ulong a, ulong b, ulong c) { import ldc.llvmasm; ulong result = __asm!ulong("syscall", "={rax},{rax},{rdi},{rsi},{rdx},~{rcx},~{r11}", 1, a, b, c); return result; } A named register must be surrounded with { }. If any register is ok then you can use simply r. As far as I know there is no way that to tell LLVM that a memory range is clobbered. Regardsm KaiThank you! It works great. I added it to the Wiki for future reference: http://wiki.dlang.org/LDC_inline_assembly_expressions Mike
May 06 2015
On Wednesday, 6 May 2015 at 13:31:07 UTC, Mike wrote:Thank you! It works great. I added it to the Wiki for future reference: http://wiki.dlang.org/LDC_inline_assembly_expressions MikeThanks for the wiki update! Regards, Kai
May 07 2015