summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/InstPrinter
diff options
context:
space:
mode:
authorTim Northover <Tim.Northover@arm.com>2012-09-22 11:18:12 +0000
committerTim Northover <Tim.Northover@arm.com>2012-09-22 11:18:12 +0000
commit93c7c449a1351542fa5a275587187154dbedb8e0 (patch)
tree090aa4c36f20481371bbe181268f9adf30736a57 /lib/Target/ARM/InstPrinter
parent23bd47c2d6d3c0735736bd0994ae116f534d9992 (diff)
downloadllvm-93c7c449a1351542fa5a275587187154dbedb8e0.tar.gz
llvm-93c7c449a1351542fa5a275587187154dbedb8e0.tar.bz2
llvm-93c7c449a1351542fa5a275587187154dbedb8e0.tar.xz
Fix the handling of edge cases in ARM shifted operands.
This patch fixes load/store instructions to handle less common cases like "asr #32", "rrx" properly throughout the MC layer. Patch by Chris Lidbury. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164455 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/InstPrinter')
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index 8b9109ec98..60f92f82d4 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -29,11 +29,27 @@ using namespace llvm;
///
/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
static unsigned translateShiftImm(unsigned imm) {
+ // lsr #32 and asr #32 exist, but should be encoded as a 0.
+ assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
+
if (imm == 0)
return 32;
return imm;
}
+/// Prints the shift value with an immediate value.
+static void printRegImmShift(raw_ostream &O, ARM_AM::ShiftOpc ShOpc,
+ unsigned ShImm) {
+ if (ShOpc == ARM_AM::no_shift || (ShOpc == ARM_AM::lsl && !ShImm))
+ return;
+ O << ", ";
+
+ assert (!(ShOpc == ARM_AM::ror && !ShImm) && "Cannot have ror #0");
+ O << getShiftOpcStr(ShOpc);
+
+ if (ShOpc != ARM_AM::rrx)
+ O << " #" << translateShiftImm(ShImm);
+}
ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI,
const MCInstrInfo &MII,
@@ -319,10 +335,8 @@ void ARMInstPrinter::printAM2PreOrOffsetIndexOp(const MCInst *MI, unsigned Op,
<< ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
<< getRegisterName(MO2.getReg());
- if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
- O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
- << " #" << ShImm;
+ printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO3.getImm()),
+ ARM_AM::getAM2Offset(MO3.getImm()));
O << "]";
}
@@ -403,10 +417,8 @@ void ARMInstPrinter::printAddrMode2OffsetOperand(const MCInst *MI,
O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
<< getRegisterName(MO1.getReg());
- if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
- O << ", "
- << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
- << " #" << ShImm;
+ printRegImmShift(O, ARM_AM::getAM2ShiftOpc(MO2.getImm()),
+ ARM_AM::getAM2Offset(MO2.getImm()));
}
//===--------------------------------------------------------------------===//