mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
(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
This commit is contained in:
parent
bb7aee52af
commit
18fe9799ec
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user