Home | History | Annotate | Download | only in Hexagon
      1 //=- HexagonInstrInfoV5.td - Target Desc. for Hexagon Target -*- tablegen -*-=//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the Hexagon V5 instructions in TableGen format.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 //===----------------------------------------------------------------------===//
     15 // XTYPE/MPY
     16 //===----------------------------------------------------------------------===//
     17 
     18   //Rdd[+]=vrmpybsu(Rss,Rtt)
     19 let Predicates = [HasV5T] in {
     20   def M5_vrmpybsu: T_XTYPE_Vect<"vrmpybsu", 0b110, 0b001, 0>;
     21   def M5_vrmacbsu: T_XTYPE_Vect_acc<"vrmpybsu", 0b110, 0b001, 0>;
     22 
     23   //Rdd[+]=vrmpybu(Rss,Rtt)
     24   def M5_vrmpybuu: T_XTYPE_Vect<"vrmpybu", 0b100, 0b001, 0>;
     25   def M5_vrmacbuu: T_XTYPE_Vect_acc<"vrmpybu", 0b100, 0b001, 0>;
     26 
     27   def M5_vdmpybsu: T_M2_vmpy<"vdmpybsu", 0b101, 0b001, 0, 0, 1>;
     28   def M5_vdmacbsu: T_M2_vmpy_acc_sat <"vdmpybsu", 0b001, 0b001, 0, 0>;
     29 }
     30 
     31 // Vector multiply bytes
     32 // Rdd=vmpyb[s]u(Rs,Rt)
     33 let Predicates = [HasV5T] in {
     34   def M5_vmpybsu: T_XTYPE_mpy64 <"vmpybsu", 0b010, 0b001, 0, 0, 0>;
     35   def M5_vmpybuu: T_XTYPE_mpy64 <"vmpybu",  0b100, 0b001, 0, 0, 0>;
     36 
     37   // Rxx+=vmpyb[s]u(Rs,Rt)
     38   def M5_vmacbsu: T_XTYPE_mpy64_acc <"vmpybsu", "+", 0b110, 0b001, 0, 0, 0>;
     39   def M5_vmacbuu: T_XTYPE_mpy64_acc <"vmpybu", "+", 0b100, 0b001, 0, 0, 0>;
     40 
     41   // Rd=vaddhub(Rss,Rtt):sat
     42   let hasNewValue = 1, opNewValue = 0 in
     43     def A5_vaddhubs: T_S3op_1 <"vaddhub", IntRegs, 0b01, 0b001, 0, 1>;
     44 }
     45 
     46 def S2_asr_i_p_rnd : S_2OpInstImm<"asr", 0b110, 0b111, u6Imm,
     47       [(set I64:$dst,
     48             (sra (i64 (add (i64 (sra I64:$src1, u6ImmPred:$src2)), 1)),
     49                  (i32 1)))], 1>,
     50       Requires<[HasV5T]> {
     51   bits<6> src2;
     52   let Inst{13-8} = src2;
     53 }
     54 
     55 let isAsmParserOnly = 1 in
     56 def S2_asr_i_p_rnd_goodsyntax
     57   : MInst<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1, u6Imm:$src2),
     58     "$dst = asrrnd($src1, #$src2)">;
     59 
     60 def C4_fastcorner9 : T_LOGICAL_2OP<"fastcorner9", 0b000, 0, 0>,
     61   Requires<[HasV5T]> {
     62   let Inst{13,7,4} = 0b111;
     63 }
     64 
     65 def C4_fastcorner9_not : T_LOGICAL_2OP<"!fastcorner9", 0b000, 0, 0>,
     66   Requires<[HasV5T]> {
     67   let Inst{20,13,7,4} = 0b1111;
     68 }
     69 
     70 def SDTHexagonFCONST32 : SDTypeProfile<1, 1, [SDTCisVT<0, f32>,
     71                                               SDTCisPtrTy<1>]>;
     72 def HexagonFCONST32 : SDNode<"HexagonISD::FCONST32", SDTHexagonFCONST32>;
     73 
     74 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
     75 def FCONST32_nsdata : LDInst<(outs IntRegs:$dst), (ins globaladdress:$global),
     76                              "$dst = CONST32(#$global)",
     77                              [(set F32:$dst,
     78                               (HexagonFCONST32 tglobaladdr:$global))]>,
     79                              Requires<[HasV5T]>;
     80 
     81 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
     82 def CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1),
     83                                 "$dst = CONST64(#$src1)",
     84                                 [(set F64:$dst, fpimm:$src1)]>,
     85                                 Requires<[HasV5T]>;
     86 
     87 let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in
     88 def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1),
     89                                 "$dst = CONST32(#$src1)",
     90                                 [(set F32:$dst, fpimm:$src1)]>,
     91                                 Requires<[HasV5T]>;
     92 
     93 // Transfer immediate float.
     94 // Only works with single precision fp value.
     95 // For double precision, use CONST64_float_real, as 64bit transfer
     96 // can only hold 40-bit values - 32 from const ext + 8 bit immediate.
     97 // Make sure that complexity is more than the CONST32 pattern in
     98 // HexagonInstrInfo.td patterns.
     99 let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1,
    100     isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT,
    101     isCodeGenOnly = 1 in
    102 def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1),
    103                       "$dst = #$src1",
    104                       [(set F32:$dst, fpimm:$src1)]>,
    105                       Requires<[HasV5T]>;
    106 
    107 let isExtended = 1, opExtendable = 2, isPredicated = 1,
    108     hasSideEffects = 0, validSubTargets = HasV5SubT, isCodeGenOnly = 1 in
    109 def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst),
    110                           (ins PredRegs:$src1, f32Ext:$src2),
    111                           "if ($src1) $dst = #$src2", []>,
    112                           Requires<[HasV5T]>;
    113 
    114 let isPseudo = 1, isExtended = 1, opExtendable = 2, isPredicated = 1,
    115     isPredicatedFalse = 1, hasSideEffects = 0, validSubTargets = HasV5SubT in
    116 def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst),
    117                              (ins PredRegs:$src1, f32Ext:$src2),
    118                              "if (!$src1) $dst = #$src2", []>,
    119                              Requires<[HasV5T]>;
    120 
    121 def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>,
    122                                            SDTCisVT<1, i64>]>;
    123 
    124 def HexagonPOPCOUNT: SDNode<"HexagonISD::POPCOUNT", SDTHexagonI32I64>;
    125 
    126 let hasNewValue = 1, validSubTargets = HasV5SubT in
    127 def S5_popcountp : ALU64_rr<(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
    128   "$Rd = popcount($Rss)",
    129   [(set I32:$Rd, (HexagonPOPCOUNT I64:$Rss))], "", S_2op_tc_2_SLOT23>,
    130   Requires<[HasV5T]> {
    131     bits<5> Rd;
    132     bits<5> Rss;
    133 
    134     let IClass = 0b1000;
    135 
    136     let Inst{27-21} = 0b1000011;
    137     let Inst{7-5} = 0b011;
    138     let Inst{4-0} = Rd;
    139     let Inst{20-16} = Rss;
    140   }
    141 
    142 defm: Loadx_pat<load, f32, s30_2ImmPred, L2_loadri_io>;
    143 defm: Loadx_pat<load, f64, s29_3ImmPred, L2_loadrd_io>;
    144 
    145 defm: Storex_pat<store, F32, s30_2ImmPred, S2_storeri_io>;
    146 defm: Storex_pat<store, F64, s29_3ImmPred, S2_storerd_io>;
    147 def: Storex_simple_pat<store, F32, S2_storeri_io>;
    148 def: Storex_simple_pat<store, F64, S2_storerd_io>;
    149 
    150 let isFP = 1, hasNewValue = 1, opNewValue = 0 in
    151 class T_MInstFloat <string mnemonic, bits<3> MajOp, bits<3> MinOp>
    152   : MInst<(outs IntRegs:$Rd),
    153           (ins IntRegs:$Rs, IntRegs:$Rt),
    154   "$Rd = "#mnemonic#"($Rs, $Rt)", [],
    155   "" , M_tc_3or4x_SLOT23 > ,
    156   Requires<[HasV5T]> {
    157     bits<5> Rd;
    158     bits<5> Rs;
    159     bits<5> Rt;
    160 
    161     let IClass = 0b1110;
    162 
    163     let Inst{27-24} = 0b1011;
    164     let Inst{23-21} = MajOp;
    165     let Inst{20-16} = Rs;
    166     let Inst{13} = 0b0;
    167     let Inst{12-8} = Rt;
    168     let Inst{7-5} = MinOp;
    169     let Inst{4-0} = Rd;
    170   }
    171 
    172 let isCommutable = 1 in {
    173   def F2_sfadd : T_MInstFloat < "sfadd", 0b000, 0b000>;
    174   def F2_sfmpy : T_MInstFloat < "sfmpy", 0b010, 0b000>;
    175 }
    176 
    177 def F2_sfsub : T_MInstFloat < "sfsub", 0b000, 0b001>;
    178 
    179 def: Pat<(f32 (fadd F32:$src1, F32:$src2)),
    180          (F2_sfadd F32:$src1, F32:$src2)>;
    181 
    182 def: Pat<(f32 (fsub F32:$src1, F32:$src2)),
    183          (F2_sfsub F32:$src1, F32:$src2)>;
    184 
    185 def: Pat<(f32 (fmul F32:$src1, F32:$src2)),
    186          (F2_sfmpy F32:$src1, F32:$src2)>;
    187 
    188 let Itinerary = M_tc_3x_SLOT23 in {
    189   def F2_sfmax : T_MInstFloat < "sfmax", 0b100, 0b000>;
    190   def F2_sfmin : T_MInstFloat < "sfmin", 0b100, 0b001>;
    191 }
    192 
    193 let AddedComplexity = 100, Predicates = [HasV5T] in {
    194   def: Pat<(f32 (select (i1 (setolt F32:$src1, F32:$src2)),
    195                         F32:$src1, F32:$src2)),
    196            (F2_sfmin F32:$src1, F32:$src2)>;
    197 
    198   def: Pat<(f32 (select (i1 (setogt F32:$src1, F32:$src2)),
    199                         F32:$src2, F32:$src1)),
    200            (F2_sfmin F32:$src1, F32:$src2)>;
    201 
    202   def: Pat<(f32 (select (i1 (setogt F32:$src1, F32:$src2)),
    203                         F32:$src1, F32:$src2)),
    204            (F2_sfmax F32:$src1, F32:$src2)>;
    205 
    206   def: Pat<(f32 (select (i1 (setolt F32:$src1, F32:$src2)),
    207                         F32:$src2, F32:$src1)),
    208            (F2_sfmax F32:$src1, F32:$src2)>;
    209 }
    210 
    211 def F2_sffixupn : T_MInstFloat < "sffixupn", 0b110, 0b000>;
    212 def F2_sffixupd : T_MInstFloat < "sffixupd", 0b110, 0b001>;
    213 
    214 // F2_sfrecipa: Reciprocal approximation for division.
    215 let isPredicateLate = 1, isFP = 1,
    216 hasSideEffects = 0, hasNewValue = 1 in
    217 def F2_sfrecipa: MInst <
    218   (outs IntRegs:$Rd, PredRegs:$Pe),
    219   (ins IntRegs:$Rs, IntRegs:$Rt),
    220   "$Rd, $Pe = sfrecipa($Rs, $Rt)">,
    221   Requires<[HasV5T]> {
    222     bits<5> Rd;
    223     bits<2> Pe;
    224     bits<5> Rs;
    225     bits<5> Rt;
    226 
    227     let IClass = 0b1110;
    228     let Inst{27-21} = 0b1011111;
    229     let Inst{20-16} = Rs;
    230     let Inst{13}    = 0b0;
    231     let Inst{12-8}  = Rt;
    232     let Inst{7}     = 0b1;
    233     let Inst{6-5}   = Pe;
    234     let Inst{4-0}   = Rd;
    235   }
    236 
    237 // F2_dfcmpeq: Floating point compare for equal.
    238 let isCompare = 1, isFP = 1 in
    239 class T_fcmp <string mnemonic, RegisterClass RC, bits<3> MinOp,
    240               list<dag> pattern = [] >
    241   : ALU64Inst <(outs PredRegs:$dst), (ins RC:$src1, RC:$src2),
    242   "$dst = "#mnemonic#"($src1, $src2)", pattern,
    243   "" , ALU64_tc_2early_SLOT23 > ,
    244   Requires<[HasV5T]> {
    245     bits<2> dst;
    246     bits<5> src1;
    247     bits<5> src2;
    248 
    249     let IClass = 0b1101;
    250 
    251     let Inst{27-21} = 0b0010111;
    252     let Inst{20-16} = src1;
    253     let Inst{12-8}  = src2;
    254     let Inst{7-5}   = MinOp;
    255     let Inst{1-0}   = dst;
    256   }
    257 
    258 class T_fcmp64 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
    259   : T_fcmp <mnemonic, DoubleRegs, MinOp,
    260   [(set  I1:$dst, (OpNode F64:$src1, F64:$src2))]> {
    261   let IClass = 0b1101;
    262   let Inst{27-21} = 0b0010111;
    263 }
    264 
    265 class T_fcmp32 <string mnemonic, PatFrag OpNode, bits<3> MinOp>
    266   : T_fcmp <mnemonic, IntRegs, MinOp,
    267   [(set  I1:$dst, (OpNode F32:$src1, F32:$src2))]> {
    268   let IClass = 0b1100;
    269   let Inst{27-21} = 0b0111111;
    270 }
    271 
    272 def F2_dfcmpeq : T_fcmp64<"dfcmp.eq", setoeq, 0b000>;
    273 def F2_dfcmpgt : T_fcmp64<"dfcmp.gt", setogt, 0b001>;
    274 def F2_dfcmpge : T_fcmp64<"dfcmp.ge", setoge, 0b010>;
    275 def F2_dfcmpuo : T_fcmp64<"dfcmp.uo", setuo,  0b011>;
    276 
    277 def F2_sfcmpge : T_fcmp32<"sfcmp.ge", setoge, 0b000>;
    278 def F2_sfcmpuo : T_fcmp32<"sfcmp.uo", setuo,  0b001>;
    279 def F2_sfcmpeq : T_fcmp32<"sfcmp.eq", setoeq, 0b011>;
    280 def F2_sfcmpgt : T_fcmp32<"sfcmp.gt", setogt, 0b100>;
    281 
    282 //===----------------------------------------------------------------------===//
    283 // Multiclass to define 'Def Pats' for ordered gt, ge, eq operations.
    284 //===----------------------------------------------------------------------===//
    285 
    286 let Predicates = [HasV5T] in
    287 multiclass T_fcmp_pats<PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
    288   // IntRegs
    289   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
    290            (IntMI F32:$src1, F32:$src2)>;
    291   // DoubleRegs
    292   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
    293            (DoubleMI F64:$src1, F64:$src2)>;
    294 }
    295 
    296 defm : T_fcmp_pats <seteq, F2_sfcmpeq, F2_dfcmpeq>;
    297 defm : T_fcmp_pats <setgt, F2_sfcmpgt, F2_dfcmpgt>;
    298 defm : T_fcmp_pats <setge, F2_sfcmpge, F2_dfcmpge>;
    299 
    300 //===----------------------------------------------------------------------===//
    301 // Multiclass to define 'Def Pats' for unordered gt, ge, eq operations.
    302 //===----------------------------------------------------------------------===//
    303 let Predicates = [HasV5T] in
    304 multiclass unord_Pats <PatFrag cmpOp, InstHexagon IntMI, InstHexagon DoubleMI> {
    305   // IntRegs
    306   def: Pat<(i1 (cmpOp F32:$src1, F32:$src2)),
    307            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
    308                   (IntMI F32:$src1, F32:$src2))>;
    309 
    310   // DoubleRegs
    311   def: Pat<(i1 (cmpOp F64:$src1, F64:$src2)),
    312            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
    313                   (DoubleMI F64:$src1, F64:$src2))>;
    314 }
    315 
    316 defm : unord_Pats <setuge, F2_sfcmpge, F2_dfcmpge>;
    317 defm : unord_Pats <setugt, F2_sfcmpgt, F2_dfcmpgt>;
    318 defm : unord_Pats <setueq, F2_sfcmpeq, F2_dfcmpeq>;
    319 
    320 //===----------------------------------------------------------------------===//
    321 // Multiclass to define 'Def Pats' for the following dags:
    322 // seteq(setoeq(op1, op2), 0) -> not(setoeq(op1, op2))
    323 // seteq(setoeq(op1, op2), 1) -> setoeq(op1, op2)
    324 // setne(setoeq(op1, op2), 0) -> setoeq(op1, op2)
    325 // setne(setoeq(op1, op2), 1) -> not(setoeq(op1, op2))
    326 //===----------------------------------------------------------------------===//
    327 let Predicates = [HasV5T] in
    328 multiclass eq_ordgePats <PatFrag cmpOp, InstHexagon IntMI,
    329                          InstHexagon DoubleMI> {
    330   // IntRegs
    331   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
    332            (C2_not (IntMI F32:$src1, F32:$src2))>;
    333   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
    334            (IntMI F32:$src1, F32:$src2)>;
    335   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
    336            (IntMI F32:$src1, F32:$src2)>;
    337   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
    338            (C2_not (IntMI F32:$src1, F32:$src2))>;
    339 
    340   // DoubleRegs
    341   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
    342             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
    343   def : Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
    344             (DoubleMI F64:$src1, F64:$src2)>;
    345   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
    346             (DoubleMI F64:$src1, F64:$src2)>;
    347   def : Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
    348             (C2_not (DoubleMI F64:$src1, F64:$src2))>;
    349 }
    350 
    351 defm : eq_ordgePats<setoeq, F2_sfcmpeq, F2_dfcmpeq>;
    352 defm : eq_ordgePats<setoge, F2_sfcmpge, F2_dfcmpge>;
    353 defm : eq_ordgePats<setogt, F2_sfcmpgt, F2_dfcmpgt>;
    354 
    355 //===----------------------------------------------------------------------===//
    356 // Multiclass to define 'Def Pats' for the following dags:
    357 // seteq(setolt(op1, op2), 0) -> not(setogt(op2, op1))
    358 // seteq(setolt(op1, op2), 1) -> setogt(op2, op1)
    359 // setne(setolt(op1, op2), 0) -> setogt(op2, op1)
    360 // setne(setolt(op1, op2), 1) -> not(setogt(op2, op1))
    361 //===----------------------------------------------------------------------===//
    362 let Predicates = [HasV5T] in
    363 multiclass eq_ordltPats <PatFrag cmpOp, InstHexagon IntMI,
    364                          InstHexagon DoubleMI> {
    365   // IntRegs
    366   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
    367            (C2_not (IntMI F32:$src2, F32:$src1))>;
    368   def: Pat<(i1 (seteq (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
    369            (IntMI F32:$src2, F32:$src1)>;
    370   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 0)),
    371            (IntMI F32:$src2, F32:$src1)>;
    372   def: Pat<(i1 (setne (i1 (cmpOp F32:$src1, F32:$src2)), 1)),
    373            (C2_not (IntMI F32:$src2, F32:$src1))>;
    374 
    375   // DoubleRegs
    376   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
    377            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
    378   def: Pat<(i1 (seteq (i1 (cmpOp F64:$src1, F64:$src2)), 1)),
    379            (DoubleMI F64:$src2, F64:$src1)>;
    380   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
    381            (DoubleMI F64:$src2, F64:$src1)>;
    382   def: Pat<(i1 (setne (i1 (cmpOp F64:$src1, F64:$src2)), 0)),
    383            (C2_not (DoubleMI F64:$src2, F64:$src1))>;
    384 }
    385 
    386 defm : eq_ordltPats<setole, F2_sfcmpge, F2_dfcmpge>;
    387 defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>;
    388 
    389 
    390 // o. seto inverse of setuo. http://llvm.org/docs/LangRef.html#i_fcmp
    391 let Predicates = [HasV5T] in {
    392   def: Pat<(i1 (seto F32:$src1, F32:$src2)),
    393            (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>;
    394   def: Pat<(i1 (seto F32:$src1, fpimm:$src2)),
    395            (C2_not (F2_sfcmpuo (TFRI_f fpimm:$src2), F32:$src1))>;
    396   def: Pat<(i1 (seto F64:$src1, F64:$src2)),
    397            (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>;
    398   def: Pat<(i1 (seto F64:$src1, fpimm:$src2)),
    399            (C2_not (F2_dfcmpuo (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
    400 }
    401 
    402 // Ordered lt.
    403 let Predicates = [HasV5T] in {
    404   def: Pat<(i1 (setolt F32:$src1, F32:$src2)),
    405            (F2_sfcmpgt F32:$src2, F32:$src1)>;
    406   def: Pat<(i1 (setolt F32:$src1, fpimm:$src2)),
    407            (F2_sfcmpgt (f32 (TFRI_f fpimm:$src2)), F32:$src1)>;
    408   def: Pat<(i1 (setolt F64:$src1, F64:$src2)),
    409            (F2_dfcmpgt F64:$src2, F64:$src1)>;
    410   def: Pat<(i1 (setolt F64:$src1, fpimm:$src2)),
    411            (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
    412 }
    413 
    414 // Unordered lt.
    415 let Predicates = [HasV5T] in {
    416   def: Pat<(i1 (setult F32:$src1, F32:$src2)),
    417            (C2_or (F2_sfcmpuo  F32:$src1, F32:$src2),
    418                   (F2_sfcmpgt F32:$src2, F32:$src1))>;
    419   def: Pat<(i1 (setult F32:$src1, fpimm:$src2)),
    420            (C2_or (F2_sfcmpuo  F32:$src1, (TFRI_f fpimm:$src2)),
    421                   (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1))>;
    422   def: Pat<(i1 (setult F64:$src1, F64:$src2)),
    423            (C2_or (F2_dfcmpuo  F64:$src1, F64:$src2),
    424                   (F2_dfcmpgt F64:$src2, F64:$src1))>;
    425   def: Pat<(i1 (setult F64:$src1, fpimm:$src2)),
    426            (C2_or (F2_dfcmpuo  F64:$src1, (CONST64_Float_Real fpimm:$src2)),
    427                   (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
    428 }
    429 
    430 // Ordered le.
    431 let Predicates = [HasV5T] in {
    432   // rs <= rt -> rt >= rs.
    433   def: Pat<(i1 (setole F32:$src1, F32:$src2)),
    434            (F2_sfcmpge F32:$src2, F32:$src1)>;
    435   def: Pat<(i1 (setole F32:$src1, fpimm:$src2)),
    436            (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
    437 
    438   // Rss <= Rtt -> Rtt >= Rss.
    439   def: Pat<(i1 (setole F64:$src1, F64:$src2)),
    440            (F2_dfcmpge F64:$src2, F64:$src1)>;
    441   def: Pat<(i1 (setole F64:$src1, fpimm:$src2)),
    442            (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
    443 }
    444 
    445 // Unordered le.
    446 let Predicates = [HasV5T] in {
    447 // rs <= rt -> rt >= rs.
    448   def: Pat<(i1 (setule F32:$src1, F32:$src2)),
    449            (C2_or (F2_sfcmpuo  F32:$src1, F32:$src2),
    450                   (F2_sfcmpge F32:$src2, F32:$src1))>;
    451   def: Pat<(i1 (setule F32:$src1, fpimm:$src2)),
    452            (C2_or (F2_sfcmpuo  F32:$src1, (TFRI_f fpimm:$src2)),
    453                   (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1))>;
    454   def: Pat<(i1 (setule F64:$src1, F64:$src2)),
    455            (C2_or (F2_dfcmpuo  F64:$src1, F64:$src2),
    456                   (F2_dfcmpge F64:$src2, F64:$src1))>;
    457   def: Pat<(i1 (setule F64:$src1, fpimm:$src2)),
    458            (C2_or (F2_dfcmpuo  F64:$src1, (CONST64_Float_Real fpimm:$src2)),
    459                   (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1))>;
    460 }
    461 
    462 // Ordered ne.
    463 let Predicates = [HasV5T] in {
    464   def: Pat<(i1 (setone F32:$src1, F32:$src2)),
    465            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
    466   def: Pat<(i1 (setone F64:$src1, F64:$src2)),
    467            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
    468   def: Pat<(i1 (setone F32:$src1, fpimm:$src2)),
    469            (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
    470   def: Pat<(i1 (setone F64:$src1, fpimm:$src2)),
    471            (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
    472 }
    473 
    474 // Unordered ne.
    475 let Predicates = [HasV5T] in {
    476   def: Pat<(i1 (setune F32:$src1, F32:$src2)),
    477            (C2_or (F2_sfcmpuo F32:$src1, F32:$src2),
    478                   (C2_not (F2_sfcmpeq F32:$src1, F32:$src2)))>;
    479   def: Pat<(i1 (setune F64:$src1, F64:$src2)),
    480            (C2_or (F2_dfcmpuo F64:$src1, F64:$src2),
    481                   (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>;
    482   def: Pat<(i1 (setune F32:$src1, fpimm:$src2)),
    483            (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)),
    484                   (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2))))>;
    485   def: Pat<(i1 (setune F64:$src1, fpimm:$src2)),
    486            (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)),
    487                   (C2_not (F2_dfcmpeq F64:$src1,
    488                                         (CONST64_Float_Real fpimm:$src2))))>;
    489 }
    490 
    491 // Besides set[o|u][comparions], we also need set[comparisons].
    492 let Predicates = [HasV5T] in {
    493   // lt.
    494   def: Pat<(i1 (setlt F32:$src1, F32:$src2)),
    495            (F2_sfcmpgt F32:$src2, F32:$src1)>;
    496   def: Pat<(i1 (setlt F32:$src1, fpimm:$src2)),
    497            (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1)>;
    498   def: Pat<(i1 (setlt F64:$src1, F64:$src2)),
    499            (F2_dfcmpgt F64:$src2, F64:$src1)>;
    500   def: Pat<(i1 (setlt F64:$src1, fpimm:$src2)),
    501            (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
    502 
    503   // le.
    504   // rs <= rt -> rt >= rs.
    505   def: Pat<(i1 (setle F32:$src1, F32:$src2)),
    506            (F2_sfcmpge F32:$src2, F32:$src1)>;
    507   def: Pat<(i1 (setle F32:$src1, fpimm:$src2)),
    508            (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>;
    509 
    510   // Rss <= Rtt -> Rtt >= Rss.
    511   def: Pat<(i1 (setle F64:$src1, F64:$src2)),
    512            (F2_dfcmpge F64:$src2, F64:$src1)>;
    513   def: Pat<(i1 (setle F64:$src1, fpimm:$src2)),
    514            (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>;
    515 
    516   // ne.
    517   def: Pat<(i1 (setne F32:$src1, F32:$src2)),
    518            (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>;
    519   def: Pat<(i1 (setne F64:$src1, F64:$src2)),
    520            (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>;
    521   def: Pat<(i1 (setne F32:$src1, fpimm:$src2)),
    522            (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>;
    523   def: Pat<(i1 (setne F64:$src1, fpimm:$src2)),
    524            (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>;
    525 }
    526 
    527 // F2 convert template classes:
    528 let isFP = 1 in
    529 class F2_RDD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
    530                          SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
    531                          string chop ="">
    532   : SInst <(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss),
    533    "$Rdd = "#mnemonic#"($Rss)"#chop,
    534    [(set RCOut:$Rdd, (Op RCIn:$Rss))], "",
    535    S_2op_tc_3or4x_SLOT23> {
    536      bits<5> Rdd;
    537      bits<5> Rss;
    538 
    539      let IClass = 0b1000;
    540 
    541      let Inst{27-21} = 0b0000111;
    542      let Inst{20-16} = Rss;
    543      let Inst{7-5} = MinOp;
    544      let Inst{4-0} = Rdd;
    545   }
    546 
    547 let isFP = 1 in
    548 class F2_RDD_RS_CONVERT<string mnemonic, bits<3> MinOp,
    549                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
    550                         string chop ="">
    551   : SInst <(outs DoubleRegs:$Rdd), (ins IntRegs:$Rs),
    552    "$Rdd = "#mnemonic#"($Rs)"#chop,
    553    [(set RCOut:$Rdd, (Op RCIn:$Rs))], "",
    554    S_2op_tc_3or4x_SLOT23> {
    555      bits<5> Rdd;
    556      bits<5> Rs;
    557 
    558      let IClass = 0b1000;
    559 
    560      let Inst{27-21} = 0b0100100;
    561      let Inst{20-16} = Rs;
    562      let Inst{7-5} = MinOp;
    563      let Inst{4-0} = Rdd;
    564   }
    565 
    566 let isFP = 1, hasNewValue = 1 in
    567 class F2_RD_RSS_CONVERT<string mnemonic, bits<3> MinOp,
    568                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
    569                         string chop ="">
    570   : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss),
    571    "$Rd = "#mnemonic#"($Rss)"#chop,
    572    [(set RCOut:$Rd, (Op RCIn:$Rss))], "",
    573    S_2op_tc_3or4x_SLOT23> {
    574      bits<5> Rd;
    575      bits<5> Rss;
    576 
    577      let IClass = 0b1000;
    578 
    579      let Inst{27-24} = 0b1000;
    580      let Inst{23-21} = MinOp;
    581      let Inst{20-16} = Rss;
    582      let Inst{7-5} = 0b001;
    583      let Inst{4-0} = Rd;
    584   }
    585 
    586 let isFP = 1, hasNewValue = 1 in
    587 class F2_RD_RS_CONVERT<string mnemonic, bits<3> MajOp, bits<3> MinOp,
    588                         SDNode Op, PatLeaf RCOut, PatLeaf RCIn,
    589                         string chop ="">
    590   : SInst <(outs IntRegs:$Rd), (ins IntRegs:$Rs),
    591    "$Rd = "#mnemonic#"($Rs)"#chop,
    592    [(set RCOut:$Rd, (Op RCIn:$Rs))], "",
    593    S_2op_tc_3or4x_SLOT23> {
    594      bits<5> Rd;
    595      bits<5> Rs;
    596 
    597      let IClass = 0b1000;
    598 
    599      let Inst{27-24} = 0b1011;
    600      let Inst{23-21} = MajOp;
    601      let Inst{20-16} = Rs;
    602      let Inst{7-5} = MinOp;
    603      let Inst{4-0} = Rd;
    604   }
    605 
    606 // Convert single precision to double precision and vice-versa.
    607 def F2_conv_sf2df : F2_RDD_RS_CONVERT <"convert_sf2df", 0b000,
    608                                        fextend, F64, F32>;
    609 
    610 def F2_conv_df2sf : F2_RD_RSS_CONVERT <"convert_df2sf", 0b000,
    611                                        fround, F32, F64>;
    612 
    613 // Convert Integer to Floating Point.
    614 def F2_conv_d2sf : F2_RD_RSS_CONVERT <"convert_d2sf", 0b010,
    615                                        sint_to_fp, F32, I64>;
    616 def F2_conv_ud2sf : F2_RD_RSS_CONVERT <"convert_ud2sf", 0b001,
    617                                        uint_to_fp, F32, I64>;
    618 def F2_conv_uw2sf : F2_RD_RS_CONVERT <"convert_uw2sf", 0b001, 0b000,
    619                                        uint_to_fp, F32, I32>;
    620 def F2_conv_w2sf : F2_RD_RS_CONVERT <"convert_w2sf", 0b010, 0b000,
    621                                        sint_to_fp, F32, I32>;
    622 def F2_conv_d2df : F2_RDD_RSS_CONVERT <"convert_d2df", 0b011,
    623                                        sint_to_fp, F64, I64>;
    624 def F2_conv_ud2df : F2_RDD_RSS_CONVERT <"convert_ud2df", 0b010,
    625                                         uint_to_fp, F64, I64>;
    626 def F2_conv_uw2df : F2_RDD_RS_CONVERT <"convert_uw2df", 0b001,
    627                                        uint_to_fp, F64, I32>;
    628 def F2_conv_w2df : F2_RDD_RS_CONVERT <"convert_w2df", 0b010,
    629                                        sint_to_fp, F64, I32>;
    630 
    631 // Convert Floating Point to Integer - default.
    632 def F2_conv_df2uw_chop : F2_RD_RSS_CONVERT <"convert_df2uw", 0b101,
    633                                             fp_to_uint, I32, F64, ":chop">;
    634 def F2_conv_df2w_chop : F2_RD_RSS_CONVERT <"convert_df2w", 0b111,
    635                                             fp_to_sint, I32, F64, ":chop">;
    636 def F2_conv_sf2uw_chop : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b001,
    637                                        fp_to_uint, I32, F32, ":chop">;
    638 def F2_conv_sf2w_chop : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b001,
    639                                        fp_to_sint, I32, F32, ":chop">;
    640 def F2_conv_df2d_chop : F2_RDD_RSS_CONVERT <"convert_df2d", 0b110,
    641                                             fp_to_sint, I64, F64, ":chop">;
    642 def F2_conv_df2ud_chop : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b111,
    643                                              fp_to_uint, I64, F64, ":chop">;
    644 def F2_conv_sf2d_chop : F2_RDD_RS_CONVERT <"convert_sf2d", 0b110,
    645                                        fp_to_sint, I64, F32, ":chop">;
    646 def F2_conv_sf2ud_chop : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b101,
    647                                             fp_to_uint, I64, F32, ":chop">;
    648 
    649 // Convert Floating Point to Integer: non-chopped.
    650 let AddedComplexity = 20, Predicates = [HasV5T, IEEERndNearV5T] in {
    651   def F2_conv_df2d : F2_RDD_RSS_CONVERT <"convert_df2d", 0b000,
    652                                          fp_to_sint, I64, F64>;
    653   def F2_conv_df2ud : F2_RDD_RSS_CONVERT <"convert_df2ud", 0b001,
    654                                           fp_to_uint, I64, F64>;
    655   def F2_conv_sf2ud : F2_RDD_RS_CONVERT <"convert_sf2ud", 0b011,
    656                                          fp_to_uint, I64, F32>;
    657   def F2_conv_sf2d : F2_RDD_RS_CONVERT <"convert_sf2d", 0b100,
    658                                          fp_to_sint, I64, F32>;
    659   def F2_conv_df2uw : F2_RD_RSS_CONVERT <"convert_df2uw", 0b011,
    660                                          fp_to_uint, I32, F64>;
    661   def F2_conv_df2w : F2_RD_RSS_CONVERT <"convert_df2w", 0b100,
    662                                          fp_to_sint, I32, F64>;
    663   def F2_conv_sf2uw : F2_RD_RS_CONVERT <"convert_sf2uw", 0b011, 0b000,
    664                                          fp_to_uint, I32, F32>;
    665   def F2_conv_sf2w : F2_RD_RS_CONVERT <"convert_sf2w", 0b100, 0b000,
    666                                          fp_to_sint, I32, F32>;
    667 }
    668 
    669 // Fix up radicand.
    670 let isFP = 1, hasNewValue = 1 in
    671 def F2_sffixupr: SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs),
    672   "$Rd = sffixupr($Rs)",
    673   [], "" , S_2op_tc_3or4x_SLOT23>, Requires<[HasV5T]> {
    674     bits<5> Rd;
    675     bits<5> Rs;
    676 
    677     let IClass = 0b1000;
    678 
    679     let Inst{27-21} = 0b1011101;
    680     let Inst{20-16} = Rs;
    681     let Inst{7-5}   = 0b000;
    682     let Inst{4-0}   = Rd;
    683   }
    684 
    685 // Bitcast is different than [fp|sint|uint]_to_[sint|uint|fp].
    686 let Predicates = [HasV5T] in {
    687   def: Pat <(i32 (bitconvert F32:$src)), (I32:$src)>;
    688   def: Pat <(f32 (bitconvert I32:$src)), (F32:$src)>;
    689   def: Pat <(i64 (bitconvert F64:$src)), (I64:$src)>;
    690   def: Pat <(f64 (bitconvert I64:$src)), (F64:$src)>;
    691 }
    692 
    693 // F2_sffma: Floating-point fused multiply add.
    694 let isFP = 1, hasNewValue = 1 in
    695 class T_sfmpy_acc <bit isSub, bit isLib>
    696   : MInst<(outs IntRegs:$Rx),
    697           (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt),
    698   "$Rx "#!if(isSub, "-=","+=")#" sfmpy($Rs, $Rt)"#!if(isLib, ":lib",""),
    699   [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
    700   Requires<[HasV5T]> {
    701     bits<5> Rx;
    702     bits<5> Rs;
    703     bits<5> Rt;
    704 
    705     let IClass = 0b1110;
    706 
    707     let Inst{27-21} = 0b1111000;
    708     let Inst{20-16} = Rs;
    709     let Inst{13}    = 0b0;
    710     let Inst{12-8}  = Rt;
    711     let Inst{7}     = 0b1;
    712     let Inst{6}     = isLib;
    713     let Inst{5}     = isSub;
    714     let Inst{4-0}   = Rx;
    715   }
    716 
    717 def F2_sffma: T_sfmpy_acc <0, 0>;
    718 def F2_sffms: T_sfmpy_acc <1, 0>;
    719 def F2_sffma_lib: T_sfmpy_acc <0, 1>;
    720 def F2_sffms_lib: T_sfmpy_acc <1, 1>;
    721 
    722 def : Pat <(f32 (fma F32:$src2, F32:$src3, F32:$src1)),
    723            (F2_sffma F32:$src1, F32:$src2, F32:$src3)>;
    724 
    725 // Floating-point fused multiply add w/ additional scaling (2**pu).
    726 let isFP = 1, hasNewValue = 1 in
    727 def F2_sffma_sc: MInst <
    728   (outs IntRegs:$Rx),
    729   (ins IntRegs:$dst2, IntRegs:$Rs, IntRegs:$Rt, PredRegs:$Pu),
    730   "$Rx += sfmpy($Rs, $Rt, $Pu):scale" ,
    731   [], "$dst2 = $Rx" , M_tc_3_SLOT23 > ,
    732   Requires<[HasV5T]> {
    733     bits<5> Rx;
    734     bits<5> Rs;
    735     bits<5> Rt;
    736     bits<2> Pu;
    737 
    738     let IClass = 0b1110;
    739 
    740     let Inst{27-21} = 0b1111011;
    741     let Inst{20-16} = Rs;
    742     let Inst{13}    = 0b0;
    743     let Inst{12-8}  = Rt;
    744     let Inst{7}     = 0b1;
    745     let Inst{6-5}   = Pu;
    746     let Inst{4-0}   = Rx;
    747   }
    748 
    749 let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 3,
    750     isPseudo = 1, InputType = "imm" in
    751 def MUX_ir_f : ALU32_rr<(outs IntRegs:$dst),
    752       (ins PredRegs:$src1, IntRegs:$src2, f32Ext:$src3),
    753       "$dst = mux($src1, $src2, #$src3)",
    754       [(set F32:$dst, (f32 (select I1:$src1, F32:$src2, fpimm:$src3)))]>,
    755     Requires<[HasV5T]>;
    756 
    757 let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 2,
    758     isPseudo = 1, InputType = "imm" in
    759 def MUX_ri_f : ALU32_rr<(outs IntRegs:$dst),
    760       (ins PredRegs:$src1, f32Ext:$src2, IntRegs:$src3),
    761       "$dst = mux($src1, #$src2, $src3)",
    762       [(set F32:$dst, (f32 (select I1:$src1, fpimm:$src2, F32:$src3)))]>,
    763     Requires<[HasV5T]>;
    764 
    765 def: Pat<(select I1:$src1, F32:$src2, F32:$src3),
    766          (C2_mux I1:$src1, F32:$src2, F32:$src3)>,
    767      Requires<[HasV5T]>;
    768 
    769 def: Pat<(select (i1 (setult F32:$src1, F32:$src2)), F32:$src3, F32:$src4),
    770          (C2_mux (F2_sfcmpgt F32:$src2, F32:$src1), F32:$src4, F32:$src3)>,
    771      Requires<[HasV5T]>;
    772 
    773 def: Pat<(select I1:$src1, F64:$src2, F64:$src3),
    774          (C2_vmux I1:$src1, F64:$src2, F64:$src3)>,
    775     Requires<[HasV5T]>;
    776 
    777 def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4),
    778          (C2_vmux (F2_dfcmpgt F64:$src2, F64:$src1), F64:$src3, F64:$src4)>,
    779      Requires<[HasV5T]>;
    780 
    781 // Map from p0 = pnot(p0); r0 = select(p0, #i, r1)
    782 // => r0 = MUX_ir_f(p0, #i, r1)
    783 def: Pat<(select (not I1:$src1), fpimm:$src2, F32:$src3),
    784          (MUX_ir_f I1:$src1, F32:$src3, fpimm:$src2)>,
    785      Requires<[HasV5T]>;
    786 
    787 // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
    788 // => r0 = MUX_ri_f(p0, r1, #i)
    789 def: Pat<(select (not I1:$src1), F32:$src2, fpimm:$src3),
    790          (MUX_ri_f I1:$src1, fpimm:$src3, F32:$src2)>,
    791      Requires<[HasV5T]>;
    792 
    793 def: Pat<(i32 (fp_to_sint F64:$src1)),
    794          (LoReg (F2_conv_df2d_chop F64:$src1))>,
    795      Requires<[HasV5T]>;
    796 
    797 //===----------------------------------------------------------------------===//
    798 // :natural forms of vasrh and vasrhub insns
    799 //===----------------------------------------------------------------------===//
    800 // S5_asrhub_rnd_sat: Vector arithmetic shift right by immediate with round,
    801 // saturate, and pack.
    802 let Defs = [USR_OVF], hasSideEffects = 0, hasNewValue = 1, opNewValue = 0 in
    803 class T_ASRHUB<bit isSat>
    804   : SInst <(outs IntRegs:$Rd),
    805   (ins DoubleRegs:$Rss, u4Imm:$u4),
    806   "$Rd = vasrhub($Rss, #$u4):"#!if(isSat, "sat", "raw"),
    807   [], "", S_2op_tc_2_SLOT23>,
    808   Requires<[HasV5T]> {
    809     bits<5> Rd;
    810     bits<5> Rss;
    811     bits<4> u4;
    812 
    813     let IClass = 0b1000;
    814 
    815     let Inst{27-21} = 0b1000011;
    816     let Inst{20-16} = Rss;
    817     let Inst{13-12} = 0b00;
    818     let Inst{11-8} = u4;
    819     let Inst{7-6} = 0b10;
    820     let Inst{5} = isSat;
    821     let Inst{4-0} = Rd;
    822   }
    823 
    824 def S5_asrhub_rnd_sat : T_ASRHUB <0>;
    825 def S5_asrhub_sat : T_ASRHUB <1>;
    826 
    827 let isAsmParserOnly = 1 in
    828 def S5_asrhub_rnd_sat_goodsyntax
    829   : SInst <(outs IntRegs:$Rd), (ins DoubleRegs:$Rss, u4Imm:$u4),
    830   "$Rd = vasrhub($Rss, #$u4):rnd:sat">, Requires<[HasV5T]>;
    831 
    832 // S5_vasrhrnd: Vector arithmetic shift right by immediate with round.
    833 let hasSideEffects = 0 in
    834 def S5_vasrhrnd : SInst <(outs DoubleRegs:$Rdd),
    835                          (ins DoubleRegs:$Rss, u4Imm:$u4),
    836   "$Rdd = vasrh($Rss, #$u4):raw">,
    837   Requires<[HasV5T]> {
    838     bits<5> Rdd;
    839     bits<5> Rss;
    840     bits<4> u4;
    841 
    842     let IClass = 0b1000;
    843 
    844     let Inst{27-21} = 0b0000001;
    845     let Inst{20-16} = Rss;
    846     let Inst{13-12} = 0b00;
    847     let Inst{11-8}  = u4;
    848     let Inst{7-5}   = 0b000;
    849     let Inst{4-0}   = Rdd;
    850   }
    851 
    852 let isAsmParserOnly = 1 in
    853 def S5_vasrhrnd_goodsyntax
    854   : SInst <(outs DoubleRegs:$Rdd), (ins DoubleRegs:$Rss, u4Imm:$u4),
    855   "$Rdd = vasrh($Rss,#$u4):rnd">, Requires<[HasV5T]>;
    856 
    857 // Floating point reciprocal square root approximation
    858 let Uses = [USR], isPredicateLate = 1, isFP = 1,
    859     hasSideEffects = 0, hasNewValue = 1, opNewValue = 0,
    860     validSubTargets = HasV5SubT in
    861 def F2_sfinvsqrta: SInst <
    862   (outs IntRegs:$Rd, PredRegs:$Pe),
    863   (ins IntRegs:$Rs),
    864   "$Rd, $Pe = sfinvsqrta($Rs)" > ,
    865   Requires<[HasV5T]> {
    866     bits<5> Rd;
    867     bits<2> Pe;
    868     bits<5> Rs;
    869 
    870     let IClass = 0b1000;
    871 
    872     let Inst{27-21} = 0b1011111;
    873     let Inst{20-16} = Rs;
    874     let Inst{7} = 0b0;
    875     let Inst{6-5} = Pe;
    876     let Inst{4-0} = Rd;
    877   }
    878 
    879 // Complex multiply 32x16
    880 let Defs = [USR_OVF], Itinerary = S_3op_tc_3x_SLOT23 in {
    881   def M4_cmpyi_whc : T_S3op_8<"cmpyiwh", 0b101, 1, 1, 1, 1>;
    882   def M4_cmpyr_whc : T_S3op_8<"cmpyrwh", 0b111, 1, 1, 1, 1>;
    883 }
    884 
    885 // Classify floating-point value
    886 let isFP = 1 in
    887  def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>;
    888 
    889 let isFP = 1 in
    890 def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5),
    891   "$Pd = dfclass($Rss, #$u5)",
    892   [], "" , ALU64_tc_2early_SLOT23 > , Requires<[HasV5T]> {
    893     bits<2> Pd;
    894     bits<5> Rss;
    895     bits<5> u5;
    896 
    897     let IClass = 0b1101;
    898     let Inst{27-21} = 0b1100100;
    899     let Inst{20-16} = Rss;
    900     let Inst{12-10} = 0b000;
    901     let Inst{9-5}   = u5;
    902     let Inst{4-3}   = 0b10;
    903     let Inst{1-0}   = Pd;
    904   }
    905 
    906 // Instructions to create floating point constant
    907 class T_fimm <string mnemonic, RegisterClass RC, bits<4> RegType, bit isNeg>
    908   : ALU64Inst<(outs RC:$dst), (ins u10Imm:$src),
    909   "$dst = "#mnemonic#"(#$src)"#!if(isNeg, ":neg", ":pos"),
    910   [], "", ALU64_tc_3x_SLOT23>, Requires<[HasV5T]> {
    911     bits<5> dst;
    912     bits<10> src;
    913 
    914     let IClass = 0b1101;
    915     let Inst{27-24} = RegType;
    916     let Inst{23}    = 0b0;
    917     let Inst{22}    = isNeg;
    918     let Inst{21}    = src{9};
    919     let Inst{13-5}  = src{8-0};
    920     let Inst{4-0}   = dst;
    921   }
    922 
    923 let hasNewValue = 1, opNewValue = 0 in {
    924 def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>;
    925 def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>;
    926 }
    927 
    928 def F2_dfimm_p : T_fimm <"dfmake", DoubleRegs, 0b1001, 0>;
    929 def F2_dfimm_n : T_fimm <"dfmake", DoubleRegs, 0b1001, 1>;
    930 
    931 def : Pat <(fabs (f32 IntRegs:$src1)),
    932            (S2_clrbit_i (f32 IntRegs:$src1), 31)>,
    933           Requires<[HasV5T]>;
    934 
    935 def : Pat <(fneg (f32 IntRegs:$src1)),
    936            (S2_togglebit_i (f32 IntRegs:$src1), 31)>,
    937           Requires<[HasV5T]>;
    938