diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-10-29 17:41:25 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-10-29 17:41:25 +0000 |
commit | 80eb233a3ce1a6f2e6c0847cb3e456d735e37569 (patch) | |
tree | 3d55cb47c2ed981332806053751e58d855b72aab /lib | |
parent | 8a8e26fb1867b45ab7c5832dc3f509127d6624b8 (diff) | |
download | llvm-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.cpp | 33 |
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; |