diff options
Diffstat (limited to 'tools/llvm-mc/AsmParser.cpp')
-rw-r--r-- | tools/llvm-mc/AsmParser.cpp | 60 |
1 files changed, 57 insertions, 3 deletions
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 715ff39..9e8b3cf 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -168,7 +168,9 @@ bool AsmParser::ParseX86MemOperand(X86Operand &Op) { // memory operand consumed. } else { // It must be an parenthesized expression, parse it now. - if (ParseParenExpr(Disp)) return true; + if (ParseParenExpr(Disp) || + ParseBinOpRHS(1, Disp)) + return true; // After parsing the base expression we could either have a parenthesized // memory address or not. If not, return now. If so, eat the (. @@ -274,9 +276,61 @@ bool AsmParser::ParsePrimaryExpr(int64_t &Res) { /// expr ::= primaryexpr /// bool AsmParser::ParseExpression(int64_t &Res) { - return ParsePrimaryExpr(Res); + return ParsePrimaryExpr(Res) || + ParseBinOpRHS(1, Res); } - + +static unsigned getBinOpPrecedence(asmtok::TokKind K) { + switch (K) { + default: return 0; // not a binop. + case asmtok::Plus: + case asmtok::Minus: + return 1; + case asmtok::Pipe: + case asmtok::Caret: + case asmtok::Amp: + case asmtok::Exclaim: + return 2; + case asmtok::Star: + case asmtok::Slash: + case asmtok::Percent: + case asmtok::LessLess: + case asmtok::GreaterGreater: + return 3; + } +} + + +/// ParseBinOpRHS - Parse all binary operators with precedence >= 'Precedence'. +/// Res contains the LHS of the expression on input. +bool AsmParser::ParseBinOpRHS(unsigned Precedence, int64_t &Res) { + while (1) { + unsigned TokPrec = getBinOpPrecedence(Lexer.getKind()); + + // If the next token is lower precedence than we are allowed to eat, return + // successfully with what we ate already. + if (TokPrec < Precedence) + return false; + + //asmtok::TokKind BinOp = Lexer.getKind(); + Lexer.Lex(); + + // Eat the next primary expression. + int64_t RHS; + if (ParsePrimaryExpr(RHS)) return true; + + // If BinOp binds less tightly with RHS than the operator after RHS, let + // the pending operator take RHS as its LHS. + unsigned NextTokPrec = getBinOpPrecedence(Lexer.getKind()); + if (TokPrec < NextTokPrec) { + if (ParseBinOpRHS(Precedence+1, RHS)) return true; + } + + // Merge LHS/RHS: fixme use the right operator etc. + Res += RHS; + } +} + |