From a0472dc4205d5f2cc4e9cc5a08c51625573a26ce Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 20 Jul 2011 20:32:09 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMInstrFormats.td | 4 +-- lib/Target/ARM/ARMInstrInfo.td | 30 +++++++------------ lib/Target/ARM/ARMInstrThumb2.td | 26 ++++++++-------- .../ARM/Disassembler/ARMDisassemblerCore.cpp | 5 +++- .../ARM/Disassembler/ThumbDisassemblerCore.h | 7 ++++- 5 files changed, 35 insertions(+), 37 deletions(-) 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; }