summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@imgtec.com>2016-10-18 15:17:17 +0000
committerSimon Dardis <simon.dardis@imgtec.com>2016-10-18 15:17:17 +0000
commit858915f054ef80a89d285ffb4b0a50e32b08defe (patch)
tree90881ce0c80a609a9beae24ed3016a7e6bd727fe /llvm/lib
parentaf6ff2a91bd65ae5ed417314713e24190e428a45 (diff)
downloadbcm5719-llvm-858915f054ef80a89d285ffb4b0a50e32b08defe.tar.gz
bcm5719-llvm-858915f054ef80a89d285ffb4b0a50e32b08defe.zip
[mips][ias] Handle more complicated expressions for memory operands
This patch teaches ias for mips to handle expressions such as (8*4)+(8*31)($sp). Such expression typically occur from the expansion of multiple macro definitions. This partially resolves PR/30383. Thanks to Sean Bruno for reporting the issue! Reviewers: zoran.jovanovic, vkalintiris Differential Revision: https://reviews.llvm.org/D24667 llvm-svn: 284485
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp56
1 files changed, 54 insertions, 2 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index ec8873289d6..70a5e50748b 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -4553,8 +4553,60 @@ MipsAsmParser::parseMemOperand(OperandVector &Operands) {
MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
return MatchOperand_Success;
}
- Error(Parser.getTok().getLoc(), "'(' expected");
- return MatchOperand_ParseFail;
+ MCBinaryExpr::Opcode Opcode;
+ // GAS and LLVM treat comparison operators different. GAS will generate -1
+ // or 0, while LLVM will generate 0 or 1. Since a comparsion operator is
+ // highly unlikely to be found in a memory offset expression, we don't
+ // handle them.
+ switch (Tok.getKind()) {
+ case AsmToken::Plus:
+ Opcode = MCBinaryExpr::Add;
+ Parser.Lex();
+ break;
+ case AsmToken::Minus:
+ Opcode = MCBinaryExpr::Sub;
+ Parser.Lex();
+ break;
+ case AsmToken::Star:
+ Opcode = MCBinaryExpr::Mul;
+ Parser.Lex();
+ break;
+ case AsmToken::Pipe:
+ Opcode = MCBinaryExpr::Or;
+ Parser.Lex();
+ break;
+ case AsmToken::Amp:
+ Opcode = MCBinaryExpr::And;
+ Parser.Lex();
+ break;
+ case AsmToken::LessLess:
+ Opcode = MCBinaryExpr::Shl;
+ Parser.Lex();
+ break;
+ case AsmToken::GreaterGreater:
+ Opcode = MCBinaryExpr::LShr;
+ Parser.Lex();
+ break;
+ case AsmToken::Caret:
+ Opcode = MCBinaryExpr::Xor;
+ Parser.Lex();
+ break;
+ case AsmToken::Slash:
+ Opcode = MCBinaryExpr::Div;
+ Parser.Lex();
+ break;
+ case AsmToken::Percent:
+ Opcode = MCBinaryExpr::Mod;
+ Parser.Lex();
+ break;
+ default:
+ Error(Parser.getTok().getLoc(), "'(' or expression expected");
+ return MatchOperand_ParseFail;
+ }
+ const MCExpr * NextExpr;
+ if (getParser().parseExpression(NextExpr))
+ return MatchOperand_ParseFail;
+ IdVal = MCBinaryExpr::create(Opcode, IdVal, NextExpr, getContext());
}
Parser.Lex(); // Eat the '(' token.
OpenPOWER on IntegriCloud