1234285Sdim//==- HexagonInstrInfo.td - Target Description for Hexagon -*- tablegen -*-===// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file describes the Hexagon instructions in TableGen format. 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14234285Sdiminclude "HexagonInstrFormats.td" 15249423Sdiminclude "HexagonOperands.td" 16234285Sdim 17251662Sdim//===----------------------------------------------------------------------===// 18251662Sdim 19234285Sdim// Multi-class for logical operators. 20234285Sdimmulticlass ALU32_rr_ri<string OpcStr, SDNode OpNode> { 21234285Sdim def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 22234285Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 23239462Sdim [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b), 24239462Sdim (i32 IntRegs:$c)))]>; 25234285Sdim def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c), 26234285Sdim !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")), 27239462Sdim [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b, 28239462Sdim (i32 IntRegs:$c)))]>; 29234285Sdim} 30234285Sdim 31234285Sdim// Multi-class for compare ops. 32234285Sdimlet isCompare = 1 in { 33234285Sdimmulticlass CMP64_rr<string OpcStr, PatFrag OpNode> { 34234285Sdim def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c), 35234285Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 36239462Sdim [(set (i1 PredRegs:$dst), 37239462Sdim (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>; 38234285Sdim} 39234285Sdim 40249423Sdimmulticlass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> { 41249423Sdim let CextOpcode = CextOp in { 42249423Sdim let InputType = "reg" in 43249423Sdim def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 44249423Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 45249423Sdim [(set (i1 PredRegs:$dst), 46249423Sdim (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; 47249423Sdim 48249423Sdim let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, 49249423Sdim opExtentBits = 10, InputType = "imm" in 50249423Sdim def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c), 51249423Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 52249423Sdim [(set (i1 PredRegs:$dst), 53249423Sdim (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>; 54249423Sdim } 55234285Sdim} 56234285Sdim 57249423Sdimmulticlass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> { 58249423Sdim let CextOpcode = CextOp in { 59249423Sdim let InputType = "reg" in 60249423Sdim def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 61249423Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 62249423Sdim [(set (i1 PredRegs:$dst), 63249423Sdim (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; 64249423Sdim 65249423Sdim let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, 66249423Sdim opExtentBits = 9, InputType = "imm" in 67249423Sdim def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c), 68249423Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 69249423Sdim [(set (i1 PredRegs:$dst), 70249423Sdim (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>; 71249423Sdim } 72234285Sdim} 73234285Sdim 74234285Sdimmulticlass CMP32_ri_s8<string OpcStr, PatFrag OpNode> { 75249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in 76249423Sdim def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c), 77234285Sdim !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 78239462Sdim [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), 79249423Sdim s8ExtPred:$c))]>; 80234285Sdim} 81234285Sdim} 82234285Sdim 83234285Sdim//===----------------------------------------------------------------------===// 84243830Sdim// ALU32/ALU (Instructions with register-register form) 85234285Sdim//===----------------------------------------------------------------------===// 86251662Sdimdef SDTHexagonI64I32I32 : SDTypeProfile<1, 2, 87251662Sdim [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; 88251662Sdim 89251662Sdimdef HexagonWrapperCombineII : 90251662Sdim SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>; 91251662Sdim 92251662Sdimdef HexagonWrapperCombineRR : 93251662Sdim SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>; 94251662Sdim 95251662Sdimmulticlass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot, 96243830Sdim bit isPredNew> { 97251662Sdim let isPredicatedNew = isPredNew in 98251662Sdim def NAME : ALU32_rr<(outs RC:$dst), 99243830Sdim (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3), 100243830Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 101243830Sdim ") $dst = ")#mnemonic#"($src2, $src3)", 102243830Sdim []>; 103243830Sdim} 104243830Sdim 105251662Sdimmulticlass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 106251662Sdim let isPredicatedFalse = PredNot in { 107251662Sdim defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>; 108243830Sdim // Predicate new 109251662Sdim defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>; 110243830Sdim } 111243830Sdim} 112243830Sdim 113243830Sdimlet InputType = "reg" in 114243830Sdimmulticlass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> { 115243830Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in { 116243830Sdim let isPredicable = 1 in 117249423Sdim def NAME : ALU32_rr<(outs IntRegs:$dst), 118234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 119243830Sdim "$dst = "#mnemonic#"($src1, $src2)", 120243830Sdim [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1), 121243830Sdim (i32 IntRegs:$src2)))]>; 122234285Sdim 123243830Sdim let neverHasSideEffects = 1, isPredicated = 1 in { 124251662Sdim defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>; 125251662Sdim defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>; 126243830Sdim } 127243830Sdim } 128243830Sdim} 129243830Sdim 130243830Sdimlet isCommutable = 1 in { 131243830Sdim defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel; 132243830Sdim defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel; 133243830Sdim defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel; 134243830Sdim defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel; 135243830Sdim} 136243830Sdim 137243830Sdimdefm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel; 138243830Sdim 139251662Sdim// Combines the two integer registers SRC1 and SRC2 into a double register. 140251662Sdimlet isPredicable = 1 in 141251662Sdimclass T_Combine : ALU32_rr<(outs DoubleRegs:$dst), 142251662Sdim (ins IntRegs:$src1, IntRegs:$src2), 143251662Sdim "$dst = combine($src1, $src2)", 144251662Sdim [(set (i64 DoubleRegs:$dst), 145251662Sdim (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1), 146251662Sdim (i32 IntRegs:$src2))))]>; 147251662Sdim 148251662Sdimmulticlass Combine_base { 149251662Sdim let BaseOpcode = "combine" in { 150251662Sdim def NAME : T_Combine; 151251662Sdim let neverHasSideEffects = 1, isPredicated = 1 in { 152251662Sdim defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>; 153251662Sdim defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>; 154251662Sdim } 155251662Sdim } 156251662Sdim} 157251662Sdim 158251662Sdimdefm COMBINE_rr : Combine_base, PredNewRel; 159251662Sdim 160251662Sdim// Combines the two immediates SRC1 and SRC2 into a double register. 161251662Sdimclass COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> : 162251662Sdim ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2), 163251662Sdim "$dst = combine(#$src1, #$src2)", 164251662Sdim [(set (i64 DoubleRegs:$dst), 165251662Sdim (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>; 166251662Sdim 167251662Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in 168251662Sdimdef COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>; 169251662Sdim 170243830Sdim//===----------------------------------------------------------------------===// 171243830Sdim// ALU32/ALU (ADD with register-immediate form) 172243830Sdim//===----------------------------------------------------------------------===// 173243830Sdimmulticlass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> { 174251662Sdim let isPredicatedNew = isPredNew in 175249423Sdim def NAME : ALU32_ri<(outs IntRegs:$dst), 176249423Sdim (ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3), 177243830Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 178243830Sdim ") $dst = ")#mnemonic#"($src2, #$src3)", 179243830Sdim []>; 180243830Sdim} 181243830Sdim 182243830Sdimmulticlass ALU32ri_Pred<string mnemonic, bit PredNot> { 183251662Sdim let isPredicatedFalse = PredNot in { 184249423Sdim defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>; 185243830Sdim // Predicate new 186249423Sdim defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>; 187243830Sdim } 188243830Sdim} 189243830Sdim 190249423Sdimlet isExtendable = 1, InputType = "imm" in 191243830Sdimmulticlass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> { 192243830Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in { 193249423Sdim let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16, 194249423Sdim isPredicable = 1 in 195249423Sdim def NAME : ALU32_ri<(outs IntRegs:$dst), 196249423Sdim (ins IntRegs:$src1, s16Ext:$src2), 197243830Sdim "$dst = "#mnemonic#"($src1, #$src2)", 198243830Sdim [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1), 199249423Sdim (s16ExtPred:$src2)))]>; 200234285Sdim 201249423Sdim let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 202249423Sdim neverHasSideEffects = 1, isPredicated = 1 in { 203243830Sdim defm Pt : ALU32ri_Pred<mnemonic, 0>; 204243830Sdim defm NotPt : ALU32ri_Pred<mnemonic, 1>; 205243830Sdim } 206243830Sdim } 207243830Sdim} 208234285Sdim 209243830Sdimdefm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel; 210234285Sdim 211249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10, 212249423SdimCextOpcode = "OR", InputType = "imm" in 213234285Sdimdef OR_ri : ALU32_ri<(outs IntRegs:$dst), 214249423Sdim (ins IntRegs:$src1, s10Ext:$src2), 215234285Sdim "$dst = or($src1, #$src2)", 216239462Sdim [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), 217249423Sdim s10ExtPred:$src2))]>, ImmRegRel; 218234285Sdim 219249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10, 220249423SdimInputType = "imm", CextOpcode = "AND" in 221234285Sdimdef AND_ri : ALU32_ri<(outs IntRegs:$dst), 222249423Sdim (ins IntRegs:$src1, s10Ext:$src2), 223234285Sdim "$dst = and($src1, #$src2)", 224239462Sdim [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), 225249423Sdim s10ExtPred:$src2))]>, ImmRegRel; 226251662Sdim 227234285Sdim// Nop. 228234285Sdimlet neverHasSideEffects = 1 in 229234285Sdimdef NOP : ALU32_rr<(outs), (ins), 230234285Sdim "nop", 231234285Sdim []>; 232234285Sdim 233239462Sdim// Rd32=sub(#s10,Rs32) 234249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10, 235249423SdimCextOpcode = "SUB", InputType = "imm" in 236239462Sdimdef SUB_ri : ALU32_ri<(outs IntRegs:$dst), 237249423Sdim (ins s10Ext:$src1, IntRegs:$src2), 238239462Sdim "$dst = sub(#$src1, $src2)", 239249423Sdim [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>, 240249423Sdim ImmRegRel; 241239462Sdim 242251662Sdim// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs). 243251662Sdimdef : Pat<(not (i32 IntRegs:$src1)), 244251662Sdim (SUB_ri -1, (i32 IntRegs:$src1))>; 245234285Sdim 246251662Sdim// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs). 247251662Sdim// Pattern definition for 'neg' was not necessary. 248251662Sdim 249249423Sdimmulticlass TFR_Pred<bit PredNot> { 250251662Sdim let isPredicatedFalse = PredNot in { 251249423Sdim def _c#NAME : ALU32_rr<(outs IntRegs:$dst), 252249423Sdim (ins PredRegs:$src1, IntRegs:$src2), 253249423Sdim !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2", 254249423Sdim []>; 255249423Sdim // Predicate new 256251662Sdim let isPredicatedNew = 1 in 257249423Sdim def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst), 258249423Sdim (ins PredRegs:$src1, IntRegs:$src2), 259249423Sdim !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2", 260249423Sdim []>; 261249423Sdim } 262249423Sdim} 263234285Sdim 264249423Sdimlet InputType = "reg", neverHasSideEffects = 1 in 265249423Sdimmulticlass TFR_base<string CextOp> { 266249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp in { 267249423Sdim let isPredicable = 1 in 268249423Sdim def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), 269249423Sdim "$dst = $src1", 270249423Sdim []>; 271239462Sdim 272249423Sdim let isPredicated = 1 in { 273249423Sdim defm Pt : TFR_Pred<0>; 274249423Sdim defm NotPt : TFR_Pred<1>; 275249423Sdim } 276249423Sdim } 277249423Sdim} 278249423Sdim 279249423Sdimclass T_TFR64_Pred<bit PredNot, bit isPredNew> 280249423Sdim : ALU32_rr<(outs DoubleRegs:$dst), 281249423Sdim (ins PredRegs:$src1, DoubleRegs:$src2), 282249423Sdim !if(PredNot, "if (!$src1", "if ($src1")# 283249423Sdim !if(isPredNew, ".new) ", ") ")#"$dst = $src2", []> 284249423Sdim{ 285249423Sdim bits<5> dst; 286249423Sdim bits<2> src1; 287249423Sdim bits<5> src2; 288249423Sdim 289249423Sdim let IClass = 0b1111; 290249423Sdim let Inst{27-24} = 0b1101; 291249423Sdim let Inst{13} = isPredNew; 292249423Sdim let Inst{7} = PredNot; 293249423Sdim let Inst{4-0} = dst; 294249423Sdim let Inst{6-5} = src1; 295249423Sdim let Inst{20-17} = src2{4-1}; 296249423Sdim let Inst{16} = 0b1; 297249423Sdim let Inst{12-9} = src2{4-1}; 298249423Sdim let Inst{8} = 0b0; 299249423Sdim} 300249423Sdim 301249423Sdimmulticlass TFR64_Pred<bit PredNot> { 302251662Sdim let isPredicatedFalse = PredNot in { 303249423Sdim def _c#NAME : T_TFR64_Pred<PredNot, 0>; 304249423Sdim 305251662Sdim let isPredicatedNew = 1 in 306249423Sdim def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new 307249423Sdim } 308249423Sdim} 309249423Sdim 310249423Sdimlet neverHasSideEffects = 1 in 311249423Sdimmulticlass TFR64_base<string BaseName> { 312249423Sdim let BaseOpcode = BaseName in { 313249423Sdim let isPredicable = 1 in 314249423Sdim def NAME : ALU32Inst <(outs DoubleRegs:$dst), 315249423Sdim (ins DoubleRegs:$src1), 316249423Sdim "$dst = $src1" > { 317249423Sdim bits<5> dst; 318249423Sdim bits<5> src1; 319249423Sdim 320249423Sdim let IClass = 0b1111; 321249423Sdim let Inst{27-23} = 0b01010; 322249423Sdim let Inst{4-0} = dst; 323249423Sdim let Inst{20-17} = src1{4-1}; 324249423Sdim let Inst{16} = 0b1; 325249423Sdim let Inst{12-9} = src1{4-1}; 326249423Sdim let Inst{8} = 0b0; 327249423Sdim } 328249423Sdim 329249423Sdim let isPredicated = 1 in { 330249423Sdim defm Pt : TFR64_Pred<0>; 331249423Sdim defm NotPt : TFR64_Pred<1>; 332249423Sdim } 333249423Sdim } 334249423Sdim} 335249423Sdim 336249423Sdimmulticlass TFRI_Pred<bit PredNot> { 337251662Sdim let isMoveImm = 1, isPredicatedFalse = PredNot in { 338249423Sdim def _c#NAME : ALU32_ri<(outs IntRegs:$dst), 339249423Sdim (ins PredRegs:$src1, s12Ext:$src2), 340249423Sdim !if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2", 341249423Sdim []>; 342249423Sdim 343249423Sdim // Predicate new 344251662Sdim let isPredicatedNew = 1 in 345249423Sdim def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst), 346249423Sdim (ins PredRegs:$src1, s12Ext:$src2), 347249423Sdim !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2", 348249423Sdim []>; 349249423Sdim } 350249423Sdim} 351249423Sdim 352249423Sdimlet InputType = "imm", isExtendable = 1, isExtentSigned = 1 in 353249423Sdimmulticlass TFRI_base<string CextOp> { 354249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#I in { 355249423Sdim let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16, 356249423Sdim isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in 357249423Sdim def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), 358249423Sdim "$dst = #$src1", 359249423Sdim [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>; 360249423Sdim 361249423Sdim let opExtendable = 2, opExtentBits = 12, neverHasSideEffects = 1, 362249423Sdim isPredicated = 1 in { 363249423Sdim defm Pt : TFRI_Pred<0>; 364249423Sdim defm NotPt : TFRI_Pred<1>; 365249423Sdim } 366249423Sdim } 367249423Sdim} 368249423Sdim 369249423Sdimdefm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel; 370249423Sdimdefm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel; 371249423Sdimdefm TFR64 : TFR64_base<"TFR64">, PredNewRel; 372249423Sdim 373234285Sdim// Transfer control register. 374234285Sdimlet neverHasSideEffects = 1 in 375234285Sdimdef TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1), 376234285Sdim "$dst = $src1", 377234285Sdim []>; 378234285Sdim//===----------------------------------------------------------------------===// 379234285Sdim// ALU32/ALU - 380234285Sdim//===----------------------------------------------------------------------===// 381234285Sdim 382234285Sdim 383234285Sdim//===----------------------------------------------------------------------===// 384234285Sdim// ALU32/PERM + 385234285Sdim//===----------------------------------------------------------------------===// 386234285Sdim 387263508Sdimlet neverHasSideEffects = 1 in 388263508Sdimdef COMBINE_ii : ALU32_ii<(outs DoubleRegs:$dst), 389263508Sdim (ins s8Imm:$src1, s8Imm:$src2), 390263508Sdim "$dst = combine(#$src1, #$src2)", 391263508Sdim []>; 392263508Sdim 393234285Sdim// Mux. 394234285Sdimdef VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, 395234285Sdim DoubleRegs:$src2, 396234285Sdim DoubleRegs:$src3), 397234285Sdim "$dst = vmux($src1, $src2, $src3)", 398234285Sdim []>; 399234285Sdim 400249423Sdimlet CextOpcode = "MUX", InputType = "reg" in 401234285Sdimdef MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, 402234285Sdim IntRegs:$src2, IntRegs:$src3), 403234285Sdim "$dst = mux($src1, $src2, $src3)", 404249423Sdim [(set (i32 IntRegs:$dst), 405249423Sdim (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 406249423Sdim (i32 IntRegs:$src3))))]>, ImmRegRel; 407234285Sdim 408249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 409249423SdimCextOpcode = "MUX", InputType = "imm" in 410249423Sdimdef MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2, 411234285Sdim IntRegs:$src3), 412234285Sdim "$dst = mux($src1, #$src2, $src3)", 413249423Sdim [(set (i32 IntRegs:$dst), 414249423Sdim (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2, 415249423Sdim (i32 IntRegs:$src3))))]>, ImmRegRel; 416234285Sdim 417249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 418249423SdimCextOpcode = "MUX", InputType = "imm" in 419234285Sdimdef MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, 420249423Sdim s8Ext:$src3), 421234285Sdim "$dst = mux($src1, $src2, #$src3)", 422249423Sdim [(set (i32 IntRegs:$dst), 423249423Sdim (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 424249423Sdim s8ExtPred:$src3)))]>, ImmRegRel; 425234285Sdim 426249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in 427249423Sdimdef MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2, 428234285Sdim s8Imm:$src3), 429234285Sdim "$dst = mux($src1, #$src2, #$src3)", 430239462Sdim [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), 431249423Sdim s8ExtPred:$src2, 432239462Sdim s8ImmPred:$src3)))]>; 433234285Sdim 434249423Sdim// ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth 435249423Sdimmulticlass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> { 436249423Sdim let isPredicatedNew = isPredNew in 437249423Sdim def NAME : ALU32Inst<(outs IntRegs:$dst), 438249423Sdim (ins PredRegs:$src1, IntRegs:$src2), 439249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 440249423Sdim ") $dst = ")#mnemonic#"($src2)">, 441249423Sdim Requires<[HasV4T]>; 442249423Sdim} 443234285Sdim 444249423Sdimmulticlass ALU32_2op_Pred<string mnemonic, bit PredNot> { 445249423Sdim let isPredicatedFalse = PredNot in { 446249423Sdim defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>; 447249423Sdim // Predicate new 448249423Sdim defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>; 449249423Sdim } 450249423Sdim} 451234285Sdim 452249423Sdimmulticlass ALU32_2op_base<string mnemonic> { 453249423Sdim let BaseOpcode = mnemonic in { 454249423Sdim let isPredicable = 1, neverHasSideEffects = 1 in 455249423Sdim def NAME : ALU32Inst<(outs IntRegs:$dst), 456249423Sdim (ins IntRegs:$src1), 457249423Sdim "$dst = "#mnemonic#"($src1)">; 458234285Sdim 459249423Sdim let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1, 460249423Sdim neverHasSideEffects = 1 in { 461249423Sdim defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>; 462249423Sdim defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>; 463249423Sdim } 464249423Sdim } 465249423Sdim} 466234285Sdim 467249423Sdimdefm ASLH : ALU32_2op_base<"aslh">, PredNewRel; 468249423Sdimdefm ASRH : ALU32_2op_base<"asrh">, PredNewRel; 469249423Sdimdefm SXTB : ALU32_2op_base<"sxtb">, PredNewRel; 470249423Sdimdefm SXTH : ALU32_2op_base<"sxth">, PredNewRel; 471249423Sdimdefm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel; 472249423Sdimdefm ZXTH : ALU32_2op_base<"zxth">, PredNewRel; 473234285Sdim 474249423Sdimdef : Pat <(shl (i32 IntRegs:$src1), (i32 16)), 475249423Sdim (ASLH IntRegs:$src1)>; 476249423Sdim 477249423Sdimdef : Pat <(sra (i32 IntRegs:$src1), (i32 16)), 478249423Sdim (ASRH IntRegs:$src1)>; 479249423Sdim 480249423Sdimdef : Pat <(sext_inreg (i32 IntRegs:$src1), i8), 481249423Sdim (SXTB IntRegs:$src1)>; 482249423Sdim 483249423Sdimdef : Pat <(sext_inreg (i32 IntRegs:$src1), i16), 484249423Sdim (SXTH IntRegs:$src1)>; 485249423Sdim 486234285Sdim//===----------------------------------------------------------------------===// 487234285Sdim// ALU32/PERM - 488234285Sdim//===----------------------------------------------------------------------===// 489234285Sdim 490234285Sdim 491234285Sdim//===----------------------------------------------------------------------===// 492234285Sdim// ALU32/PRED + 493234285Sdim//===----------------------------------------------------------------------===// 494234285Sdim 495249423Sdim// Compare. 496249423Sdimdefm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel; 497249423Sdimdefm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel; 498249423Sdimdefm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel; 499234285Sdim 500251662Sdim// SDNode for converting immediate C to C-1. 501251662Sdimdef DEC_CONST_SIGNED : SDNodeXForm<imm, [{ 502251662Sdim // Return the byte immediate const-1 as an SDNode. 503251662Sdim int32_t imm = N->getSExtValue(); 504251662Sdim return XformSToSM1Imm(imm); 505251662Sdim}]>; 506251662Sdim 507251662Sdim// SDNode for converting immediate C to C-1. 508251662Sdimdef DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{ 509251662Sdim // Return the byte immediate const-1 as an SDNode. 510251662Sdim uint32_t imm = N->getZExtValue(); 511251662Sdim return XformUToUM1Imm(imm); 512251662Sdim}]>; 513251662Sdim 514249423Sdimdef CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), 515249423Sdim "$dst = cl0($src1)", 516249423Sdim [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>; 517234285Sdim 518249423Sdimdef CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), 519249423Sdim "$dst = ct0($src1)", 520249423Sdim [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>; 521239462Sdim 522249423Sdimdef CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), 523249423Sdim "$dst = cl0($src1)", 524249423Sdim [(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>; 525239462Sdim 526249423Sdimdef CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), 527249423Sdim "$dst = ct0($src1)", 528249423Sdim [(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>; 529234285Sdim 530249423Sdimdef TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 531249423Sdim "$dst = tstbit($src1, $src2)", 532249423Sdim [(set (i1 PredRegs:$dst), 533249423Sdim (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>; 534234285Sdim 535249423Sdimdef TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 536249423Sdim "$dst = tstbit($src1, $src2)", 537249423Sdim [(set (i1 PredRegs:$dst), 538249423Sdim (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>; 539234285Sdim 540234285Sdim//===----------------------------------------------------------------------===// 541234285Sdim// ALU32/PRED - 542234285Sdim//===----------------------------------------------------------------------===// 543234285Sdim 544234285Sdim 545234285Sdim//===----------------------------------------------------------------------===// 546234285Sdim// ALU64/ALU + 547234285Sdim//===----------------------------------------------------------------------===// 548234285Sdim// Add. 549234285Sdimdef ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 550234285Sdim DoubleRegs:$src2), 551234285Sdim "$dst = add($src1, $src2)", 552239462Sdim [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1), 553239462Sdim (i64 DoubleRegs:$src2)))]>; 554234285Sdim 555234285Sdim// Add halfword. 556234285Sdim 557234285Sdim// Compare. 558234285Sdimdefm CMPEHexagon4 : CMP64_rr<"cmp.eq", seteq>; 559234285Sdimdefm CMPGT64 : CMP64_rr<"cmp.gt", setgt>; 560234285Sdimdefm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>; 561234285Sdim 562234285Sdim// Logical operations. 563234285Sdimdef AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 564234285Sdim DoubleRegs:$src2), 565234285Sdim "$dst = and($src1, $src2)", 566239462Sdim [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), 567239462Sdim (i64 DoubleRegs:$src2)))]>; 568234285Sdim 569234285Sdimdef OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 570234285Sdim DoubleRegs:$src2), 571234285Sdim "$dst = or($src1, $src2)", 572239462Sdim [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1), 573239462Sdim (i64 DoubleRegs:$src2)))]>; 574234285Sdim 575234285Sdimdef XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 576234285Sdim DoubleRegs:$src2), 577234285Sdim "$dst = xor($src1, $src2)", 578239462Sdim [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), 579239462Sdim (i64 DoubleRegs:$src2)))]>; 580234285Sdim 581234285Sdim// Maximum. 582234285Sdimdef MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 583234285Sdim "$dst = max($src2, $src1)", 584239462Sdim [(set (i32 IntRegs:$dst), 585239462Sdim (i32 (select (i1 (setlt (i32 IntRegs:$src2), 586239462Sdim (i32 IntRegs:$src1))), 587239462Sdim (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 588234285Sdim 589239462Sdimdef MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 590239462Sdim "$dst = maxu($src2, $src1)", 591239462Sdim [(set (i32 IntRegs:$dst), 592239462Sdim (i32 (select (i1 (setult (i32 IntRegs:$src2), 593239462Sdim (i32 IntRegs:$src1))), 594239462Sdim (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 595239462Sdim 596239462Sdimdef MAXd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 597239462Sdim DoubleRegs:$src2), 598239462Sdim "$dst = max($src2, $src1)", 599239462Sdim [(set (i64 DoubleRegs:$dst), 600239462Sdim (i64 (select (i1 (setlt (i64 DoubleRegs:$src2), 601239462Sdim (i64 DoubleRegs:$src1))), 602239462Sdim (i64 DoubleRegs:$src1), 603239462Sdim (i64 DoubleRegs:$src2))))]>; 604239462Sdim 605239462Sdimdef MAXUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 606239462Sdim DoubleRegs:$src2), 607239462Sdim "$dst = maxu($src2, $src1)", 608239462Sdim [(set (i64 DoubleRegs:$dst), 609239462Sdim (i64 (select (i1 (setult (i64 DoubleRegs:$src2), 610239462Sdim (i64 DoubleRegs:$src1))), 611239462Sdim (i64 DoubleRegs:$src1), 612239462Sdim (i64 DoubleRegs:$src2))))]>; 613239462Sdim 614234285Sdim// Minimum. 615234285Sdimdef MINw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 616234285Sdim "$dst = min($src2, $src1)", 617239462Sdim [(set (i32 IntRegs:$dst), 618239462Sdim (i32 (select (i1 (setgt (i32 IntRegs:$src2), 619239462Sdim (i32 IntRegs:$src1))), 620239462Sdim (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 621234285Sdim 622239462Sdimdef MINUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 623239462Sdim "$dst = minu($src2, $src1)", 624239462Sdim [(set (i32 IntRegs:$dst), 625239462Sdim (i32 (select (i1 (setugt (i32 IntRegs:$src2), 626239462Sdim (i32 IntRegs:$src1))), 627239462Sdim (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 628239462Sdim 629239462Sdimdef MINd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 630239462Sdim DoubleRegs:$src2), 631239462Sdim "$dst = min($src2, $src1)", 632239462Sdim [(set (i64 DoubleRegs:$dst), 633239462Sdim (i64 (select (i1 (setgt (i64 DoubleRegs:$src2), 634239462Sdim (i64 DoubleRegs:$src1))), 635239462Sdim (i64 DoubleRegs:$src1), 636239462Sdim (i64 DoubleRegs:$src2))))]>; 637239462Sdim 638239462Sdimdef MINUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 639239462Sdim DoubleRegs:$src2), 640239462Sdim "$dst = minu($src2, $src1)", 641239462Sdim [(set (i64 DoubleRegs:$dst), 642239462Sdim (i64 (select (i1 (setugt (i64 DoubleRegs:$src2), 643239462Sdim (i64 DoubleRegs:$src1))), 644239462Sdim (i64 DoubleRegs:$src1), 645239462Sdim (i64 DoubleRegs:$src2))))]>; 646239462Sdim 647234285Sdim// Subtract. 648234285Sdimdef SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 649234285Sdim DoubleRegs:$src2), 650234285Sdim "$dst = sub($src1, $src2)", 651239462Sdim [(set (i64 DoubleRegs:$dst), (sub (i64 DoubleRegs:$src1), 652239462Sdim (i64 DoubleRegs:$src2)))]>; 653234285Sdim 654234285Sdim// Subtract halfword. 655234285Sdim 656234285Sdim//===----------------------------------------------------------------------===// 657234285Sdim// ALU64/ALU - 658234285Sdim//===----------------------------------------------------------------------===// 659234285Sdim 660234285Sdim//===----------------------------------------------------------------------===// 661234285Sdim// ALU64/BIT + 662234285Sdim//===----------------------------------------------------------------------===// 663234285Sdim// 664234285Sdim//===----------------------------------------------------------------------===// 665234285Sdim// ALU64/BIT - 666234285Sdim//===----------------------------------------------------------------------===// 667234285Sdim 668234285Sdim//===----------------------------------------------------------------------===// 669234285Sdim// ALU64/PERM + 670234285Sdim//===----------------------------------------------------------------------===// 671234285Sdim// 672234285Sdim//===----------------------------------------------------------------------===// 673234285Sdim// ALU64/PERM - 674234285Sdim//===----------------------------------------------------------------------===// 675234285Sdim 676234285Sdim//===----------------------------------------------------------------------===// 677234285Sdim// CR + 678234285Sdim//===----------------------------------------------------------------------===// 679234285Sdim// Logical reductions on predicates. 680234285Sdim 681234285Sdim// Looping instructions. 682234285Sdim 683234285Sdim// Pipelined looping instructions. 684234285Sdim 685234285Sdim// Logical operations on predicates. 686234285Sdimdef AND_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 687234285Sdim "$dst = and($src1, $src2)", 688239462Sdim [(set (i1 PredRegs:$dst), (and (i1 PredRegs:$src1), 689239462Sdim (i1 PredRegs:$src2)))]>; 690234285Sdim 691234285Sdimlet neverHasSideEffects = 1 in 692234285Sdimdef AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, 693234285Sdim PredRegs:$src2), 694234285Sdim "$dst = and($src1, !$src2)", 695234285Sdim []>; 696234285Sdim 697234285Sdimdef ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 698234285Sdim "$dst = any8($src1)", 699234285Sdim []>; 700234285Sdim 701234285Sdimdef ALL_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 702234285Sdim "$dst = all8($src1)", 703234285Sdim []>; 704234285Sdim 705234285Sdimdef VITPACK_pp : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1, 706234285Sdim PredRegs:$src2), 707234285Sdim "$dst = vitpack($src1, $src2)", 708234285Sdim []>; 709234285Sdim 710234285Sdimdef VALIGN_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 711234285Sdim DoubleRegs:$src2, 712234285Sdim PredRegs:$src3), 713234285Sdim "$dst = valignb($src1, $src2, $src3)", 714234285Sdim []>; 715234285Sdim 716234285Sdimdef VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 717234285Sdim DoubleRegs:$src2, 718234285Sdim PredRegs:$src3), 719234285Sdim "$dst = vspliceb($src1, $src2, $src3)", 720234285Sdim []>; 721234285Sdim 722234285Sdimdef MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1), 723234285Sdim "$dst = mask($src1)", 724234285Sdim []>; 725234285Sdim 726234285Sdimdef NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 727234285Sdim "$dst = not($src1)", 728239462Sdim [(set (i1 PredRegs:$dst), (not (i1 PredRegs:$src1)))]>; 729234285Sdim 730234285Sdimdef OR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 731234285Sdim "$dst = or($src1, $src2)", 732239462Sdim [(set (i1 PredRegs:$dst), (or (i1 PredRegs:$src1), 733239462Sdim (i1 PredRegs:$src2)))]>; 734234285Sdim 735234285Sdimdef XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 736234285Sdim "$dst = xor($src1, $src2)", 737239462Sdim [(set (i1 PredRegs:$dst), (xor (i1 PredRegs:$src1), 738239462Sdim (i1 PredRegs:$src2)))]>; 739234285Sdim 740234285Sdim 741234285Sdim// User control register transfer. 742234285Sdim//===----------------------------------------------------------------------===// 743234285Sdim// CR - 744234285Sdim//===----------------------------------------------------------------------===// 745234285Sdim 746251662Sdimdef retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone, 747251662Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 748251662Sdimdef eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, 749251662Sdim [SDNPHasChain]>; 750234285Sdim 751251662Sdimdef SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 752251662Sdimdef HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>; 753234285Sdim 754251662Sdimlet InputType = "imm", isBarrier = 1, isPredicable = 1, 755251662SdimDefs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1, 756251662SdimopExtentBits = 24 in 757251662Sdimclass T_JMP <dag InsDag, list<dag> JumpList = []> 758251662Sdim : JInst<(outs), InsDag, 759251662Sdim "jump $dst" , JumpList> { 760251662Sdim bits<24> dst; 761251662Sdim 762251662Sdim let IClass = 0b0101; 763251662Sdim 764251662Sdim let Inst{27-25} = 0b100; 765251662Sdim let Inst{24-16} = dst{23-15}; 766251662Sdim let Inst{13-1} = dst{14-2}; 767234285Sdim} 768234285Sdim 769251662Sdimlet InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1, 770251662SdimDefs = [PC], isPredicated = 1, opExtentBits = 17 in 771251662Sdimclass T_JMP_c <bit PredNot, bit isPredNew, bit isTaken>: 772251662Sdim JInst<(outs ), (ins PredRegs:$src, brtarget:$dst), 773251662Sdim !if(PredNot, "if (!$src", "if ($src")# 774251662Sdim !if(isPredNew, ".new) ", ") ")#"jump"# 775251662Sdim !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> { 776251662Sdim 777251662Sdim let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), ""); 778251662Sdim let isPredicatedFalse = PredNot; 779251662Sdim let isPredicatedNew = isPredNew; 780251662Sdim bits<2> src; 781251662Sdim bits<17> dst; 782251662Sdim 783251662Sdim let IClass = 0b0101; 784251662Sdim 785251662Sdim let Inst{27-24} = 0b1100; 786251662Sdim let Inst{21} = PredNot; 787251662Sdim let Inst{12} = !if(isPredNew, isTaken, zero); 788251662Sdim let Inst{11} = isPredNew; 789251662Sdim let Inst{9-8} = src; 790251662Sdim let Inst{23-22} = dst{16-15}; 791251662Sdim let Inst{20-16} = dst{14-10}; 792251662Sdim let Inst{13} = dst{9}; 793251662Sdim let Inst{7-1} = dst{8-2}; 794251662Sdim } 795251662Sdim 796251662Sdimlet isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in 797251662Sdimclass T_JMPr<dag InsDag = (ins IntRegs:$dst)> 798251662Sdim : JRInst<(outs ), InsDag, 799251662Sdim "jumpr $dst" , 800251662Sdim []> { 801251662Sdim bits<5> dst; 802251662Sdim 803251662Sdim let IClass = 0b0101; 804251662Sdim let Inst{27-21} = 0b0010100; 805251662Sdim let Inst{20-16} = dst; 806234285Sdim} 807234285Sdim 808251662Sdimlet Defs = [PC], isPredicated = 1, InputType = "reg" in 809251662Sdimclass T_JMPr_c <bit PredNot, bit isPredNew, bit isTaken>: 810251662Sdim JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst), 811251662Sdim !if(PredNot, "if (!$src", "if ($src")# 812251662Sdim !if(isPredNew, ".new) ", ") ")#"jumpr"# 813251662Sdim !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> { 814251662Sdim 815251662Sdim let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), ""); 816251662Sdim let isPredicatedFalse = PredNot; 817251662Sdim let isPredicatedNew = isPredNew; 818251662Sdim bits<2> src; 819251662Sdim bits<5> dst; 820251662Sdim 821251662Sdim let IClass = 0b0101; 822251662Sdim 823251662Sdim let Inst{27-22} = 0b001101; 824251662Sdim let Inst{21} = PredNot; 825251662Sdim let Inst{20-16} = dst; 826251662Sdim let Inst{12} = !if(isPredNew, isTaken, zero); 827251662Sdim let Inst{11} = isPredNew; 828251662Sdim let Inst{9-8} = src; 829251662Sdim let Predicates = !if(isPredNew, [HasV3T], [HasV2T]); 830251662Sdim let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT); 831234285Sdim} 832234285Sdim 833251662Sdimmulticlass JMP_Pred<bit PredNot> { 834251662Sdim def _#NAME : T_JMP_c<PredNot, 0, 0>; 835251662Sdim // Predicate new 836251662Sdim def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken 837251662Sdim def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken 838234285Sdim} 839234285Sdim 840251662Sdimmulticlass JMP_base<string BaseOp> { 841251662Sdim let BaseOpcode = BaseOp in { 842251662Sdim def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>; 843251662Sdim defm t : JMP_Pred<0>; 844251662Sdim defm f : JMP_Pred<1>; 845251662Sdim } 846234285Sdim} 847234285Sdim 848251662Sdimmulticlass JMPR_Pred<bit PredNot> { 849251662Sdim def NAME: T_JMPr_c<PredNot, 0, 0>; 850251662Sdim // Predicate new 851251662Sdim def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken 852251662Sdim def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken 853234285Sdim} 854234285Sdim 855251662Sdimmulticlass JMPR_base<string BaseOp> { 856251662Sdim let BaseOpcode = BaseOp in { 857251662Sdim def NAME : T_JMPr; 858251662Sdim defm _t : JMPR_Pred<0>; 859251662Sdim defm _f : JMPR_Pred<1>; 860251662Sdim } 861234285Sdim} 862234285Sdim 863251662Sdimlet isTerminator = 1, neverHasSideEffects = 1 in { 864251662Sdimlet isBranch = 1 in 865251662Sdimdefm JMP : JMP_base<"JMP">, PredNewRel; 866234285Sdim 867251662Sdimlet isBranch = 1, isIndirectBranch = 1 in 868251662Sdimdefm JMPR : JMPR_base<"JMPr">, PredNewRel; 869234285Sdim 870251662Sdimlet isReturn = 1, isCodeGenOnly = 1 in 871251662Sdimdefm JMPret : JMPR_base<"JMPret">, PredNewRel; 872234285Sdim} 873234285Sdim 874251662Sdimdef : Pat<(retflag), 875251662Sdim (JMPret (i32 R31))>; 876234285Sdim 877251662Sdimdef : Pat <(brcond (i1 PredRegs:$src1), bb:$offset), 878251662Sdim (JMP_t (i1 PredRegs:$src1), bb:$offset)>; 879251662Sdim 880251662Sdim// A return through builtin_eh_return. 881251662Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1, 882251662SdimisCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in 883251662Sdimdef EH_RETURN_JMPR : T_JMPr; 884251662Sdim 885251662Sdimdef : Pat<(eh_return), 886251662Sdim (EH_RETURN_JMPR (i32 R31))>; 887251662Sdim 888251662Sdimdef : Pat<(HexagonBR_JT (i32 IntRegs:$dst)), 889251662Sdim (JMPR (i32 IntRegs:$dst))>; 890251662Sdim 891251662Sdimdef : Pat<(brind (i32 IntRegs:$dst)), 892251662Sdim (JMPR (i32 IntRegs:$dst))>; 893251662Sdim 894234285Sdim//===----------------------------------------------------------------------===// 895234285Sdim// JR - 896234285Sdim//===----------------------------------------------------------------------===// 897234285Sdim 898234285Sdim//===----------------------------------------------------------------------===// 899234285Sdim// LD + 900234285Sdim//===----------------------------------------------------------------------===// 901234285Sdim/// 902249423Sdim// Load -- MEMri operand 903249423Sdimmulticlass LD_MEMri_Pbase<string mnemonic, RegisterClass RC, 904249423Sdim bit isNot, bit isPredNew> { 905251662Sdim let isPredicatedNew = isPredNew in 906249423Sdim def NAME : LDInst2<(outs RC:$dst), 907249423Sdim (ins PredRegs:$src1, MEMri:$addr), 908249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 909249423Sdim ") ")#"$dst = "#mnemonic#"($addr)", 910249423Sdim []>; 911249423Sdim} 912234285Sdim 913249423Sdimmulticlass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 914251662Sdim let isPredicatedFalse = PredNot in { 915249423Sdim defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>; 916249423Sdim // Predicate new 917249423Sdim defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>; 918249423Sdim } 919249423Sdim} 920234285Sdim 921249423Sdimlet isExtendable = 1, neverHasSideEffects = 1 in 922249423Sdimmulticlass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC, 923249423Sdim bits<5> ImmBits, bits<5> PredImmBits> { 924234285Sdim 925249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp in { 926249423Sdim let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits, 927249423Sdim isPredicable = 1 in 928249423Sdim def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr), 929249423Sdim "$dst = "#mnemonic#"($addr)", 930249423Sdim []>; 931234285Sdim 932249423Sdim let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits, 933249423Sdim isPredicated = 1 in { 934249423Sdim defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >; 935249423Sdim defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >; 936249423Sdim } 937249423Sdim } 938249423Sdim} 939234285Sdim 940249423Sdimlet addrMode = BaseImmOffset, isMEMri = "true" in { 941263508Sdim let accessSize = ByteAccess in { 942263508Sdim defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel; 943263508Sdim defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel; 944263508Sdim } 945263508Sdim 946263508Sdim let accessSize = HalfWordAccess in { 947263508Sdim defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel; 948263508Sdim defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel; 949263508Sdim } 950263508Sdim 951263508Sdim let accessSize = WordAccess in 952263508Sdim defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel; 953263508Sdim 954263508Sdim let accessSize = DoubleWordAccess in 955263508Sdim defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel; 956249423Sdim} 957234285Sdim 958249423Sdimdef : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)), 959249423Sdim (LDrib ADDRriS11_0:$addr) >; 960234285Sdim 961249423Sdimdef : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)), 962249423Sdim (LDriub ADDRriS11_0:$addr) >; 963234285Sdim 964249423Sdimdef : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)), 965249423Sdim (LDrih ADDRriS11_1:$addr) >; 966234285Sdim 967249423Sdimdef : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)), 968249423Sdim (LDriuh ADDRriS11_1:$addr) >; 969234285Sdim 970249423Sdimdef : Pat < (i32 (load ADDRriS11_2:$addr)), 971249423Sdim (LDriw ADDRriS11_2:$addr) >; 972234285Sdim 973249423Sdimdef : Pat < (i64 (load ADDRriS11_3:$addr)), 974249423Sdim (LDrid ADDRriS11_3:$addr) >; 975234285Sdim 976234285Sdim 977249423Sdim// Load - Base with Immediate offset addressing mode 978249423Sdimmulticlass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp, 979249423Sdim bit isNot, bit isPredNew> { 980251662Sdim let isPredicatedNew = isPredNew in 981249423Sdim def NAME : LDInst2<(outs RC:$dst), 982249423Sdim (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3), 983249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 984249423Sdim ") ")#"$dst = "#mnemonic#"($src2+#$src3)", 985234285Sdim []>; 986249423Sdim} 987234285Sdim 988249423Sdimmulticlass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp, 989249423Sdim bit PredNot> { 990251662Sdim let isPredicatedFalse = PredNot in { 991249423Sdim defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>; 992249423Sdim // Predicate new 993249423Sdim defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>; 994249423Sdim } 995249423Sdim} 996234285Sdim 997249423Sdimlet isExtendable = 1, neverHasSideEffects = 1 in 998249423Sdimmulticlass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC, 999249423Sdim Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 1000249423Sdim bits<5> PredImmBits> { 1001234285Sdim 1002249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 1003249423Sdim let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits, 1004249423Sdim isPredicable = 1, AddedComplexity = 20 in 1005249423Sdim def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset), 1006249423Sdim "$dst = "#mnemonic#"($src1+#$offset)", 1007249423Sdim []>; 1008234285Sdim 1009249423Sdim let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits, 1010249423Sdim isPredicated = 1 in { 1011249423Sdim defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >; 1012249423Sdim defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >; 1013249423Sdim } 1014249423Sdim } 1015249423Sdim} 1016234285Sdim 1017249423Sdimlet addrMode = BaseImmOffset in { 1018263508Sdim let accessSize = ByteAccess in { 1019263508Sdim defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext, 1020263508Sdim 11, 6>, AddrModeRel; 1021263508Sdim defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext, 1022263508Sdim 11, 6>, AddrModeRel; 1023263508Sdim } 1024263508Sdim let accessSize = HalfWordAccess in { 1025263508Sdim defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext, 1026263508Sdim 12, 7>, AddrModeRel; 1027263508Sdim defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext, 1028263508Sdim 12, 7>, AddrModeRel; 1029263508Sdim } 1030263508Sdim let accessSize = WordAccess in 1031263508Sdim defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext, 1032263508Sdim 13, 8>, AddrModeRel; 1033263508Sdim 1034263508Sdim let accessSize = DoubleWordAccess in 1035263508Sdim defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext, 1036263508Sdim 14, 9>, AddrModeRel; 1037249423Sdim} 1038234285Sdim 1039249423Sdimlet AddedComplexity = 20 in { 1040249423Sdimdef : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))), 1041249423Sdim (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >; 1042234285Sdim 1043249423Sdimdef : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))), 1044249423Sdim (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >; 1045234285Sdim 1046249423Sdimdef : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))), 1047249423Sdim (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >; 1048234285Sdim 1049249423Sdimdef : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))), 1050249423Sdim (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >; 1051234285Sdim 1052249423Sdimdef : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))), 1053249423Sdim (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >; 1054234285Sdim 1055249423Sdimdef : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))), 1056249423Sdim (LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >; 1057249423Sdim} 1058234285Sdim 1059249423Sdim//===----------------------------------------------------------------------===// 1060249423Sdim// Post increment load 1061249423Sdim//===----------------------------------------------------------------------===// 1062234285Sdim 1063249423Sdimmulticlass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, 1064249423Sdim bit isNot, bit isPredNew> { 1065251662Sdim let isPredicatedNew = isPredNew in 1066249423Sdim def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2), 1067249423Sdim (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset), 1068249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1069249423Sdim ") ")#"$dst = "#mnemonic#"($src2++#$offset)", 1070234285Sdim [], 1071234285Sdim "$src2 = $dst2">; 1072249423Sdim} 1073234285Sdim 1074249423Sdimmulticlass LD_PostInc_Pred<string mnemonic, RegisterClass RC, 1075249423Sdim Operand ImmOp, bit PredNot> { 1076251662Sdim let isPredicatedFalse = PredNot in { 1077249423Sdim defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; 1078249423Sdim // Predicate new 1079249423Sdim let Predicates = [HasV4T], validSubTargets = HasV4SubT in 1080249423Sdim defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>; 1081249423Sdim } 1082249423Sdim} 1083234285Sdim 1084249423Sdimmulticlass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC, 1085249423Sdim Operand ImmOp> { 1086234285Sdim 1087249423Sdim let BaseOpcode = "POST_"#BaseOp in { 1088249423Sdim let isPredicable = 1 in 1089249423Sdim def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2), 1090249423Sdim (ins IntRegs:$src1, ImmOp:$offset), 1091249423Sdim "$dst = "#mnemonic#"($src1++#$offset)", 1092249423Sdim [], 1093249423Sdim "$src1 = $dst2">; 1094234285Sdim 1095249423Sdim let isPredicated = 1 in { 1096249423Sdim defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >; 1097249423Sdim defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >; 1098249423Sdim } 1099249423Sdim } 1100249423Sdim} 1101234285Sdim 1102263508Sdimlet hasCtrlDep = 1, neverHasSideEffects = 1, addrMode = PostInc in { 1103249423Sdim defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>, 1104249423Sdim PredNewRel; 1105249423Sdim defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>, 1106249423Sdim PredNewRel; 1107249423Sdim defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>, 1108249423Sdim PredNewRel; 1109249423Sdim defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>, 1110249423Sdim PredNewRel; 1111249423Sdim defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>, 1112249423Sdim PredNewRel; 1113249423Sdim defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>, 1114249423Sdim PredNewRel; 1115249423Sdim} 1116234285Sdim 1117249423Sdimdef : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)), 1118249423Sdim (i32 (LDrib ADDRriS11_0:$addr)) >; 1119234285Sdim 1120249423Sdim// Load byte any-extend. 1121249423Sdimdef : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)), 1122249423Sdim (i32 (LDrib ADDRriS11_0:$addr)) >; 1123234285Sdim 1124249423Sdim// Indexed load byte any-extend. 1125249423Sdimlet AddedComplexity = 20 in 1126249423Sdimdef : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))), 1127249423Sdim (i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >; 1128234285Sdim 1129239462Sdimdef : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)), 1130239462Sdim (i32 (LDrih ADDRriS11_1:$addr))>; 1131234285Sdim 1132234285Sdimlet AddedComplexity = 20 in 1133239462Sdimdef : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))), 1134239462Sdim (i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >; 1135234285Sdim 1136249423Sdimlet AddedComplexity = 10 in 1137239462Sdimdef : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)), 1138239462Sdim (i32 (LDriub ADDRriS11_0:$addr))>; 1139234285Sdim 1140234285Sdimlet AddedComplexity = 20 in 1141239462Sdimdef : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))), 1142239462Sdim (i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>; 1143234285Sdim 1144234285Sdim// Load predicate. 1145249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13, 1146249423SdimisPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in 1147249423Sdimdef LDriw_pred : LDInst2<(outs PredRegs:$dst), 1148234285Sdim (ins MEMri:$addr), 1149234285Sdim "Error; should not emit", 1150234285Sdim []>; 1151234285Sdim 1152234285Sdim// Deallocate stack frame. 1153234285Sdimlet Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in { 1154249423Sdim def DEALLOCFRAME : LDInst2<(outs), (ins), 1155234285Sdim "deallocframe", 1156234285Sdim []>; 1157234285Sdim} 1158234285Sdim 1159234285Sdim// Load and unpack bytes to halfwords. 1160234285Sdim//===----------------------------------------------------------------------===// 1161234285Sdim// LD - 1162234285Sdim//===----------------------------------------------------------------------===// 1163234285Sdim 1164234285Sdim//===----------------------------------------------------------------------===// 1165234285Sdim// MTYPE/ALU + 1166234285Sdim//===----------------------------------------------------------------------===// 1167234285Sdim//===----------------------------------------------------------------------===// 1168234285Sdim// MTYPE/ALU - 1169234285Sdim//===----------------------------------------------------------------------===// 1170234285Sdim 1171234285Sdim//===----------------------------------------------------------------------===// 1172234285Sdim// MTYPE/COMPLEX + 1173234285Sdim//===----------------------------------------------------------------------===// 1174234285Sdim//===----------------------------------------------------------------------===// 1175234285Sdim// MTYPE/COMPLEX - 1176234285Sdim//===----------------------------------------------------------------------===// 1177234285Sdim 1178234285Sdim//===----------------------------------------------------------------------===// 1179234285Sdim// MTYPE/MPYH + 1180234285Sdim//===----------------------------------------------------------------------===// 1181234285Sdim// Multiply and use lower result. 1182234285Sdim// Rd=+mpyi(Rs,#u8) 1183249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in 1184249423Sdimdef MPYI_riu : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Ext:$src2), 1185234285Sdim "$dst =+ mpyi($src1, #$src2)", 1186239462Sdim [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1187249423Sdim u8ExtPred:$src2))]>; 1188234285Sdim 1189234285Sdim// Rd=-mpyi(Rs,#u8) 1190249423Sdimdef MPYI_rin : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2), 1191234285Sdim "$dst =- mpyi($src1, #$src2)", 1192249423Sdim [(set (i32 IntRegs:$dst), (ineg (mul (i32 IntRegs:$src1), 1193249423Sdim u8ImmPred:$src2)))]>; 1194234285Sdim 1195234285Sdim// Rd=mpyi(Rs,#m9) 1196234285Sdim// s9 is NOT the same as m9 - but it works.. so far. 1197234285Sdim// Assembler maps to either Rd=+mpyi(Rs,#u8 or Rd=-mpyi(Rs,#u8) 1198234285Sdim// depending on the value of m9. See Arch Spec. 1199249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 9, 1200249423SdimCextOpcode = "MPYI", InputType = "imm" in 1201249423Sdimdef MPYI_ri : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2), 1202234285Sdim "$dst = mpyi($src1, #$src2)", 1203239462Sdim [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1204249423Sdim s9ExtPred:$src2))]>, ImmRegRel; 1205234285Sdim 1206234285Sdim// Rd=mpyi(Rs,Rt) 1207249423Sdimlet CextOpcode = "MPYI", InputType = "reg" in 1208234285Sdimdef MPYI : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1209234285Sdim "$dst = mpyi($src1, $src2)", 1210239462Sdim [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1211249423Sdim (i32 IntRegs:$src2)))]>, ImmRegRel; 1212234285Sdim 1213234285Sdim// Rx+=mpyi(Rs,#u8) 1214249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8, 1215249423SdimCextOpcode = "MPYI_acc", InputType = "imm" in 1216234285Sdimdef MPYI_acc_ri : MInst_acc<(outs IntRegs:$dst), 1217249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3), 1218234285Sdim "$dst += mpyi($src2, #$src3)", 1219239462Sdim [(set (i32 IntRegs:$dst), 1220249423Sdim (add (mul (i32 IntRegs:$src2), u8ExtPred:$src3), 1221239462Sdim (i32 IntRegs:$src1)))], 1222249423Sdim "$src1 = $dst">, ImmRegRel; 1223234285Sdim 1224234285Sdim// Rx+=mpyi(Rs,Rt) 1225249423Sdimlet CextOpcode = "MPYI_acc", InputType = "reg" in 1226234285Sdimdef MPYI_acc_rr : MInst_acc<(outs IntRegs:$dst), 1227234285Sdim (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1228234285Sdim "$dst += mpyi($src2, $src3)", 1229239462Sdim [(set (i32 IntRegs:$dst), 1230239462Sdim (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1231239462Sdim (i32 IntRegs:$src1)))], 1232249423Sdim "$src1 = $dst">, ImmRegRel; 1233234285Sdim 1234234285Sdim// Rx-=mpyi(Rs,#u8) 1235249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8 in 1236234285Sdimdef MPYI_sub_ri : MInst_acc<(outs IntRegs:$dst), 1237249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3), 1238234285Sdim "$dst -= mpyi($src2, #$src3)", 1239239462Sdim [(set (i32 IntRegs:$dst), 1240239462Sdim (sub (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1241249423Sdim u8ExtPred:$src3)))], 1242234285Sdim "$src1 = $dst">; 1243234285Sdim 1244234285Sdim// Multiply and use upper result. 1245234285Sdim// Rd=mpy(Rs,Rt.H):<<1:rnd:sat 1246234285Sdim// Rd=mpy(Rs,Rt.L):<<1:rnd:sat 1247234285Sdim// Rd=mpy(Rs,Rt) 1248234285Sdimdef MPY : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1249234285Sdim "$dst = mpy($src1, $src2)", 1250239462Sdim [(set (i32 IntRegs:$dst), (mulhs (i32 IntRegs:$src1), 1251239462Sdim (i32 IntRegs:$src2)))]>; 1252234285Sdim 1253234285Sdim// Rd=mpy(Rs,Rt):rnd 1254234285Sdim// Rd=mpyu(Rs,Rt) 1255234285Sdimdef MPYU : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1256234285Sdim "$dst = mpyu($src1, $src2)", 1257239462Sdim [(set (i32 IntRegs:$dst), (mulhu (i32 IntRegs:$src1), 1258239462Sdim (i32 IntRegs:$src2)))]>; 1259234285Sdim 1260234285Sdim// Multiply and use full result. 1261234285Sdim// Rdd=mpyu(Rs,Rt) 1262234285Sdimdef MPYU64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1263234285Sdim "$dst = mpyu($src1, $src2)", 1264239462Sdim [(set (i64 DoubleRegs:$dst), 1265239462Sdim (mul (i64 (anyext (i32 IntRegs:$src1))), 1266239462Sdim (i64 (anyext (i32 IntRegs:$src2)))))]>; 1267234285Sdim 1268234285Sdim// Rdd=mpy(Rs,Rt) 1269234285Sdimdef MPY64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1270234285Sdim "$dst = mpy($src1, $src2)", 1271239462Sdim [(set (i64 DoubleRegs:$dst), 1272239462Sdim (mul (i64 (sext (i32 IntRegs:$src1))), 1273239462Sdim (i64 (sext (i32 IntRegs:$src2)))))]>; 1274234285Sdim 1275234285Sdim// Multiply and accumulate, use full result. 1276234285Sdim// Rxx[+-]=mpy(Rs,Rt) 1277234285Sdim// Rxx+=mpy(Rs,Rt) 1278234285Sdimdef MPY64_acc : MInst_acc<(outs DoubleRegs:$dst), 1279234285Sdim (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1280234285Sdim "$dst += mpy($src2, $src3)", 1281239462Sdim [(set (i64 DoubleRegs:$dst), 1282239462Sdim (add (mul (i64 (sext (i32 IntRegs:$src2))), 1283239462Sdim (i64 (sext (i32 IntRegs:$src3)))), 1284239462Sdim (i64 DoubleRegs:$src1)))], 1285234285Sdim "$src1 = $dst">; 1286234285Sdim 1287234285Sdim// Rxx-=mpy(Rs,Rt) 1288234285Sdimdef MPY64_sub : MInst_acc<(outs DoubleRegs:$dst), 1289234285Sdim (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1290234285Sdim "$dst -= mpy($src2, $src3)", 1291239462Sdim [(set (i64 DoubleRegs:$dst), 1292239462Sdim (sub (i64 DoubleRegs:$src1), 1293239462Sdim (mul (i64 (sext (i32 IntRegs:$src2))), 1294239462Sdim (i64 (sext (i32 IntRegs:$src3))))))], 1295234285Sdim "$src1 = $dst">; 1296234285Sdim 1297234285Sdim// Rxx[+-]=mpyu(Rs,Rt) 1298234285Sdim// Rxx+=mpyu(Rs,Rt) 1299234285Sdimdef MPYU64_acc : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1300234285Sdim IntRegs:$src2, IntRegs:$src3), 1301234285Sdim "$dst += mpyu($src2, $src3)", 1302239462Sdim [(set (i64 DoubleRegs:$dst), 1303239462Sdim (add (mul (i64 (anyext (i32 IntRegs:$src2))), 1304239462Sdim (i64 (anyext (i32 IntRegs:$src3)))), 1305239462Sdim (i64 DoubleRegs:$src1)))], "$src1 = $dst">; 1306234285Sdim 1307234285Sdim// Rxx-=mpyu(Rs,Rt) 1308234285Sdimdef MPYU64_sub : MInst_acc<(outs DoubleRegs:$dst), 1309234285Sdim (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1310249423Sdim "$dst -= mpyu($src2, $src3)", 1311239462Sdim [(set (i64 DoubleRegs:$dst), 1312239462Sdim (sub (i64 DoubleRegs:$src1), 1313239462Sdim (mul (i64 (anyext (i32 IntRegs:$src2))), 1314239462Sdim (i64 (anyext (i32 IntRegs:$src3))))))], 1315234285Sdim "$src1 = $dst">; 1316234285Sdim 1317234285Sdim 1318249423Sdimlet InputType = "reg", CextOpcode = "ADD_acc" in 1319234285Sdimdef ADDrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1320234285Sdim IntRegs:$src2, IntRegs:$src3), 1321234285Sdim "$dst += add($src2, $src3)", 1322239462Sdim [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2), 1323239462Sdim (i32 IntRegs:$src3)), 1324239462Sdim (i32 IntRegs:$src1)))], 1325249423Sdim "$src1 = $dst">, ImmRegRel; 1326234285Sdim 1327249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 1328249423SdimInputType = "imm", CextOpcode = "ADD_acc" in 1329234285Sdimdef ADDri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1330249423Sdim IntRegs:$src2, s8Ext:$src3), 1331234285Sdim "$dst += add($src2, #$src3)", 1332239462Sdim [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2), 1333249423Sdim s8_16ExtPred:$src3), 1334239462Sdim (i32 IntRegs:$src1)))], 1335249423Sdim "$src1 = $dst">, ImmRegRel; 1336234285Sdim 1337249423Sdimlet CextOpcode = "SUB_acc", InputType = "reg" in 1338234285Sdimdef SUBrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1339234285Sdim IntRegs:$src2, IntRegs:$src3), 1340234285Sdim "$dst -= add($src2, $src3)", 1341239462Sdim [(set (i32 IntRegs:$dst), 1342239462Sdim (sub (i32 IntRegs:$src1), (add (i32 IntRegs:$src2), 1343239462Sdim (i32 IntRegs:$src3))))], 1344249423Sdim "$src1 = $dst">, ImmRegRel; 1345234285Sdim 1346249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 1347249423SdimCextOpcode = "SUB_acc", InputType = "imm" in 1348234285Sdimdef SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1349249423Sdim IntRegs:$src2, s8Ext:$src3), 1350234285Sdim "$dst -= add($src2, #$src3)", 1351239462Sdim [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1), 1352239462Sdim (add (i32 IntRegs:$src2), 1353249423Sdim s8_16ExtPred:$src3)))], 1354249423Sdim "$src1 = $dst">, ImmRegRel; 1355234285Sdim 1356234285Sdim//===----------------------------------------------------------------------===// 1357234285Sdim// MTYPE/MPYH - 1358234285Sdim//===----------------------------------------------------------------------===// 1359234285Sdim 1360234285Sdim//===----------------------------------------------------------------------===// 1361234285Sdim// MTYPE/MPYS + 1362234285Sdim//===----------------------------------------------------------------------===// 1363234285Sdim//===----------------------------------------------------------------------===// 1364234285Sdim// MTYPE/MPYS - 1365234285Sdim//===----------------------------------------------------------------------===// 1366234285Sdim 1367234285Sdim//===----------------------------------------------------------------------===// 1368234285Sdim// MTYPE/VB + 1369234285Sdim//===----------------------------------------------------------------------===// 1370234285Sdim//===----------------------------------------------------------------------===// 1371234285Sdim// MTYPE/VB - 1372234285Sdim//===----------------------------------------------------------------------===// 1373234285Sdim 1374234285Sdim//===----------------------------------------------------------------------===// 1375234285Sdim// MTYPE/VH + 1376234285Sdim//===----------------------------------------------------------------------===// 1377234285Sdim//===----------------------------------------------------------------------===// 1378234285Sdim// MTYPE/VH - 1379234285Sdim//===----------------------------------------------------------------------===// 1380234285Sdim 1381234285Sdim//===----------------------------------------------------------------------===// 1382234285Sdim// ST + 1383234285Sdim//===----------------------------------------------------------------------===// 1384234285Sdim/// 1385234285Sdim// Store doubleword. 1386234285Sdim 1387249423Sdim//===----------------------------------------------------------------------===// 1388249423Sdim// Post increment store 1389249423Sdim//===----------------------------------------------------------------------===// 1390234285Sdim 1391249423Sdimmulticlass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, 1392249423Sdim bit isNot, bit isPredNew> { 1393251662Sdim let isPredicatedNew = isPredNew in 1394249423Sdim def NAME : STInst2PI<(outs IntRegs:$dst), 1395249423Sdim (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3), 1396249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1397249423Sdim ") ")#mnemonic#"($src2++#$offset) = $src3", 1398249423Sdim [], 1399249423Sdim "$src2 = $dst">; 1400249423Sdim} 1401234285Sdim 1402249423Sdimmulticlass ST_PostInc_Pred<string mnemonic, RegisterClass RC, 1403249423Sdim Operand ImmOp, bit PredNot> { 1404251662Sdim let isPredicatedFalse = PredNot in { 1405263508Sdim defm _c#NAME : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; 1406249423Sdim // Predicate new 1407249423Sdim let Predicates = [HasV4T], validSubTargets = HasV4SubT in 1408249423Sdim defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>; 1409249423Sdim } 1410249423Sdim} 1411239462Sdim 1412249423Sdimlet hasCtrlDep = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1413249423Sdimmulticlass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC, 1414249423Sdim Operand ImmOp> { 1415234285Sdim 1416249423Sdim let hasCtrlDep = 1, BaseOpcode = "POST_"#BaseOp in { 1417249423Sdim let isPredicable = 1 in 1418249423Sdim def NAME : STInst2PI<(outs IntRegs:$dst), 1419249423Sdim (ins IntRegs:$src1, ImmOp:$offset, RC:$src2), 1420263508Sdim mnemonic#"($src1++#$offset) = $src2", 1421249423Sdim [], 1422249423Sdim "$src1 = $dst">; 1423234285Sdim 1424249423Sdim let isPredicated = 1 in { 1425249423Sdim defm Pt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 0 >; 1426249423Sdim defm NotPt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 1 >; 1427249423Sdim } 1428249423Sdim } 1429249423Sdim} 1430234285Sdim 1431249423Sdimdefm POST_STbri: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel; 1432249423Sdimdefm POST_SThri: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel; 1433249423Sdimdefm POST_STwri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; 1434234285Sdim 1435249423Sdimlet isNVStorable = 0 in 1436249423Sdimdefm POST_STdri: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm>, AddrModeRel; 1437234285Sdim 1438249423Sdimdef : Pat<(post_truncsti8 (i32 IntRegs:$src1), IntRegs:$src2, 1439249423Sdim s4_3ImmPred:$offset), 1440249423Sdim (POST_STbri IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>; 1441234285Sdim 1442249423Sdimdef : Pat<(post_truncsti16 (i32 IntRegs:$src1), IntRegs:$src2, 1443249423Sdim s4_3ImmPred:$offset), 1444249423Sdim (POST_SThri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>; 1445234285Sdim 1446249423Sdimdef : Pat<(post_store (i32 IntRegs:$src1), IntRegs:$src2, s4_2ImmPred:$offset), 1447249423Sdim (POST_STwri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>; 1448234285Sdim 1449249423Sdimdef : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2, 1450249423Sdim s4_3ImmPred:$offset), 1451249423Sdim (POST_STdri IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>; 1452234285Sdim 1453249423Sdim//===----------------------------------------------------------------------===// 1454249423Sdim// multiclass for the store instructions with MEMri operand. 1455249423Sdim//===----------------------------------------------------------------------===// 1456249423Sdimmulticlass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot, 1457249423Sdim bit isPredNew> { 1458251662Sdim let isPredicatedNew = isPredNew in 1459249423Sdim def NAME : STInst2<(outs), 1460249423Sdim (ins PredRegs:$src1, MEMri:$addr, RC: $src2), 1461249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1462249423Sdim ") ")#mnemonic#"($addr) = $src2", 1463249423Sdim []>; 1464249423Sdim} 1465234285Sdim 1466249423Sdimmulticlass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 1467251662Sdim let isPredicatedFalse = PredNot in { 1468249423Sdim defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>; 1469234285Sdim 1470249423Sdim // Predicate new 1471249423Sdim let validSubTargets = HasV4SubT, Predicates = [HasV4T] in 1472249423Sdim defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>; 1473249423Sdim } 1474249423Sdim} 1475234285Sdim 1476249423Sdimlet isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1477249423Sdimmulticlass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC, 1478249423Sdim bits<5> ImmBits, bits<5> PredImmBits> { 1479234285Sdim 1480249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp in { 1481249423Sdim let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 1482249423Sdim isPredicable = 1 in 1483249423Sdim def NAME : STInst2<(outs), 1484249423Sdim (ins MEMri:$addr, RC:$src), 1485249423Sdim mnemonic#"($addr) = $src", 1486234285Sdim []>; 1487234285Sdim 1488249423Sdim let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 1489249423Sdim isPredicated = 1 in { 1490249423Sdim defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>; 1491249423Sdim defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>; 1492249423Sdim } 1493249423Sdim } 1494249423Sdim} 1495234285Sdim 1496249423Sdimlet addrMode = BaseImmOffset, isMEMri = "true" in { 1497263508Sdim let accessSize = ByteAccess in 1498263508Sdim defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel; 1499234285Sdim 1500263508Sdim let accessSize = HalfWordAccess in 1501263508Sdim defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel; 1502263508Sdim 1503263508Sdim let accessSize = WordAccess in 1504263508Sdim defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel; 1505263508Sdim 1506263508Sdim let accessSize = DoubleWordAccess, isNVStorable = 0 in 1507263508Sdim defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel; 1508249423Sdim} 1509234285Sdim 1510249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr), 1511249423Sdim (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>; 1512234285Sdim 1513249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr), 1514249423Sdim (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>; 1515234285Sdim 1516249423Sdimdef : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr), 1517249423Sdim (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>; 1518234285Sdim 1519249423Sdimdef : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr), 1520249423Sdim (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>; 1521234285Sdim 1522234285Sdim 1523249423Sdim//===----------------------------------------------------------------------===// 1524249423Sdim// multiclass for the store instructions with base+immediate offset 1525249423Sdim// addressing mode 1526249423Sdim//===----------------------------------------------------------------------===// 1527249423Sdimmulticlass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp, 1528249423Sdim bit isNot, bit isPredNew> { 1529251662Sdim let isPredicatedNew = isPredNew in 1530249423Sdim def NAME : STInst2<(outs), 1531249423Sdim (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4), 1532249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1533249423Sdim ") ")#mnemonic#"($src2+#$src3) = $src4", 1534249423Sdim []>; 1535249423Sdim} 1536234285Sdim 1537249423Sdimmulticlass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp, 1538249423Sdim bit PredNot> { 1539251662Sdim let isPredicatedFalse = PredNot, isPredicated = 1 in { 1540249423Sdim defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>; 1541234285Sdim 1542249423Sdim // Predicate new 1543249423Sdim let validSubTargets = HasV4SubT, Predicates = [HasV4T] in 1544249423Sdim defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>; 1545249423Sdim } 1546249423Sdim} 1547234285Sdim 1548249423Sdimlet isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1549249423Sdimmulticlass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC, 1550249423Sdim Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 1551249423Sdim bits<5> PredImmBits> { 1552234285Sdim 1553249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 1554249423Sdim let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 1555249423Sdim isPredicable = 1 in 1556249423Sdim def NAME : STInst2<(outs), 1557249423Sdim (ins IntRegs:$src1, ImmOp:$src2, RC:$src3), 1558249423Sdim mnemonic#"($src1+#$src2) = $src3", 1559234285Sdim []>; 1560234285Sdim 1561249423Sdim let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in { 1562249423Sdim defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>; 1563249423Sdim defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>; 1564249423Sdim } 1565249423Sdim } 1566249423Sdim} 1567234285Sdim 1568249423Sdimlet addrMode = BaseImmOffset, InputType = "reg" in { 1569263508Sdim let accessSize = ByteAccess in 1570263508Sdim defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext, 1571263508Sdim u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel; 1572263508Sdim 1573263508Sdim let accessSize = HalfWordAccess in 1574263508Sdim defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext, 1575263508Sdim u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel; 1576263508Sdim 1577263508Sdim let accessSize = WordAccess in 1578263508Sdim defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext, 1579263508Sdim u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel; 1580263508Sdim 1581263508Sdim let accessSize = DoubleWordAccess, isNVStorable = 0 in 1582263508Sdim defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext, 1583263508Sdim u6_3Ext, 14, 9>, AddrModeRel; 1584249423Sdim} 1585234285Sdim 1586249423Sdimlet AddedComplexity = 10 in { 1587249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2, 1588249423Sdim s11_0ExtPred:$offset)), 1589249423Sdim (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset, 1590249423Sdim (i32 IntRegs:$src1))>; 1591234285Sdim 1592249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2, 1593249423Sdim s11_1ExtPred:$offset)), 1594249423Sdim (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset, 1595249423Sdim (i32 IntRegs:$src1))>; 1596234285Sdim 1597249423Sdimdef : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2, 1598249423Sdim s11_2ExtPred:$offset)), 1599249423Sdim (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset, 1600249423Sdim (i32 IntRegs:$src1))>; 1601234285Sdim 1602249423Sdimdef : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2, 1603249423Sdim s11_3ExtPred:$offset)), 1604249423Sdim (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset, 1605249423Sdim (i64 DoubleRegs:$src1))>; 1606249423Sdim} 1607234285Sdim 1608249423Sdim// memh(Rx++#s4:1)=Rt.H 1609249423Sdim 1610234285Sdim// Store word. 1611234285Sdim// Store predicate. 1612239462Sdimlet Defs = [R10,R11,D5], neverHasSideEffects = 1 in 1613239462Sdimdef STriw_pred : STInst2<(outs), 1614234285Sdim (ins MEMri:$addr, PredRegs:$src1), 1615234285Sdim "Error; should not emit", 1616234285Sdim []>; 1617234285Sdim 1618234285Sdim// Allocate stack frame. 1619234285Sdimlet Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in { 1620239462Sdim def ALLOCFRAME : STInst2<(outs), 1621234285Sdim (ins i32imm:$amt), 1622234285Sdim "allocframe(#$amt)", 1623234285Sdim []>; 1624234285Sdim} 1625234285Sdim//===----------------------------------------------------------------------===// 1626234285Sdim// ST - 1627234285Sdim//===----------------------------------------------------------------------===// 1628234285Sdim 1629234285Sdim//===----------------------------------------------------------------------===// 1630234285Sdim// STYPE/ALU + 1631234285Sdim//===----------------------------------------------------------------------===// 1632234285Sdim// Logical NOT. 1633234285Sdimdef NOT_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), 1634234285Sdim "$dst = not($src1)", 1635239462Sdim [(set (i64 DoubleRegs:$dst), (not (i64 DoubleRegs:$src1)))]>; 1636234285Sdim 1637234285Sdim 1638234285Sdim// Sign extend word to doubleword. 1639234285Sdimdef SXTW : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1), 1640234285Sdim "$dst = sxtw($src1)", 1641239462Sdim [(set (i64 DoubleRegs:$dst), (sext (i32 IntRegs:$src1)))]>; 1642234285Sdim//===----------------------------------------------------------------------===// 1643234285Sdim// STYPE/ALU - 1644234285Sdim//===----------------------------------------------------------------------===// 1645234285Sdim 1646234285Sdim//===----------------------------------------------------------------------===// 1647234285Sdim// STYPE/BIT + 1648234285Sdim//===----------------------------------------------------------------------===// 1649239462Sdim// clrbit. 1650239462Sdimdef CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1651239462Sdim "$dst = clrbit($src1, #$src2)", 1652239462Sdim [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), 1653239462Sdim (not 1654239462Sdim (shl 1, u5ImmPred:$src2))))]>; 1655234285Sdim 1656239462Sdimdef CLRBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1657239462Sdim "$dst = clrbit($src1, #$src2)", 1658239462Sdim []>; 1659234285Sdim 1660239462Sdim// Map from r0 = and(r1, 2147483647) to r0 = clrbit(r1, #31). 1661239462Sdimdef : Pat <(and (i32 IntRegs:$src1), 2147483647), 1662239462Sdim (CLRBIT_31 (i32 IntRegs:$src1), 31)>; 1663234285Sdim 1664239462Sdim// setbit. 1665239462Sdimdef SETBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1666239462Sdim "$dst = setbit($src1, #$src2)", 1667239462Sdim [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), 1668239462Sdim (shl 1, u5ImmPred:$src2)))]>; 1669234285Sdim 1670239462Sdim// Map from r0 = or(r1, -2147483648) to r0 = setbit(r1, #31). 1671239462Sdimdef SETBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1672239462Sdim "$dst = setbit($src1, #$src2)", 1673239462Sdim []>; 1674239462Sdim 1675239462Sdimdef : Pat <(or (i32 IntRegs:$src1), -2147483648), 1676239462Sdim (SETBIT_31 (i32 IntRegs:$src1), 31)>; 1677239462Sdim 1678239462Sdim// togglebit. 1679239462Sdimdef TOGBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1680239462Sdim "$dst = setbit($src1, #$src2)", 1681239462Sdim [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1), 1682239462Sdim (shl 1, u5ImmPred:$src2)))]>; 1683239462Sdim 1684239462Sdim// Map from r0 = xor(r1, -2147483648) to r0 = togglebit(r1, #31). 1685239462Sdimdef TOGBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1686239462Sdim "$dst = togglebit($src1, #$src2)", 1687239462Sdim []>; 1688239462Sdim 1689239462Sdimdef : Pat <(xor (i32 IntRegs:$src1), -2147483648), 1690239462Sdim (TOGBIT_31 (i32 IntRegs:$src1), 31)>; 1691239462Sdim 1692234285Sdim// Predicate transfer. 1693234285Sdimlet neverHasSideEffects = 1 in 1694234285Sdimdef TFR_RsPd : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1), 1695239462Sdim "$dst = $src1 /* Should almost never emit this. */", 1696234285Sdim []>; 1697234285Sdim 1698234285Sdimdef TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1), 1699239462Sdim "$dst = $src1 /* Should almost never emit this. */", 1700239462Sdim [(set (i1 PredRegs:$dst), (trunc (i32 IntRegs:$src1)))]>; 1701234285Sdim//===----------------------------------------------------------------------===// 1702234285Sdim// STYPE/PRED - 1703234285Sdim//===----------------------------------------------------------------------===// 1704234285Sdim 1705234285Sdim//===----------------------------------------------------------------------===// 1706234285Sdim// STYPE/SHIFT + 1707234285Sdim//===----------------------------------------------------------------------===// 1708234285Sdim// Shift by immediate. 1709234285Sdimdef ASR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1710234285Sdim "$dst = asr($src1, #$src2)", 1711239462Sdim [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1), 1712239462Sdim u5ImmPred:$src2))]>; 1713234285Sdim 1714234285Sdimdef ASRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1715234285Sdim "$dst = asr($src1, #$src2)", 1716239462Sdim [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1), 1717239462Sdim u6ImmPred:$src2))]>; 1718234285Sdim 1719234285Sdimdef ASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1720234285Sdim "$dst = asl($src1, #$src2)", 1721239462Sdim [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1722239462Sdim u5ImmPred:$src2))]>; 1723234285Sdim 1724239462Sdimdef ASLd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1725239462Sdim "$dst = asl($src1, #$src2)", 1726239462Sdim [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1727239462Sdim u6ImmPred:$src2))]>; 1728239462Sdim 1729234285Sdimdef LSR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1730234285Sdim "$dst = lsr($src1, #$src2)", 1731239462Sdim [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1), 1732239462Sdim u5ImmPred:$src2))]>; 1733234285Sdim 1734234285Sdimdef LSRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1735234285Sdim "$dst = lsr($src1, #$src2)", 1736239462Sdim [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1), 1737239462Sdim u6ImmPred:$src2))]>; 1738234285Sdim 1739234285Sdim// Shift by immediate and add. 1740239462Sdimlet AddedComplexity = 100 in 1741234285Sdimdef ADDASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, 1742234285Sdim u3Imm:$src3), 1743234285Sdim "$dst = addasl($src1, $src2, #$src3)", 1744239462Sdim [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1), 1745239462Sdim (shl (i32 IntRegs:$src2), 1746239462Sdim u3ImmPred:$src3)))]>; 1747234285Sdim 1748234285Sdim// Shift by register. 1749234285Sdimdef ASL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1750234285Sdim "$dst = asl($src1, $src2)", 1751239462Sdim [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1752239462Sdim (i32 IntRegs:$src2)))]>; 1753234285Sdim 1754234285Sdimdef ASR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1755234285Sdim "$dst = asr($src1, $src2)", 1756239462Sdim [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1), 1757239462Sdim (i32 IntRegs:$src2)))]>; 1758234285Sdim 1759239462Sdimdef LSL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1760239462Sdim "$dst = lsl($src1, $src2)", 1761239462Sdim [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1762239462Sdim (i32 IntRegs:$src2)))]>; 1763234285Sdim 1764234285Sdimdef LSR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1765234285Sdim "$dst = lsr($src1, $src2)", 1766239462Sdim [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1), 1767239462Sdim (i32 IntRegs:$src2)))]>; 1768234285Sdim 1769239462Sdimdef ASLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2), 1770239462Sdim "$dst = asl($src1, $src2)", 1771239462Sdim [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1772239462Sdim (i32 IntRegs:$src2)))]>; 1773239462Sdim 1774234285Sdimdef LSLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2), 1775234285Sdim "$dst = lsl($src1, $src2)", 1776239462Sdim [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1777239462Sdim (i32 IntRegs:$src2)))]>; 1778234285Sdim 1779234285Sdimdef ASRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1780234285Sdim IntRegs:$src2), 1781234285Sdim "$dst = asr($src1, $src2)", 1782239462Sdim [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1), 1783239462Sdim (i32 IntRegs:$src2)))]>; 1784234285Sdim 1785234285Sdimdef LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1786234285Sdim IntRegs:$src2), 1787234285Sdim "$dst = lsr($src1, $src2)", 1788239462Sdim [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1), 1789239462Sdim (i32 IntRegs:$src2)))]>; 1790234285Sdim 1791234285Sdim//===----------------------------------------------------------------------===// 1792234285Sdim// STYPE/SHIFT - 1793234285Sdim//===----------------------------------------------------------------------===// 1794234285Sdim 1795234285Sdim//===----------------------------------------------------------------------===// 1796234285Sdim// STYPE/VH + 1797234285Sdim//===----------------------------------------------------------------------===// 1798234285Sdim//===----------------------------------------------------------------------===// 1799234285Sdim// STYPE/VH - 1800234285Sdim//===----------------------------------------------------------------------===// 1801234285Sdim 1802234285Sdim//===----------------------------------------------------------------------===// 1803234285Sdim// STYPE/VW + 1804234285Sdim//===----------------------------------------------------------------------===// 1805234285Sdim//===----------------------------------------------------------------------===// 1806234285Sdim// STYPE/VW - 1807234285Sdim//===----------------------------------------------------------------------===// 1808234285Sdim 1809234285Sdim//===----------------------------------------------------------------------===// 1810234285Sdim// SYSTEM/SUPER + 1811234285Sdim//===----------------------------------------------------------------------===// 1812234285Sdim 1813234285Sdim//===----------------------------------------------------------------------===// 1814234285Sdim// SYSTEM/USER + 1815234285Sdim//===----------------------------------------------------------------------===// 1816234285Sdimdef SDHexagonBARRIER: SDTypeProfile<0, 0, []>; 1817234285Sdimdef HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER, 1818234285Sdim [SDNPHasChain]>; 1819234285Sdim 1820249423Sdimlet hasSideEffects = 1, isSolo = 1 in 1821239462Sdimdef BARRIER : SYSInst<(outs), (ins), 1822234285Sdim "barrier", 1823234285Sdim [(HexagonBARRIER)]>; 1824234285Sdim 1825234285Sdim//===----------------------------------------------------------------------===// 1826234285Sdim// SYSTEM/SUPER - 1827234285Sdim//===----------------------------------------------------------------------===// 1828234285Sdim 1829234285Sdim// TFRI64 - assembly mapped. 1830234285Sdimlet isReMaterializable = 1 in 1831234285Sdimdef TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1), 1832234285Sdim "$dst = #$src1", 1833239462Sdim [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>; 1834234285Sdim 1835234285Sdim// Pseudo instruction to encode a set of conditional transfers. 1836234285Sdim// This instruction is used instead of a mux and trades-off codesize 1837234285Sdim// for performance. We conduct this transformation optimistically in 1838234285Sdim// the hope that these instructions get promoted to dot-new transfers. 1839239462Sdimlet AddedComplexity = 100, isPredicated = 1 in 1840234285Sdimdef TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, 1841234285Sdim IntRegs:$src2, 1842234285Sdim IntRegs:$src3), 1843234285Sdim "Error; should not emit", 1844239462Sdim [(set (i32 IntRegs:$dst), 1845239462Sdim (i32 (select (i1 PredRegs:$src1), 1846239462Sdim (i32 IntRegs:$src2), 1847239462Sdim (i32 IntRegs:$src3))))]>; 1848239462Sdimlet AddedComplexity = 100, isPredicated = 1 in 1849234285Sdimdef TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst), 1850234285Sdim (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3), 1851234285Sdim "Error; should not emit", 1852239462Sdim [(set (i32 IntRegs:$dst), 1853239462Sdim (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 1854239462Sdim s12ImmPred:$src3)))]>; 1855234285Sdim 1856239462Sdimlet AddedComplexity = 100, isPredicated = 1 in 1857234285Sdimdef TFR_condset_ir : ALU32_rr<(outs IntRegs:$dst), 1858234285Sdim (ins PredRegs:$src1, s12Imm:$src2, IntRegs:$src3), 1859234285Sdim "Error; should not emit", 1860239462Sdim [(set (i32 IntRegs:$dst), 1861239462Sdim (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2, 1862239462Sdim (i32 IntRegs:$src3))))]>; 1863234285Sdim 1864239462Sdimlet AddedComplexity = 100, isPredicated = 1 in 1865234285Sdimdef TFR_condset_ii : ALU32_rr<(outs IntRegs:$dst), 1866234285Sdim (ins PredRegs:$src1, s12Imm:$src2, s12Imm:$src3), 1867234285Sdim "Error; should not emit", 1868239462Sdim [(set (i32 IntRegs:$dst), 1869239462Sdim (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2, 1870239462Sdim s12ImmPred:$src3)))]>; 1871234285Sdim 1872234285Sdim// Generate frameindex addresses. 1873234285Sdimlet isReMaterializable = 1 in 1874234285Sdimdef TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1), 1875234285Sdim "$dst = add($src1)", 1876239462Sdim [(set (i32 IntRegs:$dst), ADDRri:$src1)]>; 1877234285Sdim 1878234285Sdim// 1879234285Sdim// CR - Type. 1880234285Sdim// 1881234285Sdimlet neverHasSideEffects = 1, Defs = [SA0, LC0] in { 1882234285Sdimdef LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2), 1883234285Sdim "loop0($offset, #$src2)", 1884234285Sdim []>; 1885234285Sdim} 1886234285Sdim 1887234285Sdimlet neverHasSideEffects = 1, Defs = [SA0, LC0] in { 1888234285Sdimdef LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2), 1889234285Sdim "loop0($offset, $src2)", 1890234285Sdim []>; 1891234285Sdim} 1892234285Sdim 1893234285Sdimlet isBranch = 1, isTerminator = 1, neverHasSideEffects = 1, 1894234285Sdim Defs = [PC, LC0], Uses = [SA0, LC0] in { 1895249423Sdimdef ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset), 1896249423Sdim ":endloop0", 1897249423Sdim []>; 1898234285Sdim} 1899234285Sdim 1900234285Sdim// Support for generating global address. 1901234285Sdim// Taken from X86InstrInfo.td. 1902239462Sdimdef SDTHexagonCONST32 : SDTypeProfile<1, 1, [ 1903239462Sdim SDTCisVT<0, i32>, 1904239462Sdim SDTCisVT<1, i32>, 1905239462Sdim SDTCisPtrTy<0>]>; 1906234285Sdimdef HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>; 1907234285Sdimdef HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>; 1908234285Sdim 1909239462Sdim// HI/LO Instructions 1910239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1911239462Sdimdef LO : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global), 1912239462Sdim "$dst.l = #LO($global)", 1913239462Sdim []>; 1914239462Sdim 1915239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1916239462Sdimdef HI : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global), 1917239462Sdim "$dst.h = #HI($global)", 1918239462Sdim []>; 1919239462Sdim 1920239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1921239462Sdimdef LOi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value), 1922239462Sdim "$dst.l = #LO($imm_value)", 1923239462Sdim []>; 1924239462Sdim 1925239462Sdim 1926239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1927239462Sdimdef HIi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value), 1928239462Sdim "$dst.h = #HI($imm_value)", 1929239462Sdim []>; 1930239462Sdim 1931239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1932239462Sdimdef LO_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1933239462Sdim "$dst.l = #LO($jt)", 1934239462Sdim []>; 1935239462Sdim 1936239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1937239462Sdimdef HI_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1938239462Sdim "$dst.h = #HI($jt)", 1939239462Sdim []>; 1940239462Sdim 1941239462Sdim 1942239462Sdimlet isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1943239462Sdimdef LO_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label), 1944239462Sdim "$dst.l = #LO($label)", 1945239462Sdim []>; 1946239462Sdim 1947239462Sdimlet isReMaterializable = 1, isMoveImm = 1 , neverHasSideEffects = 1 in 1948239462Sdimdef HI_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label), 1949239462Sdim "$dst.h = #HI($label)", 1950239462Sdim []>; 1951239462Sdim 1952234285Sdim// This pattern is incorrect. When we add small data, we should change 1953234285Sdim// this pattern to use memw(#foo). 1954239462Sdim// This is for sdata. 1955234285Sdimlet isMoveImm = 1 in 1956234285Sdimdef CONST32 : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global), 1957234285Sdim "$dst = CONST32(#$global)", 1958239462Sdim [(set (i32 IntRegs:$dst), 1959239462Sdim (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; 1960234285Sdim 1961239462Sdim// This is for non-sdata. 1962234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1963239462Sdimdef CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), 1964234285Sdim "$dst = CONST32(#$global)", 1965239462Sdim [(set (i32 IntRegs:$dst), 1966239462Sdim (HexagonCONST32 tglobaladdr:$global))]>; 1967234285Sdim 1968234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1969239462Sdimdef CONST32_set_jt : LDInst2<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1970234285Sdim "$dst = CONST32(#$jt)", 1971239462Sdim [(set (i32 IntRegs:$dst), 1972239462Sdim (HexagonCONST32 tjumptable:$jt))]>; 1973234285Sdim 1974234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1975239462Sdimdef CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), 1976234285Sdim "$dst = CONST32(#$global)", 1977239462Sdim [(set (i32 IntRegs:$dst), 1978239462Sdim (HexagonCONST32_GP tglobaladdr:$global))]>; 1979234285Sdim 1980234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1981239462Sdimdef CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global), 1982234285Sdim "$dst = CONST32(#$global)", 1983239462Sdim [(set (i32 IntRegs:$dst), imm:$global) ]>; 1984234285Sdim 1985249423Sdim// Map BlockAddress lowering to CONST32_Int_Real 1986249423Sdimdef : Pat<(HexagonCONST32_GP tblockaddress:$addr), 1987249423Sdim (CONST32_Int_Real tblockaddress:$addr)>; 1988249423Sdim 1989234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1990239462Sdimdef CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), 1991234285Sdim "$dst = CONST32($label)", 1992239462Sdim [(set (i32 IntRegs:$dst), (HexagonCONST32 bbl:$label))]>; 1993234285Sdim 1994234285Sdimlet isReMaterializable = 1, isMoveImm = 1 in 1995239462Sdimdef CONST64_Int_Real : LDInst2<(outs DoubleRegs:$dst), (ins i64imm:$global), 1996234285Sdim "$dst = CONST64(#$global)", 1997239462Sdim [(set (i64 DoubleRegs:$dst), imm:$global) ]>; 1998234285Sdim 1999234285Sdimdef TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins), 2000234285Sdim "$dst = xor($dst, $dst)", 2001239462Sdim [(set (i1 PredRegs:$dst), 0)]>; 2002234285Sdim 2003234285Sdimdef MPY_trsext : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 2004239462Sdim "$dst = mpy($src1, $src2)", 2005239462Sdim [(set (i32 IntRegs:$dst), 2006239462Sdim (trunc (i64 (srl (i64 (mul (i64 (sext (i32 IntRegs:$src1))), 2007239462Sdim (i64 (sext (i32 IntRegs:$src2))))), 2008239462Sdim (i32 32)))))]>; 2009234285Sdim 2010234285Sdim// Pseudo instructions. 2011234285Sdimdef SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 2012234285Sdim 2013234285Sdimdef SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 2014234285Sdim SDTCisVT<1, i32> ]>; 2015234285Sdim 2016234285Sdimdef callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 2017234285Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 2018234285Sdim 2019234285Sdimdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 2020234285Sdim [SDNPHasChain, SDNPOutGlue]>; 2021234285Sdim 2022234285Sdimdef SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 2023234285Sdim 2024234285Sdimdef call : SDNode<"HexagonISD::CALL", SDT_SPCall, 2025234285Sdim [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; 2026234285Sdim 2027234285Sdim// For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain, 2028234285Sdim// Optional Flag and Variable Arguments. 2029234285Sdim// Its 1 Operand has pointer type. 2030234285Sdimdef HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall, 2031234285Sdim [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 2032234285Sdim 2033234285Sdimlet Defs = [R29, R30], Uses = [R31, R30, R29] in { 2034234285Sdim def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 2035234285Sdim "Should never be emitted", 2036234285Sdim [(callseq_start timm:$amt)]>; 2037234285Sdim} 2038234285Sdim 2039234285Sdimlet Defs = [R29, R30, R31], Uses = [R29] in { 2040234285Sdim def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 2041234285Sdim "Should never be emitted", 2042234285Sdim [(callseq_end timm:$amt1, timm:$amt2)]>; 2043234285Sdim} 2044234285Sdim// Call subroutine. 2045234285Sdimlet isCall = 1, neverHasSideEffects = 1, 2046234285Sdim Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, 2047234285Sdim R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in { 2048239462Sdim def CALL : JInst<(outs), (ins calltarget:$dst), 2049234285Sdim "call $dst", []>; 2050234285Sdim} 2051234285Sdim 2052234285Sdim// Call subroutine from register. 2053234285Sdimlet isCall = 1, neverHasSideEffects = 1, 2054234285Sdim Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, 2055234285Sdim R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in { 2056239462Sdim def CALLR : JRInst<(outs), (ins IntRegs:$dst), 2057234285Sdim "callr $dst", 2058234285Sdim []>; 2059234285Sdim } 2060234285Sdim 2061251662Sdim 2062251662Sdim// Indirect tail-call. 2063251662Sdimlet isCodeGenOnly = 1, isCall = 1, isReturn = 1 in 2064251662Sdimdef TCRETURNR : T_JMPr; 2065251662Sdim 2066251662Sdim// Direct tail-calls. 2067251662Sdimlet isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0, 2068251662SdimisTerminator = 1, isCodeGenOnly = 1 in { 2069251662Sdim def TCRETURNtg : T_JMP<(ins calltarget:$dst)>; 2070251662Sdim def TCRETURNtext : T_JMP<(ins calltarget:$dst)>; 2071234285Sdim} 2072234285Sdim 2073234285Sdim// Map call instruction. 2074239462Sdimdef : Pat<(call (i32 IntRegs:$dst)), 2075239462Sdim (CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>; 2076234285Sdimdef : Pat<(call tglobaladdr:$dst), 2077234285Sdim (CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>; 2078234285Sdimdef : Pat<(call texternalsym:$dst), 2079234285Sdim (CALL texternalsym:$dst)>, Requires<[HasV2TOnly]>; 2080234285Sdim//Tail calls. 2081234285Sdimdef : Pat<(HexagonTCRet tglobaladdr:$dst), 2082234285Sdim (TCRETURNtg tglobaladdr:$dst)>; 2083234285Sdimdef : Pat<(HexagonTCRet texternalsym:$dst), 2084234285Sdim (TCRETURNtext texternalsym:$dst)>; 2085239462Sdimdef : Pat<(HexagonTCRet (i32 IntRegs:$dst)), 2086239462Sdim (TCRETURNR (i32 IntRegs:$dst))>; 2087234285Sdim 2088239462Sdim// Atomic load and store support 2089239462Sdim// 8 bit atomic load 2090239462Sdimdef : Pat<(atomic_load_8 ADDRriS11_0:$src1), 2091239462Sdim (i32 (LDriub ADDRriS11_0:$src1))>; 2092239462Sdim 2093239462Sdimdef : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)), 2094239462Sdim (i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>; 2095239462Sdim 2096239462Sdim// 16 bit atomic load 2097239462Sdimdef : Pat<(atomic_load_16 ADDRriS11_1:$src1), 2098239462Sdim (i32 (LDriuh ADDRriS11_1:$src1))>; 2099239462Sdim 2100239462Sdimdef : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)), 2101239462Sdim (i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>; 2102239462Sdim 2103239462Sdimdef : Pat<(atomic_load_32 ADDRriS11_2:$src1), 2104239462Sdim (i32 (LDriw ADDRriS11_2:$src1))>; 2105239462Sdim 2106239462Sdimdef : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)), 2107239462Sdim (i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>; 2108239462Sdim 2109239462Sdim// 64 bit atomic load 2110239462Sdimdef : Pat<(atomic_load_64 ADDRriS11_3:$src1), 2111239462Sdim (i64 (LDrid ADDRriS11_3:$src1))>; 2112239462Sdim 2113239462Sdimdef : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)), 2114239462Sdim (i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>; 2115239462Sdim 2116239462Sdim 2117239462Sdimdef : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)), 2118239462Sdim (STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>; 2119239462Sdim 2120239462Sdimdef : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset), 2121239462Sdim (i32 IntRegs:$src1)), 2122239462Sdim (STrib_indexed (i32 IntRegs:$src2), s11_0ImmPred:$offset, 2123239462Sdim (i32 IntRegs:$src1))>; 2124239462Sdim 2125239462Sdim 2126239462Sdimdef : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)), 2127239462Sdim (STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>; 2128239462Sdim 2129239462Sdimdef : Pat<(atomic_store_16 (i32 IntRegs:$src1), 2130239462Sdim (add (i32 IntRegs:$src2), s11_1ImmPred:$offset)), 2131239462Sdim (STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset, 2132239462Sdim (i32 IntRegs:$src1))>; 2133239462Sdim 2134239462Sdimdef : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)), 2135239462Sdim (STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>; 2136239462Sdim 2137239462Sdimdef : Pat<(atomic_store_32 (add (i32 IntRegs:$src2), s11_2ImmPred:$offset), 2138239462Sdim (i32 IntRegs:$src1)), 2139239462Sdim (STriw_indexed (i32 IntRegs:$src2), s11_2ImmPred:$offset, 2140239462Sdim (i32 IntRegs:$src1))>; 2141239462Sdim 2142239462Sdim 2143239462Sdim 2144239462Sdim 2145239462Sdimdef : Pat<(atomic_store_64 ADDRriS11_3:$src2, (i64 DoubleRegs:$src1)), 2146239462Sdim (STrid ADDRriS11_3:$src2, (i64 DoubleRegs:$src1))>; 2147239462Sdim 2148239462Sdimdef : Pat<(atomic_store_64 (add (i32 IntRegs:$src2), s11_3ImmPred:$offset), 2149239462Sdim (i64 DoubleRegs:$src1)), 2150239462Sdim (STrid_indexed (i32 IntRegs:$src2), s11_3ImmPred:$offset, 2151239462Sdim (i64 DoubleRegs:$src1))>; 2152239462Sdim 2153239462Sdim// Map from r0 = and(r1, 65535) to r0 = zxth(r1) 2154239462Sdimdef : Pat <(and (i32 IntRegs:$src1), 65535), 2155239462Sdim (ZXTH (i32 IntRegs:$src1))>; 2156239462Sdim 2157234285Sdim// Map from r0 = and(r1, 255) to r0 = zxtb(r1). 2158239462Sdimdef : Pat <(and (i32 IntRegs:$src1), 255), 2159239462Sdim (ZXTB (i32 IntRegs:$src1))>; 2160234285Sdim 2161234285Sdim// Map Add(p1, true) to p1 = not(p1). 2162234285Sdim// Add(p1, false) should never be produced, 2163234285Sdim// if it does, it got to be mapped to NOOP. 2164239462Sdimdef : Pat <(add (i1 PredRegs:$src1), -1), 2165239462Sdim (NOT_p (i1 PredRegs:$src1))>; 2166234285Sdim 2167234285Sdim// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) => 2168234285Sdim// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1). 2169251662Sdim// cmp.lt(r0, r1) -> cmp.gt(r1, r0) 2170239462Sdimdef : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2171239462Sdim (i32 IntRegs:$src3), 2172239462Sdim (i32 IntRegs:$src4)), 2173251662Sdim (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), 2174239462Sdim (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>, 2175239462Sdim Requires<[HasV2TOnly]>; 2176234285Sdim 2177234285Sdim// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i). 2178239462Sdimdef : Pat <(select (not (i1 PredRegs:$src1)), s8ImmPred:$src2, s8ImmPred:$src3), 2179239462Sdim (i32 (TFR_condset_ii (i1 PredRegs:$src1), s8ImmPred:$src3, 2180239462Sdim s8ImmPred:$src2))>; 2181234285Sdim 2182239462Sdim// Map from p0 = pnot(p0); r0 = select(p0, #i, r1) 2183239462Sdim// => r0 = TFR_condset_ri(p0, r1, #i) 2184239462Sdimdef : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2, 2185239462Sdim (i32 IntRegs:$src3)), 2186239462Sdim (i32 (TFR_condset_ri (i1 PredRegs:$src1), (i32 IntRegs:$src3), 2187239462Sdim s12ImmPred:$src2))>; 2188239462Sdim 2189239462Sdim// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) 2190239462Sdim// => r0 = TFR_condset_ir(p0, #i, r1) 2191251662Sdimdef : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3), 2192239462Sdim (i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3, 2193239462Sdim (i32 IntRegs:$src2)))>; 2194239462Sdim 2195234285Sdim// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. 2196251662Sdimdef : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset), 2197251662Sdim (JMP_f (i1 PredRegs:$src1), bb:$offset)>; 2198234285Sdim 2199234285Sdim// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2). 2200251662Sdimdef : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))), 2201239462Sdim (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>; 2202234285Sdim 2203251662Sdim 2204251662Sdimlet AddedComplexity = 100 in 2205251662Sdimdef : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))), 2206251662Sdim (i64 (COMBINE_rr (TFRI 0), 2207251662Sdim (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>, 2208251662Sdim Requires<[NoV4T]>; 2209251662Sdim 2210234285Sdim// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned. 2211249423Sdimlet AddedComplexity = 10 in 2212234285Sdimdef : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)), 2213239462Sdim (i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>; 2214234285Sdim 2215234285Sdim// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo). 2216239462Sdimdef : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)), 2217239462Sdim (i64 (SXTW (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>; 2218234285Sdim 2219234285Sdim// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = SXTW(SXTH(Rss.lo)). 2220239462Sdimdef : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i16)), 2221239462Sdim (i64 (SXTW (i32 (SXTH (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2222239462Sdim subreg_loreg))))))>; 2223234285Sdim 2224234285Sdim// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = SXTW(SXTB(Rss.lo)). 2225239462Sdimdef : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)), 2226239462Sdim (i64 (SXTW (i32 (SXTB (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2227239462Sdim subreg_loreg))))))>; 2228234285Sdim 2229239462Sdim// We want to prevent emitting pnot's as much as possible. 2230251662Sdim// Map brcond with an unsupported setcc to a JMP_f. 2231239462Sdimdef : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2232239462Sdim bb:$offset), 2233251662Sdim (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), 2234239462Sdim bb:$offset)>; 2235234285Sdim 2236239462Sdimdef : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)), 2237239462Sdim bb:$offset), 2238251662Sdim (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>; 2239234285Sdim 2240239462Sdimdef : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset), 2241251662Sdim (JMP_f (i1 PredRegs:$src1), bb:$offset)>; 2242234285Sdim 2243239462Sdimdef : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset), 2244251662Sdim (JMP_t (i1 PredRegs:$src1), bb:$offset)>; 2245234285Sdim 2246251662Sdim// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1) 2247239462Sdimdef : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)), 2248239462Sdim bb:$offset), 2249251662Sdim (JMP_f (CMPGTri (i32 IntRegs:$src1), 2250251662Sdim (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>; 2251234285Sdim 2252251662Sdim// cmp.lt(r0, r1) -> cmp.gt(r1, r0) 2253239462Sdimdef : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2254239462Sdim bb:$offset), 2255251662Sdim (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>; 2256234285Sdim 2257239462Sdimdef : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2258234285Sdim bb:$offset), 2259251662Sdim (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)), 2260234285Sdim bb:$offset)>; 2261234285Sdim 2262239462Sdimdef : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2263239462Sdim bb:$offset), 2264251662Sdim (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), 2265239462Sdim bb:$offset)>; 2266234285Sdim 2267239462Sdimdef : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2268234285Sdim bb:$offset), 2269251662Sdim (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2270239462Sdim bb:$offset)>; 2271234285Sdim 2272234285Sdim// Map from a 64-bit select to an emulated 64-bit mux. 2273234285Sdim// Hexagon does not support 64-bit MUXes; so emulate with combines. 2274239462Sdimdef : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2), 2275239462Sdim (i64 DoubleRegs:$src3)), 2276239462Sdim (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1), 2277239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2278239462Sdim subreg_hireg)), 2279239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), 2280239462Sdim subreg_hireg)))), 2281239462Sdim (i32 (MUX_rr (i1 PredRegs:$src1), 2282239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2283239462Sdim subreg_loreg)), 2284239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), 2285239462Sdim subreg_loreg))))))>; 2286234285Sdim 2287234285Sdim// Map from a 1-bit select to logical ops. 2288234285Sdim// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3). 2289239462Sdimdef : Pat <(select (i1 PredRegs:$src1), (i1 PredRegs:$src2), 2290239462Sdim (i1 PredRegs:$src3)), 2291239462Sdim (OR_pp (AND_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)), 2292239462Sdim (AND_pp (NOT_p (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>; 2293234285Sdim 2294234285Sdim// Map Pd = load(addr) -> Rs = load(addr); Pd = Rs. 2295234285Sdimdef : Pat<(i1 (load ADDRriS11_2:$addr)), 2296234285Sdim (i1 (TFR_PdRs (i32 (LDrib ADDRriS11_2:$addr))))>; 2297234285Sdim 2298234285Sdim// Map for truncating from 64 immediates to 32 bit immediates. 2299239462Sdimdef : Pat<(i32 (trunc (i64 DoubleRegs:$src))), 2300239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), subreg_loreg))>; 2301234285Sdim 2302234285Sdim// Map for truncating from i64 immediates to i1 bit immediates. 2303239462Sdimdef : Pat<(i1 (trunc (i64 DoubleRegs:$src))), 2304239462Sdim (i1 (TFR_PdRs (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2305239462Sdim subreg_loreg))))>; 2306234285Sdim 2307234285Sdim// Map memb(Rs) = Rdd -> memb(Rs) = Rt. 2308239462Sdimdef : Pat<(truncstorei8 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2309239462Sdim (STrib ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2310234285Sdim subreg_loreg)))>; 2311234285Sdim 2312234285Sdim// Map memh(Rs) = Rdd -> memh(Rs) = Rt. 2313239462Sdimdef : Pat<(truncstorei16 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2314239462Sdim (STrih ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2315234285Sdim subreg_loreg)))>; 2316239462Sdim// Map memw(Rs) = Rdd -> memw(Rs) = Rt 2317239462Sdimdef : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2318239462Sdim (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2319239462Sdim subreg_loreg)))>; 2320234285Sdim 2321234285Sdim// Map memw(Rs) = Rdd -> memw(Rs) = Rt. 2322239462Sdimdef : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2323239462Sdim (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2324234285Sdim subreg_loreg)))>; 2325234285Sdim 2326234285Sdim// Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0. 2327234285Sdimdef : Pat<(store (i1 -1), ADDRriS11_2:$addr), 2328234285Sdim (STrib ADDRriS11_2:$addr, (TFRI 1))>; 2329234285Sdim 2330234285Sdim 2331234285Sdim// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0. 2332234285Sdimdef : Pat<(store (i1 -1), ADDRriS11_2:$addr), 2333234285Sdim (STrib ADDRriS11_2:$addr, (TFRI 1))>; 2334234285Sdim 2335234285Sdim// Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt. 2336239462Sdimdef : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr), 2337239462Sdim (STrib ADDRriS11_2:$addr, (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0)) )>; 2338234285Sdim 2339234285Sdim// Map Rdd = anyext(Rs) -> Rdd = sxtw(Rs). 2340234285Sdim// Hexagon_TODO: We can probably use combine but that will cost 2 instructions. 2341234285Sdim// Better way to do this? 2342239462Sdimdef : Pat<(i64 (anyext (i32 IntRegs:$src1))), 2343239462Sdim (i64 (SXTW (i32 IntRegs:$src1)))>; 2344234285Sdim 2345234285Sdim// Map cmple -> cmpgt. 2346234285Sdim// rs <= rt -> !(rs > rt). 2347251662Sdimdef : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)), 2348251662Sdim (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>; 2349234285Sdim 2350234285Sdim// rs <= rt -> !(rs > rt). 2351239462Sdimdef : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2352239462Sdim (i1 (NOT_p (CMPGTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>; 2353234285Sdim 2354234285Sdim// Rss <= Rtt -> !(Rss > Rtt). 2355239462Sdimdef : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2356239462Sdim (i1 (NOT_p (CMPGT64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>; 2357234285Sdim 2358234285Sdim// Map cmpne -> cmpeq. 2359234285Sdim// Hexagon_TODO: We should improve on this. 2360234285Sdim// rs != rt -> !(rs == rt). 2361251662Sdimdef : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)), 2362251662Sdim (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>; 2363234285Sdim 2364234285Sdim// Map cmpne(Rs) -> !cmpeqe(Rs). 2365234285Sdim// rs != rt -> !(rs == rt). 2366239462Sdimdef : Pat <(i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2367239462Sdim (i1 (NOT_p (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>; 2368234285Sdim 2369234285Sdim// Convert setne back to xor for hexagon since we compute w/ pred registers. 2370239462Sdimdef : Pat <(i1 (setne (i1 PredRegs:$src1), (i1 PredRegs:$src2))), 2371239462Sdim (i1 (XOR_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>; 2372234285Sdim 2373234285Sdim// Map cmpne(Rss) -> !cmpew(Rss). 2374234285Sdim// rs != rt -> !(rs == rt). 2375239462Sdimdef : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2376239462Sdim (i1 (NOT_p (i1 (CMPEHexagon4rr (i64 DoubleRegs:$src1), 2377239462Sdim (i64 DoubleRegs:$src2)))))>; 2378234285Sdim 2379234285Sdim// Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt). 2380234285Sdim// rs >= rt -> !(rt > rs). 2381239462Sdimdef : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2382239462Sdim (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>; 2383234285Sdim 2384251662Sdim// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1) 2385251662Sdimdef : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)), 2386251662Sdim (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>; 2387234285Sdim 2388234285Sdim// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). 2389234285Sdim// rss >= rtt -> !(rtt > rss). 2390239462Sdimdef : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2391239462Sdim (i1 (NOT_p (i1 (CMPGT64rr (i64 DoubleRegs:$src2), 2392239462Sdim (i64 DoubleRegs:$src1)))))>; 2393234285Sdim 2394234285Sdim// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm). 2395251662Sdim// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1). 2396234285Sdim// rs < rt -> !(rs >= rt). 2397251662Sdimdef : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)), 2398251662Sdim (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>; 2399234285Sdim 2400239462Sdim// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs). 2401239462Sdim// rs < rt -> rt > rs. 2402239462Sdim// We can let assembler map it, or we can do in the compiler itself. 2403239462Sdimdef : Pat <(i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2404239462Sdim (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>; 2405234285Sdim 2406234285Sdim// Map cmplt(Rss, Rtt) -> cmpgt(Rtt, Rss). 2407234285Sdim// rss < rtt -> (rtt > rss). 2408239462Sdimdef : Pat <(i1 (setlt (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2409239462Sdim (i1 (CMPGT64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>; 2410234285Sdim 2411239462Sdim// Map from cmpltu(Rs, Rd) -> cmpgtu(Rd, Rs) 2412234285Sdim// rs < rt -> rt > rs. 2413239462Sdim// We can let assembler map it, or we can do in the compiler itself. 2414239462Sdimdef : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2415239462Sdim (i1 (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>; 2416234285Sdim 2417239462Sdim// Map from cmpltu(Rss, Rdd) -> cmpgtu(Rdd, Rss). 2418234285Sdim// rs < rt -> rt > rs. 2419239462Sdimdef : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2420239462Sdim (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>; 2421234285Sdim 2422251662Sdim// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs) 2423251662Sdimdef : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)), 2424251662Sdim (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>; 2425239462Sdim 2426251662Sdim// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1) 2427251662Sdimdef : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)), 2428251662Sdim (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>; 2429251662Sdim 2430239462Sdim// Generate cmpgtu(Rs, #u9) 2431251662Sdimdef : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)), 2432251662Sdim (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>; 2433239462Sdim 2434234285Sdim// Map from Rs >= Rt -> !(Rt > Rs). 2435234285Sdim// rs >= rt -> !(rt > rs). 2436239462Sdimdef : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2437239462Sdim (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>; 2438234285Sdim 2439234285Sdim// Map from Rs >= Rt -> !(Rt > Rs). 2440234285Sdim// rs >= rt -> !(rt > rs). 2441239462Sdimdef : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2442239462Sdim (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>; 2443234285Sdim 2444251662Sdim// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt). 2445234285Sdim// Map from (Rs <= Rt) -> !(Rs > Rt). 2446239462Sdimdef : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2447239462Sdim (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>; 2448234285Sdim 2449234285Sdim// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1). 2450234285Sdim// Map from (Rs <= Rt) -> !(Rs > Rt). 2451239462Sdimdef : Pat <(i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2452239462Sdim (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>; 2453234285Sdim 2454234285Sdim// Sign extends. 2455234285Sdim// i1 -> i32 2456239462Sdimdef : Pat <(i32 (sext (i1 PredRegs:$src1))), 2457239462Sdim (i32 (MUX_ii (i1 PredRegs:$src1), -1, 0))>; 2458234285Sdim 2459239462Sdim// i1 -> i64 2460239462Sdimdef : Pat <(i64 (sext (i1 PredRegs:$src1))), 2461239462Sdim (i64 (COMBINE_rr (TFRI -1), (MUX_ii (i1 PredRegs:$src1), -1, 0)))>; 2462239462Sdim 2463234285Sdim// Convert sign-extended load back to load and sign extend. 2464234285Sdim// i8 -> i64 2465234285Sdimdef: Pat <(i64 (sextloadi8 ADDRriS11_0:$src1)), 2466234285Sdim (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>; 2467234285Sdim 2468234285Sdim// Convert any-extended load back to load and sign extend. 2469234285Sdim// i8 -> i64 2470234285Sdimdef: Pat <(i64 (extloadi8 ADDRriS11_0:$src1)), 2471234285Sdim (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>; 2472234285Sdim 2473234285Sdim// Convert sign-extended load back to load and sign extend. 2474234285Sdim// i16 -> i64 2475234285Sdimdef: Pat <(i64 (sextloadi16 ADDRriS11_1:$src1)), 2476234285Sdim (i64 (SXTW (LDrih ADDRriS11_1:$src1)))>; 2477234285Sdim 2478234285Sdim// Convert sign-extended load back to load and sign extend. 2479234285Sdim// i32 -> i64 2480234285Sdimdef: Pat <(i64 (sextloadi32 ADDRriS11_2:$src1)), 2481234285Sdim (i64 (SXTW (LDriw ADDRriS11_2:$src1)))>; 2482234285Sdim 2483234285Sdim 2484234285Sdim// Zero extends. 2485234285Sdim// i1 -> i32 2486239462Sdimdef : Pat <(i32 (zext (i1 PredRegs:$src1))), 2487239462Sdim (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2488234285Sdim 2489234285Sdim// i1 -> i64 2490239462Sdimdef : Pat <(i64 (zext (i1 PredRegs:$src1))), 2491249423Sdim (i64 (COMBINE_rr (TFRI 0), (MUX_ii (i1 PredRegs:$src1), 1, 0)))>, 2492249423Sdim Requires<[NoV4T]>; 2493234285Sdim 2494234285Sdim// i32 -> i64 2495239462Sdimdef : Pat <(i64 (zext (i32 IntRegs:$src1))), 2496249423Sdim (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>, 2497249423Sdim Requires<[NoV4T]>; 2498234285Sdim 2499234285Sdim// i8 -> i64 2500234285Sdimdef: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)), 2501249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>, 2502249423Sdim Requires<[NoV4T]>; 2503234285Sdim 2504249423Sdimlet AddedComplexity = 20 in 2505249423Sdimdef: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1), 2506249423Sdim s11_0ExtPred:$offset))), 2507249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1, 2508249423Sdim s11_0ExtPred:$offset)))>, 2509249423Sdim Requires<[NoV4T]>; 2510249423Sdim 2511249423Sdim// i1 -> i64 2512249423Sdimdef: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)), 2513249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>, 2514249423Sdim Requires<[NoV4T]>; 2515249423Sdim 2516249423Sdimlet AddedComplexity = 20 in 2517249423Sdimdef: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1), 2518249423Sdim s11_0ExtPred:$offset))), 2519249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1, 2520249423Sdim s11_0ExtPred:$offset)))>, 2521249423Sdim Requires<[NoV4T]>; 2522249423Sdim 2523234285Sdim// i16 -> i64 2524234285Sdimdef: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)), 2525249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>, 2526249423Sdim Requires<[NoV4T]>; 2527234285Sdim 2528249423Sdimlet AddedComplexity = 20 in 2529249423Sdimdef: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1), 2530249423Sdim s11_1ExtPred:$offset))), 2531249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriuh_indexed IntRegs:$src1, 2532249423Sdim s11_1ExtPred:$offset)))>, 2533249423Sdim Requires<[NoV4T]>; 2534249423Sdim 2535234285Sdim// i32 -> i64 2536234285Sdimdef: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)), 2537249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>, 2538249423Sdim Requires<[NoV4T]>; 2539234285Sdim 2540251662Sdimlet AddedComplexity = 100 in 2541251662Sdimdef: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 2542251662Sdim (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1, 2543251662Sdim s11_2ExtPred:$offset)))>, 2544251662Sdim Requires<[NoV4T]>; 2545251662Sdim 2546251662Sdimlet AddedComplexity = 10 in 2547234285Sdimdef: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)), 2548234285Sdim (i32 (LDriw ADDRriS11_0:$src1))>; 2549234285Sdim 2550234285Sdim// Map from Rs = Pd to Pd = mux(Pd, #1, #0) 2551239462Sdimdef : Pat <(i32 (zext (i1 PredRegs:$src1))), 2552239462Sdim (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2553234285Sdim 2554234285Sdim// Map from Rs = Pd to Pd = mux(Pd, #1, #0) 2555239462Sdimdef : Pat <(i32 (anyext (i1 PredRegs:$src1))), 2556239462Sdim (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2557234285Sdim 2558234285Sdim// Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0)) 2559239462Sdimdef : Pat <(i64 (anyext (i1 PredRegs:$src1))), 2560239462Sdim (i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>; 2561234285Sdim 2562234285Sdim 2563251662Sdimlet AddedComplexity = 100 in 2564251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2565251662Sdim (i32 32))), 2566251662Sdim (i64 (zextloadi32 (i32 (add IntRegs:$src2, 2567251662Sdim s11_2ExtPred:$offset2)))))), 2568251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2569251662Sdim (LDriw_indexed IntRegs:$src2, 2570251662Sdim s11_2ExtPred:$offset2)))>; 2571251662Sdim 2572251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2573251662Sdim (i32 32))), 2574251662Sdim (i64 (zextloadi32 ADDRriS11_2:$srcLow)))), 2575251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2576251662Sdim (LDriw ADDRriS11_2:$srcLow)))>; 2577251662Sdim 2578251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2579251662Sdim (i32 32))), 2580251662Sdim (i64 (zext (i32 IntRegs:$srcLow))))), 2581251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2582251662Sdim IntRegs:$srcLow))>; 2583251662Sdim 2584251662Sdimlet AddedComplexity = 100 in 2585251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2586251662Sdim (i32 32))), 2587251662Sdim (i64 (zextloadi32 (i32 (add IntRegs:$src2, 2588251662Sdim s11_2ExtPred:$offset2)))))), 2589251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2590251662Sdim (LDriw_indexed IntRegs:$src2, 2591251662Sdim s11_2ExtPred:$offset2)))>; 2592251662Sdim 2593251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2594251662Sdim (i32 32))), 2595251662Sdim (i64 (zextloadi32 ADDRriS11_2:$srcLow)))), 2596251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2597251662Sdim (LDriw ADDRriS11_2:$srcLow)))>; 2598251662Sdim 2599251662Sdimdef: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2600251662Sdim (i32 32))), 2601251662Sdim (i64 (zext (i32 IntRegs:$srcLow))))), 2602251662Sdim (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2603251662Sdim IntRegs:$srcLow))>; 2604251662Sdim 2605234285Sdim// Any extended 64-bit load. 2606234285Sdim// anyext i32 -> i64 2607234285Sdimdef: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)), 2608249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>, 2609249423Sdim Requires<[NoV4T]>; 2610234285Sdim 2611249423Sdim// When there is an offset we should prefer the pattern below over the pattern above. 2612249423Sdim// The complexity of the above is 13 (gleaned from HexagonGenDAGIsel.inc) 2613249423Sdim// So this complexity below is comfortably higher to allow for choosing the below. 2614249423Sdim// If this is not done then we generate addresses such as 2615249423Sdim// ******************************************** 2616249423Sdim// r1 = add (r0, #4) 2617249423Sdim// r1 = memw(r1 + #0) 2618249423Sdim// instead of 2619249423Sdim// r1 = memw(r0 + #4) 2620249423Sdim// ******************************************** 2621249423Sdimlet AddedComplexity = 100 in 2622249423Sdimdef: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 2623249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1, 2624249423Sdim s11_2ExtPred:$offset)))>, 2625249423Sdim Requires<[NoV4T]>; 2626249423Sdim 2627234285Sdim// anyext i16 -> i64. 2628234285Sdimdef: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)), 2629249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDrih ADDRriS11_2:$src1)))>, 2630249423Sdim Requires<[NoV4T]>; 2631234285Sdim 2632249423Sdimlet AddedComplexity = 20 in 2633249423Sdimdef: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1), 2634249423Sdim s11_1ExtPred:$offset))), 2635249423Sdim (i64 (COMBINE_rr (TFRI 0), (LDrih_indexed IntRegs:$src1, 2636249423Sdim s11_1ExtPred:$offset)))>, 2637249423Sdim Requires<[NoV4T]>; 2638249423Sdim 2639234285Sdim// Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs). 2640239462Sdimdef : Pat<(i64 (zext (i32 IntRegs:$src1))), 2641249423Sdim (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>, 2642249423Sdim Requires<[NoV4T]>; 2643234285Sdim 2644234285Sdim// Multiply 64-bit unsigned and use upper result. 2645239462Sdimdef : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2646239462Sdim (i64 2647239462Sdim (MPYU64_acc 2648239462Sdim (i64 2649239462Sdim (COMBINE_rr 2650239462Sdim (TFRI 0), 2651239462Sdim (i32 2652239462Sdim (EXTRACT_SUBREG 2653239462Sdim (i64 2654239462Sdim (LSRd_ri 2655239462Sdim (i64 2656239462Sdim (MPYU64_acc 2657239462Sdim (i64 2658239462Sdim (MPYU64_acc 2659239462Sdim (i64 2660239462Sdim (COMBINE_rr (TFRI 0), 2661239462Sdim (i32 2662239462Sdim (EXTRACT_SUBREG 2663239462Sdim (i64 2664239462Sdim (LSRd_ri 2665239462Sdim (i64 2666239462Sdim (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2667239462Sdim subreg_loreg)), 2668239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2669239462Sdim subreg_loreg)))), 32)), 2670239462Sdim subreg_loreg)))), 2671239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2672239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))), 2673239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)), 2674239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))), 2675239462Sdim 32)), subreg_loreg)))), 2676239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2677239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>; 2678234285Sdim 2679234285Sdim// Multiply 64-bit signed and use upper result. 2680239462Sdimdef : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2681239462Sdim (i64 2682239462Sdim (MPY64_acc 2683239462Sdim (i64 2684239462Sdim (COMBINE_rr (TFRI 0), 2685239462Sdim (i32 2686239462Sdim (EXTRACT_SUBREG 2687239462Sdim (i64 2688239462Sdim (LSRd_ri 2689239462Sdim (i64 2690239462Sdim (MPY64_acc 2691239462Sdim (i64 2692239462Sdim (MPY64_acc 2693239462Sdim (i64 2694239462Sdim (COMBINE_rr (TFRI 0), 2695239462Sdim (i32 2696239462Sdim (EXTRACT_SUBREG 2697239462Sdim (i64 2698239462Sdim (LSRd_ri 2699239462Sdim (i64 2700239462Sdim (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2701239462Sdim subreg_loreg)), 2702239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2703239462Sdim subreg_loreg)))), 32)), 2704239462Sdim subreg_loreg)))), 2705239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2706239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))), 2707239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)), 2708239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))), 2709239462Sdim 32)), subreg_loreg)))), 2710239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2711239462Sdim (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>; 2712234285Sdim 2713234285Sdim// Hexagon specific ISD nodes. 2714239462Sdim//def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>]>; 2715239462Sdimdef SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, 2716239462Sdim [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 2717234285Sdimdef Hexagon_ADJDYNALLOC : SDNode<"HexagonISD::ADJDYNALLOC", 2718239462Sdim SDTHexagonADJDYNALLOC>; 2719234285Sdim// Needed to tag these instructions for stack layout. 2720234285Sdimlet usesCustomInserter = 1 in 2721234285Sdimdef ADJDYNALLOC : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1, 2722234285Sdim s16Imm:$src2), 2723234285Sdim "$dst = add($src1, #$src2)", 2724239462Sdim [(set (i32 IntRegs:$dst), 2725239462Sdim (Hexagon_ADJDYNALLOC (i32 IntRegs:$src1), 2726239462Sdim s16ImmPred:$src2))]>; 2727234285Sdim 2728239462Sdimdef SDTHexagonARGEXTEND : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>; 2729234285Sdimdef Hexagon_ARGEXTEND : SDNode<"HexagonISD::ARGEXTEND", SDTHexagonARGEXTEND>; 2730234285Sdimdef ARGEXTEND : ALU32_rr <(outs IntRegs:$dst), (ins IntRegs:$src1), 2731234285Sdim "$dst = $src1", 2732239462Sdim [(set (i32 IntRegs:$dst), 2733239462Sdim (Hexagon_ARGEXTEND (i32 IntRegs:$src1)))]>; 2734234285Sdim 2735234285Sdimlet AddedComplexity = 100 in 2736239462Sdimdef : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)), 2737239462Sdim (COPY (i32 IntRegs:$src1))>; 2738234285Sdim 2739234285Sdimdef HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>; 2740234285Sdim 2741234285Sdimdef : Pat<(HexagonWrapperJT tjumptable:$dst), 2742239462Sdim (i32 (CONST32_set_jt tjumptable:$dst))>; 2743234285Sdim 2744239462Sdim// XTYPE/SHIFT 2745234285Sdim 2746239462Sdim// Multi-class for logical operators : 2747239462Sdim// Shift by immediate/register and accumulate/logical 2748239462Sdimmulticlass xtype_imm<string OpcStr, SDNode OpNode1, SDNode OpNode2> { 2749239462Sdim def _ri : SInst_acc<(outs IntRegs:$dst), 2750239462Sdim (ins IntRegs:$src1, IntRegs:$src2, u5Imm:$src3), 2751239462Sdim !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")), 2752239462Sdim [(set (i32 IntRegs:$dst), 2753239462Sdim (OpNode2 (i32 IntRegs:$src1), 2754239462Sdim (OpNode1 (i32 IntRegs:$src2), 2755239462Sdim u5ImmPred:$src3)))], 2756239462Sdim "$src1 = $dst">; 2757239462Sdim 2758239462Sdim def d_ri : SInst_acc<(outs DoubleRegs:$dst), 2759239462Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, u6Imm:$src3), 2760239462Sdim !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")), 2761239462Sdim [(set (i64 DoubleRegs:$dst), (OpNode2 (i64 DoubleRegs:$src1), 2762239462Sdim (OpNode1 (i64 DoubleRegs:$src2), u6ImmPred:$src3)))], 2763239462Sdim "$src1 = $dst">; 2764239462Sdim} 2765239462Sdim 2766239462Sdim// Multi-class for logical operators : 2767239462Sdim// Shift by register and accumulate/logical (32/64 bits) 2768239462Sdimmulticlass xtype_reg<string OpcStr, SDNode OpNode1, SDNode OpNode2> { 2769239462Sdim def _rr : SInst_acc<(outs IntRegs:$dst), 2770239462Sdim (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 2771239462Sdim !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")), 2772239462Sdim [(set (i32 IntRegs:$dst), 2773239462Sdim (OpNode2 (i32 IntRegs:$src1), 2774239462Sdim (OpNode1 (i32 IntRegs:$src2), 2775239462Sdim (i32 IntRegs:$src3))))], 2776239462Sdim "$src1 = $dst">; 2777239462Sdim 2778239462Sdim def d_rr : SInst_acc<(outs DoubleRegs:$dst), 2779239462Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 2780239462Sdim !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")), 2781239462Sdim [(set (i64 DoubleRegs:$dst), 2782239462Sdim (OpNode2 (i64 DoubleRegs:$src1), 2783239462Sdim (OpNode1 (i64 DoubleRegs:$src2), 2784239462Sdim (i32 IntRegs:$src3))))], 2785239462Sdim "$src1 = $dst">; 2786239462Sdim 2787239462Sdim} 2788239462Sdim 2789239462Sdimmulticlass basic_xtype_imm<string OpcStr, SDNode OpNode> { 2790239462Sdimlet AddedComplexity = 100 in 2791239462Sdim defm _ADD : xtype_imm< !strconcat("+= ", OpcStr), OpNode, add>; 2792239462Sdim defm _SUB : xtype_imm< !strconcat("-= ", OpcStr), OpNode, sub>; 2793239462Sdim defm _AND : xtype_imm< !strconcat("&= ", OpcStr), OpNode, and>; 2794239462Sdim defm _OR : xtype_imm< !strconcat("|= ", OpcStr), OpNode, or>; 2795239462Sdim} 2796239462Sdim 2797239462Sdimmulticlass basic_xtype_reg<string OpcStr, SDNode OpNode> { 2798239462Sdimlet AddedComplexity = 100 in 2799239462Sdim defm _ADD : xtype_reg< !strconcat("+= ", OpcStr), OpNode, add>; 2800239462Sdim defm _SUB : xtype_reg< !strconcat("-= ", OpcStr), OpNode, sub>; 2801239462Sdim defm _AND : xtype_reg< !strconcat("&= ", OpcStr), OpNode, and>; 2802239462Sdim defm _OR : xtype_reg< !strconcat("|= ", OpcStr), OpNode, or>; 2803239462Sdim} 2804239462Sdim 2805239462Sdimmulticlass xtype_xor_imm<string OpcStr, SDNode OpNode> { 2806239462Sdimlet AddedComplexity = 100 in 2807239462Sdim defm _XOR : xtype_imm< !strconcat("^= ", OpcStr), OpNode, xor>; 2808239462Sdim} 2809239462Sdim 2810239462Sdimdefm ASL : basic_xtype_imm<"asl", shl>, basic_xtype_reg<"asl", shl>, 2811239462Sdim xtype_xor_imm<"asl", shl>; 2812239462Sdim 2813239462Sdimdefm LSR : basic_xtype_imm<"lsr", srl>, basic_xtype_reg<"lsr", srl>, 2814239462Sdim xtype_xor_imm<"lsr", srl>; 2815239462Sdim 2816239462Sdimdefm ASR : basic_xtype_imm<"asr", sra>, basic_xtype_reg<"asr", sra>; 2817239462Sdimdefm LSL : basic_xtype_reg<"lsl", shl>; 2818239462Sdim 2819239462Sdim// Change the sign of the immediate for Rd=-mpyi(Rs,#u8) 2820239462Sdimdef : Pat <(mul (i32 IntRegs:$src1), (ineg n8ImmPred:$src2)), 2821239462Sdim (i32 (MPYI_rin (i32 IntRegs:$src1), u8ImmPred:$src2))>; 2822239462Sdim 2823234285Sdim//===----------------------------------------------------------------------===// 2824234285Sdim// V3 Instructions + 2825234285Sdim//===----------------------------------------------------------------------===// 2826234285Sdim 2827234285Sdiminclude "HexagonInstrInfoV3.td" 2828234285Sdim 2829234285Sdim//===----------------------------------------------------------------------===// 2830234285Sdim// V3 Instructions - 2831234285Sdim//===----------------------------------------------------------------------===// 2832234285Sdim 2833234285Sdim//===----------------------------------------------------------------------===// 2834234285Sdim// V4 Instructions + 2835234285Sdim//===----------------------------------------------------------------------===// 2836234285Sdim 2837234285Sdiminclude "HexagonInstrInfoV4.td" 2838239462Sdim 2839239462Sdim//===----------------------------------------------------------------------===// 2840239462Sdim// V4 Instructions - 2841239462Sdim//===----------------------------------------------------------------------===// 2842239462Sdim 2843239462Sdim//===----------------------------------------------------------------------===// 2844239462Sdim// V5 Instructions + 2845239462Sdim//===----------------------------------------------------------------------===// 2846239462Sdim 2847239462Sdiminclude "HexagonInstrInfoV5.td" 2848239462Sdim 2849239462Sdim//===----------------------------------------------------------------------===// 2850239462Sdim// V5 Instructions - 2851239462Sdim//===----------------------------------------------------------------------===// 2852