1
0
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:
Yunzhong Gao 2016-09-02 23:15:29 +00:00
parent bb7aee52af
commit 18fe9799ec
3 changed files with 48 additions and 3 deletions

View File

@ -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;

View File

@ -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

View File

@ -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,