summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-11-03 01:49:29 +0000
committerBill Wendling <isanbard@gmail.com>2010-11-03 01:49:29 +0000
commite84eb99cbb5dbb0f8c9397a1a730246c1188ca30 (patch)
tree4d027d5daa2a3db28cab108b4a771900f3b704f7 /llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
parent68fb004616a5410033b2ad8d2b42fcd8977e6874 (diff)
downloadbcm5719-llvm-e84eb99cbb5dbb0f8c9397a1a730246c1188ca30.tar.gz
bcm5719-llvm-e84eb99cbb5dbb0f8c9397a1a730246c1188ca30.zip
The MC code couldn't handle ARM LDR instructions with negative offsets:
vldr.64 d1, [r0, #-32] The problem was with how the addressing mode 5 encodes the offsets. This change makes sure that the way offsets are handled in addressing mode 5 is consistent throughout the MC code. It involves re-refactoring the "getAddrModeImmOpValue" method into an "Imm12" and "addressing mode 5" version. But not to worry! The majority of the duplicated code has been unified. llvm-svn: 118144
Diffstat (limited to 'llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 4552374bcc7..f5dc38bcfed 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "ARM.h"
+#include "ARMAddressingModes.h"
#include "ARMSubtarget.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
@@ -260,16 +261,25 @@ public:
Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
assert(!Mem.OffsetIsReg && "invalid mode 5 operand");
+
// 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!");
+ 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
+ int64_t Offset = CE->getValue() / 4;
+ if (Offset >= 0)
+ Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add,
+ Offset)));
+ else
+ Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub,
+ -Offset)));
+ } else {
Inst.addOperand(MCOperand::CreateImm(0));
+ }
}
virtual void dump(raw_ostream &OS) const;
OpenPOWER on IntegriCloud