Index: include/llvm/MC/MCParser/MCAsmParser.h =================================================================== --- include/llvm/MC/MCParser/MCAsmParser.h +++ include/llvm/MC/MCParser/MCAsmParser.h @@ -197,6 +197,17 @@ /// \brief Ensure that we have a valid section set in the streamer. Otherwise, /// report an error and switch to .text. virtual void checkForValidSection() = 0; + + /// \brief Parse an arbitrary expression of a specified parenthesis depth, + /// assuming that the initial '(' characters have already been consumed. + /// + /// \param ParenDepth - Specifies how many trailing expressions outside the + /// current parentheses we have to parse. + /// \param Res - The value of the expression. The result is undefined + /// on error. + /// \return - False on success. + virtual bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, + SMLoc &EndLoc) = 0; }; /// \brief Create an MCAsmParser instance. Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -233,6 +233,8 @@ bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) override; bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override; bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) override; + bool parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, + SMLoc &EndLoc) override; bool parseAbsoluteExpression(int64_t &Res) override; /// \brief Parse an identifier or string (as a quoted identifier) @@ -1065,6 +1067,27 @@ return parseParenExpr(Res, EndLoc) || parseBinOpRHS(1, Res, EndLoc); } +bool AsmParser::parseParenExprOfDepth(unsigned ParenDepth, const MCExpr *&Res, + SMLoc &EndLoc) { + if (parseParenExpr(Res, EndLoc)) + return true; + + for (; ParenDepth > 0; --ParenDepth) { + if (parseBinOpRHS(1, Res, EndLoc)) + return true; + + // We don't Lex() the last RParen. + // This is the same behavior as parseParenExpression(). + if (ParenDepth - 1 > 0) { + if (Lexer.isNot(AsmToken::RParen)) + return TokError("expected ')' in parentheses expression"); + EndLoc = Lexer.getTok().getEndLoc(); + Lex(); + } + } + return false; +} + bool AsmParser::parseAbsoluteExpression(int64_t &Res) { const MCExpr *Expr; Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2758,9 +2758,12 @@ MCAsmParser &Parser = getParser(); SMLoc S; bool Result = true; + unsigned NumOfLParen = 0; - while (getLexer().getKind() == AsmToken::LParen) + while (getLexer().getKind() == AsmToken::LParen) { Parser.Lex(); + ++NumOfLParen; + } switch (getLexer().getKind()) { default: @@ -2771,7 +2774,7 @@ case AsmToken::Minus: case AsmToken::Plus: if (isParenExpr) - Result = getParser().parseParenExpression(Res, S); + Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S); else Result = (getParser().parseExpression(Res)); while (getLexer().getKind() == AsmToken::RParen) Index: test/MC/Mips/expr1.s =================================================================== --- test/MC/Mips/expr1.s +++ test/MC/Mips/expr1.s @@ -16,6 +16,11 @@ # 32R2-EL: # fixup A - offset: 0, value: foo@ABS_LO, kind: fixup_Mips_LO16 # 32R2-EL: lw $4, %lo(foo+8)($4) # encoding: [0x08'A',A,0x84,0x8c] # 32R2-EL: # fixup A - offset: 0, value: foo@ABS_LO, kind: fixup_Mips_LO16 +# 32R2-EL: lw $4, 10($4) # encoding: [0x0a,0x00,0x84,0x8c] +# 32R2-EL: lw $4, 15($4) # encoding: [0x0f,0x00,0x84,0x8c] +# 32R2-EL: lw $4, 21($4) # encoding: [0x15,0x00,0x84,0x8c] +# 32R2-EL: lw $4, 28($4) # encoding: [0x1c,0x00,0x84,0x8c] +# 32R2-EL: lw $4, 6($4) # encoding: [0x06,0x00,0x84,0x8c] # 32R2-EL: .space 64 # MM-32R2-EL: .text @@ -30,6 +35,11 @@ # MM-32R2-EL: # fixup A - offset: 0, value: foo@ABS_LO, kind: fixup_MICROMIPS_LO16 # MM-32R2-EL: lw $4, %lo(foo+8)($4) # encoding: [0x84'A',0xfc'A',0x08,0x00] # MM-32R2-EL: # fixup A - offset: 0, value: foo@ABS_LO, kind: fixup_MICROMIPS_LO16 +# MM-32R2-EL: lw $4, 10($4) # encoding: [0x84,0xfc,0x0a,0x00] +# MM-32R2-EL: lw $4, 15($4) # encoding: [0x84,0xfc,0x0f,0x00] +# MM-32R2-EL: lw $4, 21($4) # encoding: [0x84,0xfc,0x15,0x00] +# MM-32R2-EL: lw $4, 28($4) # encoding: [0x84,0xfc,0x1c,0x00] +# MM-32R2-EL: lw $4, 6($4) # encoding: [0x84,0xfc,0x06,0x00] # MM-32R2-EL: .space 64 .globl foo @@ -40,5 +50,10 @@ lw $4,%lo (2 * 4) + foo($4) lw $4,%lo((2 * 4) + foo)($4) lw $4,(((%lo ((2 * 4) + foo))))($4) + lw $4, (((1+2)+3)+4)($4) + lw $4, ((((1+2)+3)+4)+5)($4) + lw $4, (((((1+2)+3)+4)+5)+6)($4) + lw $4, ((((((1+2)+3)+4)+5)+6)+7)($4) + lw $4, (%lo((1+2)+65536)+3)($4) .space 64 .end foo