Index: include/llvm/MC/MCParser/AsmLexer.h =================================================================== --- include/llvm/MC/MCParser/AsmLexer.h +++ include/llvm/MC/MCParser/AsmLexer.h @@ -31,6 +31,7 @@ StringRef CurBuf; bool IsAtStartOfLine; bool IsAtStartOfStatement; + bool IsParsingMSInlineAsm; void operator=(const AsmLexer&) = delete; AsmLexer(const AsmLexer&) = delete; @@ -44,6 +45,7 @@ ~AsmLexer() override; void setBuffer(StringRef Buf, const char *ptr = nullptr); + void setParsingMSInlineAsm(bool V) { IsParsingMSInlineAsm = V; } StringRef LexUntilEndOfStatement() override; Index: lib/MC/MCParser/AsmLexer.cpp =================================================================== --- lib/MC/MCParser/AsmLexer.cpp +++ lib/MC/MCParser/AsmLexer.cpp @@ -28,6 +28,7 @@ CurPtr = nullptr; IsAtStartOfLine = true; IsAtStartOfStatement = true; + IsParsingMSInlineAsm = false; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } @@ -258,6 +259,41 @@ /// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH] /// Decimal integer: [1-9][0-9]* AsmToken AsmLexer::LexDigit() { + // MASM-flavor binary integer: [01]+[bB] + // MASM-flavor hexadecimal integer: [0-9][0-9a-fA-F]*[hH] + if (IsParsingMSInlineAsm && isdigit(CurPtr[-1])) { + const char *FirstNonBinary = (CurPtr[-1] != '0' && CurPtr[-1] != '1') ? + CurPtr - 1 : nullptr; + const char *OldCurPtr = CurPtr; + while (isxdigit(*CurPtr)) { + if (*CurPtr != '0' && *CurPtr != '1' && !FirstNonBinary) + FirstNonBinary = CurPtr; + ++CurPtr; + } + + if (*CurPtr == 'h' || *CurPtr == 'H') { + // hexadecimal number + StringRef Result(TokStart, CurPtr + 1 - TokStart); + APInt Value(128, 0, true); + if (Result.drop_back().getAsInteger(16, Value)) + return ReturnError(TokStart, "invalid hexdecimal number"); + ++CurPtr; + return intToken(Result, Value); + } + if (FirstNonBinary && FirstNonBinary + 1 == CurPtr && + (*FirstNonBinary == 'b' || *FirstNonBinary == 'B')) { + // binary number + StringRef Result(TokStart, CurPtr - TokStart); + APInt Value(128, 0, true); + if (Result.drop_back().getAsInteger(2, Value)) + return ReturnError(TokStart, "invalid binary number"); + return intToken(Result, Value); + } + + // octal/decimal integers, or floating point numbers, fall through + CurPtr = OldCurPtr; + } + // Decimal integer: [1-9][0-9]* if (CurPtr[-1] != '0' || CurPtr[0] == '.') { unsigned Radix = doLookAhead(CurPtr, 10); @@ -286,7 +322,7 @@ return intToken(Result, Value); } - if ((*CurPtr == 'b') || (*CurPtr == 'B')) { + if (!IsParsingMSInlineAsm && ((*CurPtr == 'b') || (*CurPtr == 'B'))) { ++CurPtr; // See if we actually have "0b" as part of something like "jmp 0b\n" if (!isdigit(CurPtr[0])) { @@ -315,7 +351,7 @@ return intToken(Result, Value); } - if ((*CurPtr == 'x') || (*CurPtr == 'X')) { + if (!IsParsingMSInlineAsm && ((*CurPtr == 'x') || (*CurPtr == 'X'))) { ++CurPtr; const char *NumStart = CurPtr; while (isxdigit(CurPtr[0])) Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -231,7 +231,10 @@ const AsmToken &Lex() override; - void setParsingInlineAsm(bool V) override { ParsingInlineAsm = V; } + void setParsingInlineAsm(bool V) override { + ParsingInlineAsm = V; + Lexer.setParsingMSInlineAsm(V); + } bool isParsingInlineAsm() override { return ParsingInlineAsm; } bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, Index: tools/clang/test/CodeGen/ms-inline-asm.c =================================================================== --- tools/clang/test/CodeGen/ms-inline-asm.c +++ tools/clang/test/CodeGen/ms-inline-asm.c @@ -40,23 +40,23 @@ } void t6(void) { - __asm int 0x2c + __asm int 2ch // CHECK: t6 -// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "int $$2ch", "~{dirflag},~{fpsr},~{flags}"() } void t7() { __asm { - int 0x2c ; } asm comments are fun! }{ + int 2ch ; } asm comments are fun! }{ } __asm { { - int 0x2c ; } asm comments are fun! }{ + int 2ch ; } asm comments are fun! }{ } } __asm {} // CHECK: t7 -// CHECK: call void asm sideeffect inteldialect "int $$0x2c", "~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "int $$2ch", "~{dirflag},~{fpsr},~{flags}"() // CHECK: call void asm sideeffect inteldialect "", "~{dirflag},~{fpsr},~{flags}"() } @@ -82,11 +82,11 @@ void t9() { __asm { push ebx - { mov ebx, 0x07 } + { mov ebx, 07h } __asm { pop ebx } } // CHECK: t9 -// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx\0A\09", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$07h\0A\09pop ebx\0A\09", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() } unsigned t10(void) { @@ -169,14 +169,14 @@ void t17() { // CHECK: t17 - __asm _emit 0x4A -// CHECK: .byte 0x4A - __asm _emit 0x43 -// CHECK: .byte 0x43 - __asm _emit 0x4B -// CHECK: .byte 0x4B - __asm _EMIT 0x4B -// CHECK: .byte 0x4B + __asm _emit 4AH +// CHECK: .byte 4AH + __asm _emit 43H +// CHECK: .byte 43H + __asm _emit 4BH +// CHECK: .byte 4BH + __asm _EMIT 4BH +// CHECK: .byte 4BH // CHECK: "~{dirflag},~{fpsr},~{flags}"() } @@ -219,11 +219,11 @@ void t21() { __asm { __asm push ebx - __asm mov ebx, 0x07 + __asm mov ebx, 07h __asm pop ebx } // CHECK: t21 -// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$0x07\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() +// CHECK: call void asm sideeffect inteldialect "push ebx\0A\09mov ebx, $$07h\0A\09pop ebx", "~{ebx},~{esp},~{dirflag},~{fpsr},~{flags}"() } extern void t22_helper(int x); @@ -262,15 +262,15 @@ void t25() { // CHECK: t25 __asm mov eax, 0ffffffffh -// CHECK: mov eax, $$4294967295 +// CHECK: mov eax, $$0ffffffffh __asm mov eax, 0fh -// CHECK: mov eax, $$15 +// CHECK: mov eax, $$0fh __asm mov eax, 0a2h -// CHECK: mov eax, $$162 - __asm mov eax, 0xa2h -// CHECK: mov eax, $$0xa2h - __asm mov eax, 0xa2 -// CHECK: mov eax, $$0xa2 +// CHECK: mov eax, $$0a2h + __asm mov eax, 10100010b +// CHECK: mov eax, $$10100010b + __asm mov eax, 10100010B +// CHECK: mov eax, $$10100010B // CHECK: "~{eax},~{dirflag},~{fpsr},~{flags}"() } Index: tools/clang/test/CodeGenCXX/ms-inline-asm-return.cpp =================================================================== --- tools/clang/test/CodeGenCXX/ms-inline-asm-return.cpp +++ tools/clang/test/CodeGenCXX/ms-inline-asm-return.cpp @@ -50,8 +50,8 @@ bool f_i1() { __asm { - mov eax, 1 - mov edx, 1 + mov eax, 1L + mov edx, 1U } } // CHECK-LABEL: define zeroext i1 @f_i1() @@ -66,11 +66,11 @@ }; FourChars f_s4() { __asm { - mov eax, 0x01010101 + mov eax, 01010101h } } // CHECK-LABEL: define i32 @f_s4() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$0x01010101", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$01010101h", "={eax},~{eax},{{.*}}" // CHECK: store i32 %[[r]], i32* %{{.*}} // CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}} // CHECK: ret i32 %[[r_i32]] @@ -80,12 +80,12 @@ }; EightChars f_s8() { __asm { - mov eax, 0x01010101 - mov edx, 0x01010101 + mov eax, 01010101h + mov edx, 01010101h } } // CHECK-LABEL: define i64 @f_s8() -// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$0x01010101\0A\09mov edx, $$0x01010101", "=A,~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$01010101h\0A\09mov edx, $$01010101h", "=A,~{eax},{{.*}}" // CHECK: store i64 %[[r]], i64* %{{.*}} // CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}} // CHECK: ret i64 %[[r_i64]] Index: tools/clang/test/Parser/ms-inline-asm.c =================================================================== --- tools/clang/test/Parser/ms-inline-asm.c +++ tools/clang/test/Parser/ms-inline-asm.c @@ -3,16 +3,16 @@ // Disabling gnu inline assembly should have no effect on this testcase // RUN: %clang_cc1 %s -triple i386-apple-darwin10 -verify -fasm-blocks -fno-gnu-inline-asm -#define M __asm int 0x2c +#define M __asm int 2ch #define M2 int void t1(void) { M } -void t2(void) { __asm int 0x2c } -void t3(void) { __asm M2 0x2c } -void t4(void) { __asm mov eax, fs:[0x10] } +void t2(void) { __asm int 2ch } +void t3(void) { __asm M2 2ch } +void t4(void) { __asm mov eax, fs:[10h] } void t5() { __asm { - int 0x2c ; } asm comments are fun! }{ + int 2ch ; } asm comments are fun! }{ } __asm {} } @@ -26,7 +26,7 @@ void t7() { __asm { push ebx - mov ebx, 0x07 + mov ebx, 07h pop ebx } }