From: Owen Anderson Date: Mon, 8 Aug 2011 20:42:17 +0000 (+0000) Subject: Fix encodings for Thumb ASR and LSR immediate operands. They encode the range 1... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=6d74631062e4464326eb5c680a4d62d340fa42eb;p=oota-llvm.git Fix encodings for Thumb ASR and LSR immediate operands. They encode the range 1-32, with 32 encoded as 0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137062 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 7d4eb6f18f9..c30aa374549 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -236,6 +236,8 @@ namespace { const {return 0; } uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx) const { return 0; } + unsigned getThumbSRImmOpValue(const MachineInstr &MI, unsigned OpIdx) + const { return 0; } unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op) const { diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index e0c03179200..b71391d5c1a 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -19,6 +19,13 @@ def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; +def imm_sr : Operand, ImmLeaf 0 && Imm <= 32; +}]> { + let EncoderMethod = "getThumbSRImmOpValue"; + let DecoderMethod = "DecodeThumbSRImm"; +} + def imm_neg_XFORM : SDNodeXFormgetTargetConstant(-(int)N->getZExtValue(), MVT::i32); }]>; @@ -91,6 +98,7 @@ def t_bltarget : Operand { def t_blxtarget : Operand { let EncoderMethod = "getThumbBLXTargetOpValue"; + let DecoderMethod = "DecodeThumbBLXOffset"; } } @@ -876,10 +884,10 @@ def tAND : // A8.6.12 // ASR immediate def tASRri : // A8.6.14 - T1sIGenEncodeImm<{0,1,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm5), + T1sIGenEncodeImm<{0,1,0,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5), IIC_iMOVsi, "asr", "\t$Rd, $Rm, $imm5", - [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm:$imm5)))]> { + [(set tGPR:$Rd, (sra tGPR:$Rm, (i32 imm_sr:$imm5)))]> { bits<5> imm5; let Inst{10-6} = imm5; } @@ -976,10 +984,10 @@ def tLSLrr : // A8.6.89 // LSR immediate def tLSRri : // A8.6.90 - T1sIGenEncodeImm<{0,0,1,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, i32imm:$imm5), + T1sIGenEncodeImm<{0,0,1,?,?}, (outs tGPR:$Rd), (ins tGPR:$Rm, imm_sr:$imm5), IIC_iMOVsi, "lsr", "\t$Rd, $Rm, $imm5", - [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm:$imm5)))]> { + [(set tGPR:$Rd, (srl tGPR:$Rm, (i32 imm_sr:$imm5)))]> { bits<5> imm5; let Inst{10-6} = imm5; } diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 8fd8a77a412..25a34410666 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -66,7 +66,7 @@ def t2_so_imm_neg : Operand, }], t2_so_imm_neg_XFORM>; /// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31]. -def imm1_31 : ImmLeaf, ImmLeaf= 1 && (int32_t)Imm < 32; }]>; @@ -759,12 +759,12 @@ multiclass T2I_rbin_s_is opcod, string opc, PatFrag opnode> { /// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift / // rotate operation that produces a value. -multiclass T2I_sh_ir opcod, string opc, PatFrag opnode> { +multiclass T2I_sh_ir opcod, string opc, Operand ty, PatFrag opnode> { // 5-bit imm def ri : T2sTwoRegShiftImm< - (outs rGPR:$Rd), (ins rGPR:$Rm, i32imm:$imm), IIC_iMOVsi, + (outs rGPR:$Rd), (ins rGPR:$Rm, ty:$imm), IIC_iMOVsi, opc, ".w\t$Rd, $Rm, $imm", - [(set rGPR:$Rd, (opnode rGPR:$Rm, imm1_31:$imm))]> { + [(set rGPR:$Rd, (opnode rGPR:$Rm, ty:$imm))]> { let Inst{31-27} = 0b11101; let Inst{26-21} = 0b010010; let Inst{19-16} = 0b1111; // Rn @@ -1913,10 +1913,10 @@ def : T2Pat<(int_arm_usat GPR:$a, imm:$pos), (t2USAT imm:$pos, GPR:$a, 0)>; // Shift and rotate Instructions. // -defm t2LSL : T2I_sh_ir<0b00, "lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>; -defm t2LSR : T2I_sh_ir<0b01, "lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>; -defm t2ASR : T2I_sh_ir<0b10, "asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>; -defm t2ROR : T2I_sh_ir<0b11, "ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>; +defm t2LSL : T2I_sh_ir<0b00, "lsl", imm1_31, BinOpFrag<(shl node:$LHS, node:$RHS)>>; +defm t2LSR : T2I_sh_ir<0b01, "lsr", imm_sr, BinOpFrag<(srl node:$LHS, node:$RHS)>>; +defm t2ASR : T2I_sh_ir<0b10, "asr", imm_sr, BinOpFrag<(sra node:$LHS, node:$RHS)>>; +defm t2ROR : T2I_sh_ir<0b11, "ror", imm1_31, BinOpFrag<(rotr node:$LHS, node:$RHS)>>; // (rotr x, (and y, 0x...1f)) ==> (ROR x, y) def : Pat<(rotr rGPR:$lhs, (and rGPR:$rhs, lo5AllOne)), diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 2caf548f888..e047fb8615f 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -294,6 +294,9 @@ public: unsigned getShiftRight64Imm(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const; + unsigned getThumbSRImmOpValue(const MCInst &MI, unsigned Op, + SmallVectorImpl &Fixups) const; + unsigned NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned EncodedValue) const; unsigned NEONThumb2LoadStorePostEncoder(const MCInst &MI, @@ -440,6 +443,16 @@ EncodeAddrModeOpValues(const MCInst &MI, unsigned OpIdx, unsigned &Reg, return isAdd; } +uint32_t ARMMCCodeEmitter:: +getThumbSRImmOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + const MCOperand &MO = MI.getOperand(OpIdx); + assert(MO.isImm() && "Expected constant shift!"); + int val = MO.getImm(); + return (val == 32) ? 0 : val; +} + + /// getBranchTargetOpValue - Helper function to get the branch target operand, /// which is either an immediate or requires a fixup. static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, diff --git a/utils/TableGen/EDEmitter.cpp b/utils/TableGen/EDEmitter.cpp index bf2cbe23c8a..59a765d5ba0 100644 --- a/utils/TableGen/EDEmitter.cpp +++ b/utils/TableGen/EDEmitter.cpp @@ -615,6 +615,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type, IMM("t2ldrlabel"); IMM("postidx_imm8"); IMM("postidx_imm8s4"); + IMM("imm_sr"); + IMM("imm1_31"); MISC("brtarget", "kOperandTypeARMBranchTarget"); // ? MISC("uncondbrtarget", "kOperandTypeARMBranchTarget"); // ?