Home | History | Annotate | Download | only in Hexagon
      1 //=- HexagonInstrInfoV4.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 V4 instructions in TableGen format.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 let neverHasSideEffects = 1 in
     15 class T_Immext<dag ins> :
     16   EXTENDERInst<(outs), ins, "immext(#$imm)", []>,
     17   Requires<[HasV4T]>;
     18 
     19 def IMMEXT_b : T_Immext<(ins brtarget:$imm)>;
     20 def IMMEXT_c : T_Immext<(ins calltarget:$imm)>;
     21 def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>;
     22 def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>;
     23 
     24 // Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address.
     25 def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>;
     26 
     27 // Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address.
     28 def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>;
     29 
     30 def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr),
     31                                        (HexagonCONST32 node:$addr), [{
     32   return hasNumUsesBelowThresGA(N->getOperand(0).getNode());
     33 }]>;
     34 
     35 // Hexagon V4 Architecture spec defines 8 instruction classes:
     36 // LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the
     37 // compiler)
     38 
     39 // LD Instructions:
     40 // ========================================
     41 // Loads (8/16/32/64 bit)
     42 // Deallocframe
     43 
     44 // ST Instructions:
     45 // ========================================
     46 // Stores (8/16/32/64 bit)
     47 // Allocframe
     48 
     49 // ALU32 Instructions:
     50 // ========================================
     51 // Arithmetic / Logical (32 bit)
     52 // Vector Halfword
     53 
     54 // XTYPE Instructions (32/64 bit):
     55 // ========================================
     56 // Arithmetic, Logical, Bit Manipulation
     57 // Multiply (Integer, Fractional, Complex)
     58 // Permute / Vector Permute Operations
     59 // Predicate Operations
     60 // Shift / Shift with Add/Sub/Logical
     61 // Vector Byte ALU
     62 // Vector Halfword (ALU, Shift, Multiply)
     63 // Vector Word (ALU, Shift)
     64 
     65 // J Instructions:
     66 // ========================================
     67 // Jump/Call PC-relative
     68 
     69 // JR Instructions:
     70 // ========================================
     71 // Jump/Call Register
     72 
     73 // MEMOP Instructions:
     74 // ========================================
     75 // Operation on memory (8/16/32 bit)
     76 
     77 // NV Instructions:
     78 // ========================================
     79 // New-value Jumps
     80 // New-value Stores
     81 
     82 // CR Instructions:
     83 // ========================================
     84 // Control-Register Transfers
     85 // Hardware Loop Setup
     86 // Predicate Logicals & Reductions
     87 
     88 // SYSTEM Instructions (not implemented in the compiler):
     89 // ========================================
     90 // Prefetch
     91 // Cache Maintenance
     92 // Bus Operations
     93 
     94 
     95 //===----------------------------------------------------------------------===//
     96 // ALU32 +
     97 //===----------------------------------------------------------------------===//
     98 // Generate frame index addresses.
     99 let neverHasSideEffects = 1, isReMaterializable = 1,
    100 isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
    101 def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
    102             (ins IntRegs:$src1, s32Imm:$offset),
    103             "$dst = add($src1, ##$offset)",
    104             []>,
    105             Requires<[HasV4T]>;
    106 
    107 // Rd=cmp.eq(Rs,#s8)
    108 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
    109 isExtentSigned = 1, opExtentBits = 8 in
    110 def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd),
    111                     (ins IntRegs:$Rs, s8Ext:$s8),
    112                     "$Rd = cmp.eq($Rs, #$s8)",
    113                     [(set (i32 IntRegs:$Rd),
    114                           (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
    115                                                 s8ExtPred:$s8)))))]>,
    116                     Requires<[HasV4T]>;
    117 
    118 // Preserve the TSTBIT generation
    119 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
    120                                            (i32 IntRegs:$src1))), 0)))),
    121       (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
    122                    1, 0))>;
    123 
    124 // Interfered with tstbit generation, above pattern preserves, see : tstbit.ll
    125 // Rd=cmp.ne(Rs,#s8)
    126 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
    127 isExtentSigned = 1, opExtentBits = 8 in
    128 def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd),
    129                      (ins IntRegs:$Rs, s8Ext:$s8),
    130                      "$Rd = !cmp.eq($Rs, #$s8)",
    131                      [(set (i32 IntRegs:$Rd),
    132                            (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
    133                                                  s8ExtPred:$s8)))))]>,
    134                      Requires<[HasV4T]>;
    135 
    136 // Rd=cmp.eq(Rs,Rt)
    137 let validSubTargets = HasV4SubT in
    138 def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd),
    139                    (ins IntRegs:$Rs, IntRegs:$Rt),
    140                    "$Rd = cmp.eq($Rs, $Rt)",
    141                    [(set (i32 IntRegs:$Rd),
    142                          (i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
    143                                                IntRegs:$Rt)))))]>,
    144                    Requires<[HasV4T]>;
    145 
    146 // Rd=cmp.ne(Rs,Rt)
    147 let validSubTargets = HasV4SubT in
    148 def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
    149                     (ins IntRegs:$Rs, IntRegs:$Rt),
    150                     "$Rd = !cmp.eq($Rs, $Rt)",
    151                     [(set (i32 IntRegs:$Rd),
    152                           (i32 (zext (i1 (setne (i32 IntRegs:$Rs),
    153                                                IntRegs:$Rt)))))]>,
    154                     Requires<[HasV4T]>;
    155 
    156 //===----------------------------------------------------------------------===//
    157 // ALU32 -
    158 //===----------------------------------------------------------------------===//
    159 
    160 
    161 //===----------------------------------------------------------------------===//
    162 // ALU32/PERM +
    163 //===----------------------------------------------------------------------===//
    164 
    165 // Combine
    166 // Rdd=combine(Rs, #s8)
    167 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
    168     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
    169 def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst),
    170             (ins IntRegs:$src1, s8Ext:$src2),
    171             "$dst = combine($src1, #$src2)",
    172             []>,
    173             Requires<[HasV4T]>;
    174 
    175 // Rdd=combine(#s8, Rs)
    176 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8,
    177     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
    178 def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst),
    179             (ins s8Ext:$src1, IntRegs:$src2),
    180             "$dst = combine(#$src1, $src2)",
    181             []>,
    182             Requires<[HasV4T]>;
    183 
    184 def HexagonWrapperCombineRI_V4 :
    185   SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>;
    186 def HexagonWrapperCombineIR_V4 :
    187   SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>;
    188 
    189 def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i),
    190            (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>,
    191           Requires<[HasV4T]>;
    192 
    193 def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r),
    194            (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>,
    195           Requires<[HasV4T]>;
    196 
    197 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6,
    198     neverHasSideEffects = 1, validSubTargets = HasV4SubT in
    199 def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst),
    200             (ins s8Imm:$src1, u6Ext:$src2),
    201             "$dst = combine(#$src1, #$src2)",
    202             []>,
    203             Requires<[HasV4T]>;
    204 
    205 //===----------------------------------------------------------------------===//
    206 // ALU32/PERM +
    207 //===----------------------------------------------------------------------===//
    208 
    209 //===----------------------------------------------------------------------===//
    210 // LD +
    211 //===----------------------------------------------------------------------===//
    212 //===----------------------------------------------------------------------===//
    213 // Template class for load instructions with Absolute set addressing mode.
    214 //===----------------------------------------------------------------------===//
    215 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
    216 validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
    217 class T_LD_abs_set<string mnemonic, RegisterClass RC>:
    218             LDInst2<(outs RC:$dst1, IntRegs:$dst2),
    219             (ins u0AlwaysExt:$addr),
    220             "$dst1 = "#mnemonic#"($dst2=##$addr)",
    221             []>,
    222             Requires<[HasV4T]>;
    223 
    224 def LDrid_abs_set_V4  : T_LD_abs_set <"memd", DoubleRegs>;
    225 def LDrib_abs_set_V4  : T_LD_abs_set <"memb", IntRegs>;
    226 def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
    227 def LDrih_abs_set_V4  : T_LD_abs_set <"memh", IntRegs>;
    228 def LDriw_abs_set_V4  : T_LD_abs_set <"memw", IntRegs>;
    229 def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
    230 
    231 
    232 // multiclass for load instructions with base + register offset
    233 // addressing mode
    234 multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot,
    235                              bit isPredNew> {
    236   let isPredicatedNew = isPredNew in
    237   def NAME : LDInst2<(outs RC:$dst),
    238             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset),
    239             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    240             ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)",
    241             []>, Requires<[HasV4T]>;
    242 }
    243 
    244 multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> {
    245   let isPredicatedFalse = PredNot in {
    246     defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>;
    247     // Predicate new
    248     defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>;
    249   }
    250 }
    251 
    252 let neverHasSideEffects  = 1 in
    253 multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
    254   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
    255     let isPredicable = 1 in
    256     def NAME#_V4 : LDInst2<(outs RC:$dst),
    257             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset),
    258             "$dst = "#mnemonic#"($src1+$src2<<#$offset)",
    259             []>, Requires<[HasV4T]>;
    260 
    261     let isPredicated = 1 in {
    262       defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >;
    263       defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>;
    264     }
    265   }
    266 }
    267 
    268 let addrMode = BaseRegOffset in {
    269   let accessSize = ByteAccess in {
    270     defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>,
    271                                         AddrModeRel;
    272     defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>,
    273                                         AddrModeRel;
    274   }
    275   let accessSize = HalfWordAccess in {
    276     defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
    277     defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>,
    278                              AddrModeRel;
    279   }
    280   let accessSize = WordAccess in
    281      defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
    282 
    283   let accessSize = DoubleWordAccess in
    284     defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>,
    285                              AddrModeRel;
    286 }
    287 
    288 // 'def pats' for load instructions with base + register offset and non-zero
    289 // immediate value. Immediate value is used to left-shift the second
    290 // register operand.
    291 let AddedComplexity = 40 in {
    292 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
    293                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
    294            (LDrib_indexed_shl_V4 IntRegs:$src1,
    295             IntRegs:$src2, u2ImmPred:$offset)>,
    296             Requires<[HasV4T]>;
    297 
    298 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
    299                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
    300            (LDriub_indexed_shl_V4 IntRegs:$src1,
    301             IntRegs:$src2, u2ImmPred:$offset)>,
    302             Requires<[HasV4T]>;
    303 
    304 def : Pat <(i32 (extloadi8 (add IntRegs:$src1,
    305                                 (shl IntRegs:$src2, u2ImmPred:$offset)))),
    306            (LDriub_indexed_shl_V4 IntRegs:$src1,
    307             IntRegs:$src2, u2ImmPred:$offset)>,
    308             Requires<[HasV4T]>;
    309 
    310 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1,
    311                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
    312            (LDrih_indexed_shl_V4 IntRegs:$src1,
    313             IntRegs:$src2, u2ImmPred:$offset)>,
    314             Requires<[HasV4T]>;
    315 
    316 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1,
    317                                   (shl IntRegs:$src2, u2ImmPred:$offset)))),
    318            (LDriuh_indexed_shl_V4 IntRegs:$src1,
    319             IntRegs:$src2, u2ImmPred:$offset)>,
    320             Requires<[HasV4T]>;
    321 
    322 def : Pat <(i32 (extloadi16 (add IntRegs:$src1,
    323                                  (shl IntRegs:$src2, u2ImmPred:$offset)))),
    324            (LDriuh_indexed_shl_V4 IntRegs:$src1,
    325             IntRegs:$src2, u2ImmPred:$offset)>,
    326             Requires<[HasV4T]>;
    327 
    328 def : Pat <(i32 (load (add IntRegs:$src1,
    329                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
    330            (LDriw_indexed_shl_V4 IntRegs:$src1,
    331             IntRegs:$src2, u2ImmPred:$offset)>,
    332             Requires<[HasV4T]>;
    333 
    334 def : Pat <(i64 (load (add IntRegs:$src1,
    335                            (shl IntRegs:$src2, u2ImmPred:$offset)))),
    336            (LDrid_indexed_shl_V4 IntRegs:$src1,
    337             IntRegs:$src2, u2ImmPred:$offset)>,
    338             Requires<[HasV4T]>;
    339 }
    340 
    341 
    342 // 'def pats' for load instruction base + register offset and
    343 // zero immediate value.
    344 let AddedComplexity = 10 in {
    345 def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))),
    346            (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    347             Requires<[HasV4T]>;
    348 
    349 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
    350            (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    351             Requires<[HasV4T]>;
    352 
    353 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))),
    354            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    355             Requires<[HasV4T]>;
    356 
    357 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))),
    358            (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    359             Requires<[HasV4T]>;
    360 
    361 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
    362            (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    363             Requires<[HasV4T]>;
    364 
    365 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))),
    366            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    367             Requires<[HasV4T]>;
    368 
    369 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))),
    370            (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    371             Requires<[HasV4T]>;
    372 
    373 def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))),
    374            (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>,
    375             Requires<[HasV4T]>;
    376 }
    377 
    378 // zext i1->i64
    379 def : Pat <(i64 (zext (i1 PredRegs:$src1))),
    380       (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>,
    381       Requires<[HasV4T]>;
    382 
    383 // zext i32->i64
    384 def : Pat <(i64 (zext (i32 IntRegs:$src1))),
    385       (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>,
    386       Requires<[HasV4T]>;
    387 // zext i8->i64
    388 def:  Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)),
    389       (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
    390       Requires<[HasV4T]>;
    391 
    392 let AddedComplexity = 20 in
    393 def:  Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1),
    394                                 s11_0ExtPred:$offset))),
    395       (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
    396                                   s11_0ExtPred:$offset)))>,
    397       Requires<[HasV4T]>;
    398 
    399 // zext i1->i64
    400 def:  Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)),
    401       (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>,
    402       Requires<[HasV4T]>;
    403 
    404 let AddedComplexity = 20 in
    405 def:  Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1),
    406                                 s11_0ExtPred:$offset))),
    407       (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1,
    408                                   s11_0ExtPred:$offset)))>,
    409       Requires<[HasV4T]>;
    410 
    411 // zext i16->i64
    412 def:  Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)),
    413       (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>,
    414       Requires<[HasV4T]>;
    415 
    416 let AddedComplexity = 20 in
    417 def:  Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1),
    418                                   s11_1ExtPred:$offset))),
    419       (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1,
    420                                   s11_1ExtPred:$offset)))>,
    421       Requires<[HasV4T]>;
    422 
    423 // anyext i16->i64
    424 def:  Pat <(i64 (extloadi16 ADDRriS11_2:$src1)),
    425       (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>,
    426       Requires<[HasV4T]>;
    427 
    428 let AddedComplexity = 20 in
    429 def:  Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1),
    430                                   s11_1ExtPred:$offset))),
    431       (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1,
    432                                   s11_1ExtPred:$offset)))>,
    433       Requires<[HasV4T]>;
    434 
    435 // zext i32->i64
    436 def:  Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)),
    437       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
    438       Requires<[HasV4T]>;
    439 
    440 let AddedComplexity = 100 in
    441 def:  Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
    442       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
    443                                   s11_2ExtPred:$offset)))>,
    444       Requires<[HasV4T]>;
    445 
    446 // anyext i32->i64
    447 def:  Pat <(i64 (extloadi32 ADDRriS11_2:$src1)),
    448       (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>,
    449       Requires<[HasV4T]>;
    450 
    451 let AddedComplexity = 100 in
    452 def:  Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))),
    453       (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1,
    454                                   s11_2ExtPred:$offset)))>,
    455       Requires<[HasV4T]>;
    456 
    457 
    458 
    459 //===----------------------------------------------------------------------===//
    460 // LD -
    461 //===----------------------------------------------------------------------===//
    462 
    463 //===----------------------------------------------------------------------===//
    464 // ST +
    465 //===----------------------------------------------------------------------===//
    466 ///
    467 //===----------------------------------------------------------------------===//
    468 // Template class for store instructions with Absolute set addressing mode.
    469 //===----------------------------------------------------------------------===//
    470 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT,
    471 addrMode = AbsoluteSet in
    472 class T_ST_abs_set<string mnemonic, RegisterClass RC>:
    473             STInst2<(outs IntRegs:$dst1),
    474             (ins RC:$src1, u0AlwaysExt:$src2),
    475             mnemonic#"($dst1=##$src2) = $src1",
    476             []>,
    477             Requires<[HasV4T]>;
    478 
    479 def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
    480 def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
    481 def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
    482 def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
    483 
    484 //===----------------------------------------------------------------------===//
    485 // multiclass for store instructions with base + register offset addressing
    486 // mode
    487 //===----------------------------------------------------------------------===//
    488 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
    489                              bit isPredNew> {
    490   let isPredicatedNew = isPredNew in
    491   def NAME : STInst2<(outs),
    492             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
    493                  RC:$src5),
    494             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    495             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5",
    496             []>,
    497             Requires<[HasV4T]>;
    498 }
    499 
    500 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
    501   let isPredicatedFalse = PredNot in {
    502     defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>;
    503     // Predicate new
    504     defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>;
    505   }
    506 }
    507 
    508 let isNVStorable = 1 in
    509 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> {
    510   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
    511     let isPredicable = 1 in
    512     def NAME#_V4 : STInst2<(outs),
    513             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
    514             mnemonic#"($src1+$src2<<#$src3) = $src4",
    515             []>,
    516             Requires<[HasV4T]>;
    517 
    518     let isPredicated = 1 in {
    519       defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >;
    520       defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>;
    521     }
    522   }
    523 }
    524 
    525 // multiclass for new-value store instructions with base + register offset
    526 // addressing mode.
    527 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
    528                              bit isPredNew> {
    529   let isPredicatedNew = isPredNew in
    530   def NAME#_nv_V4 : NVInst_V4<(outs),
    531             (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4,
    532                  RC:$src5),
    533             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    534             ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new",
    535             []>,
    536             Requires<[HasV4T]>;
    537 }
    538 
    539 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
    540   let isPredicatedFalse = PredNot in {
    541     defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>;
    542     // Predicate new
    543     defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>;
    544   }
    545 }
    546 
    547 let mayStore = 1, isNVStore = 1 in
    548 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> {
    549   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in {
    550     let isPredicable = 1 in
    551     def NAME#_nv_V4 : NVInst_V4<(outs),
    552             (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4),
    553             mnemonic#"($src1+$src2<<#$src3) = $src4.new",
    554             []>,
    555             Requires<[HasV4T]>;
    556 
    557     let isPredicated = 1 in {
    558       defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >;
    559       defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>;
    560     }
    561   }
    562 }
    563 
    564 let addrMode = BaseRegOffset, neverHasSideEffects = 1,
    565 validSubTargets = HasV4SubT in {
    566   let accessSize = ByteAccess in
    567     defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
    568                             ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
    569 
    570   let accessSize = HalfWordAccess in
    571     defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
    572                             ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
    573 
    574   let accessSize = WordAccess in
    575     defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
    576                             ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
    577 
    578   let isNVStorable = 0, accessSize = DoubleWordAccess in
    579     defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
    580 }
    581 
    582 let Predicates = [HasV4T], AddedComplexity = 10 in {
    583 def : Pat<(truncstorei8 (i32 IntRegs:$src4),
    584                        (add IntRegs:$src1, (shl IntRegs:$src2,
    585                                                 u2ImmPred:$src3))),
    586           (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
    587                                 u2ImmPred:$src3, IntRegs:$src4)>;
    588 
    589 def : Pat<(truncstorei16 (i32 IntRegs:$src4),
    590                         (add IntRegs:$src1, (shl IntRegs:$src2,
    591                                                  u2ImmPred:$src3))),
    592           (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
    593                                 u2ImmPred:$src3, IntRegs:$src4)>;
    594 
    595 def : Pat<(store (i32 IntRegs:$src4),
    596                  (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
    597           (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
    598                                 u2ImmPred:$src3, IntRegs:$src4)>;
    599 
    600 def : Pat<(store (i64 DoubleRegs:$src4),
    601                 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))),
    602           (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2,
    603                                 u2ImmPred:$src3, DoubleRegs:$src4)>;
    604 }
    605 
    606 let isExtended = 1, opExtendable = 2 in
    607 class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> :
    608             STInst<(outs),
    609             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4),
    610             mnemonic#"($src1<<#$src2+##$src3) = $src4",
    611             [(stOp (VT RC:$src4),
    612                     (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
    613                          u0AlwaysExtPred:$src3))]>,
    614             Requires<[HasV4T]>;
    615 
    616 let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in
    617 class T_ST_LongOff_nv <string mnemonic> :
    618             NVInst_V4<(outs),
    619             (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
    620             mnemonic#"($src1<<#$src2+##$src3) = $src4.new",
    621             []>,
    622             Requires<[HasV4T]>;
    623 
    624 multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> {
    625   let  BaseOpcode = BaseOp#"_shl" in {
    626     let isNVStorable = 1 in
    627     def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>;
    628 
    629     def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>;
    630   }
    631 }
    632 
    633 let AddedComplexity = 10, validSubTargets = HasV4SubT in {
    634   def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>;
    635   defm STrib_shl   : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel;
    636   defm STrih_shl   : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel;
    637   defm STriw_shl   : ST_LongOff <"memw", "STriw", store>, NewValueRel;
    638 }
    639 
    640 let AddedComplexity = 40 in
    641 multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT,
    642                            PatFrag stOp> {
    643  def : Pat<(stOp (VT RC:$src4),
    644            (add (shl IntRegs:$src1, u2ImmPred:$src2),
    645                (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
    646            (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
    647 
    648  def : Pat<(stOp (VT RC:$src4),
    649            (add IntRegs:$src1,
    650                (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
    651            (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
    652 }
    653 
    654 defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>;
    655 defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>;
    656 defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>;
    657 defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
    658 
    659 // memd(Rx++#s4:3)=Rtt
    660 // memd(Rx++#s4:3:circ(Mu))=Rtt
    661 // memd(Rx++I:circ(Mu))=Rtt
    662 // memd(Rx++Mu)=Rtt
    663 // memd(Rx++Mu:brev)=Rtt
    664 // memd(gp+#u16:3)=Rtt
    665 
    666 // Store doubleword conditionally.
    667 // if ([!]Pv[.new]) memd(#u6)=Rtt
    668 // TODO: needs to be implemented.
    669 
    670 //===----------------------------------------------------------------------===//
    671 // multiclass for store instructions with base + immediate offset
    672 // addressing mode and immediate stored value.
    673 // mem[bhw](Rx++#s4:3)=#s8
    674 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6
    675 //===----------------------------------------------------------------------===//
    676 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot,
    677                         bit isPredNew> {
    678   let isPredicatedNew = isPredNew in
    679   def NAME : STInst2<(outs),
    680             (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4),
    681             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    682             ") ")#mnemonic#"($src2+#$src3) = #$src4",
    683             []>,
    684             Requires<[HasV4T]>;
    685 }
    686 
    687 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> {
    688   let isPredicatedFalse = PredNot in {
    689     defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>;
    690     // Predicate new
    691     defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>;
    692   }
    693 }
    694 
    695 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in
    696 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> {
    697   let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in {
    698     let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in
    699     def NAME#_V4 : STInst2<(outs),
    700             (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3),
    701             mnemonic#"($src1+#$src2) = #$src3",
    702             []>,
    703             Requires<[HasV4T]>;
    704 
    705     let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in {
    706       defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>;
    707       defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >;
    708     }
    709   }
    710 }
    711 
    712 let addrMode = BaseImmOffset, InputType = "imm",
    713 validSubTargets = HasV4SubT in {
    714   let accessSize = ByteAccess in
    715     defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
    716 
    717   let accessSize = HalfWordAccess in
    718     defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
    719 
    720   let accessSize = WordAccess in
    721     defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
    722 }
    723 
    724 let Predicates = [HasV4T], AddedComplexity = 10 in {
    725 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)),
    726             (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>;
    727 
    728 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1,
    729                                               u6_1ImmPred:$src2)),
    730             (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>;
    731 
    732 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)),
    733             (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>;
    734 }
    735 
    736 let AddedComplexity = 6 in
    737 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)),
    738            (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
    739            Requires<[HasV4T]>;
    740 
    741 // memb(Rx++#s4:0:circ(Mu))=Rt
    742 // memb(Rx++I:circ(Mu))=Rt
    743 // memb(Rx++Mu)=Rt
    744 // memb(Rx++Mu:brev)=Rt
    745 // memb(gp+#u16:0)=Rt
    746 
    747 
    748 // Store halfword.
    749 // TODO: needs to be implemented
    750 // memh(Re=#U6)=Rt.H
    751 // memh(Rs+#s11:1)=Rt.H
    752 let AddedComplexity = 6 in
    753 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)),
    754            (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
    755            Requires<[HasV4T]>;
    756 
    757 // memh(Rs+Ru<<#u2)=Rt.H
    758 // TODO: needs to be implemented.
    759 
    760 // memh(Ru<<#u2+#U6)=Rt.H
    761 // memh(Rx++#s4:1:circ(Mu))=Rt.H
    762 // memh(Rx++#s4:1:circ(Mu))=Rt
    763 // memh(Rx++I:circ(Mu))=Rt.H
    764 // memh(Rx++I:circ(Mu))=Rt
    765 // memh(Rx++Mu)=Rt.H
    766 // memh(Rx++Mu)=Rt
    767 // memh(Rx++Mu:brev)=Rt.H
    768 // memh(Rx++Mu:brev)=Rt
    769 // memh(gp+#u16:1)=Rt
    770 // if ([!]Pv[.new]) memh(#u6)=Rt.H
    771 // if ([!]Pv[.new]) memh(#u6)=Rt
    772 
    773 
    774 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H
    775 // TODO: needs to be implemented.
    776 
    777 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H
    778 // TODO: Needs to be implemented.
    779 
    780 // Store word.
    781 // memw(Re=#U6)=Rt
    782 // TODO: Needs to be implemented.
    783 
    784 // Store predicate:
    785 let neverHasSideEffects = 1 in
    786 def STriw_pred_V4 : STInst2<(outs),
    787             (ins MEMri:$addr, PredRegs:$src1),
    788             "Error; should not emit",
    789             []>,
    790             Requires<[HasV4T]>;
    791 
    792 let AddedComplexity = 6 in
    793 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)),
    794            (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
    795            Requires<[HasV4T]>;
    796 
    797 // memw(Rx++#s4:2)=Rt
    798 // memw(Rx++#s4:2:circ(Mu))=Rt
    799 // memw(Rx++I:circ(Mu))=Rt
    800 // memw(Rx++Mu)=Rt
    801 // memw(Rx++Mu:brev)=Rt
    802 
    803 //===----------------------------------------------------------------------===
    804 // ST -
    805 //===----------------------------------------------------------------------===
    806 
    807 
    808 //===----------------------------------------------------------------------===//
    809 // NV/ST +
    810 //===----------------------------------------------------------------------===//
    811 
    812 // multiclass for new-value store instructions with base + immediate offset.
    813 //
    814 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC,
    815                             Operand predImmOp, bit isNot, bit isPredNew> {
    816   let isPredicatedNew = isPredNew in
    817   def NAME#_nv_V4 : NVInst_V4<(outs),
    818             (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4),
    819             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    820             ") ")#mnemonic#"($src2+#$src3) = $src4.new",
    821             []>,
    822             Requires<[HasV4T]>;
    823 }
    824 
    825 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp,
    826                            bit PredNot> {
    827   let isPredicatedFalse = PredNot in {
    828     defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>;
    829     // Predicate new
    830     defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>;
    831   }
    832 }
    833 
    834 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in
    835 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC,
    836                    Operand ImmOp, Operand predImmOp, bits<5> ImmBits,
    837                    bits<5> PredImmBits> {
    838 
    839   let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in {
    840     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
    841     isPredicable = 1 in
    842     def NAME#_nv_V4 : NVInst_V4<(outs),
    843             (ins IntRegs:$src1, ImmOp:$src2, RC:$src3),
    844             mnemonic#"($src1+#$src2) = $src3.new",
    845             []>,
    846             Requires<[HasV4T]>;
    847 
    848     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
    849     isPredicated = 1 in {
    850       defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>;
    851       defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>;
    852     }
    853   }
    854 }
    855 
    856 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
    857   let accessSize = ByteAccess in
    858     defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
    859                                    u6_0Ext, 11, 6>, AddrModeRel;
    860 
    861   let accessSize = HalfWordAccess in
    862     defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
    863                                    u6_1Ext, 12, 7>, AddrModeRel;
    864 
    865   let accessSize = WordAccess in
    866     defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
    867                                    u6_2Ext, 13, 8>, AddrModeRel;
    868 }
    869 
    870 // multiclass for new-value store instructions with base + immediate offset.
    871 // and MEMri operand.
    872 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot,
    873                           bit isPredNew> {
    874   let isPredicatedNew = isPredNew in
    875   def NAME#_nv_V4 : NVInst_V4<(outs),
    876             (ins PredRegs:$src1, MEMri:$addr, RC: $src2),
    877             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    878             ") ")#mnemonic#"($addr) = $src2.new",
    879             []>,
    880             Requires<[HasV4T]>;
    881 }
    882 
    883 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
    884   let isPredicatedFalse = PredNot in {
    885     defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>;
    886 
    887     // Predicate new
    888     defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>;
    889   }
    890 }
    891 
    892 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in
    893 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC,
    894                     bits<5> ImmBits, bits<5> PredImmBits> {
    895 
    896   let CextOpcode = CextOp, BaseOpcode = CextOp in {
    897     let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits,
    898          isPredicable = 1 in
    899     def NAME#_nv_V4 : NVInst_V4<(outs),
    900             (ins MEMri:$addr, RC:$src),
    901             mnemonic#"($addr) = $src.new",
    902             []>,
    903             Requires<[HasV4T]>;
    904 
    905     let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits,
    906         neverHasSideEffects = 1, isPredicated = 1 in {
    907       defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>;
    908       defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>;
    909     }
    910   }
    911 }
    912 
    913 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
    914 mayStore = 1 in {
    915   let accessSize = ByteAccess in
    916     defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
    917 
    918   let accessSize = HalfWordAccess in
    919     defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
    920 
    921   let accessSize = WordAccess in
    922     defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
    923 }
    924 
    925 //===----------------------------------------------------------------------===//
    926 // Post increment store
    927 // mem[bhwd](Rx++#s4:[0123])=Nt.new
    928 //===----------------------------------------------------------------------===//
    929 
    930 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp,
    931                             bit isNot, bit isPredNew> {
    932   let isPredicatedNew = isPredNew in
    933   def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
    934             (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3),
    935             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
    936             ") ")#mnemonic#"($src2++#$offset) = $src3.new",
    937             [],
    938             "$src2 = $dst">,
    939             Requires<[HasV4T]>;
    940 }
    941 
    942 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC,
    943                            Operand ImmOp, bit PredNot> {
    944   let isPredicatedFalse = PredNot in {
    945     defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>;
    946     // Predicate new
    947     let Predicates = [HasV4T], validSubTargets = HasV4SubT in
    948     defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>;
    949   }
    950 }
    951 
    952 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in
    953 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC,
    954                       Operand ImmOp> {
    955 
    956   let BaseOpcode = "POST_"#BaseOp in {
    957     let isPredicable = 1 in
    958     def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst),
    959                 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2),
    960                 mnemonic#"($src1++#$offset) = $src2.new",
    961                 [],
    962                 "$src1 = $dst">,
    963                 Requires<[HasV4T]>;
    964 
    965     let isPredicated = 1 in {
    966       defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >;
    967       defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >;
    968     }
    969   }
    970 }
    971 
    972 let addrMode = PostInc, validSubTargets = HasV4SubT in {
    973 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
    974 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
    975 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
    976 }
    977 
    978 // memb(Rx++#s4:0:circ(Mu))=Nt.new
    979 // memb(Rx++I:circ(Mu))=Nt.new
    980 // memb(Rx++Mu)=Nt.new
    981 // memb(Rx++Mu:brev)=Nt.new
    982 // memh(Rx++#s4:1:circ(Mu))=Nt.new
    983 // memh(Rx++I:circ(Mu))=Nt.new
    984 // memh(Rx++Mu)=Nt.new
    985 // memh(Rx++Mu:brev)=Nt.new
    986 
    987 // memw(Rx++#s4:2:circ(Mu))=Nt.new
    988 // memw(Rx++I:circ(Mu))=Nt.new
    989 // memw(Rx++Mu)=Nt.new
    990 // memw(Rx++Mu:brev)=Nt.new
    991 
    992 //===----------------------------------------------------------------------===//
    993 // NV/ST -
    994 //===----------------------------------------------------------------------===//
    995 
    996 //===----------------------------------------------------------------------===//
    997 // NV/J +
    998 //===----------------------------------------------------------------------===//
    999 
   1000 //===----------------------------------------------------------------------===//
   1001 // multiclass/template class for the new-value compare jumps with the register
   1002 // operands.
   1003 //===----------------------------------------------------------------------===//
   1004 
   1005 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
   1006 class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
   1007                       bit isNegCond, bit isTak>
   1008   : NVInst_V4<(outs),
   1009     (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
   1010     "if ("#!if(isNegCond, "!","")#mnemonic#
   1011     "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
   1012     "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:"
   1013     #!if(isTak, "t","nt")#" $offset",
   1014     []>, Requires<[HasV4T]> {
   1015 
   1016       bits<5> src1;
   1017       bits<5> src2;
   1018       bits<3> Ns;    // New-Value Operand
   1019       bits<5> RegOp; // Non-New-Value Operand
   1020       bits<11> offset;
   1021 
   1022       let isTaken = isTak;
   1023       let isBrTaken = !if(isTaken, "true", "false");
   1024       let isPredicatedFalse = isNegCond;
   1025 
   1026       let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
   1027       let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
   1028 
   1029       let IClass = 0b0010;
   1030       let Inst{26} = 0b0;
   1031       let Inst{25-23} = majOp;
   1032       let Inst{22} = isNegCond;
   1033       let Inst{18-16} = Ns;
   1034       let Inst{13} = isTak;
   1035       let Inst{12-8} = RegOp;
   1036       let Inst{21-20} = offset{10-9};
   1037       let Inst{7-1} = offset{8-2};
   1038 }
   1039 
   1040 
   1041 multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
   1042                        bit isNegCond> {
   1043   // Branch not taken:
   1044   def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
   1045   // Branch taken:
   1046   def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
   1047 }
   1048 
   1049 // NvOpNum = 0 -> First Operand is a new-value Register
   1050 // NvOpNum = 1 -> Second Operand is a new-value Register
   1051 
   1052 multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
   1053                        bit NvOpNum> {
   1054   let BaseOpcode = BaseOp#_NVJ in {
   1055     defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
   1056     defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
   1057   }
   1058 }
   1059 
   1060 // if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
   1061 // if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
   1062 // if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
   1063 // if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
   1064 // if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
   1065 
   1066 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
   1067   Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
   1068   defm CMPEQrr  : NVJrr_base<"cmp.eq",  "CMPEQ",  0b000, 0>, PredRel;
   1069   defm CMPGTrr  : NVJrr_base<"cmp.gt",  "CMPGT",  0b001, 0>, PredRel;
   1070   defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
   1071   defm CMPLTrr  : NVJrr_base<"cmp.gt",  "CMPLT",  0b011, 1>, PredRel;
   1072   defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
   1073 }
   1074 
   1075 //===----------------------------------------------------------------------===//
   1076 // multiclass/template class for the new-value compare jumps instruction
   1077 // with a register and an unsigned immediate (U5) operand.
   1078 //===----------------------------------------------------------------------===//
   1079 
   1080 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
   1081 class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
   1082                          bit isTak>
   1083   : NVInst_V4<(outs),
   1084     (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
   1085     "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
   1086     #!if(isTak, "t","nt")#" $offset",
   1087     []>, Requires<[HasV4T]> {
   1088 
   1089       let isTaken = isTak;
   1090       let isPredicatedFalse = isNegCond;
   1091       let isBrTaken = !if(isTaken, "true", "false");
   1092 
   1093       bits<3> src1;
   1094       bits<5> src2;
   1095       bits<11> offset;
   1096 
   1097       let IClass = 0b0010;
   1098       let Inst{26} = 0b1;
   1099       let Inst{25-23} = majOp;
   1100       let Inst{22} = isNegCond;
   1101       let Inst{18-16} = src1;
   1102       let Inst{13} = isTak;
   1103       let Inst{12-8} = src2;
   1104       let Inst{21-20} = offset{10-9};
   1105       let Inst{7-1} = offset{8-2};
   1106 }
   1107 
   1108 multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
   1109   // Branch not taken:
   1110   def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
   1111   // Branch taken:
   1112   def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
   1113 }
   1114 
   1115 multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
   1116   let BaseOpcode = BaseOp#_NVJri in {
   1117     defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
   1118     defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
   1119   }
   1120 }
   1121 
   1122 // if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2
   1123 // if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2
   1124 // if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
   1125 
   1126 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
   1127   Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
   1128   defm CMPEQri  : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
   1129   defm CMPGTri  : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
   1130   defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
   1131 }
   1132 
   1133 //===----------------------------------------------------------------------===//
   1134 // multiclass/template class for the new-value compare jumps instruction
   1135 // with a register and an hardcoded 0/-1 immediate value.
   1136 //===----------------------------------------------------------------------===//
   1137 
   1138 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
   1139 class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
   1140                             bit isNegCond, bit isTak>
   1141   : NVInst_V4<(outs),
   1142     (ins IntRegs:$src1, brtarget:$offset),
   1143     "if ("#!if(isNegCond, "!","")#mnemonic
   1144     #"($src1.new, #"#ImmVal#")) jump:"
   1145     #!if(isTak, "t","nt")#" $offset",
   1146     []>, Requires<[HasV4T]> {
   1147 
   1148       let isTaken = isTak;
   1149       let isPredicatedFalse = isNegCond;
   1150       let isBrTaken = !if(isTaken, "true", "false");
   1151 
   1152       bits<3> src1;
   1153       bits<11> offset;
   1154       let IClass = 0b0010;
   1155       let Inst{26} = 0b1;
   1156       let Inst{25-23} = majOp;
   1157       let Inst{22} = isNegCond;
   1158       let Inst{18-16} = src1;
   1159       let Inst{13} = isTak;
   1160       let Inst{21-20} = offset{10-9};
   1161       let Inst{7-1} = offset{8-2};
   1162 }
   1163 
   1164 multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
   1165                              bit isNegCond> {
   1166   // Branch not taken:
   1167   def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
   1168   // Branch taken:
   1169   def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
   1170 }
   1171 
   1172 multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
   1173                              string ImmVal> {
   1174   let BaseOpcode = BaseOp#_NVJ_ConstImm in {
   1175   defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
   1176   defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
   1177   }
   1178 }
   1179 
   1180 // if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2
   1181 // if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2
   1182 // if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
   1183 
   1184 let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
   1185   Defs = [PC], neverHasSideEffects = 1 in {
   1186   defm TSTBIT0  : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
   1187   defm CMPEQn1  : NVJ_ConstImm_base<"cmp.eq", "CMPEQ",  0b100, "-1">, PredRel;
   1188   defm CMPGTn1  : NVJ_ConstImm_base<"cmp.gt", "CMPGT",  0b101, "-1">, PredRel;
   1189 }
   1190 
   1191 //===----------------------------------------------------------------------===//
   1192 // XTYPE/ALU +
   1193 //===----------------------------------------------------------------------===//
   1194 
   1195 //  Add and accumulate.
   1196 //  Rd=add(Rs,add(Ru,#s6))
   1197 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6,
   1198 validSubTargets = HasV4SubT in
   1199 def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst),
   1200           (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3),
   1201           "$dst = add($src1, add($src2, #$src3))",
   1202           [(set (i32 IntRegs:$dst),
   1203            (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2),
   1204                                           s6_16ExtPred:$src3)))]>,
   1205           Requires<[HasV4T]>;
   1206 
   1207 //  Rd=add(Rs,sub(#s6,Ru))
   1208 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
   1209 validSubTargets = HasV4SubT in
   1210 def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst),
   1211           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
   1212           "$dst = add($src1, sub(#$src2, $src3))",
   1213           [(set (i32 IntRegs:$dst),
   1214            (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2,
   1215                                           (i32 IntRegs:$src3))))]>,
   1216           Requires<[HasV4T]>;
   1217 
   1218 // Generates the same instruction as ADDr_SUBri_V4 but matches different
   1219 // pattern.
   1220 //  Rd=add(Rs,sub(#s6,Ru))
   1221 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6,
   1222 validSubTargets = HasV4SubT in
   1223 def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst),
   1224           (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3),
   1225           "$dst = add($src1, sub(#$src2, $src3))",
   1226           [(set (i32 IntRegs:$dst),
   1227                 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2),
   1228                      (i32 IntRegs:$src3)))]>,
   1229           Requires<[HasV4T]>;
   1230 
   1231 
   1232 //  Add or subtract doublewords with carry.
   1233 //TODO:
   1234 //  Rdd=add(Rss,Rtt,Px):carry
   1235 //TODO:
   1236 //  Rdd=sub(Rss,Rtt,Px):carry
   1237 
   1238 
   1239 //  Logical doublewords.
   1240 //  Rdd=and(Rtt,~Rss)
   1241 let validSubTargets = HasV4SubT in
   1242 def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
   1243           (ins DoubleRegs:$src1, DoubleRegs:$src2),
   1244           "$dst = and($src1, ~$src2)",
   1245           [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1),
   1246                                       (not (i64 DoubleRegs:$src2))))]>,
   1247           Requires<[HasV4T]>;
   1248 
   1249 //  Rdd=or(Rtt,~Rss)
   1250 let validSubTargets = HasV4SubT in
   1251 def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst),
   1252           (ins DoubleRegs:$src1, DoubleRegs:$src2),
   1253           "$dst = or($src1, ~$src2)",
   1254           [(set (i64 DoubleRegs:$dst),
   1255            (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>,
   1256           Requires<[HasV4T]>;
   1257 
   1258 
   1259 //  Logical-logical doublewords.
   1260 //  Rxx^=xor(Rss,Rtt)
   1261 let validSubTargets = HasV4SubT in
   1262 def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst),
   1263           (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3),
   1264           "$dst ^= xor($src2, $src3)",
   1265           [(set (i64 DoubleRegs:$dst),
   1266            (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2),
   1267                                              (i64 DoubleRegs:$src3))))],
   1268           "$src1 = $dst">,
   1269           Requires<[HasV4T]>;
   1270 
   1271 
   1272 // Logical-logical words.
   1273 // Rx=or(Ru,and(Rx,#s10))
   1274 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
   1275 validSubTargets = HasV4SubT in
   1276 def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst),
   1277             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
   1278             "$dst = or($src1, and($src2, #$src3))",
   1279             [(set (i32 IntRegs:$dst),
   1280                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1281                                                 s10ExtPred:$src3)))],
   1282             "$src2 = $dst">,
   1283             Requires<[HasV4T]>;
   1284 
   1285 // Rx[&|^]=and(Rs,Rt)
   1286 // Rx&=and(Rs,Rt)
   1287 let validSubTargets = HasV4SubT in
   1288 def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1289             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1290             "$dst &= and($src2, $src3)",
   1291             [(set (i32 IntRegs:$dst),
   1292                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1293                                                  (i32 IntRegs:$src3))))],
   1294             "$src1 = $dst">,
   1295             Requires<[HasV4T]>;
   1296 
   1297 // Rx|=and(Rs,Rt)
   1298 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in
   1299 def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1300             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1301             "$dst |= and($src2, $src3)",
   1302             [(set (i32 IntRegs:$dst),
   1303                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1304                                                 (i32 IntRegs:$src3))))],
   1305             "$src1 = $dst">,
   1306             Requires<[HasV4T]>, ImmRegRel;
   1307 
   1308 // Rx^=and(Rs,Rt)
   1309 let validSubTargets = HasV4SubT in
   1310 def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1311             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1312             "$dst ^= and($src2, $src3)",
   1313             [(set (i32 IntRegs:$dst),
   1314              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1315                                             (i32 IntRegs:$src3))))],
   1316             "$src1 = $dst">,
   1317             Requires<[HasV4T]>;
   1318 
   1319 // Rx[&|^]=and(Rs,~Rt)
   1320 // Rx&=and(Rs,~Rt)
   1321 let validSubTargets = HasV4SubT in
   1322 def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
   1323             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1324             "$dst &= and($src2, ~$src3)",
   1325             [(set (i32 IntRegs:$dst),
   1326                   (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1327                                                  (not (i32 IntRegs:$src3)))))],
   1328             "$src1 = $dst">,
   1329             Requires<[HasV4T]>;
   1330 
   1331 // Rx|=and(Rs,~Rt)
   1332 let validSubTargets = HasV4SubT in
   1333 def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
   1334             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1335             "$dst |= and($src2, ~$src3)",
   1336             [(set (i32 IntRegs:$dst),
   1337              (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1338                                            (not (i32 IntRegs:$src3)))))],
   1339             "$src1 = $dst">,
   1340             Requires<[HasV4T]>;
   1341 
   1342 // Rx^=and(Rs,~Rt)
   1343 let validSubTargets = HasV4SubT in
   1344 def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst),
   1345             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1346             "$dst ^= and($src2, ~$src3)",
   1347             [(set (i32 IntRegs:$dst),
   1348              (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1349                                             (not (i32 IntRegs:$src3)))))],
   1350             "$src1 = $dst">,
   1351             Requires<[HasV4T]>;
   1352 
   1353 // Rx[&|^]=or(Rs,Rt)
   1354 // Rx&=or(Rs,Rt)
   1355 let validSubTargets = HasV4SubT in
   1356 def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1357             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1358             "$dst &= or($src2, $src3)",
   1359             [(set (i32 IntRegs:$dst),
   1360                   (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
   1361                                                 (i32 IntRegs:$src3))))],
   1362             "$src1 = $dst">,
   1363             Requires<[HasV4T]>;
   1364 
   1365 // Rx|=or(Rs,Rt)
   1366 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in
   1367 def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1368             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1369             "$dst |= or($src2, $src3)",
   1370             [(set (i32 IntRegs:$dst),
   1371                   (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
   1372                                                (i32 IntRegs:$src3))))],
   1373             "$src1 = $dst">,
   1374             Requires<[HasV4T]>, ImmRegRel;
   1375 
   1376 // Rx^=or(Rs,Rt)
   1377 let validSubTargets = HasV4SubT in
   1378 def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1379             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1380             "$dst ^= or($src2, $src3)",
   1381             [(set (i32 IntRegs:$dst),
   1382              (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2),
   1383                                            (i32 IntRegs:$src3))))],
   1384             "$src1 = $dst">,
   1385             Requires<[HasV4T]>;
   1386 
   1387 // Rx[&|^]=xor(Rs,Rt)
   1388 // Rx&=xor(Rs,Rt)
   1389 let validSubTargets = HasV4SubT in
   1390 def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1391             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1392             "$dst &= xor($src2, $src3)",
   1393             [(set (i32 IntRegs:$dst),
   1394                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
   1395                                                  (i32 IntRegs:$src3))))],
   1396             "$src1 = $dst">,
   1397             Requires<[HasV4T]>;
   1398 
   1399 // Rx|=xor(Rs,Rt)
   1400 let validSubTargets = HasV4SubT in
   1401 def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1402             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1403             "$dst |= xor($src2, $src3)",
   1404             [(set (i32 IntRegs:$dst),
   1405                   (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
   1406                                                  (i32 IntRegs:$src3))))],
   1407             "$src1 = $dst">,
   1408             Requires<[HasV4T]>;
   1409 
   1410 // Rx^=xor(Rs,Rt)
   1411 let validSubTargets = HasV4SubT in
   1412 def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1413             (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3),
   1414             "$dst ^= xor($src2, $src3)",
   1415             [(set (i32 IntRegs:$dst),
   1416              (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2),
   1417                                             (i32 IntRegs:$src3))))],
   1418             "$src1 = $dst">,
   1419             Requires<[HasV4T]>;
   1420 
   1421 // Rx|=and(Rs,#s10)
   1422 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
   1423 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in
   1424 def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst),
   1425             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
   1426             "$dst |= and($src2, #$src3)",
   1427             [(set (i32 IntRegs:$dst),
   1428                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1429                                                 s10ExtPred:$src3)))],
   1430             "$src1 = $dst">,
   1431             Requires<[HasV4T]>, ImmRegRel;
   1432 
   1433 // Rx|=or(Rs,#s10)
   1434 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10,
   1435 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in
   1436 def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst),
   1437             (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3),
   1438             "$dst |= or($src2, #$src3)",
   1439             [(set (i32 IntRegs:$dst),
   1440                   (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2),
   1441                                                 s10ExtPred:$src3)))],
   1442             "$src1 = $dst">,
   1443             Requires<[HasV4T]>, ImmRegRel;
   1444 
   1445 
   1446 //    Modulo wrap
   1447 //        Rd=modwrap(Rs,Rt)
   1448 //    Round
   1449 //        Rd=cround(Rs,#u5)
   1450 //        Rd=cround(Rs,Rt)
   1451 //        Rd=round(Rs,#u5)[:sat]
   1452 //        Rd=round(Rs,Rt)[:sat]
   1453 //    Vector reduce add unsigned halfwords
   1454 //        Rd=vraddh(Rss,Rtt)
   1455 //    Vector add bytes
   1456 //        Rdd=vaddb(Rss,Rtt)
   1457 //    Vector conditional negate
   1458 //        Rdd=vcnegh(Rss,Rt)
   1459 //        Rxx+=vrcnegh(Rss,Rt)
   1460 //    Vector maximum bytes
   1461 //        Rdd=vmaxb(Rtt,Rss)
   1462 //    Vector reduce maximum halfwords
   1463 //        Rxx=vrmaxh(Rss,Ru)
   1464 //        Rxx=vrmaxuh(Rss,Ru)
   1465 //    Vector reduce maximum words
   1466 //        Rxx=vrmaxuw(Rss,Ru)
   1467 //        Rxx=vrmaxw(Rss,Ru)
   1468 //    Vector minimum bytes
   1469 //        Rdd=vminb(Rtt,Rss)
   1470 //    Vector reduce minimum halfwords
   1471 //        Rxx=vrminh(Rss,Ru)
   1472 //        Rxx=vrminuh(Rss,Ru)
   1473 //    Vector reduce minimum words
   1474 //        Rxx=vrminuw(Rss,Ru)
   1475 //        Rxx=vrminw(Rss,Ru)
   1476 //    Vector subtract bytes
   1477 //        Rdd=vsubb(Rss,Rtt)
   1478 
   1479 //===----------------------------------------------------------------------===//
   1480 // XTYPE/ALU -
   1481 //===----------------------------------------------------------------------===//
   1482 
   1483 
   1484 //===----------------------------------------------------------------------===//
   1485 // XTYPE/MPY +
   1486 //===----------------------------------------------------------------------===//
   1487 
   1488 // Multiply and user lower result.
   1489 // Rd=add(#u6,mpyi(Rs,#U6))
   1490 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
   1491 validSubTargets = HasV4SubT in
   1492 def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst),
   1493             (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3),
   1494             "$dst = add(#$src1, mpyi($src2, #$src3))",
   1495             [(set (i32 IntRegs:$dst),
   1496                   (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
   1497                        u6ExtPred:$src1))]>,
   1498             Requires<[HasV4T]>;
   1499 
   1500 // Rd=add(##,mpyi(Rs,#U6))
   1501 def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3),
   1502                      (HexagonCONST32 tglobaladdr:$src1)),
   1503            (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2,
   1504                                u6ImmPred:$src3))>;
   1505 
   1506 // Rd=add(#u6,mpyi(Rs,Rt))
   1507 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6,
   1508 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
   1509 def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst),
   1510             (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3),
   1511             "$dst = add(#$src1, mpyi($src2, $src3))",
   1512             [(set (i32 IntRegs:$dst),
   1513                   (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
   1514                        u6ExtPred:$src1))]>,
   1515             Requires<[HasV4T]>, ImmRegRel;
   1516 
   1517 // Rd=add(##,mpyi(Rs,Rt))
   1518 def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)),
   1519                      (HexagonCONST32 tglobaladdr:$src1)),
   1520            (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2,
   1521                                IntRegs:$src3))>;
   1522 
   1523 // Rd=add(Ru,mpyi(#u6:2,Rs))
   1524 let validSubTargets = HasV4SubT in
   1525 def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst),
   1526             (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3),
   1527             "$dst = add($src1, mpyi(#$src2, $src3))",
   1528             [(set (i32 IntRegs:$dst),
   1529              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3),
   1530                                             u6_2ImmPred:$src2)))]>,
   1531             Requires<[HasV4T]>;
   1532 
   1533 // Rd=add(Ru,mpyi(Rs,#u6))
   1534 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6,
   1535 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in
   1536 def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst),
   1537             (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3),
   1538             "$dst = add($src1, mpyi($src2, #$src3))",
   1539             [(set (i32 IntRegs:$dst),
   1540                   (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
   1541                                                  u6ExtPred:$src3)))]>,
   1542             Requires<[HasV4T]>, ImmRegRel;
   1543 
   1544 // Rx=add(Ru,mpyi(Rx,Rs))
   1545 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in
   1546 def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst),
   1547             (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3),
   1548             "$dst = add($src1, mpyi($src2, $src3))",
   1549             [(set (i32 IntRegs:$dst),
   1550              (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2),
   1551                                             (i32 IntRegs:$src3))))],
   1552             "$src2 = $dst">,
   1553             Requires<[HasV4T]>, ImmRegRel;
   1554 
   1555 
   1556 // Polynomial multiply words
   1557 // Rdd=pmpyw(Rs,Rt)
   1558 // Rxx^=pmpyw(Rs,Rt)
   1559 
   1560 // Vector reduce multiply word by signed half (32x16)
   1561 // Rdd=vrmpyweh(Rss,Rtt)[:<<1]
   1562 // Rdd=vrmpywoh(Rss,Rtt)[:<<1]
   1563 // Rxx+=vrmpyweh(Rss,Rtt)[:<<1]
   1564 // Rxx+=vrmpywoh(Rss,Rtt)[:<<1]
   1565 
   1566 // Multiply and use upper result
   1567 // Rd=mpy(Rs,Rt.H):<<1:sat
   1568 // Rd=mpy(Rs,Rt.L):<<1:sat
   1569 // Rd=mpy(Rs,Rt):<<1
   1570 // Rd=mpy(Rs,Rt):<<1:sat
   1571 // Rd=mpysu(Rs,Rt)
   1572 // Rx+=mpy(Rs,Rt):<<1:sat
   1573 // Rx-=mpy(Rs,Rt):<<1:sat
   1574 
   1575 // Vector multiply bytes
   1576 // Rdd=vmpybsu(Rs,Rt)
   1577 // Rdd=vmpybu(Rs,Rt)
   1578 // Rxx+=vmpybsu(Rs,Rt)
   1579 // Rxx+=vmpybu(Rs,Rt)
   1580 
   1581 // Vector polynomial multiply halfwords
   1582 // Rdd=vpmpyh(Rs,Rt)
   1583 // Rxx^=vpmpyh(Rs,Rt)
   1584 
   1585 //===----------------------------------------------------------------------===//
   1586 // XTYPE/MPY -
   1587 //===----------------------------------------------------------------------===//
   1588 
   1589 
   1590 //===----------------------------------------------------------------------===//
   1591 // XTYPE/SHIFT +
   1592 //===----------------------------------------------------------------------===//
   1593 
   1594 // Shift by immediate and accumulate.
   1595 // Rx=add(#u8,asl(Rx,#U5))
   1596 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1597 validSubTargets = HasV4SubT in
   1598 def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
   1599             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1600             "$dst = add(#$src1, asl($src2, #$src3))",
   1601             [(set (i32 IntRegs:$dst),
   1602                   (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1603                        u8ExtPred:$src1))],
   1604             "$src2 = $dst">,
   1605             Requires<[HasV4T]>;
   1606 
   1607 // Rx=add(#u8,lsr(Rx,#U5))
   1608 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1609 validSubTargets = HasV4SubT in
   1610 def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
   1611             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1612             "$dst = add(#$src1, lsr($src2, #$src3))",
   1613             [(set (i32 IntRegs:$dst),
   1614                   (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1615                        u8ExtPred:$src1))],
   1616             "$src2 = $dst">,
   1617             Requires<[HasV4T]>;
   1618 
   1619 // Rx=sub(#u8,asl(Rx,#U5))
   1620 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1621 validSubTargets = HasV4SubT in
   1622 def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
   1623             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1624             "$dst = sub(#$src1, asl($src2, #$src3))",
   1625             [(set (i32 IntRegs:$dst),
   1626                   (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1627                        u8ExtPred:$src1))],
   1628             "$src2 = $dst">,
   1629             Requires<[HasV4T]>;
   1630 
   1631 // Rx=sub(#u8,lsr(Rx,#U5))
   1632 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1633 validSubTargets = HasV4SubT in
   1634 def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
   1635             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1636             "$dst = sub(#$src1, lsr($src2, #$src3))",
   1637             [(set (i32 IntRegs:$dst),
   1638                   (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1639                        u8ExtPred:$src1))],
   1640             "$src2 = $dst">,
   1641             Requires<[HasV4T]>;
   1642 
   1643 
   1644 //Shift by immediate and logical.
   1645 //Rx=and(#u8,asl(Rx,#U5))
   1646 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1647 validSubTargets = HasV4SubT in
   1648 def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
   1649             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1650             "$dst = and(#$src1, asl($src2, #$src3))",
   1651             [(set (i32 IntRegs:$dst),
   1652                   (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1653                        u8ExtPred:$src1))],
   1654             "$src2 = $dst">,
   1655             Requires<[HasV4T]>;
   1656 
   1657 //Rx=and(#u8,lsr(Rx,#U5))
   1658 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1659 validSubTargets = HasV4SubT in
   1660 def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
   1661             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1662             "$dst = and(#$src1, lsr($src2, #$src3))",
   1663             [(set (i32 IntRegs:$dst),
   1664                   (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1665                        u8ExtPred:$src1))],
   1666             "$src2 = $dst">,
   1667             Requires<[HasV4T]>;
   1668 
   1669 //Rx=or(#u8,asl(Rx,#U5))
   1670 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1671 AddedComplexity = 30, validSubTargets = HasV4SubT in
   1672 def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst),
   1673             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1674             "$dst = or(#$src1, asl($src2, #$src3))",
   1675             [(set (i32 IntRegs:$dst),
   1676                   (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1677                       u8ExtPred:$src1))],
   1678             "$src2 = $dst">,
   1679             Requires<[HasV4T]>;
   1680 
   1681 //Rx=or(#u8,lsr(Rx,#U5))
   1682 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8,
   1683 AddedComplexity = 30, validSubTargets = HasV4SubT in
   1684 def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst),
   1685             (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3),
   1686             "$dst = or(#$src1, lsr($src2, #$src3))",
   1687             [(set (i32 IntRegs:$dst),
   1688                   (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3),
   1689                       u8ExtPred:$src1))],
   1690             "$src2 = $dst">,
   1691             Requires<[HasV4T]>;
   1692 
   1693 
   1694 //Shift by register.
   1695 //Rd=lsl(#s6,Rt)
   1696 let validSubTargets = HasV4SubT in {
   1697 def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2),
   1698             "$dst = lsl(#$src1, $src2)",
   1699             [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1,
   1700                                            (i32 IntRegs:$src2)))]>,
   1701             Requires<[HasV4T]>;
   1702 
   1703 
   1704 //Shift by register and logical.
   1705 //Rxx^=asl(Rss,Rt)
   1706 def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
   1707             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
   1708             "$dst ^= asl($src2, $src3)",
   1709             [(set (i64 DoubleRegs:$dst),
   1710                   (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2),
   1711                                                     (i32 IntRegs:$src3))))],
   1712             "$src1 = $dst">,
   1713             Requires<[HasV4T]>;
   1714 
   1715 //Rxx^=asr(Rss,Rt)
   1716 def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
   1717             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
   1718             "$dst ^= asr($src2, $src3)",
   1719             [(set (i64 DoubleRegs:$dst),
   1720                   (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2),
   1721                                                     (i32 IntRegs:$src3))))],
   1722             "$src1 = $dst">,
   1723             Requires<[HasV4T]>;
   1724 
   1725 //Rxx^=lsl(Rss,Rt)
   1726 def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
   1727             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
   1728             "$dst ^= lsl($src2, $src3)",
   1729             [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1),
   1730                                               (shl (i64 DoubleRegs:$src2),
   1731                                                    (i32 IntRegs:$src3))))],
   1732             "$src1 = $dst">,
   1733             Requires<[HasV4T]>;
   1734 
   1735 //Rxx^=lsr(Rss,Rt)
   1736 def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst),
   1737             (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3),
   1738             "$dst ^= lsr($src2, $src3)",
   1739             [(set (i64 DoubleRegs:$dst),
   1740                   (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2),
   1741                                                     (i32 IntRegs:$src3))))],
   1742             "$src1 = $dst">,
   1743             Requires<[HasV4T]>;
   1744 }
   1745 
   1746 //===----------------------------------------------------------------------===//
   1747 // XTYPE/SHIFT -
   1748 //===----------------------------------------------------------------------===//
   1749 
   1750 //===----------------------------------------------------------------------===//
   1751 // MEMOP: Word, Half, Byte
   1752 //===----------------------------------------------------------------------===//
   1753 
   1754 def MEMOPIMM : SDNodeXForm<imm, [{
   1755   // Call the transformation function XformM5ToU5Imm to get the negative
   1756   // immediate's positive counterpart.
   1757   int32_t imm = N->getSExtValue();
   1758   return XformM5ToU5Imm(imm);
   1759 }]>;
   1760 
   1761 def MEMOPIMM_HALF : SDNodeXForm<imm, [{
   1762   // -1 .. -31 represented as 65535..65515
   1763   // assigning to a short restores our desired signed value.
   1764   // Call the transformation function XformM5ToU5Imm to get the negative
   1765   // immediate's positive counterpart.
   1766   int16_t imm = N->getSExtValue();
   1767   return XformM5ToU5Imm(imm);
   1768 }]>;
   1769 
   1770 def MEMOPIMM_BYTE : SDNodeXForm<imm, [{
   1771   // -1 .. -31 represented as 255..235
   1772   // assigning to a char restores our desired signed value.
   1773   // Call the transformation function XformM5ToU5Imm to get the negative
   1774   // immediate's positive counterpart.
   1775   int8_t imm = N->getSExtValue();
   1776   return XformM5ToU5Imm(imm);
   1777 }]>;
   1778 
   1779 def SETMEMIMM : SDNodeXForm<imm, [{
   1780    // Return the bit position we will set [0-31].
   1781    // As an SDNode.
   1782    int32_t imm = N->getSExtValue();
   1783    return XformMskToBitPosU5Imm(imm);
   1784 }]>;
   1785 
   1786 def CLRMEMIMM : SDNodeXForm<imm, [{
   1787    // Return the bit position we will clear [0-31].
   1788    // As an SDNode.
   1789    // we bit negate the value first
   1790    int32_t imm = ~(N->getSExtValue());
   1791    return XformMskToBitPosU5Imm(imm);
   1792 }]>;
   1793 
   1794 def SETMEMIMM_SHORT : SDNodeXForm<imm, [{
   1795    // Return the bit position we will set [0-15].
   1796    // As an SDNode.
   1797    int16_t imm = N->getSExtValue();
   1798    return XformMskToBitPosU4Imm(imm);
   1799 }]>;
   1800 
   1801 def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{
   1802    // Return the bit position we will clear [0-15].
   1803    // As an SDNode.
   1804    // we bit negate the value first
   1805    int16_t imm = ~(N->getSExtValue());
   1806    return XformMskToBitPosU4Imm(imm);
   1807 }]>;
   1808 
   1809 def SETMEMIMM_BYTE : SDNodeXForm<imm, [{
   1810    // Return the bit position we will set [0-7].
   1811    // As an SDNode.
   1812    int8_t imm =  N->getSExtValue();
   1813    return XformMskToBitPosU3Imm(imm);
   1814 }]>;
   1815 
   1816 def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{
   1817    // Return the bit position we will clear [0-7].
   1818    // As an SDNode.
   1819    // we bit negate the value first
   1820    int8_t imm = ~(N->getSExtValue());
   1821    return XformMskToBitPosU3Imm(imm);
   1822 }]>;
   1823 
   1824 //===----------------------------------------------------------------------===//
   1825 // Template class for MemOp instructions with the register value.
   1826 //===----------------------------------------------------------------------===//
   1827 class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp,
   1828                      string memOp, bits<2> memOpBits> :
   1829       MEMInst_V4<(outs),
   1830                  (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta),
   1831                  opc#"($base+#$offset)"#memOp#"$delta",
   1832                  []>,
   1833                  Requires<[HasV4T, UseMEMOP]> {
   1834 
   1835     bits<5> base;
   1836     bits<5> delta;
   1837     bits<32> offset;
   1838     bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
   1839 
   1840     let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
   1841                      !if (!eq(opcBits, 0b01), offset{6-1},
   1842                      !if (!eq(opcBits, 0b10), offset{7-2},0)));
   1843 
   1844     let IClass = 0b0011;
   1845     let Inst{27-24} = 0b1110;
   1846     let Inst{22-21} = opcBits;
   1847     let Inst{20-16} = base;
   1848     let Inst{13} = 0b0;
   1849     let Inst{12-7} = offsetBits;
   1850     let Inst{6-5} = memOpBits;
   1851     let Inst{4-0} = delta;
   1852 }
   1853 
   1854 //===----------------------------------------------------------------------===//
   1855 // Template class for MemOp instructions with the immediate value.
   1856 //===----------------------------------------------------------------------===//
   1857 class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp,
   1858                      string memOp, bits<2> memOpBits> :
   1859       MEMInst_V4 <(outs),
   1860                   (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta),
   1861                   opc#"($base+#$offset)"#memOp#"#$delta"
   1862                   #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')'
   1863                   []>,
   1864                   Requires<[HasV4T, UseMEMOP]> {
   1865 
   1866     bits<5> base;
   1867     bits<5> delta;
   1868     bits<32> offset;
   1869     bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2
   1870 
   1871     let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0},
   1872                      !if (!eq(opcBits, 0b01), offset{6-1},
   1873                      !if (!eq(opcBits, 0b10), offset{7-2},0)));
   1874 
   1875     let IClass = 0b0011;
   1876     let Inst{27-24} = 0b1111;
   1877     let Inst{22-21} = opcBits;
   1878     let Inst{20-16} = base;
   1879     let Inst{13} = 0b0;
   1880     let Inst{12-7} = offsetBits;
   1881     let Inst{6-5} = memOpBits;
   1882     let Inst{4-0} = delta;
   1883 }
   1884 
   1885 // multiclass to define MemOp instructions with register operand.
   1886 multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> {
   1887   def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add
   1888   def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub
   1889   def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and
   1890   def _OR#NAME#_V4  : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or
   1891 }
   1892 
   1893 // multiclass to define MemOp instructions with immediate Operand.
   1894 multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> {
   1895   def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >;
   1896   def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >;
   1897   def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>;
   1898   def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>;
   1899 }
   1900 
   1901 multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> {
   1902   defm r : MemOp_rr <opc, opcBits, ImmOp>;
   1903   defm i : MemOp_ri <opc, opcBits, ImmOp>;
   1904 }
   1905 
   1906 // Define MemOp instructions.
   1907 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0,
   1908 validSubTargets =HasV4SubT in {
   1909   let opExtentBits = 6, accessSize = ByteAccess in
   1910   defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>;
   1911 
   1912   let opExtentBits = 7, accessSize = HalfWordAccess in
   1913   defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>;
   1914 
   1915   let opExtentBits = 8, accessSize = WordAccess in
   1916   defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>;
   1917 }
   1918 
   1919 //===----------------------------------------------------------------------===//
   1920 // Multiclass to define 'Def Pats' for ALU operations on the memory
   1921 // Here value used for the ALU operation is an immediate value.
   1922 // mem[bh](Rs+#0) += #U5
   1923 // mem[bh](Rs+#u6) += #U5
   1924 //===----------------------------------------------------------------------===//
   1925 
   1926 multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
   1927                           InstHexagon MI, SDNode OpNode> {
   1928   let AddedComplexity = 180 in
   1929   def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend),
   1930                     IntRegs:$addr),
   1931               (MI IntRegs:$addr, #0, u5ImmPred:$addend )>;
   1932 
   1933   let AddedComplexity = 190 in
   1934   def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)),
   1935                      u5ImmPred:$addend),
   1936              (add IntRegs:$base, ExtPred:$offset)),
   1937        (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>;
   1938 }
   1939 
   1940 multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred,
   1941                           InstHexagon addMI, InstHexagon subMI> {
   1942   defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>;
   1943   defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>;
   1944 }
   1945 
   1946 multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
   1947   // Half Word
   1948   defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred,
   1949                          MemOPh_ADDi_V4, MemOPh_SUBi_V4>;
   1950   // Byte
   1951   defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred,
   1952                          MemOPb_ADDi_V4, MemOPb_SUBi_V4>;
   1953 }
   1954 
   1955 let Predicates = [HasV4T, UseMEMOP] in {
   1956   defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend
   1957   defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend
   1958   defm : MemOpi_u5ExtType<extloadi8,  extloadi16>;  // any extend
   1959 
   1960   // Word
   1961   defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4,
   1962                          MemOPw_SUBi_V4>;
   1963 }
   1964 
   1965 //===----------------------------------------------------------------------===//
   1966 // multiclass to define 'Def Pats' for ALU operations on the memory.
   1967 // Here value used for the ALU operation is a negative value.
   1968 // mem[bh](Rs+#0) += #m5
   1969 // mem[bh](Rs+#u6) += #m5
   1970 //===----------------------------------------------------------------------===//
   1971 
   1972 multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred,
   1973                           PatLeaf immPred, ComplexPattern addrPred,
   1974                           SDNodeXForm xformFunc, InstHexagon MI> {
   1975   let AddedComplexity = 190 in
   1976   def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend),
   1977                    IntRegs:$addr),
   1978              (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>;
   1979 
   1980   let AddedComplexity = 195 in
   1981   def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)),
   1982                        immPred:$subend),
   1983                   (add IntRegs:$base, extPred:$offset)),
   1984             (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>;
   1985 }
   1986 
   1987 multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
   1988   // Half Word
   1989   defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred,
   1990                         ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>;
   1991   // Byte
   1992   defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred,
   1993                         ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>;
   1994 }
   1995 
   1996 let Predicates = [HasV4T, UseMEMOP] in {
   1997   defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend
   1998   defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend
   1999   defm : MemOpi_m5ExtType<extloadi8,  extloadi16>;  // any extend
   2000 
   2001   // Word
   2002   defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred,
   2003                           ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>;
   2004 }
   2005 
   2006 //===----------------------------------------------------------------------===//
   2007 // Multiclass to define 'def Pats' for bit operations on the memory.
   2008 // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
   2009 // mem[bhw](Rs+#u6) = [clrbit|setbit](#U5)
   2010 //===----------------------------------------------------------------------===//
   2011 
   2012 multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred,
   2013                      PatLeaf extPred, ComplexPattern addrPred,
   2014                      SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> {
   2015 
   2016   // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5)
   2017   let AddedComplexity = 250 in
   2018   def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
   2019                           immPred:$bitend),
   2020                   (add IntRegs:$base, extPred:$offset)),
   2021             (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>;
   2022 
   2023   // mem[bhw](Rs+#0) = [clrbit|setbit](#U5)
   2024   let AddedComplexity = 225 in
   2025   def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)),
   2026                            immPred:$bitend),
   2027                    (addrPred (i32 IntRegs:$addr), extPred:$offset)),
   2028              (MI IntRegs:$addr, extPred:$offset, (xformFunc immPred:$bitend))>;
   2029 }
   2030 
   2031 multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
   2032   // Byte - clrbit
   2033   defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred,
   2034                        ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>;
   2035   // Byte - setbit
   2036   defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred,  u6ExtPred,
   2037                        ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>;
   2038   // Half Word - clrbit
   2039   defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred,
   2040                        ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>;
   2041   // Half Word - setbit
   2042   defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred,
   2043                        ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>;
   2044 }
   2045 
   2046 let Predicates = [HasV4T, UseMEMOP] in {
   2047   // mem[bh](Rs+#0) = [clrbit|setbit](#U5)
   2048   // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5)
   2049   defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend
   2050   defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend
   2051   defm : MemOpi_bitExtType<extloadi8,  extloadi16>;  // any extend
   2052 
   2053   // memw(Rs+#0) = [clrbit|setbit](#U5)
   2054   // memw(Rs+#u6:2) = [clrbit|setbit](#U5)
   2055   defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2,
   2056                        CLRMEMIMM, MemOPw_CLRBITi_V4, and>;
   2057   defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2,
   2058                        SETMEMIMM, MemOPw_SETBITi_V4, or>;
   2059 }
   2060 
   2061 //===----------------------------------------------------------------------===//
   2062 // Multiclass to define 'def Pats' for ALU operations on the memory
   2063 // where addend is a register.
   2064 // mem[bhw](Rs+#0) [+-&|]= Rt
   2065 // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
   2066 //===----------------------------------------------------------------------===//
   2067 
   2068 multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred,
   2069                      PatLeaf extPred, InstHexagon MI, SDNode OpNode> {
   2070   let AddedComplexity = 141 in
   2071   // mem[bhw](Rs+#0) [+-&|]= Rt
   2072   def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)),
   2073                            (i32 IntRegs:$addend)),
   2074                    (addrPred (i32 IntRegs:$addr), extPred:$offset)),
   2075              (MI IntRegs:$addr, extPred:$offset, (i32 IntRegs:$addend) )>;
   2076 
   2077   // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt
   2078   let AddedComplexity = 150 in
   2079   def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)),
   2080                            (i32 IntRegs:$orend)),
   2081                    (add IntRegs:$base, extPred:$offset)),
   2082              (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>;
   2083 }
   2084 
   2085 multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp,
   2086                         ComplexPattern addrPred, PatLeaf extPred,
   2087                         InstHexagon addMI, InstHexagon subMI,
   2088                         InstHexagon andMI, InstHexagon orMI > {
   2089 
   2090   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>;
   2091   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>;
   2092   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>;
   2093   defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI,  or>;
   2094 }
   2095 
   2096 multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > {
   2097   // Half Word
   2098   defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred,
   2099                        MemOPh_ADDr_V4, MemOPh_SUBr_V4,
   2100                        MemOPh_ANDr_V4, MemOPh_ORr_V4>;
   2101   // Byte
   2102   defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred,
   2103                        MemOPb_ADDr_V4, MemOPb_SUBr_V4,
   2104                        MemOPb_ANDr_V4, MemOPb_ORr_V4>;
   2105 }
   2106 
   2107 // Define 'def Pats' for MemOps with register addend.
   2108 let Predicates = [HasV4T, UseMEMOP] in {
   2109   // Byte, Half Word
   2110   defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend
   2111   defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend
   2112   defm : MemOPr_ExtType<extloadi8,  extloadi16>;  // any extend
   2113   // Word
   2114   defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4,
   2115                        MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >;
   2116 }
   2117 
   2118 //===----------------------------------------------------------------------===//
   2119 // XTYPE/PRED +
   2120 //===----------------------------------------------------------------------===//
   2121 
   2122 // Hexagon V4 only supports these flavors of byte/half compare instructions:
   2123 // EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by
   2124 // hardware. However, compiler can still implement these patterns through
   2125 // appropriate patterns combinations based on current implemented patterns.
   2126 // The implemented patterns are: EQ/GT/GTU.
   2127 // Missing patterns are: GE/GEU/LT/LTU/LE/LEU.
   2128 
   2129 // Following instruction is not being extended as it results into the
   2130 // incorrect code for negative numbers.
   2131 // Pd=cmpb.eq(Rs,#u8)
   2132 
   2133 // p=!cmp.eq(r1,r2)
   2134 let isCompare = 1, validSubTargets = HasV4SubT in
   2135 def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
   2136                            (ins IntRegs:$src1, IntRegs:$src2),
   2137       "$dst = !cmp.eq($src1, $src2)",
   2138       [(set (i1 PredRegs:$dst),
   2139             (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
   2140       Requires<[HasV4T]>;
   2141 
   2142 // p=!cmp.eq(r1,#s10)
   2143 let isCompare = 1, validSubTargets = HasV4SubT in
   2144 def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
   2145                            (ins IntRegs:$src1, s10Ext:$src2),
   2146       "$dst = !cmp.eq($src1, #$src2)",
   2147       [(set (i1 PredRegs:$dst),
   2148             (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
   2149       Requires<[HasV4T]>;
   2150 
   2151 // p=!cmp.gt(r1,r2)
   2152 let isCompare = 1, validSubTargets = HasV4SubT in
   2153 def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
   2154                            (ins IntRegs:$src1, IntRegs:$src2),
   2155       "$dst = !cmp.gt($src1, $src2)",
   2156       [(set (i1 PredRegs:$dst),
   2157             (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
   2158       Requires<[HasV4T]>;
   2159 
   2160 // p=!cmp.gt(r1,#s10)
   2161 let isCompare = 1, validSubTargets = HasV4SubT in
   2162 def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
   2163                            (ins IntRegs:$src1, s10Ext:$src2),
   2164       "$dst = !cmp.gt($src1, #$src2)",
   2165       [(set (i1 PredRegs:$dst),
   2166             (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
   2167       Requires<[HasV4T]>;
   2168 
   2169 // p=!cmp.gtu(r1,r2)
   2170 let isCompare = 1, validSubTargets = HasV4SubT in
   2171 def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
   2172                             (ins IntRegs:$src1, IntRegs:$src2),
   2173       "$dst = !cmp.gtu($src1, $src2)",
   2174       [(set (i1 PredRegs:$dst),
   2175             (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
   2176       Requires<[HasV4T]>;
   2177 
   2178 // p=!cmp.gtu(r1,#u9)
   2179 let isCompare = 1, validSubTargets = HasV4SubT in
   2180 def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
   2181                             (ins IntRegs:$src1, u9Ext:$src2),
   2182       "$dst = !cmp.gtu($src1, #$src2)",
   2183       [(set (i1 PredRegs:$dst),
   2184             (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
   2185       Requires<[HasV4T]>;
   2186 
   2187 let isCompare = 1, validSubTargets = HasV4SubT in
   2188 def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
   2189             (ins IntRegs:$src1, u8Imm:$src2),
   2190             "$dst = cmpb.eq($src1, #$src2)",
   2191             [(set (i1 PredRegs:$dst),
   2192                   (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
   2193             Requires<[HasV4T]>;
   2194 
   2195 def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
   2196                        bb:$offset),
   2197       (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
   2198                 bb:$offset)>,
   2199       Requires<[HasV4T]>;
   2200 
   2201 // Pd=cmpb.eq(Rs,Rt)
   2202 let isCompare = 1, validSubTargets = HasV4SubT in
   2203 def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
   2204             (ins IntRegs:$src1, IntRegs:$src2),
   2205             "$dst = cmpb.eq($src1, $src2)",
   2206             [(set (i1 PredRegs:$dst),
   2207                   (seteq (and (xor (i32 IntRegs:$src1),
   2208                                    (i32 IntRegs:$src2)), 255), 0))]>,
   2209             Requires<[HasV4T]>;
   2210 
   2211 // Pd=cmpb.eq(Rs,Rt)
   2212 let isCompare = 1, validSubTargets = HasV4SubT in
   2213 def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst),
   2214             (ins IntRegs:$src1, IntRegs:$src2),
   2215             "$dst = cmpb.eq($src1, $src2)",
   2216             [(set (i1 PredRegs:$dst),
   2217                   (seteq (shl (i32 IntRegs:$src1), (i32 24)),
   2218                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
   2219             Requires<[HasV4T]>;
   2220 
   2221 // Pd=cmpb.gt(Rs,Rt)
   2222 let isCompare = 1, validSubTargets = HasV4SubT in
   2223 def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst),
   2224             (ins IntRegs:$src1, IntRegs:$src2),
   2225             "$dst = cmpb.gt($src1, $src2)",
   2226             [(set (i1 PredRegs:$dst),
   2227                   (setgt (shl (i32 IntRegs:$src1), (i32 24)),
   2228                          (shl (i32 IntRegs:$src2), (i32 24))))]>,
   2229             Requires<[HasV4T]>;
   2230 
   2231 // Pd=cmpb.gtu(Rs,#u7)
   2232 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
   2233 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in
   2234 def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
   2235             (ins IntRegs:$src1, u7Ext:$src2),
   2236             "$dst = cmpb.gtu($src1, #$src2)",
   2237             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
   2238                                               u7ExtPred:$src2))]>,
   2239             Requires<[HasV4T]>, ImmRegRel;
   2240 
   2241 // SDNode for converting immediate C to C-1.
   2242 def DEC_CONST_BYTE : SDNodeXForm<imm, [{
   2243    // Return the byte immediate const-1 as an SDNode.
   2244    int32_t imm = N->getSExtValue();
   2245    return XformU7ToU7M1Imm(imm);
   2246 }]>;
   2247 
   2248 // For the sequence
   2249 //   zext( seteq ( and(Rs, 255), u8))
   2250 // Generate
   2251 //   Pd=cmpb.eq(Rs, #u8)
   2252 //   if (Pd.new) Rd=#1
   2253 //   if (!Pd.new) Rd=#0
   2254 def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)),
   2255                                            u8ExtPred:$u8)))),
   2256            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
   2257                                                  (u8ExtPred:$u8))),
   2258                                 1, 0))>,
   2259            Requires<[HasV4T]>;
   2260 
   2261 // For the sequence
   2262 //   zext( setne ( and(Rs, 255), u8))
   2263 // Generate
   2264 //   Pd=cmpb.eq(Rs, #u8)
   2265 //   if (Pd.new) Rd=#0
   2266 //   if (!Pd.new) Rd=#1
   2267 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)),
   2268                                            u8ExtPred:$u8)))),
   2269            (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs),
   2270                                                  (u8ExtPred:$u8))),
   2271                                 0, 1))>,
   2272            Requires<[HasV4T]>;
   2273 
   2274 // For the sequence
   2275 //   zext( seteq (Rs, and(Rt, 255)))
   2276 // Generate
   2277 //   Pd=cmpb.eq(Rs, Rt)
   2278 //   if (Pd.new) Rd=#1
   2279 //   if (!Pd.new) Rd=#0
   2280 def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt),
   2281                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
   2282            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
   2283                                                       (i32 IntRegs:$Rt))),
   2284                                 1, 0))>,
   2285            Requires<[HasV4T]>;
   2286 
   2287 // For the sequence
   2288 //   zext( setne (Rs, and(Rt, 255)))
   2289 // Generate
   2290 //   Pd=cmpb.eq(Rs, Rt)
   2291 //   if (Pd.new) Rd=#0
   2292 //   if (!Pd.new) Rd=#1
   2293 def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt),
   2294                                  (i32 (and (i32 IntRegs:$Rs), 255)))))),
   2295            (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs),
   2296                                                       (i32 IntRegs:$Rt))),
   2297                                 0, 1))>,
   2298            Requires<[HasV4T]>;
   2299 
   2300 // For the sequence
   2301 //   zext( setugt ( and(Rs, 255), u8))
   2302 // Generate
   2303 //   Pd=cmpb.gtu(Rs, #u8)
   2304 //   if (Pd.new) Rd=#1
   2305 //   if (!Pd.new) Rd=#0
   2306 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)),
   2307                                             u8ExtPred:$u8)))),
   2308            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
   2309                                                   (u8ExtPred:$u8))),
   2310                                 1, 0))>,
   2311            Requires<[HasV4T]>;
   2312 
   2313 // For the sequence
   2314 //   zext( setugt ( and(Rs, 254), u8))
   2315 // Generate
   2316 //   Pd=cmpb.gtu(Rs, #u8)
   2317 //   if (Pd.new) Rd=#1
   2318 //   if (!Pd.new) Rd=#0
   2319 def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)),
   2320                                             u8ExtPred:$u8)))),
   2321            (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs),
   2322                                                   (u8ExtPred:$u8))),
   2323                                 1, 0))>,
   2324            Requires<[HasV4T]>;
   2325 
   2326 // For the sequence
   2327 //   zext( setult ( Rs, Rt))
   2328 // Generate
   2329 //   Pd=cmp.ltu(Rs, Rt)
   2330 //   if (Pd.new) Rd=#1
   2331 //   if (!Pd.new) Rd=#0
   2332 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
   2333 def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2334            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
   2335                                               (i32 IntRegs:$Rs))),
   2336                                 1, 0))>,
   2337            Requires<[HasV4T]>;
   2338 
   2339 // For the sequence
   2340 //   zext( setlt ( Rs, Rt))
   2341 // Generate
   2342 //   Pd=cmp.lt(Rs, Rt)
   2343 //   if (Pd.new) Rd=#1
   2344 //   if (!Pd.new) Rd=#0
   2345 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
   2346 def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2347            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
   2348                                              (i32 IntRegs:$Rs))),
   2349                                 1, 0))>,
   2350            Requires<[HasV4T]>;
   2351 
   2352 // For the sequence
   2353 //   zext( setugt ( Rs, Rt))
   2354 // Generate
   2355 //   Pd=cmp.gtu(Rs, Rt)
   2356 //   if (Pd.new) Rd=#1
   2357 //   if (!Pd.new) Rd=#0
   2358 def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2359            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
   2360                                               (i32 IntRegs:$Rt))),
   2361                                 1, 0))>,
   2362            Requires<[HasV4T]>;
   2363 
   2364 // This pattern interefers with coremark performance, not implementing at this
   2365 // time.
   2366 // For the sequence
   2367 //   zext( setgt ( Rs, Rt))
   2368 // Generate
   2369 //   Pd=cmp.gt(Rs, Rt)
   2370 //   if (Pd.new) Rd=#1
   2371 //   if (!Pd.new) Rd=#0
   2372 
   2373 // For the sequence
   2374 //   zext( setuge ( Rs, Rt))
   2375 // Generate
   2376 //   Pd=cmp.ltu(Rs, Rt)
   2377 //   if (Pd.new) Rd=#0
   2378 //   if (!Pd.new) Rd=#1
   2379 // cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs)
   2380 def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2381            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt),
   2382                                               (i32 IntRegs:$Rs))),
   2383                                 0, 1))>,
   2384            Requires<[HasV4T]>;
   2385 
   2386 // For the sequence
   2387 //   zext( setge ( Rs, Rt))
   2388 // Generate
   2389 //   Pd=cmp.lt(Rs, Rt)
   2390 //   if (Pd.new) Rd=#0
   2391 //   if (!Pd.new) Rd=#1
   2392 // cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs)
   2393 def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2394            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt),
   2395                                              (i32 IntRegs:$Rs))),
   2396                                 0, 1))>,
   2397            Requires<[HasV4T]>;
   2398 
   2399 // For the sequence
   2400 //   zext( setule ( Rs, Rt))
   2401 // Generate
   2402 //   Pd=cmp.gtu(Rs, Rt)
   2403 //   if (Pd.new) Rd=#0
   2404 //   if (!Pd.new) Rd=#1
   2405 def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2406            (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs),
   2407                                               (i32 IntRegs:$Rt))),
   2408                                 0, 1))>,
   2409            Requires<[HasV4T]>;
   2410 
   2411 // For the sequence
   2412 //   zext( setle ( Rs, Rt))
   2413 // Generate
   2414 //   Pd=cmp.gt(Rs, Rt)
   2415 //   if (Pd.new) Rd=#0
   2416 //   if (!Pd.new) Rd=#1
   2417 def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))),
   2418            (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs),
   2419                                              (i32 IntRegs:$Rt))),
   2420                                 0, 1))>,
   2421            Requires<[HasV4T]>;
   2422 
   2423 // For the sequence
   2424 //   zext( setult ( and(Rs, 255), u8))
   2425 // Use the isdigit transformation below
   2426 
   2427 // Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)'
   2428 // for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;.
   2429 // The isdigit transformation relies on two 'clever' aspects:
   2430 // 1) The data type is unsigned which allows us to eliminate a zero test after
   2431 //    biasing the expression by 48. We are depending on the representation of
   2432 //    the unsigned types, and semantics.
   2433 // 2) The front end has converted <= 9 into < 10 on entry to LLVM
   2434 //
   2435 // For the C code:
   2436 //   retval = ((c>='0') & (c<='9')) ? 1 : 0;
   2437 // The code is transformed upstream of llvm into
   2438 //   retval = (c-48) < 10 ? 1 : 0;
   2439 let AddedComplexity = 139 in
   2440 def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)),
   2441                                   u7StrictPosImmPred:$src2)))),
   2442   (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1),
   2443                                  (DEC_CONST_BYTE u7StrictPosImmPred:$src2))),
   2444                    0, 1))>,
   2445                    Requires<[HasV4T]>;
   2446 
   2447 // Pd=cmpb.gtu(Rs,Rt)
   2448 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
   2449 InputType = "reg" in
   2450 def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
   2451             (ins IntRegs:$src1, IntRegs:$src2),
   2452             "$dst = cmpb.gtu($src1, $src2)",
   2453             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
   2454                                              (and (i32 IntRegs:$src2), 255)))]>,
   2455             Requires<[HasV4T]>, ImmRegRel;
   2456 
   2457 // Following instruction is not being extended as it results into the incorrect
   2458 // code for negative numbers.
   2459 
   2460 // Signed half compare(.eq) ri.
   2461 // Pd=cmph.eq(Rs,#s8)
   2462 let isCompare = 1, validSubTargets = HasV4SubT in
   2463 def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
   2464             (ins IntRegs:$src1, s8Imm:$src2),
   2465             "$dst = cmph.eq($src1, #$src2)",
   2466             [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535),
   2467                                              s8ImmPred:$src2))]>,
   2468             Requires<[HasV4T]>;
   2469 
   2470 // Signed half compare(.eq) rr.
   2471 // Case 1: xor + and, then compare:
   2472 //   r0=xor(r0,r1)
   2473 //   r0=and(r0,#0xffff)
   2474 //   p0=cmp.eq(r0,#0)
   2475 // Pd=cmph.eq(Rs,Rt)
   2476 let isCompare = 1, validSubTargets = HasV4SubT in
   2477 def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
   2478             (ins IntRegs:$src1, IntRegs:$src2),
   2479             "$dst = cmph.eq($src1, $src2)",
   2480             [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1),
   2481                                                        (i32 IntRegs:$src2)),
   2482                                                   65535), 0))]>,
   2483             Requires<[HasV4T]>;
   2484 
   2485 // Signed half compare(.eq) rr.
   2486 // Case 2: shift left 16 bits then compare:
   2487 //   r0=asl(r0,16)
   2488 //   r1=asl(r1,16)
   2489 //   p0=cmp.eq(r0,r1)
   2490 // Pd=cmph.eq(Rs,Rt)
   2491 let isCompare = 1, validSubTargets = HasV4SubT in
   2492 def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
   2493             (ins IntRegs:$src1, IntRegs:$src2),
   2494             "$dst = cmph.eq($src1, $src2)",
   2495             [(set (i1 PredRegs:$dst),
   2496                   (seteq (shl (i32 IntRegs:$src1), (i32 16)),
   2497                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
   2498             Requires<[HasV4T]>;
   2499 
   2500 /* Incorrect Pattern -- immediate should be right shifted before being
   2501 used in the cmph.gt instruction.
   2502 // Signed half compare(.gt) ri.
   2503 // Pd=cmph.gt(Rs,#s8)
   2504 
   2505 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
   2506 isCompare = 1, validSubTargets = HasV4SubT in
   2507 def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
   2508             (ins IntRegs:$src1, s8Ext:$src2),
   2509             "$dst = cmph.gt($src1, #$src2)",
   2510             [(set (i1 PredRegs:$dst),
   2511                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
   2512                          s8ExtPred:$src2))]>,
   2513             Requires<[HasV4T]>;
   2514 */
   2515 
   2516 // Signed half compare(.gt) rr.
   2517 // Pd=cmph.gt(Rs,Rt)
   2518 let isCompare = 1, validSubTargets = HasV4SubT in
   2519 def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
   2520             (ins IntRegs:$src1, IntRegs:$src2),
   2521             "$dst = cmph.gt($src1, $src2)",
   2522             [(set (i1 PredRegs:$dst),
   2523                   (setgt (shl (i32 IntRegs:$src1), (i32 16)),
   2524                          (shl (i32 IntRegs:$src2), (i32 16))))]>,
   2525             Requires<[HasV4T]>;
   2526 
   2527 // Unsigned half compare rr (.gtu).
   2528 // Pd=cmph.gtu(Rs,Rt)
   2529 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
   2530 InputType = "reg" in
   2531 def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
   2532             (ins IntRegs:$src1, IntRegs:$src2),
   2533             "$dst = cmph.gtu($src1, $src2)",
   2534             [(set (i1 PredRegs:$dst),
   2535                   (setugt (and (i32 IntRegs:$src1), 65535),
   2536                           (and (i32 IntRegs:$src2), 65535)))]>,
   2537             Requires<[HasV4T]>, ImmRegRel;
   2538 
   2539 // Unsigned half compare ri (.gtu).
   2540 // Pd=cmph.gtu(Rs,#u7)
   2541 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
   2542 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
   2543 InputType = "imm" in
   2544 def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
   2545             (ins IntRegs:$src1, u7Ext:$src2),
   2546             "$dst = cmph.gtu($src1, #$src2)",
   2547             [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
   2548                                               u7ExtPred:$src2))]>,
   2549             Requires<[HasV4T]>, ImmRegRel;
   2550 
   2551 let validSubTargets = HasV4SubT in
   2552 def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
   2553     "$dst = !tstbit($src1, $src2)",
   2554     [(set (i1 PredRegs:$dst),
   2555           (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
   2556     Requires<[HasV4T]>;
   2557 
   2558 let validSubTargets = HasV4SubT in
   2559 def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
   2560     "$dst = !tstbit($src1, $src2)",
   2561     [(set (i1 PredRegs:$dst),
   2562           (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
   2563     Requires<[HasV4T]>;
   2564 
   2565 //===----------------------------------------------------------------------===//
   2566 // XTYPE/PRED -
   2567 //===----------------------------------------------------------------------===//
   2568 
   2569 //Deallocate frame and return.
   2570 //    dealloc_return
   2571 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
   2572   Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in {
   2573 let validSubTargets = HasV4SubT in
   2574   def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
   2575             "dealloc_return",
   2576             []>,
   2577             Requires<[HasV4T]>;
   2578 }
   2579 
   2580 // Restore registers and dealloc return function call.
   2581 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
   2582   Defs = [R29, R30, R31, PC] in {
   2583 let validSubTargets = HasV4SubT in
   2584   def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
   2585                                    (ins calltarget:$dst),
   2586              "jump $dst",
   2587              []>,
   2588              Requires<[HasV4T]>;
   2589 }
   2590 
   2591 // Restore registers and dealloc frame before a tail call.
   2592 let isCall = 1, isBarrier = 1,
   2593   Defs = [R29, R30, R31, PC] in {
   2594 let validSubTargets = HasV4SubT in
   2595   def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
   2596                                            (ins calltarget:$dst),
   2597              "call $dst",
   2598              []>,
   2599              Requires<[HasV4T]>;
   2600 }
   2601 
   2602 // Save registers function call.
   2603 let isCall = 1, isBarrier = 1,
   2604   Uses = [R29, R31] in {
   2605   def SAVE_REGISTERS_CALL_V4 : JInst<(outs),
   2606                                (ins calltarget:$dst),
   2607              "call $dst // Save_calle_saved_registers",
   2608              []>,
   2609              Requires<[HasV4T]>;
   2610 }
   2611 
   2612 //    if (Ps) dealloc_return
   2613 let isReturn = 1, isTerminator = 1,
   2614     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2615     isPredicated = 1 in {
   2616 let validSubTargets = HasV4SubT in
   2617   def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
   2618                            (ins PredRegs:$src1),
   2619             "if ($src1) dealloc_return",
   2620             []>,
   2621             Requires<[HasV4T]>;
   2622 }
   2623 
   2624 //    if (!Ps) dealloc_return
   2625 let isReturn = 1, isTerminator = 1,
   2626     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2627     isPredicated = 1, isPredicatedFalse = 1 in {
   2628 let validSubTargets = HasV4SubT in
   2629   def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
   2630             "if (!$src1) dealloc_return",
   2631             []>,
   2632             Requires<[HasV4T]>;
   2633 }
   2634 
   2635 //    if (Ps.new) dealloc_return:nt
   2636 let isReturn = 1, isTerminator = 1,
   2637     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2638     isPredicated = 1 in {
   2639 let validSubTargets = HasV4SubT in
   2640   def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
   2641             "if ($src1.new) dealloc_return:nt",
   2642             []>,
   2643             Requires<[HasV4T]>;
   2644 }
   2645 
   2646 //    if (!Ps.new) dealloc_return:nt
   2647 let isReturn = 1, isTerminator = 1,
   2648     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2649     isPredicated = 1, isPredicatedFalse = 1 in {
   2650 let validSubTargets = HasV4SubT in
   2651   def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
   2652             "if (!$src1.new) dealloc_return:nt",
   2653             []>,
   2654             Requires<[HasV4T]>;
   2655 }
   2656 
   2657 //    if (Ps.new) dealloc_return:t
   2658 let isReturn = 1, isTerminator = 1,
   2659     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2660     isPredicated = 1 in {
   2661 let validSubTargets = HasV4SubT in
   2662   def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
   2663             "if ($src1.new) dealloc_return:t",
   2664             []>,
   2665             Requires<[HasV4T]>;
   2666 }
   2667 
   2668 // if (!Ps.new) dealloc_return:nt
   2669 let isReturn = 1, isTerminator = 1,
   2670     Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
   2671     isPredicated = 1, isPredicatedFalse = 1 in {
   2672 let validSubTargets = HasV4SubT in
   2673   def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
   2674             "if (!$src1.new) dealloc_return:t",
   2675             []>,
   2676             Requires<[HasV4T]>;
   2677 }
   2678 
   2679 // Load/Store with absolute addressing mode
   2680 // memw(#u6)=Rt
   2681 
   2682 multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
   2683                            bit isPredNew> {
   2684   let isPredicatedNew = isPredNew in
   2685   def NAME#_V4 : STInst2<(outs),
   2686             (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
   2687             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
   2688             ") ")#mnemonic#"(##$absaddr) = $src2",
   2689             []>,
   2690             Requires<[HasV4T]>;
   2691 }
   2692 
   2693 multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
   2694   let isPredicatedFalse = PredNot in {
   2695     defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>;
   2696     // Predicate new
   2697     defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>;
   2698   }
   2699 }
   2700 
   2701 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in
   2702 multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> {
   2703   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
   2704     let opExtendable = 0, isPredicable = 1 in
   2705     def NAME#_V4 : STInst2<(outs),
   2706             (ins u0AlwaysExt:$absaddr, RC:$src),
   2707             mnemonic#"(##$absaddr) = $src",
   2708             []>,
   2709             Requires<[HasV4T]>;
   2710 
   2711     let opExtendable = 1, isPredicated = 1 in {
   2712       defm Pt : ST_Abs_Pred<mnemonic, RC, 0>;
   2713       defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>;
   2714     }
   2715   }
   2716 }
   2717 
   2718 multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot,
   2719                            bit isPredNew> {
   2720   let isPredicatedNew = isPredNew in
   2721   def NAME#_nv_V4 : NVInst_V4<(outs),
   2722             (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
   2723             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
   2724             ") ")#mnemonic#"(##$absaddr) = $src2.new",
   2725             []>,
   2726             Requires<[HasV4T]>;
   2727 }
   2728 
   2729 multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> {
   2730   let isPredicatedFalse = PredNot in {
   2731     defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>;
   2732     // Predicate new
   2733     defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>;
   2734   }
   2735 }
   2736 
   2737 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in
   2738 multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> {
   2739   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
   2740     let opExtendable = 0, isPredicable = 1 in
   2741     def NAME#_nv_V4 : NVInst_V4<(outs),
   2742             (ins u0AlwaysExt:$absaddr, RC:$src),
   2743             mnemonic#"(##$absaddr) = $src.new",
   2744             []>,
   2745             Requires<[HasV4T]>;
   2746 
   2747     let opExtendable = 1, isPredicated = 1 in {
   2748       defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
   2749       defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
   2750     }
   2751   }
   2752 }
   2753 
   2754 let addrMode = Absolute in {
   2755   let accessSize = ByteAccess in
   2756     defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
   2757                      ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
   2758 
   2759   let accessSize = HalfWordAccess in
   2760     defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
   2761                      ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
   2762 
   2763   let accessSize = WordAccess in
   2764     defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
   2765                      ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
   2766 
   2767   let accessSize = DoubleWordAccess, isNVStorable = 0 in
   2768     defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
   2769 }
   2770 
   2771 let Predicates = [HasV4T], AddedComplexity = 30 in {
   2772 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
   2773                         (HexagonCONST32 tglobaladdr:$absaddr)),
   2774           (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
   2775 
   2776 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
   2777                           (HexagonCONST32 tglobaladdr:$absaddr)),
   2778           (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
   2779 
   2780 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)),
   2781           (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>;
   2782 
   2783 def : Pat<(store (i64 DoubleRegs:$src1),
   2784                  (HexagonCONST32 tglobaladdr:$absaddr)),
   2785           (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>;
   2786 }
   2787 
   2788 //===----------------------------------------------------------------------===//
   2789 // multiclass for store instructions with GP-relative addressing mode.
   2790 // mem[bhwd](#global)=Rt
   2791 // if ([!]Pv[.new]) mem[bhwd](##global) = Rt
   2792 //===----------------------------------------------------------------------===//
   2793 let mayStore = 1, isNVStorable = 1 in
   2794 multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
   2795   let BaseOpcode = BaseOp, isPredicable = 1 in
   2796   def NAME#_V4 : STInst2<(outs),
   2797           (ins globaladdress:$global, RC:$src),
   2798           mnemonic#"(#$global) = $src",
   2799           []>;
   2800 
   2801   // When GP-relative instructions are predicated, their addressing mode is
   2802   // changed to absolute and they are always constant extended.
   2803   let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
   2804   isPredicated = 1 in {
   2805     defm Pt : ST_Abs_Pred <mnemonic, RC, 0>;
   2806     defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>;
   2807   }
   2808 }
   2809 
   2810 let mayStore = 1, isNVStore = 1 in
   2811 multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> {
   2812   let BaseOpcode = BaseOp, isPredicable = 1 in
   2813   def NAME#_nv_V4 : NVInst_V4<(outs),
   2814           (ins u0AlwaysExt:$global, RC:$src),
   2815           mnemonic#"(#$global) = $src.new",
   2816           []>,
   2817           Requires<[HasV4T]>;
   2818 
   2819   // When GP-relative instructions are predicated, their addressing mode is
   2820   // changed to absolute and they are always constant extended.
   2821   let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1,
   2822   isPredicated = 1 in {
   2823     defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>;
   2824     defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>;
   2825   }
   2826 }
   2827 
   2828 let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
   2829   let isNVStorable = 0 in
   2830   defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
   2831 
   2832   defm STb_GP : ST_GP<"memb",  "STb_GP", IntRegs>,
   2833                 ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
   2834   defm STh_GP : ST_GP<"memh",  "STh_GP", IntRegs>,
   2835                 ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
   2836   defm STw_GP : ST_GP<"memw",  "STw_GP", IntRegs>,
   2837                 ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
   2838 }
   2839 
   2840 // 64 bit atomic store
   2841 def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global),
   2842                             (i64 DoubleRegs:$src1)),
   2843            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>,
   2844            Requires<[HasV4T]>;
   2845 
   2846 // Map from store(globaladdress) -> memd(#foo)
   2847 let AddedComplexity = 100 in
   2848 def : Pat <(store (i64 DoubleRegs:$src1),
   2849                   (HexagonCONST32_GP tglobaladdr:$global)),
   2850            (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>;
   2851 
   2852 // 8 bit atomic store
   2853 def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global),
   2854                             (i32 IntRegs:$src1)),
   2855             (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2856 
   2857 // Map from store(globaladdress) -> memb(#foo)
   2858 let AddedComplexity = 100 in
   2859 def : Pat<(truncstorei8 (i32 IntRegs:$src1),
   2860           (HexagonCONST32_GP tglobaladdr:$global)),
   2861           (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2862 
   2863 // Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1"
   2864 //       to "r0 = 1; memw(#foo) = r0"
   2865 let AddedComplexity = 100 in
   2866 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)),
   2867           (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>;
   2868 
   2869 def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global),
   2870                            (i32 IntRegs:$src1)),
   2871           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2872 
   2873 // Map from store(globaladdress) -> memh(#foo)
   2874 let AddedComplexity = 100 in
   2875 def : Pat<(truncstorei16 (i32 IntRegs:$src1),
   2876                          (HexagonCONST32_GP tglobaladdr:$global)),
   2877           (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2878 
   2879 // 32 bit atomic store
   2880 def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global),
   2881                            (i32 IntRegs:$src1)),
   2882           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2883 
   2884 // Map from store(globaladdress) -> memw(#foo)
   2885 let AddedComplexity = 100 in
   2886 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)),
   2887           (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>;
   2888 
   2889 //===----------------------------------------------------------------------===//
   2890 // Multiclass for the load instructions with absolute addressing mode.
   2891 //===----------------------------------------------------------------------===//
   2892 multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot,
   2893                            bit isPredNew> {
   2894   let isPredicatedNew = isPredNew in
   2895   def NAME : LDInst2<(outs RC:$dst),
   2896             (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
   2897             !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
   2898             ") ")#"$dst = "#mnemonic#"(##$absaddr)",
   2899             []>,
   2900             Requires<[HasV4T]>;
   2901 }
   2902 
   2903 multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> {
   2904   let isPredicatedFalse = PredNot in {
   2905     defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>;
   2906     // Predicate new
   2907     defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>;
   2908   }
   2909 }
   2910 
   2911 let isExtended = 1, neverHasSideEffects = 1 in
   2912 multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> {
   2913   let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
   2914     let  opExtendable = 1, isPredicable = 1 in
   2915     def NAME#_V4 : LDInst2<(outs RC:$dst),
   2916             (ins u0AlwaysExt:$absaddr),
   2917             "$dst = "#mnemonic#"(##$absaddr)",
   2918             []>,
   2919             Requires<[HasV4T]>;
   2920 
   2921     let opExtendable = 2, isPredicated = 1 in {
   2922       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
   2923       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
   2924     }
   2925   }
   2926 }
   2927 
   2928 let addrMode = Absolute in {
   2929   let accessSize = ByteAccess in {
   2930     defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
   2931     defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
   2932   }
   2933   let accessSize = HalfWordAccess in {
   2934     defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
   2935     defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
   2936   }
   2937   let accessSize = WordAccess in
   2938     defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
   2939 
   2940   let accessSize = DoubleWordAccess in
   2941     defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
   2942 }
   2943 
   2944 let Predicates = [HasV4T], AddedComplexity  = 30 in {
   2945 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
   2946           (LDriw_abs_V4 tglobaladdr: $absaddr)>;
   2947 
   2948 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
   2949           (LDrib_abs_V4 tglobaladdr:$absaddr)>;
   2950 
   2951 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
   2952           (LDriub_abs_V4 tglobaladdr:$absaddr)>;
   2953 
   2954 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
   2955           (LDrih_abs_V4 tglobaladdr:$absaddr)>;
   2956 
   2957 def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
   2958           (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
   2959 }
   2960 
   2961 //===----------------------------------------------------------------------===//
   2962 // multiclass for load instructions with GP-relative addressing mode.
   2963 // Rx=mem[bhwd](##global)
   2964 // if ([!]Pv[.new]) Rx=mem[bhwd](##global)
   2965 //===----------------------------------------------------------------------===//
   2966 let neverHasSideEffects = 1, validSubTargets = HasV4SubT in
   2967 multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> {
   2968   let BaseOpcode = BaseOp in {
   2969     let isPredicable = 1 in
   2970     def NAME#_V4 : LDInst2<(outs RC:$dst),
   2971             (ins globaladdress:$global),
   2972             "$dst = "#mnemonic#"(#$global)",
   2973             []>;
   2974 
   2975     let isExtended = 1, opExtendable = 2, isPredicated = 1 in {
   2976       defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>;
   2977       defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>;
   2978     }
   2979   }
   2980 }
   2981 
   2982 defm LDd_GP  : LD_GP<"memd",  "LDd_GP",  DoubleRegs>, PredNewRel;
   2983 defm LDb_GP  : LD_GP<"memb",  "LDb_GP",  IntRegs>, PredNewRel;
   2984 defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
   2985 defm LDh_GP  : LD_GP<"memh",  "LDh_GP",  IntRegs>, PredNewRel;
   2986 defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
   2987 defm LDw_GP  : LD_GP<"memw",  "LDw_GP",  IntRegs>, PredNewRel;
   2988 
   2989 def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
   2990            (i64 (LDd_GP_V4 tglobaladdr:$global))>;
   2991 
   2992 def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)),
   2993            (i32 (LDw_GP_V4 tglobaladdr:$global))>;
   2994 
   2995 def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)),
   2996            (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
   2997 
   2998 def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)),
   2999            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
   3000 
   3001 // Map from load(globaladdress) -> memw(#foo + 0)
   3002 let AddedComplexity = 100 in
   3003 def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))),
   3004            (i64 (LDd_GP_V4 tglobaladdr:$global))>;
   3005 
   3006 // Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd
   3007 let AddedComplexity = 100 in
   3008 def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))),
   3009            (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>;
   3010 
   3011 // When the Interprocedural Global Variable optimizer realizes that a certain
   3012 // global variable takes only two constant values, it shrinks the global to
   3013 // a boolean. Catch those loads here in the following 3 patterns.
   3014 let AddedComplexity = 100 in
   3015 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
   3016            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
   3017 
   3018 let AddedComplexity = 100 in
   3019 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
   3020            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
   3021 
   3022 // Map from load(globaladdress) -> memb(#foo)
   3023 let AddedComplexity = 100 in
   3024 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
   3025            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
   3026 
   3027 // Map from load(globaladdress) -> memb(#foo)
   3028 let AddedComplexity = 100 in
   3029 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
   3030            (i32 (LDb_GP_V4 tglobaladdr:$global))>;
   3031 
   3032 let AddedComplexity = 100 in
   3033 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))),
   3034            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
   3035 
   3036 // Map from load(globaladdress) -> memub(#foo)
   3037 let AddedComplexity = 100 in
   3038 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))),
   3039            (i32 (LDub_GP_V4 tglobaladdr:$global))>;
   3040 
   3041 // Map from load(globaladdress) -> memh(#foo)
   3042 let AddedComplexity = 100 in
   3043 def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
   3044            (i32 (LDh_GP_V4 tglobaladdr:$global))>;
   3045 
   3046 // Map from load(globaladdress) -> memh(#foo)
   3047 let AddedComplexity = 100 in
   3048 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
   3049            (i32 (LDh_GP_V4 tglobaladdr:$global))>;
   3050 
   3051 // Map from load(globaladdress) -> memuh(#foo)
   3052 let AddedComplexity = 100 in
   3053 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))),
   3054            (i32 (LDuh_GP_V4 tglobaladdr:$global))>;
   3055 
   3056 // Map from load(globaladdress) -> memw(#foo)
   3057 let AddedComplexity = 100 in
   3058 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))),
   3059            (i32 (LDw_GP_V4 tglobaladdr:$global))>;
   3060 
   3061 
   3062 // Transfer global address into a register
   3063 let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
   3064 isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in
   3065 def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
   3066            "$dst = #$src1",
   3067            [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
   3068            Requires<[HasV4T]>;
   3069 
   3070 // Transfer a block address into a register
   3071 def : Pat<(HexagonCONST32_GP tblockaddress:$src1),
   3072           (TFRI_V4 tblockaddress:$src1)>,
   3073           Requires<[HasV4T]>;
   3074 
   3075 let isExtended = 1, opExtendable = 2, AddedComplexity=50,
   3076 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
   3077 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
   3078                            (ins PredRegs:$src1, s16Ext:$src2),
   3079            "if($src1) $dst = #$src2",
   3080            []>,
   3081            Requires<[HasV4T]>;
   3082 
   3083 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
   3084 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
   3085 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
   3086                               (ins PredRegs:$src1, s16Ext:$src2),
   3087            "if(!$src1) $dst = #$src2",
   3088            []>,
   3089            Requires<[HasV4T]>;
   3090 
   3091 let isExtended = 1, opExtendable = 2, AddedComplexity=50,
   3092 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
   3093 def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
   3094                              (ins PredRegs:$src1, s16Ext:$src2),
   3095            "if($src1.new) $dst = #$src2",
   3096            []>,
   3097            Requires<[HasV4T]>;
   3098 
   3099 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
   3100 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
   3101 def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
   3102                                 (ins PredRegs:$src1, s16Ext:$src2),
   3103            "if(!$src1.new) $dst = #$src2",
   3104            []>,
   3105            Requires<[HasV4T]>;
   3106 
   3107 let AddedComplexity = 50, Predicates = [HasV4T] in
   3108 def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
   3109            (TFRI_V4 tglobaladdr:$src1)>,
   3110            Requires<[HasV4T]>;
   3111 
   3112 
   3113 // Load - Indirect with long offset: These instructions take global address
   3114 // as an operand
   3115 let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
   3116 validSubTargets = HasV4SubT in
   3117 def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
   3118             (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
   3119             "$dst=memd($src1<<#$src2+##$offset)",
   3120             [(set (i64 DoubleRegs:$dst),
   3121                   (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
   3122                         (HexagonCONST32 tglobaladdr:$offset))))]>,
   3123             Requires<[HasV4T]>;
   3124 
   3125 let AddedComplexity = 40 in
   3126 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
   3127 let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
   3128   def _lo_V4 : LDInst<(outs IntRegs:$dst),
   3129             (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
   3130             !strconcat("$dst = ",
   3131             !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
   3132             [(set IntRegs:$dst,
   3133                   (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2),
   3134                           (HexagonCONST32 tglobaladdr:$offset)))))]>,
   3135             Requires<[HasV4T]>;
   3136 }
   3137 
   3138 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
   3139 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
   3140 defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
   3141 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
   3142 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
   3143 defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
   3144 defm LDriw_ind : LD_indirect_lo<"memw", load>;
   3145 
   3146 let AddedComplexity = 40 in
   3147 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
   3148                                  (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
   3149            (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
   3150            Requires<[HasV4T]>;
   3151 
   3152 let AddedComplexity = 40 in
   3153 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
   3154                                  (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
   3155            (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
   3156            Requires<[HasV4T]>;
   3157 
   3158 let Predicates = [HasV4T], AddedComplexity  = 30 in {
   3159 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
   3160           (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
   3161 
   3162 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
   3163           (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
   3164 
   3165 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
   3166           (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
   3167 }
   3168 
   3169 let Predicates = [HasV4T], AddedComplexity  = 30 in {
   3170 def : Pat<(i32 (load u0AlwaysExtPred:$src)),
   3171           (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
   3172 
   3173 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
   3174           (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
   3175 
   3176 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
   3177           (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
   3178 
   3179 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
   3180           (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
   3181 
   3182 def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
   3183           (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
   3184 }
   3185 
   3186 // Indexed store word - global address.
   3187 // memw(Rs+#u6:2)=#S8
   3188 let AddedComplexity = 10 in
   3189 def STriw_offset_ext_V4 : STInst<(outs),
   3190             (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3),
   3191             "memw($src1+#$src2) = ##$src3",
   3192             [(store (HexagonCONST32 tglobaladdr:$src3),
   3193                     (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
   3194             Requires<[HasV4T]>;
   3195 
   3196 def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
   3197           (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
   3198           Requires<[HasV4T]>;
   3199 
   3200 def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
   3201           (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
   3202           Requires<[HasV4T]>;
   3203 
   3204 
   3205 // i8 -> i64 loads
   3206 // We need a complexity of 120 here to override preceding handling of
   3207 // zextloadi8.
   3208 let Predicates = [HasV4T], AddedComplexity = 120 in {
   3209 def:  Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3210       (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
   3211 
   3212 def:  Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3213       (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
   3214 
   3215 def:  Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3216       (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>;
   3217 
   3218 def:  Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
   3219       (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
   3220 
   3221 def:  Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
   3222       (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
   3223 
   3224 def:  Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
   3225       (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
   3226 }
   3227 // i16 -> i64 loads
   3228 // We need a complexity of 120 here to override preceding handling of
   3229 // zextloadi16.
   3230 let AddedComplexity = 120 in {
   3231 def:  Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3232       (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
   3233       Requires<[HasV4T]>;
   3234 
   3235 def:  Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3236       (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
   3237       Requires<[HasV4T]>;
   3238 
   3239 def:  Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3240       (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>,
   3241       Requires<[HasV4T]>;
   3242 
   3243 def:  Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
   3244       (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
   3245       Requires<[HasV4T]>;
   3246 
   3247 def:  Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
   3248       (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
   3249       Requires<[HasV4T]>;
   3250 
   3251 def:  Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
   3252       (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
   3253       Requires<[HasV4T]>;
   3254 }
   3255 // i32->i64 loads
   3256 // We need a complexity of 120 here to override preceding handling of
   3257 // zextloadi32.
   3258 let AddedComplexity = 120 in {
   3259 def:  Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3260       (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
   3261       Requires<[HasV4T]>;
   3262 
   3263 def:  Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3264       (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
   3265       Requires<[HasV4T]>;
   3266 
   3267 def:  Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
   3268       (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>,
   3269       Requires<[HasV4T]>;
   3270 
   3271 def:  Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
   3272       (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
   3273       Requires<[HasV4T]>;
   3274 
   3275 def:  Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
   3276       (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
   3277       Requires<[HasV4T]>;
   3278 
   3279 def:  Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
   3280       (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
   3281       Requires<[HasV4T]>;
   3282 }
   3283 
   3284 // Indexed store double word - global address.
   3285 // memw(Rs+#u6:2)=#S8
   3286 let AddedComplexity = 10 in
   3287 def STrih_offset_ext_V4 : STInst<(outs),
   3288             (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3),
   3289             "memh($src1+#$src2) = ##$src3",
   3290             [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3),
   3291                     (add IntRegs:$src1, u6_1ImmPred:$src2))]>,
   3292             Requires<[HasV4T]>;
   3293 // Map from store(globaladdress + x) -> memd(#foo + x)
   3294 let AddedComplexity = 100 in
   3295 def : Pat<(store (i64 DoubleRegs:$src1),
   3296                  FoldGlobalAddrGP:$addr),
   3297           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
   3298           Requires<[HasV4T]>;
   3299 
   3300 def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr,
   3301                            (i64 DoubleRegs:$src1)),
   3302           (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>,
   3303           Requires<[HasV4T]>;
   3304 
   3305 // Map from store(globaladdress + x) -> memb(#foo + x)
   3306 let AddedComplexity = 100 in
   3307 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
   3308           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3309             Requires<[HasV4T]>;
   3310 
   3311 def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
   3312           (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3313             Requires<[HasV4T]>;
   3314 
   3315 // Map from store(globaladdress + x) -> memh(#foo + x)
   3316 let AddedComplexity = 100 in
   3317 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
   3318           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3319             Requires<[HasV4T]>;
   3320 
   3321 def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
   3322           (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3323             Requires<[HasV4T]>;
   3324 
   3325 // Map from store(globaladdress + x) -> memw(#foo + x)
   3326 let AddedComplexity = 100 in
   3327 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr),
   3328           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3329            Requires<[HasV4T]>;
   3330 
   3331 def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)),
   3332           (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>,
   3333             Requires<[HasV4T]>;
   3334 
   3335 // Map from load(globaladdress + x) -> memd(#foo + x)
   3336 let AddedComplexity = 100 in
   3337 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)),
   3338           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
   3339            Requires<[HasV4T]>;
   3340 
   3341 def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr),
   3342           (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>,
   3343            Requires<[HasV4T]>;
   3344 
   3345 // Map from load(globaladdress + x) -> memb(#foo + x)
   3346 let AddedComplexity = 100 in
   3347 def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)),
   3348           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
   3349            Requires<[HasV4T]>;
   3350 
   3351 // Map from load(globaladdress + x) -> memb(#foo + x)
   3352 let AddedComplexity = 100 in
   3353 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)),
   3354           (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>,
   3355            Requires<[HasV4T]>;
   3356 
   3357 //let AddedComplexity = 100 in
   3358 let AddedComplexity = 100 in
   3359 def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)),
   3360           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
   3361            Requires<[HasV4T]>;
   3362 
   3363 // Map from load(globaladdress + x) -> memh(#foo + x)
   3364 let AddedComplexity = 100 in
   3365 def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)),
   3366           (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>,
   3367            Requires<[HasV4T]>;
   3368 
   3369 // Map from load(globaladdress + x) -> memuh(#foo + x)
   3370 let AddedComplexity = 100 in
   3371 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)),
   3372           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
   3373            Requires<[HasV4T]>;
   3374 
   3375 def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr),
   3376           (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>,
   3377            Requires<[HasV4T]>;
   3378 
   3379 // Map from load(globaladdress + x) -> memub(#foo + x)
   3380 let AddedComplexity = 100 in
   3381 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)),
   3382           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
   3383            Requires<[HasV4T]>;
   3384 
   3385 def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr),
   3386           (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>,
   3387            Requires<[HasV4T]>;
   3388 
   3389 // Map from load(globaladdress + x) -> memw(#foo + x)
   3390 let AddedComplexity = 100 in
   3391 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)),
   3392           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
   3393            Requires<[HasV4T]>;
   3394 
   3395 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr),
   3396           (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>,
   3397            Requires<[HasV4T]>;
   3398