1// Pattern fragment that combines the value type and the register class 2// into a single parameter. 3// The pat frags in the definitions below need to have a named register, 4// otherwise i32 will be assumed regardless of the register class. The 5// name of the register does not matter. 6def I1 : PatLeaf<(i1 PredRegs:$R)>; 7def I32 : PatLeaf<(i32 IntRegs:$R)>; 8def I64 : PatLeaf<(i64 DoubleRegs:$R)>; 9def F32 : PatLeaf<(f32 IntRegs:$R)>; 10def F64 : PatLeaf<(f64 DoubleRegs:$R)>; 11 12// Pattern fragments to extract the low and high subregisters from a 13// 64-bit value. 14def LoReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_lo)>; 15def HiReg: OutPatFrag<(ops node:$Rs), (EXTRACT_SUBREG (i64 $Rs), isub_hi)>; 16 17def IsOrAdd: PatFrag<(ops node:$Addr, node:$off), 18 (or node:$Addr, node:$off), [{ return isOrEquivalentToAdd(N); }]>; 19 20def IsPow2_32 : PatLeaf<(i32 imm), [{ 21 uint32_t V = N->getZExtValue(); 22 return isPowerOf2_32(V); 23}]>; 24 25def IsPow2_64 : PatLeaf<(i64 imm), [{ 26 uint64_t V = N->getZExtValue(); 27 return isPowerOf2_64(V); 28}]>; 29 30def IsNPow2_32 : PatLeaf<(i32 imm), [{ 31 uint32_t NV = ~N->getZExtValue(); 32 return isPowerOf2_32(NV); 33}]>; 34 35def IsPow2_64L : PatLeaf<(i64 imm), [{ 36 uint64_t V = N->getZExtValue(); 37 return isPowerOf2_64(V) && Log2_64(V) < 32; 38}]>; 39 40def IsPow2_64H : PatLeaf<(i64 imm), [{ 41 uint64_t V = N->getZExtValue(); 42 return isPowerOf2_64(V) && Log2_64(V) >= 32; 43}]>; 44 45def IsNPow2_64L : PatLeaf<(i64 imm), [{ 46 uint64_t NV = ~N->getZExtValue(); 47 return isPowerOf2_64(NV) && Log2_64(NV) < 32; 48}]>; 49 50def IsNPow2_64H : PatLeaf<(i64 imm), [{ 51 uint64_t NV = ~N->getZExtValue(); 52 return isPowerOf2_64(NV) && Log2_64(NV) >= 32; 53}]>; 54 55def SDEC1 : SDNodeXForm<imm, [{ 56 int32_t V = N->getSExtValue(); 57 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); 58}]>; 59 60def UDEC1 : SDNodeXForm<imm, [{ 61 uint32_t V = N->getZExtValue(); 62 assert(V >= 1); 63 return CurDAG->getTargetConstant(V-1, SDLoc(N), MVT::i32); 64}]>; 65 66def UDEC32 : SDNodeXForm<imm, [{ 67 uint32_t V = N->getZExtValue(); 68 assert(V >= 32); 69 return CurDAG->getTargetConstant(V-32, SDLoc(N), MVT::i32); 70}]>; 71 72def Log2_32 : SDNodeXForm<imm, [{ 73 uint32_t V = N->getZExtValue(); 74 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); 75}]>; 76 77def Log2_64 : SDNodeXForm<imm, [{ 78 uint64_t V = N->getZExtValue(); 79 return CurDAG->getTargetConstant(Log2_64(V), SDLoc(N), MVT::i32); 80}]>; 81 82def LogN2_32 : SDNodeXForm<imm, [{ 83 uint32_t NV = ~N->getZExtValue(); 84 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); 85}]>; 86 87def LogN2_64 : SDNodeXForm<imm, [{ 88 uint64_t NV = ~N->getZExtValue(); 89 return CurDAG->getTargetConstant(Log2_64(NV), SDLoc(N), MVT::i32); 90}]>; 91 92 93class T_CMP_pat <InstHexagon MI, PatFrag OpNode, PatLeaf ImmPred> 94 : Pat<(i1 (OpNode I32:$src1, ImmPred:$src2)), 95 (MI IntRegs:$src1, ImmPred:$src2)>; 96 97def : T_CMP_pat <C2_cmpeqi, seteq, s10_0ImmPred>; 98def : T_CMP_pat <C2_cmpgti, setgt, s10_0ImmPred>; 99def : T_CMP_pat <C2_cmpgtui, setugt, u9_0ImmPred>; 100 101def SDTHexagonI64I32I32 : SDTypeProfile<1, 2, 102 [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; 103 104def HexagonCOMBINE : SDNode<"HexagonISD::COMBINE", SDTHexagonI64I32I32>; 105def HexagonPACKHL : SDNode<"HexagonISD::PACKHL", SDTHexagonI64I32I32>; 106 107// Pats for instruction selection. 108class BinOp32_pat<SDNode Op, InstHexagon MI, ValueType ResT> 109 : Pat<(ResT (Op I32:$Rs, I32:$Rt)), 110 (ResT (MI IntRegs:$Rs, IntRegs:$Rt))>; 111 112def: BinOp32_pat<add, A2_add, i32>; 113def: BinOp32_pat<and, A2_and, i32>; 114def: BinOp32_pat<or, A2_or, i32>; 115def: BinOp32_pat<sub, A2_sub, i32>; 116def: BinOp32_pat<xor, A2_xor, i32>; 117 118def: BinOp32_pat<HexagonCOMBINE, A2_combinew, i64>; 119def: BinOp32_pat<HexagonPACKHL, S2_packhl, i64>; 120 121// Patfrag to convert the usual comparison patfrags (e.g. setlt) to ones 122// that reverse the order of the operands. 123class RevCmp<PatFrag F> : PatFrag<(ops node:$rhs, node:$lhs), F.Fragment>; 124 125// Pats for compares. They use PatFrags as operands, not SDNodes, 126// since seteq/setgt/etc. are defined as ParFrags. 127class T_cmp32_rr_pat<InstHexagon MI, PatFrag Op, ValueType VT> 128 : Pat<(VT (Op I32:$Rs, I32:$Rt)), 129 (MI IntRegs:$Rs, IntRegs:$Rt)>; 130 131def: T_cmp32_rr_pat<C2_cmpeq, seteq, i1>; 132def: T_cmp32_rr_pat<C2_cmpgt, setgt, i1>; 133def: T_cmp32_rr_pat<C2_cmpgtu, setugt, i1>; 134 135def: T_cmp32_rr_pat<C2_cmpgt, RevCmp<setlt>, i1>; 136def: T_cmp32_rr_pat<C2_cmpgtu, RevCmp<setult>, i1>; 137 138def: Pat<(select I1:$Pu, I32:$Rs, I32:$Rt), 139 (C2_mux PredRegs:$Pu, IntRegs:$Rs, IntRegs:$Rt)>; 140 141def: Pat<(add I32:$Rs, s32_0ImmPred:$s16), 142 (A2_addi I32:$Rs, imm:$s16)>; 143 144def: Pat<(or I32:$Rs, s32_0ImmPred:$s10), 145 (A2_orir IntRegs:$Rs, imm:$s10)>; 146def: Pat<(and I32:$Rs, s32_0ImmPred:$s10), 147 (A2_andir IntRegs:$Rs, imm:$s10)>; 148 149def: Pat<(sub s32_0ImmPred:$s10, IntRegs:$Rs), 150 (A2_subri imm:$s10, IntRegs:$Rs)>; 151 152// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs). 153def: Pat<(not I32:$src1), 154 (A2_subri -1, IntRegs:$src1)>; 155 156def: Pat<(s32_0ImmPred:$s16), (A2_tfrsi imm:$s16)>; 157def: Pat<(s8_0Imm64Pred:$s8), (A2_tfrpi imm:$s8)>; 158 159def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, I32:$Rs), 160 (C2_muxri I1:$Pu, imm:$s8, I32:$Rs)>; 161 162def : Pat<(select I1:$Pu, I32:$Rs, s32_0ImmPred:$s8), 163 (C2_muxir I1:$Pu, I32:$Rs, imm:$s8)>; 164 165def : Pat<(select I1:$Pu, s32_0ImmPred:$s8, s8_0ImmPred:$S8), 166 (C2_muxii I1:$Pu, imm:$s8, imm:$S8)>; 167 168def: Pat<(shl I32:$src1, (i32 16)), (A2_aslh I32:$src1)>; 169def: Pat<(sra I32:$src1, (i32 16)), (A2_asrh I32:$src1)>; 170def: Pat<(sext_inreg I32:$src1, i8), (A2_sxtb I32:$src1)>; 171def: Pat<(sext_inreg I32:$src1, i16), (A2_sxth I32:$src1)>; 172 173class T_vcmp_pat<InstHexagon MI, PatFrag Op, ValueType T> 174 : Pat<(i1 (Op (T DoubleRegs:$Rss), (T DoubleRegs:$Rtt))), 175 (i1 (MI DoubleRegs:$Rss, DoubleRegs:$Rtt))>; 176 177def: T_vcmp_pat<A2_vcmpbeq, seteq, v8i8>; 178def: T_vcmp_pat<A2_vcmpbgtu, setugt, v8i8>; 179def: T_vcmp_pat<A2_vcmpheq, seteq, v4i16>; 180def: T_vcmp_pat<A2_vcmphgt, setgt, v4i16>; 181def: T_vcmp_pat<A2_vcmphgtu, setugt, v4i16>; 182def: T_vcmp_pat<A2_vcmpweq, seteq, v2i32>; 183def: T_vcmp_pat<A2_vcmpwgt, setgt, v2i32>; 184def: T_vcmp_pat<A2_vcmpwgtu, setugt, v2i32>; 185 186// Add halfword. 187def: Pat<(sext_inreg (add I32:$src1, I32:$src2), i16), 188 (A2_addh_l16_ll I32:$src1, I32:$src2)>; 189 190def: Pat<(sra (add (shl I32:$src1, (i32 16)), I32:$src2), (i32 16)), 191 (A2_addh_l16_hl I32:$src1, I32:$src2)>; 192 193def: Pat<(shl (add I32:$src1, I32:$src2), (i32 16)), 194 (A2_addh_h16_ll I32:$src1, I32:$src2)>; 195 196// Subtract halfword. 197def: Pat<(sext_inreg (sub I32:$src1, I32:$src2), i16), 198 (A2_subh_l16_ll I32:$src1, I32:$src2)>; 199 200def: Pat<(shl (sub I32:$src1, I32:$src2), (i32 16)), 201 (A2_subh_h16_ll I32:$src1, I32:$src2)>; 202 203// Here, depending on the operand being selected, we'll either generate a 204// min or max instruction. 205// Ex: 206// (a>b)?a:b --> max(a,b) => Here check performed is '>' and the value selected 207// is the larger of two. So, the corresponding HexagonInst is passed in 'Inst'. 208// (a>b)?b:a --> min(a,b) => Here check performed is '>' but the smaller value 209// is selected and the corresponding HexagonInst is passed in 'SwapInst'. 210 211multiclass T_MinMax_pats <PatFrag Op, PatLeaf Val, 212 InstHexagon Inst, InstHexagon SwapInst> { 213 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src1, Val:$src2), 214 (Inst Val:$src1, Val:$src2)>; 215 def: Pat<(select (i1 (Op Val:$src1, Val:$src2)), Val:$src2, Val:$src1), 216 (SwapInst Val:$src1, Val:$src2)>; 217} 218 219def IsPosHalf : PatLeaf<(i32 IntRegs:$a), [{ 220 return isPositiveHalfWord(N); 221}]>; 222 223multiclass MinMax_pats <PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> { 224 defm: T_MinMax_pats<Op, I32, Inst, SwapInst>; 225 226 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)), 227 IsPosHalf:$src1, IsPosHalf:$src2), 228 i16), 229 (Inst IntRegs:$src1, IntRegs:$src2)>; 230 231 def: Pat<(sext_inreg (select (i1 (Op IsPosHalf:$src1, IsPosHalf:$src2)), 232 IsPosHalf:$src2, IsPosHalf:$src1), 233 i16), 234 (SwapInst IntRegs:$src1, IntRegs:$src2)>; 235} 236 237let AddedComplexity = 200 in { 238 defm: MinMax_pats<setge, A2_max, A2_min>; 239 defm: MinMax_pats<setgt, A2_max, A2_min>; 240 defm: MinMax_pats<setle, A2_min, A2_max>; 241 defm: MinMax_pats<setlt, A2_min, A2_max>; 242 defm: MinMax_pats<setuge, A2_maxu, A2_minu>; 243 defm: MinMax_pats<setugt, A2_maxu, A2_minu>; 244 defm: MinMax_pats<setule, A2_minu, A2_maxu>; 245 defm: MinMax_pats<setult, A2_minu, A2_maxu>; 246} 247 248class T_cmp64_rr_pat<InstHexagon MI, PatFrag CmpOp> 249 : Pat<(i1 (CmpOp I64:$Rs, I64:$Rt)), 250 (i1 (MI DoubleRegs:$Rs, DoubleRegs:$Rt))>; 251 252def: T_cmp64_rr_pat<C2_cmpeqp, seteq>; 253def: T_cmp64_rr_pat<C2_cmpgtp, setgt>; 254def: T_cmp64_rr_pat<C2_cmpgtup, setugt>; 255def: T_cmp64_rr_pat<C2_cmpgtp, RevCmp<setlt>>; 256def: T_cmp64_rr_pat<C2_cmpgtup, RevCmp<setult>>; 257 258def: Pat<(i64 (add I64:$Rs, I64:$Rt)), (A2_addp I64:$Rs, I64:$Rt)>; 259def: Pat<(i64 (sub I64:$Rs, I64:$Rt)), (A2_subp I64:$Rs, I64:$Rt)>; 260 261def: Pat<(i64 (and I64:$Rs, I64:$Rt)), (A2_andp I64:$Rs, I64:$Rt)>; 262def: Pat<(i64 (or I64:$Rs, I64:$Rt)), (A2_orp I64:$Rs, I64:$Rt)>; 263def: Pat<(i64 (xor I64:$Rs, I64:$Rt)), (A2_xorp I64:$Rs, I64:$Rt)>; 264 265def: Pat<(i1 (not I1:$Ps)), (C2_not PredRegs:$Ps)>; 266 267def: Pat<(i1 (and I1:$Ps, I1:$Pt)), (C2_and I1:$Ps, I1:$Pt)>; 268def: Pat<(i1 (or I1:$Ps, I1:$Pt)), (C2_or I1:$Ps, I1:$Pt)>; 269def: Pat<(i1 (xor I1:$Ps, I1:$Pt)), (C2_xor I1:$Ps, I1:$Pt)>; 270def: Pat<(i1 (and I1:$Ps, (not I1:$Pt))), (C2_andn I1:$Ps, I1:$Pt)>; 271def: Pat<(i1 (or I1:$Ps, (not I1:$Pt))), (C2_orn I1:$Ps, I1:$Pt)>; 272 273def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone, 274 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 275def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, [SDNPHasChain]>; 276 277def: Pat<(br bb:$dst), (J2_jump brtarget:$dst)>; 278def: Pat<(brcond I1:$src1, bb:$block), (J2_jumpt PredRegs:$src1, bb:$block)>; 279def: Pat<(brind I32:$dst), (J2_jumpr IntRegs:$dst)>; 280 281def: Pat<(retflag), (PS_jmpret (i32 R31))>; 282def: Pat<(eh_return), (EH_RETURN_JMPR (i32 R31))>; 283 284// Patterns to select load-indexed (i.e. load from base+offset). 285multiclass Loadx_pat<PatFrag Load, ValueType VT, PatLeaf ImmPred, 286 InstHexagon MI> { 287 def: Pat<(VT (Load AddrFI:$fi)), (VT (MI AddrFI:$fi, 0))>; 288 def: Pat<(VT (Load (add (i32 AddrFI:$fi), ImmPred:$Off))), 289 (VT (MI AddrFI:$fi, imm:$Off))>; 290 def: Pat<(VT (Load (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off))), 291 (VT (MI AddrFI:$fi, imm:$Off))>; 292 def: Pat<(VT (Load (add I32:$Rs, ImmPred:$Off))), 293 (VT (MI IntRegs:$Rs, imm:$Off))>; 294 def: Pat<(VT (Load I32:$Rs)), (VT (MI IntRegs:$Rs, 0))>; 295} 296 297let AddedComplexity = 20 in { 298 defm: Loadx_pat<load, i32, s30_2ImmPred, L2_loadri_io>; 299 defm: Loadx_pat<load, i64, s29_3ImmPred, L2_loadrd_io>; 300 defm: Loadx_pat<atomic_load_8 , i32, s32_0ImmPred, L2_loadrub_io>; 301 defm: Loadx_pat<atomic_load_16, i32, s31_1ImmPred, L2_loadruh_io>; 302 defm: Loadx_pat<atomic_load_32, i32, s30_2ImmPred, L2_loadri_io>; 303 defm: Loadx_pat<atomic_load_64, i64, s29_3ImmPred, L2_loadrd_io>; 304 305 defm: Loadx_pat<extloadi1, i32, s32_0ImmPred, L2_loadrub_io>; 306 defm: Loadx_pat<extloadi8, i32, s32_0ImmPred, L2_loadrub_io>; 307 defm: Loadx_pat<extloadi16, i32, s31_1ImmPred, L2_loadruh_io>; 308 defm: Loadx_pat<sextloadi8, i32, s32_0ImmPred, L2_loadrb_io>; 309 defm: Loadx_pat<sextloadi16, i32, s31_1ImmPred, L2_loadrh_io>; 310 defm: Loadx_pat<zextloadi1, i32, s32_0ImmPred, L2_loadrub_io>; 311 defm: Loadx_pat<zextloadi8, i32, s32_0ImmPred, L2_loadrub_io>; 312 defm: Loadx_pat<zextloadi16, i32, s31_1ImmPred, L2_loadruh_io>; 313 // No sextloadi1. 314} 315 316// Sign-extending loads of i1 need to replicate the lowest bit throughout 317// the 32-bit value. Since the loaded value can only be 0 or 1, 0-v should 318// do the trick. 319let AddedComplexity = 20 in 320def: Pat<(i32 (sextloadi1 I32:$Rs)), 321 (A2_subri 0, (L2_loadrub_io IntRegs:$Rs, 0))>; 322 323def: Pat<(i32 (mul I32:$src1, I32:$src2)), (M2_mpyi I32:$src1, I32:$src2)>; 324def: Pat<(i32 (mulhs I32:$src1, I32:$src2)), (M2_mpy_up I32:$src1, I32:$src2)>; 325def: Pat<(i32 (mulhu I32:$src1, I32:$src2)), (M2_mpyu_up I32:$src1, I32:$src2)>; 326 327def: Pat<(mul IntRegs:$Rs, u32_0ImmPred:$u8), 328 (M2_mpysip IntRegs:$Rs, imm:$u8)>; 329def: Pat<(ineg (mul IntRegs:$Rs, u8_0ImmPred:$u8)), 330 (M2_mpysin IntRegs:$Rs, imm:$u8)>; 331def: Pat<(mul IntRegs:$src1, s32_0ImmPred:$src2), 332 (M2_mpysmi IntRegs:$src1, imm:$src2)>; 333def: Pat<(add (mul IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1), 334 (M2_macsip IntRegs:$src1, IntRegs:$src2, imm:$src3)>; 335def: Pat<(add (mul I32:$src2, I32:$src3), I32:$src1), 336 (M2_maci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 337def: Pat<(add (add IntRegs:$src2, u32_0ImmPred:$src3), IntRegs:$src1), 338 (M2_accii IntRegs:$src1, IntRegs:$src2, imm:$src3)>; 339def: Pat<(add (add I32:$src2, I32:$src3), I32:$src1), 340 (M2_acci IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 341 342class T_MType_acc_pat1 <InstHexagon MI, SDNode firstOp, SDNode secOp, 343 PatLeaf ImmPred> 344 : Pat <(secOp IntRegs:$src1, (firstOp IntRegs:$src2, ImmPred:$src3)), 345 (MI IntRegs:$src1, IntRegs:$src2, ImmPred:$src3)>; 346 347class T_MType_acc_pat2 <InstHexagon MI, SDNode firstOp, SDNode secOp> 348 : Pat <(i32 (secOp IntRegs:$src1, (firstOp IntRegs:$src2, IntRegs:$src3))), 349 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 350 351def : T_MType_acc_pat2 <M2_xor_xacc, xor, xor>; 352def : T_MType_acc_pat1 <M2_macsin, mul, sub, u32_0ImmPred>; 353 354def : T_MType_acc_pat1 <M2_naccii, add, sub, s32_0ImmPred>; 355def : T_MType_acc_pat2 <M2_nacci, add, sub>; 356 357def: T_MType_acc_pat2 <M4_or_xor, xor, or>; 358def: T_MType_acc_pat2 <M4_and_xor, xor, and>; 359def: T_MType_acc_pat2 <M4_or_and, and, or>; 360def: T_MType_acc_pat2 <M4_and_and, and, and>; 361def: T_MType_acc_pat2 <M4_xor_and, and, xor>; 362def: T_MType_acc_pat2 <M4_or_or, or, or>; 363def: T_MType_acc_pat2 <M4_and_or, or, and>; 364def: T_MType_acc_pat2 <M4_xor_or, or, xor>; 365 366class T_MType_acc_pat3 <InstHexagon MI, SDNode firstOp, SDNode secOp> 367 : Pat <(secOp I32:$src1, (firstOp I32:$src2, (not I32:$src3))), 368 (MI IntRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 369 370def: T_MType_acc_pat3 <M4_or_andn, and, or>; 371def: T_MType_acc_pat3 <M4_and_andn, and, and>; 372def: T_MType_acc_pat3 <M4_xor_andn, and, xor>; 373 374def Aext64: PatFrag<(ops node:$Rs), (i64 (anyext node:$Rs))>; 375def Sext64: PatFrag<(ops node:$Rs), (i64 (sext node:$Rs))>; 376def Zext64: PatFrag<(ops node:$Rs), (i64 (zext node:$Rs))>; 377 378// Return true if for a 32 to 64-bit sign-extended load. 379def Sext64Ld : PatLeaf<(i64 DoubleRegs:$src1), [{ 380 LoadSDNode *LD = dyn_cast<LoadSDNode>(N); 381 if (!LD) 382 return false; 383 return LD->getExtensionType() == ISD::SEXTLOAD && 384 LD->getMemoryVT().getScalarType() == MVT::i32; 385}]>; 386 387def: Pat<(mul (Aext64 I32:$src1), (Aext64 I32:$src2)), 388 (M2_dpmpyuu_s0 IntRegs:$src1, IntRegs:$src2)>; 389 390def: Pat<(mul (Sext64 I32:$src1), (Sext64 I32:$src2)), 391 (M2_dpmpyss_s0 IntRegs:$src1, IntRegs:$src2)>; 392 393def: Pat<(mul Sext64Ld:$src1, Sext64Ld:$src2), 394 (M2_dpmpyss_s0 (LoReg DoubleRegs:$src1), (LoReg DoubleRegs:$src2))>; 395 396// Multiply and accumulate, use full result. 397// Rxx[+-]=mpy(Rs,Rt) 398 399def: Pat<(add I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))), 400 (M2_dpmpyss_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 401 402def: Pat<(sub I64:$src1, (mul (Sext64 I32:$src2), (Sext64 I32:$src3))), 403 (M2_dpmpyss_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 404 405def: Pat<(add I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))), 406 (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 407 408def: Pat<(add I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))), 409 (M2_dpmpyuu_acc_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 410 411def: Pat<(sub I64:$src1, (mul (Aext64 I32:$src2), (Aext64 I32:$src3))), 412 (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 413 414def: Pat<(sub I64:$src1, (mul (Zext64 I32:$src2), (Zext64 I32:$src3))), 415 (M2_dpmpyuu_nac_s0 DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3)>; 416 417class Storepi_pat<PatFrag Store, PatFrag Value, PatFrag Offset, 418 InstHexagon MI> 419 : Pat<(Store Value:$src1, I32:$src2, Offset:$offset), 420 (MI I32:$src2, imm:$offset, Value:$src1)>; 421 422def: Storepi_pat<post_truncsti8, I32, s4_0ImmPred, S2_storerb_pi>; 423def: Storepi_pat<post_truncsti16, I32, s4_1ImmPred, S2_storerh_pi>; 424def: Storepi_pat<post_store, I32, s4_2ImmPred, S2_storeri_pi>; 425def: Storepi_pat<post_store, I64, s4_3ImmPred, S2_storerd_pi>; 426 427// Patterns for generating stores, where the address takes different forms: 428// - frameindex, 429// - frameindex + offset, 430// - base + offset, 431// - simple (base address without offset). 432// These would usually be used together (via Storex_pat defined below), but 433// in some cases one may want to apply different properties (such as 434// AddedComplexity) to the individual patterns. 435class Storex_fi_pat<PatFrag Store, PatFrag Value, InstHexagon MI> 436 : Pat<(Store Value:$Rs, AddrFI:$fi), (MI AddrFI:$fi, 0, Value:$Rs)>; 437multiclass Storex_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, 438 InstHexagon MI> { 439 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), 440 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>; 441 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)), 442 (MI AddrFI:$fi, imm:$Off, Value:$Rs)>; 443} 444multiclass Storex_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, 445 InstHexagon MI> { 446 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)), 447 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>; 448 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)), 449 (MI IntRegs:$Rs, imm:$Off, Value:$Rt)>; 450} 451class Storex_simple_pat<PatFrag Store, PatFrag Value, InstHexagon MI> 452 : Pat<(Store Value:$Rt, I32:$Rs), 453 (MI IntRegs:$Rs, 0, Value:$Rt)>; 454 455// Patterns for generating stores, where the address takes different forms, 456// and where the value being stored is transformed through the value modifier 457// ValueMod. The address forms are same as above. 458class Storexm_fi_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod, 459 InstHexagon MI> 460 : Pat<(Store Value:$Rs, AddrFI:$fi), 461 (MI AddrFI:$fi, 0, (ValueMod Value:$Rs))>; 462multiclass Storexm_fi_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, 463 PatFrag ValueMod, InstHexagon MI> { 464 def: Pat<(Store Value:$Rs, (add (i32 AddrFI:$fi), ImmPred:$Off)), 465 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>; 466 def: Pat<(Store Value:$Rs, (IsOrAdd (i32 AddrFI:$fi), ImmPred:$Off)), 467 (MI AddrFI:$fi, imm:$Off, (ValueMod Value:$Rs))>; 468} 469multiclass Storexm_add_pat<PatFrag Store, PatFrag Value, PatFrag ImmPred, 470 PatFrag ValueMod, InstHexagon MI> { 471 def: Pat<(Store Value:$Rt, (add I32:$Rs, ImmPred:$Off)), 472 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; 473 def: Pat<(Store Value:$Rt, (IsOrAdd I32:$Rs, ImmPred:$Off)), 474 (MI IntRegs:$Rs, imm:$Off, (ValueMod Value:$Rt))>; 475} 476class Storexm_simple_pat<PatFrag Store, PatFrag Value, PatFrag ValueMod, 477 InstHexagon MI> 478 : Pat<(Store Value:$Rt, I32:$Rs), 479 (MI IntRegs:$Rs, 0, (ValueMod Value:$Rt))>; 480 481multiclass Storex_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred, 482 InstHexagon MI> { 483 def: Storex_fi_pat <Store, Value, MI>; 484 defm: Storex_fi_add_pat <Store, Value, ImmPred, MI>; 485 defm: Storex_add_pat <Store, Value, ImmPred, MI>; 486} 487 488multiclass Storexm_pat<PatFrag Store, PatFrag Value, PatLeaf ImmPred, 489 PatFrag ValueMod, InstHexagon MI> { 490 def: Storexm_fi_pat <Store, Value, ValueMod, MI>; 491 defm: Storexm_fi_add_pat <Store, Value, ImmPred, ValueMod, MI>; 492 defm: Storexm_add_pat <Store, Value, ImmPred, ValueMod, MI>; 493} 494 495// Regular stores in the DAG have two operands: value and address. 496// Atomic stores also have two, but they are reversed: address, value. 497// To use atomic stores with the patterns, they need to have their operands 498// swapped. This relies on the knowledge that the F.Fragment uses names 499// "ptr" and "val". 500class SwapSt<PatFrag F> 501 : PatFrag<(ops node:$val, node:$ptr), F.Fragment, F.PredicateCode, 502 F.OperandTransform>; 503 504let AddedComplexity = 20 in { 505 defm: Storex_pat<truncstorei8, I32, s32_0ImmPred, S2_storerb_io>; 506 defm: Storex_pat<truncstorei16, I32, s31_1ImmPred, S2_storerh_io>; 507 defm: Storex_pat<store, I32, s30_2ImmPred, S2_storeri_io>; 508 defm: Storex_pat<store, I64, s29_3ImmPred, S2_storerd_io>; 509 510 defm: Storex_pat<SwapSt<atomic_store_8>, I32, s32_0ImmPred, S2_storerb_io>; 511 defm: Storex_pat<SwapSt<atomic_store_16>, I32, s31_1ImmPred, S2_storerh_io>; 512 defm: Storex_pat<SwapSt<atomic_store_32>, I32, s30_2ImmPred, S2_storeri_io>; 513 defm: Storex_pat<SwapSt<atomic_store_64>, I64, s29_3ImmPred, S2_storerd_io>; 514} 515 516// Simple patterns should be tried with the least priority. 517def: Storex_simple_pat<truncstorei8, I32, S2_storerb_io>; 518def: Storex_simple_pat<truncstorei16, I32, S2_storerh_io>; 519def: Storex_simple_pat<store, I32, S2_storeri_io>; 520def: Storex_simple_pat<store, I64, S2_storerd_io>; 521 522def: Storex_simple_pat<SwapSt<atomic_store_8>, I32, S2_storerb_io>; 523def: Storex_simple_pat<SwapSt<atomic_store_16>, I32, S2_storerh_io>; 524def: Storex_simple_pat<SwapSt<atomic_store_32>, I32, S2_storeri_io>; 525def: Storex_simple_pat<SwapSt<atomic_store_64>, I64, S2_storerd_io>; 526 527let AddedComplexity = 20 in { 528 defm: Storexm_pat<truncstorei8, I64, s32_0ImmPred, LoReg, S2_storerb_io>; 529 defm: Storexm_pat<truncstorei16, I64, s31_1ImmPred, LoReg, S2_storerh_io>; 530 defm: Storexm_pat<truncstorei32, I64, s30_2ImmPred, LoReg, S2_storeri_io>; 531} 532 533def: Storexm_simple_pat<truncstorei8, I64, LoReg, S2_storerb_io>; 534def: Storexm_simple_pat<truncstorei16, I64, LoReg, S2_storerh_io>; 535def: Storexm_simple_pat<truncstorei32, I64, LoReg, S2_storeri_io>; 536 537def: Pat <(Sext64 I32:$src), (A2_sxtw I32:$src)>; 538 539def: Pat<(select (i1 (setlt I32:$src, 0)), (sub 0, I32:$src), I32:$src), 540 (A2_abs IntRegs:$src)>; 541 542let AddedComplexity = 50 in 543def: Pat<(xor (add (sra I32:$src, (i32 31)), 544 I32:$src), 545 (sra I32:$src, (i32 31))), 546 (A2_abs IntRegs:$src)>; 547 548def: Pat<(sra I32:$src, u5_0ImmPred:$u5), 549 (S2_asr_i_r IntRegs:$src, imm:$u5)>; 550def: Pat<(srl I32:$src, u5_0ImmPred:$u5), 551 (S2_lsr_i_r IntRegs:$src, imm:$u5)>; 552def: Pat<(shl I32:$src, u5_0ImmPred:$u5), 553 (S2_asl_i_r IntRegs:$src, imm:$u5)>; 554 555def: Pat<(sra (add (sra I32:$src1, u5_0ImmPred:$src2), 1), (i32 1)), 556 (S2_asr_i_r_rnd IntRegs:$src1, u5_0ImmPred:$src2)>; 557 558def : Pat<(not I64:$src1), 559 (A2_notp DoubleRegs:$src1)>; 560 561// Count leading zeros. 562def: Pat<(ctlz I32:$Rs), (S2_cl0 I32:$Rs)>; 563def: Pat<(i32 (trunc (ctlz I64:$Rss))), (S2_cl0p I64:$Rss)>; 564 565// Count trailing zeros: 32-bit. 566def: Pat<(cttz I32:$Rs), (S2_ct0 I32:$Rs)>; 567 568// Count leading ones. 569def: Pat<(ctlz (not I32:$Rs)), (S2_cl1 I32:$Rs)>; 570def: Pat<(i32 (trunc (ctlz (not I64:$Rss)))), (S2_cl1p I64:$Rss)>; 571 572// Count trailing ones: 32-bit. 573def: Pat<(cttz (not I32:$Rs)), (S2_ct1 I32:$Rs)>; 574 575let AddedComplexity = 20 in { // Complexity greater than and/or/xor 576 def: Pat<(and I32:$Rs, IsNPow2_32:$V), 577 (S2_clrbit_i IntRegs:$Rs, (LogN2_32 $V))>; 578 def: Pat<(or I32:$Rs, IsPow2_32:$V), 579 (S2_setbit_i IntRegs:$Rs, (Log2_32 $V))>; 580 def: Pat<(xor I32:$Rs, IsPow2_32:$V), 581 (S2_togglebit_i IntRegs:$Rs, (Log2_32 $V))>; 582 583 def: Pat<(and I32:$Rs, (not (shl 1, I32:$Rt))), 584 (S2_clrbit_r IntRegs:$Rs, IntRegs:$Rt)>; 585 def: Pat<(or I32:$Rs, (shl 1, I32:$Rt)), 586 (S2_setbit_r IntRegs:$Rs, IntRegs:$Rt)>; 587 def: Pat<(xor I32:$Rs, (shl 1, I32:$Rt)), 588 (S2_togglebit_r IntRegs:$Rs, IntRegs:$Rt)>; 589} 590 591// Clr/set/toggle bit for 64-bit values with immediate bit index. 592let AddedComplexity = 20 in { // Complexity greater than and/or/xor 593 def: Pat<(and I64:$Rss, IsNPow2_64L:$V), 594 (REG_SEQUENCE DoubleRegs, 595 (i32 (HiReg $Rss)), isub_hi, 596 (S2_clrbit_i (LoReg $Rss), (LogN2_64 $V)), isub_lo)>; 597 def: Pat<(and I64:$Rss, IsNPow2_64H:$V), 598 (REG_SEQUENCE DoubleRegs, 599 (S2_clrbit_i (HiReg $Rss), (UDEC32 (i32 (LogN2_64 $V)))), 600 isub_hi, 601 (i32 (LoReg $Rss)), isub_lo)>; 602 603 def: Pat<(or I64:$Rss, IsPow2_64L:$V), 604 (REG_SEQUENCE DoubleRegs, 605 (i32 (HiReg $Rss)), isub_hi, 606 (S2_setbit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>; 607 def: Pat<(or I64:$Rss, IsPow2_64H:$V), 608 (REG_SEQUENCE DoubleRegs, 609 (S2_setbit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))), 610 isub_hi, 611 (i32 (LoReg $Rss)), isub_lo)>; 612 613 def: Pat<(xor I64:$Rss, IsPow2_64L:$V), 614 (REG_SEQUENCE DoubleRegs, 615 (i32 (HiReg $Rss)), isub_hi, 616 (S2_togglebit_i (LoReg $Rss), (Log2_64 $V)), isub_lo)>; 617 def: Pat<(xor I64:$Rss, IsPow2_64H:$V), 618 (REG_SEQUENCE DoubleRegs, 619 (S2_togglebit_i (HiReg $Rss), (UDEC32 (i32 (Log2_64 $V)))), 620 isub_hi, 621 (i32 (LoReg $Rss)), isub_lo)>; 622} 623 624let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. 625 def: Pat<(i1 (setne (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)), 626 (S2_tstbit_i IntRegs:$Rs, u5_0ImmPred:$u5)>; 627 def: Pat<(i1 (setne (and (shl 1, I32:$Rt), I32:$Rs), 0)), 628 (S2_tstbit_r IntRegs:$Rs, IntRegs:$Rt)>; 629 def: Pat<(i1 (trunc I32:$Rs)), 630 (S2_tstbit_i IntRegs:$Rs, 0)>; 631 def: Pat<(i1 (trunc I64:$Rs)), 632 (S2_tstbit_i (LoReg DoubleRegs:$Rs), 0)>; 633} 634 635let AddedComplexity = 20 in { // Complexity greater than compare reg-imm. 636 def: Pat<(i1 (seteq (and I32:$Rs, u6_0ImmPred:$u6), 0)), 637 (C2_bitsclri IntRegs:$Rs, u6_0ImmPred:$u6)>; 638 def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), 0)), 639 (C2_bitsclr IntRegs:$Rs, IntRegs:$Rt)>; 640} 641 642let AddedComplexity = 10 in // Complexity greater than compare reg-reg. 643def: Pat<(i1 (seteq (and I32:$Rs, I32:$Rt), IntRegs:$Rt)), 644 (C2_bitsset IntRegs:$Rs, IntRegs:$Rt)>; 645 646def: Pat<(or (or (shl (or (shl (i32 (extloadi8 (add I32:$b, 3))), 647 (i32 8)), 648 (i32 (zextloadi8 (add I32:$b, 2)))), 649 (i32 16)), 650 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))), 651 (zextloadi8 I32:$b)), 652 (A2_swiz (L2_loadri_io IntRegs:$b, 0))>; 653 654// Patterns for loads of i1: 655def: Pat<(i1 (load AddrFI:$fi)), 656 (C2_tfrrp (L2_loadrub_io AddrFI:$fi, 0))>; 657def: Pat<(i1 (load (add I32:$Rs, s32_0ImmPred:$Off))), 658 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, imm:$Off))>; 659def: Pat<(i1 (load I32:$Rs)), 660 (C2_tfrrp (L2_loadrub_io IntRegs:$Rs, 0))>; 661 662def I1toI32: OutPatFrag<(ops node:$Rs), 663 (C2_muxii (i1 $Rs), 1, 0)>; 664 665def I32toI1: OutPatFrag<(ops node:$Rs), 666 (i1 (C2_tfrrp (i32 $Rs)))>; 667 668defm: Storexm_pat<store, I1, s32_0ImmPred, I1toI32, S2_storerb_io>; 669def: Storexm_simple_pat<store, I1, I1toI32, S2_storerb_io>; 670 671def: Pat<(sra I64:$src, u6_0ImmPred:$u6), 672 (S2_asr_i_p DoubleRegs:$src, imm:$u6)>; 673def: Pat<(srl I64:$src, u6_0ImmPred:$u6), 674 (S2_lsr_i_p DoubleRegs:$src, imm:$u6)>; 675def: Pat<(shl I64:$src, u6_0ImmPred:$u6), 676 (S2_asl_i_p DoubleRegs:$src, imm:$u6)>; 677 678let AddedComplexity = 100 in 679def: Pat<(add I32:$Rt, (shl I32:$Rs, u3_0ImmPred:$u3)), 680 (S2_addasl_rrri IntRegs:$Rt, IntRegs:$Rs, imm:$u3)>; 681 682def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDTNone, [SDNPHasChain]>; 683def: Pat<(HexagonBARRIER), (Y2_barrier)>; 684 685def: Pat<(IsOrAdd (i32 AddrFI:$Rs), s32_0ImmPred:$off), 686 (PS_fi (i32 AddrFI:$Rs), s32_0ImmPred:$off)>; 687 688 689// Support for generating global address. 690// Taken from X86InstrInfo.td. 691def SDTHexagonCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 692 SDTCisVT<1, i32>, 693 SDTCisPtrTy<0>]>; 694def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>; 695def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>; 696 697// Map TLS addressses to A2_tfrsi. 698def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16_0Ext:$addr)>; 699def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16_0Ext:$label)>; 700 701def: Pat<(i64 imm:$v), (CONST64 imm:$v)>; 702def: Pat<(i1 0), (PS_false)>; 703def: Pat<(i1 1), (PS_true)>; 704 705// Pseudo instructions. 706def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 707def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 708 SDTCisVT<1, i32> ]>; 709 710def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 711 [SDNPHasChain, SDNPOutGlue]>; 712def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 713 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 714 715def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 716 717// For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain, 718// Optional Flag and Variable Arguments. 719// Its 1 Operand has pointer type. 720def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall, 721 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 722 723 724def: Pat<(callseq_start timm:$amt), 725 (ADJCALLSTACKDOWN imm:$amt)>; 726def: Pat<(callseq_end timm:$amt1, timm:$amt2), 727 (ADJCALLSTACKUP imm:$amt1, imm:$amt2)>; 728 729//Tail calls. 730def: Pat<(HexagonTCRet tglobaladdr:$dst), 731 (PS_tailcall_i tglobaladdr:$dst)>; 732def: Pat<(HexagonTCRet texternalsym:$dst), 733 (PS_tailcall_i texternalsym:$dst)>; 734def: Pat<(HexagonTCRet I32:$dst), 735 (PS_tailcall_r I32:$dst)>; 736 737// Map from r0 = and(r1, 65535) to r0 = zxth(r1) 738def: Pat<(and I32:$src1, 65535), 739 (A2_zxth IntRegs:$src1)>; 740 741// Map from r0 = and(r1, 255) to r0 = zxtb(r1). 742def: Pat<(and I32:$src1, 255), 743 (A2_zxtb IntRegs:$src1)>; 744 745// Map Add(p1, true) to p1 = not(p1). 746// Add(p1, false) should never be produced, 747// if it does, it got to be mapped to NOOP. 748def: Pat<(add I1:$src1, -1), 749 (C2_not PredRegs:$src1)>; 750 751// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i). 752def: Pat<(select (not I1:$src1), s8_0ImmPred:$src2, s32_0ImmPred:$src3), 753 (C2_muxii PredRegs:$src1, s32_0ImmPred:$src3, s8_0ImmPred:$src2)>; 754 755// Map from p0 = pnot(p0); r0 = select(p0, #i, r1) 756// => r0 = C2_muxir(p0, r1, #i) 757def: Pat<(select (not I1:$src1), s32_0ImmPred:$src2, 758 I32:$src3), 759 (C2_muxir PredRegs:$src1, IntRegs:$src3, s32_0ImmPred:$src2)>; 760 761// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) 762// => r0 = C2_muxri (p0, #i, r1) 763def: Pat<(select (not I1:$src1), IntRegs:$src2, s32_0ImmPred:$src3), 764 (C2_muxri PredRegs:$src1, s32_0ImmPred:$src3, IntRegs:$src2)>; 765 766// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. 767def: Pat<(brcond (not I1:$src1), bb:$offset), 768 (J2_jumpf PredRegs:$src1, bb:$offset)>; 769 770// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = A2_sxtw(Rss.lo). 771def: Pat<(i64 (sext_inreg I64:$src1, i32)), 772 (A2_sxtw (LoReg DoubleRegs:$src1))>; 773 774// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = A2_sxtw(A2_sxth(Rss.lo)). 775def: Pat<(i64 (sext_inreg I64:$src1, i16)), 776 (A2_sxtw (A2_sxth (LoReg DoubleRegs:$src1)))>; 777 778// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = A2_sxtw(A2_sxtb(Rss.lo)). 779def: Pat<(i64 (sext_inreg I64:$src1, i8)), 780 (A2_sxtw (A2_sxtb (LoReg DoubleRegs:$src1)))>; 781 782// We want to prevent emitting pnot's as much as possible. 783// Map brcond with an unsupported setcc to a J2_jumpf. 784def : Pat <(brcond (i1 (setne I32:$src1, I32:$src2)), 785 bb:$offset), 786 (J2_jumpf (C2_cmpeq I32:$src1, I32:$src2), 787 bb:$offset)>; 788 789def : Pat <(brcond (i1 (setne I32:$src1, s10_0ImmPred:$src2)), 790 bb:$offset), 791 (J2_jumpf (C2_cmpeqi I32:$src1, s10_0ImmPred:$src2), bb:$offset)>; 792 793def: Pat<(brcond (i1 (setne I1:$src1, (i1 -1))), bb:$offset), 794 (J2_jumpf PredRegs:$src1, bb:$offset)>; 795 796def: Pat<(brcond (i1 (setne I1:$src1, (i1 0))), bb:$offset), 797 (J2_jumpt PredRegs:$src1, bb:$offset)>; 798 799// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1) 800def: Pat<(brcond (i1 (setlt I32:$src1, s8_0ImmPred:$src2)), bb:$offset), 801 (J2_jumpf (C2_cmpgti IntRegs:$src1, (SDEC1 s8_0ImmPred:$src2)), 802 bb:$offset)>; 803 804// Map from a 64-bit select to an emulated 64-bit mux. 805// Hexagon does not support 64-bit MUXes; so emulate with combines. 806def: Pat<(select I1:$src1, I64:$src2, 807 I64:$src3), 808 (A2_combinew (C2_mux PredRegs:$src1, (HiReg DoubleRegs:$src2), 809 (HiReg DoubleRegs:$src3)), 810 (C2_mux PredRegs:$src1, (LoReg DoubleRegs:$src2), 811 (LoReg DoubleRegs:$src3)))>; 812 813// Map from a 1-bit select to logical ops. 814// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3). 815def: Pat<(select I1:$src1, I1:$src2, I1:$src3), 816 (C2_or (C2_and PredRegs:$src1, PredRegs:$src2), 817 (C2_and (C2_not PredRegs:$src1), PredRegs:$src3))>; 818 819// Map for truncating from 64 immediates to 32 bit immediates. 820def: Pat<(i32 (trunc I64:$src)), 821 (LoReg DoubleRegs:$src)>; 822 823// Map for truncating from i64 immediates to i1 bit immediates. 824def: Pat<(i1 (trunc I64:$src)), 825 (C2_tfrrp (LoReg DoubleRegs:$src))>; 826 827// rs <= rt -> !(rs > rt). 828let AddedComplexity = 30 in 829def: Pat<(i1 (setle I32:$src1, s32_0ImmPred:$src2)), 830 (C2_not (C2_cmpgti IntRegs:$src1, s32_0ImmPred:$src2))>; 831 832// rs <= rt -> !(rs > rt). 833def : Pat<(i1 (setle I32:$src1, I32:$src2)), 834 (i1 (C2_not (C2_cmpgt I32:$src1, I32:$src2)))>; 835 836// Rss <= Rtt -> !(Rss > Rtt). 837def: Pat<(i1 (setle I64:$src1, I64:$src2)), 838 (C2_not (C2_cmpgtp DoubleRegs:$src1, DoubleRegs:$src2))>; 839 840// Map cmpne -> cmpeq. 841// Hexagon_TODO: We should improve on this. 842// rs != rt -> !(rs == rt). 843let AddedComplexity = 30 in 844def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)), 845 (C2_not (C2_cmpeqi IntRegs:$src1, s32_0ImmPred:$src2))>; 846 847// Convert setne back to xor for hexagon since we compute w/ pred registers. 848def: Pat<(i1 (setne I1:$src1, I1:$src2)), 849 (C2_xor PredRegs:$src1, PredRegs:$src2)>; 850 851// Map cmpne(Rss) -> !cmpew(Rss). 852// rs != rt -> !(rs == rt). 853def: Pat<(i1 (setne I64:$src1, I64:$src2)), 854 (C2_not (C2_cmpeqp DoubleRegs:$src1, DoubleRegs:$src2))>; 855 856// Map cmpge(Rs, Rt) -> !cmpgt(Rs, Rt). 857// rs >= rt -> !(rt > rs). 858def : Pat <(i1 (setge I32:$src1, I32:$src2)), 859 (i1 (C2_not (i1 (C2_cmpgt I32:$src2, I32:$src1))))>; 860 861// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1) 862let AddedComplexity = 30 in 863def: Pat<(i1 (setge I32:$src1, s32_0ImmPred:$src2)), 864 (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>; 865 866// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). 867// rss >= rtt -> !(rtt > rss). 868def: Pat<(i1 (setge I64:$src1, I64:$src2)), 869 (C2_not (C2_cmpgtp DoubleRegs:$src2, DoubleRegs:$src1))>; 870 871// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm). 872// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1). 873// rs < rt -> !(rs >= rt). 874let AddedComplexity = 30 in 875def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)), 876 (C2_not (C2_cmpgti IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2)))>; 877 878// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs) 879def: Pat<(i1 (setuge I32:$src1, 0)), 880 (C2_cmpeq IntRegs:$src1, IntRegs:$src1)>; 881 882// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1) 883def: Pat<(i1 (setuge I32:$src1, u32_0ImmPred:$src2)), 884 (C2_cmpgtui IntRegs:$src1, (UDEC1 u32_0ImmPred:$src2))>; 885 886// Generate cmpgtu(Rs, #u9) 887def: Pat<(i1 (setugt I32:$src1, u32_0ImmPred:$src2)), 888 (C2_cmpgtui IntRegs:$src1, u32_0ImmPred:$src2)>; 889 890// Map from Rs >= Rt -> !(Rt > Rs). 891// rs >= rt -> !(rt > rs). 892def: Pat<(i1 (setuge I64:$src1, I64:$src2)), 893 (C2_not (C2_cmpgtup DoubleRegs:$src2, DoubleRegs:$src1))>; 894 895// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1). 896// Map from (Rs <= Rt) -> !(Rs > Rt). 897def: Pat<(i1 (setule I64:$src1, I64:$src2)), 898 (C2_not (C2_cmpgtup DoubleRegs:$src1, DoubleRegs:$src2))>; 899 900// Sign extends. 901// i1 -> i32 902def: Pat<(i32 (sext I1:$src1)), 903 (C2_muxii PredRegs:$src1, -1, 0)>; 904 905// i1 -> i64 906def: Pat<(i64 (sext I1:$src1)), 907 (A2_combinew (A2_tfrsi -1), (C2_muxii PredRegs:$src1, -1, 0))>; 908 909// Zero extends. 910// i1 -> i32 911def: Pat<(i32 (zext I1:$src1)), 912 (C2_muxii PredRegs:$src1, 1, 0)>; 913 914// Map from Rs = Pd to Pd = mux(Pd, #1, #0) 915def: Pat<(i32 (anyext I1:$src1)), 916 (C2_muxii PredRegs:$src1, 1, 0)>; 917 918// Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0)) 919def: Pat<(i64 (anyext I1:$src1)), 920 (A2_sxtw (C2_muxii PredRegs:$src1, 1, 0))>; 921 922// Clear the sign bit in a 64-bit register. 923def ClearSign : OutPatFrag<(ops node:$Rss), 924 (A2_combinew (S2_clrbit_i (HiReg $Rss), 31), (LoReg $Rss))>; 925 926def MulHU : OutPatFrag<(ops node:$Rss, node:$Rtt), 927 (A2_addp 928 (M2_dpmpyuu_acc_s0 929 (S2_lsr_i_p 930 (A2_addp 931 (M2_dpmpyuu_acc_s0 932 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (LoReg $Rtt)), 32), 933 (HiReg $Rss), 934 (LoReg $Rtt)), 935 (A2_combinew (A2_tfrsi 0), 936 (LoReg (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt))))), 937 32), 938 (HiReg $Rss), 939 (HiReg $Rtt)), 940 (S2_lsr_i_p (M2_dpmpyuu_s0 (LoReg $Rss), (HiReg $Rtt)), 32))>; 941 942// Multiply 64-bit unsigned and use upper result. 943def : Pat <(mulhu I64:$Rss, I64:$Rtt), (MulHU $Rss, $Rtt)>; 944 945// Multiply 64-bit signed and use upper result. 946// 947// For two signed 64-bit integers A and B, let A' and B' denote A and B 948// with the sign bit cleared. Then A = -2^63*s(A) + A', where s(A) is the 949// sign bit of A (and identically for B). With this notation, the signed 950// product A*B can be written as: 951// AB = (-2^63 s(A) + A') * (-2^63 s(B) + B') 952// = 2^126 s(A)s(B) - 2^63 [s(A)B'+s(B)A'] + A'B' 953// = 2^126 s(A)s(B) + 2^63 [s(A)B'+s(B)A'] + A'B' - 2*2^63 [s(A)B'+s(B)A'] 954// = (unsigned product AB) - 2^64 [s(A)B'+s(B)A'] 955 956def : Pat <(mulhs I64:$Rss, I64:$Rtt), 957 (A2_subp 958 (MulHU $Rss, $Rtt), 959 (A2_addp 960 (A2_andp (S2_asr_i_p $Rss, 63), (ClearSign $Rtt)), 961 (A2_andp (S2_asr_i_p $Rtt, 63), (ClearSign $Rss))))>; 962 963// Hexagon specific ISD nodes. 964def SDTHexagonALLOCA : SDTypeProfile<1, 2, 965 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 966def HexagonALLOCA : SDNode<"HexagonISD::ALLOCA", SDTHexagonALLOCA, 967 [SDNPHasChain]>; 968 969 970def: Pat<(HexagonALLOCA I32:$Rs, (i32 imm:$A)), 971 (PS_alloca IntRegs:$Rs, imm:$A)>; 972 973def HexagonJT: SDNode<"HexagonISD::JT", SDTIntUnaryOp>; 974def HexagonCP: SDNode<"HexagonISD::CP", SDTIntUnaryOp>; 975 976def: Pat<(HexagonJT tjumptable:$dst), (A2_tfrsi imm:$dst)>; 977def: Pat<(HexagonCP tconstpool:$dst), (A2_tfrsi imm:$dst)>; 978 979let AddedComplexity = 100 in 980def: Pat<(add I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 981def: Pat<(sub I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 982def: Pat<(and I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 983def: Pat<(or I32:$src1, (sra I32:$Rs, u5_0ImmPred:$u5)), (S2_asr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 984 985let AddedComplexity = 100 in 986def: Pat<(add I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 987def: Pat<(sub I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 988def: Pat<(and I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 989def: Pat<(or I64:$src1, (sra I64:$Rs, u6_0ImmPred:$u5)), (S2_asr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 990 991let AddedComplexity = 100 in 992def: Pat<(add I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 993def: Pat<(sub I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 994def: Pat<(and I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 995def: Pat<(or I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 996let AddedComplexity = 100 in 997def: Pat<(xor I32:$src1, (srl I32:$Rs, u5_0ImmPred:$u5)), (S2_lsr_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 998 999let AddedComplexity = 100 in 1000def: Pat<(add I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1001def: Pat<(sub I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1002def: Pat<(and I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1003def: Pat<(or I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1004let AddedComplexity = 100 in 1005def: Pat<(xor I64:$src1, (srl I64:$Rs, u6_0ImmPred:$u5)), (S2_lsr_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1006 1007let AddedComplexity = 100 in 1008def: Pat<(add I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_acc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 1009def: Pat<(sub I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_nac IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 1010def: Pat<(and I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_and IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 1011def: Pat<(or I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_or IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 1012let AddedComplexity = 100 in 1013def: Pat<(xor I32:$src1, (shl I32:$Rs, u5_0ImmPred:$u5)), (S2_asl_i_r_xacc IntRegs:$src1, IntRegs:$Rs, u5_0ImmPred:$u5)>; 1014 1015let AddedComplexity = 100 in 1016def: Pat<(add I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1017def: Pat<(sub I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1018def: Pat<(and I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_and DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1019def: Pat<(or I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_or DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1020let AddedComplexity = 100 in 1021def: Pat<(xor I64:$src1, (shl I64:$Rs, u6_0ImmPred:$u5)), (S2_asl_i_p_xacc DoubleRegs:$src1, DoubleRegs:$Rs, u6_0ImmPred:$u5)>; 1022 1023let AddedComplexity = 100 in 1024def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1025def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1026def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1027def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_asl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1028let AddedComplexity = 100 in 1029def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1030def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1031def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1032def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1033def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_asl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1034 1035let AddedComplexity = 100 in 1036def: Pat<(add I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1037def: Pat<(sub I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1038def: Pat<(and I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1039def: Pat<(or I32:$src1, (sra I32:$Rs, I32:$Rt)), (S2_asr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1040let AddedComplexity = 100 in 1041def: Pat<(add I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1042def: Pat<(sub I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1043def: Pat<(and I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1044def: Pat<(or I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1045def: Pat<(xor I64:$src1, (sra I64:$Rs, I32:$Rt)), (S2_asr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1046 1047let AddedComplexity = 100 in 1048def: Pat<(add I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1049def: Pat<(sub I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1050def: Pat<(and I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1051def: Pat<(or I32:$src1, (srl I32:$Rs, I32:$Rt)), (S2_lsr_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1052let AddedComplexity = 100 in 1053def: Pat<(add I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1054def: Pat<(sub I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1055def: Pat<(and I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1056def: Pat<(or I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1057def: Pat<(xor I64:$src1, (srl I64:$Rs, I32:$Rt)), (S2_lsr_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1058 1059let AddedComplexity = 100 in 1060def: Pat<(add I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_acc IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1061def: Pat<(sub I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_nac IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1062def: Pat<(and I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_and IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1063def: Pat<(or I32:$src1, (shl I32:$Rs, I32:$Rt)), (S2_lsl_r_r_or IntRegs:$src1, IntRegs:$Rs, IntRegs:$Rt)>; 1064let AddedComplexity = 100 in 1065def: Pat<(add I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_acc DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1066def: Pat<(sub I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_nac DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1067def: Pat<(and I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_and DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1068def: Pat<(or I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_or DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1069def: Pat<(xor I64:$src1, (shl I64:$Rs, I32:$Rt)), (S2_lsl_r_p_xor DoubleRegs:$src1, DoubleRegs:$Rs, IntRegs:$Rt)>; 1070 1071def: Pat<(sra I64:$src1, I32:$src2), (S2_asr_r_p DoubleRegs:$src1, IntRegs:$src2)>; 1072def: Pat<(srl I64:$src1, I32:$src2), (S2_lsr_r_p DoubleRegs:$src1, IntRegs:$src2)>; 1073def: Pat<(shl I64:$src1, I32:$src2), (S2_asl_r_p DoubleRegs:$src1, IntRegs:$src2)>; 1074def: Pat<(shl I64:$src1, I32:$src2), (S2_lsl_r_p DoubleRegs:$src1, IntRegs:$src2)>; 1075 1076def: Pat<(sra I32:$src1, I32:$src2), (S2_asr_r_r IntRegs:$src1, IntRegs:$src2)>; 1077def: Pat<(srl I32:$src1, I32:$src2), (S2_lsr_r_r IntRegs:$src1, IntRegs:$src2)>; 1078def: Pat<(shl I32:$src1, I32:$src2), (S2_asl_r_r IntRegs:$src1, IntRegs:$src2)>; 1079def: Pat<(shl I32:$src1, I32:$src2), (S2_lsl_r_r IntRegs:$src1, IntRegs:$src2)>; 1080 1081def SDTHexagonINSERT: 1082 SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 1083 SDTCisInt<0>, SDTCisVT<3, i32>, SDTCisVT<4, i32>]>; 1084def SDTHexagonINSERTRP: 1085 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, 1086 SDTCisInt<0>, SDTCisVT<3, i64>]>; 1087 1088def HexagonINSERT : SDNode<"HexagonISD::INSERT", SDTHexagonINSERT>; 1089def HexagonINSERTRP : SDNode<"HexagonISD::INSERTRP", SDTHexagonINSERTRP>; 1090 1091def: Pat<(HexagonINSERT I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2), 1092 (S2_insert I32:$Rs, I32:$Rt, u5_0ImmPred:$u1, u5_0ImmPred:$u2)>; 1093def: Pat<(HexagonINSERT I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2), 1094 (S2_insertp I64:$Rs, I64:$Rt, u6_0ImmPred:$u1, u6_0ImmPred:$u2)>; 1095def: Pat<(HexagonINSERTRP I32:$Rs, I32:$Rt, I64:$Ru), 1096 (S2_insert_rp I32:$Rs, I32:$Rt, I64:$Ru)>; 1097def: Pat<(HexagonINSERTRP I64:$Rs, I64:$Rt, I64:$Ru), 1098 (S2_insertp_rp I64:$Rs, I64:$Rt, I64:$Ru)>; 1099 1100let AddedComplexity = 100 in 1101def: Pat<(or (or (shl (HexagonINSERT (i32 (zextloadi8 (add I32:$b, 2))), 1102 (i32 (extloadi8 (add I32:$b, 3))), 1103 24, 8), 1104 (i32 16)), 1105 (shl (i32 (zextloadi8 (add I32:$b, 1))), (i32 8))), 1106 (zextloadi8 I32:$b)), 1107 (A2_swiz (L2_loadri_io I32:$b, 0))>; 1108 1109def SDTHexagonEXTRACTU: 1110 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>, 1111 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>; 1112def SDTHexagonEXTRACTURP: 1113 SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<1>, 1114 SDTCisVT<2, i64>]>; 1115 1116def HexagonEXTRACTU : SDNode<"HexagonISD::EXTRACTU", SDTHexagonEXTRACTU>; 1117def HexagonEXTRACTURP : SDNode<"HexagonISD::EXTRACTURP", SDTHexagonEXTRACTURP>; 1118 1119def: Pat<(HexagonEXTRACTU I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3), 1120 (S2_extractu I32:$src1, u5_0ImmPred:$src2, u5_0ImmPred:$src3)>; 1121def: Pat<(HexagonEXTRACTU I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3), 1122 (S2_extractup I64:$src1, u6_0ImmPred:$src2, u6_0ImmPred:$src3)>; 1123def: Pat<(HexagonEXTRACTURP I32:$src1, I64:$src2), 1124 (S2_extractu_rp I32:$src1, I64:$src2)>; 1125def: Pat<(HexagonEXTRACTURP I64:$src1, I64:$src2), 1126 (S2_extractup_rp I64:$src1, I64:$src2)>; 1127 1128def n8_0ImmPred: PatLeaf<(i32 imm), [{ 1129 int64_t V = N->getSExtValue(); 1130 return -255 <= V && V <= 0; 1131}]>; 1132 1133// Change the sign of the immediate for Rd=-mpyi(Rs,#u8) 1134def: Pat<(mul I32:$src1, (ineg n8_0ImmPred:$src2)), 1135 (M2_mpysin IntRegs:$src1, u8_0ImmPred:$src2)>; 1136 1137multiclass MinMax_pats_p<PatFrag Op, InstHexagon Inst, InstHexagon SwapInst> { 1138 defm: T_MinMax_pats<Op, I64, Inst, SwapInst>; 1139} 1140 1141def: Pat<(add (Sext64 I32:$Rs), I64:$Rt), 1142 (A2_addsp IntRegs:$Rs, DoubleRegs:$Rt)>; 1143 1144let AddedComplexity = 200 in { 1145 defm: MinMax_pats_p<setge, A2_maxp, A2_minp>; 1146 defm: MinMax_pats_p<setgt, A2_maxp, A2_minp>; 1147 defm: MinMax_pats_p<setle, A2_minp, A2_maxp>; 1148 defm: MinMax_pats_p<setlt, A2_minp, A2_maxp>; 1149 defm: MinMax_pats_p<setuge, A2_maxup, A2_minup>; 1150 defm: MinMax_pats_p<setugt, A2_maxup, A2_minup>; 1151 defm: MinMax_pats_p<setule, A2_minup, A2_maxup>; 1152 defm: MinMax_pats_p<setult, A2_minup, A2_maxup>; 1153} 1154 1155def callv3 : SDNode<"HexagonISD::CALL", SDT_SPCall, 1156 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; 1157 1158def callv3nr : SDNode<"HexagonISD::CALLnr", SDT_SPCall, 1159 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; 1160 1161 1162// Map call instruction 1163def : Pat<(callv3 I32:$dst), 1164 (J2_callr I32:$dst)>; 1165def : Pat<(callv3 tglobaladdr:$dst), 1166 (J2_call tglobaladdr:$dst)>; 1167def : Pat<(callv3 texternalsym:$dst), 1168 (J2_call texternalsym:$dst)>; 1169def : Pat<(callv3 tglobaltlsaddr:$dst), 1170 (J2_call tglobaltlsaddr:$dst)>; 1171 1172def : Pat<(callv3nr I32:$dst), 1173 (PS_callr_nr I32:$dst)>; 1174def : Pat<(callv3nr tglobaladdr:$dst), 1175 (PS_call_nr tglobaladdr:$dst)>; 1176def : Pat<(callv3nr texternalsym:$dst), 1177 (PS_call_nr texternalsym:$dst)>; 1178 1179 1180def addrga: PatLeaf<(i32 AddrGA:$Addr)>; 1181def addrgp: PatLeaf<(i32 AddrGP:$Addr)>; 1182 1183 1184// Pats for instruction selection. 1185 1186// A class to embed the usual comparison patfrags within a zext to i32. 1187// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same 1188// names, or else the frag's "body" won't match the operands. 1189class CmpInReg<PatFrag Op> 1190 : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>; 1191 1192def: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>; 1193def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>; 1194 1195def: T_cmp32_rr_pat<C4_cmpneq, setne, i1>; 1196def: T_cmp32_rr_pat<C4_cmplte, setle, i1>; 1197def: T_cmp32_rr_pat<C4_cmplteu, setule, i1>; 1198 1199def: T_cmp32_rr_pat<C4_cmplte, RevCmp<setge>, i1>; 1200def: T_cmp32_rr_pat<C4_cmplteu, RevCmp<setuge>, i1>; 1201 1202let AddedComplexity = 100 in { 1203 def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt), 1204 255), 0)), 1205 (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt)>; 1206 def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt), 1207 255), 0)), 1208 (C2_not (A4_cmpbeq IntRegs:$Rs, IntRegs:$Rt))>; 1209 def: Pat<(i1 (seteq (and (xor I32:$Rs, I32:$Rt), 1210 65535), 0)), 1211 (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt)>; 1212 def: Pat<(i1 (setne (and (xor I32:$Rs, I32:$Rt), 1213 65535), 0)), 1214 (C2_not (A4_cmpheq IntRegs:$Rs, IntRegs:$Rt))>; 1215} 1216 1217def: Pat<(i32 (zext (i1 (seteq I32:$Rs, s32_0ImmPred:$s8)))), 1218 (A4_rcmpeqi IntRegs:$Rs, s32_0ImmPred:$s8)>; 1219def: Pat<(i32 (zext (i1 (setne I32:$Rs, s32_0ImmPred:$s8)))), 1220 (A4_rcmpneqi IntRegs:$Rs, s32_0ImmPred:$s8)>; 1221 1222// Preserve the S2_tstbit_r generation 1223def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, I32:$src2)), 1224 I32:$src1)), 0)))), 1225 (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>; 1226 1227// The complexity of the combines involving immediates should be greater 1228// than the complexity of the combine with two registers. 1229let AddedComplexity = 50 in { 1230def: Pat<(HexagonCOMBINE IntRegs:$r, s32_0ImmPred:$i), 1231 (A4_combineri IntRegs:$r, s32_0ImmPred:$i)>; 1232 1233def: Pat<(HexagonCOMBINE s32_0ImmPred:$i, IntRegs:$r), 1234 (A4_combineir s32_0ImmPred:$i, IntRegs:$r)>; 1235} 1236 1237// The complexity of the combine with two immediates should be greater than 1238// the complexity of a combine involving a register. 1239let AddedComplexity = 75 in { 1240def: Pat<(HexagonCOMBINE s8_0ImmPred:$s8, u32_0ImmPred:$u6), 1241 (A4_combineii imm:$s8, imm:$u6)>; 1242def: Pat<(HexagonCOMBINE s32_0ImmPred:$s8, s8_0ImmPred:$S8), 1243 (A2_combineii imm:$s8, imm:$S8)>; 1244} 1245 1246 1247def ToZext64: OutPatFrag<(ops node:$Rs), 1248 (i64 (A4_combineir 0, (i32 $Rs)))>; 1249def ToSext64: OutPatFrag<(ops node:$Rs), 1250 (i64 (A2_sxtw (i32 $Rs)))>; 1251 1252// Patterns to generate indexed loads with different forms of the address: 1253// - frameindex, 1254// - base + offset, 1255// - base (without offset). 1256multiclass Loadxm_pat<PatFrag Load, ValueType VT, PatFrag ValueMod, 1257 PatLeaf ImmPred, InstHexagon MI> { 1258 def: Pat<(VT (Load AddrFI:$fi)), 1259 (VT (ValueMod (MI AddrFI:$fi, 0)))>; 1260 def: Pat<(VT (Load (add AddrFI:$fi, ImmPred:$Off))), 1261 (VT (ValueMod (MI AddrFI:$fi, imm:$Off)))>; 1262 def: Pat<(VT (Load (add IntRegs:$Rs, ImmPred:$Off))), 1263 (VT (ValueMod (MI IntRegs:$Rs, imm:$Off)))>; 1264 def: Pat<(VT (Load I32:$Rs)), 1265 (VT (ValueMod (MI IntRegs:$Rs, 0)))>; 1266} 1267 1268defm: Loadxm_pat<extloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>; 1269defm: Loadxm_pat<extloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>; 1270defm: Loadxm_pat<extloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>; 1271defm: Loadxm_pat<zextloadi1, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>; 1272defm: Loadxm_pat<zextloadi8, i64, ToZext64, s32_0ImmPred, L2_loadrub_io>; 1273defm: Loadxm_pat<zextloadi16, i64, ToZext64, s31_1ImmPred, L2_loadruh_io>; 1274defm: Loadxm_pat<sextloadi8, i64, ToSext64, s32_0ImmPred, L2_loadrb_io>; 1275defm: Loadxm_pat<sextloadi16, i64, ToSext64, s31_1ImmPred, L2_loadrh_io>; 1276 1277// Map Rdd = anyext(Rs) -> Rdd = combine(#0, Rs). 1278def: Pat<(Aext64 I32:$src1), (ToZext64 IntRegs:$src1)>; 1279 1280multiclass T_LoadAbsReg_Pat <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> { 1281 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2), 1282 (HexagonCONST32 tglobaladdr:$src3)))), 1283 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3)>; 1284 def : Pat <(VT (ldOp (add IntRegs:$src1, 1285 (HexagonCONST32 tglobaladdr:$src2)))), 1286 (MI IntRegs:$src1, 0, tglobaladdr:$src2)>; 1287 1288 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2), 1289 (HexagonCONST32 tconstpool:$src3)))), 1290 (MI IntRegs:$src1, u2_0ImmPred:$src2, tconstpool:$src3)>; 1291 def : Pat <(VT (ldOp (add IntRegs:$src1, 1292 (HexagonCONST32 tconstpool:$src2)))), 1293 (MI IntRegs:$src1, 0, tconstpool:$src2)>; 1294 1295 def : Pat <(VT (ldOp (add (shl IntRegs:$src1, u2_0ImmPred:$src2), 1296 (HexagonCONST32 tjumptable:$src3)))), 1297 (MI IntRegs:$src1, u2_0ImmPred:$src2, tjumptable:$src3)>; 1298 def : Pat <(VT (ldOp (add IntRegs:$src1, 1299 (HexagonCONST32 tjumptable:$src2)))), 1300 (MI IntRegs:$src1, 0, tjumptable:$src2)>; 1301} 1302 1303let AddedComplexity = 60 in { 1304defm : T_LoadAbsReg_Pat <sextloadi8, L4_loadrb_ur>; 1305defm : T_LoadAbsReg_Pat <zextloadi8, L4_loadrub_ur>; 1306defm : T_LoadAbsReg_Pat <extloadi8, L4_loadrub_ur>; 1307 1308defm : T_LoadAbsReg_Pat <sextloadi16, L4_loadrh_ur>; 1309defm : T_LoadAbsReg_Pat <zextloadi16, L4_loadruh_ur>; 1310defm : T_LoadAbsReg_Pat <extloadi16, L4_loadruh_ur>; 1311 1312defm : T_LoadAbsReg_Pat <load, L4_loadri_ur>; 1313defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, i64>; 1314} 1315 1316// 'def pats' for load instructions with base + register offset and non-zero 1317// immediate value. Immediate value is used to left-shift the second 1318// register operand. 1319class Loadxs_pat<PatFrag Load, ValueType VT, InstHexagon MI> 1320 : Pat<(VT (Load (add I32:$Rs, 1321 (i32 (shl I32:$Rt, u2_0ImmPred:$u2))))), 1322 (VT (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2))>; 1323 1324let AddedComplexity = 40 in { 1325 def: Loadxs_pat<extloadi8, i32, L4_loadrub_rr>; 1326 def: Loadxs_pat<zextloadi8, i32, L4_loadrub_rr>; 1327 def: Loadxs_pat<sextloadi8, i32, L4_loadrb_rr>; 1328 def: Loadxs_pat<extloadi16, i32, L4_loadruh_rr>; 1329 def: Loadxs_pat<zextloadi16, i32, L4_loadruh_rr>; 1330 def: Loadxs_pat<sextloadi16, i32, L4_loadrh_rr>; 1331 def: Loadxs_pat<load, i32, L4_loadri_rr>; 1332 def: Loadxs_pat<load, i64, L4_loadrd_rr>; 1333} 1334 1335// 'def pats' for load instruction base + register offset and 1336// zero immediate value. 1337class Loadxs_simple_pat<PatFrag Load, ValueType VT, InstHexagon MI> 1338 : Pat<(VT (Load (add I32:$Rs, I32:$Rt))), 1339 (VT (MI IntRegs:$Rs, IntRegs:$Rt, 0))>; 1340 1341let AddedComplexity = 20 in { 1342 def: Loadxs_simple_pat<extloadi8, i32, L4_loadrub_rr>; 1343 def: Loadxs_simple_pat<zextloadi8, i32, L4_loadrub_rr>; 1344 def: Loadxs_simple_pat<sextloadi8, i32, L4_loadrb_rr>; 1345 def: Loadxs_simple_pat<extloadi16, i32, L4_loadruh_rr>; 1346 def: Loadxs_simple_pat<zextloadi16, i32, L4_loadruh_rr>; 1347 def: Loadxs_simple_pat<sextloadi16, i32, L4_loadrh_rr>; 1348 def: Loadxs_simple_pat<load, i32, L4_loadri_rr>; 1349 def: Loadxs_simple_pat<load, i64, L4_loadrd_rr>; 1350} 1351 1352// zext i1->i64 1353def: Pat<(i64 (zext I1:$src1)), 1354 (ToZext64 (C2_muxii PredRegs:$src1, 1, 0))>; 1355 1356// zext i32->i64 1357def: Pat<(Zext64 I32:$src1), 1358 (ToZext64 IntRegs:$src1)>; 1359 1360let AddedComplexity = 40 in 1361multiclass T_StoreAbsReg_Pats <InstHexagon MI, RegisterClass RC, ValueType VT, 1362 PatFrag stOp> { 1363 def : Pat<(stOp (VT RC:$src4), 1364 (add (shl I32:$src1, u2_0ImmPred:$src2), 1365 u32_0ImmPred:$src3)), 1366 (MI IntRegs:$src1, u2_0ImmPred:$src2, u32_0ImmPred:$src3, RC:$src4)>; 1367 1368 def : Pat<(stOp (VT RC:$src4), 1369 (add (shl IntRegs:$src1, u2_0ImmPred:$src2), 1370 (HexagonCONST32 tglobaladdr:$src3))), 1371 (MI IntRegs:$src1, u2_0ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>; 1372 1373 def : Pat<(stOp (VT RC:$src4), 1374 (add IntRegs:$src1, (HexagonCONST32 tglobaladdr:$src3))), 1375 (MI IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>; 1376} 1377 1378defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, i64, store>; 1379defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, i32, store>; 1380defm : T_StoreAbsReg_Pats <S4_storerb_ur, IntRegs, i32, truncstorei8>; 1381defm : T_StoreAbsReg_Pats <S4_storerh_ur, IntRegs, i32, truncstorei16>; 1382 1383class Storexs_pat<PatFrag Store, PatFrag Value, InstHexagon MI> 1384 : Pat<(Store Value:$Ru, (add I32:$Rs, 1385 (i32 (shl I32:$Rt, u2_0ImmPred:$u2)))), 1386 (MI IntRegs:$Rs, IntRegs:$Rt, imm:$u2, Value:$Ru)>; 1387 1388let AddedComplexity = 40 in { 1389 def: Storexs_pat<truncstorei8, I32, S4_storerb_rr>; 1390 def: Storexs_pat<truncstorei16, I32, S4_storerh_rr>; 1391 def: Storexs_pat<store, I32, S4_storeri_rr>; 1392 def: Storexs_pat<store, I64, S4_storerd_rr>; 1393} 1394 1395def s30_2ProperPred : PatLeaf<(i32 imm), [{ 1396 int64_t v = (int64_t)N->getSExtValue(); 1397 return isShiftedInt<30,2>(v) && !isShiftedInt<29,3>(v); 1398}]>; 1399def RoundTo8 : SDNodeXForm<imm, [{ 1400 int32_t Imm = N->getSExtValue(); 1401 return CurDAG->getTargetConstant(Imm & -8, SDLoc(N), MVT::i32); 1402}]>; 1403 1404let AddedComplexity = 40 in 1405def: Pat<(store I64:$Ru, (add I32:$Rs, s30_2ProperPred:$Off)), 1406 (S2_storerd_io (A2_addi I32:$Rs, 4), (RoundTo8 $Off), I64:$Ru)>; 1407 1408class Store_rr_pat<PatFrag Store, PatFrag Value, InstHexagon MI> 1409 : Pat<(Store Value:$Ru, (add I32:$Rs, I32:$Rt)), 1410 (MI IntRegs:$Rs, IntRegs:$Rt, 0, Value:$Ru)>; 1411 1412let AddedComplexity = 20 in { 1413 def: Store_rr_pat<truncstorei8, I32, S4_storerb_rr>; 1414 def: Store_rr_pat<truncstorei16, I32, S4_storerh_rr>; 1415 def: Store_rr_pat<store, I32, S4_storeri_rr>; 1416 def: Store_rr_pat<store, I64, S4_storerd_rr>; 1417} 1418 1419 1420def IMM_BYTE : SDNodeXForm<imm, [{ 1421 // -1 etc is represented as 255 etc 1422 // assigning to a byte restores our desired signed value. 1423 int8_t imm = N->getSExtValue(); 1424 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32); 1425}]>; 1426 1427def IMM_HALF : SDNodeXForm<imm, [{ 1428 // -1 etc is represented as 65535 etc 1429 // assigning to a short restores our desired signed value. 1430 int16_t imm = N->getSExtValue(); 1431 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32); 1432}]>; 1433 1434def IMM_WORD : SDNodeXForm<imm, [{ 1435 // -1 etc can be represented as 4294967295 etc 1436 // Currently, it's not doing this. But some optimization 1437 // might convert -1 to a large +ve number. 1438 // assigning to a word restores our desired signed value. 1439 int32_t imm = N->getSExtValue(); 1440 return CurDAG->getTargetConstant(imm, SDLoc(N), MVT::i32); 1441}]>; 1442 1443def ToImmByte : OutPatFrag<(ops node:$R), (IMM_BYTE $R)>; 1444def ToImmHalf : OutPatFrag<(ops node:$R), (IMM_HALF $R)>; 1445def ToImmWord : OutPatFrag<(ops node:$R), (IMM_WORD $R)>; 1446 1447// Emit store-immediate, but only when the stored value will not be constant- 1448// extended. The reason for that is that there is no pass that can optimize 1449// constant extenders in store-immediate instructions. In some cases we can 1450// end up will a number of such stores, all of which store the same extended 1451// value (e.g. after unrolling a loop that initializes floating point array). 1452 1453// Predicates to determine if the 16-bit immediate is expressible as a sign- 1454// extended 8-bit immediate. Store-immediate-halfword will ignore any bits 1455// beyond 0..15, so we don't care what is in there. 1456 1457def i16in8ImmPred: PatLeaf<(i32 imm), [{ 1458 int64_t v = (int16_t)N->getSExtValue(); 1459 return v == (int64_t)(int8_t)v; 1460}]>; 1461 1462// Predicates to determine if the 32-bit immediate is expressible as a sign- 1463// extended 8-bit immediate. 1464def i32in8ImmPred: PatLeaf<(i32 imm), [{ 1465 int64_t v = (int32_t)N->getSExtValue(); 1466 return v == (int64_t)(int8_t)v; 1467}]>; 1468 1469 1470let AddedComplexity = 40 in { 1471 // Even though the offset is not extendable in the store-immediate, we 1472 // can still generate the fi# in the base address. If the final offset 1473 // is not valid for the instruction, we will replace it with a scratch 1474 // register. 1475// def: Storexm_fi_pat <truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>; 1476// def: Storexm_fi_pat <truncstorei16, i16in8ImmPred, ToImmHalf, 1477// S4_storeirh_io>; 1478// def: Storexm_fi_pat <store, i32in8ImmPred, ToImmWord, S4_storeiri_io>; 1479 1480// defm: Storexm_fi_add_pat <truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte, 1481// S4_storeirb_io>; 1482// defm: Storexm_fi_add_pat <truncstorei16, i16in8ImmPred, u6_1ImmPred, 1483// ToImmHalf, S4_storeirh_io>; 1484// defm: Storexm_fi_add_pat <store, i32in8ImmPred, u6_2ImmPred, ToImmWord, 1485// S4_storeiri_io>; 1486 1487 defm: Storexm_add_pat<truncstorei8, s32_0ImmPred, u6_0ImmPred, ToImmByte, 1488 S4_storeirb_io>; 1489 defm: Storexm_add_pat<truncstorei16, i16in8ImmPred, u6_1ImmPred, ToImmHalf, 1490 S4_storeirh_io>; 1491 defm: Storexm_add_pat<store, i32in8ImmPred, u6_2ImmPred, ToImmWord, 1492 S4_storeiri_io>; 1493} 1494 1495def: Storexm_simple_pat<truncstorei8, s32_0ImmPred, ToImmByte, S4_storeirb_io>; 1496def: Storexm_simple_pat<truncstorei16, s32_0ImmPred, ToImmHalf, S4_storeirh_io>; 1497def: Storexm_simple_pat<store, s32_0ImmPred, ToImmWord, S4_storeiri_io>; 1498 1499// op(Ps, op(Pt, Pu)) 1500class LogLog_pat<SDNode Op1, SDNode Op2, InstHexagon MI> 1501 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, I1:$Pu))), 1502 (MI I1:$Ps, I1:$Pt, I1:$Pu)>; 1503 1504// op(Ps, op(Pt, ~Pu)) 1505class LogLogNot_pat<SDNode Op1, SDNode Op2, InstHexagon MI> 1506 : Pat<(i1 (Op1 I1:$Ps, (Op2 I1:$Pt, (not I1:$Pu)))), 1507 (MI I1:$Ps, I1:$Pt, I1:$Pu)>; 1508 1509def: LogLog_pat<and, and, C4_and_and>; 1510def: LogLog_pat<and, or, C4_and_or>; 1511def: LogLog_pat<or, and, C4_or_and>; 1512def: LogLog_pat<or, or, C4_or_or>; 1513 1514def: LogLogNot_pat<and, and, C4_and_andn>; 1515def: LogLogNot_pat<and, or, C4_and_orn>; 1516def: LogLogNot_pat<or, and, C4_or_andn>; 1517def: LogLogNot_pat<or, or, C4_or_orn>; 1518 1519//===----------------------------------------------------------------------===// 1520// PIC: Support for PIC compilations. The patterns and SD nodes defined 1521// below are needed to support code generation for PIC 1522//===----------------------------------------------------------------------===// 1523 1524def SDT_HexagonAtGot 1525 : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32>]>; 1526def SDT_HexagonAtPcrel 1527 : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 1528 1529// AT_GOT address-of-GOT, address-of-global, offset-in-global 1530def HexagonAtGot : SDNode<"HexagonISD::AT_GOT", SDT_HexagonAtGot>; 1531// AT_PCREL address-of-global 1532def HexagonAtPcrel : SDNode<"HexagonISD::AT_PCREL", SDT_HexagonAtPcrel>; 1533 1534def: Pat<(HexagonAtGot I32:$got, I32:$addr, (i32 0)), 1535 (L2_loadri_io I32:$got, imm:$addr)>; 1536def: Pat<(HexagonAtGot I32:$got, I32:$addr, s30_2ImmPred:$off), 1537 (A2_addi (L2_loadri_io I32:$got, imm:$addr), imm:$off)>; 1538def: Pat<(HexagonAtPcrel I32:$addr), 1539 (C4_addipc imm:$addr)>; 1540 1541def: Pat<(i64 (and I64:$Rs, (i64 (not I64:$Rt)))), 1542 (A4_andnp DoubleRegs:$Rs, DoubleRegs:$Rt)>; 1543def: Pat<(i64 (or I64:$Rs, (i64 (not I64:$Rt)))), 1544 (A4_ornp DoubleRegs:$Rs, DoubleRegs:$Rt)>; 1545 1546def: Pat<(add I32:$Rs, (add I32:$Ru, s32_0ImmPred:$s6)), 1547 (S4_addaddi IntRegs:$Rs, IntRegs:$Ru, imm:$s6)>; 1548 1549// Rd=add(Rs,sub(#s6,Ru)) 1550def: Pat<(add I32:$src1, (sub s32_0ImmPred:$src2, 1551 I32:$src3)), 1552 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>; 1553 1554// Rd=sub(add(Rs,#s6),Ru) 1555def: Pat<(sub (add I32:$src1, s32_0ImmPred:$src2), 1556 I32:$src3), 1557 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>; 1558 1559// Rd=add(sub(Rs,Ru),#s6) 1560def: Pat<(add (sub I32:$src1, I32:$src3), 1561 (s32_0ImmPred:$src2)), 1562 (S4_subaddi IntRegs:$src1, s32_0ImmPred:$src2, IntRegs:$src3)>; 1563 1564def: Pat<(xor I64:$dst2, 1565 (xor I64:$Rss, I64:$Rtt)), 1566 (M4_xor_xacc DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt)>; 1567def: Pat<(or I32:$Ru, (and (i32 IntRegs:$_src_), s32_0ImmPred:$s10)), 1568 (S4_or_andix IntRegs:$Ru, IntRegs:$_src_, imm:$s10)>; 1569 1570def: Pat<(or I32:$src1, (and I32:$Rs, s32_0ImmPred:$s10)), 1571 (S4_or_andi IntRegs:$src1, IntRegs:$Rs, imm:$s10)>; 1572 1573def: Pat<(or I32:$src1, (or I32:$Rs, s32_0ImmPred:$s10)), 1574 (S4_or_ori IntRegs:$src1, IntRegs:$Rs, imm:$s10)>; 1575 1576 1577 1578// Count trailing zeros: 64-bit. 1579def: Pat<(i32 (trunc (cttz I64:$Rss))), (S2_ct0p I64:$Rss)>; 1580 1581// Count trailing ones: 64-bit. 1582def: Pat<(i32 (trunc (cttz (not I64:$Rss)))), (S2_ct1p I64:$Rss)>; 1583 1584// Define leading/trailing patterns that require zero-extensions to 64 bits. 1585def: Pat<(i64 (ctlz I64:$Rss)), (ToZext64 (S2_cl0p I64:$Rss))>; 1586def: Pat<(i64 (cttz I64:$Rss)), (ToZext64 (S2_ct0p I64:$Rss))>; 1587def: Pat<(i64 (ctlz (not I64:$Rss))), (ToZext64 (S2_cl1p I64:$Rss))>; 1588def: Pat<(i64 (cttz (not I64:$Rss))), (ToZext64 (S2_ct1p I64:$Rss))>; 1589 1590 1591let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. 1592 def: Pat<(i1 (seteq (and (shl 1, u5_0ImmPred:$u5), I32:$Rs), 0)), 1593 (S4_ntstbit_i I32:$Rs, u5_0ImmPred:$u5)>; 1594 def: Pat<(i1 (seteq (and (shl 1, I32:$Rt), I32:$Rs), 0)), 1595 (S4_ntstbit_r I32:$Rs, I32:$Rt)>; 1596} 1597 1598// Add extra complexity to prefer these instructions over bitsset/bitsclr. 1599// The reason is that tstbit/ntstbit can be folded into a compound instruction: 1600// if ([!]tstbit(...)) jump ... 1601let AddedComplexity = 100 in 1602def: Pat<(i1 (setne (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))), 1603 (S2_tstbit_i I32:$Rs, (Log2_32 imm:$u5))>; 1604 1605let AddedComplexity = 100 in 1606def: Pat<(i1 (seteq (and I32:$Rs, (i32 IsPow2_32:$u5)), (i32 0))), 1607 (S4_ntstbit_i I32:$Rs, (Log2_32 imm:$u5))>; 1608 1609// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be 1610// represented as a compare against "value & 0xFF", which is an exact match 1611// for cmpb (same for cmph). The patterns below do not contain any additional 1612// complexity that would make them preferable, and if they were actually used 1613// instead of cmpb/cmph, they would result in a compare against register that 1614// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF). 1615def: Pat<(i1 (setne (and I32:$Rs, u6_0ImmPred:$u6), 0)), 1616 (C4_nbitsclri I32:$Rs, u6_0ImmPred:$u6)>; 1617def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)), 1618 (C4_nbitsclr I32:$Rs, I32:$Rt)>; 1619def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)), 1620 (C4_nbitsset I32:$Rs, I32:$Rt)>; 1621 1622 1623def: Pat<(add (mul I32:$Rs, u6_0ImmPred:$U6), u32_0ImmPred:$u6), 1624 (M4_mpyri_addi imm:$u6, IntRegs:$Rs, imm:$U6)>; 1625def: Pat<(add (mul I32:$Rs, I32:$Rt), u32_0ImmPred:$u6), 1626 (M4_mpyrr_addi imm:$u6, IntRegs:$Rs, IntRegs:$Rt)>; 1627 1628def: Pat<(add I32:$src1, (mul I32:$src3, u6_2ImmPred:$src2)), 1629 (M4_mpyri_addr_u2 IntRegs:$src1, imm:$src2, IntRegs:$src3)>; 1630def: Pat<(add I32:$src1, (mul I32:$src3, u32_0ImmPred:$src2)), 1631 (M4_mpyri_addr IntRegs:$src1, IntRegs:$src3, imm:$src2)>; 1632 1633def: Pat<(add I32:$Ru, (mul (i32 IntRegs:$_src_), I32:$Rs)), 1634 (M4_mpyrr_addr IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs)>; 1635 1636def: T_vcmp_pat<A4_vcmpbgt, setgt, v8i8>; 1637 1638class T_Shift_CommOp_pat<InstHexagon MI, SDNode Op, SDNode ShOp> 1639 : Pat<(Op (ShOp IntRegs:$Rx, u5_0ImmPred:$U5), u32_0ImmPred:$u8), 1640 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>; 1641 1642let AddedComplexity = 200 in { 1643 def : T_Shift_CommOp_pat <S4_addi_asl_ri, add, shl>; 1644 def : T_Shift_CommOp_pat <S4_addi_lsr_ri, add, srl>; 1645 def : T_Shift_CommOp_pat <S4_andi_asl_ri, and, shl>; 1646 def : T_Shift_CommOp_pat <S4_andi_lsr_ri, and, srl>; 1647} 1648 1649let AddedComplexity = 30 in { 1650 def : T_Shift_CommOp_pat <S4_ori_asl_ri, or, shl>; 1651 def : T_Shift_CommOp_pat <S4_ori_lsr_ri, or, srl>; 1652} 1653 1654class T_Shift_Op_pat<InstHexagon MI, SDNode Op, SDNode ShOp> 1655 : Pat<(Op u32_0ImmPred:$u8, (ShOp IntRegs:$Rx, u5_0ImmPred:$U5)), 1656 (MI u32_0ImmPred:$u8, IntRegs:$Rx, u5_0ImmPred:$U5)>; 1657 1658def : T_Shift_Op_pat <S4_subi_asl_ri, sub, shl>; 1659def : T_Shift_Op_pat <S4_subi_lsr_ri, sub, srl>; 1660 1661let AddedComplexity = 200 in { 1662 def: Pat<(add addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)), 1663 (S4_addi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>; 1664 def: Pat<(add addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)), 1665 (S4_addi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>; 1666 def: Pat<(sub addrga:$addr, (shl I32:$src2, u5_0ImmPred:$src3)), 1667 (S4_subi_asl_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>; 1668 def: Pat<(sub addrga:$addr, (srl I32:$src2, u5_0ImmPred:$src3)), 1669 (S4_subi_lsr_ri addrga:$addr, IntRegs:$src2, u5_0ImmPred:$src3)>; 1670} 1671 1672def: Pat<(shl s6_0ImmPred:$s6, I32:$Rt), 1673 (S4_lsli imm:$s6, IntRegs:$Rt)>; 1674 1675 1676//===----------------------------------------------------------------------===// 1677// MEMOP 1678//===----------------------------------------------------------------------===// 1679 1680def m5_0Imm8Pred : PatLeaf<(i32 imm), [{ 1681 int8_t V = N->getSExtValue(); 1682 return -32 < V && V <= -1; 1683}]>; 1684 1685def m5_0Imm16Pred : PatLeaf<(i32 imm), [{ 1686 int16_t V = N->getSExtValue(); 1687 return -32 < V && V <= -1; 1688}]>; 1689 1690def m5_0ImmPred : PatLeaf<(i32 imm), [{ 1691 int64_t V = N->getSExtValue(); 1692 return -31 <= V && V <= -1; 1693}]>; 1694 1695def IsNPow2_8 : PatLeaf<(i32 imm), [{ 1696 uint8_t NV = ~N->getZExtValue(); 1697 return isPowerOf2_32(NV); 1698}]>; 1699 1700def IsNPow2_16 : PatLeaf<(i32 imm), [{ 1701 uint16_t NV = ~N->getZExtValue(); 1702 return isPowerOf2_32(NV); 1703}]>; 1704 1705def Log2_8 : SDNodeXForm<imm, [{ 1706 uint8_t V = N->getZExtValue(); 1707 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); 1708}]>; 1709 1710def Log2_16 : SDNodeXForm<imm, [{ 1711 uint16_t V = N->getZExtValue(); 1712 return CurDAG->getTargetConstant(Log2_32(V), SDLoc(N), MVT::i32); 1713}]>; 1714 1715def LogN2_8 : SDNodeXForm<imm, [{ 1716 uint8_t NV = ~N->getZExtValue(); 1717 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); 1718}]>; 1719 1720def LogN2_16 : SDNodeXForm<imm, [{ 1721 uint16_t NV = ~N->getZExtValue(); 1722 return CurDAG->getTargetConstant(Log2_32(NV), SDLoc(N), MVT::i32); 1723}]>; 1724 1725def NegImm8 : SDNodeXForm<imm, [{ 1726 int8_t NV = -N->getSExtValue(); 1727 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32); 1728}]>; 1729 1730def NegImm16 : SDNodeXForm<imm, [{ 1731 int16_t NV = -N->getSExtValue(); 1732 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32); 1733}]>; 1734 1735def NegImm32 : SDNodeXForm<imm, [{ 1736 int32_t NV = -N->getSExtValue(); 1737 return CurDAG->getTargetConstant(NV, SDLoc(N), MVT::i32); 1738}]>; 1739 1740def IdImm : SDNodeXForm<imm, [{ return SDValue(N, 0); }]>; 1741 1742multiclass Memopxr_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper, 1743 InstHexagon MI> { 1744 // Addr: i32 1745 def: Pat<(Store (Oper (Load I32:$Rs), I32:$A), I32:$Rs), 1746 (MI I32:$Rs, 0, I32:$A)>; 1747 // Addr: fi 1748 def: Pat<(Store (Oper (Load AddrFI:$Rs), I32:$A), AddrFI:$Rs), 1749 (MI AddrFI:$Rs, 0, I32:$A)>; 1750} 1751 1752multiclass Memopxr_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, 1753 SDNode Oper, InstHexagon MI> { 1754 // Addr: i32 1755 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), I32:$A), 1756 (add I32:$Rs, ImmPred:$Off)), 1757 (MI I32:$Rs, imm:$Off, I32:$A)>; 1758 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), I32:$A), 1759 (IsOrAdd I32:$Rs, ImmPred:$Off)), 1760 (MI I32:$Rs, imm:$Off, I32:$A)>; 1761 // Addr: fi 1762 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), I32:$A), 1763 (add AddrFI:$Rs, ImmPred:$Off)), 1764 (MI AddrFI:$Rs, imm:$Off, I32:$A)>; 1765 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), I32:$A), 1766 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), 1767 (MI AddrFI:$Rs, imm:$Off, I32:$A)>; 1768} 1769 1770multiclass Memopxr_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, 1771 SDNode Oper, InstHexagon MI> { 1772 defm: Memopxr_simple_pat <Load, Store, Oper, MI>; 1773 defm: Memopxr_add_pat <Load, Store, ImmPred, Oper, MI>; 1774} 1775 1776let AddedComplexity = 180 in { 1777 // add reg 1778 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, add, 1779 /*anyext*/ L4_add_memopb_io>; 1780 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, 1781 /*sext*/ L4_add_memopb_io>; 1782 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, 1783 /*zext*/ L4_add_memopb_io>; 1784 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, add, 1785 /*anyext*/ L4_add_memoph_io>; 1786 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, 1787 /*sext*/ L4_add_memoph_io>; 1788 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, 1789 /*zext*/ L4_add_memoph_io>; 1790 defm: Memopxr_pat<load, store, u6_2ImmPred, add, L4_add_memopw_io>; 1791 1792 // sub reg 1793 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, 1794 /*anyext*/ L4_sub_memopb_io>; 1795 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, 1796 /*sext*/ L4_sub_memopb_io>; 1797 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, 1798 /*zext*/ L4_sub_memopb_io>; 1799 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, 1800 /*anyext*/ L4_sub_memoph_io>; 1801 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, 1802 /*sext*/ L4_sub_memoph_io>; 1803 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, 1804 /*zext*/ L4_sub_memoph_io>; 1805 defm: Memopxr_pat<load, store, u6_2ImmPred, sub, L4_sub_memopw_io>; 1806 1807 // and reg 1808 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, and, 1809 /*anyext*/ L4_and_memopb_io>; 1810 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, 1811 /*sext*/ L4_and_memopb_io>; 1812 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, 1813 /*zext*/ L4_and_memopb_io>; 1814 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, and, 1815 /*anyext*/ L4_and_memoph_io>; 1816 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, 1817 /*sext*/ L4_and_memoph_io>; 1818 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, 1819 /*zext*/ L4_and_memoph_io>; 1820 defm: Memopxr_pat<load, store, u6_2ImmPred, and, L4_and_memopw_io>; 1821 1822 // or reg 1823 defm: Memopxr_pat<extloadi8, truncstorei8, u6_0ImmPred, or, 1824 /*anyext*/ L4_or_memopb_io>; 1825 defm: Memopxr_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, 1826 /*sext*/ L4_or_memopb_io>; 1827 defm: Memopxr_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, 1828 /*zext*/ L4_or_memopb_io>; 1829 defm: Memopxr_pat<extloadi16, truncstorei16, u6_1ImmPred, or, 1830 /*anyext*/ L4_or_memoph_io>; 1831 defm: Memopxr_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, 1832 /*sext*/ L4_or_memoph_io>; 1833 defm: Memopxr_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, 1834 /*zext*/ L4_or_memoph_io>; 1835 defm: Memopxr_pat<load, store, u6_2ImmPred, or, L4_or_memopw_io>; 1836} 1837 1838 1839multiclass Memopxi_simple_pat<PatFrag Load, PatFrag Store, SDNode Oper, 1840 PatFrag Arg, SDNodeXForm ArgMod, 1841 InstHexagon MI> { 1842 // Addr: i32 1843 def: Pat<(Store (Oper (Load I32:$Rs), Arg:$A), I32:$Rs), 1844 (MI I32:$Rs, 0, (ArgMod Arg:$A))>; 1845 // Addr: fi 1846 def: Pat<(Store (Oper (Load AddrFI:$Rs), Arg:$A), AddrFI:$Rs), 1847 (MI AddrFI:$Rs, 0, (ArgMod Arg:$A))>; 1848} 1849 1850multiclass Memopxi_add_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, 1851 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod, 1852 InstHexagon MI> { 1853 // Addr: i32 1854 def: Pat<(Store (Oper (Load (add I32:$Rs, ImmPred:$Off)), Arg:$A), 1855 (add I32:$Rs, ImmPred:$Off)), 1856 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>; 1857 def: Pat<(Store (Oper (Load (IsOrAdd I32:$Rs, ImmPred:$Off)), Arg:$A), 1858 (IsOrAdd I32:$Rs, ImmPred:$Off)), 1859 (MI I32:$Rs, imm:$Off, (ArgMod Arg:$A))>; 1860 // Addr: fi 1861 def: Pat<(Store (Oper (Load (add AddrFI:$Rs, ImmPred:$Off)), Arg:$A), 1862 (add AddrFI:$Rs, ImmPred:$Off)), 1863 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>; 1864 def: Pat<(Store (Oper (Load (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), Arg:$A), 1865 (IsOrAdd AddrFI:$Rs, ImmPred:$Off)), 1866 (MI AddrFI:$Rs, imm:$Off, (ArgMod Arg:$A))>; 1867} 1868 1869multiclass Memopxi_pat<PatFrag Load, PatFrag Store, PatFrag ImmPred, 1870 SDNode Oper, PatFrag Arg, SDNodeXForm ArgMod, 1871 InstHexagon MI> { 1872 defm: Memopxi_simple_pat <Load, Store, Oper, Arg, ArgMod, MI>; 1873 defm: Memopxi_add_pat <Load, Store, ImmPred, Oper, Arg, ArgMod, MI>; 1874} 1875 1876 1877let AddedComplexity = 200 in { 1878 // add imm 1879 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred, 1880 /*anyext*/ IdImm, L4_iadd_memopb_io>; 1881 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred, 1882 /*sext*/ IdImm, L4_iadd_memopb_io>; 1883 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, u5_0ImmPred, 1884 /*zext*/ IdImm, L4_iadd_memopb_io>; 1885 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred, 1886 /*anyext*/ IdImm, L4_iadd_memoph_io>; 1887 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred, 1888 /*sext*/ IdImm, L4_iadd_memoph_io>; 1889 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, u5_0ImmPred, 1890 /*zext*/ IdImm, L4_iadd_memoph_io>; 1891 defm: Memopxi_pat<load, store, u6_2ImmPred, add, u5_0ImmPred, IdImm, 1892 L4_iadd_memopw_io>; 1893 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred, 1894 /*anyext*/ NegImm8, L4_iadd_memopb_io>; 1895 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred, 1896 /*sext*/ NegImm8, L4_iadd_memopb_io>; 1897 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, m5_0Imm8Pred, 1898 /*zext*/ NegImm8, L4_iadd_memopb_io>; 1899 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred, 1900 /*anyext*/ NegImm16, L4_iadd_memoph_io>; 1901 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred, 1902 /*sext*/ NegImm16, L4_iadd_memoph_io>; 1903 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, m5_0Imm16Pred, 1904 /*zext*/ NegImm16, L4_iadd_memoph_io>; 1905 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, m5_0ImmPred, NegImm32, 1906 L4_iadd_memopw_io>; 1907 1908 // sub imm 1909 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred, 1910 /*anyext*/ IdImm, L4_isub_memopb_io>; 1911 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred, 1912 /*sext*/ IdImm, L4_isub_memopb_io>; 1913 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, sub, u5_0ImmPred, 1914 /*zext*/ IdImm, L4_isub_memopb_io>; 1915 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred, 1916 /*anyext*/ IdImm, L4_isub_memoph_io>; 1917 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred, 1918 /*sext*/ IdImm, L4_isub_memoph_io>; 1919 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, sub, u5_0ImmPred, 1920 /*zext*/ IdImm, L4_isub_memoph_io>; 1921 defm: Memopxi_pat<load, store, u6_2ImmPred, sub, u5_0ImmPred, IdImm, 1922 L4_isub_memopw_io>; 1923 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred, 1924 /*anyext*/ NegImm8, L4_isub_memopb_io>; 1925 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred, 1926 /*sext*/ NegImm8, L4_isub_memopb_io>; 1927 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, add, m5_0Imm8Pred, 1928 /*zext*/ NegImm8, L4_isub_memopb_io>; 1929 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred, 1930 /*anyext*/ NegImm16, L4_isub_memoph_io>; 1931 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred, 1932 /*sext*/ NegImm16, L4_isub_memoph_io>; 1933 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, add, m5_0Imm16Pred, 1934 /*zext*/ NegImm16, L4_isub_memoph_io>; 1935 defm: Memopxi_pat<load, store, u6_2ImmPred, add, m5_0ImmPred, NegImm32, 1936 L4_isub_memopw_io>; 1937 1938 // clrbit imm 1939 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8, 1940 /*anyext*/ LogN2_8, L4_iand_memopb_io>; 1941 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8, 1942 /*sext*/ LogN2_8, L4_iand_memopb_io>; 1943 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, and, IsNPow2_8, 1944 /*zext*/ LogN2_8, L4_iand_memopb_io>; 1945 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16, 1946 /*anyext*/ LogN2_16, L4_iand_memoph_io>; 1947 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16, 1948 /*sext*/ LogN2_16, L4_iand_memoph_io>; 1949 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, and, IsNPow2_16, 1950 /*zext*/ LogN2_16, L4_iand_memoph_io>; 1951 defm: Memopxi_pat<load, store, u6_2ImmPred, and, IsNPow2_32, 1952 LogN2_32, L4_iand_memopw_io>; 1953 1954 // setbit imm 1955 defm: Memopxi_pat<extloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32, 1956 /*anyext*/ Log2_8, L4_ior_memopb_io>; 1957 defm: Memopxi_pat<sextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32, 1958 /*sext*/ Log2_8, L4_ior_memopb_io>; 1959 defm: Memopxi_pat<zextloadi8, truncstorei8, u6_0ImmPred, or, IsPow2_32, 1960 /*zext*/ Log2_8, L4_ior_memopb_io>; 1961 defm: Memopxi_pat<extloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32, 1962 /*anyext*/ Log2_16, L4_ior_memoph_io>; 1963 defm: Memopxi_pat<sextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32, 1964 /*sext*/ Log2_16, L4_ior_memoph_io>; 1965 defm: Memopxi_pat<zextloadi16, truncstorei16, u6_1ImmPred, or, IsPow2_32, 1966 /*zext*/ Log2_16, L4_ior_memoph_io>; 1967 defm: Memopxi_pat<load, store, u6_2ImmPred, or, IsPow2_32, 1968 Log2_32, L4_ior_memopw_io>; 1969} 1970 1971def : T_CMP_pat <C4_cmpneqi, setne, s32_0ImmPred>; 1972def : T_CMP_pat <C4_cmpltei, setle, s32_0ImmPred>; 1973def : T_CMP_pat <C4_cmplteui, setule, u9_0ImmPred>; 1974 1975// Map cmplt(Rs, Imm) -> !cmpgt(Rs, Imm-1). 1976def: Pat<(i1 (setlt I32:$src1, s32_0ImmPred:$src2)), 1977 (C4_cmpltei IntRegs:$src1, (SDEC1 s32_0ImmPred:$src2))>; 1978 1979// rs != rt -> !(rs == rt). 1980def: Pat<(i1 (setne I32:$src1, s32_0ImmPred:$src2)), 1981 (C4_cmpneqi IntRegs:$src1, s32_0ImmPred:$src2)>; 1982 1983// For the sequence 1984// zext( setult ( and(Rs, 255), u8)) 1985// Use the isdigit transformation below 1986 1987 1988def u7_0PosImmPred : ImmLeaf<i32, [{ 1989 // True if the immediate fits in an 7-bit unsigned field and 1990 // is strictly greater than 0. 1991 return Imm > 0 && isUInt<7>(Imm); 1992}]>; 1993 1994 1995// Generate code of the form 'C2_muxii(cmpbgtui(Rdd, C-1),0,1)' 1996// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;. 1997// The isdigit transformation relies on two 'clever' aspects: 1998// 1) The data type is unsigned which allows us to eliminate a zero test after 1999// biasing the expression by 48. We are depending on the representation of 2000// the unsigned types, and semantics. 2001// 2) The front end has converted <= 9 into < 10 on entry to LLVM 2002// 2003// For the C code: 2004// retval = ((c>='0') & (c<='9')) ? 1 : 0; 2005// The code is transformed upstream of llvm into 2006// retval = (c-48) < 10 ? 1 : 0; 2007 2008let AddedComplexity = 139 in 2009def: Pat<(i32 (zext (i1 (setult (and I32:$src1, 255), u7_0PosImmPred:$src2)))), 2010 (C2_muxii (A4_cmpbgtui IntRegs:$src1, (UDEC1 imm:$src2)), 0, 1)>; 2011 2012class Loada_pat<PatFrag Load, ValueType VT, PatFrag Addr, InstHexagon MI> 2013 : Pat<(VT (Load Addr:$addr)), (MI Addr:$addr)>; 2014 2015class Loadam_pat<PatFrag Load, ValueType VT, PatFrag Addr, PatFrag ValueMod, 2016 InstHexagon MI> 2017 : Pat<(VT (Load Addr:$addr)), (ValueMod (MI Addr:$addr))>; 2018 2019class Storea_pat<PatFrag Store, PatFrag Value, PatFrag Addr, InstHexagon MI> 2020 : Pat<(Store Value:$val, Addr:$addr), (MI Addr:$addr, Value:$val)>; 2021 2022class Stoream_pat<PatFrag Store, PatFrag Value, PatFrag Addr, PatFrag ValueMod, 2023 InstHexagon MI> 2024 : Pat<(Store Value:$val, Addr:$addr), 2025 (MI Addr:$addr, (ValueMod Value:$val))>; 2026 2027let AddedComplexity = 30 in { 2028 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>; 2029 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>; 2030 def: Storea_pat<store, I32, addrga, PS_storeriabs>; 2031 def: Storea_pat<store, I64, addrga, PS_storerdabs>; 2032 2033 def: Stoream_pat<truncstorei8, I64, addrga, LoReg, PS_storerbabs>; 2034 def: Stoream_pat<truncstorei16, I64, addrga, LoReg, PS_storerhabs>; 2035 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>; 2036} 2037 2038def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, S2_storerbgp>; 2039def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, S2_storerhgp>; 2040def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, S2_storerigp>; 2041def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, S2_storerdgp>; 2042 2043let AddedComplexity = 100 in { 2044 def: Storea_pat<truncstorei8, I32, addrgp, S2_storerbgp>; 2045 def: Storea_pat<truncstorei16, I32, addrgp, S2_storerhgp>; 2046 def: Storea_pat<store, I32, addrgp, S2_storerigp>; 2047 def: Storea_pat<store, I64, addrgp, S2_storerdgp>; 2048 2049 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1" 2050 // to "r0 = 1; memw(#foo) = r0" 2051 let AddedComplexity = 100 in 2052 def: Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), 2053 (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>; 2054} 2055 2056class LoadAbs_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> 2057 : Pat <(VT (ldOp (HexagonCONST32 tglobaladdr:$absaddr))), 2058 (VT (MI tglobaladdr:$absaddr))>; 2059 2060let AddedComplexity = 30 in { 2061 def: LoadAbs_pats <load, PS_loadriabs>; 2062 def: LoadAbs_pats <zextloadi1, PS_loadrubabs>; 2063 def: LoadAbs_pats <sextloadi8, PS_loadrbabs>; 2064 def: LoadAbs_pats <extloadi8, PS_loadrubabs>; 2065 def: LoadAbs_pats <zextloadi8, PS_loadrubabs>; 2066 def: LoadAbs_pats <sextloadi16, PS_loadrhabs>; 2067 def: LoadAbs_pats <extloadi16, PS_loadruhabs>; 2068 def: LoadAbs_pats <zextloadi16, PS_loadruhabs>; 2069 def: LoadAbs_pats <load, PS_loadrdabs, i64>; 2070} 2071 2072let AddedComplexity = 30 in 2073def: Pat<(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$absaddr))), 2074 (ToZext64 (PS_loadrubabs tglobaladdr:$absaddr))>; 2075 2076def: Loada_pat<atomic_load_8, i32, addrgp, L2_loadrubgp>; 2077def: Loada_pat<atomic_load_16, i32, addrgp, L2_loadruhgp>; 2078def: Loada_pat<atomic_load_32, i32, addrgp, L2_loadrigp>; 2079def: Loada_pat<atomic_load_64, i64, addrgp, L2_loadrdgp>; 2080 2081def: Loadam_pat<load, i1, addrga, I32toI1, PS_loadrubabs>; 2082def: Loadam_pat<load, i1, addrgp, I32toI1, L2_loadrubgp>; 2083 2084def: Stoream_pat<store, I1, addrga, I1toI32, PS_storerbabs>; 2085def: Stoream_pat<store, I1, addrgp, I1toI32, S2_storerbgp>; 2086 2087// Map from load(globaladdress) -> mem[u][bhwd](#foo) 2088class LoadGP_pats <PatFrag ldOp, InstHexagon MI, ValueType VT = i32> 2089 : Pat <(VT (ldOp (HexagonCONST32_GP tglobaladdr:$global))), 2090 (VT (MI tglobaladdr:$global))>; 2091 2092let AddedComplexity = 100 in { 2093 def: LoadGP_pats <extloadi8, L2_loadrubgp>; 2094 def: LoadGP_pats <sextloadi8, L2_loadrbgp>; 2095 def: LoadGP_pats <zextloadi8, L2_loadrubgp>; 2096 def: LoadGP_pats <extloadi16, L2_loadruhgp>; 2097 def: LoadGP_pats <sextloadi16, L2_loadrhgp>; 2098 def: LoadGP_pats <zextloadi16, L2_loadruhgp>; 2099 def: LoadGP_pats <load, L2_loadrigp>; 2100 def: LoadGP_pats <load, L2_loadrdgp, i64>; 2101} 2102 2103// When the Interprocedural Global Variable optimizer realizes that a certain 2104// global variable takes only two constant values, it shrinks the global to 2105// a boolean. Catch those loads here in the following 3 patterns. 2106let AddedComplexity = 100 in { 2107 def: LoadGP_pats <extloadi1, L2_loadrubgp>; 2108 def: LoadGP_pats <zextloadi1, L2_loadrubgp>; 2109} 2110 2111// Transfer global address into a register 2112def: Pat<(HexagonCONST32 tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>; 2113def: Pat<(HexagonCONST32_GP tblockaddress:$Rs), (A2_tfrsi imm:$Rs)>; 2114def: Pat<(HexagonCONST32_GP tglobaladdr:$Rs), (A2_tfrsi imm:$Rs)>; 2115 2116let AddedComplexity = 30 in { 2117 def: Storea_pat<truncstorei8, I32, u32_0ImmPred, PS_storerbabs>; 2118 def: Storea_pat<truncstorei16, I32, u32_0ImmPred, PS_storerhabs>; 2119 def: Storea_pat<store, I32, u32_0ImmPred, PS_storeriabs>; 2120} 2121 2122let AddedComplexity = 30 in { 2123 def: Loada_pat<load, i32, u32_0ImmPred, PS_loadriabs>; 2124 def: Loada_pat<sextloadi8, i32, u32_0ImmPred, PS_loadrbabs>; 2125 def: Loada_pat<zextloadi8, i32, u32_0ImmPred, PS_loadrubabs>; 2126 def: Loada_pat<sextloadi16, i32, u32_0ImmPred, PS_loadrhabs>; 2127 def: Loada_pat<zextloadi16, i32, u32_0ImmPred, PS_loadruhabs>; 2128} 2129 2130// Indexed store word - global address. 2131// memw(Rs+#u6:2)=#S8 2132let AddedComplexity = 100 in 2133defm: Storex_add_pat<store, addrga, u6_2ImmPred, S4_storeiri_io>; 2134 2135// Load from a global address that has only one use in the current basic block. 2136let AddedComplexity = 100 in { 2137 def: Loada_pat<extloadi8, i32, addrga, PS_loadrubabs>; 2138 def: Loada_pat<sextloadi8, i32, addrga, PS_loadrbabs>; 2139 def: Loada_pat<zextloadi8, i32, addrga, PS_loadrubabs>; 2140 2141 def: Loada_pat<extloadi16, i32, addrga, PS_loadruhabs>; 2142 def: Loada_pat<sextloadi16, i32, addrga, PS_loadrhabs>; 2143 def: Loada_pat<zextloadi16, i32, addrga, PS_loadruhabs>; 2144 2145 def: Loada_pat<load, i32, addrga, PS_loadriabs>; 2146 def: Loada_pat<load, i64, addrga, PS_loadrdabs>; 2147} 2148 2149// Store to a global address that has only one use in the current basic block. 2150let AddedComplexity = 100 in { 2151 def: Storea_pat<truncstorei8, I32, addrga, PS_storerbabs>; 2152 def: Storea_pat<truncstorei16, I32, addrga, PS_storerhabs>; 2153 def: Storea_pat<store, I32, addrga, PS_storeriabs>; 2154 def: Storea_pat<store, I64, addrga, PS_storerdabs>; 2155 2156 def: Stoream_pat<truncstorei32, I64, addrga, LoReg, PS_storeriabs>; 2157} 2158 2159// i8/i16/i32 -> i64 loads 2160// We need a complexity of 120 here to override preceding handling of 2161// zextload. 2162let AddedComplexity = 120 in { 2163 def: Loadam_pat<extloadi8, i64, addrga, ToZext64, PS_loadrubabs>; 2164 def: Loadam_pat<sextloadi8, i64, addrga, ToSext64, PS_loadrbabs>; 2165 def: Loadam_pat<zextloadi8, i64, addrga, ToZext64, PS_loadrubabs>; 2166 2167 def: Loadam_pat<extloadi16, i64, addrga, ToZext64, PS_loadruhabs>; 2168 def: Loadam_pat<sextloadi16, i64, addrga, ToSext64, PS_loadrhabs>; 2169 def: Loadam_pat<zextloadi16, i64, addrga, ToZext64, PS_loadruhabs>; 2170 2171 def: Loadam_pat<extloadi32, i64, addrga, ToZext64, PS_loadriabs>; 2172 def: Loadam_pat<sextloadi32, i64, addrga, ToSext64, PS_loadriabs>; 2173 def: Loadam_pat<zextloadi32, i64, addrga, ToZext64, PS_loadriabs>; 2174} 2175 2176let AddedComplexity = 100 in { 2177 def: Loada_pat<extloadi8, i32, addrgp, PS_loadrubabs>; 2178 def: Loada_pat<sextloadi8, i32, addrgp, PS_loadrbabs>; 2179 def: Loada_pat<zextloadi8, i32, addrgp, PS_loadrubabs>; 2180 2181 def: Loada_pat<extloadi16, i32, addrgp, PS_loadruhabs>; 2182 def: Loada_pat<sextloadi16, i32, addrgp, PS_loadrhabs>; 2183 def: Loada_pat<zextloadi16, i32, addrgp, PS_loadruhabs>; 2184 2185 def: Loada_pat<load, i32, addrgp, PS_loadriabs>; 2186 def: Loada_pat<load, i64, addrgp, PS_loadrdabs>; 2187} 2188 2189let AddedComplexity = 100 in { 2190 def: Storea_pat<truncstorei8, I32, addrgp, PS_storerbabs>; 2191 def: Storea_pat<truncstorei16, I32, addrgp, PS_storerhabs>; 2192 def: Storea_pat<store, I32, addrgp, PS_storeriabs>; 2193 def: Storea_pat<store, I64, addrgp, PS_storerdabs>; 2194} 2195 2196def: Loada_pat<atomic_load_8, i32, addrgp, PS_loadrubabs>; 2197def: Loada_pat<atomic_load_16, i32, addrgp, PS_loadruhabs>; 2198def: Loada_pat<atomic_load_32, i32, addrgp, PS_loadriabs>; 2199def: Loada_pat<atomic_load_64, i64, addrgp, PS_loadrdabs>; 2200 2201def: Storea_pat<SwapSt<atomic_store_8>, I32, addrgp, PS_storerbabs>; 2202def: Storea_pat<SwapSt<atomic_store_16>, I32, addrgp, PS_storerhabs>; 2203def: Storea_pat<SwapSt<atomic_store_32>, I32, addrgp, PS_storeriabs>; 2204def: Storea_pat<SwapSt<atomic_store_64>, I64, addrgp, PS_storerdabs>; 2205 2206def: Pat<(or (or (or (shl (i64 (zext (and I32:$b, (i32 65535)))), (i32 16)), 2207 (i64 (zext (i32 (and I32:$a, (i32 65535)))))), 2208 (shl (i64 (anyext (and I32:$c, (i32 65535)))), (i32 32))), 2209 (shl (Aext64 I32:$d), (i32 48))), 2210 (A2_combinew (A2_combine_ll I32:$d, I32:$c), 2211 (A2_combine_ll I32:$b, I32:$a))>; 2212 2213// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH 2214// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore. 2215// We don't really want either one here. 2216def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>; 2217def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH, 2218 [SDNPHasChain]>; 2219 2220def: Pat<(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3), 2221 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>; 2222def: Pat<(HexagonDCFETCH (i32 (add IntRegs:$Rs, u11_3ImmPred:$u11_3)), (i32 0)), 2223 (Y2_dcfetchbo IntRegs:$Rs, imm:$u11_3)>; 2224 2225def f32ImmPred : PatLeaf<(f32 fpimm:$F)>; 2226def f64ImmPred : PatLeaf<(f64 fpimm:$F)>; 2227 2228def ftoi : SDNodeXForm<fpimm, [{ 2229 APInt I = N->getValueAPF().bitcastToAPInt(); 2230 return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N), 2231 MVT::getIntegerVT(I.getBitWidth())); 2232}]>; 2233 2234 2235def: Pat<(sra (i64 (add (sra I64:$src1, u6_0ImmPred:$src2), 1)), (i32 1)), 2236 (S2_asr_i_p_rnd I64:$src1, imm:$src2)>; 2237 2238def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 2239 SDTCisVT<1, i64>]>; 2240def HexagonPOPCOUNT: SDNode<"HexagonISD::POPCOUNT", SDTHexagonI32I64>; 2241 2242def: Pat<(HexagonPOPCOUNT I64:$Rss), (S5_popcountp I64:$Rss)>; 2243 2244let AddedComplexity = 20 in { 2245 defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>; 2246 defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>; 2247} 2248 2249let AddedComplexity = 60 in { 2250 defm : T_LoadAbsReg_Pat <load, L4_loadri_ur, f32>; 2251 defm : T_LoadAbsReg_Pat <load, L4_loadrd_ur, f64>; 2252} 2253 2254let AddedComplexity = 40 in { 2255 def: Loadxs_pat<load, f32, L4_loadri_rr>; 2256 def: Loadxs_pat<load, f64, L4_loadrd_rr>; 2257} 2258 2259let AddedComplexity = 20 in { 2260 def: Loadxs_simple_pat<load, f32, L4_loadri_rr>; 2261 def: Loadxs_simple_pat<load, f64, L4_loadrd_rr>; 2262} 2263 2264let AddedComplexity = 80 in { 2265 def: Loada_pat<load, f32, u32_0ImmPred, PS_loadriabs>; 2266 def: Loada_pat<load, f32, addrga, PS_loadriabs>; 2267 def: Loada_pat<load, f64, addrga, PS_loadrdabs>; 2268} 2269 2270let AddedComplexity = 100 in { 2271 def: LoadGP_pats <load, L2_loadrigp, f32>; 2272 def: LoadGP_pats <load, L2_loadrdgp, f64>; 2273} 2274 2275let AddedComplexity = 20 in { 2276 defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>; 2277 defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>; 2278} 2279 2280// Simple patterns should be tried with the least priority. 2281def: Storex_simple_pat<store, F32, S2_storeri_io>; 2282def: Storex_simple_pat<store, F64, S2_storerd_io>; 2283 2284let AddedComplexity = 60 in { 2285 defm : T_StoreAbsReg_Pats <S4_storeri_ur, IntRegs, f32, store>; 2286 defm : T_StoreAbsReg_Pats <S4_storerd_ur, DoubleRegs, f64, store>; 2287} 2288 2289let AddedComplexity = 40 in { 2290 def: Storexs_pat<store, F32, S4_storeri_rr>; 2291 def: Storexs_pat<store, F64, S4_storerd_rr>; 2292} 2293 2294let AddedComplexity = 20 in { 2295 def: Store_rr_pat<store, F32, S4_storeri_rr>; 2296 def: Store_rr_pat<store, F64, S4_storerd_rr>; 2297} 2298 2299let AddedComplexity = 80 in { 2300 def: Storea_pat<store, F32, addrga, PS_storeriabs>; 2301 def: Storea_pat<store, F64, addrga, PS_storerdabs>; 2302} 2303 2304let AddedComplexity = 100 in { 2305 def: Storea_pat<store, F32, addrgp, S2_storerigp>; 2306 def: Storea_pat<store, F64, addrgp, S2_storerdgp>; 2307} 2308 2309defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>; 2310defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>; 2311def: Storex_simple_pat<store, F32, S2_storeri_io>; 2312def: Storex_simple_pat<store, F64, S2_storerd_io>; 2313 2314def: Pat<(fadd F32:$src1, F32:$src2), 2315 (F2_sfadd F32:$src1, F32:$src2)>; 2316 2317def: Pat<(fsub F32:$src1, F32:$src2), 2318 (F2_sfsub F32:$src1, F32:$src2)>; 2319 2320def: Pat<(fmul F32:$src1, F32:$src2), 2321 (F2_sfmpy F32:$src1, F32:$src2)>; 2322 2323let Predicates = [HasV5T] in { 2324 def: Pat<(f32 (fminnum F32:$Rs, F32:$Rt)), (F2_sfmin F32:$Rs, F32:$Rt)>; 2325 def: Pat<(f32 (fmaxnum F32:$Rs, F32:$Rt)), (F2_sfmax F32:$Rs, F32:$Rt)>; 2326} 2327 2328let AddedComplexity = 100, Predicates = [HasV5T] in { 2329 class SfSel12<PatFrag Cmp, InstHexagon MI> 2330 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rs, F32:$Rt), 2331 (MI F32:$Rs, F32:$Rt)>; 2332 class SfSel21<PatFrag Cmp, InstHexagon MI> 2333 : Pat<(select (i1 (Cmp F32:$Rs, F32:$Rt)), F32:$Rt, F32:$Rs), 2334 (MI F32:$Rs, F32:$Rt)>; 2335 2336 def: SfSel12<setolt, F2_sfmin>; 2337 def: SfSel12<setole, F2_sfmin>; 2338 def: SfSel12<setogt, F2_sfmax>; 2339 def: SfSel12<setoge, F2_sfmax>; 2340 def: SfSel21<setolt, F2_sfmax>; 2341 def: SfSel21<setole, F2_sfmax>; 2342 def: SfSel21<setogt, F2_sfmin>; 2343 def: SfSel21<setoge, F2_sfmin>; 2344} 2345 2346class T_fcmp32_pat<PatFrag OpNode, InstHexagon MI> 2347 : Pat<(i1 (OpNode F32:$src1, F32:$src2)), 2348 (MI F32:$src1, F32:$src2)>; 2349class T_fcmp64_pat<PatFrag OpNode, InstHexagon MI> 2350 : Pat<(i1 (OpNode F64:$src1, F64:$src2)), 2351 (MI F64:$src1, F64:$src2)>; 2352 2353def: T_fcmp32_pat<setoge, F2_sfcmpge>; 2354def: T_fcmp32_pat<setuo, F2_sfcmpuo>; 2355def: T_fcmp32_pat<setoeq, F2_sfcmpeq>; 2356def: T_fcmp32_pat<setogt, F2_sfcmpgt>; 2357 2358def: T_fcmp64_pat<setoge, F2_dfcmpge>; 2359def: T_fcmp64_pat<setuo, F2_dfcmpuo>; 2360def: T_fcmp64_pat<setoeq, F2_dfcmpeq>; 2361def: T_fcmp64_pat<setogt, F2_dfcmpgt>; 2362 2363let Predicates = [HasV5T] in 2364multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> { 2365 // IntRegs 2366 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)), 2367 (IntMI F32:$src1, F32:$src2)>; 2368 // DoubleRegs 2369 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)), 2370 (DoubleMI F64:$src1, F64:$src2)>; 2371} 2372 2373defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>; 2374defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>; 2375defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>; 2376 2377//===----------------------------------------------------------------------===// 2378// Multiclass to define 'Def Pats' for unordered gt, ge, eq operations. 2379//===----------------------------------------------------------------------===// 2380let Predicates = [HasV5T] in 2381multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> { 2382 // IntRegs 2383 def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)), 2384 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), 2385 (IntMI F32:$src1, F32:$src2))>; 2386 2387 // DoubleRegs 2388 def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)), 2389 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), 2390 (DoubleMI F64:$src1, F64:$src2))>; 2391} 2392 2393defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>; 2394defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>; 2395defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>; 2396 2397//===----------------------------------------------------------------------===// 2398// Multiclass to define 'Def Pats' for the following dags: 2399// seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2)) 2400// seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2) 2401// setne(setoeq(op1, op2), 0) -> setoeq(op1, op2) 2402// setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2)) 2403//===----------------------------------------------------------------------===// 2404let Predicates = [HasV5T] in 2405multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI, 2406 InstHexagon DoubleMI> { 2407 // IntRegs 2408 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)), 2409 (C2_not (IntMI F32:$src1, F32:$src2))>; 2410 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)), 2411 (IntMI F32:$src1, F32:$src2)>; 2412 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)), 2413 (IntMI F32:$src1, F32:$src2)>; 2414 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)), 2415 (C2_not (IntMI F32:$src1, F32:$src2))>; 2416 2417 // DoubleRegs 2418 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)), 2419 (C2_not (DoubleMI F64:$src1, F64:$src2))>; 2420 def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)), 2421 (DoubleMI F64:$src1, F64:$src2)>; 2422 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)), 2423 (DoubleMI F64:$src1, F64:$src2)>; 2424 def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)), 2425 (C2_not (DoubleMI F64:$src1, F64:$src2))>; 2426} 2427 2428defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>; 2429defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>; 2430defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>; 2431 2432//===----------------------------------------------------------------------===// 2433// Multiclass to define 'Def Pats' for the following dags: 2434// seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1)) 2435// seteq(setolt(op1, op2), 1) -> setogt(op2, op1) 2436// setne(setolt(op1, op2), 0) -> setogt(op2, op1) 2437// setne(setolt(op1, op2), 1) -> not(setogt(op2, op1)) 2438//===----------------------------------------------------------------------===// 2439let Predicates = [HasV5T] in 2440multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI, 2441 InstHexagon DoubleMI> { 2442 // IntRegs 2443 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)), 2444 (C2_not (IntMI F32:$src2, F32:$src1))>; 2445 def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)), 2446 (IntMI F32:$src2, F32:$src1)>; 2447 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)), 2448 (IntMI F32:$src2, F32:$src1)>; 2449 def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)), 2450 (C2_not (IntMI F32:$src2, F32:$src1))>; 2451 2452 // DoubleRegs 2453 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)), 2454 (C2_not (DoubleMI F64:$src2, F64:$src1))>; 2455 def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)), 2456 (DoubleMI F64:$src2, F64:$src1)>; 2457 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)), 2458 (DoubleMI F64:$src2, F64:$src1)>; 2459 def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)), 2460 (C2_not (DoubleMI F64:$src2, F64:$src1))>; 2461} 2462 2463defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>; 2464defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>; 2465 2466 2467// o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp 2468let Predicates = [HasV5T] in { 2469 def: Pat<(i1 (seto F32:$src1, F32:$src2)), 2470 (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>; 2471 def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)), 2472 (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; 2473 def: Pat<(i1 (seto F64:$src1, F64:$src2)), 2474 (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>; 2475 def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)), 2476 (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>; 2477} 2478 2479// Ordered lt. 2480let Predicates = [HasV5T] in { 2481 def: Pat<(i1 (setolt F32:$src1, F32:$src2)), 2482 (F2_sfcmpgt F32:$src2, F32:$src1)>; 2483 def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)), 2484 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; 2485 def: Pat<(i1 (setolt F64:$src1, F64:$src2)), 2486 (F2_dfcmpgt F64:$src2, F64:$src1)>; 2487 def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)), 2488 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>; 2489} 2490 2491// Unordered lt. 2492let Predicates = [HasV5T] in { 2493 def: Pat<(i1 (setult F32:$src1, F32:$src2)), 2494 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), 2495 (F2_sfcmpgt F32:$src2, F32:$src1))>; 2496 def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)), 2497 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), 2498 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; 2499 def: Pat<(i1 (setult F64:$src1, F64:$src2)), 2500 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), 2501 (F2_dfcmpgt F64:$src2, F64:$src1))>; 2502 def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)), 2503 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), 2504 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>; 2505} 2506 2507// Ordered le. 2508let Predicates = [HasV5T] in { 2509 // rs <= rt -> rt >= rs. 2510 def: Pat<(i1 (setole F32:$src1, F32:$src2)), 2511 (F2_sfcmpge F32:$src2, F32:$src1)>; 2512 def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)), 2513 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; 2514 2515 // Rss <= Rtt -> Rtt >= Rss. 2516 def: Pat<(i1 (setole F64:$src1, F64:$src2)), 2517 (F2_dfcmpge F64:$src2, F64:$src1)>; 2518 def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)), 2519 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>; 2520} 2521 2522// Unordered le. 2523let Predicates = [HasV5T] in { 2524// rs <= rt -> rt >= rs. 2525 def: Pat<(i1 (setule F32:$src1, F32:$src2)), 2526 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), 2527 (F2_sfcmpge F32:$src2, F32:$src1))>; 2528 def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)), 2529 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), 2530 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; 2531 def: Pat<(i1 (setule F64:$src1, F64:$src2)), 2532 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), 2533 (F2_dfcmpge F64:$src2, F64:$src1))>; 2534 def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)), 2535 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), 2536 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>; 2537} 2538 2539// Ordered ne. 2540let Predicates = [HasV5T] in { 2541 def: Pat<(i1 (setone F32:$src1, F32:$src2)), 2542 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>; 2543 def: Pat<(i1 (setone F64:$src1, F64:$src2)), 2544 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>; 2545 def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)), 2546 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>; 2547 def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)), 2548 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>; 2549} 2550 2551// Unordered ne. 2552let Predicates = [HasV5T] in { 2553 def: Pat<(i1 (setune F32:$src1, F32:$src2)), 2554 (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), 2555 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>; 2556 def: Pat<(i1 (setune F64:$src1, F64:$src2)), 2557 (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), 2558 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>; 2559 def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)), 2560 (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), 2561 (C2_not (F2_sfcmpeq F32:$src1, 2562 (f32 (A2_tfrsi (ftoi $src2))))))>; 2563 def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)), 2564 (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), 2565 (C2_not (F2_dfcmpeq F64:$src1, 2566 (CONST64 (ftoi $src2)))))>; 2567} 2568 2569// Besides set[o|u][comparions], we also need set[comparisons]. 2570let Predicates = [HasV5T] in { 2571 // lt. 2572 def: Pat<(i1 (setlt F32:$src1, F32:$src2)), 2573 (F2_sfcmpgt F32:$src2, F32:$src1)>; 2574 def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)), 2575 (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; 2576 def: Pat<(i1 (setlt F64:$src1, F64:$src2)), 2577 (F2_dfcmpgt F64:$src2, F64:$src1)>; 2578 def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)), 2579 (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>; 2580 2581 // le. 2582 // rs <= rt -> rt >= rs. 2583 def: Pat<(i1 (setle F32:$src1, F32:$src2)), 2584 (F2_sfcmpge F32:$src2, F32:$src1)>; 2585 def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)), 2586 (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; 2587 2588 // Rss <= Rtt -> Rtt >= Rss. 2589 def: Pat<(i1 (setle F64:$src1, F64:$src2)), 2590 (F2_dfcmpge F64:$src2, F64:$src1)>; 2591 def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)), 2592 (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>; 2593 2594 // ne. 2595 def: Pat<(i1 (setne F32:$src1, F32:$src2)), 2596 (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>; 2597 def: Pat<(i1 (setne F64:$src1, F64:$src2)), 2598 (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>; 2599 def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)), 2600 (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>; 2601 def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)), 2602 (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>; 2603} 2604 2605 2606def: Pat<(f64 (fpextend F32:$Rs)), (F2_conv_sf2df F32:$Rs)>; 2607def: Pat<(f32 (fpround F64:$Rs)), (F2_conv_df2sf F64:$Rs)>; 2608 2609def: Pat<(f32 (sint_to_fp I32:$Rs)), (F2_conv_w2sf I32:$Rs)>; 2610def: Pat<(f32 (sint_to_fp I64:$Rs)), (F2_conv_d2sf I64:$Rs)>; 2611def: Pat<(f64 (sint_to_fp I32:$Rs)), (F2_conv_w2df I32:$Rs)>; 2612def: Pat<(f64 (sint_to_fp I64:$Rs)), (F2_conv_d2df I64:$Rs)>; 2613 2614def: Pat<(f32 (uint_to_fp I32:$Rs)), (F2_conv_uw2sf I32:$Rs)>; 2615def: Pat<(f32 (uint_to_fp I64:$Rs)), (F2_conv_ud2sf I64:$Rs)>; 2616def: Pat<(f64 (uint_to_fp I32:$Rs)), (F2_conv_uw2df I32:$Rs)>; 2617def: Pat<(f64 (uint_to_fp I64:$Rs)), (F2_conv_ud2df I64:$Rs)>; 2618 2619def: Pat<(i32 (fp_to_sint F32:$Rs)), (F2_conv_sf2w_chop F32:$Rs)>; 2620def: Pat<(i32 (fp_to_sint F64:$Rs)), (F2_conv_df2w_chop F64:$Rs)>; 2621def: Pat<(i64 (fp_to_sint F32:$Rs)), (F2_conv_sf2d_chop F32:$Rs)>; 2622def: Pat<(i64 (fp_to_sint F64:$Rs)), (F2_conv_df2d_chop F64:$Rs)>; 2623 2624def: Pat<(i32 (fp_to_uint F32:$Rs)), (F2_conv_sf2uw_chop F32:$Rs)>; 2625def: Pat<(i32 (fp_to_uint F64:$Rs)), (F2_conv_df2uw_chop F64:$Rs)>; 2626def: Pat<(i64 (fp_to_uint F32:$Rs)), (F2_conv_sf2ud_chop F32:$Rs)>; 2627def: Pat<(i64 (fp_to_uint F64:$Rs)), (F2_conv_df2ud_chop F64:$Rs)>; 2628 2629// Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp]. 2630let Predicates = [HasV5T] in { 2631 def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>; 2632 def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>; 2633 def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>; 2634 def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>; 2635} 2636 2637def : Pat <(fma F32:$src2, F32:$src3, F32:$src1), 2638 (F2_sffma F32:$src1, F32:$src2, F32:$src3)>; 2639 2640def : Pat <(fma (fneg F32:$src2), F32:$src3, F32:$src1), 2641 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>; 2642 2643def : Pat <(fma F32:$src2, (fneg F32:$src3), F32:$src1), 2644 (F2_sffms F32:$src1, F32:$src2, F32:$src3)>; 2645 2646def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm), 2647 (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>, 2648 Requires<[HasV5T]>; 2649 2650def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt), 2651 (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>, 2652 Requires<[HasV5T]>; 2653 2654def: Pat<(select I1:$src1, F32:$src2, F32:$src3), 2655 (C2_mux I1:$src1, F32:$src2, F32:$src3)>, 2656 Requires<[HasV5T]>; 2657 2658def: Pat<(select (i1 (setult F32:$src1, F32:$src2)), F32:$src3, F32:$src4), 2659 (C2_mux (F2_sfcmpgt F32:$src2, F32:$src1), F32:$src4, F32:$src3)>, 2660 Requires<[HasV5T]>; 2661 2662def: Pat<(select I1:$src1, F64:$src2, F64:$src3), 2663 (C2_vmux I1:$src1, F64:$src2, F64:$src3)>, 2664 Requires<[HasV5T]>; 2665 2666def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4), 2667 (C2_vmux (F2_dfcmpgt F64:$src2, F64:$src1), F64:$src3, F64:$src4)>, 2668 Requires<[HasV5T]>; 2669 2670// Map from p0 = pnot(p0); r0 = select(p0, #i, r1) 2671// => r0 = mux(p0, #i, r1) 2672def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3), 2673 (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>, 2674 Requires<[HasV5T]>; 2675 2676// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) 2677// => r0 = mux(p0, r1, #i) 2678def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3), 2679 (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>, 2680 Requires<[HasV5T]>; 2681 2682def: Pat<(i32 (fp_to_sint F64:$src1)), 2683 (LoReg (F2_conv_df2d_chop F64:$src1))>, 2684 Requires<[HasV5T]>; 2685 2686def : Pat <(fabs F32:$src1), 2687 (S2_clrbit_i F32:$src1, 31)>, 2688 Requires<[HasV5T]>; 2689 2690def : Pat <(fneg F32:$src1), 2691 (S2_togglebit_i F32:$src1, 31)>, 2692 Requires<[HasV5T]>; 2693 2694def: Pat<(fabs F64:$Rs), 2695 (REG_SEQUENCE DoubleRegs, 2696 (S2_clrbit_i (HiReg $Rs), 31), isub_hi, 2697 (i32 (LoReg $Rs)), isub_lo)>; 2698 2699def: Pat<(fneg F64:$Rs), 2700 (REG_SEQUENCE DoubleRegs, 2701 (S2_togglebit_i (HiReg $Rs), 31), isub_hi, 2702 (i32 (LoReg $Rs)), isub_lo)>; 2703 2704def alignedload : PatFrag<(ops node:$addr), (load $addr), [{ 2705 return isAlignedMemNode(dyn_cast<MemSDNode>(N)); 2706}]>; 2707 2708def unalignedload : PatFrag<(ops node:$addr), (load $addr), [{ 2709 return !isAlignedMemNode(dyn_cast<MemSDNode>(N)); 2710}]>; 2711 2712def alignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{ 2713 return isAlignedMemNode(dyn_cast<MemSDNode>(N)); 2714}]>; 2715 2716def unalignedstore : PatFrag<(ops node:$val, node:$addr), (store $val, $addr), [{ 2717 return !isAlignedMemNode(dyn_cast<MemSDNode>(N)); 2718}]>; 2719 2720 2721def s4_6ImmPred: PatLeaf<(i32 imm), [{ 2722 int64_t V = N->getSExtValue(); 2723 return isShiftedInt<4,6>(V); 2724}]>; 2725 2726def s4_7ImmPred: PatLeaf<(i32 imm), [{ 2727 int64_t V = N->getSExtValue(); 2728 return isShiftedInt<4,7>(V); 2729}]>; 2730 2731 2732multiclass vS32b_ai_pats <ValueType VTSgl, ValueType VTDbl> { 2733 // Aligned stores 2734 def : Pat<(alignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr), 2735 (V6_vS32b_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>, 2736 Requires<[UseHVXSgl]>; 2737 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1), IntRegs:$addr), 2738 (V6_vS32Ub_ai IntRegs:$addr, 0, (VTSgl VectorRegs:$src1))>, 2739 Requires<[UseHVXSgl]>; 2740 2741 // 128B Aligned stores 2742 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr), 2743 (V6_vS32b_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>, 2744 Requires<[UseHVXDbl]>; 2745 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1), IntRegs:$addr), 2746 (V6_vS32Ub_ai_128B IntRegs:$addr, 0, (VTDbl VectorRegs128B:$src1))>, 2747 Requires<[UseHVXDbl]>; 2748 2749 // Fold Add R+OFF into vector store. 2750 let AddedComplexity = 10 in { 2751 def : Pat<(alignedstore (VTSgl VectorRegs:$src1), 2752 (add IntRegs:$src2, s4_6ImmPred:$offset)), 2753 (V6_vS32b_ai IntRegs:$src2, s4_6ImmPred:$offset, 2754 (VTSgl VectorRegs:$src1))>, 2755 Requires<[UseHVXSgl]>; 2756 def : Pat<(unalignedstore (VTSgl VectorRegs:$src1), 2757 (add IntRegs:$src2, s4_6ImmPred:$offset)), 2758 (V6_vS32Ub_ai IntRegs:$src2, s4_6ImmPred:$offset, 2759 (VTSgl VectorRegs:$src1))>, 2760 Requires<[UseHVXSgl]>; 2761 2762 // Fold Add R+OFF into vector store 128B. 2763 def : Pat<(alignedstore (VTDbl VectorRegs128B:$src1), 2764 (add IntRegs:$src2, s4_7ImmPred:$offset)), 2765 (V6_vS32b_ai_128B IntRegs:$src2, s4_7ImmPred:$offset, 2766 (VTDbl VectorRegs128B:$src1))>, 2767 Requires<[UseHVXDbl]>; 2768 def : Pat<(unalignedstore (VTDbl VectorRegs128B:$src1), 2769 (add IntRegs:$src2, s4_7ImmPred:$offset)), 2770 (V6_vS32Ub_ai_128B IntRegs:$src2, s4_7ImmPred:$offset, 2771 (VTDbl VectorRegs128B:$src1))>, 2772 Requires<[UseHVXDbl]>; 2773 } 2774} 2775 2776defm : vS32b_ai_pats <v64i8, v128i8>; 2777defm : vS32b_ai_pats <v32i16, v64i16>; 2778defm : vS32b_ai_pats <v16i32, v32i32>; 2779defm : vS32b_ai_pats <v8i64, v16i64>; 2780 2781 2782multiclass vL32b_ai_pats <ValueType VTSgl, ValueType VTDbl> { 2783 // Aligned loads 2784 def : Pat < (VTSgl (alignedload IntRegs:$addr)), 2785 (V6_vL32b_ai IntRegs:$addr, 0) >, 2786 Requires<[UseHVXSgl]>; 2787 def : Pat < (VTSgl (unalignedload IntRegs:$addr)), 2788 (V6_vL32Ub_ai IntRegs:$addr, 0) >, 2789 Requires<[UseHVXSgl]>; 2790 2791 // 128B Load 2792 def : Pat < (VTDbl (alignedload IntRegs:$addr)), 2793 (V6_vL32b_ai_128B IntRegs:$addr, 0) >, 2794 Requires<[UseHVXDbl]>; 2795 def : Pat < (VTDbl (unalignedload IntRegs:$addr)), 2796 (V6_vL32Ub_ai_128B IntRegs:$addr, 0) >, 2797 Requires<[UseHVXDbl]>; 2798 2799 // Fold Add R+OFF into vector load. 2800 let AddedComplexity = 10 in { 2801 def : Pat<(VTDbl (alignedload (add IntRegs:$src2, s4_7ImmPred:$offset))), 2802 (V6_vL32b_ai_128B IntRegs:$src2, s4_7ImmPred:$offset)>, 2803 Requires<[UseHVXDbl]>; 2804 def : Pat<(VTDbl (unalignedload (add IntRegs:$src2, s4_7ImmPred:$offset))), 2805 (V6_vL32Ub_ai_128B IntRegs:$src2, s4_7ImmPred:$offset)>, 2806 Requires<[UseHVXDbl]>; 2807 2808 def : Pat<(VTSgl (alignedload (add IntRegs:$src2, s4_6ImmPred:$offset))), 2809 (V6_vL32b_ai IntRegs:$src2, s4_6ImmPred:$offset)>, 2810 Requires<[UseHVXSgl]>; 2811 def : Pat<(VTSgl (unalignedload (add IntRegs:$src2, s4_6ImmPred:$offset))), 2812 (V6_vL32Ub_ai IntRegs:$src2, s4_6ImmPred:$offset)>, 2813 Requires<[UseHVXSgl]>; 2814 } 2815} 2816 2817defm : vL32b_ai_pats <v64i8, v128i8>; 2818defm : vL32b_ai_pats <v32i16, v64i16>; 2819defm : vL32b_ai_pats <v16i32, v32i32>; 2820defm : vL32b_ai_pats <v8i64, v16i64>; 2821 2822multiclass STrivv_pats <ValueType VTSgl, ValueType VTDbl> { 2823 def : Pat<(alignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr), 2824 (PS_vstorerw_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>, 2825 Requires<[UseHVXSgl]>; 2826 def : Pat<(unalignedstore (VTSgl VecDblRegs:$src1), IntRegs:$addr), 2827 (PS_vstorerwu_ai IntRegs:$addr, 0, (VTSgl VecDblRegs:$src1))>, 2828 Requires<[UseHVXSgl]>; 2829 2830 def : Pat<(alignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr), 2831 (PS_vstorerw_ai_128B IntRegs:$addr, 0, 2832 (VTDbl VecDblRegs128B:$src1))>, 2833 Requires<[UseHVXDbl]>; 2834 def : Pat<(unalignedstore (VTDbl VecDblRegs128B:$src1), IntRegs:$addr), 2835 (PS_vstorerwu_ai_128B IntRegs:$addr, 0, 2836 (VTDbl VecDblRegs128B:$src1))>, 2837 Requires<[UseHVXDbl]>; 2838} 2839 2840defm : STrivv_pats <v128i8, v256i8>; 2841defm : STrivv_pats <v64i16, v128i16>; 2842defm : STrivv_pats <v32i32, v64i32>; 2843defm : STrivv_pats <v16i64, v32i64>; 2844 2845multiclass LDrivv_pats <ValueType VTSgl, ValueType VTDbl> { 2846 def : Pat<(VTSgl (alignedload I32:$addr)), 2847 (PS_vloadrw_ai I32:$addr, 0)>, 2848 Requires<[UseHVXSgl]>; 2849 def : Pat<(VTSgl (unalignedload I32:$addr)), 2850 (PS_vloadrwu_ai I32:$addr, 0)>, 2851 Requires<[UseHVXSgl]>; 2852 2853 def : Pat<(VTDbl (alignedload I32:$addr)), 2854 (PS_vloadrw_ai_128B I32:$addr, 0)>, 2855 Requires<[UseHVXDbl]>; 2856 def : Pat<(VTDbl (unalignedload I32:$addr)), 2857 (PS_vloadrwu_ai_128B I32:$addr, 0)>, 2858 Requires<[UseHVXDbl]>; 2859} 2860 2861defm : LDrivv_pats <v128i8, v256i8>; 2862defm : LDrivv_pats <v64i16, v128i16>; 2863defm : LDrivv_pats <v32i32, v64i32>; 2864defm : LDrivv_pats <v16i64, v32i64>; 2865 2866let Predicates = [HasV60T,UseHVXSgl] in { 2867 def: Pat<(select I1:$Pu, (v16i32 VectorRegs:$Vs), VectorRegs:$Vt), 2868 (PS_vselect I1:$Pu, VectorRegs:$Vs, VectorRegs:$Vt)>; 2869 def: Pat<(select I1:$Pu, (v32i32 VecDblRegs:$Vs), VecDblRegs:$Vt), 2870 (PS_wselect I1:$Pu, VecDblRegs:$Vs, VecDblRegs:$Vt)>; 2871} 2872let Predicates = [HasV60T,UseHVXDbl] in { 2873 def: Pat<(select I1:$Pu, (v32i32 VectorRegs128B:$Vs), VectorRegs128B:$Vt), 2874 (PS_vselect_128B I1:$Pu, VectorRegs128B:$Vs, VectorRegs128B:$Vt)>; 2875 def: Pat<(select I1:$Pu, (v64i32 VecDblRegs128B:$Vs), VecDblRegs128B:$Vt), 2876 (PS_wselect_128B I1:$Pu, VecDblRegs128B:$Vs, VecDblRegs128B:$Vt)>; 2877} 2878 2879 2880def SDTHexagonVCOMBINE: SDTypeProfile<1, 2, [SDTCisSameAs<1, 2>, 2881 SDTCisSubVecOfVec<1, 0>]>; 2882 2883def HexagonVCOMBINE: SDNode<"HexagonISD::VCOMBINE", SDTHexagonVCOMBINE>; 2884 2885def: Pat<(v32i32 (HexagonVCOMBINE (v16i32 VectorRegs:$Vs), 2886 (v16i32 VectorRegs:$Vt))), 2887 (V6_vcombine VectorRegs:$Vs, VectorRegs:$Vt)>, 2888 Requires<[UseHVXSgl]>; 2889def: Pat<(v64i32 (HexagonVCOMBINE (v32i32 VecDblRegs:$Vs), 2890 (v32i32 VecDblRegs:$Vt))), 2891 (V6_vcombine_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>, 2892 Requires<[UseHVXDbl]>; 2893 2894def SDTHexagonVPACK: SDTypeProfile<1, 3, [SDTCisSameAs<1, 2>, 2895 SDTCisInt<3>]>; 2896 2897def HexagonVPACK: SDNode<"HexagonISD::VPACK", SDTHexagonVPACK>; 2898 2899// 0 as the last argument denotes vpacke. 1 denotes vpacko 2900def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs), 2901 (v64i8 VectorRegs:$Vt), (i32 0))), 2902 (V6_vpackeb VectorRegs:$Vs, VectorRegs:$Vt)>, 2903 Requires<[UseHVXSgl]>; 2904def: Pat<(v64i8 (HexagonVPACK (v64i8 VectorRegs:$Vs), 2905 (v64i8 VectorRegs:$Vt), (i32 1))), 2906 (V6_vpackob VectorRegs:$Vs, VectorRegs:$Vt)>, 2907 Requires<[UseHVXSgl]>; 2908def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs), 2909 (v32i16 VectorRegs:$Vt), (i32 0))), 2910 (V6_vpackeh VectorRegs:$Vs, VectorRegs:$Vt)>, 2911 Requires<[UseHVXSgl]>; 2912def: Pat<(v32i16 (HexagonVPACK (v32i16 VectorRegs:$Vs), 2913 (v32i16 VectorRegs:$Vt), (i32 1))), 2914 (V6_vpackoh VectorRegs:$Vs, VectorRegs:$Vt)>, 2915 Requires<[UseHVXSgl]>; 2916 2917def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs), 2918 (v128i8 VecDblRegs:$Vt), (i32 0))), 2919 (V6_vpackeb_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>, 2920 Requires<[UseHVXDbl]>; 2921def: Pat<(v128i8 (HexagonVPACK (v128i8 VecDblRegs:$Vs), 2922 (v128i8 VecDblRegs:$Vt), (i32 1))), 2923 (V6_vpackob_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>, 2924 Requires<[UseHVXDbl]>; 2925def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs), 2926 (v64i16 VecDblRegs:$Vt), (i32 0))), 2927 (V6_vpackeh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>, 2928 Requires<[UseHVXDbl]>; 2929def: Pat<(v64i16 (HexagonVPACK (v64i16 VecDblRegs:$Vs), 2930 (v64i16 VecDblRegs:$Vt), (i32 1))), 2931 (V6_vpackoh_128B VecDblRegs:$Vs, VecDblRegs:$Vt)>, 2932 Requires<[UseHVXDbl]>; 2933 2934def V2I1: PatLeaf<(v2i1 PredRegs:$R)>; 2935def V4I1: PatLeaf<(v4i1 PredRegs:$R)>; 2936def V8I1: PatLeaf<(v8i1 PredRegs:$R)>; 2937def V4I8: PatLeaf<(v4i8 IntRegs:$R)>; 2938def V2I16: PatLeaf<(v2i16 IntRegs:$R)>; 2939def V8I8: PatLeaf<(v8i8 DoubleRegs:$R)>; 2940def V4I16: PatLeaf<(v4i16 DoubleRegs:$R)>; 2941def V2I32: PatLeaf<(v2i32 DoubleRegs:$R)>; 2942 2943 2944multiclass bitconvert_32<ValueType a, ValueType b> { 2945 def : Pat <(b (bitconvert (a IntRegs:$src))), 2946 (b IntRegs:$src)>; 2947 def : Pat <(a (bitconvert (b IntRegs:$src))), 2948 (a IntRegs:$src)>; 2949} 2950 2951multiclass bitconvert_64<ValueType a, ValueType b> { 2952 def : Pat <(b (bitconvert (a DoubleRegs:$src))), 2953 (b DoubleRegs:$src)>; 2954 def : Pat <(a (bitconvert (b DoubleRegs:$src))), 2955 (a DoubleRegs:$src)>; 2956} 2957 2958// Bit convert vector types to integers. 2959defm : bitconvert_32<v4i8, i32>; 2960defm : bitconvert_32<v2i16, i32>; 2961defm : bitconvert_64<v8i8, i64>; 2962defm : bitconvert_64<v4i16, i64>; 2963defm : bitconvert_64<v2i32, i64>; 2964 2965def: Pat<(sra (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2), 2966 (S2_asr_i_vh DoubleRegs:$src1, imm:$src2)>; 2967def: Pat<(srl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2), 2968 (S2_lsr_i_vh DoubleRegs:$src1, imm:$src2)>; 2969def: Pat<(shl (v4i16 DoubleRegs:$src1), u4_0ImmPred:$src2), 2970 (S2_asl_i_vh DoubleRegs:$src1, imm:$src2)>; 2971 2972def: Pat<(sra (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2), 2973 (S2_asr_i_vw DoubleRegs:$src1, imm:$src2)>; 2974def: Pat<(srl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2), 2975 (S2_lsr_i_vw DoubleRegs:$src1, imm:$src2)>; 2976def: Pat<(shl (v2i32 DoubleRegs:$src1), u5_0ImmPred:$src2), 2977 (S2_asl_i_vw DoubleRegs:$src1, imm:$src2)>; 2978 2979def : Pat<(v2i16 (add (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))), 2980 (A2_svaddh IntRegs:$src1, IntRegs:$src2)>; 2981 2982def : Pat<(v2i16 (sub (v2i16 IntRegs:$src1), (v2i16 IntRegs:$src2))), 2983 (A2_svsubh IntRegs:$src1, IntRegs:$src2)>; 2984 2985def HexagonVSPLATB: SDNode<"HexagonISD::VSPLATB", SDTUnaryOp>; 2986def HexagonVSPLATH: SDNode<"HexagonISD::VSPLATH", SDTUnaryOp>; 2987 2988// Replicate the low 8-bits from 32-bits input register into each of the 2989// four bytes of 32-bits destination register. 2990def: Pat<(v4i8 (HexagonVSPLATB I32:$Rs)), (S2_vsplatrb I32:$Rs)>; 2991 2992// Replicate the low 16-bits from 32-bits input register into each of the 2993// four halfwords of 64-bits destination register. 2994def: Pat<(v4i16 (HexagonVSPLATH I32:$Rs)), (S2_vsplatrh I32:$Rs)>; 2995 2996 2997class VArith_pat <InstHexagon MI, SDNode Op, PatFrag Type> 2998 : Pat <(Op Type:$Rss, Type:$Rtt), 2999 (MI Type:$Rss, Type:$Rtt)>; 3000 3001def: VArith_pat <A2_vaddub, add, V8I8>; 3002def: VArith_pat <A2_vaddh, add, V4I16>; 3003def: VArith_pat <A2_vaddw, add, V2I32>; 3004def: VArith_pat <A2_vsubub, sub, V8I8>; 3005def: VArith_pat <A2_vsubh, sub, V4I16>; 3006def: VArith_pat <A2_vsubw, sub, V2I32>; 3007 3008def: VArith_pat <A2_and, and, V2I16>; 3009def: VArith_pat <A2_xor, xor, V2I16>; 3010def: VArith_pat <A2_or, or, V2I16>; 3011 3012def: VArith_pat <A2_andp, and, V8I8>; 3013def: VArith_pat <A2_andp, and, V4I16>; 3014def: VArith_pat <A2_andp, and, V2I32>; 3015def: VArith_pat <A2_orp, or, V8I8>; 3016def: VArith_pat <A2_orp, or, V4I16>; 3017def: VArith_pat <A2_orp, or, V2I32>; 3018def: VArith_pat <A2_xorp, xor, V8I8>; 3019def: VArith_pat <A2_xorp, xor, V4I16>; 3020def: VArith_pat <A2_xorp, xor, V2I32>; 3021 3022def: Pat<(v2i32 (sra V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c), 3023 (i32 u5_0ImmPred:$c))))), 3024 (S2_asr_i_vw V2I32:$b, imm:$c)>; 3025def: Pat<(v2i32 (srl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c), 3026 (i32 u5_0ImmPred:$c))))), 3027 (S2_lsr_i_vw V2I32:$b, imm:$c)>; 3028def: Pat<(v2i32 (shl V2I32:$b, (i64 (HexagonCOMBINE (i32 u5_0ImmPred:$c), 3029 (i32 u5_0ImmPred:$c))))), 3030 (S2_asl_i_vw V2I32:$b, imm:$c)>; 3031 3032def: Pat<(v4i16 (sra V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))), 3033 (S2_asr_i_vh V4I16:$b, imm:$c)>; 3034def: Pat<(v4i16 (srl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))), 3035 (S2_lsr_i_vh V4I16:$b, imm:$c)>; 3036def: Pat<(v4i16 (shl V4I16:$b, (v4i16 (HexagonVSPLATH (i32 (u4_0ImmPred:$c)))))), 3037 (S2_asl_i_vh V4I16:$b, imm:$c)>; 3038 3039 3040def SDTHexagon_v2i32_v2i32_i32 : SDTypeProfile<1, 2, 3041 [SDTCisSameAs<0, 1>, SDTCisVT<0, v2i32>, SDTCisInt<2>]>; 3042def SDTHexagon_v4i16_v4i16_i32 : SDTypeProfile<1, 2, 3043 [SDTCisSameAs<0, 1>, SDTCisVT<0, v4i16>, SDTCisInt<2>]>; 3044 3045def HexagonVSRAW: SDNode<"HexagonISD::VSRAW", SDTHexagon_v2i32_v2i32_i32>; 3046def HexagonVSRAH: SDNode<"HexagonISD::VSRAH", SDTHexagon_v4i16_v4i16_i32>; 3047def HexagonVSRLW: SDNode<"HexagonISD::VSRLW", SDTHexagon_v2i32_v2i32_i32>; 3048def HexagonVSRLH: SDNode<"HexagonISD::VSRLH", SDTHexagon_v4i16_v4i16_i32>; 3049def HexagonVSHLW: SDNode<"HexagonISD::VSHLW", SDTHexagon_v2i32_v2i32_i32>; 3050def HexagonVSHLH: SDNode<"HexagonISD::VSHLH", SDTHexagon_v4i16_v4i16_i32>; 3051 3052def: Pat<(v2i32 (HexagonVSRAW V2I32:$Rs, u5_0ImmPred:$u5)), 3053 (S2_asr_i_vw V2I32:$Rs, imm:$u5)>; 3054def: Pat<(v4i16 (HexagonVSRAH V4I16:$Rs, u4_0ImmPred:$u4)), 3055 (S2_asr_i_vh V4I16:$Rs, imm:$u4)>; 3056def: Pat<(v2i32 (HexagonVSRLW V2I32:$Rs, u5_0ImmPred:$u5)), 3057 (S2_lsr_i_vw V2I32:$Rs, imm:$u5)>; 3058def: Pat<(v4i16 (HexagonVSRLH V4I16:$Rs, u4_0ImmPred:$u4)), 3059 (S2_lsr_i_vh V4I16:$Rs, imm:$u4)>; 3060def: Pat<(v2i32 (HexagonVSHLW V2I32:$Rs, u5_0ImmPred:$u5)), 3061 (S2_asl_i_vw V2I32:$Rs, imm:$u5)>; 3062def: Pat<(v4i16 (HexagonVSHLH V4I16:$Rs, u4_0ImmPred:$u4)), 3063 (S2_asl_i_vh V4I16:$Rs, imm:$u4)>; 3064 3065class vshift_rr_pat<InstHexagon MI, SDNode Op, PatFrag Value> 3066 : Pat <(Op Value:$Rs, I32:$Rt), 3067 (MI Value:$Rs, I32:$Rt)>; 3068 3069def: vshift_rr_pat <S2_asr_r_vw, HexagonVSRAW, V2I32>; 3070def: vshift_rr_pat <S2_asr_r_vh, HexagonVSRAH, V4I16>; 3071def: vshift_rr_pat <S2_lsr_r_vw, HexagonVSRLW, V2I32>; 3072def: vshift_rr_pat <S2_lsr_r_vh, HexagonVSRLH, V4I16>; 3073def: vshift_rr_pat <S2_asl_r_vw, HexagonVSHLW, V2I32>; 3074def: vshift_rr_pat <S2_asl_r_vh, HexagonVSHLH, V4I16>; 3075 3076 3077def SDTHexagonVecCompare_v8i8 : SDTypeProfile<1, 2, 3078 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v8i8>]>; 3079def SDTHexagonVecCompare_v4i16 : SDTypeProfile<1, 2, 3080 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v4i16>]>; 3081def SDTHexagonVecCompare_v2i32 : SDTypeProfile<1, 2, 3082 [SDTCisSameAs<1, 2>, SDTCisVT<0, i1>, SDTCisVT<1, v2i32>]>; 3083 3084def HexagonVCMPBEQ: SDNode<"HexagonISD::VCMPBEQ", SDTHexagonVecCompare_v8i8>; 3085def HexagonVCMPBGT: SDNode<"HexagonISD::VCMPBGT", SDTHexagonVecCompare_v8i8>; 3086def HexagonVCMPBGTU: SDNode<"HexagonISD::VCMPBGTU", SDTHexagonVecCompare_v8i8>; 3087def HexagonVCMPHEQ: SDNode<"HexagonISD::VCMPHEQ", SDTHexagonVecCompare_v4i16>; 3088def HexagonVCMPHGT: SDNode<"HexagonISD::VCMPHGT", SDTHexagonVecCompare_v4i16>; 3089def HexagonVCMPHGTU: SDNode<"HexagonISD::VCMPHGTU", SDTHexagonVecCompare_v4i16>; 3090def HexagonVCMPWEQ: SDNode<"HexagonISD::VCMPWEQ", SDTHexagonVecCompare_v2i32>; 3091def HexagonVCMPWGT: SDNode<"HexagonISD::VCMPWGT", SDTHexagonVecCompare_v2i32>; 3092def HexagonVCMPWGTU: SDNode<"HexagonISD::VCMPWGTU", SDTHexagonVecCompare_v2i32>; 3093 3094 3095class vcmp_i1_pat<InstHexagon MI, SDNode Op, PatFrag Value> 3096 : Pat <(i1 (Op Value:$Rs, Value:$Rt)), 3097 (MI Value:$Rs, Value:$Rt)>; 3098 3099def: vcmp_i1_pat<A2_vcmpbeq, HexagonVCMPBEQ, V8I8>; 3100def: vcmp_i1_pat<A4_vcmpbgt, HexagonVCMPBGT, V8I8>; 3101def: vcmp_i1_pat<A2_vcmpbgtu, HexagonVCMPBGTU, V8I8>; 3102 3103def: vcmp_i1_pat<A2_vcmpheq, HexagonVCMPHEQ, V4I16>; 3104def: vcmp_i1_pat<A2_vcmphgt, HexagonVCMPHGT, V4I16>; 3105def: vcmp_i1_pat<A2_vcmphgtu, HexagonVCMPHGTU, V4I16>; 3106 3107def: vcmp_i1_pat<A2_vcmpweq, HexagonVCMPWEQ, V2I32>; 3108def: vcmp_i1_pat<A2_vcmpwgt, HexagonVCMPWGT, V2I32>; 3109def: vcmp_i1_pat<A2_vcmpwgtu, HexagonVCMPWGTU, V2I32>; 3110 3111 3112class vcmp_vi1_pat<InstHexagon MI, PatFrag Op, PatFrag InVal, ValueType OutTy> 3113 : Pat <(OutTy (Op InVal:$Rs, InVal:$Rt)), 3114 (MI InVal:$Rs, InVal:$Rt)>; 3115 3116def: vcmp_vi1_pat<A2_vcmpweq, seteq, V2I32, v2i1>; 3117def: vcmp_vi1_pat<A2_vcmpwgt, setgt, V2I32, v2i1>; 3118def: vcmp_vi1_pat<A2_vcmpwgtu, setugt, V2I32, v2i1>; 3119 3120def: vcmp_vi1_pat<A2_vcmpheq, seteq, V4I16, v4i1>; 3121def: vcmp_vi1_pat<A2_vcmphgt, setgt, V4I16, v4i1>; 3122def: vcmp_vi1_pat<A2_vcmphgtu, setugt, V4I16, v4i1>; 3123 3124def: Pat<(mul V2I32:$Rs, V2I32:$Rt), 3125 (PS_vmulw DoubleRegs:$Rs, DoubleRegs:$Rt)>; 3126def: Pat<(add V2I32:$Rx, (mul V2I32:$Rs, V2I32:$Rt)), 3127 (PS_vmulw_acc DoubleRegs:$Rx, DoubleRegs:$Rs, DoubleRegs:$Rt)>; 3128 3129 3130// Adds two v4i8: Hexagon does not have an insn for this one, so we 3131// use the double add v8i8, and use only the low part of the result. 3132def: Pat<(v4i8 (add (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))), 3133 (LoReg (A2_vaddub (ToZext64 $Rs), (ToZext64 $Rt)))>; 3134 3135// Subtract two v4i8: Hexagon does not have an insn for this one, so we 3136// use the double sub v8i8, and use only the low part of the result. 3137def: Pat<(v4i8 (sub (v4i8 IntRegs:$Rs), (v4i8 IntRegs:$Rt))), 3138 (LoReg (A2_vsubub (ToZext64 $Rs), (ToZext64 $Rt)))>; 3139 3140// 3141// No 32 bit vector mux. 3142// 3143def: Pat<(v4i8 (select I1:$Pu, V4I8:$Rs, V4I8:$Rt)), 3144 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>; 3145def: Pat<(v2i16 (select I1:$Pu, V2I16:$Rs, V2I16:$Rt)), 3146 (LoReg (C2_vmux I1:$Pu, (ToZext64 $Rs), (ToZext64 $Rt)))>; 3147 3148// 3149// 64-bit vector mux. 3150// 3151def: Pat<(v8i8 (vselect V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)), 3152 (C2_vmux V8I1:$Pu, V8I8:$Rs, V8I8:$Rt)>; 3153def: Pat<(v4i16 (vselect V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)), 3154 (C2_vmux V4I1:$Pu, V4I16:$Rs, V4I16:$Rt)>; 3155def: Pat<(v2i32 (vselect V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)), 3156 (C2_vmux V2I1:$Pu, V2I32:$Rs, V2I32:$Rt)>; 3157 3158// 3159// No 32 bit vector compare. 3160// 3161def: Pat<(i1 (seteq V4I8:$Rs, V4I8:$Rt)), 3162 (A2_vcmpbeq (ToZext64 $Rs), (ToZext64 $Rt))>; 3163def: Pat<(i1 (setgt V4I8:$Rs, V4I8:$Rt)), 3164 (A4_vcmpbgt (ToZext64 $Rs), (ToZext64 $Rt))>; 3165def: Pat<(i1 (setugt V4I8:$Rs, V4I8:$Rt)), 3166 (A2_vcmpbgtu (ToZext64 $Rs), (ToZext64 $Rt))>; 3167 3168def: Pat<(i1 (seteq V2I16:$Rs, V2I16:$Rt)), 3169 (A2_vcmpheq (ToZext64 $Rs), (ToZext64 $Rt))>; 3170def: Pat<(i1 (setgt V2I16:$Rs, V2I16:$Rt)), 3171 (A2_vcmphgt (ToZext64 $Rs), (ToZext64 $Rt))>; 3172def: Pat<(i1 (setugt V2I16:$Rs, V2I16:$Rt)), 3173 (A2_vcmphgtu (ToZext64 $Rs), (ToZext64 $Rt))>; 3174 3175 3176class InvertCmp_pat<InstHexagon InvMI, PatFrag CmpOp, PatFrag Value, 3177 ValueType CmpTy> 3178 : Pat<(CmpTy (CmpOp Value:$Rs, Value:$Rt)), 3179 (InvMI Value:$Rt, Value:$Rs)>; 3180 3181// Map from a compare operation to the corresponding instruction with the 3182// order of operands reversed, e.g. x > y --> cmp.lt(y,x). 3183def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, i1>; 3184def: InvertCmp_pat<A4_vcmpbgt, setlt, V8I8, v8i1>; 3185def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, i1>; 3186def: InvertCmp_pat<A2_vcmphgt, setlt, V4I16, v4i1>; 3187def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, i1>; 3188def: InvertCmp_pat<A2_vcmpwgt, setlt, V2I32, v2i1>; 3189 3190def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, i1>; 3191def: InvertCmp_pat<A2_vcmpbgtu, setult, V8I8, v8i1>; 3192def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, i1>; 3193def: InvertCmp_pat<A2_vcmphgtu, setult, V4I16, v4i1>; 3194def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, i1>; 3195def: InvertCmp_pat<A2_vcmpwgtu, setult, V2I32, v2i1>; 3196 3197// Map from vcmpne(Rss) -> !vcmpew(Rss). 3198// rs != rt -> !(rs == rt). 3199def: Pat<(v2i1 (setne V2I32:$Rs, V2I32:$Rt)), 3200 (C2_not (v2i1 (A2_vcmpbeq V2I32:$Rs, V2I32:$Rt)))>; 3201 3202 3203// Truncate: from vector B copy all 'E'ven 'B'yte elements: 3204// A[0] = B[0]; A[1] = B[2]; A[2] = B[4]; A[3] = B[6]; 3205def: Pat<(v4i8 (trunc V4I16:$Rs)), 3206 (S2_vtrunehb V4I16:$Rs)>; 3207 3208// Truncate: from vector B copy all 'O'dd 'B'yte elements: 3209// A[0] = B[1]; A[1] = B[3]; A[2] = B[5]; A[3] = B[7]; 3210// S2_vtrunohb 3211 3212// Truncate: from vectors B and C copy all 'E'ven 'H'alf-word elements: 3213// A[0] = B[0]; A[1] = B[2]; A[2] = C[0]; A[3] = C[2]; 3214// S2_vtruneh 3215 3216def: Pat<(v2i16 (trunc V2I32:$Rs)), 3217 (LoReg (S2_packhl (HiReg $Rs), (LoReg $Rs)))>; 3218 3219 3220def HexagonVSXTBH : SDNode<"HexagonISD::VSXTBH", SDTUnaryOp>; 3221def HexagonVSXTBW : SDNode<"HexagonISD::VSXTBW", SDTUnaryOp>; 3222 3223def: Pat<(i64 (HexagonVSXTBH I32:$Rs)), (S2_vsxtbh I32:$Rs)>; 3224def: Pat<(i64 (HexagonVSXTBW I32:$Rs)), (S2_vsxthw I32:$Rs)>; 3225 3226def: Pat<(v4i16 (zext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>; 3227def: Pat<(v2i32 (zext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>; 3228def: Pat<(v4i16 (anyext V4I8:$Rs)), (S2_vzxtbh V4I8:$Rs)>; 3229def: Pat<(v2i32 (anyext V2I16:$Rs)), (S2_vzxthw V2I16:$Rs)>; 3230def: Pat<(v4i16 (sext V4I8:$Rs)), (S2_vsxtbh V4I8:$Rs)>; 3231def: Pat<(v2i32 (sext V2I16:$Rs)), (S2_vsxthw V2I16:$Rs)>; 3232 3233// Sign extends a v2i8 into a v2i32. 3234def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i8)), 3235 (A2_combinew (A2_sxtb (HiReg $Rs)), (A2_sxtb (LoReg $Rs)))>; 3236 3237// Sign extends a v2i16 into a v2i32. 3238def: Pat<(v2i32 (sext_inreg V2I32:$Rs, v2i16)), 3239 (A2_combinew (A2_sxth (HiReg $Rs)), (A2_sxth (LoReg $Rs)))>; 3240 3241 3242// Multiplies two v2i16 and returns a v2i32. We are using here the 3243// saturating multiply, as hexagon does not provide a non saturating 3244// vector multiply, and saturation does not impact the result that is 3245// in double precision of the operands. 3246 3247// Multiplies two v2i16 vectors: as Hexagon does not have a multiply 3248// with the C semantics for this one, this pattern uses the half word 3249// multiply vmpyh that takes two v2i16 and returns a v2i32. This is 3250// then truncated to fit this back into a v2i16 and to simulate the 3251// wrap around semantics for unsigned in C. 3252def vmpyh: OutPatFrag<(ops node:$Rs, node:$Rt), 3253 (M2_vmpy2s_s0 (i32 $Rs), (i32 $Rt))>; 3254 3255def: Pat<(v2i16 (mul V2I16:$Rs, V2I16:$Rt)), 3256 (LoReg (S2_vtrunewh (v2i32 (A2_combineii 0, 0)), 3257 (v2i32 (vmpyh V2I16:$Rs, V2I16:$Rt))))>; 3258 3259// Multiplies two v4i16 vectors. 3260def: Pat<(v4i16 (mul V4I16:$Rs, V4I16:$Rt)), 3261 (S2_vtrunewh (vmpyh (HiReg $Rs), (HiReg $Rt)), 3262 (vmpyh (LoReg $Rs), (LoReg $Rt)))>; 3263 3264def VMPYB_no_V5: OutPatFrag<(ops node:$Rs, node:$Rt), 3265 (S2_vtrunewh (vmpyh (HiReg (S2_vsxtbh $Rs)), (HiReg (S2_vsxtbh $Rt))), 3266 (vmpyh (LoReg (S2_vsxtbh $Rs)), (LoReg (S2_vsxtbh $Rt))))>; 3267 3268// Multiplies two v4i8 vectors. 3269def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)), 3270 (S2_vtrunehb (M5_vmpybsu V4I8:$Rs, V4I8:$Rt))>, 3271 Requires<[HasV5T]>; 3272 3273def: Pat<(v4i8 (mul V4I8:$Rs, V4I8:$Rt)), 3274 (S2_vtrunehb (VMPYB_no_V5 V4I8:$Rs, V4I8:$Rt))>; 3275 3276// Multiplies two v8i8 vectors. 3277def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)), 3278 (A2_combinew (S2_vtrunehb (M5_vmpybsu (HiReg $Rs), (HiReg $Rt))), 3279 (S2_vtrunehb (M5_vmpybsu (LoReg $Rs), (LoReg $Rt))))>, 3280 Requires<[HasV5T]>; 3281 3282def: Pat<(v8i8 (mul V8I8:$Rs, V8I8:$Rt)), 3283 (A2_combinew (S2_vtrunehb (VMPYB_no_V5 (HiReg $Rs), (HiReg $Rt))), 3284 (S2_vtrunehb (VMPYB_no_V5 (LoReg $Rs), (LoReg $Rt))))>; 3285 3286def SDTHexagonBinOp64 : SDTypeProfile<1, 2, 3287 [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>]>; 3288 3289def HexagonSHUFFEB: SDNode<"HexagonISD::SHUFFEB", SDTHexagonBinOp64>; 3290def HexagonSHUFFEH: SDNode<"HexagonISD::SHUFFEH", SDTHexagonBinOp64>; 3291def HexagonSHUFFOB: SDNode<"HexagonISD::SHUFFOB", SDTHexagonBinOp64>; 3292def HexagonSHUFFOH: SDNode<"HexagonISD::SHUFFOH", SDTHexagonBinOp64>; 3293 3294class ShufflePat<InstHexagon MI, SDNode Op> 3295 : Pat<(i64 (Op DoubleRegs:$src1, DoubleRegs:$src2)), 3296 (i64 (MI DoubleRegs:$src1, DoubleRegs:$src2))>; 3297 3298// Shuffles even bytes for i=0..3: A[2*i].b = C[2*i].b; A[2*i+1].b = B[2*i].b 3299def: ShufflePat<S2_shuffeb, HexagonSHUFFEB>; 3300 3301// Shuffles odd bytes for i=0..3: A[2*i].b = C[2*i+1].b; A[2*i+1].b = B[2*i+1].b 3302def: ShufflePat<S2_shuffob, HexagonSHUFFOB>; 3303 3304// Shuffles even half for i=0,1: A[2*i].h = C[2*i].h; A[2*i+1].h = B[2*i].h 3305def: ShufflePat<S2_shuffeh, HexagonSHUFFEH>; 3306 3307// Shuffles odd half for i=0,1: A[2*i].h = C[2*i+1].h; A[2*i+1].h = B[2*i+1].h 3308def: ShufflePat<S2_shuffoh, HexagonSHUFFOH>; 3309 3310 3311// Truncated store from v4i16 to v4i8. 3312def truncstorev4i8: PatFrag<(ops node:$val, node:$ptr), 3313 (truncstore node:$val, node:$ptr), 3314 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v4i8; }]>; 3315 3316// Truncated store from v2i32 to v2i16. 3317def truncstorev2i16: PatFrag<(ops node:$val, node:$ptr), 3318 (truncstore node:$val, node:$ptr), 3319 [{ return cast<StoreSDNode>(N)->getMemoryVT() == MVT::v2i16; }]>; 3320 3321def: Pat<(truncstorev2i16 V2I32:$Rs, I32:$Rt), 3322 (S2_storeri_io I32:$Rt, 0, (LoReg (S2_packhl (HiReg $Rs), 3323 (LoReg $Rs))))>; 3324 3325def: Pat<(truncstorev4i8 V4I16:$Rs, I32:$Rt), 3326 (S2_storeri_io I32:$Rt, 0, (S2_vtrunehb V4I16:$Rs))>; 3327 3328 3329// Zero and sign extended load from v2i8 into v2i16. 3330def zextloadv2i8: PatFrag<(ops node:$ptr), (zextload node:$ptr), 3331 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>; 3332 3333def sextloadv2i8: PatFrag<(ops node:$ptr), (sextload node:$ptr), 3334 [{ return cast<LoadSDNode>(N)->getMemoryVT() == MVT::v2i8; }]>; 3335 3336def: Pat<(v2i16 (zextloadv2i8 I32:$Rs)), 3337 (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0))))>; 3338 3339def: Pat<(v2i16 (sextloadv2i8 I32:$Rs)), 3340 (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0))))>; 3341 3342def: Pat<(v2i32 (zextloadv2i8 I32:$Rs)), 3343 (S2_vzxthw (LoReg (v4i16 (S2_vzxtbh (L2_loadruh_io I32:$Rs, 0)))))>; 3344 3345def: Pat<(v2i32 (sextloadv2i8 I32:$Rs)), 3346 (S2_vsxthw (LoReg (v4i16 (S2_vsxtbh (L2_loadrh_io I32:$Rs, 0)))))>; 3347 3348