ARM: Tidy up representation of PKH instruction.

The shift type is implied by the instruction (PKHBT vs. PKHTB) and so shouldn't
be also encoded as part of the shift value immediate. Otherwise we're able to
represent invalid instructions, plus it needlessly complicates the
representation. Preparatory work for asm parsing of these instructions.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135616 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-07-20 20:32:09 +00:00
parent aeb7de764a
commit a0472dc420
5 changed files with 35 additions and 37 deletions

View File

@ -854,11 +854,11 @@ class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
bits<4> Rd;
bits<4> Rn;
bits<4> Rm;
bits<8> sh;
bits<5> sh;
let Inst{27-20} = opcod;
let Inst{19-16} = Rn;
let Inst{15-12} = Rd;
let Inst{11-7} = sh{7-3};
let Inst{11-7} = sh;
let Inst{6} = tb;
let Inst{5-4} = 0b01;
let Inst{3-0} = Rm;

View File

@ -3111,18 +3111,13 @@ def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)),
(and (srl GPR:$Rm, (i32 8)), 0xFF)),
(REVSH GPR:$Rm)>;
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 : ImmLeaf<i32, [{
return Imm >= 0 && Imm < 32;
}]>;
def lsl_amt : ImmLeaf<i32, [{
return Imm > 0 && Imm < 32;
}], lsl_shift_imm>;
def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
(ins GPR:$Rn, GPR:$Rm, i32imm:$sh),
IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm, lsl $sh",
[(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
(and (shl GPR:$Rm, lsl_amt:$sh),
0xFFFF0000)))]>,
@ -3132,22 +3127,17 @@ def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (and GPR:$Rm, 0xFFFF0000)),
(PKHBT GPR:$Rn, GPR:$Rm, 0)>;
def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
(PKHBT GPR:$Rn, GPR:$Rm, (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);
}]>;
(PKHBT GPR:$Rn, GPR:$Rm, imm16_31:$sh)>;
def asr_amt : ImmLeaf<i32, [{
return Imm > 0 && Imm <= 32;
}], asr_shift_imm>;
}]>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below.
def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
(ins GPR:$Rn, GPR:$Rm, shift_imm:$sh),
IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
(ins GPR:$Rn, GPR:$Rm, i32imm:$sh),
IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm, asr $sh",
[(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
(and (sra GPR:$Rm, asr_amt:$sh),
0xFFFF)))]>,
@ -3156,10 +3146,10 @@ def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
// 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)),
(PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm16_31:$sh))>;
(PKHTB GPR:$src1, GPR:$src2, imm16_31:$sh)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
(and (srl GPR:$src2, imm1_15:$sh), 0xFFFF)),
(PKHTB GPR:$src1, GPR:$src2, (asr_shift_imm imm1_15:$sh))>;
(PKHTB GPR:$src1, GPR:$src2, imm1_15:$sh)>;
//===----------------------------------------------------------------------===//
// Comparison Instructions...

View File

@ -2613,8 +2613,8 @@ def : T2Pat<(or (sra (shl rGPR:$Rm, (i32 24)), (i32 16)),
(t2REVSH rGPR:$Rm)>;
def t2PKHBT : T2ThreeReg<
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$sh),
IIC_iBITsi, "pkhbt", "\t$Rd, $Rn, $Rm, lsl $sh",
[(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF),
(and (shl rGPR:$Rm, lsl_amt:$sh),
0xFFFF0000)))]>,
@ -2625,9 +2625,9 @@ def t2PKHBT : T2ThreeReg<
let Inst{5} = 0; // BT form
let Inst{4} = 0;
bits<8> sh;
let Inst{14-12} = sh{7-5};
let Inst{7-6} = sh{4-3};
bits<5> sh;
let Inst{14-12} = sh{4-2};
let Inst{7-6} = sh{1-0};
}
// Alternate cases for PKHBT where identities eliminate some nodes.
@ -2635,14 +2635,14 @@ def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
(t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
(t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
(t2PKHBT rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below.
def t2PKHTB : T2ThreeReg<
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, shift_imm:$sh),
IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$sh),
IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm, asr $sh",
[(set rGPR:$Rd, (or (and rGPR:$Rn, 0xFFFF0000),
(and (sra rGPR:$Rm, asr_amt:$sh),
0xFFFF)))]>,
@ -2653,19 +2653,19 @@ def t2PKHTB : T2ThreeReg<
let Inst{5} = 1; // TB form
let Inst{4} = 0;
bits<8> sh;
let Inst{14-12} = sh{7-5};
let Inst{7-6} = sh{4-3};
bits<5> sh;
let Inst{14-12} = sh{4-2};
let Inst{7-6} = sh{1-0};
}
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
// 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)),
(t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
(t2PKHTB rGPR:$src1, rGPR:$src2, imm16_31:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
(and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
(t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
(t2PKHTB rGPR:$src1, rGPR:$src2, imm1_15:$sh)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
//===----------------------------------------------------------------------===//

View File

@ -1638,7 +1638,10 @@ static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
else if (Opcode == ARM::PKHTB)
Opc = ARM_AM::asr;
getImmShiftSE(Opc, ShiftAmt);
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShiftAmt)));
if (Opcode == ARM::PKHBT || Opcode == ARM::PKHTB)
MI.addOperand(MCOperand::CreateImm(ShiftAmt));
else
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShiftAmt)));
++OpIdx;
}

View File

@ -1502,7 +1502,12 @@ static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned imm5 = getShiftAmtBits(insn);
ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
// The PKHBT/PKHTB instructions have an implied shift type and so just
// use a plain immediate for the amount.
if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
MI.addOperand(MCOperand::CreateImm(ShAmt));
else
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
}
++OpIdx;
}