diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index af04355e94f..67d39a38684 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -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, diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index e047fb8615f..ee720d7dada 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -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); } diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt index 52cd1126297..a6299895f99 100644 --- a/test/MC/Disassembler/ARM/arm-tests.txt +++ b/test/MC/Disassembler/ARM/arm-tests.txt @@ -302,3 +302,6 @@ # CHECK: nop 0x00 0xf0 0x20 0xe3 + +# CHECK: andeq r0, r0, r0, lsr #32 +0x20 0x00 0x00 0x00