Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

MS Inline Assembly $ syntax not supported #19860

Open Quuxplusone opened 10 years ago

Quuxplusone commented 10 years ago
Bugzilla Link PR19861
Status NEW
Importance P normal
Reported by João Matos (joao@tritao.eu)
Reported on 2014-05-26 19:27:55 -0700
Last modified on 2019-01-30 10:46:22 -0800
Version trunk
Hardware PC Windows NT
CC dgregor@apple.com, llvm-bugs@lists.llvm.org, llvm-dev@ndave.org, rnk@google.com
Fixed by commit(s)
Attachments MSVC-InlineAsm-Dollar.patch (2473 bytes, application/octet-stream)
Blocks PR13340
Blocked by
See also
While compiling the Mono runtime via clang-cl I've found an issue while
handling MSVC inline assembly. This works correctly with cl but fails with
clang.

Failure:

>clang-cl asm.c
asm.c(1,25) :  error: unexpected token in argument list
int main() { __asm call $+5; }
                         ^
asm.c(1,30) :  error: expected '}'
int main() { __asm call $+5; }
                              ^
asm.c(1,11) :  note: to match this '{'
int main() { __asm call $+5; }
           ^
2 errors generated.

Minimal repro:

int main() { __asm call $+5; }

Repro with some context:

typedef int mgreg_t;

typedef struct {
  mgreg_t eax;
  mgreg_t ebx;
  mgreg_t ecx;
  mgreg_t edx;
  mgreg_t ebp;
  mgreg_t esp;
  mgreg_t esi;
  mgreg_t edi;
  mgreg_t eip;
} MonoContext;

#define MONO_CONTEXT_GET_CURRENT(ctx) do { \
    void *_ptr = &(ctx); \
    __asm { \
    __asm mov eax, _ptr \
    __asm mov [eax+0x00], eax \
    __asm mov [eax+0x04], ebx \
    __asm mov [eax+0x08], ecx \
    __asm mov [eax+0x0c], edx \
    __asm mov [eax+0x10], ebp \
    __asm mov [eax+0x14], esp \
    __asm mov [eax+0x18], esi \
    __asm mov [eax+0x1c], edi \
    __asm call $+5 \
    __asm pop dword ptr [eax+0x20] \
    } \
  } while (0)

int main()
{
  MonoContext ctx;
  MONO_CONTEXT_GET_CURRENT(ctx);
  return 0;
}
Quuxplusone commented 10 years ago

By the way, this syntax is documented in MSDN: http://msdn.microsoft.com/en-us/library/78cxesy1.aspx

"As in MASM programs, the dollar symbol ($) serves as the current location counter. It is a label for the instruction currently being assembled. In __asm blocks, its main use is to make long conditional jumps"

Quuxplusone commented 10 years ago
*blink*  OK, sounds good, let's do it.  :)
Quuxplusone commented 10 years ago

Attached MSVC-InlineAsm-Dollar.patch (2473 bytes, application/octet-stream): MSVC Inline Asm Dollar WIP patch

Quuxplusone commented 10 years ago

I've spent a couple hours trying learning this part of the codebase and trying to add this to Clang but I've not been able to get it working. I've attached a work in progress patch, it goes a bit further and emits the inline assembly but there's some asm rewriting going on for translating immediates and it's output as "call $$$" which the assembler fails to deal with.

I'm not that familiar with either AT&T or Intel assembly and neither am I sure that the approach I am taking is the correct one so I'll leave more knowledge souls to deal with this.

FWIW I just rewrote this part of code in Mono to use labels and that works as an alternative in this specific case.

This was also the only issue I've found so far while compiling Mono with clang-cl, awesome job Reid & co. on improving the MS ABI these last couple of months.