Change ARM PKHTB and PKHBT instructions to use a shift_imm operand to avoid

printing "lsl #0".  This fixes the remaining parts of pr7792.  Make
corresponding changes for encoding/decoding these instructions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111251 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2010-08-17 17:23:19 +00:00
parent 087fbeb7d1
commit f955f290c9
9 changed files with 79 additions and 41 deletions

View File

@ -1227,6 +1227,11 @@ void ARMCodeEmitter::emitMiscArithInstruction(const MachineInstr &MI) {
// Encode shift_imm. // Encode shift_imm.
unsigned ShiftAmt = MI.getOperand(OpIdx).getImm(); unsigned ShiftAmt = MI.getOperand(OpIdx).getImm();
if (TID.Opcode == ARM::PKHTB) {
assert(ShiftAmt != 0 && "PKHTB shift_imm is 0!");
if (ShiftAmt == 32)
ShiftAmt = 0;
}
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!"); assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
Binary |= ShiftAmt << ARMII::ShiftShift; Binary |= ShiftAmt << ARMII::ShiftShift;

View File

@ -2240,11 +2240,20 @@ def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
let Inst{19-16} = 0b1111; let Inst{19-16} = 0b1111;
} }
def lsl_shift_imm : SDNodeXForm<imm, [{
unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::lsl, N->getZExtValue());
return CurDAG->getTargetConstant(Sh, MVT::i32);
}]>;
def lsl_amt : PatLeaf<(i32 imm), [{
return (N->getZExtValue() < 32);
}], lsl_shift_imm>;
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst), def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt), (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt", IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF), [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
(and (shl GPR:$src2, (i32 imm:$shamt)), (and (shl GPR:$src2, lsl_amt:$sh),
0xFFFF0000)))]>, 0xFFFF0000)))]>,
Requires<[IsARM, HasV6]> { Requires<[IsARM, HasV6]> {
let Inst{6-4} = 0b001; let Inst{6-4} = 0b001;
@ -2253,28 +2262,37 @@ def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
// Alternate cases for PKHBT where identities eliminate some nodes. // Alternate cases for PKHBT where identities eliminate some nodes.
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)), def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
(PKHBT GPR:$src1, GPR:$src2, 0)>; (PKHBT GPR:$src1, GPR:$src2, 0)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)), def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$sh)),
(PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>; (PKHBT GPR:$src1, GPR:$src2, (lsl_shift_imm imm16_31:$sh))>;
def asr_shift_imm : SDNodeXForm<imm, [{
unsigned Sh = ARM_AM::getSORegOpc(ARM_AM::asr, N->getZExtValue());
return CurDAG->getTargetConstant(Sh, MVT::i32);
}]>;
def asr_amt : PatLeaf<(i32 imm), [{
return (N->getZExtValue() <= 32);
}], asr_shift_imm>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below. // will match the pattern below.
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst), def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt), (ins GPR:$src1, GPR:$src2, shift_imm:$sh),
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt", IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2$sh",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000), [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
(and (sra GPR:$src2, imm16_31:$shamt), (and (sra GPR:$src2, asr_amt:$sh),
0xFFFF)))]>, Requires<[IsARM, HasV6]> { 0xFFFF)))]>,
Requires<[IsARM, HasV6]> {
let Inst{6-4} = 0b101; let Inst{6-4} = 0b101;
} }
// Alternate cases for PKHTB where identities eliminate some nodes. Note that // Alternate cases for PKHTB where identities eliminate some nodes. Note that
// a shift amount of 0 is *not legal* here, it is PKHBT instead. // a shift amount of 0 is *not legal* here, it is PKHBT instead.
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)), def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, imm16_31:$sh)),
(PKHTB GPR:$src1, GPR:$src2, imm16_31:$sh)>; (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)), (and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
(PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>; (PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Comparison Instructions... // Comparison Instructions...

View File

@ -2085,10 +2085,10 @@ def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
(or (srl (and rGPR:$src, 0xFF00), (i32 8)), (or (srl (and rGPR:$src, 0xFF00), (i32 8)),
(shl rGPR:$src, (i32 8))), i16))]>; (shl rGPR:$src, (i32 8))), i16))]>;
def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, i32imm:$shamt), def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, lsl $shamt", IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2$sh",
[(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF), [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
(and (shl rGPR:$src2, (i32 imm:$shamt)), (and (shl rGPR:$src2, lsl_amt:$sh),
0xFFFF0000)))]>, 0xFFFF0000)))]>,
Requires<[HasT2ExtractPack]> { Requires<[HasT2ExtractPack]> {
let Inst{31-27} = 0b11101; let Inst{31-27} = 0b11101;
@ -2102,17 +2102,17 @@ def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, i32imm:$shamt),
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)), def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
(t2PKHBT rGPR:$src1, rGPR:$src2, 0)>, (t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
Requires<[HasT2ExtractPack]>; Requires<[HasT2ExtractPack]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$shamt)), def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
(t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$shamt)>, (t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
Requires<[HasT2ExtractPack]>; Requires<[HasT2ExtractPack]>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below. // will match the pattern below.
def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, i32imm:$shamt), def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, asr $shamt", IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2$sh",
[(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000), [(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
(and (sra rGPR:$src2, imm16_31:$shamt), (and (sra rGPR:$src2, asr_amt:$sh),
0xFFFF)))]>, 0xFFFF)))]>,
Requires<[HasT2ExtractPack]> { Requires<[HasT2ExtractPack]> {
let Inst{31-27} = 0b11101; let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01; let Inst{26-25} = 0b01;
@ -2124,11 +2124,11 @@ def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, i32imm:$shamt),
// Alternate cases for PKHTB where identities eliminate some nodes. Note that // Alternate cases for PKHTB where identities eliminate some nodes. Note that
// a shift amount of 0 is *not legal* here, it is PKHBT instead. // a shift amount of 0 is *not legal* here, it is PKHBT instead.
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)), def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>, (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
Requires<[HasT2ExtractPack]>; Requires<[HasT2ExtractPack]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
(and (srl rGPR:$src2, imm1_15:$shamt), 0xFFFF)), (and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
(t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$shamt)>, (t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
Requires<[HasT2ExtractPack]>; Requires<[HasT2ExtractPack]>;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -456,12 +456,20 @@ static inline ARM_AM::ShiftOpc getShiftOpcForBits(unsigned bits) {
// //
// A8-11: DecodeImmShift() // A8-11: DecodeImmShift()
static inline void getImmShiftSE(ARM_AM::ShiftOpc &ShOp, unsigned &ShImm) { static inline void getImmShiftSE(ARM_AM::ShiftOpc &ShOp, unsigned &ShImm) {
// If type == 0b11 and imm5 == 0, we have an rrx, instead. if (ShImm != 0)
if (ShOp == ARM_AM::ror && ShImm == 0) return;
ShOp = ARM_AM::rrx; switch (ShOp) {
// If (lsr or asr) and imm5 == 0, shift amount is 32. case ARM_AM::lsl:
if ((ShOp == ARM_AM::lsr || ShOp == ARM_AM::asr) && ShImm == 0) ShOp = ARM_AM::no_shift;
break;
case ARM_AM::lsr:
case ARM_AM::asr:
ShImm = 32; ShImm = 32;
break;
case ARM_AM::ror:
ShOp = ARM_AM::rrx;
break;
}
} }
// getAMSubModeForBits - getAMSubModeForBits translates from the ARM encoding // getAMSubModeForBits - getAMSubModeForBits translates from the ARM encoding
@ -1445,7 +1453,13 @@ static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
&& !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) { && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
// Extract the 5-bit immediate field Inst{11-7}. // Extract the 5-bit immediate field Inst{11-7}.
unsigned ShiftAmt = (insn >> ARMII::ShiftShift) & 0x1F; unsigned ShiftAmt = (insn >> ARMII::ShiftShift) & 0x1F;
MI.addOperand(MCOperand::CreateImm(ShiftAmt)); ARM_AM::ShiftOpc Opc = ARM_AM::no_shift;
if (Opcode == ARM::PKHBT)
Opc = ARM_AM::lsl;
else if (Opcode == ARM::PKHBT)
Opc = ARM_AM::asr;
getImmShiftSE(Opc, ShiftAmt);
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShiftAmt)));
++OpIdx; ++OpIdx;
} }

View File

@ -220,7 +220,7 @@ static inline unsigned decodeImmShift(unsigned bits2, unsigned imm5,
switch (bits2) { switch (bits2) {
default: assert(0 && "No such value"); default: assert(0 && "No such value");
case 0: case 0:
ShOp = ARM_AM::lsl; ShOp = (imm5 == 0 ? ARM_AM::no_shift : ARM_AM::lsl);
return imm5; return imm5;
case 1: case 1:
ShOp = ARM_AM::lsr; ShOp = ARM_AM::lsr;
@ -1389,14 +1389,7 @@ static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned imm5 = getShiftAmtBits(insn); unsigned imm5 = getShiftAmtBits(insn);
ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift; ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp); unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
// PKHBT/PKHTB are special in that we need the decodeImmShift() call to
// decode the shift amount from raw imm5 and bits2, but we DO NOT need
// to encode the ShOp, as it's in the asm string already.
if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
MI.addOperand(MCOperand::CreateImm(ShAmt));
else
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
} }
++OpIdx; ++OpIdx;
} }

View File

@ -38,7 +38,7 @@ define i32 @test3(i32 %X, i32 %Y) {
} }
; CHECK: test4 ; CHECK: test4
; CHECK: pkhbt r0, r0, r1, lsl #0 ; CHECK: pkhbt r0, r0, r1
define i32 @test4(i32 %X, i32 %Y) { define i32 @test4(i32 %X, i32 %Y) {
%tmp1 = and i32 %X, 65535 ; <i32> [#uses=1] %tmp1 = and i32 %X, 65535 ; <i32> [#uses=1]
%tmp3 = and i32 %Y, -65536 ; <i32> [#uses=1] %tmp3 = and i32 %Y, -65536 ; <i32> [#uses=1]

View File

@ -38,7 +38,7 @@ define i32 @test3(i32 %X, i32 %Y) {
} }
; CHECK: test4 ; CHECK: test4
; CHECK: pkhbt r0, r0, r1, lsl #0 ; CHECK: pkhbt r0, r0, r1
define i32 @test4(i32 %X, i32 %Y) { define i32 @test4(i32 %X, i32 %Y) {
%tmp1 = and i32 %X, 65535 ; <i32> [#uses=1] %tmp1 = and i32 %X, 65535 ; <i32> [#uses=1]
%tmp3 = and i32 %Y, -65536 ; <i32> [#uses=1] %tmp3 = and i32 %Y, -65536 ; <i32> [#uses=1]

View File

@ -61,6 +61,10 @@
# CHECK: pkhbt r8, r9, r10, lsl #4 # CHECK: pkhbt r8, r9, r10, lsl #4
0x1a 0x82 0x89 0xe6 0x1a 0x82 0x89 0xe6
# CHECK-NOT: pkhbtls pc, r11, r11, lsl #0
# CHECK: pkhbtls pc, r11, r11
0x1b 0xf0 0x8b 0x96
# CHECK: pop {r0, r2, r4, r6, r8, r10} # CHECK: pop {r0, r2, r4, r6, r8, r10}
0x55 0x05 0xbd 0xe8 0x55 0x05 0xbd 0xe8

View File

@ -42,6 +42,10 @@
# CHECK: pkhtb r2, r4, r6, asr #16 # CHECK: pkhtb r2, r4, r6, asr #16
0xc4 0xea 0x26 0x42 0xc4 0xea 0x26 0x42
# CHECK-NOT: pkhbt r2, r4, r6, lsl #0
# CHECK: pkhbt r2, r4, r6
0xc4 0xea 0x06 0x02
# CHECK: pop {r2, r4, r6, r8, r10, r12} # CHECK: pop {r2, r4, r6, r8, r10, r12}
0xbd 0xe8 0x54 0x15 0xbd 0xe8 0x54 0x15