summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-10-29 17:41:25 +0000
committerJim Grosbach <grosbach@apple.com>2010-10-29 17:41:25 +0000
commit80eb233a3ce1a6f2e6c0847cb3e456d735e37569 (patch)
tree3d55cb47c2ed981332806053751e58d855b72aab /lib
parent8a8e26fb1867b45ab7c5832dc3f509127d6624b8 (diff)
downloadllvm-80eb233a3ce1a6f2e6c0847cb3e456d735e37569.tar.gz
llvm-80eb233a3ce1a6f2e6c0847cb3e456d735e37569.tar.bz2
llvm-80eb233a3ce1a6f2e6c0847cb3e456d735e37569.tar.xz
Handle ARM addrmode5 instructions with an offset.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index b09dcd080f..9bcced35f9 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -236,12 +236,18 @@ public:
bool isMemMode5() const {
- // FIXME: Is this right? What about postindexed and Writeback?
if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
- Mem.Preindexed || Mem.Negative)
+ Mem.Writeback || Mem.Negative)
return false;
-
- return true;
+ // If there is an offset expression, make sure it's valid.
+ if (!Mem.Offset)
+ return true;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+ if (!CE)
+ return false;
+ // The offset must be a multiple of 4 in the range 0-1020.
+ int64_t Value = CE->getValue();
+ return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
}
void addMemMode5Operands(MCInst &Inst, unsigned N) const {
@@ -249,7 +255,16 @@ public:
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
assert(!Mem.OffsetIsReg && "invalid mode 5 operand");
- addExpr(Inst, Mem.Offset);
+ // FIXME: #-0 is encoded differently than #0. Does the parser preserve
+ // the difference?
+ if (Mem.Offset) {
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+ assert (CE && "non-constant mode 5 offset operand!");
+ // The MCInst offset operand doesn't include the low two bits (like
+ // the instruction encoding).
+ Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+ } else
+ Inst.addOperand(MCOperand::CreateImm(0));
}
virtual void dump(raw_ostream &OS) const;
@@ -513,10 +528,8 @@ ARMOperand *ARMAsmParser::ParseMemory() {
}
// The "[Rn" we have so far was not followed by a comma.
else if (Tok.is(AsmToken::RBrac)) {
- // This is a post indexing addressing forms, that is a ']' follows after
- // the "[Rn".
- Postindexed = true;
- Writeback = true;
+ // If there's anything other than the right brace, this is a post indexing
+ // addressing form.
E = Tok.getLoc();
Parser.Lex(); // Eat right bracket token.
@@ -528,6 +541,8 @@ ARMOperand *ARMAsmParser::ParseMemory() {
const AsmToken &NextTok = Parser.getTok();
if (NextTok.isNot(AsmToken::EndOfStatement)) {
+ Postindexed = true;
+ Writeback = true;
if (NextTok.isNot(AsmToken::Comma)) {
Error(NextTok.getLoc(), "',' expected");
return 0;