Correct immediate range for shifter operands. Patch by James Molloy, with additional...
authorOwen Anderson <resistor@mac.com>
Thu, 11 Aug 2011 18:41:59 +0000 (18:41 +0000)
committerOwen Anderson <resistor@mac.com>
Thu, 11 Aug 2011 18:41:59 +0000 (18:41 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137322 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp
test/MC/Disassembler/ARM/arm-tests.txt

index af04355e94f6b9189077b9496bab5f083f701927..67d39a3868487eea14f3031ad202ebf06ea9ce0b 100644 (file)
@@ -25,6 +25,16 @@ using namespace llvm;
 #define GET_INSTRUCTION_NAME
 #include "ARMGenAsmWriter.inc"
 
+/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
+///
+/// getSORegOffset returns an integer from 0-31, but '0' should actually be printed
+/// 32 as the immediate shouldbe within the range 1-32.
+static unsigned translateShiftImm(unsigned imm) {
+  if (imm == 0)
+    return 32;
+  return imm;
+}
+
 StringRef ARMInstPrinter::getOpcodeName(unsigned Opcode) const {
   return getInstructionName(Opcode);
 }
@@ -72,7 +82,7 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O) {
     if (ARM_AM::getSORegShOp(MO2.getImm()) == ARM_AM::rrx)
       return;
 
-    O << ", #" << ARM_AM::getSORegOffset(MO2.getImm());
+    O << ", #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm()));
     return;
   }
 
@@ -211,7 +221,7 @@ void ARMInstPrinter::printSORegImmOperand(const MCInst *MI, unsigned OpNum,
   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
   if (ShOpc == ARM_AM::rrx)
     return;
-  O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
+  O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm()));
 }
 
 
@@ -722,7 +732,7 @@ void ARMInstPrinter::printT2SOOperand(const MCInst *MI, unsigned OpNum,
   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
   if (ShOpc != ARM_AM::rrx)
-    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
+    O << " #" << translateShiftImm(ARM_AM::getSORegOffset(MO2.getImm()));
 }
 
 void ARMInstPrinter::printAddrModeImm12Operand(const MCInst *MI, unsigned OpNum,
index e047fb8615f24a459f760a621a9ba8dd2438d5ce..ee720d7dadad90561b7421c68b087ebaca8d457d 100644 (file)
@@ -1032,7 +1032,10 @@ getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
 
   // Encode shift_imm bit[11:7].
   Binary |= SBits << 4;
-  return Binary | ARM_AM::getSORegOffset(MO1.getImm()) << 7;
+  unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
+  assert(Offset && "Offset must be in range 1-32!");
+  if (Offset == 32) Offset = 0;
+  return Binary | (Offset << 7);
 }
 
 
index 52cd112629702538a6653f97222c94d5bda87e81..a6299895f99197a04e957b9654269ca5ca4f7af4 100644 (file)
 
 # CHECK:       nop
 0x00 0xf0 0x20 0xe3
+
+# CHECK:        andeq   r0, r0, r0, lsr #32
+0x20 0x00 0x00 0x00