Unify internal representation of ARM instructions with a register right-shifted by #32. These are stored as shifts by #0 in the MCInst and correctly marshalled when transforming from or to assembly representation.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155565 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Barton 2012-04-25 18:00:18 +00:00
parent bdbf015476
commit b56e4115ed
2 changed files with 10 additions and 4 deletions

View File

@ -1446,8 +1446,10 @@ public:
assert(isRegShiftedImm() && assert(isRegShiftedImm() &&
"addRegShiftedImmOperands() on non RegShiftedImm!"); "addRegShiftedImmOperands() on non RegShiftedImm!");
Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg)); Inst.addOperand(MCOperand::CreateReg(RegShiftedImm.SrcReg));
// Shift of #32 is encoded as 0 where permitted
unsigned Imm = (RegShiftedImm.ShiftImm == 32 ? 0 : RegShiftedImm.ShiftImm);
Inst.addOperand(MCOperand::CreateImm( Inst.addOperand(MCOperand::CreateImm(
ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm))); ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, Imm)));
} }
void addShifterImmOperands(MCInst &Inst, unsigned N) const { void addShifterImmOperands(MCInst &Inst, unsigned N) const {
@ -6809,6 +6811,9 @@ processInstruction(MCInst &Inst,
// A shift by zero is a plain MOVr, not a MOVsi. // A shift by zero is a plain MOVr, not a MOVsi.
unsigned Amt = Inst.getOperand(2).getImm(); unsigned Amt = Inst.getOperand(2).getImm();
unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi; unsigned Opc = Amt == 0 ? ARM::MOVr : ARM::MOVsi;
// A shift by 32 should be encoded as 0 when permitted
if (Amt == 32 && (ShiftTy == ARM_AM::lsr || ShiftTy == ARM_AM::asr))
Amt = 0;
unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt); unsigned Shifter = ARM_AM::getSORegOpc(ShiftTy, Amt);
MCInst TmpInst; MCInst TmpInst;
TmpInst.setOpcode(Opc); TmpInst.setOpcode(Opc);
@ -7154,7 +7159,9 @@ processInstruction(MCInst &Inst,
} }
case ARM::MOVsi: { case ARM::MOVsi: {
ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm()); ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(2).getImm());
if (SOpc == ARM_AM::rrx) return false; // rrx shifts and asr/lsr of #32 is encoded as 0
if (SOpc == ARM_AM::rrx || SOpc == ARM_AM::asr || SOpc == ARM_AM::lsr)
return false;
if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) { if (ARM_AM::getSORegOffset(Inst.getOperand(2).getImm()) == 0) {
// Shifting by zero is accepted as a vanilla 'MOVr' // Shifting by zero is accepted as a vanilla 'MOVr'
MCInst TmpInst; MCInst TmpInst;

View File

@ -1192,8 +1192,7 @@ getSORegImmOpValue(const MCInst &MI, unsigned OpIdx,
// Encode shift_imm bit[11:7]. // Encode shift_imm bit[11:7].
Binary |= SBits << 4; Binary |= SBits << 4;
unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm());
assert(Offset && "Offset must be in range 1-32!"); assert(Offset < 32 && "Offset must be in range 0-31!");
if (Offset == 32) Offset = 0;
return Binary | (Offset << 7); return Binary | (Offset << 7);
} }