Skip to content

[Windows] Support MSVC __asm syntax #13712

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
timurrrr opened this issue Jul 12, 2012 · 25 comments
Closed

[Windows] Support MSVC __asm syntax #13712

timurrrr opened this issue Jul 12, 2012 · 25 comments
Labels
bugzilla Issues migrated from bugzilla c++

Comments

@timurrrr
Copy link
Contributor

Bugzilla Link 13340
Resolution FIXED
Resolved on Sep 21, 2015 22:07
Version trunk
OS Windows NT
Depends On llvm/llvm-bugzilla-archive#16830 llvm/llvm-bugzilla-archive#19861 llvm/llvm-bugzilla-archive#17201
Blocks llvm/llvm-bugzilla-archive#13707
CC @lattner,@DougGregor,@jrmuizel,@tritao,@nico,@rnk

Extended Description

$ cat assembly.cpp
int foo(int argument) {
int result;
__asm {
mov eax, argument
inc eax
mov result, eax
}
return result;
}

extern "C"
int printf(const char *fmt, ...);

int main() {
int val = 42;
int res = foo(val);
printf("res = %d\n", res);
return res != 43;
}

$ cl -nologo assembly.cpp && ./assembly.exe && echo "OK"
assembly.cpp
res = 43
OK

As of r159923,
$ clang++ -Xclang -cxx-abi -Xclang microsoft assembly.cpp && ./a.out && echo "OK"
assembly.cpp:3:3: warning: MS-style inline assembly is not supported [-Wmicrosoft]
__asm {
^
1 warning generated.
res = 11

@lattner
Copy link
Collaborator

lattner commented Jul 15, 2012

Chad is working on this.

@timurrrr
Copy link
Contributor Author

Oops, wrong platform.

@tritao
Copy link
Mannequin

tritao mannequin commented Feb 26, 2013

What is the state of the asm support in trunk?

Can this be closed as fixed?

@timurrrr
Copy link
Contributor Author

I think the support is not complete yet, e.g. this doesn't work IIRC:

__asm {
mov ecx, 1
L:
dec ecx
jnz L
}

@rnk
Copy link
Collaborator

rnk commented Mar 25, 2013

Apparently this is also supported by MSVC:

struct Foo {
static int *ptr;
};

__asm {
mov eax, dword ptr [Foo::ptr]
mov byte ptr [eax], 66
}

Clang gives what you might expect:
$ clang -fsyntax-only namespace_asm.cpp
namespace_asm.cpp:10:28: error: Expected ']' token!
mov eax, dword ptr [Foo::ptr]
^

@llvmbot
Copy link
Member

llvmbot commented Mar 25, 2013

Tracking the issue pointed out by Reid in rdar://13499009. Should should be relatively easy to fix.

@llvmbot
Copy link
Member

llvmbot commented Mar 29, 2013

Reid, I'm unable to verify if your example is supported. With this example,

struct Foo {
static int *ptr;
};
void t() {
__asm mov eax, dword ptr [Foo::ptr]
}

I get the following errors:
C:\t.c(3) : error C2071: 'ptr' : illegal storage class
C:\t.c(6) : error C2400: inline assembler syntax error in 'third operand'; found ':'

I'm compiling with the /Od /Fa options using Visual Studio 10.

Am I doing something wrong?

@timurrrr
Copy link
Contributor Author

Should be a .cpp file, I suppose?

@llvmbot
Copy link
Member

llvmbot commented Mar 29, 2013

Doh! That should have been obvious.. :o/ Thanks, Timur. The example works as expected.

@rnk
Copy link
Collaborator

rnk commented Apr 17, 2013

MSVC asm using setc

@rnk
Copy link
Collaborator

rnk commented Apr 17, 2013

Discovered one more bug: LLVM doesn't recognize the setc opcode. It's an alias for setb; they both check the carry flag (CF).

Test case attached.

@llvmbot
Copy link
Member

llvmbot commented Apr 17, 2013

The setc issue is also being tracked in rdar://13674398. Hopefully, I can address this shortly.

@llvmbot
Copy link
Member

llvmbot commented Apr 19, 2013

The setc issue should be resolved with r179804 and r179813.

@llvmbot
Copy link
Member

llvmbot commented Apr 23, 2013

*** Bug llvm/llvm-bugzilla-archive#15779 has been marked as a duplicate of this bug. ***

@rnk
Copy link
Collaborator

rnk commented Jun 4, 2013

@rnk
Copy link
Collaborator

rnk commented Jun 4, 2013

I've discovered another feature. :) Apparently you can do something like:
struct Foo { int a; };
__asm {
mov eax, [ebx]Foo.a
}

The "Foo.a" expression here computes the offset of Foo::a and adds it to ebx before dereferencing.

@rnk
Copy link
Collaborator

rnk commented Jun 4, 2013

This is probably related, the 'context.Eip' expression fails to parse with an assertion (infinite loop in NDEBUG build):

$ cat ms_inline_asm_call_pop_pic.cc
extern "C" int printf(const char *fmt, ...);
struct MyContext {
void *Eip;
};
int main() {
MyContext context;
__asm {
call x
x: pop eax
mov context.Eip, eax
}
printf("%p\n", my_pc);
}

$ ../../build_debug/bin/clang -c ms_inline_asm_call_pop_pic.cc
Assertion failed: End.getPointer() <= EndPtr && "frontend claimed part of a token?", file ..\lib\Target\X86\AsmParser\X86AsmParser.cpp, line 1392
Stack dump:
0. Program arguments: D:/src/llvm/build_debug/bin/clang.exe -cc1 -triple i686-pc-win32 -emit-obj -mrelax-all -disable-free -main-file-name ms_inline_asm_call_pop_pic.cc -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -target-cpu pentium4 -coverage-file ms_inline_asm_call_pop_pic.o -resource-dir D:/src/llvm/build_debug/bin..\lib\clang\3.4 -internal-isystem D:/src/llvm/build_debug/bin/../lib/clang/3.4/include -internal-isystem C:/PROGRA2/MICROS3.0/VC/include -internal-isystem C:/PROGRA2/WI3CF21/8.0/Include/shared -internal-isystem C:/PROGRA2/WI3CF21/8.0/Include/um -internal-isystem C:/PROGRA2/WI3CF21/8.0/Include/winrt -internal-isystem C:/PROGRA2/MICROS3.0/include -std=c++11 -fdeprecated-macro -fdebug-compilation-dir D:\src\llvm\tools\clang -ferror-limit 19 -fmessage-length 0 -mstackrealign -fms-extensions -fms-compatibility -fmsc-version=1300 -fdelayed-template-parsing -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fcxx-exceptions -fexceptions -fdiagnostics-show-option -backend-option -vectorize-loops -o ms_inline_asm_call_pop_pic.o -x c++ ms_inline_asm_call_pop_pic.cc

  1.  ms_inline_asm_call_pop_pic.cc:12:3: current parser token 'printf'
    
  2.  ms_inline_asm_call_pop_pic.cc:5:12: parsing function body 'main'
    
  3.  ms_inline_asm_call_pop_pic.cc:5:12: in compound statement ('{}')
    

0x6166C94A (0x0000000A 0x00000000 0x0374B4E4 0x61747114), exit() + 0x13A bytes(s)
0x61757A9C (0x0374B530 0x0374B4F8 0xCCCCCCCC 0xCCCCCCCC), abort() + 0x1C bytes(s)
0x61747114 (0x02E54BA0 0x02E54B40 0x00000570 0x0374B608), _wassert() + 0xC04 bytes(s)
0x00356810 (0x0374B5E0 0x0374B5B4 0x0374B5C4 0x00000000), anonymous namespace'::X86AsmParser::ParseIntelIdentifier() + 0x120 bytes(s), d:\src\llvm\lib\target\x86\asmparser\x86asmparser.cpp, line 1392 + 0x2D byte(s) 0x00355CDA (0x00000000 0x00000000 0x00000000 0x0374C918), anonymous namespace'::X86AsmParser::ParseIntelMemOperand() + 0x3DA bytes(s), d:\src\llvm\lib\target\x86\asmparser\x86asmparser.cpp, line 1455 + 0x1A byte(s)
0x00355199 (0x03B8BB50 0x0374BBEC 0x0035B4E4 0x0374BF58), anonymous namespace'::X86AsmParser::ParseIntelOperand() + 0x539 bytes(s), d:\src\llvm\lib\target\x86\asmparser\x86asmparser.cpp, line 1636 0x003549A5 (0x0374BF58 0x0374BC08 0xCCCCCCCC 0xCCCCCCCC), anonymous namespace'::X86AsmParser::ParseOperand() + 0x25 bytes(s), d:\src\llvm\lib\target\x86\asmparser\x86asmparser.cpp, line 1117 + 0x8 byte(s)
0x0035B4E4 (0x0374BEB4 0x0374BEC4 0x00000003 0x0374C914), anonymous namespace'::X86AsmParser::ParseInstruction() + 0xA74 bytes(s), d:\src\llvm\lib\target\x86\asmparser\x86asmparser.cpp, line 1928 + 0x8 byte(s) 0x006B84F6 (0x0374C140 0x0374CCA4 0x0374C3BC 0xCCCCCCCC), anonymous namespace'::AsmParser::ParseStatement() + 0xFA6 bytes(s), d:\src\llvm\lib\mc\mcparser\asmparser.cpp, line 1474 + 0x41 byte(s)
0x006B5E90 (0x00000076 0x0374C630 0x0374C660 0x0374C654), `anonymous namespace'::AsmParser::parseMSInlineAsm() + 0xF0 bytes(s), d:\src\llvm\lib\mc\mcparser\asmparser.cpp, line 4089 + 0xF byte(s)
0x01468B11 (0x0374CF9C 0x00000076 0x0374D074 0x0374E2D4), clang::Parser::ParseMicrosoftAsmStatement() + 0xAA1 bytes(s), d:\src\llvm\tools\clang\lib\parse\parsestmt.cpp, line 2139 + 0x6E byte(s)
0x01467844 (0x0374CF9C 0x0374CFF7 0x0374D0D8 0xCCCCCCCC), clang::Parser::ParseAsmStatement() + 0xC4 bytes(s), d:\src\llvm\tools\clang\lib\parse\parsestmt.cpp, line 2198 + 0x10 byte(s)

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2013

Adding support for

struct Foo { int a; };
__asm {
mov eax, [ebx]Foo.a
}

is also being tracked in rdar://14070479.

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2013

The assertion failure (infinite loop in NDEBUG build) is also being tracked by rdar://14070517

@nico
Copy link
Contributor

nico commented Sep 22, 2015

This basically works. The test cases in the last few comments work fine on trunk. There are bugs left (blockers of this bug, and others), but the feature basically exists. Marking this fixed.

@tritao
Copy link
Mannequin

tritao mannequin commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#13707

@llvmbot
Copy link
Member

llvmbot commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#15779

@rnk
Copy link
Collaborator

rnk commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#16830

@majnemer
Copy link
Mannequin

majnemer mannequin commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#17201

@tritao
Copy link
Mannequin

tritao mannequin commented Nov 26, 2021

mentioned in issue llvm/llvm-bugzilla-archive#19861

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++
Projects
None yet
Development

No branches or pull requests

5 participants