diff --git a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index 8f1c3beea3e..113f7fb759d 100644 --- a/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -172,6 +172,16 @@ inline SDValue XformUToUM1Imm(unsigned Imm) { return CurDAG->getTargetConstant(Imm - 1, MVT::i32); } +// XformSToSM2Imm - Return a target constant decremented by 2. +inline SDValue XformSToSM2Imm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm - 2, MVT::i32); +} + +// XformSToSM3Imm - Return a target constant decremented by 3. +inline SDValue XformSToSM3Imm(unsigned Imm) { + return CurDAG->getTargetConstant(Imm - 3, MVT::i32); +} + // Include the pieces autogenerated from the target description. #include "HexagonGenDAGISel.inc" diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 1a4b603b577..b18041576ed 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -39,6 +39,20 @@ def DEC_CONST_SIGNED : SDNodeXForm; +// SDNode for converting immediate C to C-2. +def DEC2_CONST_SIGNED : SDNodeXFormgetSExtValue(); + return XformSToSM2Imm(imm); +}]>; + +// SDNode for converting immediate C to C-3. +def DEC3_CONST_SIGNED : SDNodeXFormgetSExtValue(); + return XformSToSM3Imm(imm); +}]>; + // SDNode for converting immediate C to C-1. def DEC_CONST_UNSIGNED : SDNodeXForm; def: T_RI_pat; def: T_RR_pat; +// Linear feedback-shift Iteration. +def : T_PP_pat ; + // Shift by immediate and add def : T_RRI_pat; @@ -706,6 +709,22 @@ def : T_RR_pat ; def : T_RR_pat ; def : T_RR_pat ; +def : T_R_pat ; + +def : T_R_pat ; + +def : T_R_pat ; +def : T_R_pat ; +def : T_R_pat ; + +def : T_R_pat ; + +def : T_P_pat ; +def : T_R_pat ; +def : T_R_pat ; +def : T_R_pat ; +def : T_R_pat ; + def : T_RI_pat ; def : T_RI_pat ; def : T_RI_pat ; @@ -716,6 +735,33 @@ def : T_RI_pat ; +//===----------------------------------------------------------------------===// +// Template 'def pat' to map tableidx[bhwd] intrinsics to :raw instructions. +//===----------------------------------------------------------------------===// +class S2op_tableidx_pat + : Pat <(IntID IntRegs:$src1, IntRegs:$src2, u4ImmPred:$src3, u5ImmPred:$src4), + (OutputInst IntRegs:$src1, IntRegs:$src2, u4ImmPred:$src3, + (XformImm u5ImmPred:$src4))>; + + +// Table Index : Extract and insert bits. +// Map to the real hardware instructions after subtracting appropriate +// values from the 4th input operand. Please note that subtraction is not +// needed for int_hexagon_S2_tableidxb_goodsyntax. + +def : Pat <(int_hexagon_S2_tableidxb_goodsyntax IntRegs:$src1, IntRegs:$src2, + u4ImmPred:$src3, u5ImmPred:$src4), + (S2_tableidxb IntRegs:$src1, IntRegs:$src2, + u4ImmPred:$src3, u5ImmPred:$src4)>; + +def : S2op_tableidx_pat ; +def : S2op_tableidx_pat ; +def : S2op_tableidx_pat ; + // // ALU 32 types. // @@ -2561,42 +2607,10 @@ class di_LDInstPI_diu4 * ALU32/PERM * *********************************************************************/ -// ALU32 / PERM / Combine. -def HEXAGON_A2_combinew: - di_ALU32_sisi <"combine", int_hexagon_A2_combinew>; -def HEXAGON_A2_combine_hh: - si_MInst_sisi_hh <"combine", int_hexagon_A2_combine_hh>; -def HEXAGON_A2_combine_lh: - si_MInst_sisi_lh <"combine", int_hexagon_A2_combine_lh>; -def HEXAGON_A2_combine_hl: - si_MInst_sisi_hl <"combine", int_hexagon_A2_combine_hl>; -def HEXAGON_A2_combine_ll: - si_MInst_sisi_ll <"combine", int_hexagon_A2_combine_ll>; -def HEXAGON_A2_combineii: - di_MInst_s8s8 <"combine", int_hexagon_A2_combineii>; - // ALU32 / PERM / Mux. def HEXAGON_C2_mux: si_ALU32_qisisi <"mux", int_hexagon_C2_mux>; -// ALU32 / PERM / Shift halfword. -def HEXAGON_A2_aslh: - si_ALU32_si <"aslh", int_hexagon_A2_aslh>; -def HEXAGON_A2_asrh: - si_ALU32_si <"asrh", int_hexagon_A2_asrh>; -def SI_to_SXTHI_asrh: - si_ALU32_si <"asrh", int_hexagon_SI_to_SXTHI_asrh>; - -// ALU32 / PERM / Sign/zero extend. -def HEXAGON_A2_sxth: - si_ALU32_si <"sxth", int_hexagon_A2_sxth>; -def HEXAGON_A2_sxtb: - si_ALU32_si <"sxtb", int_hexagon_A2_sxtb>; -def HEXAGON_A2_zxth: - si_ALU32_si <"zxth", int_hexagon_A2_zxth>; -def HEXAGON_A2_zxtb: - si_ALU32_si <"zxtb", int_hexagon_A2_zxtb>; - /******************************************************************** * ALU32/PRED * *********************************************************************/ @@ -2656,12 +2670,6 @@ def HEXAGON_A2_svsubuhs: * ALU64/ALU * *********************************************************************/ -// ALU64 / ALU / Add. -def HEXAGON_A2_addp: - di_ALU64_didi <"add", int_hexagon_A2_addp>; -def HEXAGON_A2_addsat: - si_ALU64_sisi_sat <"add", int_hexagon_A2_addsat>; - // ALU64 / ALU / Compare. def HEXAGON_C2_cmpeqp: qi_ALU64_didi <"cmp.eq", int_hexagon_C2_cmpeqp>; @@ -2670,40 +2678,10 @@ def HEXAGON_C2_cmpgtp: def HEXAGON_C2_cmpgtup: qi_ALU64_didi <"cmp.gtu", int_hexagon_C2_cmpgtup>; -// ALU64 / ALU / Logical operations. -def HEXAGON_A2_andp: - di_ALU64_didi <"and", int_hexagon_A2_andp>; -def HEXAGON_A2_orp: - di_ALU64_didi <"or", int_hexagon_A2_orp>; -def HEXAGON_A2_xorp: - di_ALU64_didi <"xor", int_hexagon_A2_xorp>; - -// ALU64 / ALU / Subtract. -def HEXAGON_A2_subp: - di_ALU64_didi <"sub", int_hexagon_A2_subp>; -def HEXAGON_A2_subsat: - si_ALU64_sisi_sat <"sub", int_hexagon_A2_subsat>; - // ALU64 / ALU / Transfer register. def HEXAGON_A2_tfrp: di_ALU64_di <"", int_hexagon_A2_tfrp>; -/******************************************************************** -* ALU64/BIT * -*********************************************************************/ - -// ALU64 / BIT / Masked parity. -def HEXAGON_S2_parityp: - si_ALU64_didi <"parity", int_hexagon_S2_parityp>; - -/******************************************************************** -* ALU64/PERM * -*********************************************************************/ - -// ALU64 / PERM / Vector pack high and low halfwords. -def HEXAGON_S2_packhl: - di_ALU64_sisi <"packhl", int_hexagon_S2_packhl>; - /******************************************************************** * ALU64/VB * *********************************************************************/ @@ -2891,30 +2869,12 @@ def HEXAGON_C2_xor: * MTYPE/ALU * *********************************************************************/ -// MTYPE / ALU / Add and accumulate. -def HEXAGON_M2_acci: - si_MInst_sisisi_acc <"add", int_hexagon_M2_acci>; -def HEXAGON_M2_accii: - si_MInst_sisis8_acc <"add", int_hexagon_M2_accii>; -def HEXAGON_M2_nacci: - si_MInst_sisisi_nac <"add", int_hexagon_M2_nacci>; -def HEXAGON_M2_naccii: - si_MInst_sisis8_nac <"add", int_hexagon_M2_naccii>; - -// MTYPE / ALU / Subtract and accumulate. -def HEXAGON_M2_subacc: - si_MInst_sisisi_acc <"sub", int_hexagon_M2_subacc>; - // MTYPE / ALU / Vector absolute difference. def HEXAGON_M2_vabsdiffh: di_MInst_didi <"vabsdiffh",int_hexagon_M2_vabsdiffh>; def HEXAGON_M2_vabsdiffw: di_MInst_didi <"vabsdiffw",int_hexagon_M2_vabsdiffw>; -// MTYPE / ALU / XOR and xor with destination. -def HEXAGON_M2_xor_xacc: - si_MInst_sisisi_xacc <"xor", int_hexagon_M2_xor_xacc>; - /******************************************************************** * MTYPE/COMPLEX * @@ -3014,23 +2974,6 @@ def HEXAGON_M2_vrcmacr_s0c: * MTYPE/MPYH * *********************************************************************/ -// MTYPE / MPYH / Multiply and use lower result. -//def HEXAGON_M2_mpysmi: -//FIXME: Hexagon_M2_mpysmi should really by of the type si_MInst_sim9, -// not si_MInst_sis9 - but for now, we will use s9. -// def Hexagon_M2_mpysmi: -// si_MInst_sim9 <"mpyi", int_hexagon_M2_mpysmi>; -def Hexagon_M2_mpysmi: - si_MInst_sis9 <"mpyi", int_hexagon_M2_mpysmi>; -def HEXAGON_M2_mpyi: - si_MInst_sisi <"mpyi", int_hexagon_M2_mpyi>; -def HEXAGON_M2_macsip: - si_MInst_sisiu8_acc <"mpyi", int_hexagon_M2_macsip>; -def HEXAGON_M2_maci: - si_MInst_sisisi_acc <"mpyi", int_hexagon_M2_maci>; -def HEXAGON_M2_macsin: - si_MInst_sisiu8_nac <"mpyi", int_hexagon_M2_macsin>; - // MTYPE / MPYH / Multiply word by half (32x16). //Rdd[+]=vmpywoh(Rss,Rtt)[:<<1][:rnd][:sat] //Rdd[+]=vmpyweh(Rss,Rtt)[:<<1][:rnd][:sat] @@ -3176,112 +3119,6 @@ def HEXAGON_M2_vrmpy_s0: def HEXAGON_M2_vrmac_s0: di_MInst_dididi_acc <"vrmpyh", int_hexagon_M2_vrmac_s0>; - -/******************************************************************** -* STYPE/ALU * -*********************************************************************/ - -// STYPE / ALU / Absolute value. -def HEXAGON_A2_abs: - si_SInst_si <"abs", int_hexagon_A2_abs>; -def HEXAGON_A2_abssat: - si_SInst_si_sat <"abs", int_hexagon_A2_abssat>; - -// STYPE / ALU / Sign extend word to doubleword. -def HEXAGON_A2_sxtw: - di_SInst_si <"sxtw", int_hexagon_A2_sxtw>; - - -/******************************************************************** -* STYPE/BIT * -*********************************************************************/ - -// STYPE / BIT / Count leading. -def HEXAGON_S2_cl0: - si_SInst_si <"cl0", int_hexagon_S2_cl0>; -def HEXAGON_S2_cl0p: - si_SInst_di <"cl0", int_hexagon_S2_cl0p>; -def HEXAGON_S2_cl1: - si_SInst_si <"cl1", int_hexagon_S2_cl1>; -def HEXAGON_S2_cl1p: - si_SInst_di <"cl1", int_hexagon_S2_cl1p>; -def HEXAGON_S2_clb: - si_SInst_si <"clb", int_hexagon_S2_clb>; -def HEXAGON_S2_clbp: - si_SInst_di <"clb", int_hexagon_S2_clbp>; -def HEXAGON_S2_clbnorm: - si_SInst_si <"normamt", int_hexagon_S2_clbnorm>; - -// STYPE / BIT / Count trailing. -def HEXAGON_S2_ct0: - si_SInst_si <"ct0", int_hexagon_S2_ct0>; -def HEXAGON_S2_ct1: - si_SInst_si <"ct1", int_hexagon_S2_ct1>; - -// STYPE / BIT / Compare bit mask. -def Hexagon_C2_bitsclr: - qi_SInst_sisi <"bitsclr", int_hexagon_C2_bitsclr>; -def Hexagon_C2_bitsclri: - qi_SInst_siu6 <"bitsclr", int_hexagon_C2_bitsclri>; -def Hexagon_C2_bitsset: - qi_SInst_sisi <"bitsset", int_hexagon_C2_bitsset>; - -// STYPE / BIT / Extract unsigned. -// Rd[d][32/64]=extractu(Rs[s],Rt[t],[imm]) -def HEXAGON_S2_extractu: - si_SInst_siu5u5 <"extractu",int_hexagon_S2_extractu>; -def HEXAGON_S2_extractu_rp: - si_SInst_sidi <"extractu",int_hexagon_S2_extractu_rp>; -def HEXAGON_S2_extractup: - di_SInst_diu6u6 <"extractu",int_hexagon_S2_extractup>; -def HEXAGON_S2_extractup_rp: - di_SInst_didi <"extractu",int_hexagon_S2_extractup_rp>; - -// STYPE / BIT / Insert bitfield. -def Hexagon_S2_insert: - si_SInst_sisiu5u5 <"insert", int_hexagon_S2_insert>; -def Hexagon_S2_insert_rp: - si_SInst_sisidi <"insert", int_hexagon_S2_insert_rp>; -def Hexagon_S2_insertp: - di_SInst_didiu6u6 <"insert", int_hexagon_S2_insertp>; -def Hexagon_S2_insertp_rp: - di_SInst_dididi <"insert", int_hexagon_S2_insertp_rp>; - -// STYPE / BIT / Innterleave/deinterleave. -def Hexagon_S2_interleave: - di_SInst_di <"interleave", int_hexagon_S2_interleave>; -def Hexagon_S2_deinterleave: - di_SInst_di <"deinterleave", int_hexagon_S2_deinterleave>; - -// STYPE / BIT / Linear feedback-shift Iteration. -def Hexagon_S2_lfsp: - di_SInst_didi <"lfs", int_hexagon_S2_lfsp>; - -// STYPE / BIT / Bit reverse. -def Hexagon_S2_brev: - si_SInst_si <"brev", int_hexagon_S2_brev>; - -// STYPE / BIT / Set/Clear/Toggle Bit. -def HEXAGON_S2_setbit_i: - si_SInst_siu5 <"setbit", int_hexagon_S2_setbit_i>; -def HEXAGON_S2_togglebit_i: - si_SInst_siu5 <"togglebit", int_hexagon_S2_togglebit_i>; -def HEXAGON_S2_clrbit_i: - si_SInst_siu5 <"clrbit", int_hexagon_S2_clrbit_i>; -def HEXAGON_S2_setbit_r: - si_SInst_sisi <"setbit", int_hexagon_S2_setbit_r>; -def HEXAGON_S2_togglebit_r: - si_SInst_sisi <"togglebit", int_hexagon_S2_togglebit_r>; -def HEXAGON_S2_clrbit_r: - si_SInst_sisi <"clrbit", int_hexagon_S2_clrbit_r>; - -// STYPE / BIT / Test Bit. -def HEXAGON_S2_tstbit_i: - qi_SInst_siu5 <"tstbit", int_hexagon_S2_tstbit_i>; -def HEXAGON_S2_tstbit_r: - qi_SInst_sisi <"tstbit", int_hexagon_S2_tstbit_r>; - - /******************************************************************** * STYPE/COMPLEX * *********************************************************************/ @@ -3299,22 +3136,6 @@ def HEXAGON_S2_vcrotate: * STYPE/PERM * *********************************************************************/ -// STYPE / PERM / Saturate. -def HEXAGON_A2_sat: - si_SInst_di <"sat", int_hexagon_A2_sat>; -def HEXAGON_A2_satb: - si_SInst_si <"satb", int_hexagon_A2_satb>; -def HEXAGON_A2_sath: - si_SInst_si <"sath", int_hexagon_A2_sath>; -def HEXAGON_A2_satub: - si_SInst_si <"satub", int_hexagon_A2_satub>; -def HEXAGON_A2_satuh: - si_SInst_si <"satuh", int_hexagon_A2_satuh>; - -// STYPE / PERM / Swizzle bytes. -def HEXAGON_A2_swiz: - si_SInst_si <"swiz", int_hexagon_A2_swiz>; - // STYPE / PERM / Vector align. // Need custom lowering def HEXAGON_S2_valignib: @@ -3417,16 +3238,6 @@ def HEXAGON_C2_tfrrp: def HEXAGON_C2_vitpack: si_SInst_qiqi <"vitpack",int_hexagon_C2_vitpack>; -// STYPE / SHIFT / Table Index. -def Hexagon_S2_tableidxb_goodsyntax: - si_MInst_sisiu4u5 <"tableidxb",int_hexagon_S2_tableidxb_goodsyntax>; -def Hexagon_S2_tableidxd_goodsyntax: - si_MInst_sisiu4u5 <"tableidxd",int_hexagon_S2_tableidxd_goodsyntax>; -def Hexagon_S2_tableidxh_goodsyntax: - si_MInst_sisiu4u5 <"tableidxh",int_hexagon_S2_tableidxh_goodsyntax>; -def Hexagon_S2_tableidxw_goodsyntax: - si_MInst_sisiu4u5 <"tableidxw",int_hexagon_S2_tableidxw_goodsyntax>; - /******************************************************************** * STYPE/VH * diff --git a/lib/Target/Hexagon/HexagonIntrinsicsDerived.td b/lib/Target/Hexagon/HexagonIntrinsicsDerived.td index df89378603a..4c28b28337f 100644 --- a/lib/Target/Hexagon/HexagonIntrinsicsDerived.td +++ b/lib/Target/Hexagon/HexagonIntrinsicsDerived.td @@ -14,8 +14,8 @@ def : Pat <(mul DoubleRegs:$src1, DoubleRegs:$src2), (i64 (A2_combinew - (HEXAGON_M2_maci - (HEXAGON_M2_maci + (M2_maci + (M2_maci (i32 (EXTRACT_SUBREG (i64 diff --git a/lib/Target/Hexagon/HexagonOperands.td b/lib/Target/Hexagon/HexagonOperands.td index 51e61461423..15fb728f6d8 100644 --- a/lib/Target/Hexagon/HexagonOperands.td +++ b/lib/Target/Hexagon/HexagonOperands.td @@ -343,6 +343,12 @@ def u5ImmPred : PatLeaf<(i32 imm), [{ return isUInt<5>(v); }]>; +def u4ImmPred : PatLeaf<(i32 imm), [{ + // u4ImmPred predicate - True if the immediate fits in a 4-bit unsigned + // field. + int64_t v = (int64_t)N->getSExtValue(); + return isUInt<4>(v); +}]>; def u3ImmPred : PatLeaf<(i32 imm), [{ // u3ImmPred predicate - True if the immediate fits in a 3-bit unsigned diff --git a/test/CodeGen/Hexagon/intrinsics/xtype_bit.ll b/test/CodeGen/Hexagon/intrinsics/xtype_bit.ll index a7fc754da21..8531b2f9334 100644 --- a/test/CodeGen/Hexagon/intrinsics/xtype_bit.ll +++ b/test/CodeGen/Hexagon/intrinsics/xtype_bit.ll @@ -312,18 +312,18 @@ define i32 @S2_tableidxh_goodsyntax(i32 %a, i32 %b) { %z = call i32 @llvm.hexagon.S2.tableidxh.goodsyntax(i32 %a, i32 %b, i32 0, i32 0) ret i32 %z } -; CHECK: r0 = tableidxh(r1, #0, #0) +; CHECK: r0 = tableidxh(r1, #0, #-1) declare i32 @llvm.hexagon.S2.tableidxw.goodsyntax(i32, i32, i32, i32) define i32 @S2_tableidxw_goodsyntax(i32 %a, i32 %b) { %z = call i32 @llvm.hexagon.S2.tableidxw.goodsyntax(i32 %a, i32 %b, i32 0, i32 0) ret i32 %z } -; CHECK: r0 = tableidxw(r1, #0, #0) +; CHECK: r0 = tableidxw(r1, #0, #-2) declare i32 @llvm.hexagon.S2.tableidxd.goodsyntax(i32, i32, i32, i32) define i32 @S2_tableidxd_goodsyntax(i32 %a, i32 %b) { %z = call i32 @llvm.hexagon.S2.tableidxd.goodsyntax(i32 %a, i32 %b, i32 0, i32 0) ret i32 %z } -; CHECK: r0 = tableidxd(r1, #0, #0) +; CHECK: r0 = tableidxd(r1, #0, #-3)