diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index fe77f2f9fbc..cd109c9dc94 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -854,11 +854,11 @@ class APKHI 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; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 9a140679a7b..be81b598260 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(Sh, MVT::i32); +def lsl_amt : ImmLeaf= 0 && Imm < 32; }]>; -def lsl_amt : ImmLeaf 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 : SDNodeXFormgetZExtValue()); - return CurDAG->getTargetConstant(Sh, MVT::i32); -}]>; + (PKHBT GPR:$Rn, GPR:$Rm, imm16_31:$sh)>; def asr_amt : ImmLeaf 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... diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index d1d0a9795f5..55dbd89f579 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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]>; //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index d89c80a9d45..320679ea88a 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -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; } diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index 4a790a4ea71..9d1fdc1feb1 100644 --- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h @@ -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; }