From: Yunzhong Gao Date: Fri, 2 Sep 2016 23:15:29 +0000 (+0000) Subject: (LLVM part) Implement MASM-flavor intel syntax behavior for inline MS asm block: X-Git-Tag: llvmorg-4.0.0-rc1~10709 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=27ea29b3b74900be58b77eb148b61fe7f6d8d97f;p=platform%2Fupstream%2Fllvm.git (LLVM part) Implement MASM-flavor intel syntax behavior for inline MS asm block: 1. 0xNN and NNh are accepted as valid hexadecimal numbers, but 0xNNh is not. 0xNN and NNh may come with optional U or L suffix. 2. NNb is accepted as a valid binary (base-2) number, but 0bNN is not. NNb may come with optional U or L suffix. Differential Revision: https://reviews.llvm.org/D22112 llvm-svn: 280555 --- diff --git a/llvm/include/llvm/MC/MCParser/AsmLexer.h b/llvm/include/llvm/MC/MCParser/AsmLexer.h index c779121..06937e2 100644 --- a/llvm/include/llvm/MC/MCParser/AsmLexer.h +++ b/llvm/include/llvm/MC/MCParser/AsmLexer.h @@ -31,6 +31,7 @@ class AsmLexer : public MCAsmLexer { StringRef CurBuf; bool IsAtStartOfLine; bool IsAtStartOfStatement; + bool IsParsingMSInlineAsm; void operator=(const AsmLexer&) = delete; AsmLexer(const AsmLexer&) = delete; @@ -44,6 +45,7 @@ public: ~AsmLexer() override; void setBuffer(StringRef Buf, const char *ptr = nullptr); + void setParsingMSInlineAsm(bool V) { IsParsingMSInlineAsm = V; } StringRef LexUntilEndOfStatement() override; diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp index 71e3544..c1f71bc 100644 --- a/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -33,6 +33,7 @@ AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) { CurPtr = nullptr; IsAtStartOfLine = true; IsAtStartOfStatement = true; + IsParsingMSInlineAsm = false; AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } @@ -264,6 +265,45 @@ static AsmToken intToken(StringRef Ref, APInt &Value) /// 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; + } + + unsigned Radix = 0; + if (*CurPtr == 'h' || *CurPtr == 'H') { + // hexadecimal number + ++CurPtr; + Radix = 16; + } else if (FirstNonBinary && FirstNonBinary + 1 == CurPtr && + (*FirstNonBinary == 'b' || *FirstNonBinary == 'B')) + Radix = 2; + + if (Radix == 2 || Radix == 16) { + StringRef Result(TokStart, CurPtr - TokStart); + APInt Value(128, 0, true); + + if (Result.drop_back().getAsInteger(Radix, Value)) + return ReturnError(TokStart, Radix == 2 ? "invalid binary number" : + "invalid hexdecimal number"); + + // MSVC accepts and ignores type suffices on integer literals. + SkipIgnoredIntegerSuffix(CurPtr); + + 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); @@ -292,7 +332,7 @@ AsmToken AsmLexer::LexDigit() { 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])) { @@ -341,7 +381,7 @@ AsmToken AsmLexer::LexDigit() { return ReturnError(TokStart, "invalid hexadecimal number"); // Consume the optional [hH]. - if (*CurPtr == 'h' || *CurPtr == 'H') + if (!IsParsingMSInlineAsm && (*CurPtr == 'h' || *CurPtr == 'H')) ++CurPtr; // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 0315767..43c88c9 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -256,7 +256,10 @@ public: 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,