diff options
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 30 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 22 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 3 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h | 8 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 14 | ||||
-rw-r--r-- | lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 1 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 11 |
8 files changed, 47 insertions, 44 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 61a49a8a09..6c10a431d9 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -215,8 +215,6 @@ namespace { const { return 0; } unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } - unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op) - const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 55735802a3..3b755933b3 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -388,10 +388,20 @@ def neon_vcvt_imm32 : Operand<i32> { } // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24. -def rot_imm : Operand<i32>, ImmLeaf<i32, [{ - int32_t v = (int32_t)Imm; - return v == 8 || v == 16 || v == 24; }]> { - let EncoderMethod = "getRotImmOpValue"; +def rot_imm_XFORM: SDNodeXForm<imm, [{ + switch (N->getZExtValue()){ + default: assert(0); + case 0: return CurDAG->getTargetConstant(0, MVT::i32); + case 8: return CurDAG->getTargetConstant(1, MVT::i32); + case 16: return CurDAG->getTargetConstant(2, MVT::i32); + case 24: return CurDAG->getTargetConstant(3, MVT::i32); + } +}]>; +def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{ + int32_t v = N->getZExtValue(); + return v == 8 || v == 16 || v == 24; }], + rot_imm_XFORM> { + let PrintMethod = "printRotImmOperand"; } // shift_imm: An integer that encodes a shift amount and the type of shift @@ -989,7 +999,7 @@ multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> { let Inst{3-0} = Rm; } def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), - IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", + IIC_iEXTr, opc, "\t$Rd, $Rm, $rot", [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>, Requires<[IsARM, HasV6]> { bits<4> Rd; @@ -1011,7 +1021,7 @@ multiclass AI_ext_rrot_np<bits<8> opcod, string opc> { let Inst{11-10} = 0b00; } def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot), - IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot", + IIC_iEXTr, opc, "\t$Rd, $Rm, $rot", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { bits<2> rot; @@ -1038,7 +1048,7 @@ multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> { } def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, rot_imm:$rot), - IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, $rot", [(set GPR:$Rd, (opnode GPR:$Rn, (rotr GPR:$Rm, rot_imm:$rot)))]>, Requires<[IsARM, HasV6]> { @@ -1064,7 +1074,7 @@ multiclass AI_exta_rrot_np<bits<8> opcod, string opc> { } def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm, rot_imm:$rot), - IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot", + IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, $rot", [/* For disassembly only; pattern left blank */]>, Requires<[IsARM, HasV6]> { bits<4> Rn; @@ -2414,9 +2424,9 @@ defm UXTB16 : AI_ext_rrot<0b01101100, // instead so we can include a check for masking back in the upper // eight bits of the source into the lower eight bits of the result. //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF), -// (UXTB16r_rot GPR:$Src, 24)>; +// (UXTB16r_rot GPR:$Src, 3)>; def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF), - (UXTB16r_rot GPR:$Src, 8)>; + (UXTB16r_rot GPR:$Src, 1)>; defm UXTAB : AI_exta_rrot<0b01101110, "uxtab", BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 1a9ab1c876..bc9d878399 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -990,7 +990,7 @@ multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> { let Inst{5-4} = 0b00; // rotate } def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr, - opc, ".w\t$Rd, $Rm, ror $rot", + opc, ".w\t$Rd, $Rm, $rot", [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; @@ -1019,7 +1019,7 @@ multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> { let Inst{5-4} = 0b00; // rotate } def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot), - IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot", + IIC_iEXTr, opc, "\t$dst, $Rm, $rot", [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>, Requires<[HasT2ExtractPack, IsThumb2]> { let Inst{31-27} = 0b11111; @@ -1079,7 +1079,7 @@ multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> { } def rr_rot : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot), - IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", + IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, $rot", [(set rGPR:$Rd, (opnode rGPR:$Rn, (rotr rGPR:$Rm, rot_imm:$rot)))]>, Requires<[HasT2ExtractPack, IsThumb2]> { @@ -1094,9 +1094,7 @@ multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> { } } -// DO variant - disassembly only, no pattern - -multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> { +multiclass T2I_exta_rrot_np<bits<3> opcod, string opc> { def rr : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm", []> { let Inst{31-27} = 0b11111; @@ -1106,8 +1104,8 @@ multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> { let Inst{7} = 1; let Inst{5-4} = 0b00; // rotate } - def rr_rot :T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot), - IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> { + def rr_rot :T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot), + IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, $rot", []> { let Inst{31-27} = 0b11111; let Inst{26-23} = 0b0100; let Inst{22-20} = opcod; @@ -1681,7 +1679,7 @@ defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>; defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>; -defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">; +defm t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">; // TODO: SXT(A){B|H}16 - done for disassembly only @@ -1700,17 +1698,17 @@ defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16", // instead so we can include a check for masking back in the upper // eight bits of the source into the lower eight bits of the result. //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF), -// (t2UXTB16r_rot rGPR:$Src, 24)>, +// (t2UXTB16r_rot rGPR:$Src, 3)>, // Requires<[HasT2ExtractPack, IsThumb2]>; def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF), - (t2UXTB16r_rot rGPR:$Src, 8)>, + (t2UXTB16r_rot rGPR:$Src, 1)>, Requires<[HasT2ExtractPack, IsThumb2]>; defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab", BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>; defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah", BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>; -defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">; +defm t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 07d9f8ebc7..f16870054e 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -1785,8 +1785,7 @@ static bool DisassembleExtFrm(MCInst &MI, unsigned Opcode, uint32_t insn, && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) { // Extract the 2-bit rotate field Inst{11-10}. unsigned rot = (insn >> ARMII::ExtRotImmShift) & 3; - // Rotation by 8, 16, or 24 bits. - MI.addOperand(MCOperand::CreateImm(rot << 3)); + MI.addOperand(MCOperand::CreateImm(rot)); ++OpIdx; } diff --git a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index 694ffe6e99..e534e21375 100644 --- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h @@ -323,12 +323,6 @@ static inline int decodeImm32_BLX(uint32_t insn) { return SignExtend32<25>(Imm25); } -// See, for example, A8.6.221 SXTAB16. -static inline unsigned decodeRotate(uint32_t insn) { - unsigned rotate = slice(insn, 5, 4); - return rotate << 3; -} - /////////////////////////////////////////////// // // // Thumb1 instruction disassembly functions. // @@ -2195,7 +2189,7 @@ static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn, if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) { // Add the rotation amount immediate. - MI.addOperand(MCOperand::CreateImm(decodeRotate(insn))); + MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4))); ++OpIdx; } diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 3e58631c6c..30ec4981b7 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -835,3 +835,17 @@ void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, unsigned Imm = MI->getOperand(OpNum).getImm(); O << "#" << Imm + 1; } + +void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum, + raw_ostream &O) { + unsigned Imm = MI->getOperand(OpNum).getImm(); + if (Imm == 0) + return; + O << "ror #"; + switch (Imm) { + default: assert (0 && "illegal ror immediate!"); + case 1: O << "8\n"; break; + case 2: O << "16\n"; break; + case 3: O << "24\n"; break; + } +} diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index c254ace6bc..8b5ccad181 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -115,6 +115,7 @@ public: void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); + void printRotImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O); void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O); }; diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 57439df153..9482a6db1a 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -259,17 +259,6 @@ public: unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const; - unsigned getRotImmOpValue(const MCInst &MI, unsigned Op, - SmallVectorImpl<MCFixup> &Fixups) const { - switch (MI.getOperand(Op).getImm()) { - default: assert (0 && "Not a valid rot_imm value!"); - case 0: return 0; - case 8: return 1; - case 16: return 2; - case 24: return 3; - } - } - unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl<MCFixup> &Fixups) const { return MI.getOperand(Op).getImm() - 1; |