HexagonInstrInfo.td revision 252723
150397Sobrien//==- HexagonInstrInfo.td - Target Description for Hexagon -*- tablegen -*-===// 250397Sobrien// 350397Sobrien// The LLVM Compiler Infrastructure 450397Sobrien// 550397Sobrien// This file is distributed under the University of Illinois Open Source 650397Sobrien// License. See LICENSE.TXT for details. 750397Sobrien// 850397Sobrien//===----------------------------------------------------------------------===// 950397Sobrien// 1050397Sobrien// This file describes the Hexagon instructions in TableGen format. 1150397Sobrien// 1250397Sobrien//===----------------------------------------------------------------------===// 1350397Sobrien 1450397Sobrieninclude "HexagonInstrFormats.td" 1550397Sobrieninclude "HexagonOperands.td" 1650397Sobrien 1750397Sobrien//===----------------------------------------------------------------------===// 1850397Sobrien 1950397Sobrien// Multi-class for logical operators. 2050397Sobrienmulticlass ALU32_rr_ri<string OpcStr, SDNode OpNode> { 2150397Sobrien def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 2250397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 2350397Sobrien [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$b), 2450397Sobrien (i32 IntRegs:$c)))]>; 2550397Sobrien def ri : ALU32_ri<(outs IntRegs:$dst), (ins s10Imm:$b, IntRegs:$c), 2650397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "(#$b, $c)")), 2750397Sobrien [(set (i32 IntRegs:$dst), (OpNode s10Imm:$b, 2850397Sobrien (i32 IntRegs:$c)))]>; 2950397Sobrien} 3050397Sobrien 3150397Sobrien// Multi-class for compare ops. 3250397Sobrienlet isCompare = 1 in { 3350397Sobrienmulticlass CMP64_rr<string OpcStr, PatFrag OpNode> { 3450397Sobrien def rr : ALU64_rr<(outs PredRegs:$dst), (ins DoubleRegs:$b, DoubleRegs:$c), 3550397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 3650397Sobrien [(set (i1 PredRegs:$dst), 3750397Sobrien (OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>; 3850397Sobrien} 3950397Sobrien 4050397Sobrienmulticlass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> { 4150397Sobrien let CextOpcode = CextOp in { 4250397Sobrien let InputType = "reg" in 4350397Sobrien def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 4450397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 4550397Sobrien [(set (i1 PredRegs:$dst), 4650397Sobrien (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; 4750397Sobrien 4850397Sobrien let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, 4950397Sobrien opExtentBits = 10, InputType = "imm" in 5050397Sobrien def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s10Ext:$c), 5150397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 5250397Sobrien [(set (i1 PredRegs:$dst), 5350397Sobrien (OpNode (i32 IntRegs:$b), s10ExtPred:$c))]>; 5450397Sobrien } 5550397Sobrien} 5650397Sobrien 5750397Sobrienmulticlass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> { 5850397Sobrien let CextOpcode = CextOp in { 5950397Sobrien let InputType = "reg" in 6050397Sobrien def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c), 6150397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")), 6250397Sobrien [(set (i1 PredRegs:$dst), 6350397Sobrien (OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>; 6450397Sobrien 6550397Sobrien let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, 6650397Sobrien opExtentBits = 9, InputType = "imm" in 6750397Sobrien def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u9Ext:$c), 6850397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 6950397Sobrien [(set (i1 PredRegs:$dst), 7050397Sobrien (OpNode (i32 IntRegs:$b), u9ExtPred:$c))]>; 7150397Sobrien } 7250397Sobrien} 7350397Sobrien 7450397Sobrienmulticlass CMP32_ri_s8<string OpcStr, PatFrag OpNode> { 7550397Sobrienlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in 7650397Sobrien def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c), 7750397Sobrien !strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")), 7850397Sobrien [(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b), 7950397Sobrien s8ExtPred:$c))]>; 8050397Sobrien} 8150397Sobrien} 8250397Sobrien 8350397Sobrien//===----------------------------------------------------------------------===// 8450397Sobrien// ALU32/ALU (Instructions with register-register form) 8550397Sobrien//===----------------------------------------------------------------------===// 8650397Sobriendef SDTHexagonI64I32I32 : SDTypeProfile<1, 2, 8750397Sobrien [SDTCisVT<0, i64>, SDTCisVT<1, i32>, SDTCisSameAs<1, 2>]>; 8850397Sobrien 8950397Sobriendef HexagonWrapperCombineII : 9050397Sobrien SDNode<"HexagonISD::WrapperCombineII", SDTHexagonI64I32I32>; 9150397Sobrien 9250397Sobriendef HexagonWrapperCombineRR : 9350397Sobrien SDNode<"HexagonISD::WrapperCombineRR", SDTHexagonI64I32I32>; 9450397Sobrien 9550397Sobrienmulticlass ALU32_Pbase<string mnemonic, RegisterClass RC, bit isNot, 9650397Sobrien bit isPredNew> { 9750397Sobrien let isPredicatedNew = isPredNew in 9850397Sobrien def NAME : ALU32_rr<(outs RC:$dst), 9950397Sobrien (ins PredRegs:$src1, IntRegs:$src2, IntRegs: $src3), 10050397Sobrien !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 10150397Sobrien ") $dst = ")#mnemonic#"($src2, $src3)", 10250397Sobrien []>; 10350397Sobrien} 10450397Sobrien 10550397Sobrienmulticlass ALU32_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 10650397Sobrien let isPredicatedFalse = PredNot in { 10750397Sobrien defm _c#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 0>; 10850397Sobrien // Predicate new 10950397Sobrien defm _cdn#NAME : ALU32_Pbase<mnemonic, RC, PredNot, 1>; 11050397Sobrien } 11150397Sobrien} 11250397Sobrien 11350397Sobrienlet InputType = "reg" in 11450397Sobrienmulticlass ALU32_base<string mnemonic, string CextOp, SDNode OpNode> { 11550397Sobrien let CextOpcode = CextOp, BaseOpcode = CextOp#_rr in { 11650397Sobrien let isPredicable = 1 in 11750397Sobrien def NAME : ALU32_rr<(outs IntRegs:$dst), 11850397Sobrien (ins IntRegs:$src1, IntRegs:$src2), 11950397Sobrien "$dst = "#mnemonic#"($src1, $src2)", 12050397Sobrien [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1), 12150397Sobrien (i32 IntRegs:$src2)))]>; 12250397Sobrien 12350397Sobrien let neverHasSideEffects = 1, isPredicated = 1 in { 12450397Sobrien defm Pt : ALU32_Pred<mnemonic, IntRegs, 0>; 12550397Sobrien defm NotPt : ALU32_Pred<mnemonic, IntRegs, 1>; 12650397Sobrien } 12750397Sobrien } 12850397Sobrien} 12950397Sobrien 13050397Sobrienlet isCommutable = 1 in { 13150397Sobrien defm ADD_rr : ALU32_base<"add", "ADD", add>, ImmRegRel, PredNewRel; 13250397Sobrien defm AND_rr : ALU32_base<"and", "AND", and>, ImmRegRel, PredNewRel; 13350397Sobrien defm XOR_rr : ALU32_base<"xor", "XOR", xor>, ImmRegRel, PredNewRel; 13450397Sobrien defm OR_rr : ALU32_base<"or", "OR", or>, ImmRegRel, PredNewRel; 13550397Sobrien} 13650397Sobrien 13750397Sobriendefm SUB_rr : ALU32_base<"sub", "SUB", sub>, ImmRegRel, PredNewRel; 13850397Sobrien 13950397Sobrien// Combines the two integer registers SRC1 and SRC2 into a double register. 14050397Sobrienlet isPredicable = 1 in 14150397Sobrienclass T_Combine : ALU32_rr<(outs DoubleRegs:$dst), 14250397Sobrien (ins IntRegs:$src1, IntRegs:$src2), 14350397Sobrien "$dst = combine($src1, $src2)", 14450397Sobrien [(set (i64 DoubleRegs:$dst), 14550397Sobrien (i64 (HexagonWrapperCombineRR (i32 IntRegs:$src1), 14650397Sobrien (i32 IntRegs:$src2))))]>; 14750397Sobrien 14850397Sobrienmulticlass Combine_base { 14950397Sobrien let BaseOpcode = "combine" in { 15050397Sobrien def NAME : T_Combine; 15150397Sobrien let neverHasSideEffects = 1, isPredicated = 1 in { 15250397Sobrien defm Pt : ALU32_Pred<"combine", DoubleRegs, 0>; 15350397Sobrien defm NotPt : ALU32_Pred<"combine", DoubleRegs, 1>; 15450397Sobrien } 15550397Sobrien } 15650397Sobrien} 15750397Sobrien 15850397Sobriendefm COMBINE_rr : Combine_base, PredNewRel; 15950397Sobrien 16050397Sobrien// Combines the two immediates SRC1 and SRC2 into a double register. 16150397Sobrienclass COMBINE_imm<Operand imm1, Operand imm2, PatLeaf pat1, PatLeaf pat2> : 16250397Sobrien ALU32_ii<(outs DoubleRegs:$dst), (ins imm1:$src1, imm2:$src2), 16350397Sobrien "$dst = combine(#$src1, #$src2)", 16450397Sobrien [(set (i64 DoubleRegs:$dst), 16550397Sobrien (i64 (HexagonWrapperCombineII (i32 pat1:$src1), (i32 pat2:$src2))))]>; 16650397Sobrien 16750397Sobrienlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8 in 16850397Sobriendef COMBINE_Ii : COMBINE_imm<s8Ext, s8Imm, s8ExtPred, s8ImmPred>; 16950397Sobrien 17050397Sobrien//===----------------------------------------------------------------------===// 17150397Sobrien// ALU32/ALU (ADD with register-immediate form) 17250397Sobrien//===----------------------------------------------------------------------===// 17350397Sobrienmulticlass ALU32ri_Pbase<string mnemonic, bit isNot, bit isPredNew> { 17450397Sobrien let isPredicatedNew = isPredNew in 17550397Sobrien def NAME : ALU32_ri<(outs IntRegs:$dst), 17650397Sobrien (ins PredRegs:$src1, IntRegs:$src2, s8Ext: $src3), 17750397Sobrien !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 17850397Sobrien ") $dst = ")#mnemonic#"($src2, #$src3)", 17950397Sobrien []>; 18050397Sobrien} 18150397Sobrien 18250397Sobrienmulticlass ALU32ri_Pred<string mnemonic, bit PredNot> { 18350397Sobrien let isPredicatedFalse = PredNot in { 18450397Sobrien defm _c#NAME : ALU32ri_Pbase<mnemonic, PredNot, 0>; 18550397Sobrien // Predicate new 18650397Sobrien defm _cdn#NAME : ALU32ri_Pbase<mnemonic, PredNot, 1>; 18750397Sobrien } 18850397Sobrien} 18950397Sobrien 19050397Sobrienlet isExtendable = 1, InputType = "imm" in 19150397Sobrienmulticlass ALU32ri_base<string mnemonic, string CextOp, SDNode OpNode> { 19250397Sobrien let CextOpcode = CextOp, BaseOpcode = CextOp#_ri in { 19350397Sobrien let opExtendable = 2, isExtentSigned = 1, opExtentBits = 16, 19450397Sobrien isPredicable = 1 in 19550397Sobrien def NAME : ALU32_ri<(outs IntRegs:$dst), 19650397Sobrien (ins IntRegs:$src1, s16Ext:$src2), 19750397Sobrien "$dst = "#mnemonic#"($src1, #$src2)", 19850397Sobrien [(set (i32 IntRegs:$dst), (OpNode (i32 IntRegs:$src1), 19950397Sobrien (s16ExtPred:$src2)))]>; 20050397Sobrien 20150397Sobrien let opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 20250397Sobrien neverHasSideEffects = 1, isPredicated = 1 in { 20350397Sobrien defm Pt : ALU32ri_Pred<mnemonic, 0>; 20450397Sobrien defm NotPt : ALU32ri_Pred<mnemonic, 1>; 20550397Sobrien } 20650397Sobrien } 20750397Sobrien} 20850397Sobrien 20950397Sobriendefm ADD_ri : ALU32ri_base<"add", "ADD", add>, ImmRegRel, PredNewRel; 21050397Sobrien 21150397Sobrienlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10, 21250397SobrienCextOpcode = "OR", InputType = "imm" in 21350397Sobriendef OR_ri : ALU32_ri<(outs IntRegs:$dst), 21450397Sobrien (ins IntRegs:$src1, s10Ext:$src2), 21550397Sobrien "$dst = or($src1, #$src2)", 21650397Sobrien [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), 21750397Sobrien s10ExtPred:$src2))]>, ImmRegRel; 21850397Sobrien 21950397Sobrienlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10, 22050397SobrienInputType = "imm", CextOpcode = "AND" in 22150397Sobriendef AND_ri : ALU32_ri<(outs IntRegs:$dst), 22250397Sobrien (ins IntRegs:$src1, s10Ext:$src2), 22350397Sobrien "$dst = and($src1, #$src2)", 22450397Sobrien [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), 22550397Sobrien s10ExtPred:$src2))]>, ImmRegRel; 22650397Sobrien 22750397Sobrien// Nop. 22850397Sobrienlet neverHasSideEffects = 1 in 22950397Sobriendef NOP : ALU32_rr<(outs), (ins), 23050397Sobrien "nop", 23150397Sobrien []>; 23250397Sobrien 23350397Sobrien// Rd32=sub(#s10,Rs32) 23450397Sobrienlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 10, 23550397SobrienCextOpcode = "SUB", InputType = "imm" in 23650397Sobriendef SUB_ri : ALU32_ri<(outs IntRegs:$dst), 23750397Sobrien (ins s10Ext:$src1, IntRegs:$src2), 23850397Sobrien "$dst = sub(#$src1, $src2)", 23950397Sobrien [(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>, 24050397Sobrien ImmRegRel; 24150397Sobrien 24250397Sobrien// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs). 24350397Sobriendef : Pat<(not (i32 IntRegs:$src1)), 24450397Sobrien (SUB_ri -1, (i32 IntRegs:$src1))>; 24550397Sobrien 24650397Sobrien// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs). 24750397Sobrien// Pattern definition for 'neg' was not necessary. 24850397Sobrien 24950397Sobrienmulticlass TFR_Pred<bit PredNot> { 25050397Sobrien let isPredicatedFalse = PredNot in { 25150397Sobrien def _c#NAME : ALU32_rr<(outs IntRegs:$dst), 25250397Sobrien (ins PredRegs:$src1, IntRegs:$src2), 25350397Sobrien !if(PredNot, "if (!$src1", "if ($src1")#") $dst = $src2", 25450397Sobrien []>; 25550397Sobrien // Predicate new 25650397Sobrien let isPredicatedNew = 1 in 25750397Sobrien def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst), 25850397Sobrien (ins PredRegs:$src1, IntRegs:$src2), 25950397Sobrien !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = $src2", 26050397Sobrien []>; 26150397Sobrien } 26250397Sobrien} 26350397Sobrien 26450397Sobrienlet InputType = "reg", neverHasSideEffects = 1 in 26550397Sobrienmulticlass TFR_base<string CextOp> { 26650397Sobrien let CextOpcode = CextOp, BaseOpcode = CextOp in { 26750397Sobrien let isPredicable = 1 in 26850397Sobrien def NAME : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1), 26950397Sobrien "$dst = $src1", 27050397Sobrien []>; 27150397Sobrien 27250397Sobrien let isPredicated = 1 in { 27350397Sobrien defm Pt : TFR_Pred<0>; 27450397Sobrien defm NotPt : TFR_Pred<1>; 27550397Sobrien } 27650397Sobrien } 27750397Sobrien} 27850397Sobrien 27950397Sobrienclass T_TFR64_Pred<bit PredNot, bit isPredNew> 28050397Sobrien : ALU32_rr<(outs DoubleRegs:$dst), 28150397Sobrien (ins PredRegs:$src1, DoubleRegs:$src2), 28250397Sobrien !if(PredNot, "if (!$src1", "if ($src1")# 28350397Sobrien !if(isPredNew, ".new) ", ") ")#"$dst = $src2", []> 28450397Sobrien{ 28550397Sobrien bits<5> dst; 28650397Sobrien bits<2> src1; 28750397Sobrien bits<5> src2; 28850397Sobrien 28950397Sobrien let IClass = 0b1111; 29050397Sobrien let Inst{27-24} = 0b1101; 29150397Sobrien let Inst{13} = isPredNew; 29250397Sobrien let Inst{7} = PredNot; 29350397Sobrien let Inst{4-0} = dst; 29450397Sobrien let Inst{6-5} = src1; 29550397Sobrien let Inst{20-17} = src2{4-1}; 29650397Sobrien let Inst{16} = 0b1; 29750397Sobrien let Inst{12-9} = src2{4-1}; 29850397Sobrien let Inst{8} = 0b0; 29950397Sobrien} 30050397Sobrien 30150397Sobrienmulticlass TFR64_Pred<bit PredNot> { 30250397Sobrien let isPredicatedFalse = PredNot in { 30350397Sobrien def _c#NAME : T_TFR64_Pred<PredNot, 0>; 30450397Sobrien 30550397Sobrien let isPredicatedNew = 1 in 30650397Sobrien def _cdn#NAME : T_TFR64_Pred<PredNot, 1>; // Predicate new 30750397Sobrien } 30850397Sobrien} 30950397Sobrien 31050397Sobrienlet neverHasSideEffects = 1 in 31150397Sobrienmulticlass TFR64_base<string BaseName> { 31250397Sobrien let BaseOpcode = BaseName in { 31350397Sobrien let isPredicable = 1 in 31450397Sobrien def NAME : ALU32Inst <(outs DoubleRegs:$dst), 31550397Sobrien (ins DoubleRegs:$src1), 31650397Sobrien "$dst = $src1" > { 31750397Sobrien bits<5> dst; 31850397Sobrien bits<5> src1; 31950397Sobrien 32050397Sobrien let IClass = 0b1111; 32150397Sobrien let Inst{27-23} = 0b01010; 32250397Sobrien let Inst{4-0} = dst; 32350397Sobrien let Inst{20-17} = src1{4-1}; 32450397Sobrien let Inst{16} = 0b1; 32550397Sobrien let Inst{12-9} = src1{4-1}; 32650397Sobrien let Inst{8} = 0b0; 32750397Sobrien } 32850397Sobrien 32950397Sobrien let isPredicated = 1 in { 33050397Sobrien defm Pt : TFR64_Pred<0>; 33150397Sobrien defm NotPt : TFR64_Pred<1>; 33250397Sobrien } 33350397Sobrien } 33450397Sobrien} 33550397Sobrien 33650397Sobrienmulticlass TFRI_Pred<bit PredNot> { 33750397Sobrien let isMoveImm = 1, isPredicatedFalse = PredNot in { 338 def _c#NAME : ALU32_ri<(outs IntRegs:$dst), 339 (ins PredRegs:$src1, s12Ext:$src2), 340 !if(PredNot, "if (!$src1", "if ($src1")#") $dst = #$src2", 341 []>; 342 343 // Predicate new 344 let isPredicatedNew = 1 in 345 def _cdn#NAME : ALU32_rr<(outs IntRegs:$dst), 346 (ins PredRegs:$src1, s12Ext:$src2), 347 !if(PredNot, "if (!$src1", "if ($src1")#".new) $dst = #$src2", 348 []>; 349 } 350} 351 352let InputType = "imm", isExtendable = 1, isExtentSigned = 1 in 353multiclass TFRI_base<string CextOp> { 354 let CextOpcode = CextOp, BaseOpcode = CextOp#I in { 355 let isAsCheapAsAMove = 1 , opExtendable = 1, opExtentBits = 16, 356 isMoveImm = 1, isPredicable = 1, isReMaterializable = 1 in 357 def NAME : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), 358 "$dst = #$src1", 359 [(set (i32 IntRegs:$dst), s16ExtPred:$src1)]>; 360 361 let opExtendable = 2, opExtentBits = 12, neverHasSideEffects = 1, 362 isPredicated = 1 in { 363 defm Pt : TFRI_Pred<0>; 364 defm NotPt : TFRI_Pred<1>; 365 } 366 } 367} 368 369defm TFRI : TFRI_base<"TFR">, ImmRegRel, PredNewRel; 370defm TFR : TFR_base<"TFR">, ImmRegRel, PredNewRel; 371defm TFR64 : TFR64_base<"TFR64">, PredNewRel; 372 373// Transfer control register. 374let neverHasSideEffects = 1 in 375def TFCR : CRInst<(outs CRRegs:$dst), (ins IntRegs:$src1), 376 "$dst = $src1", 377 []>; 378//===----------------------------------------------------------------------===// 379// ALU32/ALU - 380//===----------------------------------------------------------------------===// 381 382 383//===----------------------------------------------------------------------===// 384// ALU32/PERM + 385//===----------------------------------------------------------------------===// 386 387// Mux. 388def VMUX_prr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, 389 DoubleRegs:$src2, 390 DoubleRegs:$src3), 391 "$dst = vmux($src1, $src2, $src3)", 392 []>; 393 394let CextOpcode = "MUX", InputType = "reg" in 395def MUX_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, 396 IntRegs:$src2, IntRegs:$src3), 397 "$dst = mux($src1, $src2, $src3)", 398 [(set (i32 IntRegs:$dst), 399 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 400 (i32 IntRegs:$src3))))]>, ImmRegRel; 401 402let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 403CextOpcode = "MUX", InputType = "imm" in 404def MUX_ir : ALU32_ir<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2, 405 IntRegs:$src3), 406 "$dst = mux($src1, #$src2, $src3)", 407 [(set (i32 IntRegs:$dst), 408 (i32 (select (i1 PredRegs:$src1), s8ExtPred:$src2, 409 (i32 IntRegs:$src3))))]>, ImmRegRel; 410 411let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 412CextOpcode = "MUX", InputType = "imm" in 413def MUX_ri : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, 414 s8Ext:$src3), 415 "$dst = mux($src1, $src2, #$src3)", 416 [(set (i32 IntRegs:$dst), 417 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 418 s8ExtPred:$src3)))]>, ImmRegRel; 419 420let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in 421def MUX_ii : ALU32_ii<(outs IntRegs:$dst), (ins PredRegs:$src1, s8Ext:$src2, 422 s8Imm:$src3), 423 "$dst = mux($src1, #$src2, #$src3)", 424 [(set (i32 IntRegs:$dst), (i32 (select (i1 PredRegs:$src1), 425 s8ExtPred:$src2, 426 s8ImmPred:$src3)))]>; 427 428// ALU32 - aslh, asrh, sxtb, sxth, zxtb, zxth 429multiclass ALU32_2op_Pbase<string mnemonic, bit isNot, bit isPredNew> { 430 let isPredicatedNew = isPredNew in 431 def NAME : ALU32Inst<(outs IntRegs:$dst), 432 (ins PredRegs:$src1, IntRegs:$src2), 433 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew,".new) $dst = ", 434 ") $dst = ")#mnemonic#"($src2)">, 435 Requires<[HasV4T]>; 436} 437 438multiclass ALU32_2op_Pred<string mnemonic, bit PredNot> { 439 let isPredicatedFalse = PredNot in { 440 defm _c#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 0>; 441 // Predicate new 442 defm _cdn#NAME : ALU32_2op_Pbase<mnemonic, PredNot, 1>; 443 } 444} 445 446multiclass ALU32_2op_base<string mnemonic> { 447 let BaseOpcode = mnemonic in { 448 let isPredicable = 1, neverHasSideEffects = 1 in 449 def NAME : ALU32Inst<(outs IntRegs:$dst), 450 (ins IntRegs:$src1), 451 "$dst = "#mnemonic#"($src1)">; 452 453 let Predicates = [HasV4T], validSubTargets = HasV4SubT, isPredicated = 1, 454 neverHasSideEffects = 1 in { 455 defm Pt_V4 : ALU32_2op_Pred<mnemonic, 0>; 456 defm NotPt_V4 : ALU32_2op_Pred<mnemonic, 1>; 457 } 458 } 459} 460 461defm ASLH : ALU32_2op_base<"aslh">, PredNewRel; 462defm ASRH : ALU32_2op_base<"asrh">, PredNewRel; 463defm SXTB : ALU32_2op_base<"sxtb">, PredNewRel; 464defm SXTH : ALU32_2op_base<"sxth">, PredNewRel; 465defm ZXTB : ALU32_2op_base<"zxtb">, PredNewRel; 466defm ZXTH : ALU32_2op_base<"zxth">, PredNewRel; 467 468def : Pat <(shl (i32 IntRegs:$src1), (i32 16)), 469 (ASLH IntRegs:$src1)>; 470 471def : Pat <(sra (i32 IntRegs:$src1), (i32 16)), 472 (ASRH IntRegs:$src1)>; 473 474def : Pat <(sext_inreg (i32 IntRegs:$src1), i8), 475 (SXTB IntRegs:$src1)>; 476 477def : Pat <(sext_inreg (i32 IntRegs:$src1), i16), 478 (SXTH IntRegs:$src1)>; 479 480//===----------------------------------------------------------------------===// 481// ALU32/PERM - 482//===----------------------------------------------------------------------===// 483 484 485//===----------------------------------------------------------------------===// 486// ALU32/PRED + 487//===----------------------------------------------------------------------===// 488 489// Compare. 490defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel; 491defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel; 492defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel; 493 494// SDNode for converting immediate C to C-1. 495def DEC_CONST_SIGNED : SDNodeXForm<imm, [{ 496 // Return the byte immediate const-1 as an SDNode. 497 int32_t imm = N->getSExtValue(); 498 return XformSToSM1Imm(imm); 499}]>; 500 501// SDNode for converting immediate C to C-1. 502def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{ 503 // Return the byte immediate const-1 as an SDNode. 504 uint32_t imm = N->getZExtValue(); 505 return XformUToUM1Imm(imm); 506}]>; 507 508def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), 509 "$dst = cl0($src1)", 510 [(set (i32 IntRegs:$dst), (ctlz (i32 IntRegs:$src1)))]>; 511 512def CTTZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1), 513 "$dst = ct0($src1)", 514 [(set (i32 IntRegs:$dst), (cttz (i32 IntRegs:$src1)))]>; 515 516def CTLZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), 517 "$dst = cl0($src1)", 518 [(set (i32 IntRegs:$dst), (i32 (trunc (ctlz (i64 DoubleRegs:$src1)))))]>; 519 520def CTTZ64_rr : SInst<(outs IntRegs:$dst), (ins DoubleRegs:$src1), 521 "$dst = ct0($src1)", 522 [(set (i32 IntRegs:$dst), (i32 (trunc (cttz (i64 DoubleRegs:$src1)))))]>; 523 524def TSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 525 "$dst = tstbit($src1, $src2)", 526 [(set (i1 PredRegs:$dst), 527 (setne (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>; 528 529def TSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 530 "$dst = tstbit($src1, $src2)", 531 [(set (i1 PredRegs:$dst), 532 (setne (and (shl 1, (u5ImmPred:$src2)), (i32 IntRegs:$src1)), 0))]>; 533 534//===----------------------------------------------------------------------===// 535// ALU32/PRED - 536//===----------------------------------------------------------------------===// 537 538 539//===----------------------------------------------------------------------===// 540// ALU64/ALU + 541//===----------------------------------------------------------------------===// 542// Add. 543def ADD64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 544 DoubleRegs:$src2), 545 "$dst = add($src1, $src2)", 546 [(set (i64 DoubleRegs:$dst), (add (i64 DoubleRegs:$src1), 547 (i64 DoubleRegs:$src2)))]>; 548 549// Add halfword. 550 551// Compare. 552defm CMPEHexagon4 : CMP64_rr<"cmp.eq", seteq>; 553defm CMPGT64 : CMP64_rr<"cmp.gt", setgt>; 554defm CMPGTU64 : CMP64_rr<"cmp.gtu", setugt>; 555 556// Logical operations. 557def AND_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 558 DoubleRegs:$src2), 559 "$dst = and($src1, $src2)", 560 [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), 561 (i64 DoubleRegs:$src2)))]>; 562 563def OR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 564 DoubleRegs:$src2), 565 "$dst = or($src1, $src2)", 566 [(set (i64 DoubleRegs:$dst), (or (i64 DoubleRegs:$src1), 567 (i64 DoubleRegs:$src2)))]>; 568 569def XOR_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 570 DoubleRegs:$src2), 571 "$dst = xor($src1, $src2)", 572 [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), 573 (i64 DoubleRegs:$src2)))]>; 574 575// Maximum. 576def MAXw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 577 "$dst = max($src2, $src1)", 578 [(set (i32 IntRegs:$dst), 579 (i32 (select (i1 (setlt (i32 IntRegs:$src2), 580 (i32 IntRegs:$src1))), 581 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 582 583def MAXUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 584 "$dst = maxu($src2, $src1)", 585 [(set (i32 IntRegs:$dst), 586 (i32 (select (i1 (setult (i32 IntRegs:$src2), 587 (i32 IntRegs:$src1))), 588 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 589 590def MAXd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 591 DoubleRegs:$src2), 592 "$dst = max($src2, $src1)", 593 [(set (i64 DoubleRegs:$dst), 594 (i64 (select (i1 (setlt (i64 DoubleRegs:$src2), 595 (i64 DoubleRegs:$src1))), 596 (i64 DoubleRegs:$src1), 597 (i64 DoubleRegs:$src2))))]>; 598 599def MAXUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 600 DoubleRegs:$src2), 601 "$dst = maxu($src2, $src1)", 602 [(set (i64 DoubleRegs:$dst), 603 (i64 (select (i1 (setult (i64 DoubleRegs:$src2), 604 (i64 DoubleRegs:$src1))), 605 (i64 DoubleRegs:$src1), 606 (i64 DoubleRegs:$src2))))]>; 607 608// Minimum. 609def MINw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 610 "$dst = min($src2, $src1)", 611 [(set (i32 IntRegs:$dst), 612 (i32 (select (i1 (setgt (i32 IntRegs:$src2), 613 (i32 IntRegs:$src1))), 614 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 615 616def MINUw_rr : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 617 "$dst = minu($src2, $src1)", 618 [(set (i32 IntRegs:$dst), 619 (i32 (select (i1 (setugt (i32 IntRegs:$src2), 620 (i32 IntRegs:$src1))), 621 (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>; 622 623def MINd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 624 DoubleRegs:$src2), 625 "$dst = min($src2, $src1)", 626 [(set (i64 DoubleRegs:$dst), 627 (i64 (select (i1 (setgt (i64 DoubleRegs:$src2), 628 (i64 DoubleRegs:$src1))), 629 (i64 DoubleRegs:$src1), 630 (i64 DoubleRegs:$src2))))]>; 631 632def MINUd_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 633 DoubleRegs:$src2), 634 "$dst = minu($src2, $src1)", 635 [(set (i64 DoubleRegs:$dst), 636 (i64 (select (i1 (setugt (i64 DoubleRegs:$src2), 637 (i64 DoubleRegs:$src1))), 638 (i64 DoubleRegs:$src1), 639 (i64 DoubleRegs:$src2))))]>; 640 641// Subtract. 642def SUB64_rr : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 643 DoubleRegs:$src2), 644 "$dst = sub($src1, $src2)", 645 [(set (i64 DoubleRegs:$dst), (sub (i64 DoubleRegs:$src1), 646 (i64 DoubleRegs:$src2)))]>; 647 648// Subtract halfword. 649 650//===----------------------------------------------------------------------===// 651// ALU64/ALU - 652//===----------------------------------------------------------------------===// 653 654//===----------------------------------------------------------------------===// 655// ALU64/BIT + 656//===----------------------------------------------------------------------===// 657// 658//===----------------------------------------------------------------------===// 659// ALU64/BIT - 660//===----------------------------------------------------------------------===// 661 662//===----------------------------------------------------------------------===// 663// ALU64/PERM + 664//===----------------------------------------------------------------------===// 665// 666//===----------------------------------------------------------------------===// 667// ALU64/PERM - 668//===----------------------------------------------------------------------===// 669 670//===----------------------------------------------------------------------===// 671// CR + 672//===----------------------------------------------------------------------===// 673// Logical reductions on predicates. 674 675// Looping instructions. 676 677// Pipelined looping instructions. 678 679// Logical operations on predicates. 680def AND_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 681 "$dst = and($src1, $src2)", 682 [(set (i1 PredRegs:$dst), (and (i1 PredRegs:$src1), 683 (i1 PredRegs:$src2)))]>; 684 685let neverHasSideEffects = 1 in 686def AND_pnotp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, 687 PredRegs:$src2), 688 "$dst = and($src1, !$src2)", 689 []>; 690 691def ANY_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 692 "$dst = any8($src1)", 693 []>; 694 695def ALL_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 696 "$dst = all8($src1)", 697 []>; 698 699def VITPACK_pp : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1, 700 PredRegs:$src2), 701 "$dst = vitpack($src1, $src2)", 702 []>; 703 704def VALIGN_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 705 DoubleRegs:$src2, 706 PredRegs:$src3), 707 "$dst = valignb($src1, $src2, $src3)", 708 []>; 709 710def VSPLICE_rrp : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 711 DoubleRegs:$src2, 712 PredRegs:$src3), 713 "$dst = vspliceb($src1, $src2, $src3)", 714 []>; 715 716def MASK_p : SInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1), 717 "$dst = mask($src1)", 718 []>; 719 720def NOT_p : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1), 721 "$dst = not($src1)", 722 [(set (i1 PredRegs:$dst), (not (i1 PredRegs:$src1)))]>; 723 724def OR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 725 "$dst = or($src1, $src2)", 726 [(set (i1 PredRegs:$dst), (or (i1 PredRegs:$src1), 727 (i1 PredRegs:$src2)))]>; 728 729def XOR_pp : SInst<(outs PredRegs:$dst), (ins PredRegs:$src1, PredRegs:$src2), 730 "$dst = xor($src1, $src2)", 731 [(set (i1 PredRegs:$dst), (xor (i1 PredRegs:$src1), 732 (i1 PredRegs:$src2)))]>; 733 734 735// User control register transfer. 736//===----------------------------------------------------------------------===// 737// CR - 738//===----------------------------------------------------------------------===// 739 740def retflag : SDNode<"HexagonISD::RET_FLAG", SDTNone, 741 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 742def eh_return: SDNode<"HexagonISD::EH_RETURN", SDTNone, 743 [SDNPHasChain]>; 744 745def SDHexagonBR_JT: SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 746def HexagonBR_JT: SDNode<"HexagonISD::BR_JT", SDHexagonBR_JT, [SDNPHasChain]>; 747 748let InputType = "imm", isBarrier = 1, isPredicable = 1, 749Defs = [PC], isExtendable = 1, opExtendable = 0, isExtentSigned = 1, 750opExtentBits = 24 in 751class T_JMP <dag InsDag, list<dag> JumpList = []> 752 : JInst<(outs), InsDag, 753 "jump $dst" , JumpList> { 754 bits<24> dst; 755 756 let IClass = 0b0101; 757 758 let Inst{27-25} = 0b100; 759 let Inst{24-16} = dst{23-15}; 760 let Inst{13-1} = dst{14-2}; 761} 762 763let InputType = "imm", isExtendable = 1, opExtendable = 1, isExtentSigned = 1, 764Defs = [PC], isPredicated = 1, opExtentBits = 17 in 765class T_JMP_c <bit PredNot, bit isPredNew, bit isTaken>: 766 JInst<(outs ), (ins PredRegs:$src, brtarget:$dst), 767 !if(PredNot, "if (!$src", "if ($src")# 768 !if(isPredNew, ".new) ", ") ")#"jump"# 769 !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> { 770 771 let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), ""); 772 let isPredicatedFalse = PredNot; 773 let isPredicatedNew = isPredNew; 774 bits<2> src; 775 bits<17> dst; 776 777 let IClass = 0b0101; 778 779 let Inst{27-24} = 0b1100; 780 let Inst{21} = PredNot; 781 let Inst{12} = !if(isPredNew, isTaken, zero); 782 let Inst{11} = isPredNew; 783 let Inst{9-8} = src; 784 let Inst{23-22} = dst{16-15}; 785 let Inst{20-16} = dst{14-10}; 786 let Inst{13} = dst{9}; 787 let Inst{7-1} = dst{8-2}; 788 } 789 790let isBarrier = 1, Defs = [PC], isPredicable = 1, InputType = "reg" in 791class T_JMPr<dag InsDag = (ins IntRegs:$dst)> 792 : JRInst<(outs ), InsDag, 793 "jumpr $dst" , 794 []> { 795 bits<5> dst; 796 797 let IClass = 0b0101; 798 let Inst{27-21} = 0b0010100; 799 let Inst{20-16} = dst; 800} 801 802let Defs = [PC], isPredicated = 1, InputType = "reg" in 803class T_JMPr_c <bit PredNot, bit isPredNew, bit isTaken>: 804 JRInst <(outs ), (ins PredRegs:$src, IntRegs:$dst), 805 !if(PredNot, "if (!$src", "if ($src")# 806 !if(isPredNew, ".new) ", ") ")#"jumpr"# 807 !if(isPredNew, !if(isTaken, ":t ", ":nt "), " ")#"$dst"> { 808 809 let isBrTaken = !if(isPredNew, !if(isTaken, "true", "false"), ""); 810 let isPredicatedFalse = PredNot; 811 let isPredicatedNew = isPredNew; 812 bits<2> src; 813 bits<5> dst; 814 815 let IClass = 0b0101; 816 817 let Inst{27-22} = 0b001101; 818 let Inst{21} = PredNot; 819 let Inst{20-16} = dst; 820 let Inst{12} = !if(isPredNew, isTaken, zero); 821 let Inst{11} = isPredNew; 822 let Inst{9-8} = src; 823 let Predicates = !if(isPredNew, [HasV3T], [HasV2T]); 824 let validSubTargets = !if(isPredNew, HasV3SubT, HasV2SubT); 825} 826 827multiclass JMP_Pred<bit PredNot> { 828 def _#NAME : T_JMP_c<PredNot, 0, 0>; 829 // Predicate new 830 def _#NAME#new_t : T_JMP_c<PredNot, 1, 1>; // taken 831 def _#NAME#new_nt : T_JMP_c<PredNot, 1, 0>; // not taken 832} 833 834multiclass JMP_base<string BaseOp> { 835 let BaseOpcode = BaseOp in { 836 def NAME : T_JMP<(ins brtarget:$dst), [(br bb:$dst)]>; 837 defm t : JMP_Pred<0>; 838 defm f : JMP_Pred<1>; 839 } 840} 841 842multiclass JMPR_Pred<bit PredNot> { 843 def NAME: T_JMPr_c<PredNot, 0, 0>; 844 // Predicate new 845 def NAME#new_tV3 : T_JMPr_c<PredNot, 1, 1>; // taken 846 def NAME#new_ntV3 : T_JMPr_c<PredNot, 1, 0>; // not taken 847} 848 849multiclass JMPR_base<string BaseOp> { 850 let BaseOpcode = BaseOp in { 851 def NAME : T_JMPr; 852 defm _t : JMPR_Pred<0>; 853 defm _f : JMPR_Pred<1>; 854 } 855} 856 857let isTerminator = 1, neverHasSideEffects = 1 in { 858let isBranch = 1 in 859defm JMP : JMP_base<"JMP">, PredNewRel; 860 861let isBranch = 1, isIndirectBranch = 1 in 862defm JMPR : JMPR_base<"JMPr">, PredNewRel; 863 864let isReturn = 1, isCodeGenOnly = 1 in 865defm JMPret : JMPR_base<"JMPret">, PredNewRel; 866} 867 868def : Pat<(retflag), 869 (JMPret (i32 R31))>; 870 871def : Pat <(brcond (i1 PredRegs:$src1), bb:$offset), 872 (JMP_t (i1 PredRegs:$src1), bb:$offset)>; 873 874// A return through builtin_eh_return. 875let isReturn = 1, isTerminator = 1, isBarrier = 1, neverHasSideEffects = 1, 876isCodeGenOnly = 1, Defs = [PC], Uses = [R28], isPredicable = 0 in 877def EH_RETURN_JMPR : T_JMPr; 878 879def : Pat<(eh_return), 880 (EH_RETURN_JMPR (i32 R31))>; 881 882def : Pat<(HexagonBR_JT (i32 IntRegs:$dst)), 883 (JMPR (i32 IntRegs:$dst))>; 884 885def : Pat<(brind (i32 IntRegs:$dst)), 886 (JMPR (i32 IntRegs:$dst))>; 887 888//===----------------------------------------------------------------------===// 889// JR - 890//===----------------------------------------------------------------------===// 891 892//===----------------------------------------------------------------------===// 893// LD + 894//===----------------------------------------------------------------------===// 895/// 896// Load -- MEMri operand 897multiclass LD_MEMri_Pbase<string mnemonic, RegisterClass RC, 898 bit isNot, bit isPredNew> { 899 let isPredicatedNew = isPredNew in 900 def NAME : LDInst2<(outs RC:$dst), 901 (ins PredRegs:$src1, MEMri:$addr), 902 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 903 ") ")#"$dst = "#mnemonic#"($addr)", 904 []>; 905} 906 907multiclass LD_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 908 let isPredicatedFalse = PredNot in { 909 defm _c#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 0>; 910 // Predicate new 911 defm _cdn#NAME : LD_MEMri_Pbase<mnemonic, RC, PredNot, 1>; 912 } 913} 914 915let isExtendable = 1, neverHasSideEffects = 1 in 916multiclass LD_MEMri<string mnemonic, string CextOp, RegisterClass RC, 917 bits<5> ImmBits, bits<5> PredImmBits> { 918 919 let CextOpcode = CextOp, BaseOpcode = CextOp in { 920 let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits, 921 isPredicable = 1 in 922 def NAME : LDInst2<(outs RC:$dst), (ins MEMri:$addr), 923 "$dst = "#mnemonic#"($addr)", 924 []>; 925 926 let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits, 927 isPredicated = 1 in { 928 defm Pt : LD_MEMri_Pred<mnemonic, RC, 0 >; 929 defm NotPt : LD_MEMri_Pred<mnemonic, RC, 1 >; 930 } 931 } 932} 933 934let addrMode = BaseImmOffset, isMEMri = "true" in { 935 defm LDrib: LD_MEMri < "memb", "LDrib", IntRegs, 11, 6>, AddrModeRel; 936 defm LDriub: LD_MEMri < "memub" , "LDriub", IntRegs, 11, 6>, AddrModeRel; 937 defm LDrih: LD_MEMri < "memh", "LDrih", IntRegs, 12, 7>, AddrModeRel; 938 defm LDriuh: LD_MEMri < "memuh", "LDriuh", IntRegs, 12, 7>, AddrModeRel; 939 defm LDriw: LD_MEMri < "memw", "LDriw", IntRegs, 13, 8>, AddrModeRel; 940 defm LDrid: LD_MEMri < "memd", "LDrid", DoubleRegs, 14, 9>, AddrModeRel; 941} 942 943def : Pat < (i32 (sextloadi8 ADDRriS11_0:$addr)), 944 (LDrib ADDRriS11_0:$addr) >; 945 946def : Pat < (i32 (zextloadi8 ADDRriS11_0:$addr)), 947 (LDriub ADDRriS11_0:$addr) >; 948 949def : Pat < (i32 (sextloadi16 ADDRriS11_1:$addr)), 950 (LDrih ADDRriS11_1:$addr) >; 951 952def : Pat < (i32 (zextloadi16 ADDRriS11_1:$addr)), 953 (LDriuh ADDRriS11_1:$addr) >; 954 955def : Pat < (i32 (load ADDRriS11_2:$addr)), 956 (LDriw ADDRriS11_2:$addr) >; 957 958def : Pat < (i64 (load ADDRriS11_3:$addr)), 959 (LDrid ADDRriS11_3:$addr) >; 960 961 962// Load - Base with Immediate offset addressing mode 963multiclass LD_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp, 964 bit isNot, bit isPredNew> { 965 let isPredicatedNew = isPredNew in 966 def NAME : LDInst2<(outs RC:$dst), 967 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3), 968 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 969 ") ")#"$dst = "#mnemonic#"($src2+#$src3)", 970 []>; 971} 972 973multiclass LD_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp, 974 bit PredNot> { 975 let isPredicatedFalse = PredNot in { 976 defm _c#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>; 977 // Predicate new 978 defm _cdn#NAME : LD_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>; 979 } 980} 981 982let isExtendable = 1, neverHasSideEffects = 1 in 983multiclass LD_Idxd<string mnemonic, string CextOp, RegisterClass RC, 984 Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 985 bits<5> PredImmBits> { 986 987 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 988 let opExtendable = 2, isExtentSigned = 1, opExtentBits = ImmBits, 989 isPredicable = 1, AddedComplexity = 20 in 990 def NAME : LDInst2<(outs RC:$dst), (ins IntRegs:$src1, ImmOp:$offset), 991 "$dst = "#mnemonic#"($src1+#$offset)", 992 []>; 993 994 let opExtendable = 3, isExtentSigned = 0, opExtentBits = PredImmBits, 995 isPredicated = 1 in { 996 defm Pt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 0 >; 997 defm NotPt : LD_Idxd_Pred<mnemonic, RC, predImmOp, 1 >; 998 } 999 } 1000} 1001 1002let addrMode = BaseImmOffset in { 1003 defm LDrib_indexed: LD_Idxd <"memb", "LDrib", IntRegs, s11_0Ext, u6_0Ext, 1004 11, 6>, AddrModeRel; 1005 defm LDriub_indexed: LD_Idxd <"memub" , "LDriub", IntRegs, s11_0Ext, u6_0Ext, 1006 11, 6>, AddrModeRel; 1007 defm LDrih_indexed: LD_Idxd <"memh", "LDrih", IntRegs, s11_1Ext, u6_1Ext, 1008 12, 7>, AddrModeRel; 1009 defm LDriuh_indexed: LD_Idxd <"memuh", "LDriuh", IntRegs, s11_1Ext, u6_1Ext, 1010 12, 7>, AddrModeRel; 1011 defm LDriw_indexed: LD_Idxd <"memw", "LDriw", IntRegs, s11_2Ext, u6_2Ext, 1012 13, 8>, AddrModeRel; 1013 defm LDrid_indexed: LD_Idxd <"memd", "LDrid", DoubleRegs, s11_3Ext, u6_3Ext, 1014 14, 9>, AddrModeRel; 1015} 1016 1017let AddedComplexity = 20 in { 1018def : Pat < (i32 (sextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))), 1019 (LDrib_indexed IntRegs:$src1, s11_0ExtPred:$offset) >; 1020 1021def : Pat < (i32 (zextloadi8 (add IntRegs:$src1, s11_0ExtPred:$offset))), 1022 (LDriub_indexed IntRegs:$src1, s11_0ExtPred:$offset) >; 1023 1024def : Pat < (i32 (sextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))), 1025 (LDrih_indexed IntRegs:$src1, s11_1ExtPred:$offset) >; 1026 1027def : Pat < (i32 (zextloadi16 (add IntRegs:$src1, s11_1ExtPred:$offset))), 1028 (LDriuh_indexed IntRegs:$src1, s11_1ExtPred:$offset) >; 1029 1030def : Pat < (i32 (load (add IntRegs:$src1, s11_2ExtPred:$offset))), 1031 (LDriw_indexed IntRegs:$src1, s11_2ExtPred:$offset) >; 1032 1033def : Pat < (i64 (load (add IntRegs:$src1, s11_3ExtPred:$offset))), 1034 (LDrid_indexed IntRegs:$src1, s11_3ExtPred:$offset) >; 1035} 1036 1037//===----------------------------------------------------------------------===// 1038// Post increment load 1039// Make sure that in post increment load, the first operand is always the post 1040// increment operand. 1041//===----------------------------------------------------------------------===// 1042 1043multiclass LD_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, 1044 bit isNot, bit isPredNew> { 1045 let isPredicatedNew = isPredNew in 1046 def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2), 1047 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset), 1048 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1049 ") ")#"$dst = "#mnemonic#"($src2++#$offset)", 1050 [], 1051 "$src2 = $dst2">; 1052} 1053 1054multiclass LD_PostInc_Pred<string mnemonic, RegisterClass RC, 1055 Operand ImmOp, bit PredNot> { 1056 let isPredicatedFalse = PredNot in { 1057 defm _c#NAME : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; 1058 // Predicate new 1059 let Predicates = [HasV4T], validSubTargets = HasV4SubT in 1060 defm _cdn#NAME#_V4 : LD_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>; 1061 } 1062} 1063 1064multiclass LD_PostInc<string mnemonic, string BaseOp, RegisterClass RC, 1065 Operand ImmOp> { 1066 1067 let BaseOpcode = "POST_"#BaseOp in { 1068 let isPredicable = 1 in 1069 def NAME : LDInst2PI<(outs RC:$dst, IntRegs:$dst2), 1070 (ins IntRegs:$src1, ImmOp:$offset), 1071 "$dst = "#mnemonic#"($src1++#$offset)", 1072 [], 1073 "$src1 = $dst2">; 1074 1075 let isPredicated = 1 in { 1076 defm Pt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 0 >; 1077 defm NotPt : LD_PostInc_Pred<mnemonic, RC, ImmOp, 1 >; 1078 } 1079 } 1080} 1081 1082let hasCtrlDep = 1, neverHasSideEffects = 1 in { 1083 defm POST_LDrib : LD_PostInc<"memb", "LDrib", IntRegs, s4_0Imm>, 1084 PredNewRel; 1085 defm POST_LDriub : LD_PostInc<"memub", "LDriub", IntRegs, s4_0Imm>, 1086 PredNewRel; 1087 defm POST_LDrih : LD_PostInc<"memh", "LDrih", IntRegs, s4_1Imm>, 1088 PredNewRel; 1089 defm POST_LDriuh : LD_PostInc<"memuh", "LDriuh", IntRegs, s4_1Imm>, 1090 PredNewRel; 1091 defm POST_LDriw : LD_PostInc<"memw", "LDriw", IntRegs, s4_2Imm>, 1092 PredNewRel; 1093 defm POST_LDrid : LD_PostInc<"memd", "LDrid", DoubleRegs, s4_3Imm>, 1094 PredNewRel; 1095} 1096 1097def : Pat< (i32 (extloadi1 ADDRriS11_0:$addr)), 1098 (i32 (LDrib ADDRriS11_0:$addr)) >; 1099 1100// Load byte any-extend. 1101def : Pat < (i32 (extloadi8 ADDRriS11_0:$addr)), 1102 (i32 (LDrib ADDRriS11_0:$addr)) >; 1103 1104// Indexed load byte any-extend. 1105let AddedComplexity = 20 in 1106def : Pat < (i32 (extloadi8 (add IntRegs:$src1, s11_0ImmPred:$offset))), 1107 (i32 (LDrib_indexed IntRegs:$src1, s11_0ImmPred:$offset)) >; 1108 1109def : Pat < (i32 (extloadi16 ADDRriS11_1:$addr)), 1110 (i32 (LDrih ADDRriS11_1:$addr))>; 1111 1112let AddedComplexity = 20 in 1113def : Pat < (i32 (extloadi16 (add IntRegs:$src1, s11_1ImmPred:$offset))), 1114 (i32 (LDrih_indexed IntRegs:$src1, s11_1ImmPred:$offset)) >; 1115 1116let AddedComplexity = 10 in 1117def : Pat < (i32 (zextloadi1 ADDRriS11_0:$addr)), 1118 (i32 (LDriub ADDRriS11_0:$addr))>; 1119 1120let AddedComplexity = 20 in 1121def : Pat < (i32 (zextloadi1 (add IntRegs:$src1, s11_0ImmPred:$offset))), 1122 (i32 (LDriub_indexed IntRegs:$src1, s11_0ImmPred:$offset))>; 1123 1124// Load predicate. 1125let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 13, 1126isPseudo = 1, Defs = [R10,R11,D5], neverHasSideEffects = 1 in 1127def LDriw_pred : LDInst2<(outs PredRegs:$dst), 1128 (ins MEMri:$addr), 1129 "Error; should not emit", 1130 []>; 1131 1132// Deallocate stack frame. 1133let Defs = [R29, R30, R31], Uses = [R29], neverHasSideEffects = 1 in { 1134 def DEALLOCFRAME : LDInst2<(outs), (ins), 1135 "deallocframe", 1136 []>; 1137} 1138 1139// Load and unpack bytes to halfwords. 1140//===----------------------------------------------------------------------===// 1141// LD - 1142//===----------------------------------------------------------------------===// 1143 1144//===----------------------------------------------------------------------===// 1145// MTYPE/ALU + 1146//===----------------------------------------------------------------------===// 1147//===----------------------------------------------------------------------===// 1148// MTYPE/ALU - 1149//===----------------------------------------------------------------------===// 1150 1151//===----------------------------------------------------------------------===// 1152// MTYPE/COMPLEX + 1153//===----------------------------------------------------------------------===// 1154//===----------------------------------------------------------------------===// 1155// MTYPE/COMPLEX - 1156//===----------------------------------------------------------------------===// 1157 1158//===----------------------------------------------------------------------===// 1159// MTYPE/MPYH + 1160//===----------------------------------------------------------------------===// 1161// Multiply and use lower result. 1162// Rd=+mpyi(Rs,#u8) 1163let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in 1164def MPYI_riu : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Ext:$src2), 1165 "$dst =+ mpyi($src1, #$src2)", 1166 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1167 u8ExtPred:$src2))]>; 1168 1169// Rd=-mpyi(Rs,#u8) 1170def MPYI_rin : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u8Imm:$src2), 1171 "$dst =- mpyi($src1, #$src2)", 1172 [(set (i32 IntRegs:$dst), (ineg (mul (i32 IntRegs:$src1), 1173 u8ImmPred:$src2)))]>; 1174 1175// Rd=mpyi(Rs,#m9) 1176// s9 is NOT the same as m9 - but it works.. so far. 1177// Assembler maps to either Rd=+mpyi(Rs,#u8 or Rd=-mpyi(Rs,#u8) 1178// depending on the value of m9. See Arch Spec. 1179let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 9, 1180CextOpcode = "MPYI", InputType = "imm" in 1181def MPYI_ri : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, s9Ext:$src2), 1182 "$dst = mpyi($src1, #$src2)", 1183 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1184 s9ExtPred:$src2))]>, ImmRegRel; 1185 1186// Rd=mpyi(Rs,Rt) 1187let CextOpcode = "MPYI", InputType = "reg" in 1188def MPYI : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1189 "$dst = mpyi($src1, $src2)", 1190 [(set (i32 IntRegs:$dst), (mul (i32 IntRegs:$src1), 1191 (i32 IntRegs:$src2)))]>, ImmRegRel; 1192 1193// Rx+=mpyi(Rs,#u8) 1194let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8, 1195CextOpcode = "MPYI_acc", InputType = "imm" in 1196def MPYI_acc_ri : MInst_acc<(outs IntRegs:$dst), 1197 (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3), 1198 "$dst += mpyi($src2, #$src3)", 1199 [(set (i32 IntRegs:$dst), 1200 (add (mul (i32 IntRegs:$src2), u8ExtPred:$src3), 1201 (i32 IntRegs:$src1)))], 1202 "$src1 = $dst">, ImmRegRel; 1203 1204// Rx+=mpyi(Rs,Rt) 1205let CextOpcode = "MPYI_acc", InputType = "reg" in 1206def MPYI_acc_rr : MInst_acc<(outs IntRegs:$dst), 1207 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1208 "$dst += mpyi($src2, $src3)", 1209 [(set (i32 IntRegs:$dst), 1210 (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1211 (i32 IntRegs:$src1)))], 1212 "$src1 = $dst">, ImmRegRel; 1213 1214// Rx-=mpyi(Rs,#u8) 1215let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 8 in 1216def MPYI_sub_ri : MInst_acc<(outs IntRegs:$dst), 1217 (ins IntRegs:$src1, IntRegs:$src2, u8Ext:$src3), 1218 "$dst -= mpyi($src2, #$src3)", 1219 [(set (i32 IntRegs:$dst), 1220 (sub (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1221 u8ExtPred:$src3)))], 1222 "$src1 = $dst">; 1223 1224// Multiply and use upper result. 1225// Rd=mpy(Rs,Rt.H):<<1:rnd:sat 1226// Rd=mpy(Rs,Rt.L):<<1:rnd:sat 1227// Rd=mpy(Rs,Rt) 1228def MPY : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1229 "$dst = mpy($src1, $src2)", 1230 [(set (i32 IntRegs:$dst), (mulhs (i32 IntRegs:$src1), 1231 (i32 IntRegs:$src2)))]>; 1232 1233// Rd=mpy(Rs,Rt):rnd 1234// Rd=mpyu(Rs,Rt) 1235def MPYU : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1236 "$dst = mpyu($src1, $src2)", 1237 [(set (i32 IntRegs:$dst), (mulhu (i32 IntRegs:$src1), 1238 (i32 IntRegs:$src2)))]>; 1239 1240// Multiply and use full result. 1241// Rdd=mpyu(Rs,Rt) 1242def MPYU64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1243 "$dst = mpyu($src1, $src2)", 1244 [(set (i64 DoubleRegs:$dst), 1245 (mul (i64 (anyext (i32 IntRegs:$src1))), 1246 (i64 (anyext (i32 IntRegs:$src2)))))]>; 1247 1248// Rdd=mpy(Rs,Rt) 1249def MPY64 : MInst<(outs DoubleRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1250 "$dst = mpy($src1, $src2)", 1251 [(set (i64 DoubleRegs:$dst), 1252 (mul (i64 (sext (i32 IntRegs:$src1))), 1253 (i64 (sext (i32 IntRegs:$src2)))))]>; 1254 1255// Multiply and accumulate, use full result. 1256// Rxx[+-]=mpy(Rs,Rt) 1257// Rxx+=mpy(Rs,Rt) 1258def MPY64_acc : MInst_acc<(outs DoubleRegs:$dst), 1259 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1260 "$dst += mpy($src2, $src3)", 1261 [(set (i64 DoubleRegs:$dst), 1262 (add (mul (i64 (sext (i32 IntRegs:$src2))), 1263 (i64 (sext (i32 IntRegs:$src3)))), 1264 (i64 DoubleRegs:$src1)))], 1265 "$src1 = $dst">; 1266 1267// Rxx-=mpy(Rs,Rt) 1268def MPY64_sub : MInst_acc<(outs DoubleRegs:$dst), 1269 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1270 "$dst -= mpy($src2, $src3)", 1271 [(set (i64 DoubleRegs:$dst), 1272 (sub (i64 DoubleRegs:$src1), 1273 (mul (i64 (sext (i32 IntRegs:$src2))), 1274 (i64 (sext (i32 IntRegs:$src3))))))], 1275 "$src1 = $dst">; 1276 1277// Rxx[+-]=mpyu(Rs,Rt) 1278// Rxx+=mpyu(Rs,Rt) 1279def MPYU64_acc : MInst_acc<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1280 IntRegs:$src2, IntRegs:$src3), 1281 "$dst += mpyu($src2, $src3)", 1282 [(set (i64 DoubleRegs:$dst), 1283 (add (mul (i64 (anyext (i32 IntRegs:$src2))), 1284 (i64 (anyext (i32 IntRegs:$src3)))), 1285 (i64 DoubleRegs:$src1)))], "$src1 = $dst">; 1286 1287// Rxx-=mpyu(Rs,Rt) 1288def MPYU64_sub : MInst_acc<(outs DoubleRegs:$dst), 1289 (ins DoubleRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1290 "$dst -= mpyu($src2, $src3)", 1291 [(set (i64 DoubleRegs:$dst), 1292 (sub (i64 DoubleRegs:$src1), 1293 (mul (i64 (anyext (i32 IntRegs:$src2))), 1294 (i64 (anyext (i32 IntRegs:$src3))))))], 1295 "$src1 = $dst">; 1296 1297 1298let InputType = "reg", CextOpcode = "ADD_acc" in 1299def ADDrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1300 IntRegs:$src2, IntRegs:$src3), 1301 "$dst += add($src2, $src3)", 1302 [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2), 1303 (i32 IntRegs:$src3)), 1304 (i32 IntRegs:$src1)))], 1305 "$src1 = $dst">, ImmRegRel; 1306 1307let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 1308InputType = "imm", CextOpcode = "ADD_acc" in 1309def ADDri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1310 IntRegs:$src2, s8Ext:$src3), 1311 "$dst += add($src2, #$src3)", 1312 [(set (i32 IntRegs:$dst), (add (add (i32 IntRegs:$src2), 1313 s8_16ExtPred:$src3), 1314 (i32 IntRegs:$src1)))], 1315 "$src1 = $dst">, ImmRegRel; 1316 1317let CextOpcode = "SUB_acc", InputType = "reg" in 1318def SUBrr_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1319 IntRegs:$src2, IntRegs:$src3), 1320 "$dst -= add($src2, $src3)", 1321 [(set (i32 IntRegs:$dst), 1322 (sub (i32 IntRegs:$src1), (add (i32 IntRegs:$src2), 1323 (i32 IntRegs:$src3))))], 1324 "$src1 = $dst">, ImmRegRel; 1325 1326let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 8, 1327CextOpcode = "SUB_acc", InputType = "imm" in 1328def SUBri_acc : MInst_acc<(outs IntRegs: $dst), (ins IntRegs:$src1, 1329 IntRegs:$src2, s8Ext:$src3), 1330 "$dst -= add($src2, #$src3)", 1331 [(set (i32 IntRegs:$dst), (sub (i32 IntRegs:$src1), 1332 (add (i32 IntRegs:$src2), 1333 s8_16ExtPred:$src3)))], 1334 "$src1 = $dst">, ImmRegRel; 1335 1336//===----------------------------------------------------------------------===// 1337// MTYPE/MPYH - 1338//===----------------------------------------------------------------------===// 1339 1340//===----------------------------------------------------------------------===// 1341// MTYPE/MPYS + 1342//===----------------------------------------------------------------------===// 1343//===----------------------------------------------------------------------===// 1344// MTYPE/MPYS - 1345//===----------------------------------------------------------------------===// 1346 1347//===----------------------------------------------------------------------===// 1348// MTYPE/VB + 1349//===----------------------------------------------------------------------===// 1350//===----------------------------------------------------------------------===// 1351// MTYPE/VB - 1352//===----------------------------------------------------------------------===// 1353 1354//===----------------------------------------------------------------------===// 1355// MTYPE/VH + 1356//===----------------------------------------------------------------------===// 1357//===----------------------------------------------------------------------===// 1358// MTYPE/VH - 1359//===----------------------------------------------------------------------===// 1360 1361//===----------------------------------------------------------------------===// 1362// ST + 1363//===----------------------------------------------------------------------===// 1364/// 1365// Store doubleword. 1366 1367//===----------------------------------------------------------------------===// 1368// Post increment store 1369//===----------------------------------------------------------------------===// 1370 1371multiclass ST_PostInc_Pbase<string mnemonic, RegisterClass RC, Operand ImmOp, 1372 bit isNot, bit isPredNew> { 1373 let isPredicatedNew = isPredNew in 1374 def NAME : STInst2PI<(outs IntRegs:$dst), 1375 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3), 1376 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1377 ") ")#mnemonic#"($src2++#$offset) = $src3", 1378 [], 1379 "$src2 = $dst">; 1380} 1381 1382multiclass ST_PostInc_Pred<string mnemonic, RegisterClass RC, 1383 Operand ImmOp, bit PredNot> { 1384 let isPredicatedFalse = PredNot in { 1385 defm _c#NAME# : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 0>; 1386 // Predicate new 1387 let Predicates = [HasV4T], validSubTargets = HasV4SubT in 1388 defm _cdn#NAME#_V4 : ST_PostInc_Pbase<mnemonic, RC, ImmOp, PredNot, 1>; 1389 } 1390} 1391 1392let hasCtrlDep = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1393multiclass ST_PostInc<string mnemonic, string BaseOp, RegisterClass RC, 1394 Operand ImmOp> { 1395 1396 let hasCtrlDep = 1, BaseOpcode = "POST_"#BaseOp in { 1397 let isPredicable = 1 in 1398 def NAME : STInst2PI<(outs IntRegs:$dst), 1399 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2), 1400 #mnemonic#"($src1++#$offset) = $src2", 1401 [], 1402 "$src1 = $dst">; 1403 1404 let isPredicated = 1 in { 1405 defm Pt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 0 >; 1406 defm NotPt : ST_PostInc_Pred<mnemonic, RC, ImmOp, 1 >; 1407 } 1408 } 1409} 1410 1411defm POST_STbri: ST_PostInc <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel; 1412defm POST_SThri: ST_PostInc <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel; 1413defm POST_STwri: ST_PostInc <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; 1414 1415let isNVStorable = 0 in 1416defm POST_STdri: ST_PostInc <"memd", "STrid", DoubleRegs, s4_3Imm>, AddrModeRel; 1417 1418def : Pat<(post_truncsti8 (i32 IntRegs:$src1), IntRegs:$src2, 1419 s4_3ImmPred:$offset), 1420 (POST_STbri IntRegs:$src2, s4_0ImmPred:$offset, IntRegs:$src1)>; 1421 1422def : Pat<(post_truncsti16 (i32 IntRegs:$src1), IntRegs:$src2, 1423 s4_3ImmPred:$offset), 1424 (POST_SThri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>; 1425 1426def : Pat<(post_store (i32 IntRegs:$src1), IntRegs:$src2, s4_2ImmPred:$offset), 1427 (POST_STwri IntRegs:$src2, s4_1ImmPred:$offset, IntRegs:$src1)>; 1428 1429def : Pat<(post_store (i64 DoubleRegs:$src1), IntRegs:$src2, 1430 s4_3ImmPred:$offset), 1431 (POST_STdri IntRegs:$src2, s4_3ImmPred:$offset, DoubleRegs:$src1)>; 1432 1433//===----------------------------------------------------------------------===// 1434// multiclass for the store instructions with MEMri operand. 1435//===----------------------------------------------------------------------===// 1436multiclass ST_MEMri_Pbase<string mnemonic, RegisterClass RC, bit isNot, 1437 bit isPredNew> { 1438 let isPredicatedNew = isPredNew in 1439 def NAME : STInst2<(outs), 1440 (ins PredRegs:$src1, MEMri:$addr, RC: $src2), 1441 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1442 ") ")#mnemonic#"($addr) = $src2", 1443 []>; 1444} 1445 1446multiclass ST_MEMri_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 1447 let isPredicatedFalse = PredNot in { 1448 defm _c#NAME : ST_MEMri_Pbase<mnemonic, RC, PredNot, 0>; 1449 1450 // Predicate new 1451 let validSubTargets = HasV4SubT, Predicates = [HasV4T] in 1452 defm _cdn#NAME#_V4 : ST_MEMri_Pbase<mnemonic, RC, PredNot, 1>; 1453 } 1454} 1455 1456let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1457multiclass ST_MEMri<string mnemonic, string CextOp, RegisterClass RC, 1458 bits<5> ImmBits, bits<5> PredImmBits> { 1459 1460 let CextOpcode = CextOp, BaseOpcode = CextOp in { 1461 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 1462 isPredicable = 1 in 1463 def NAME : STInst2<(outs), 1464 (ins MEMri:$addr, RC:$src), 1465 mnemonic#"($addr) = $src", 1466 []>; 1467 1468 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 1469 isPredicated = 1 in { 1470 defm Pt : ST_MEMri_Pred<mnemonic, RC, 0>; 1471 defm NotPt : ST_MEMri_Pred<mnemonic, RC, 1>; 1472 } 1473 } 1474} 1475 1476let addrMode = BaseImmOffset, isMEMri = "true" in { 1477 defm STrib: ST_MEMri < "memb", "STrib", IntRegs, 11, 6>, AddrModeRel; 1478 defm STrih: ST_MEMri < "memh", "STrih", IntRegs, 12, 7>, AddrModeRel; 1479 defm STriw: ST_MEMri < "memw", "STriw", IntRegs, 13, 8>, AddrModeRel; 1480 1481 let isNVStorable = 0 in 1482 defm STrid: ST_MEMri < "memd", "STrid", DoubleRegs, 14, 9>, AddrModeRel; 1483} 1484 1485def : Pat<(truncstorei8 (i32 IntRegs:$src1), ADDRriS11_0:$addr), 1486 (STrib ADDRriS11_0:$addr, (i32 IntRegs:$src1))>; 1487 1488def : Pat<(truncstorei16 (i32 IntRegs:$src1), ADDRriS11_1:$addr), 1489 (STrih ADDRriS11_1:$addr, (i32 IntRegs:$src1))>; 1490 1491def : Pat<(store (i32 IntRegs:$src1), ADDRriS11_2:$addr), 1492 (STriw ADDRriS11_2:$addr, (i32 IntRegs:$src1))>; 1493 1494def : Pat<(store (i64 DoubleRegs:$src1), ADDRriS11_3:$addr), 1495 (STrid ADDRriS11_3:$addr, (i64 DoubleRegs:$src1))>; 1496 1497 1498//===----------------------------------------------------------------------===// 1499// multiclass for the store instructions with base+immediate offset 1500// addressing mode 1501//===----------------------------------------------------------------------===// 1502multiclass ST_Idxd_Pbase<string mnemonic, RegisterClass RC, Operand predImmOp, 1503 bit isNot, bit isPredNew> { 1504 let isPredicatedNew = isPredNew in 1505 def NAME : STInst2<(outs), 1506 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4), 1507 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1508 ") ")#mnemonic#"($src2+#$src3) = $src4", 1509 []>; 1510} 1511 1512multiclass ST_Idxd_Pred<string mnemonic, RegisterClass RC, Operand predImmOp, 1513 bit PredNot> { 1514 let isPredicatedFalse = PredNot, isPredicated = 1 in { 1515 defm _c#NAME : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 0>; 1516 1517 // Predicate new 1518 let validSubTargets = HasV4SubT, Predicates = [HasV4T] in 1519 defm _cdn#NAME#_V4 : ST_Idxd_Pbase<mnemonic, RC, predImmOp, PredNot, 1>; 1520 } 1521} 1522 1523let isExtendable = 1, isNVStorable = 1, neverHasSideEffects = 1 in 1524multiclass ST_Idxd<string mnemonic, string CextOp, RegisterClass RC, 1525 Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 1526 bits<5> PredImmBits> { 1527 1528 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 1529 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 1530 isPredicable = 1 in 1531 def NAME : STInst2<(outs), 1532 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3), 1533 mnemonic#"($src1+#$src2) = $src3", 1534 []>; 1535 1536 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits in { 1537 defm Pt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 0>; 1538 defm NotPt : ST_Idxd_Pred<mnemonic, RC, predImmOp, 1>; 1539 } 1540 } 1541} 1542 1543let addrMode = BaseImmOffset, InputType = "reg" in { 1544 defm STrib_indexed: ST_Idxd < "memb", "STrib", IntRegs, s11_0Ext, 1545 u6_0Ext, 11, 6>, AddrModeRel, ImmRegRel; 1546 defm STrih_indexed: ST_Idxd < "memh", "STrih", IntRegs, s11_1Ext, 1547 u6_1Ext, 12, 7>, AddrModeRel, ImmRegRel; 1548 defm STriw_indexed: ST_Idxd < "memw", "STriw", IntRegs, s11_2Ext, 1549 u6_2Ext, 13, 8>, AddrModeRel, ImmRegRel; 1550 let isNVStorable = 0 in 1551 defm STrid_indexed: ST_Idxd < "memd", "STrid", DoubleRegs, s11_3Ext, 1552 u6_3Ext, 14, 9>, AddrModeRel; 1553} 1554 1555let AddedComplexity = 10 in { 1556def : Pat<(truncstorei8 (i32 IntRegs:$src1), (add IntRegs:$src2, 1557 s11_0ExtPred:$offset)), 1558 (STrib_indexed IntRegs:$src2, s11_0ImmPred:$offset, 1559 (i32 IntRegs:$src1))>; 1560 1561def : Pat<(truncstorei16 (i32 IntRegs:$src1), (add IntRegs:$src2, 1562 s11_1ExtPred:$offset)), 1563 (STrih_indexed IntRegs:$src2, s11_1ImmPred:$offset, 1564 (i32 IntRegs:$src1))>; 1565 1566def : Pat<(store (i32 IntRegs:$src1), (add IntRegs:$src2, 1567 s11_2ExtPred:$offset)), 1568 (STriw_indexed IntRegs:$src2, s11_2ImmPred:$offset, 1569 (i32 IntRegs:$src1))>; 1570 1571def : Pat<(store (i64 DoubleRegs:$src1), (add IntRegs:$src2, 1572 s11_3ExtPred:$offset)), 1573 (STrid_indexed IntRegs:$src2, s11_3ImmPred:$offset, 1574 (i64 DoubleRegs:$src1))>; 1575} 1576 1577// memh(Rx++#s4:1)=Rt.H 1578 1579// Store word. 1580// Store predicate. 1581let Defs = [R10,R11,D5], neverHasSideEffects = 1 in 1582def STriw_pred : STInst2<(outs), 1583 (ins MEMri:$addr, PredRegs:$src1), 1584 "Error; should not emit", 1585 []>; 1586 1587// Allocate stack frame. 1588let Defs = [R29, R30], Uses = [R31, R30], neverHasSideEffects = 1 in { 1589 def ALLOCFRAME : STInst2<(outs), 1590 (ins i32imm:$amt), 1591 "allocframe(#$amt)", 1592 []>; 1593} 1594//===----------------------------------------------------------------------===// 1595// ST - 1596//===----------------------------------------------------------------------===// 1597 1598//===----------------------------------------------------------------------===// 1599// STYPE/ALU + 1600//===----------------------------------------------------------------------===// 1601// Logical NOT. 1602def NOT_rr64 : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1), 1603 "$dst = not($src1)", 1604 [(set (i64 DoubleRegs:$dst), (not (i64 DoubleRegs:$src1)))]>; 1605 1606 1607// Sign extend word to doubleword. 1608def SXTW : ALU64_rr<(outs DoubleRegs:$dst), (ins IntRegs:$src1), 1609 "$dst = sxtw($src1)", 1610 [(set (i64 DoubleRegs:$dst), (sext (i32 IntRegs:$src1)))]>; 1611//===----------------------------------------------------------------------===// 1612// STYPE/ALU - 1613//===----------------------------------------------------------------------===// 1614 1615//===----------------------------------------------------------------------===// 1616// STYPE/BIT + 1617//===----------------------------------------------------------------------===// 1618// clrbit. 1619def CLRBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1620 "$dst = clrbit($src1, #$src2)", 1621 [(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1), 1622 (not 1623 (shl 1, u5ImmPred:$src2))))]>; 1624 1625def CLRBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1626 "$dst = clrbit($src1, #$src2)", 1627 []>; 1628 1629// Map from r0 = and(r1, 2147483647) to r0 = clrbit(r1, #31). 1630def : Pat <(and (i32 IntRegs:$src1), 2147483647), 1631 (CLRBIT_31 (i32 IntRegs:$src1), 31)>; 1632 1633// setbit. 1634def SETBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1635 "$dst = setbit($src1, #$src2)", 1636 [(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1), 1637 (shl 1, u5ImmPred:$src2)))]>; 1638 1639// Map from r0 = or(r1, -2147483648) to r0 = setbit(r1, #31). 1640def SETBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1641 "$dst = setbit($src1, #$src2)", 1642 []>; 1643 1644def : Pat <(or (i32 IntRegs:$src1), -2147483648), 1645 (SETBIT_31 (i32 IntRegs:$src1), 31)>; 1646 1647// togglebit. 1648def TOGBIT : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1649 "$dst = setbit($src1, #$src2)", 1650 [(set (i32 IntRegs:$dst), (xor (i32 IntRegs:$src1), 1651 (shl 1, u5ImmPred:$src2)))]>; 1652 1653// Map from r0 = xor(r1, -2147483648) to r0 = togglebit(r1, #31). 1654def TOGBIT_31 : ALU64_rr<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1655 "$dst = togglebit($src1, #$src2)", 1656 []>; 1657 1658def : Pat <(xor (i32 IntRegs:$src1), -2147483648), 1659 (TOGBIT_31 (i32 IntRegs:$src1), 31)>; 1660 1661// Predicate transfer. 1662let neverHasSideEffects = 1 in 1663def TFR_RsPd : SInst<(outs IntRegs:$dst), (ins PredRegs:$src1), 1664 "$dst = $src1 /* Should almost never emit this. */", 1665 []>; 1666 1667def TFR_PdRs : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1), 1668 "$dst = $src1 /* Should almost never emit this. */", 1669 [(set (i1 PredRegs:$dst), (trunc (i32 IntRegs:$src1)))]>; 1670//===----------------------------------------------------------------------===// 1671// STYPE/PRED - 1672//===----------------------------------------------------------------------===// 1673 1674//===----------------------------------------------------------------------===// 1675// STYPE/SHIFT + 1676//===----------------------------------------------------------------------===// 1677// Shift by immediate. 1678def ASR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1679 "$dst = asr($src1, #$src2)", 1680 [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1), 1681 u5ImmPred:$src2))]>; 1682 1683def ASRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1684 "$dst = asr($src1, #$src2)", 1685 [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1), 1686 u6ImmPred:$src2))]>; 1687 1688def ASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1689 "$dst = asl($src1, #$src2)", 1690 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1691 u5ImmPred:$src2))]>; 1692 1693def ASLd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1694 "$dst = asl($src1, #$src2)", 1695 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1696 u6ImmPred:$src2))]>; 1697 1698def LSR_ri : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 1699 "$dst = lsr($src1, #$src2)", 1700 [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1), 1701 u5ImmPred:$src2))]>; 1702 1703def LSRd_ri : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2), 1704 "$dst = lsr($src1, #$src2)", 1705 [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1), 1706 u6ImmPred:$src2))]>; 1707 1708// Shift by immediate and add. 1709let AddedComplexity = 100 in 1710def ADDASL : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2, 1711 u3Imm:$src3), 1712 "$dst = addasl($src1, $src2, #$src3)", 1713 [(set (i32 IntRegs:$dst), (add (i32 IntRegs:$src1), 1714 (shl (i32 IntRegs:$src2), 1715 u3ImmPred:$src3)))]>; 1716 1717// Shift by register. 1718def ASL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1719 "$dst = asl($src1, $src2)", 1720 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1721 (i32 IntRegs:$src2)))]>; 1722 1723def ASR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1724 "$dst = asr($src1, $src2)", 1725 [(set (i32 IntRegs:$dst), (sra (i32 IntRegs:$src1), 1726 (i32 IntRegs:$src2)))]>; 1727 1728def LSL_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1729 "$dst = lsl($src1, $src2)", 1730 [(set (i32 IntRegs:$dst), (shl (i32 IntRegs:$src1), 1731 (i32 IntRegs:$src2)))]>; 1732 1733def LSR_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1734 "$dst = lsr($src1, $src2)", 1735 [(set (i32 IntRegs:$dst), (srl (i32 IntRegs:$src1), 1736 (i32 IntRegs:$src2)))]>; 1737 1738def ASLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2), 1739 "$dst = asl($src1, $src2)", 1740 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1741 (i32 IntRegs:$src2)))]>; 1742 1743def LSLd : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, IntRegs:$src2), 1744 "$dst = lsl($src1, $src2)", 1745 [(set (i64 DoubleRegs:$dst), (shl (i64 DoubleRegs:$src1), 1746 (i32 IntRegs:$src2)))]>; 1747 1748def ASRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1749 IntRegs:$src2), 1750 "$dst = asr($src1, $src2)", 1751 [(set (i64 DoubleRegs:$dst), (sra (i64 DoubleRegs:$src1), 1752 (i32 IntRegs:$src2)))]>; 1753 1754def LSRd_rr : SInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, 1755 IntRegs:$src2), 1756 "$dst = lsr($src1, $src2)", 1757 [(set (i64 DoubleRegs:$dst), (srl (i64 DoubleRegs:$src1), 1758 (i32 IntRegs:$src2)))]>; 1759 1760//===----------------------------------------------------------------------===// 1761// STYPE/SHIFT - 1762//===----------------------------------------------------------------------===// 1763 1764//===----------------------------------------------------------------------===// 1765// STYPE/VH + 1766//===----------------------------------------------------------------------===// 1767//===----------------------------------------------------------------------===// 1768// STYPE/VH - 1769//===----------------------------------------------------------------------===// 1770 1771//===----------------------------------------------------------------------===// 1772// STYPE/VW + 1773//===----------------------------------------------------------------------===// 1774//===----------------------------------------------------------------------===// 1775// STYPE/VW - 1776//===----------------------------------------------------------------------===// 1777 1778//===----------------------------------------------------------------------===// 1779// SYSTEM/SUPER + 1780//===----------------------------------------------------------------------===// 1781 1782//===----------------------------------------------------------------------===// 1783// SYSTEM/USER + 1784//===----------------------------------------------------------------------===// 1785def SDHexagonBARRIER: SDTypeProfile<0, 0, []>; 1786def HexagonBARRIER: SDNode<"HexagonISD::BARRIER", SDHexagonBARRIER, 1787 [SDNPHasChain]>; 1788 1789let hasSideEffects = 1, isSolo = 1 in 1790def BARRIER : SYSInst<(outs), (ins), 1791 "barrier", 1792 [(HexagonBARRIER)]>; 1793 1794//===----------------------------------------------------------------------===// 1795// SYSTEM/SUPER - 1796//===----------------------------------------------------------------------===// 1797 1798// TFRI64 - assembly mapped. 1799let isReMaterializable = 1 in 1800def TFRI64 : ALU64_rr<(outs DoubleRegs:$dst), (ins s8Imm64:$src1), 1801 "$dst = #$src1", 1802 [(set (i64 DoubleRegs:$dst), s8Imm64Pred:$src1)]>; 1803 1804// Pseudo instruction to encode a set of conditional transfers. 1805// This instruction is used instead of a mux and trades-off codesize 1806// for performance. We conduct this transformation optimistically in 1807// the hope that these instructions get promoted to dot-new transfers. 1808let AddedComplexity = 100, isPredicated = 1 in 1809def TFR_condset_rr : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, 1810 IntRegs:$src2, 1811 IntRegs:$src3), 1812 "Error; should not emit", 1813 [(set (i32 IntRegs:$dst), 1814 (i32 (select (i1 PredRegs:$src1), 1815 (i32 IntRegs:$src2), 1816 (i32 IntRegs:$src3))))]>; 1817let AddedComplexity = 100, isPredicated = 1 in 1818def TFR_condset_ri : ALU32_rr<(outs IntRegs:$dst), 1819 (ins PredRegs:$src1, IntRegs:$src2, s12Imm:$src3), 1820 "Error; should not emit", 1821 [(set (i32 IntRegs:$dst), 1822 (i32 (select (i1 PredRegs:$src1), (i32 IntRegs:$src2), 1823 s12ImmPred:$src3)))]>; 1824 1825let AddedComplexity = 100, isPredicated = 1 in 1826def TFR_condset_ir : ALU32_rr<(outs IntRegs:$dst), 1827 (ins PredRegs:$src1, s12Imm:$src2, IntRegs:$src3), 1828 "Error; should not emit", 1829 [(set (i32 IntRegs:$dst), 1830 (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2, 1831 (i32 IntRegs:$src3))))]>; 1832 1833let AddedComplexity = 100, isPredicated = 1 in 1834def TFR_condset_ii : ALU32_rr<(outs IntRegs:$dst), 1835 (ins PredRegs:$src1, s12Imm:$src2, s12Imm:$src3), 1836 "Error; should not emit", 1837 [(set (i32 IntRegs:$dst), 1838 (i32 (select (i1 PredRegs:$src1), s12ImmPred:$src2, 1839 s12ImmPred:$src3)))]>; 1840 1841// Generate frameindex addresses. 1842let isReMaterializable = 1 in 1843def TFR_FI : ALU32_ri<(outs IntRegs:$dst), (ins FrameIndex:$src1), 1844 "$dst = add($src1)", 1845 [(set (i32 IntRegs:$dst), ADDRri:$src1)]>; 1846 1847// 1848// CR - Type. 1849// 1850let neverHasSideEffects = 1, Defs = [SA0, LC0] in { 1851def LOOP0_i : CRInst<(outs), (ins brtarget:$offset, u10Imm:$src2), 1852 "loop0($offset, #$src2)", 1853 []>; 1854} 1855 1856let neverHasSideEffects = 1, Defs = [SA0, LC0] in { 1857def LOOP0_r : CRInst<(outs), (ins brtarget:$offset, IntRegs:$src2), 1858 "loop0($offset, $src2)", 1859 []>; 1860} 1861 1862let isBranch = 1, isTerminator = 1, neverHasSideEffects = 1, 1863 Defs = [PC, LC0], Uses = [SA0, LC0] in { 1864def ENDLOOP0 : Endloop<(outs), (ins brtarget:$offset), 1865 ":endloop0", 1866 []>; 1867} 1868 1869// Support for generating global address. 1870// Taken from X86InstrInfo.td. 1871def SDTHexagonCONST32 : SDTypeProfile<1, 1, [ 1872 SDTCisVT<0, i32>, 1873 SDTCisVT<1, i32>, 1874 SDTCisPtrTy<0>]>; 1875def HexagonCONST32 : SDNode<"HexagonISD::CONST32", SDTHexagonCONST32>; 1876def HexagonCONST32_GP : SDNode<"HexagonISD::CONST32_GP", SDTHexagonCONST32>; 1877 1878// HI/LO Instructions 1879let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1880def LO : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global), 1881 "$dst.l = #LO($global)", 1882 []>; 1883 1884let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1885def HI : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global), 1886 "$dst.h = #HI($global)", 1887 []>; 1888 1889let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1890def LOi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value), 1891 "$dst.l = #LO($imm_value)", 1892 []>; 1893 1894 1895let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1896def HIi : ALU32_ri<(outs IntRegs:$dst), (ins i32imm:$imm_value), 1897 "$dst.h = #HI($imm_value)", 1898 []>; 1899 1900let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1901def LO_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1902 "$dst.l = #LO($jt)", 1903 []>; 1904 1905let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1906def HI_jt : ALU32_ri<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1907 "$dst.h = #HI($jt)", 1908 []>; 1909 1910 1911let isReMaterializable = 1, isMoveImm = 1, neverHasSideEffects = 1 in 1912def LO_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label), 1913 "$dst.l = #LO($label)", 1914 []>; 1915 1916let isReMaterializable = 1, isMoveImm = 1 , neverHasSideEffects = 1 in 1917def HI_label : ALU32_ri<(outs IntRegs:$dst), (ins bblabel:$label), 1918 "$dst.h = #HI($label)", 1919 []>; 1920 1921// This pattern is incorrect. When we add small data, we should change 1922// this pattern to use memw(#foo). 1923// This is for sdata. 1924let isMoveImm = 1 in 1925def CONST32 : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global), 1926 "$dst = CONST32(#$global)", 1927 [(set (i32 IntRegs:$dst), 1928 (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; 1929 1930// This is for non-sdata. 1931let isReMaterializable = 1, isMoveImm = 1 in 1932def CONST32_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), 1933 "$dst = CONST32(#$global)", 1934 [(set (i32 IntRegs:$dst), 1935 (HexagonCONST32 tglobaladdr:$global))]>; 1936 1937let isReMaterializable = 1, isMoveImm = 1 in 1938def CONST32_set_jt : LDInst2<(outs IntRegs:$dst), (ins jumptablebase:$jt), 1939 "$dst = CONST32(#$jt)", 1940 [(set (i32 IntRegs:$dst), 1941 (HexagonCONST32 tjumptable:$jt))]>; 1942 1943let isReMaterializable = 1, isMoveImm = 1 in 1944def CONST32GP_set : LDInst2<(outs IntRegs:$dst), (ins globaladdress:$global), 1945 "$dst = CONST32(#$global)", 1946 [(set (i32 IntRegs:$dst), 1947 (HexagonCONST32_GP tglobaladdr:$global))]>; 1948 1949let isReMaterializable = 1, isMoveImm = 1 in 1950def CONST32_Int_Real : LDInst2<(outs IntRegs:$dst), (ins i32imm:$global), 1951 "$dst = CONST32(#$global)", 1952 [(set (i32 IntRegs:$dst), imm:$global) ]>; 1953 1954// Map BlockAddress lowering to CONST32_Int_Real 1955def : Pat<(HexagonCONST32_GP tblockaddress:$addr), 1956 (CONST32_Int_Real tblockaddress:$addr)>; 1957 1958let isReMaterializable = 1, isMoveImm = 1 in 1959def CONST32_Label : LDInst2<(outs IntRegs:$dst), (ins bblabel:$label), 1960 "$dst = CONST32($label)", 1961 [(set (i32 IntRegs:$dst), (HexagonCONST32 bbl:$label))]>; 1962 1963let isReMaterializable = 1, isMoveImm = 1 in 1964def CONST64_Int_Real : LDInst2<(outs DoubleRegs:$dst), (ins i64imm:$global), 1965 "$dst = CONST64(#$global)", 1966 [(set (i64 DoubleRegs:$dst), imm:$global) ]>; 1967 1968def TFR_PdFalse : SInst<(outs PredRegs:$dst), (ins), 1969 "$dst = xor($dst, $dst)", 1970 [(set (i1 PredRegs:$dst), 0)]>; 1971 1972def MPY_trsext : MInst<(outs IntRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 1973 "$dst = mpy($src1, $src2)", 1974 [(set (i32 IntRegs:$dst), 1975 (trunc (i64 (srl (i64 (mul (i64 (sext (i32 IntRegs:$src1))), 1976 (i64 (sext (i32 IntRegs:$src2))))), 1977 (i32 32)))))]>; 1978 1979// Pseudo instructions. 1980def SDT_SPCallSeqStart : SDCallSeqStart<[ SDTCisVT<0, i32> ]>; 1981 1982def SDT_SPCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, 1983 SDTCisVT<1, i32> ]>; 1984 1985def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPCallSeqEnd, 1986 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 1987 1988def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPCallSeqStart, 1989 [SDNPHasChain, SDNPOutGlue]>; 1990 1991def SDT_SPCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; 1992 1993def call : SDNode<"HexagonISD::CALL", SDT_SPCall, 1994 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; 1995 1996// For tailcalls a HexagonTCRet SDNode has 3 SDNode Properties - a chain, 1997// Optional Flag and Variable Arguments. 1998// Its 1 Operand has pointer type. 1999def HexagonTCRet : SDNode<"HexagonISD::TC_RETURN", SDT_SPCall, 2000 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 2001 2002let Defs = [R29, R30], Uses = [R31, R30, R29] in { 2003 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt), 2004 "Should never be emitted", 2005 [(callseq_start timm:$amt)]>; 2006} 2007 2008let Defs = [R29, R30, R31], Uses = [R29] in { 2009 def ADJCALLSTACKUP : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2), 2010 "Should never be emitted", 2011 [(callseq_end timm:$amt1, timm:$amt2)]>; 2012} 2013// Call subroutine. 2014let isCall = 1, neverHasSideEffects = 1, 2015 Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, 2016 R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in { 2017 def CALL : JInst<(outs), (ins calltarget:$dst), 2018 "call $dst", []>; 2019} 2020 2021// Call subroutine from register. 2022let isCall = 1, neverHasSideEffects = 1, 2023 Defs = [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, 2024 R22, R23, R28, R31, P0, P1, P2, P3, LC0, LC1, SA0, SA1] in { 2025 def CALLR : JRInst<(outs), (ins IntRegs:$dst), 2026 "callr $dst", 2027 []>; 2028 } 2029 2030 2031// Indirect tail-call. 2032let isCodeGenOnly = 1, isCall = 1, isReturn = 1 in 2033def TCRETURNR : T_JMPr; 2034 2035// Direct tail-calls. 2036let isCall = 1, isReturn = 1, isBarrier = 1, isPredicable = 0, 2037isTerminator = 1, isCodeGenOnly = 1 in { 2038 def TCRETURNtg : T_JMP<(ins calltarget:$dst)>; 2039 def TCRETURNtext : T_JMP<(ins calltarget:$dst)>; 2040} 2041 2042// Map call instruction. 2043def : Pat<(call (i32 IntRegs:$dst)), 2044 (CALLR (i32 IntRegs:$dst))>, Requires<[HasV2TOnly]>; 2045def : Pat<(call tglobaladdr:$dst), 2046 (CALL tglobaladdr:$dst)>, Requires<[HasV2TOnly]>; 2047def : Pat<(call texternalsym:$dst), 2048 (CALL texternalsym:$dst)>, Requires<[HasV2TOnly]>; 2049//Tail calls. 2050def : Pat<(HexagonTCRet tglobaladdr:$dst), 2051 (TCRETURNtg tglobaladdr:$dst)>; 2052def : Pat<(HexagonTCRet texternalsym:$dst), 2053 (TCRETURNtext texternalsym:$dst)>; 2054def : Pat<(HexagonTCRet (i32 IntRegs:$dst)), 2055 (TCRETURNR (i32 IntRegs:$dst))>; 2056 2057// Atomic load and store support 2058// 8 bit atomic load 2059def : Pat<(atomic_load_8 ADDRriS11_0:$src1), 2060 (i32 (LDriub ADDRriS11_0:$src1))>; 2061 2062def : Pat<(atomic_load_8 (add (i32 IntRegs:$src1), s11_0ImmPred:$offset)), 2063 (i32 (LDriub_indexed (i32 IntRegs:$src1), s11_0ImmPred:$offset))>; 2064 2065// 16 bit atomic load 2066def : Pat<(atomic_load_16 ADDRriS11_1:$src1), 2067 (i32 (LDriuh ADDRriS11_1:$src1))>; 2068 2069def : Pat<(atomic_load_16 (add (i32 IntRegs:$src1), s11_1ImmPred:$offset)), 2070 (i32 (LDriuh_indexed (i32 IntRegs:$src1), s11_1ImmPred:$offset))>; 2071 2072def : Pat<(atomic_load_32 ADDRriS11_2:$src1), 2073 (i32 (LDriw ADDRriS11_2:$src1))>; 2074 2075def : Pat<(atomic_load_32 (add (i32 IntRegs:$src1), s11_2ImmPred:$offset)), 2076 (i32 (LDriw_indexed (i32 IntRegs:$src1), s11_2ImmPred:$offset))>; 2077 2078// 64 bit atomic load 2079def : Pat<(atomic_load_64 ADDRriS11_3:$src1), 2080 (i64 (LDrid ADDRriS11_3:$src1))>; 2081 2082def : Pat<(atomic_load_64 (add (i32 IntRegs:$src1), s11_3ImmPred:$offset)), 2083 (i64 (LDrid_indexed (i32 IntRegs:$src1), s11_3ImmPred:$offset))>; 2084 2085 2086def : Pat<(atomic_store_8 ADDRriS11_0:$src2, (i32 IntRegs:$src1)), 2087 (STrib ADDRriS11_0:$src2, (i32 IntRegs:$src1))>; 2088 2089def : Pat<(atomic_store_8 (add (i32 IntRegs:$src2), s11_0ImmPred:$offset), 2090 (i32 IntRegs:$src1)), 2091 (STrib_indexed (i32 IntRegs:$src2), s11_0ImmPred:$offset, 2092 (i32 IntRegs:$src1))>; 2093 2094 2095def : Pat<(atomic_store_16 ADDRriS11_1:$src2, (i32 IntRegs:$src1)), 2096 (STrih ADDRriS11_1:$src2, (i32 IntRegs:$src1))>; 2097 2098def : Pat<(atomic_store_16 (i32 IntRegs:$src1), 2099 (add (i32 IntRegs:$src2), s11_1ImmPred:$offset)), 2100 (STrih_indexed (i32 IntRegs:$src2), s11_1ImmPred:$offset, 2101 (i32 IntRegs:$src1))>; 2102 2103def : Pat<(atomic_store_32 ADDRriS11_2:$src2, (i32 IntRegs:$src1)), 2104 (STriw ADDRriS11_2:$src2, (i32 IntRegs:$src1))>; 2105 2106def : Pat<(atomic_store_32 (add (i32 IntRegs:$src2), s11_2ImmPred:$offset), 2107 (i32 IntRegs:$src1)), 2108 (STriw_indexed (i32 IntRegs:$src2), s11_2ImmPred:$offset, 2109 (i32 IntRegs:$src1))>; 2110 2111 2112 2113 2114def : Pat<(atomic_store_64 ADDRriS11_3:$src2, (i64 DoubleRegs:$src1)), 2115 (STrid ADDRriS11_3:$src2, (i64 DoubleRegs:$src1))>; 2116 2117def : Pat<(atomic_store_64 (add (i32 IntRegs:$src2), s11_3ImmPred:$offset), 2118 (i64 DoubleRegs:$src1)), 2119 (STrid_indexed (i32 IntRegs:$src2), s11_3ImmPred:$offset, 2120 (i64 DoubleRegs:$src1))>; 2121 2122// Map from r0 = and(r1, 65535) to r0 = zxth(r1) 2123def : Pat <(and (i32 IntRegs:$src1), 65535), 2124 (ZXTH (i32 IntRegs:$src1))>; 2125 2126// Map from r0 = and(r1, 255) to r0 = zxtb(r1). 2127def : Pat <(and (i32 IntRegs:$src1), 255), 2128 (ZXTB (i32 IntRegs:$src1))>; 2129 2130// Map Add(p1, true) to p1 = not(p1). 2131// Add(p1, false) should never be produced, 2132// if it does, it got to be mapped to NOOP. 2133def : Pat <(add (i1 PredRegs:$src1), -1), 2134 (NOT_p (i1 PredRegs:$src1))>; 2135 2136// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) => 2137// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1). 2138// cmp.lt(r0, r1) -> cmp.gt(r1, r0) 2139def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2140 (i32 IntRegs:$src3), 2141 (i32 IntRegs:$src4)), 2142 (i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), 2143 (i32 IntRegs:$src4), (i32 IntRegs:$src3)))>, 2144 Requires<[HasV2TOnly]>; 2145 2146// Map from p0 = pnot(p0); r0 = mux(p0, #i, #j) => r0 = mux(p0, #j, #i). 2147def : Pat <(select (not (i1 PredRegs:$src1)), s8ImmPred:$src2, s8ImmPred:$src3), 2148 (i32 (TFR_condset_ii (i1 PredRegs:$src1), s8ImmPred:$src3, 2149 s8ImmPred:$src2))>; 2150 2151// Map from p0 = pnot(p0); r0 = select(p0, #i, r1) 2152// => r0 = TFR_condset_ri(p0, r1, #i) 2153def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2, 2154 (i32 IntRegs:$src3)), 2155 (i32 (TFR_condset_ri (i1 PredRegs:$src1), (i32 IntRegs:$src3), 2156 s12ImmPred:$src2))>; 2157 2158// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) 2159// => r0 = TFR_condset_ir(p0, #i, r1) 2160def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3), 2161 (i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3, 2162 (i32 IntRegs:$src2)))>; 2163 2164// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump. 2165def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset), 2166 (JMP_f (i1 PredRegs:$src1), bb:$offset)>; 2167 2168// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2). 2169def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))), 2170 (i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>; 2171 2172 2173let AddedComplexity = 100 in 2174def : Pat <(i64 (zextloadi1 (HexagonCONST32 tglobaladdr:$global))), 2175 (i64 (COMBINE_rr (TFRI 0), 2176 (LDriub_indexed (CONST32_set tglobaladdr:$global), 0)))>, 2177 Requires<[NoV4T]>; 2178 2179// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned. 2180let AddedComplexity = 10 in 2181def : Pat <(i32 (zextloadi1 ADDRriS11_0:$addr)), 2182 (i32 (AND_rr (i32 (LDrib ADDRriS11_0:$addr)), (TFRI 0x1)))>; 2183 2184// Map from Rdd = sign_extend_inreg(Rss, i32) -> Rdd = SXTW(Rss.lo). 2185def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i32)), 2186 (i64 (SXTW (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg))))>; 2187 2188// Map from Rdd = sign_extend_inreg(Rss, i16) -> Rdd = SXTW(SXTH(Rss.lo)). 2189def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i16)), 2190 (i64 (SXTW (i32 (SXTH (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2191 subreg_loreg))))))>; 2192 2193// Map from Rdd = sign_extend_inreg(Rss, i8) -> Rdd = SXTW(SXTB(Rss.lo)). 2194def : Pat <(i64 (sext_inreg (i64 DoubleRegs:$src1), i8)), 2195 (i64 (SXTW (i32 (SXTB (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2196 subreg_loreg))))))>; 2197 2198// We want to prevent emitting pnot's as much as possible. 2199// Map brcond with an unsupported setcc to a JMP_f. 2200def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2201 bb:$offset), 2202 (JMP_f (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), 2203 bb:$offset)>; 2204 2205def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)), 2206 bb:$offset), 2207 (JMP_f (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2), bb:$offset)>; 2208 2209def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset), 2210 (JMP_f (i1 PredRegs:$src1), bb:$offset)>; 2211 2212def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset), 2213 (JMP_t (i1 PredRegs:$src1), bb:$offset)>; 2214 2215// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1) 2216def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)), 2217 bb:$offset), 2218 (JMP_f (CMPGTri (i32 IntRegs:$src1), 2219 (DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>; 2220 2221// cmp.lt(r0, r1) -> cmp.gt(r1, r0) 2222def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2223 bb:$offset), 2224 (JMP_t (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>; 2225 2226def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2227 bb:$offset), 2228 (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)), 2229 bb:$offset)>; 2230 2231def : Pat <(brcond (i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2232 bb:$offset), 2233 (JMP_f (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), 2234 bb:$offset)>; 2235 2236def : Pat <(brcond (i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2237 bb:$offset), 2238 (JMP_f (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2239 bb:$offset)>; 2240 2241// Map from a 64-bit select to an emulated 64-bit mux. 2242// Hexagon does not support 64-bit MUXes; so emulate with combines. 2243def : Pat <(select (i1 PredRegs:$src1), (i64 DoubleRegs:$src2), 2244 (i64 DoubleRegs:$src3)), 2245 (i64 (COMBINE_rr (i32 (MUX_rr (i1 PredRegs:$src1), 2246 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2247 subreg_hireg)), 2248 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), 2249 subreg_hireg)))), 2250 (i32 (MUX_rr (i1 PredRegs:$src1), 2251 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2252 subreg_loreg)), 2253 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src3), 2254 subreg_loreg))))))>; 2255 2256// Map from a 1-bit select to logical ops. 2257// From LegalizeDAG.cpp: (B1 ? B2 : B3) <=> (B1 & B2)|(!B1&B3). 2258def : Pat <(select (i1 PredRegs:$src1), (i1 PredRegs:$src2), 2259 (i1 PredRegs:$src3)), 2260 (OR_pp (AND_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)), 2261 (AND_pp (NOT_p (i1 PredRegs:$src1)), (i1 PredRegs:$src3)))>; 2262 2263// Map Pd = load(addr) -> Rs = load(addr); Pd = Rs. 2264def : Pat<(i1 (load ADDRriS11_2:$addr)), 2265 (i1 (TFR_PdRs (i32 (LDrib ADDRriS11_2:$addr))))>; 2266 2267// Map for truncating from 64 immediates to 32 bit immediates. 2268def : Pat<(i32 (trunc (i64 DoubleRegs:$src))), 2269 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), subreg_loreg))>; 2270 2271// Map for truncating from i64 immediates to i1 bit immediates. 2272def : Pat<(i1 (trunc (i64 DoubleRegs:$src))), 2273 (i1 (TFR_PdRs (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2274 subreg_loreg))))>; 2275 2276// Map memb(Rs) = Rdd -> memb(Rs) = Rt. 2277def : Pat<(truncstorei8 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2278 (STrib ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2279 subreg_loreg)))>; 2280 2281// Map memh(Rs) = Rdd -> memh(Rs) = Rt. 2282def : Pat<(truncstorei16 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2283 (STrih ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2284 subreg_loreg)))>; 2285// Map memw(Rs) = Rdd -> memw(Rs) = Rt 2286def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2287 (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2288 subreg_loreg)))>; 2289 2290// Map memw(Rs) = Rdd -> memw(Rs) = Rt. 2291def : Pat<(truncstorei32 (i64 DoubleRegs:$src), ADDRriS11_0:$addr), 2292 (STriw ADDRriS11_0:$addr, (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src), 2293 subreg_loreg)))>; 2294 2295// Map from i1 = constant<-1>; memw(addr) = i1 -> r0 = 1; memw(addr) = r0. 2296def : Pat<(store (i1 -1), ADDRriS11_2:$addr), 2297 (STrib ADDRriS11_2:$addr, (TFRI 1))>; 2298 2299 2300// Map from i1 = constant<-1>; store i1 -> r0 = 1; store r0. 2301def : Pat<(store (i1 -1), ADDRriS11_2:$addr), 2302 (STrib ADDRriS11_2:$addr, (TFRI 1))>; 2303 2304// Map from memb(Rs) = Pd -> Rt = mux(Pd, #0, #1); store Rt. 2305def : Pat<(store (i1 PredRegs:$src1), ADDRriS11_2:$addr), 2306 (STrib ADDRriS11_2:$addr, (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0)) )>; 2307 2308// Map Rdd = anyext(Rs) -> Rdd = sxtw(Rs). 2309// Hexagon_TODO: We can probably use combine but that will cost 2 instructions. 2310// Better way to do this? 2311def : Pat<(i64 (anyext (i32 IntRegs:$src1))), 2312 (i64 (SXTW (i32 IntRegs:$src1)))>; 2313 2314// Map cmple -> cmpgt. 2315// rs <= rt -> !(rs > rt). 2316def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)), 2317 (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>; 2318 2319// rs <= rt -> !(rs > rt). 2320def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2321 (i1 (NOT_p (CMPGTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>; 2322 2323// Rss <= Rtt -> !(Rss > Rtt). 2324def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2325 (i1 (NOT_p (CMPGT64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>; 2326 2327// Map cmpne -> cmpeq. 2328// Hexagon_TODO: We should improve on this. 2329// rs != rt -> !(rs == rt). 2330def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)), 2331 (i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>; 2332 2333// Map cmpne(Rs) -> !cmpeqe(Rs). 2334// rs != rt -> !(rs == rt). 2335def : Pat <(i1 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2336 (i1 (NOT_p (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)))))>; 2337 2338// Convert setne back to xor for hexagon since we compute w/ pred registers. 2339def : Pat <(i1 (setne (i1 PredRegs:$src1), (i1 PredRegs:$src2))), 2340 (i1 (XOR_pp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>; 2341 2342// Map cmpne(Rss) -> !cmpew(Rss). 2343// rs != rt -> !(rs == rt). 2344def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2345 (i1 (NOT_p (i1 (CMPEHexagon4rr (i64 DoubleRegs:$src1), 2346 (i64 DoubleRegs:$src2)))))>; 2347 2348// Map cmpge(Rs, Rt) -> !(cmpgt(Rs, Rt). 2349// rs >= rt -> !(rt > rs). 2350def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2351 (i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>; 2352 2353// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1) 2354def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)), 2355 (i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>; 2356 2357// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss). 2358// rss >= rtt -> !(rtt > rss). 2359def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2360 (i1 (NOT_p (i1 (CMPGT64rr (i64 DoubleRegs:$src2), 2361 (i64 DoubleRegs:$src1)))))>; 2362 2363// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm). 2364// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1). 2365// rs < rt -> !(rs >= rt). 2366def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)), 2367 (i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>; 2368 2369// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs). 2370// rs < rt -> rt > rs. 2371// We can let assembler map it, or we can do in the compiler itself. 2372def : Pat <(i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2373 (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>; 2374 2375// Map cmplt(Rss, Rtt) -> cmpgt(Rtt, Rss). 2376// rss < rtt -> (rtt > rss). 2377def : Pat <(i1 (setlt (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2378 (i1 (CMPGT64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>; 2379 2380// Map from cmpltu(Rs, Rd) -> cmpgtu(Rd, Rs) 2381// rs < rt -> rt > rs. 2382// We can let assembler map it, or we can do in the compiler itself. 2383def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2384 (i1 (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))>; 2385 2386// Map from cmpltu(Rss, Rdd) -> cmpgtu(Rdd, Rss). 2387// rs < rt -> rt > rs. 2388def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2389 (i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>; 2390 2391// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs) 2392def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)), 2393 (i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>; 2394 2395// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1) 2396def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)), 2397 (i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>; 2398 2399// Generate cmpgtu(Rs, #u9) 2400def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)), 2401 (i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>; 2402 2403// Map from Rs >= Rt -> !(Rt > Rs). 2404// rs >= rt -> !(rt > rs). 2405def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2406 (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src2), (i32 IntRegs:$src1))))>; 2407 2408// Map from Rs >= Rt -> !(Rt > Rs). 2409// rs >= rt -> !(rt > rs). 2410def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2411 (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>; 2412 2413// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt). 2414// Map from (Rs <= Rt) -> !(Rs > Rt). 2415def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 2416 (i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>; 2417 2418// Map from cmpleu(Rss, Rtt) -> !cmpgtu(Rss, Rtt-1). 2419// Map from (Rs <= Rt) -> !(Rs > Rt). 2420def : Pat <(i1 (setule (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))), 2421 (i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))))>; 2422 2423// Sign extends. 2424// i1 -> i32 2425def : Pat <(i32 (sext (i1 PredRegs:$src1))), 2426 (i32 (MUX_ii (i1 PredRegs:$src1), -1, 0))>; 2427 2428// i1 -> i64 2429def : Pat <(i64 (sext (i1 PredRegs:$src1))), 2430 (i64 (COMBINE_rr (TFRI -1), (MUX_ii (i1 PredRegs:$src1), -1, 0)))>; 2431 2432// Convert sign-extended load back to load and sign extend. 2433// i8 -> i64 2434def: Pat <(i64 (sextloadi8 ADDRriS11_0:$src1)), 2435 (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>; 2436 2437// Convert any-extended load back to load and sign extend. 2438// i8 -> i64 2439def: Pat <(i64 (extloadi8 ADDRriS11_0:$src1)), 2440 (i64 (SXTW (LDrib ADDRriS11_0:$src1)))>; 2441 2442// Convert sign-extended load back to load and sign extend. 2443// i16 -> i64 2444def: Pat <(i64 (sextloadi16 ADDRriS11_1:$src1)), 2445 (i64 (SXTW (LDrih ADDRriS11_1:$src1)))>; 2446 2447// Convert sign-extended load back to load and sign extend. 2448// i32 -> i64 2449def: Pat <(i64 (sextloadi32 ADDRriS11_2:$src1)), 2450 (i64 (SXTW (LDriw ADDRriS11_2:$src1)))>; 2451 2452 2453// Zero extends. 2454// i1 -> i32 2455def : Pat <(i32 (zext (i1 PredRegs:$src1))), 2456 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2457 2458// i1 -> i64 2459def : Pat <(i64 (zext (i1 PredRegs:$src1))), 2460 (i64 (COMBINE_rr (TFRI 0), (MUX_ii (i1 PredRegs:$src1), 1, 0)))>, 2461 Requires<[NoV4T]>; 2462 2463// i32 -> i64 2464def : Pat <(i64 (zext (i32 IntRegs:$src1))), 2465 (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>, 2466 Requires<[NoV4T]>; 2467 2468// i8 -> i64 2469def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)), 2470 (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>, 2471 Requires<[NoV4T]>; 2472 2473let AddedComplexity = 20 in 2474def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1), 2475 s11_0ExtPred:$offset))), 2476 (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1, 2477 s11_0ExtPred:$offset)))>, 2478 Requires<[NoV4T]>; 2479 2480// i1 -> i64 2481def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)), 2482 (i64 (COMBINE_rr (TFRI 0), (LDriub ADDRriS11_0:$src1)))>, 2483 Requires<[NoV4T]>; 2484 2485let AddedComplexity = 20 in 2486def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1), 2487 s11_0ExtPred:$offset))), 2488 (i64 (COMBINE_rr (TFRI 0), (LDriub_indexed IntRegs:$src1, 2489 s11_0ExtPred:$offset)))>, 2490 Requires<[NoV4T]>; 2491 2492// i16 -> i64 2493def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)), 2494 (i64 (COMBINE_rr (TFRI 0), (LDriuh ADDRriS11_1:$src1)))>, 2495 Requires<[NoV4T]>; 2496 2497let AddedComplexity = 20 in 2498def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1), 2499 s11_1ExtPred:$offset))), 2500 (i64 (COMBINE_rr (TFRI 0), (LDriuh_indexed IntRegs:$src1, 2501 s11_1ExtPred:$offset)))>, 2502 Requires<[NoV4T]>; 2503 2504// i32 -> i64 2505def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)), 2506 (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>, 2507 Requires<[NoV4T]>; 2508 2509let AddedComplexity = 100 in 2510def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 2511 (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1, 2512 s11_2ExtPred:$offset)))>, 2513 Requires<[NoV4T]>; 2514 2515let AddedComplexity = 10 in 2516def: Pat <(i32 (zextloadi1 ADDRriS11_0:$src1)), 2517 (i32 (LDriw ADDRriS11_0:$src1))>; 2518 2519// Map from Rs = Pd to Pd = mux(Pd, #1, #0) 2520def : Pat <(i32 (zext (i1 PredRegs:$src1))), 2521 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2522 2523// Map from Rs = Pd to Pd = mux(Pd, #1, #0) 2524def : Pat <(i32 (anyext (i1 PredRegs:$src1))), 2525 (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))>; 2526 2527// Map from Rss = Pd to Rdd = sxtw (mux(Pd, #1, #0)) 2528def : Pat <(i64 (anyext (i1 PredRegs:$src1))), 2529 (i64 (SXTW (i32 (MUX_ii (i1 PredRegs:$src1), 1, 0))))>; 2530 2531 2532let AddedComplexity = 100 in 2533def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2534 (i32 32))), 2535 (i64 (zextloadi32 (i32 (add IntRegs:$src2, 2536 s11_2ExtPred:$offset2)))))), 2537 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2538 (LDriw_indexed IntRegs:$src2, 2539 s11_2ExtPred:$offset2)))>; 2540 2541def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2542 (i32 32))), 2543 (i64 (zextloadi32 ADDRriS11_2:$srcLow)))), 2544 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2545 (LDriw ADDRriS11_2:$srcLow)))>; 2546 2547def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2548 (i32 32))), 2549 (i64 (zext (i32 IntRegs:$srcLow))))), 2550 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2551 IntRegs:$srcLow))>; 2552 2553let AddedComplexity = 100 in 2554def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2555 (i32 32))), 2556 (i64 (zextloadi32 (i32 (add IntRegs:$src2, 2557 s11_2ExtPred:$offset2)))))), 2558 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2559 (LDriw_indexed IntRegs:$src2, 2560 s11_2ExtPred:$offset2)))>; 2561 2562def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2563 (i32 32))), 2564 (i64 (zextloadi32 ADDRriS11_2:$srcLow)))), 2565 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2566 (LDriw ADDRriS11_2:$srcLow)))>; 2567 2568def: Pat<(i64 (or (i64 (shl (i64 DoubleRegs:$srcHigh), 2569 (i32 32))), 2570 (i64 (zext (i32 IntRegs:$srcLow))))), 2571 (i64 (COMBINE_rr (EXTRACT_SUBREG (i64 DoubleRegs:$srcHigh), subreg_loreg), 2572 IntRegs:$srcLow))>; 2573 2574// Any extended 64-bit load. 2575// anyext i32 -> i64 2576def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)), 2577 (i64 (COMBINE_rr (TFRI 0), (LDriw ADDRriS11_2:$src1)))>, 2578 Requires<[NoV4T]>; 2579 2580// When there is an offset we should prefer the pattern below over the pattern above. 2581// The complexity of the above is 13 (gleaned from HexagonGenDAGIsel.inc) 2582// So this complexity below is comfortably higher to allow for choosing the below. 2583// If this is not done then we generate addresses such as 2584// ******************************************** 2585// r1 = add (r0, #4) 2586// r1 = memw(r1 + #0) 2587// instead of 2588// r1 = memw(r0 + #4) 2589// ******************************************** 2590let AddedComplexity = 100 in 2591def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 2592 (i64 (COMBINE_rr (TFRI 0), (LDriw_indexed IntRegs:$src1, 2593 s11_2ExtPred:$offset)))>, 2594 Requires<[NoV4T]>; 2595 2596// anyext i16 -> i64. 2597def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)), 2598 (i64 (COMBINE_rr (TFRI 0), (LDrih ADDRriS11_2:$src1)))>, 2599 Requires<[NoV4T]>; 2600 2601let AddedComplexity = 20 in 2602def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1), 2603 s11_1ExtPred:$offset))), 2604 (i64 (COMBINE_rr (TFRI 0), (LDrih_indexed IntRegs:$src1, 2605 s11_1ExtPred:$offset)))>, 2606 Requires<[NoV4T]>; 2607 2608// Map from Rdd = zxtw(Rs) -> Rdd = combine(0, Rs). 2609def : Pat<(i64 (zext (i32 IntRegs:$src1))), 2610 (i64 (COMBINE_rr (TFRI 0), (i32 IntRegs:$src1)))>, 2611 Requires<[NoV4T]>; 2612 2613// Multiply 64-bit unsigned and use upper result. 2614def : Pat <(mulhu (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2615 (i64 2616 (MPYU64_acc 2617 (i64 2618 (COMBINE_rr 2619 (TFRI 0), 2620 (i32 2621 (EXTRACT_SUBREG 2622 (i64 2623 (LSRd_ri 2624 (i64 2625 (MPYU64_acc 2626 (i64 2627 (MPYU64_acc 2628 (i64 2629 (COMBINE_rr (TFRI 0), 2630 (i32 2631 (EXTRACT_SUBREG 2632 (i64 2633 (LSRd_ri 2634 (i64 2635 (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2636 subreg_loreg)), 2637 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2638 subreg_loreg)))), 32)), 2639 subreg_loreg)))), 2640 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2641 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))), 2642 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)), 2643 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))), 2644 32)), subreg_loreg)))), 2645 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2646 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>; 2647 2648// Multiply 64-bit signed and use upper result. 2649def : Pat <(mulhs (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2)), 2650 (i64 2651 (MPY64_acc 2652 (i64 2653 (COMBINE_rr (TFRI 0), 2654 (i32 2655 (EXTRACT_SUBREG 2656 (i64 2657 (LSRd_ri 2658 (i64 2659 (MPY64_acc 2660 (i64 2661 (MPY64_acc 2662 (i64 2663 (COMBINE_rr (TFRI 0), 2664 (i32 2665 (EXTRACT_SUBREG 2666 (i64 2667 (LSRd_ri 2668 (i64 2669 (MPYU64 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), 2670 subreg_loreg)), 2671 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), 2672 subreg_loreg)))), 32)), 2673 subreg_loreg)))), 2674 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2675 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_loreg)))), 2676 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_loreg)), 2677 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg)))), 2678 32)), subreg_loreg)))), 2679 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src1), subreg_hireg)), 2680 (i32 (EXTRACT_SUBREG (i64 DoubleRegs:$src2), subreg_hireg))))>; 2681 2682// Hexagon specific ISD nodes. 2683//def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>]>; 2684def SDTHexagonADJDYNALLOC : SDTypeProfile<1, 2, 2685 [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 2686def Hexagon_ADJDYNALLOC : SDNode<"HexagonISD::ADJDYNALLOC", 2687 SDTHexagonADJDYNALLOC>; 2688// Needed to tag these instructions for stack layout. 2689let usesCustomInserter = 1 in 2690def ADJDYNALLOC : ALU32_ri<(outs IntRegs:$dst), (ins IntRegs:$src1, 2691 s16Imm:$src2), 2692 "$dst = add($src1, #$src2)", 2693 [(set (i32 IntRegs:$dst), 2694 (Hexagon_ADJDYNALLOC (i32 IntRegs:$src1), 2695 s16ImmPred:$src2))]>; 2696 2697def SDTHexagonARGEXTEND : SDTypeProfile<1, 1, [SDTCisVT<0, i32>]>; 2698def Hexagon_ARGEXTEND : SDNode<"HexagonISD::ARGEXTEND", SDTHexagonARGEXTEND>; 2699def ARGEXTEND : ALU32_rr <(outs IntRegs:$dst), (ins IntRegs:$src1), 2700 "$dst = $src1", 2701 [(set (i32 IntRegs:$dst), 2702 (Hexagon_ARGEXTEND (i32 IntRegs:$src1)))]>; 2703 2704let AddedComplexity = 100 in 2705def : Pat<(i32 (sext_inreg (Hexagon_ARGEXTEND (i32 IntRegs:$src1)), i16)), 2706 (COPY (i32 IntRegs:$src1))>; 2707 2708def HexagonWrapperJT: SDNode<"HexagonISD::WrapperJT", SDTIntUnaryOp>; 2709 2710def : Pat<(HexagonWrapperJT tjumptable:$dst), 2711 (i32 (CONST32_set_jt tjumptable:$dst))>; 2712 2713// XTYPE/SHIFT 2714 2715// Multi-class for logical operators : 2716// Shift by immediate/register and accumulate/logical 2717multiclass xtype_imm<string OpcStr, SDNode OpNode1, SDNode OpNode2> { 2718 def _ri : SInst_acc<(outs IntRegs:$dst), 2719 (ins IntRegs:$src1, IntRegs:$src2, u5Imm:$src3), 2720 !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")), 2721 [(set (i32 IntRegs:$dst), 2722 (OpNode2 (i32 IntRegs:$src1), 2723 (OpNode1 (i32 IntRegs:$src2), 2724 u5ImmPred:$src3)))], 2725 "$src1 = $dst">; 2726 2727 def d_ri : SInst_acc<(outs DoubleRegs:$dst), 2728 (ins DoubleRegs:$src1, DoubleRegs:$src2, u6Imm:$src3), 2729 !strconcat("$dst ", !strconcat(OpcStr, "($src2, #$src3)")), 2730 [(set (i64 DoubleRegs:$dst), (OpNode2 (i64 DoubleRegs:$src1), 2731 (OpNode1 (i64 DoubleRegs:$src2), u6ImmPred:$src3)))], 2732 "$src1 = $dst">; 2733} 2734 2735// Multi-class for logical operators : 2736// Shift by register and accumulate/logical (32/64 bits) 2737multiclass xtype_reg<string OpcStr, SDNode OpNode1, SDNode OpNode2> { 2738 def _rr : SInst_acc<(outs IntRegs:$dst), 2739 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 2740 !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")), 2741 [(set (i32 IntRegs:$dst), 2742 (OpNode2 (i32 IntRegs:$src1), 2743 (OpNode1 (i32 IntRegs:$src2), 2744 (i32 IntRegs:$src3))))], 2745 "$src1 = $dst">; 2746 2747 def d_rr : SInst_acc<(outs DoubleRegs:$dst), 2748 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 2749 !strconcat("$dst ", !strconcat(OpcStr, "($src2, $src3)")), 2750 [(set (i64 DoubleRegs:$dst), 2751 (OpNode2 (i64 DoubleRegs:$src1), 2752 (OpNode1 (i64 DoubleRegs:$src2), 2753 (i32 IntRegs:$src3))))], 2754 "$src1 = $dst">; 2755 2756} 2757 2758multiclass basic_xtype_imm<string OpcStr, SDNode OpNode> { 2759let AddedComplexity = 100 in 2760 defm _ADD : xtype_imm< !strconcat("+= ", OpcStr), OpNode, add>; 2761 defm _SUB : xtype_imm< !strconcat("-= ", OpcStr), OpNode, sub>; 2762 defm _AND : xtype_imm< !strconcat("&= ", OpcStr), OpNode, and>; 2763 defm _OR : xtype_imm< !strconcat("|= ", OpcStr), OpNode, or>; 2764} 2765 2766multiclass basic_xtype_reg<string OpcStr, SDNode OpNode> { 2767let AddedComplexity = 100 in 2768 defm _ADD : xtype_reg< !strconcat("+= ", OpcStr), OpNode, add>; 2769 defm _SUB : xtype_reg< !strconcat("-= ", OpcStr), OpNode, sub>; 2770 defm _AND : xtype_reg< !strconcat("&= ", OpcStr), OpNode, and>; 2771 defm _OR : xtype_reg< !strconcat("|= ", OpcStr), OpNode, or>; 2772} 2773 2774multiclass xtype_xor_imm<string OpcStr, SDNode OpNode> { 2775let AddedComplexity = 100 in 2776 defm _XOR : xtype_imm< !strconcat("^= ", OpcStr), OpNode, xor>; 2777} 2778 2779defm ASL : basic_xtype_imm<"asl", shl>, basic_xtype_reg<"asl", shl>, 2780 xtype_xor_imm<"asl", shl>; 2781 2782defm LSR : basic_xtype_imm<"lsr", srl>, basic_xtype_reg<"lsr", srl>, 2783 xtype_xor_imm<"lsr", srl>; 2784 2785defm ASR : basic_xtype_imm<"asr", sra>, basic_xtype_reg<"asr", sra>; 2786defm LSL : basic_xtype_reg<"lsl", shl>; 2787 2788// Change the sign of the immediate for Rd=-mpyi(Rs,#u8) 2789def : Pat <(mul (i32 IntRegs:$src1), (ineg n8ImmPred:$src2)), 2790 (i32 (MPYI_rin (i32 IntRegs:$src1), u8ImmPred:$src2))>; 2791 2792//===----------------------------------------------------------------------===// 2793// V3 Instructions + 2794//===----------------------------------------------------------------------===// 2795 2796include "HexagonInstrInfoV3.td" 2797 2798//===----------------------------------------------------------------------===// 2799// V3 Instructions - 2800//===----------------------------------------------------------------------===// 2801 2802//===----------------------------------------------------------------------===// 2803// V4 Instructions + 2804//===----------------------------------------------------------------------===// 2805 2806include "HexagonInstrInfoV4.td" 2807 2808//===----------------------------------------------------------------------===// 2809// V4 Instructions - 2810//===----------------------------------------------------------------------===// 2811 2812//===----------------------------------------------------------------------===// 2813// V5 Instructions + 2814//===----------------------------------------------------------------------===// 2815 2816include "HexagonInstrInfoV5.td" 2817 2818//===----------------------------------------------------------------------===// 2819// V5 Instructions - 2820//===----------------------------------------------------------------------===// 2821