diff options
author | Yunzhong Gao <Yunzhong.Gao@sony.com> | 2016-09-02 23:15:29 +0000 |
---|---|---|
committer | Yunzhong Gao <Yunzhong.Gao@sony.com> | 2016-09-02 23:15:29 +0000 |
commit | 27ea29b3b74900be58b77eb148b61fe7f6d8d97f (patch) | |
tree | 0afe390aa690dcd3a1979db0db63912dd943335e /llvm/lib | |
parent | b1000c39a0cbeee76cae796e53a1eb16854e633d (diff) | |
download | bcm5719-llvm-27ea29b3b74900be58b77eb148b61fe7f6d8d97f.tar.gz bcm5719-llvm-27ea29b3b74900be58b77eb148b61fe7f6d8d97f.zip |
(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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCParser/AsmLexer.cpp | 44 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 5 |
2 files changed, 46 insertions, 3 deletions
diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp index 71e35448919..c1f71bcc368 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 03157671da1..43c88c96860 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, |