1234285Sdim//=- HexagonInstrInfoV4.td - Target Desc. for Hexagon Target -*- tablegen -*-=// 2234285Sdim// 3234285Sdim// The LLVM Compiler Infrastructure 4234285Sdim// 5234285Sdim// This file is distributed under the University of Illinois Open Source 6234285Sdim// License. See LICENSE.TXT for details. 7234285Sdim// 8234285Sdim//===----------------------------------------------------------------------===// 9234285Sdim// 10234285Sdim// This file describes the Hexagon V4 instructions in TableGen format. 11234285Sdim// 12234285Sdim//===----------------------------------------------------------------------===// 13234285Sdim 14239462Sdimlet neverHasSideEffects = 1 in 15249423Sdimclass T_Immext<dag ins> : 16249423Sdim EXTENDERInst<(outs), ins, "immext(#$imm)", []>, 17249423Sdim Requires<[HasV4T]>; 18239462Sdim 19249423Sdimdef IMMEXT_b : T_Immext<(ins brtarget:$imm)>; 20249423Sdimdef IMMEXT_c : T_Immext<(ins calltarget:$imm)>; 21249423Sdimdef IMMEXT_g : T_Immext<(ins globaladdress:$imm)>; 22249423Sdimdef IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>; 23249423Sdim 24249423Sdim// Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address. 25249423Sdimdef FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>; 26249423Sdim 27249423Sdim// Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address. 28249423Sdimdef FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>; 29249423Sdim 30249423Sdimdef NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr), 31249423Sdim (HexagonCONST32 node:$addr), [{ 32249423Sdim return hasNumUsesBelowThresGA(N->getOperand(0).getNode()); 33249423Sdim}]>; 34249423Sdim 35234285Sdim// Hexagon V4 Architecture spec defines 8 instruction classes: 36234285Sdim// LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the 37234285Sdim// compiler) 38234285Sdim 39234285Sdim// LD Instructions: 40234285Sdim// ======================================== 41234285Sdim// Loads (8/16/32/64 bit) 42234285Sdim// Deallocframe 43234285Sdim 44234285Sdim// ST Instructions: 45234285Sdim// ======================================== 46234285Sdim// Stores (8/16/32/64 bit) 47234285Sdim// Allocframe 48234285Sdim 49234285Sdim// ALU32 Instructions: 50234285Sdim// ======================================== 51234285Sdim// Arithmetic / Logical (32 bit) 52234285Sdim// Vector Halfword 53234285Sdim 54234285Sdim// XTYPE Instructions (32/64 bit): 55234285Sdim// ======================================== 56234285Sdim// Arithmetic, Logical, Bit Manipulation 57234285Sdim// Multiply (Integer, Fractional, Complex) 58234285Sdim// Permute / Vector Permute Operations 59234285Sdim// Predicate Operations 60234285Sdim// Shift / Shift with Add/Sub/Logical 61234285Sdim// Vector Byte ALU 62234285Sdim// Vector Halfword (ALU, Shift, Multiply) 63234285Sdim// Vector Word (ALU, Shift) 64234285Sdim 65234285Sdim// J Instructions: 66234285Sdim// ======================================== 67234285Sdim// Jump/Call PC-relative 68234285Sdim 69234285Sdim// JR Instructions: 70234285Sdim// ======================================== 71234285Sdim// Jump/Call Register 72234285Sdim 73234285Sdim// MEMOP Instructions: 74234285Sdim// ======================================== 75234285Sdim// Operation on memory (8/16/32 bit) 76234285Sdim 77234285Sdim// NV Instructions: 78234285Sdim// ======================================== 79234285Sdim// New-value Jumps 80234285Sdim// New-value Stores 81234285Sdim 82234285Sdim// CR Instructions: 83234285Sdim// ======================================== 84234285Sdim// Control-Register Transfers 85234285Sdim// Hardware Loop Setup 86234285Sdim// Predicate Logicals & Reductions 87234285Sdim 88234285Sdim// SYSTEM Instructions (not implemented in the compiler): 89234285Sdim// ======================================== 90234285Sdim// Prefetch 91234285Sdim// Cache Maintenance 92234285Sdim// Bus Operations 93234285Sdim 94234285Sdim 95234285Sdim//===----------------------------------------------------------------------===// 96234285Sdim// ALU32 + 97234285Sdim//===----------------------------------------------------------------------===// 98249423Sdim// Generate frame index addresses. 99249423Sdimlet neverHasSideEffects = 1, isReMaterializable = 1, 100249423SdimisExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in 101249423Sdimdef TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst), 102249423Sdim (ins IntRegs:$src1, s32Imm:$offset), 103249423Sdim "$dst = add($src1, ##$offset)", 104234285Sdim []>, 105234285Sdim Requires<[HasV4T]>; 106234285Sdim 107249423Sdim// Rd=cmp.eq(Rs,#s8) 108249423Sdimlet validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2, 109249423SdimisExtentSigned = 1, opExtentBits = 8 in 110249423Sdimdef V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd), 111249423Sdim (ins IntRegs:$Rs, s8Ext:$s8), 112249423Sdim "$Rd = cmp.eq($Rs, #$s8)", 113249423Sdim [(set (i32 IntRegs:$Rd), 114249423Sdim (i32 (zext (i1 (seteq (i32 IntRegs:$Rs), 115249423Sdim s8ExtPred:$s8)))))]>, 116249423Sdim Requires<[HasV4T]>; 117234285Sdim 118249423Sdim// Preserve the TSTBIT generation 119249423Sdimdef : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))), 120249423Sdim (i32 IntRegs:$src1))), 0)))), 121249423Sdim (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 122249423Sdim 1, 0))>; 123234285Sdim 124249423Sdim// Interfered with tstbit generation, above pattern preserves, see : tstbit.ll 125249423Sdim// Rd=cmp.ne(Rs,#s8) 126249423Sdimlet validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2, 127249423SdimisExtentSigned = 1, opExtentBits = 8 in 128249423Sdimdef V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd), 129249423Sdim (ins IntRegs:$Rs, s8Ext:$s8), 130249423Sdim "$Rd = !cmp.eq($Rs, #$s8)", 131249423Sdim [(set (i32 IntRegs:$Rd), 132249423Sdim (i32 (zext (i1 (setne (i32 IntRegs:$Rs), 133249423Sdim s8ExtPred:$s8)))))]>, 134249423Sdim Requires<[HasV4T]>; 135234285Sdim 136249423Sdim// Rd=cmp.eq(Rs,Rt) 137249423Sdimlet validSubTargets = HasV4SubT in 138249423Sdimdef V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd), 139249423Sdim (ins IntRegs:$Rs, IntRegs:$Rt), 140249423Sdim "$Rd = cmp.eq($Rs, $Rt)", 141249423Sdim [(set (i32 IntRegs:$Rd), 142249423Sdim (i32 (zext (i1 (seteq (i32 IntRegs:$Rs), 143249423Sdim IntRegs:$Rt)))))]>, 144249423Sdim Requires<[HasV4T]>; 145234285Sdim 146249423Sdim// Rd=cmp.ne(Rs,Rt) 147249423Sdimlet validSubTargets = HasV4SubT in 148249423Sdimdef V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd), 149249423Sdim (ins IntRegs:$Rs, IntRegs:$Rt), 150249423Sdim "$Rd = !cmp.eq($Rs, $Rt)", 151249423Sdim [(set (i32 IntRegs:$Rd), 152249423Sdim (i32 (zext (i1 (setne (i32 IntRegs:$Rs), 153249423Sdim IntRegs:$Rt)))))]>, 154249423Sdim Requires<[HasV4T]>; 155234285Sdim 156234285Sdim//===----------------------------------------------------------------------===// 157234285Sdim// ALU32 - 158234285Sdim//===----------------------------------------------------------------------===// 159234285Sdim 160234285Sdim 161239462Sdim//===----------------------------------------------------------------------===// 162239462Sdim// ALU32/PERM + 163239462Sdim//===----------------------------------------------------------------------===// 164234285Sdim 165239462Sdim// Combine 166239462Sdim// Rdd=combine(Rs, #s8) 167249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 168249423Sdim neverHasSideEffects = 1, validSubTargets = HasV4SubT in 169249423Sdimdef COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst), 170249423Sdim (ins IntRegs:$src1, s8Ext:$src2), 171239462Sdim "$dst = combine($src1, #$src2)", 172239462Sdim []>, 173239462Sdim Requires<[HasV4T]>; 174249423Sdim 175239462Sdim// Rdd=combine(#s8, Rs) 176249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8, 177249423Sdim neverHasSideEffects = 1, validSubTargets = HasV4SubT in 178249423Sdimdef COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst), 179249423Sdim (ins s8Ext:$src1, IntRegs:$src2), 180239462Sdim "$dst = combine(#$src1, $src2)", 181239462Sdim []>, 182239462Sdim Requires<[HasV4T]>; 183249423Sdim 184249423Sdimdef HexagonWrapperCombineRI_V4 : 185249423Sdim SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>; 186249423Sdimdef HexagonWrapperCombineIR_V4 : 187249423Sdim SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>; 188249423Sdim 189249423Sdimdef : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i), 190249423Sdim (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>, 191249423Sdim Requires<[HasV4T]>; 192249423Sdim 193249423Sdimdef : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r), 194249423Sdim (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>, 195249423Sdim Requires<[HasV4T]>; 196249423Sdim 197249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6, 198249423Sdim neverHasSideEffects = 1, validSubTargets = HasV4SubT in 199249423Sdimdef COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst), 200249423Sdim (ins s8Imm:$src1, u6Ext:$src2), 201249423Sdim "$dst = combine(#$src1, #$src2)", 202249423Sdim []>, 203249423Sdim Requires<[HasV4T]>; 204249423Sdim 205234285Sdim//===----------------------------------------------------------------------===// 206239462Sdim// ALU32/PERM + 207239462Sdim//===----------------------------------------------------------------------===// 208239462Sdim 209239462Sdim//===----------------------------------------------------------------------===// 210234285Sdim// LD + 211234285Sdim//===----------------------------------------------------------------------===// 212251662Sdim//===----------------------------------------------------------------------===// 213251662Sdim// Template class for load instructions with Absolute set addressing mode. 214251662Sdim//===----------------------------------------------------------------------===// 215249423Sdimlet isExtended = 1, opExtendable = 2, neverHasSideEffects = 1, 216263508SdimvalidSubTargets = HasV4SubT, addrMode = AbsoluteSet in 217251662Sdimclass T_LD_abs_set<string mnemonic, RegisterClass RC>: 218251662Sdim LDInst2<(outs RC:$dst1, IntRegs:$dst2), 219249423Sdim (ins u0AlwaysExt:$addr), 220251662Sdim "$dst1 = "#mnemonic#"($dst2=##$addr)", 221239462Sdim []>, 222239462Sdim Requires<[HasV4T]>; 223239462Sdim 224251662Sdimdef LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>; 225251662Sdimdef LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>; 226251662Sdimdef LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>; 227251662Sdimdef LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>; 228251662Sdimdef LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>; 229251662Sdimdef LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>; 230239462Sdim 231239462Sdim 232249423Sdim// multiclass for load instructions with base + register offset 233249423Sdim// addressing mode 234249423Sdimmulticlass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot, 235249423Sdim bit isPredNew> { 236251662Sdim let isPredicatedNew = isPredNew in 237249423Sdim def NAME : LDInst2<(outs RC:$dst), 238249423Sdim (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), 239249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 240249423Sdim ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)", 241249423Sdim []>, Requires<[HasV4T]>; 242249423Sdim} 243234285Sdim 244249423Sdimmulticlass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> { 245251662Sdim let isPredicatedFalse = PredNot in { 246249423Sdim defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>; 247249423Sdim // Predicate new 248249423Sdim defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>; 249249423Sdim } 250249423Sdim} 251234285Sdim 252249423Sdimlet neverHasSideEffects = 1 in 253249423Sdimmulticlass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> { 254249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 255249423Sdim let isPredicable = 1 in 256249423Sdim def NAME#_V4 : LDInst2<(outs RC:$dst), 257249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), 258249423Sdim "$dst = "#mnemonic#"($src1+$src2<<#$offset)", 259249423Sdim []>, Requires<[HasV4T]>; 260234285Sdim 261249423Sdim let isPredicated = 1 in { 262249423Sdim defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >; 263249423Sdim defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>; 264249423Sdim } 265249423Sdim } 266249423Sdim} 267234285Sdim 268249423Sdimlet addrMode = BaseRegOffset in { 269263508Sdim let accessSize = ByteAccess in { 270263508Sdim defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, 271263508Sdim AddrModeRel; 272263508Sdim defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, 273263508Sdim AddrModeRel; 274263508Sdim } 275263508Sdim let accessSize = HalfWordAccess in { 276263508Sdim defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel; 277263508Sdim defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, 278263508Sdim AddrModeRel; 279263508Sdim } 280263508Sdim let accessSize = WordAccess in 281263508Sdim defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel; 282263508Sdim 283263508Sdim let accessSize = DoubleWordAccess in 284263508Sdim defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, 285263508Sdim AddrModeRel; 286249423Sdim} 287234285Sdim 288249423Sdim// 'def pats' for load instructions with base + register offset and non-zero 289249423Sdim// immediate value. Immediate value is used to left-shift the second 290249423Sdim// register operand. 291249423Sdimlet AddedComplexity = 40 in { 292249423Sdimdef : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 293249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 294249423Sdim (LDrib_indexed_shl_V4 IntRegs:$src1, 295249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 296239462Sdim Requires<[HasV4T]>; 297239462Sdim 298249423Sdimdef : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 299249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 300249423Sdim (LDriub_indexed_shl_V4 IntRegs:$src1, 301249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 302234285Sdim Requires<[HasV4T]>; 303234285Sdim 304249423Sdimdef : Pat <(i32 (extloadi8 (add IntRegs:$src1, 305249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 306249423Sdim (LDriub_indexed_shl_V4 IntRegs:$src1, 307249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 308234285Sdim Requires<[HasV4T]>; 309234285Sdim 310249423Sdimdef : Pat <(i32 (sextloadi16 (add IntRegs:$src1, 311249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 312249423Sdim (LDrih_indexed_shl_V4 IntRegs:$src1, 313249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 314234285Sdim Requires<[HasV4T]>; 315234285Sdim 316249423Sdimdef : Pat <(i32 (zextloadi16 (add IntRegs:$src1, 317249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 318249423Sdim (LDriuh_indexed_shl_V4 IntRegs:$src1, 319249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 320234285Sdim Requires<[HasV4T]>; 321234285Sdim 322249423Sdimdef : Pat <(i32 (extloadi16 (add IntRegs:$src1, 323249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 324249423Sdim (LDriuh_indexed_shl_V4 IntRegs:$src1, 325249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 326234285Sdim Requires<[HasV4T]>; 327234285Sdim 328249423Sdimdef : Pat <(i32 (load (add IntRegs:$src1, 329249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 330249423Sdim (LDriw_indexed_shl_V4 IntRegs:$src1, 331249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 332234285Sdim Requires<[HasV4T]>; 333234285Sdim 334249423Sdimdef : Pat <(i64 (load (add IntRegs:$src1, 335249423Sdim (shl IntRegs:$src2, u2ImmPred:$offset)))), 336249423Sdim (LDrid_indexed_shl_V4 IntRegs:$src1, 337249423Sdim IntRegs:$src2, u2ImmPred:$offset)>, 338234285Sdim Requires<[HasV4T]>; 339249423Sdim} 340234285Sdim 341234285Sdim 342249423Sdim// 'def pats' for load instruction base + register offset and 343249423Sdim// zero immediate value. 344249423Sdimlet AddedComplexity = 10 in { 345249423Sdimdef : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))), 346249423Sdim (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 347234285Sdim Requires<[HasV4T]>; 348234285Sdim 349249423Sdimdef : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 350249423Sdim (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 351234285Sdim Requires<[HasV4T]>; 352234285Sdim 353249423Sdimdef : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 354249423Sdim (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 355234285Sdim Requires<[HasV4T]>; 356234285Sdim 357249423Sdimdef : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))), 358249423Sdim (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 359234285Sdim Requires<[HasV4T]>; 360234285Sdim 361249423Sdimdef : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 362249423Sdim (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 363239462Sdim Requires<[HasV4T]>; 364239462Sdim 365249423Sdimdef : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 366249423Sdim (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 367239462Sdim Requires<[HasV4T]>; 368239462Sdim 369249423Sdimdef : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))), 370249423Sdim (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 371239462Sdim Requires<[HasV4T]>; 372239462Sdim 373249423Sdimdef : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))), 374249423Sdim (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 375239462Sdim Requires<[HasV4T]>; 376249423Sdim} 377239462Sdim 378249423Sdim// zext i1->i64 379249423Sdimdef : Pat <(i64 (zext (i1 PredRegs:$src1))), 380249423Sdim (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>, 381249423Sdim Requires<[HasV4T]>; 382239462Sdim 383249423Sdim// zext i32->i64 384249423Sdimdef : Pat <(i64 (zext (i32 IntRegs:$src1))), 385249423Sdim (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>, 386249423Sdim Requires<[HasV4T]>; 387249423Sdim// zext i8->i64 388249423Sdimdef: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)), 389249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>, 390249423Sdim Requires<[HasV4T]>; 391239462Sdim 392249423Sdimlet AddedComplexity = 20 in 393249423Sdimdef: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1), 394249423Sdim s11_0ExtPred:$offset))), 395249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1, 396249423Sdim s11_0ExtPred:$offset)))>, 397249423Sdim Requires<[HasV4T]>; 398239462Sdim 399249423Sdim// zext i1->i64 400249423Sdimdef: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)), 401249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>, 402249423Sdim Requires<[HasV4T]>; 403239462Sdim 404249423Sdimlet AddedComplexity = 20 in 405249423Sdimdef: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1), 406249423Sdim s11_0ExtPred:$offset))), 407249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1, 408249423Sdim s11_0ExtPred:$offset)))>, 409249423Sdim Requires<[HasV4T]>; 410239462Sdim 411249423Sdim// zext i16->i64 412249423Sdimdef: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)), 413249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>, 414249423Sdim Requires<[HasV4T]>; 415239462Sdim 416249423Sdimlet AddedComplexity = 20 in 417249423Sdimdef: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1), 418249423Sdim s11_1ExtPred:$offset))), 419249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1, 420249423Sdim s11_1ExtPred:$offset)))>, 421249423Sdim Requires<[HasV4T]>; 422239462Sdim 423249423Sdim// anyext i16->i64 424249423Sdimdef: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)), 425249423Sdim (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>, 426249423Sdim Requires<[HasV4T]>; 427239462Sdim 428249423Sdimlet AddedComplexity = 20 in 429249423Sdimdef: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1), 430249423Sdim s11_1ExtPred:$offset))), 431249423Sdim (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1, 432249423Sdim s11_1ExtPred:$offset)))>, 433249423Sdim Requires<[HasV4T]>; 434239462Sdim 435249423Sdim// zext i32->i64 436249423Sdimdef: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)), 437249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>, 438249423Sdim Requires<[HasV4T]>; 439239462Sdim 440239462Sdimlet AddedComplexity = 100 in 441249423Sdimdef: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 442249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1, 443249423Sdim s11_2ExtPred:$offset)))>, 444249423Sdim Requires<[HasV4T]>; 445239462Sdim 446249423Sdim// anyext i32->i64 447249423Sdimdef: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)), 448249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>, 449249423Sdim Requires<[HasV4T]>; 450239462Sdim 451239462Sdimlet AddedComplexity = 100 in 452249423Sdimdef: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 453249423Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1, 454249423Sdim s11_2ExtPred:$offset)))>, 455249423Sdim Requires<[HasV4T]>; 456239462Sdim 457239462Sdim 458239462Sdim 459234285Sdim//===----------------------------------------------------------------------===// 460234285Sdim// LD - 461234285Sdim//===----------------------------------------------------------------------===// 462234285Sdim 463234285Sdim//===----------------------------------------------------------------------===// 464234285Sdim// ST + 465234285Sdim//===----------------------------------------------------------------------===// 466234285Sdim/// 467251662Sdim//===----------------------------------------------------------------------===// 468251662Sdim// Template class for store instructions with Absolute set addressing mode. 469251662Sdim//===----------------------------------------------------------------------===// 470263508Sdimlet isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT, 471263508SdimaddrMode = AbsoluteSet in 472251662Sdimclass T_ST_abs_set<string mnemonic, RegisterClass RC>: 473251662Sdim STInst2<(outs IntRegs:$dst1), 474251662Sdim (ins RC:$src1, u0AlwaysExt:$src2), 475251662Sdim mnemonic#"($dst1=##$src2) = $src1", 476239462Sdim []>, 477239462Sdim Requires<[HasV4T]>; 478234285Sdim 479251662Sdimdef STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>; 480251662Sdimdef STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>; 481251662Sdimdef STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>; 482251662Sdimdef STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>; 483239462Sdim 484251662Sdim//===----------------------------------------------------------------------===// 485249423Sdim// multiclass for store instructions with base + register offset addressing 486249423Sdim// mode 487251662Sdim//===----------------------------------------------------------------------===// 488249423Sdimmulticlass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot, 489249423Sdim bit isPredNew> { 490251662Sdim let isPredicatedNew = isPredNew in 491249423Sdim def NAME : STInst2<(outs), 492249423Sdim (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, 493249423Sdim RC:$src5), 494249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 495249423Sdim ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5", 496249423Sdim []>, 497234285Sdim Requires<[HasV4T]>; 498249423Sdim} 499234285Sdim 500249423Sdimmulticlass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 501251662Sdim let isPredicatedFalse = PredNot in { 502249423Sdim defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>; 503249423Sdim // Predicate new 504249423Sdim defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>; 505249423Sdim } 506249423Sdim} 507249423Sdim 508249423Sdimlet isNVStorable = 1 in 509249423Sdimmulticlass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> { 510249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 511249423Sdim let isPredicable = 1 in 512249423Sdim def NAME#_V4 : STInst2<(outs), 513249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4), 514249423Sdim mnemonic#"($src1+$src2<<#$src3) = $src4", 515249423Sdim []>, 516249423Sdim Requires<[HasV4T]>; 517249423Sdim 518249423Sdim let isPredicated = 1 in { 519249423Sdim defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >; 520249423Sdim defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>; 521249423Sdim } 522249423Sdim } 523249423Sdim} 524249423Sdim 525249423Sdim// multiclass for new-value store instructions with base + register offset 526249423Sdim// addressing mode. 527249423Sdimmulticlass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot, 528249423Sdim bit isPredNew> { 529251662Sdim let isPredicatedNew = isPredNew in 530249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 531249423Sdim (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, 532249423Sdim RC:$src5), 533249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 534249423Sdim ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new", 535249423Sdim []>, 536249423Sdim Requires<[HasV4T]>; 537249423Sdim} 538249423Sdim 539249423Sdimmulticlass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 540251662Sdim let isPredicatedFalse = PredNot in { 541249423Sdim defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>; 542249423Sdim // Predicate new 543249423Sdim defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>; 544249423Sdim } 545249423Sdim} 546249423Sdim 547249423Sdimlet mayStore = 1, isNVStore = 1 in 548249423Sdimmulticlass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> { 549249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 550249423Sdim let isPredicable = 1 in 551249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 552249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4), 553249423Sdim mnemonic#"($src1+$src2<<#$src3) = $src4.new", 554249423Sdim []>, 555249423Sdim Requires<[HasV4T]>; 556249423Sdim 557249423Sdim let isPredicated = 1 in { 558249423Sdim defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >; 559249423Sdim defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>; 560249423Sdim } 561249423Sdim } 562249423Sdim} 563249423Sdim 564249423Sdimlet addrMode = BaseRegOffset, neverHasSideEffects = 1, 565249423SdimvalidSubTargets = HasV4SubT in { 566263508Sdim let accessSize = ByteAccess in 567263508Sdim defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>, 568263508Sdim ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel; 569249423Sdim 570263508Sdim let accessSize = HalfWordAccess in 571263508Sdim defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>, 572263508Sdim ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel; 573249423Sdim 574263508Sdim let accessSize = WordAccess in 575263508Sdim defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>, 576263508Sdim ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel; 577249423Sdim 578263508Sdim let isNVStorable = 0, accessSize = DoubleWordAccess in 579263508Sdim defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel; 580249423Sdim} 581249423Sdim 582249423Sdimlet Predicates = [HasV4T], AddedComplexity = 10 in { 583249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src4), 584249423Sdim (add IntRegs:$src1, (shl IntRegs:$src2, 585249423Sdim u2ImmPred:$src3))), 586249423Sdim (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 587249423Sdim u2ImmPred:$src3, IntRegs:$src4)>; 588249423Sdim 589249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src4), 590249423Sdim (add IntRegs:$src1, (shl IntRegs:$src2, 591249423Sdim u2ImmPred:$src3))), 592249423Sdim (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 593249423Sdim u2ImmPred:$src3, IntRegs:$src4)>; 594249423Sdim 595249423Sdimdef : Pat<(store (i32 IntRegs:$src4), 596249423Sdim (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 597249423Sdim (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 598249423Sdim u2ImmPred:$src3, IntRegs:$src4)>; 599249423Sdim 600249423Sdimdef : Pat<(store (i64 DoubleRegs:$src4), 601249423Sdim (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 602249423Sdim (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 603249423Sdim u2ImmPred:$src3, DoubleRegs:$src4)>; 604249423Sdim} 605249423Sdim 606251662Sdimlet isExtended = 1, opExtendable = 2 in 607251662Sdimclass T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> : 608251662Sdim STInst<(outs), 609251662Sdim (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4), 610251662Sdim mnemonic#"($src1<<#$src2+##$src3) = $src4", 611251662Sdim [(stOp (VT RC:$src4), 612239462Sdim (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), 613249423Sdim u0AlwaysExtPred:$src3))]>, 614234285Sdim Requires<[HasV4T]>; 615234285Sdim 616251662Sdimlet isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in 617251662Sdimclass T_ST_LongOff_nv <string mnemonic> : 618251662Sdim NVInst_V4<(outs), 619251662Sdim (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4), 620251662Sdim mnemonic#"($src1<<#$src2+##$src3) = $src4.new", 621251662Sdim []>, 622251662Sdim Requires<[HasV4T]>; 623251662Sdim 624251662Sdimmulticlass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> { 625251662Sdim let BaseOpcode = BaseOp#"_shl" in { 626251662Sdim let isNVStorable = 1 in 627251662Sdim def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>; 628251662Sdim 629251662Sdim def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>; 630251662Sdim } 631251662Sdim} 632251662Sdim 633251662Sdimlet AddedComplexity = 10, validSubTargets = HasV4SubT in { 634251662Sdim def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>; 635251662Sdim defm STrib_shl : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel; 636251662Sdim defm STrih_shl : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel; 637251662Sdim defm STriw_shl : ST_LongOff <"memw", "STriw", store>, NewValueRel; 638251662Sdim} 639251662Sdim 640251662Sdimlet AddedComplexity = 40 in 641251662Sdimmulticlass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT, 642251662Sdim PatFrag stOp> { 643251662Sdim def : Pat<(stOp (VT RC:$src4), 644251662Sdim (add (shl IntRegs:$src1, u2ImmPred:$src2), 645251662Sdim (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 646251662Sdim (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>; 647251662Sdim 648251662Sdim def : Pat<(stOp (VT RC:$src4), 649251662Sdim (add IntRegs:$src1, 650251662Sdim (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 651251662Sdim (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>; 652251662Sdim} 653251662Sdim 654251662Sdimdefm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>; 655251662Sdimdefm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>; 656251662Sdimdefm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>; 657251662Sdimdefm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>; 658251662Sdim 659234285Sdim// memd(Rx++#s4:3)=Rtt 660234285Sdim// memd(Rx++#s4:3:circ(Mu))=Rtt 661234285Sdim// memd(Rx++I:circ(Mu))=Rtt 662234285Sdim// memd(Rx++Mu)=Rtt 663234285Sdim// memd(Rx++Mu:brev)=Rtt 664234285Sdim// memd(gp+#u16:3)=Rtt 665234285Sdim 666234285Sdim// Store doubleword conditionally. 667234285Sdim// if ([!]Pv[.new]) memd(#u6)=Rtt 668234285Sdim// TODO: needs to be implemented. 669234285Sdim 670249423Sdim//===----------------------------------------------------------------------===// 671249423Sdim// multiclass for store instructions with base + immediate offset 672249423Sdim// addressing mode and immediate stored value. 673249423Sdim// mem[bhw](Rx++#s4:3)=#s8 674249423Sdim// if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6 675249423Sdim//===----------------------------------------------------------------------===// 676249423Sdimmulticlass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot, 677249423Sdim bit isPredNew> { 678251662Sdim let isPredicatedNew = isPredNew in 679249423Sdim def NAME : STInst2<(outs), 680249423Sdim (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4), 681249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 682249423Sdim ") ")#mnemonic#"($src2+#$src3) = #$src4", 683234285Sdim []>, 684234285Sdim Requires<[HasV4T]>; 685249423Sdim} 686234285Sdim 687249423Sdimmulticlass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> { 688251662Sdim let isPredicatedFalse = PredNot in { 689249423Sdim defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>; 690249423Sdim // Predicate new 691249423Sdim defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>; 692249423Sdim } 693249423Sdim} 694234285Sdim 695249423Sdimlet isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in 696249423Sdimmulticlass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> { 697249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in { 698249423Sdim let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in 699249423Sdim def NAME#_V4 : STInst2<(outs), 700249423Sdim (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3), 701249423Sdim mnemonic#"($src1+#$src2) = #$src3", 702234285Sdim []>, 703234285Sdim Requires<[HasV4T]>; 704234285Sdim 705249423Sdim let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in { 706249423Sdim defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>; 707249423Sdim defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >; 708249423Sdim } 709249423Sdim } 710249423Sdim} 711234285Sdim 712249423Sdimlet addrMode = BaseImmOffset, InputType = "imm", 713263508SdimvalidSubTargets = HasV4SubT in { 714263508Sdim let accessSize = ByteAccess in 715263508Sdim defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel; 716263508Sdim 717263508Sdim let accessSize = HalfWordAccess in 718263508Sdim defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel; 719263508Sdim 720263508Sdim let accessSize = WordAccess in 721263508Sdim defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel; 722249423Sdim} 723234285Sdim 724249423Sdimlet Predicates = [HasV4T], AddedComplexity = 10 in { 725249423Sdimdef: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)), 726249423Sdim (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>; 727234285Sdim 728249423Sdimdef: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1, 729249423Sdim u6_1ImmPred:$src2)), 730249423Sdim (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>; 731234285Sdim 732249423Sdimdef: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)), 733249423Sdim (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>; 734249423Sdim} 735234285Sdim 736249423Sdimlet AddedComplexity = 6 in 737249423Sdimdef : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)), 738249423Sdim (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 739249423Sdim Requires<[HasV4T]>; 740234285Sdim 741234285Sdim// memb(Rx++#s4:0:circ(Mu))=Rt 742234285Sdim// memb(Rx++I:circ(Mu))=Rt 743234285Sdim// memb(Rx++Mu)=Rt 744234285Sdim// memb(Rx++Mu:brev)=Rt 745234285Sdim// memb(gp+#u16:0)=Rt 746234285Sdim 747234285Sdim 748234285Sdim// Store halfword. 749239462Sdim// TODO: needs to be implemented 750234982Sdim// memh(Re=#U6)=Rt.H 751234285Sdim// memh(Rs+#s11:1)=Rt.H 752249423Sdimlet AddedComplexity = 6 in 753249423Sdimdef : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)), 754249423Sdim (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 755249423Sdim Requires<[HasV4T]>; 756234285Sdim 757234285Sdim// memh(Rs+Ru<<#u2)=Rt.H 758234285Sdim// TODO: needs to be implemented. 759234285Sdim 760234285Sdim// memh(Ru<<#u2+#U6)=Rt.H 761234285Sdim// memh(Rx++#s4:1:circ(Mu))=Rt.H 762234285Sdim// memh(Rx++#s4:1:circ(Mu))=Rt 763234285Sdim// memh(Rx++I:circ(Mu))=Rt.H 764234285Sdim// memh(Rx++I:circ(Mu))=Rt 765234285Sdim// memh(Rx++Mu)=Rt.H 766234285Sdim// memh(Rx++Mu)=Rt 767234285Sdim// memh(Rx++Mu:brev)=Rt.H 768234285Sdim// memh(Rx++Mu:brev)=Rt 769234285Sdim// memh(gp+#u16:1)=Rt 770234285Sdim// if ([!]Pv[.new]) memh(#u6)=Rt.H 771234285Sdim// if ([!]Pv[.new]) memh(#u6)=Rt 772234285Sdim 773234285Sdim 774234285Sdim// if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H 775234285Sdim// TODO: needs to be implemented. 776234285Sdim 777234285Sdim// if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H 778234285Sdim// TODO: Needs to be implemented. 779234285Sdim 780234285Sdim// Store word. 781234285Sdim// memw(Re=#U6)=Rt 782234285Sdim// TODO: Needs to be implemented. 783234285Sdim 784239462Sdim// Store predicate: 785239462Sdimlet neverHasSideEffects = 1 in 786239462Sdimdef STriw_pred_V4 : STInst2<(outs), 787239462Sdim (ins MEMri:$addr, PredRegs:$src1), 788239462Sdim "Error; should not emit", 789239462Sdim []>, 790239462Sdim Requires<[HasV4T]>; 791239462Sdim 792249423Sdimlet AddedComplexity = 6 in 793249423Sdimdef : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)), 794249423Sdim (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 795249423Sdim Requires<[HasV4T]>; 796239462Sdim 797234285Sdim// memw(Rx++#s4:2)=Rt 798234285Sdim// memw(Rx++#s4:2:circ(Mu))=Rt 799234285Sdim// memw(Rx++I:circ(Mu))=Rt 800234285Sdim// memw(Rx++Mu)=Rt 801234285Sdim// memw(Rx++Mu:brev)=Rt 802234285Sdim 803234285Sdim//===----------------------------------------------------------------------=== 804234285Sdim// ST - 805234285Sdim//===----------------------------------------------------------------------=== 806234285Sdim 807234285Sdim 808234285Sdim//===----------------------------------------------------------------------===// 809234285Sdim// NV/ST + 810234285Sdim//===----------------------------------------------------------------------===// 811234285Sdim 812249423Sdim// multiclass for new-value store instructions with base + immediate offset. 813249423Sdim// 814249423Sdimmulticlass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC, 815249423Sdim Operand predImmOp, bit isNot, bit isPredNew> { 816251662Sdim let isPredicatedNew = isPredNew in 817249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 818249423Sdim (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4), 819249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 820249423Sdim ") ")#mnemonic#"($src2+#$src3) = $src4.new", 821234285Sdim []>, 822234285Sdim Requires<[HasV4T]>; 823249423Sdim} 824234285Sdim 825249423Sdimmulticlass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp, 826249423Sdim bit PredNot> { 827251662Sdim let isPredicatedFalse = PredNot in { 828249423Sdim defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>; 829249423Sdim // Predicate new 830249423Sdim defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>; 831249423Sdim } 832249423Sdim} 833234285Sdim 834249423Sdimlet mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in 835249423Sdimmulticlass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC, 836249423Sdim Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 837249423Sdim bits<5> PredImmBits> { 838234285Sdim 839249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 840249423Sdim let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 841249423Sdim isPredicable = 1 in 842249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 843249423Sdim (ins IntRegs:$src1, ImmOp:$src2, RC:$src3), 844249423Sdim mnemonic#"($src1+#$src2) = $src3.new", 845234285Sdim []>, 846234285Sdim Requires<[HasV4T]>; 847234285Sdim 848249423Sdim let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 849249423Sdim isPredicated = 1 in { 850249423Sdim defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>; 851249423Sdim defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>; 852249423Sdim } 853249423Sdim } 854249423Sdim} 855234285Sdim 856249423Sdimlet addrMode = BaseImmOffset, validSubTargets = HasV4SubT in { 857263508Sdim let accessSize = ByteAccess in 858263508Sdim defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext, 859263508Sdim u6_0Ext, 11, 6>, AddrModeRel; 860263508Sdim 861263508Sdim let accessSize = HalfWordAccess in 862263508Sdim defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext, 863263508Sdim u6_1Ext, 12, 7>, AddrModeRel; 864263508Sdim 865263508Sdim let accessSize = WordAccess in 866263508Sdim defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext, 867263508Sdim u6_2Ext, 13, 8>, AddrModeRel; 868249423Sdim} 869234285Sdim 870249423Sdim// multiclass for new-value store instructions with base + immediate offset. 871249423Sdim// and MEMri operand. 872249423Sdimmulticlass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot, 873249423Sdim bit isPredNew> { 874251662Sdim let isPredicatedNew = isPredNew in 875249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 876249423Sdim (ins PredRegs:$src1, MEMri:$addr, RC: $src2), 877249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 878249423Sdim ") ")#mnemonic#"($addr) = $src2.new", 879234285Sdim []>, 880234285Sdim Requires<[HasV4T]>; 881249423Sdim} 882234285Sdim 883249423Sdimmulticlass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 884251662Sdim let isPredicatedFalse = PredNot in { 885249423Sdim defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>; 886234285Sdim 887249423Sdim // Predicate new 888249423Sdim defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>; 889249423Sdim } 890249423Sdim} 891234285Sdim 892249423Sdimlet mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in 893249423Sdimmulticlass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC, 894249423Sdim bits<5> ImmBits, bits<5> PredImmBits> { 895234285Sdim 896249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp in { 897249423Sdim let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 898249423Sdim isPredicable = 1 in 899249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 900249423Sdim (ins MEMri:$addr, RC:$src), 901249423Sdim mnemonic#"($addr) = $src.new", 902234285Sdim []>, 903234285Sdim Requires<[HasV4T]>; 904234285Sdim 905249423Sdim let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 906249423Sdim neverHasSideEffects = 1, isPredicated = 1 in { 907249423Sdim defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>; 908249423Sdim defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>; 909249423Sdim } 910249423Sdim } 911249423Sdim} 912234285Sdim 913249423Sdimlet addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT, 914249423SdimmayStore = 1 in { 915263508Sdim let accessSize = ByteAccess in 916263508Sdim defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel; 917263508Sdim 918263508Sdim let accessSize = HalfWordAccess in 919263508Sdim defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel; 920263508Sdim 921263508Sdim let accessSize = WordAccess in 922263508Sdim defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel; 923249423Sdim} 924234285Sdim 925249423Sdim//===----------------------------------------------------------------------===// 926249423Sdim// Post increment store 927249423Sdim// mem[bhwd](Rx++#s4:[0123])=Nt.new 928249423Sdim//===----------------------------------------------------------------------===// 929234285Sdim 930249423Sdimmulticlass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp, 931249423Sdim bit isNot, bit isPredNew> { 932251662Sdim let isPredicatedNew = isPredNew in 933249423Sdim def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), 934249423Sdim (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3), 935249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 936249423Sdim ") ")#mnemonic#"($src2++#$offset) = $src3.new", 937249423Sdim [], 938249423Sdim "$src2 = $dst">, 939234285Sdim Requires<[HasV4T]>; 940249423Sdim} 941234285Sdim 942249423Sdimmulticlass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC, 943249423Sdim Operand ImmOp, bit PredNot> { 944251662Sdim let isPredicatedFalse = PredNot in { 945249423Sdim defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>; 946249423Sdim // Predicate new 947249423Sdim let Predicates = [HasV4T], validSubTargets = HasV4SubT in 948249423Sdim defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>; 949249423Sdim } 950249423Sdim} 951234285Sdim 952249423Sdimlet hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in 953249423Sdimmulticlass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC, 954249423Sdim Operand ImmOp> { 955234285Sdim 956249423Sdim let BaseOpcode = "POST_"#BaseOp in { 957249423Sdim let isPredicable = 1 in 958249423Sdim def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), 959249423Sdim (ins IntRegs:$src1, ImmOp:$offset, RC:$src2), 960249423Sdim mnemonic#"($src1++#$offset) = $src2.new", 961249423Sdim [], 962249423Sdim "$src1 = $dst">, 963249423Sdim Requires<[HasV4T]>; 964234285Sdim 965249423Sdim let isPredicated = 1 in { 966249423Sdim defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >; 967249423Sdim defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >; 968249423Sdim } 969249423Sdim } 970249423Sdim} 971234285Sdim 972263508Sdimlet addrMode = PostInc, validSubTargets = HasV4SubT in { 973249423Sdimdefm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel; 974249423Sdimdefm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel; 975249423Sdimdefm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; 976249423Sdim} 977234285Sdim 978249423Sdim// memb(Rx++#s4:0:circ(Mu))=Nt.new 979249423Sdim// memb(Rx++I:circ(Mu))=Nt.new 980249423Sdim// memb(Rx++Mu)=Nt.new 981249423Sdim// memb(Rx++Mu:brev)=Nt.new 982234285Sdim// memh(Rx++#s4:1:circ(Mu))=Nt.new 983234285Sdim// memh(Rx++I:circ(Mu))=Nt.new 984234285Sdim// memh(Rx++Mu)=Nt.new 985234285Sdim// memh(Rx++Mu:brev)=Nt.new 986234285Sdim 987234285Sdim// memw(Rx++#s4:2:circ(Mu))=Nt.new 988234285Sdim// memw(Rx++I:circ(Mu))=Nt.new 989234285Sdim// memw(Rx++Mu)=Nt.new 990234285Sdim// memw(Rx++Mu:brev)=Nt.new 991234285Sdim 992234285Sdim//===----------------------------------------------------------------------===// 993234285Sdim// NV/ST - 994234285Sdim//===----------------------------------------------------------------------===// 995234285Sdim 996234285Sdim//===----------------------------------------------------------------------===// 997234285Sdim// NV/J + 998234285Sdim//===----------------------------------------------------------------------===// 999234285Sdim 1000251662Sdim//===----------------------------------------------------------------------===// 1001251662Sdim// multiclass/template class for the new-value compare jumps with the register 1002251662Sdim// operands. 1003251662Sdim//===----------------------------------------------------------------------===// 1004234285Sdim 1005251662Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in 1006251662Sdimclass NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum, 1007251662Sdim bit isNegCond, bit isTaken> 1008251662Sdim : NVInst_V4<(outs), 1009251662Sdim (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), 1010251662Sdim "if ("#!if(isNegCond, "!","")#mnemonic# 1011251662Sdim "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")# 1012251662Sdim "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:" 1013251662Sdim #!if(isTaken, "t","nt")#" $offset", 1014251662Sdim []>, Requires<[HasV4T]> { 1015234285Sdim 1016251662Sdim bits<5> src1; 1017251662Sdim bits<5> src2; 1018251662Sdim bits<3> Ns; // New-Value Operand 1019251662Sdim bits<5> RegOp; // Non New-Value Operand 1020251662Sdim bits<11> offset; 1021234285Sdim 1022251662Sdim let isBrTaken = !if(isTaken, "true", "false"); 1023251662Sdim let isPredicatedFalse = isNegCond; 1024234285Sdim 1025251662Sdim let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0}); 1026251662Sdim let RegOp = !if(!eq(NvOpNum, 0), src2, src1); 1027234285Sdim 1028251662Sdim let IClass = 0b0010; 1029251662Sdim let Inst{26} = 0b0; 1030251662Sdim let Inst{25-23} = majOp; 1031251662Sdim let Inst{22} = isNegCond; 1032251662Sdim let Inst{18-16} = Ns; 1033251662Sdim let Inst{13} = isTaken; 1034251662Sdim let Inst{12-8} = RegOp; 1035251662Sdim let Inst{21-20} = offset{10-9}; 1036251662Sdim let Inst{7-1} = offset{8-2}; 1037234285Sdim} 1038234285Sdim 1039234285Sdim 1040251662Sdimmulticlass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum, 1041251662Sdim bit isNegCond> { 1042251662Sdim // Branch not taken: 1043251662Sdim def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>; 1044251662Sdim // Branch taken: 1045251662Sdim def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>; 1046234285Sdim} 1047234285Sdim 1048251662Sdim// NvOpNum = 0 -> First Operand is a new-value Register 1049251662Sdim// NvOpNum = 1 -> Second Operand is a new-value Register 1050234285Sdim 1051251662Sdimmulticlass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp, 1052251662Sdim bit NvOpNum> { 1053251662Sdim let BaseOpcode = BaseOp#_NVJ in { 1054251662Sdim defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond 1055251662Sdim defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond 1056251662Sdim } 1057234285Sdim} 1058234285Sdim 1059251662Sdim// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2 1060251662Sdim// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2 1061251662Sdim// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2 1062251662Sdim// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2 1063251662Sdim// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2 1064251662Sdim 1065251662Sdimlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1066251662Sdim Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { 1067251662Sdim defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel; 1068251662Sdim defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel; 1069251662Sdim defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel; 1070251662Sdim defm CMPLTrr : NVJrr_base<"cmp.gt", "CMPLT", 0b011, 1>, PredRel; 1071251662Sdim defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel; 1072234285Sdim} 1073234285Sdim 1074251662Sdim//===----------------------------------------------------------------------===// 1075251662Sdim// multiclass/template class for the new-value compare jumps instruction 1076251662Sdim// with a register and an unsigned immediate (U5) operand. 1077251662Sdim//===----------------------------------------------------------------------===// 1078251662Sdim 1079251662Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in 1080251662Sdimclass NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond, 1081251662Sdim bit isTaken> 1082251662Sdim : NVInst_V4<(outs), 1083251662Sdim (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), 1084251662Sdim "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:" 1085251662Sdim #!if(isTaken, "t","nt")#" $offset", 1086251662Sdim []>, Requires<[HasV4T]> { 1087251662Sdim 1088251662Sdim let isPredicatedFalse = isNegCond; 1089251662Sdim let isBrTaken = !if(isTaken, "true", "false"); 1090251662Sdim 1091251662Sdim bits<3> src1; 1092251662Sdim bits<5> src2; 1093251662Sdim bits<11> offset; 1094251662Sdim 1095251662Sdim let IClass = 0b0010; 1096251662Sdim let Inst{26} = 0b1; 1097251662Sdim let Inst{25-23} = majOp; 1098251662Sdim let Inst{22} = isNegCond; 1099251662Sdim let Inst{18-16} = src1; 1100251662Sdim let Inst{13} = isTaken; 1101251662Sdim let Inst{12-8} = src2; 1102251662Sdim let Inst{21-20} = offset{10-9}; 1103251662Sdim let Inst{7-1} = offset{8-2}; 1104234285Sdim} 1105234285Sdim 1106251662Sdimmulticlass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> { 1107251662Sdim // Branch not taken: 1108251662Sdim def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>; 1109251662Sdim // Branch taken: 1110251662Sdim def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>; 1111234285Sdim} 1112234285Sdim 1113251662Sdimmulticlass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> { 1114251662Sdim let BaseOpcode = BaseOp#_NVJri in { 1115251662Sdim defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond 1116251662Sdim defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond 1117251662Sdim } 1118234285Sdim} 1119234285Sdim 1120251662Sdim// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2 1121251662Sdim// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2 1122251662Sdim// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2 1123251662Sdim 1124251662Sdimlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1125251662Sdim Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { 1126251662Sdim defm CMPEQri : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel; 1127251662Sdim defm CMPGTri : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel; 1128251662Sdim defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel; 1129234285Sdim} 1130234285Sdim 1131251662Sdim//===----------------------------------------------------------------------===// 1132251662Sdim// multiclass/template class for the new-value compare jumps instruction 1133251662Sdim// with a register and an hardcoded 0/-1 immediate value. 1134251662Sdim//===----------------------------------------------------------------------===// 1135251662Sdim 1136251662Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in 1137251662Sdimclass NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal, 1138251662Sdim bit isNegCond, bit isTaken> 1139251662Sdim : NVInst_V4<(outs), 1140251662Sdim (ins IntRegs:$src1, brtarget:$offset), 1141251662Sdim "if ("#!if(isNegCond, "!","")#mnemonic 1142251662Sdim #"($src1.new, #"#ImmVal#")) jump:" 1143251662Sdim #!if(isTaken, "t","nt")#" $offset", 1144251662Sdim []>, Requires<[HasV4T]> { 1145251662Sdim 1146251662Sdim let isPredicatedFalse = isNegCond; 1147251662Sdim let isBrTaken = !if(isTaken, "true", "false"); 1148251662Sdim 1149251662Sdim bits<3> src1; 1150251662Sdim bits<11> offset; 1151251662Sdim let IClass = 0b0010; 1152251662Sdim let Inst{26} = 0b1; 1153251662Sdim let Inst{25-23} = majOp; 1154251662Sdim let Inst{22} = isNegCond; 1155251662Sdim let Inst{18-16} = src1; 1156251662Sdim let Inst{13} = isTaken; 1157251662Sdim let Inst{21-20} = offset{10-9}; 1158251662Sdim let Inst{7-1} = offset{8-2}; 1159234285Sdim} 1160234285Sdim 1161251662Sdimmulticlass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal, 1162251662Sdim bit isNegCond> { 1163251662Sdim // Branch not taken: 1164251662Sdim def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>; 1165251662Sdim // Branch taken: 1166251662Sdim def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>; 1167234285Sdim} 1168234285Sdim 1169251662Sdimmulticlass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp, 1170251662Sdim string ImmVal> { 1171251662Sdim let BaseOpcode = BaseOp#_NVJ_ConstImm in { 1172251662Sdim defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond 1173251662Sdim defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond 1174251662Sdim } 1175234285Sdim} 1176234285Sdim 1177251662Sdim// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2 1178251662Sdim// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2 1179251662Sdim// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2 1180234285Sdim 1181251662Sdimlet isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1, 1182251662Sdim Defs = [PC], neverHasSideEffects = 1 in { 1183251662Sdim defm TSTBIT0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel; 1184251662Sdim defm CMPEQn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ", 0b100, "-1">, PredRel; 1185251662Sdim defm CMPGTn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT", 0b101, "-1">, PredRel; 1186234285Sdim} 1187234285Sdim 1188234285Sdim//===----------------------------------------------------------------------===// 1189234285Sdim// XTYPE/ALU + 1190234285Sdim//===----------------------------------------------------------------------===// 1191234285Sdim 1192234285Sdim// Add and accumulate. 1193234285Sdim// Rd=add(Rs,add(Ru,#s6)) 1194249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6, 1195249423SdimvalidSubTargets = HasV4SubT in 1196234285Sdimdef ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst), 1197249423Sdim (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3), 1198234285Sdim "$dst = add($src1, add($src2, #$src3))", 1199239462Sdim [(set (i32 IntRegs:$dst), 1200239462Sdim (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2), 1201249423Sdim s6_16ExtPred:$src3)))]>, 1202234285Sdim Requires<[HasV4T]>; 1203234285Sdim 1204234285Sdim// Rd=add(Rs,sub(#s6,Ru)) 1205249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1206249423SdimvalidSubTargets = HasV4SubT in 1207234285Sdimdef ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst), 1208249423Sdim (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3), 1209234285Sdim "$dst = add($src1, sub(#$src2, $src3))", 1210239462Sdim [(set (i32 IntRegs:$dst), 1211249423Sdim (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2, 1212239462Sdim (i32 IntRegs:$src3))))]>, 1213234285Sdim Requires<[HasV4T]>; 1214234285Sdim 1215234285Sdim// Generates the same instruction as ADDr_SUBri_V4 but matches different 1216234285Sdim// pattern. 1217234285Sdim// Rd=add(Rs,sub(#s6,Ru)) 1218249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1219249423SdimvalidSubTargets = HasV4SubT in 1220234285Sdimdef ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst), 1221249423Sdim (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3), 1222234285Sdim "$dst = add($src1, sub(#$src2, $src3))", 1223239462Sdim [(set (i32 IntRegs:$dst), 1224249423Sdim (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2), 1225239462Sdim (i32 IntRegs:$src3)))]>, 1226234285Sdim Requires<[HasV4T]>; 1227234285Sdim 1228234285Sdim 1229234285Sdim// Add or subtract doublewords with carry. 1230234285Sdim//TODO: 1231234285Sdim// Rdd=add(Rss,Rtt,Px):carry 1232234285Sdim//TODO: 1233234285Sdim// Rdd=sub(Rss,Rtt,Px):carry 1234234285Sdim 1235234285Sdim 1236234285Sdim// Logical doublewords. 1237234285Sdim// Rdd=and(Rtt,~Rss) 1238249423Sdimlet validSubTargets = HasV4SubT in 1239234285Sdimdef ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), 1240234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2), 1241234285Sdim "$dst = and($src1, ~$src2)", 1242239462Sdim [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), 1243239462Sdim (not (i64 DoubleRegs:$src2))))]>, 1244234285Sdim Requires<[HasV4T]>; 1245234285Sdim 1246234285Sdim// Rdd=or(Rtt,~Rss) 1247249423Sdimlet validSubTargets = HasV4SubT in 1248234285Sdimdef ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), 1249234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2), 1250234285Sdim "$dst = or($src1, ~$src2)", 1251239462Sdim [(set (i64 DoubleRegs:$dst), 1252239462Sdim (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>, 1253234285Sdim Requires<[HasV4T]>; 1254234285Sdim 1255234285Sdim 1256234285Sdim// Logical-logical doublewords. 1257234285Sdim// Rxx^=xor(Rss,Rtt) 1258249423Sdimlet validSubTargets = HasV4SubT in 1259234285Sdimdef XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst), 1260234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3), 1261234285Sdim "$dst ^= xor($src2, $src3)", 1262239462Sdim [(set (i64 DoubleRegs:$dst), 1263239462Sdim (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2), 1264239462Sdim (i64 DoubleRegs:$src3))))], 1265234285Sdim "$src1 = $dst">, 1266234285Sdim Requires<[HasV4T]>; 1267234285Sdim 1268234285Sdim 1269234285Sdim// Logical-logical words. 1270234285Sdim// Rx=or(Ru,and(Rx,#s10)) 1271249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1272249423SdimvalidSubTargets = HasV4SubT in 1273234285Sdimdef ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst), 1274249423Sdim (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1275234285Sdim "$dst = or($src1, and($src2, #$src3))", 1276239462Sdim [(set (i32 IntRegs:$dst), 1277239462Sdim (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1278249423Sdim s10ExtPred:$src3)))], 1279234285Sdim "$src2 = $dst">, 1280234285Sdim Requires<[HasV4T]>; 1281234285Sdim 1282234285Sdim// Rx[&|^]=and(Rs,Rt) 1283234285Sdim// Rx&=and(Rs,Rt) 1284249423Sdimlet validSubTargets = HasV4SubT in 1285234285Sdimdef ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1286234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1287234285Sdim "$dst &= and($src2, $src3)", 1288239462Sdim [(set (i32 IntRegs:$dst), 1289239462Sdim (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1290239462Sdim (i32 IntRegs:$src3))))], 1291234285Sdim "$src1 = $dst">, 1292234285Sdim Requires<[HasV4T]>; 1293234285Sdim 1294234285Sdim// Rx|=and(Rs,Rt) 1295249423Sdimlet validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in 1296234285Sdimdef ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1297234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1298234285Sdim "$dst |= and($src2, $src3)", 1299239462Sdim [(set (i32 IntRegs:$dst), 1300239462Sdim (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1301239462Sdim (i32 IntRegs:$src3))))], 1302234285Sdim "$src1 = $dst">, 1303249423Sdim Requires<[HasV4T]>, ImmRegRel; 1304234285Sdim 1305234285Sdim// Rx^=and(Rs,Rt) 1306249423Sdimlet validSubTargets = HasV4SubT in 1307234285Sdimdef XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1308234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1309234285Sdim "$dst ^= and($src2, $src3)", 1310239462Sdim [(set (i32 IntRegs:$dst), 1311239462Sdim (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1312239462Sdim (i32 IntRegs:$src3))))], 1313234285Sdim "$src1 = $dst">, 1314234285Sdim Requires<[HasV4T]>; 1315234285Sdim 1316234285Sdim// Rx[&|^]=and(Rs,~Rt) 1317234285Sdim// Rx&=and(Rs,~Rt) 1318249423Sdimlet validSubTargets = HasV4SubT in 1319234285Sdimdef ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1320234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1321234285Sdim "$dst &= and($src2, ~$src3)", 1322239462Sdim [(set (i32 IntRegs:$dst), 1323239462Sdim (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1324239462Sdim (not (i32 IntRegs:$src3)))))], 1325234285Sdim "$src1 = $dst">, 1326234285Sdim Requires<[HasV4T]>; 1327234285Sdim 1328234285Sdim// Rx|=and(Rs,~Rt) 1329249423Sdimlet validSubTargets = HasV4SubT in 1330234285Sdimdef ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1331234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1332234285Sdim "$dst |= and($src2, ~$src3)", 1333239462Sdim [(set (i32 IntRegs:$dst), 1334239462Sdim (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1335239462Sdim (not (i32 IntRegs:$src3)))))], 1336234285Sdim "$src1 = $dst">, 1337234285Sdim Requires<[HasV4T]>; 1338234285Sdim 1339234285Sdim// Rx^=and(Rs,~Rt) 1340249423Sdimlet validSubTargets = HasV4SubT in 1341234285Sdimdef XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1342234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1343234285Sdim "$dst ^= and($src2, ~$src3)", 1344239462Sdim [(set (i32 IntRegs:$dst), 1345239462Sdim (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1346239462Sdim (not (i32 IntRegs:$src3)))))], 1347234285Sdim "$src1 = $dst">, 1348234285Sdim Requires<[HasV4T]>; 1349234285Sdim 1350234285Sdim// Rx[&|^]=or(Rs,Rt) 1351234285Sdim// Rx&=or(Rs,Rt) 1352249423Sdimlet validSubTargets = HasV4SubT in 1353234285Sdimdef ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1354234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1355234285Sdim "$dst &= or($src2, $src3)", 1356239462Sdim [(set (i32 IntRegs:$dst), 1357239462Sdim (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1358239462Sdim (i32 IntRegs:$src3))))], 1359234285Sdim "$src1 = $dst">, 1360234285Sdim Requires<[HasV4T]>; 1361234285Sdim 1362234285Sdim// Rx|=or(Rs,Rt) 1363249423Sdimlet validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in 1364234285Sdimdef ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1365234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1366234285Sdim "$dst |= or($src2, $src3)", 1367239462Sdim [(set (i32 IntRegs:$dst), 1368239462Sdim (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1369239462Sdim (i32 IntRegs:$src3))))], 1370234285Sdim "$src1 = $dst">, 1371249423Sdim Requires<[HasV4T]>, ImmRegRel; 1372234285Sdim 1373234285Sdim// Rx^=or(Rs,Rt) 1374249423Sdimlet validSubTargets = HasV4SubT in 1375234285Sdimdef XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1376234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1377234285Sdim "$dst ^= or($src2, $src3)", 1378239462Sdim [(set (i32 IntRegs:$dst), 1379239462Sdim (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1380239462Sdim (i32 IntRegs:$src3))))], 1381234285Sdim "$src1 = $dst">, 1382234285Sdim Requires<[HasV4T]>; 1383234285Sdim 1384234285Sdim// Rx[&|^]=xor(Rs,Rt) 1385234285Sdim// Rx&=xor(Rs,Rt) 1386249423Sdimlet validSubTargets = HasV4SubT in 1387234285Sdimdef ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1388234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1389234285Sdim "$dst &= xor($src2, $src3)", 1390239462Sdim [(set (i32 IntRegs:$dst), 1391239462Sdim (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1392239462Sdim (i32 IntRegs:$src3))))], 1393234285Sdim "$src1 = $dst">, 1394234285Sdim Requires<[HasV4T]>; 1395234285Sdim 1396234285Sdim// Rx|=xor(Rs,Rt) 1397249423Sdimlet validSubTargets = HasV4SubT in 1398234285Sdimdef ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1399234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1400234285Sdim "$dst |= xor($src2, $src3)", 1401239462Sdim [(set (i32 IntRegs:$dst), 1402239462Sdim (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1403239462Sdim (i32 IntRegs:$src3))))], 1404234285Sdim "$src1 = $dst">, 1405234285Sdim Requires<[HasV4T]>; 1406234285Sdim 1407234285Sdim// Rx^=xor(Rs,Rt) 1408249423Sdimlet validSubTargets = HasV4SubT in 1409234285Sdimdef XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1410234285Sdim (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1411234285Sdim "$dst ^= xor($src2, $src3)", 1412239462Sdim [(set (i32 IntRegs:$dst), 1413239462Sdim (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1414239462Sdim (i32 IntRegs:$src3))))], 1415234285Sdim "$src1 = $dst">, 1416234285Sdim Requires<[HasV4T]>; 1417234285Sdim 1418234285Sdim// Rx|=and(Rs,#s10) 1419249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1420249423SdimvalidSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in 1421234285Sdimdef ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst), 1422249423Sdim (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1423234285Sdim "$dst |= and($src2, #$src3)", 1424239462Sdim [(set (i32 IntRegs:$dst), 1425239462Sdim (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1426249423Sdim s10ExtPred:$src3)))], 1427234285Sdim "$src1 = $dst">, 1428249423Sdim Requires<[HasV4T]>, ImmRegRel; 1429234285Sdim 1430234285Sdim// Rx|=or(Rs,#s10) 1431249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1432249423SdimvalidSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in 1433234285Sdimdef ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst), 1434249423Sdim (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1435234285Sdim "$dst |= or($src2, #$src3)", 1436239462Sdim [(set (i32 IntRegs:$dst), 1437239462Sdim (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1438249423Sdim s10ExtPred:$src3)))], 1439234285Sdim "$src1 = $dst">, 1440249423Sdim Requires<[HasV4T]>, ImmRegRel; 1441234285Sdim 1442234285Sdim 1443234285Sdim// Modulo wrap 1444234285Sdim// Rd=modwrap(Rs,Rt) 1445234285Sdim// Round 1446234285Sdim// Rd=cround(Rs,#u5) 1447234285Sdim// Rd=cround(Rs,Rt) 1448234285Sdim// Rd=round(Rs,#u5)[:sat] 1449234285Sdim// Rd=round(Rs,Rt)[:sat] 1450234285Sdim// Vector reduce add unsigned halfwords 1451234285Sdim// Rd=vraddh(Rss,Rtt) 1452234285Sdim// Vector add bytes 1453234285Sdim// Rdd=vaddb(Rss,Rtt) 1454234285Sdim// Vector conditional negate 1455234285Sdim// Rdd=vcnegh(Rss,Rt) 1456234285Sdim// Rxx+=vrcnegh(Rss,Rt) 1457234285Sdim// Vector maximum bytes 1458234285Sdim// Rdd=vmaxb(Rtt,Rss) 1459234285Sdim// Vector reduce maximum halfwords 1460234285Sdim// Rxx=vrmaxh(Rss,Ru) 1461234285Sdim// Rxx=vrmaxuh(Rss,Ru) 1462234285Sdim// Vector reduce maximum words 1463234285Sdim// Rxx=vrmaxuw(Rss,Ru) 1464234285Sdim// Rxx=vrmaxw(Rss,Ru) 1465234285Sdim// Vector minimum bytes 1466234285Sdim// Rdd=vminb(Rtt,Rss) 1467234285Sdim// Vector reduce minimum halfwords 1468234285Sdim// Rxx=vrminh(Rss,Ru) 1469234285Sdim// Rxx=vrminuh(Rss,Ru) 1470234285Sdim// Vector reduce minimum words 1471234285Sdim// Rxx=vrminuw(Rss,Ru) 1472234285Sdim// Rxx=vrminw(Rss,Ru) 1473234285Sdim// Vector subtract bytes 1474234285Sdim// Rdd=vsubb(Rss,Rtt) 1475234285Sdim 1476234285Sdim//===----------------------------------------------------------------------===// 1477234285Sdim// XTYPE/ALU - 1478234285Sdim//===----------------------------------------------------------------------===// 1479234285Sdim 1480234285Sdim 1481234285Sdim//===----------------------------------------------------------------------===// 1482234285Sdim// XTYPE/MPY + 1483234285Sdim//===----------------------------------------------------------------------===// 1484234285Sdim 1485234285Sdim// Multiply and user lower result. 1486234285Sdim// Rd=add(#u6,mpyi(Rs,#U6)) 1487249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1488249423SdimvalidSubTargets = HasV4SubT in 1489234285Sdimdef ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst), 1490249423Sdim (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3), 1491234285Sdim "$dst = add(#$src1, mpyi($src2, #$src3))", 1492239462Sdim [(set (i32 IntRegs:$dst), 1493239462Sdim (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), 1494249423Sdim u6ExtPred:$src1))]>, 1495234285Sdim Requires<[HasV4T]>; 1496234285Sdim 1497249423Sdim// Rd=add(##,mpyi(Rs,#U6)) 1498249423Sdimdef : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), 1499249423Sdim (HexagonCONST32 tglobaladdr:$src1)), 1500249423Sdim (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2, 1501249423Sdim u6ImmPred:$src3))>; 1502249423Sdim 1503234285Sdim// Rd=add(#u6,mpyi(Rs,Rt)) 1504249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1505249423SdimvalidSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1506234285Sdimdef ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst), 1507249423Sdim (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3), 1508234285Sdim "$dst = add(#$src1, mpyi($src2, $src3))", 1509239462Sdim [(set (i32 IntRegs:$dst), 1510239462Sdim (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1511249423Sdim u6ExtPred:$src1))]>, 1512249423Sdim Requires<[HasV4T]>, ImmRegRel; 1513234285Sdim 1514249423Sdim// Rd=add(##,mpyi(Rs,Rt)) 1515249423Sdimdef : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1516249423Sdim (HexagonCONST32 tglobaladdr:$src1)), 1517249423Sdim (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2, 1518249423Sdim IntRegs:$src3))>; 1519249423Sdim 1520234285Sdim// Rd=add(Ru,mpyi(#u6:2,Rs)) 1521249423Sdimlet validSubTargets = HasV4SubT in 1522234285Sdimdef ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst), 1523234285Sdim (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3), 1524234285Sdim "$dst = add($src1, mpyi(#$src2, $src3))", 1525239462Sdim [(set (i32 IntRegs:$dst), 1526239462Sdim (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), 1527239462Sdim u6_2ImmPred:$src2)))]>, 1528234285Sdim Requires<[HasV4T]>; 1529234285Sdim 1530234285Sdim// Rd=add(Ru,mpyi(Rs,#u6)) 1531249423Sdimlet isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6, 1532249423SdimvalidSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1533234285Sdimdef ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst), 1534249423Sdim (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3), 1535234285Sdim "$dst = add($src1, mpyi($src2, #$src3))", 1536239462Sdim [(set (i32 IntRegs:$dst), 1537239462Sdim (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1538249423Sdim u6ExtPred:$src3)))]>, 1539249423Sdim Requires<[HasV4T]>, ImmRegRel; 1540234285Sdim 1541234285Sdim// Rx=add(Ru,mpyi(Rx,Rs)) 1542249423Sdimlet validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in 1543234285Sdimdef ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst), 1544234285Sdim (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1545234285Sdim "$dst = add($src1, mpyi($src2, $src3))", 1546239462Sdim [(set (i32 IntRegs:$dst), 1547239462Sdim (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1548239462Sdim (i32 IntRegs:$src3))))], 1549234285Sdim "$src2 = $dst">, 1550249423Sdim Requires<[HasV4T]>, ImmRegRel; 1551234285Sdim 1552234285Sdim 1553234285Sdim// Polynomial multiply words 1554234285Sdim// Rdd=pmpyw(Rs,Rt) 1555234285Sdim// Rxx^=pmpyw(Rs,Rt) 1556234285Sdim 1557234285Sdim// Vector reduce multiply word by signed half (32x16) 1558234285Sdim// Rdd=vrmpyweh(Rss,Rtt)[:<<1] 1559234285Sdim// Rdd=vrmpywoh(Rss,Rtt)[:<<1] 1560234285Sdim// Rxx+=vrmpyweh(Rss,Rtt)[:<<1] 1561234285Sdim// Rxx+=vrmpywoh(Rss,Rtt)[:<<1] 1562234285Sdim 1563234285Sdim// Multiply and use upper result 1564234285Sdim// Rd=mpy(Rs,Rt.H):<<1:sat 1565234285Sdim// Rd=mpy(Rs,Rt.L):<<1:sat 1566234285Sdim// Rd=mpy(Rs,Rt):<<1 1567234285Sdim// Rd=mpy(Rs,Rt):<<1:sat 1568234285Sdim// Rd=mpysu(Rs,Rt) 1569234285Sdim// Rx+=mpy(Rs,Rt):<<1:sat 1570234285Sdim// Rx-=mpy(Rs,Rt):<<1:sat 1571234285Sdim 1572234285Sdim// Vector multiply bytes 1573234285Sdim// Rdd=vmpybsu(Rs,Rt) 1574234285Sdim// Rdd=vmpybu(Rs,Rt) 1575234285Sdim// Rxx+=vmpybsu(Rs,Rt) 1576234285Sdim// Rxx+=vmpybu(Rs,Rt) 1577234285Sdim 1578234285Sdim// Vector polynomial multiply halfwords 1579234285Sdim// Rdd=vpmpyh(Rs,Rt) 1580234285Sdim// Rxx^=vpmpyh(Rs,Rt) 1581234285Sdim 1582234285Sdim//===----------------------------------------------------------------------===// 1583234285Sdim// XTYPE/MPY - 1584234285Sdim//===----------------------------------------------------------------------===// 1585234285Sdim 1586234285Sdim 1587234285Sdim//===----------------------------------------------------------------------===// 1588234285Sdim// XTYPE/SHIFT + 1589234285Sdim//===----------------------------------------------------------------------===// 1590234285Sdim 1591234285Sdim// Shift by immediate and accumulate. 1592234285Sdim// Rx=add(#u8,asl(Rx,#U5)) 1593249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1594249423SdimvalidSubTargets = HasV4SubT in 1595234285Sdimdef ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1596249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1597234285Sdim "$dst = add(#$src1, asl($src2, #$src3))", 1598239462Sdim [(set (i32 IntRegs:$dst), 1599239462Sdim (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1600249423Sdim u8ExtPred:$src1))], 1601234285Sdim "$src2 = $dst">, 1602234285Sdim Requires<[HasV4T]>; 1603234285Sdim 1604234285Sdim// Rx=add(#u8,lsr(Rx,#U5)) 1605249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1606249423SdimvalidSubTargets = HasV4SubT in 1607234285Sdimdef ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1608249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1609234285Sdim "$dst = add(#$src1, lsr($src2, #$src3))", 1610239462Sdim [(set (i32 IntRegs:$dst), 1611239462Sdim (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1612249423Sdim u8ExtPred:$src1))], 1613234285Sdim "$src2 = $dst">, 1614234285Sdim Requires<[HasV4T]>; 1615234285Sdim 1616234285Sdim// Rx=sub(#u8,asl(Rx,#U5)) 1617249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1618249423SdimvalidSubTargets = HasV4SubT in 1619234285Sdimdef SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1620249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1621234285Sdim "$dst = sub(#$src1, asl($src2, #$src3))", 1622239462Sdim [(set (i32 IntRegs:$dst), 1623239462Sdim (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1624249423Sdim u8ExtPred:$src1))], 1625234285Sdim "$src2 = $dst">, 1626234285Sdim Requires<[HasV4T]>; 1627234285Sdim 1628234285Sdim// Rx=sub(#u8,lsr(Rx,#U5)) 1629249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1630249423SdimvalidSubTargets = HasV4SubT in 1631234285Sdimdef SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1632249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1633234285Sdim "$dst = sub(#$src1, lsr($src2, #$src3))", 1634239462Sdim [(set (i32 IntRegs:$dst), 1635239462Sdim (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1636249423Sdim u8ExtPred:$src1))], 1637234285Sdim "$src2 = $dst">, 1638234285Sdim Requires<[HasV4T]>; 1639234285Sdim 1640234285Sdim 1641234285Sdim//Shift by immediate and logical. 1642234285Sdim//Rx=and(#u8,asl(Rx,#U5)) 1643249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1644249423SdimvalidSubTargets = HasV4SubT in 1645234285Sdimdef ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1646249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1647234285Sdim "$dst = and(#$src1, asl($src2, #$src3))", 1648239462Sdim [(set (i32 IntRegs:$dst), 1649239462Sdim (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1650249423Sdim u8ExtPred:$src1))], 1651234285Sdim "$src2 = $dst">, 1652234285Sdim Requires<[HasV4T]>; 1653234285Sdim 1654234285Sdim//Rx=and(#u8,lsr(Rx,#U5)) 1655249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1656249423SdimvalidSubTargets = HasV4SubT in 1657234285Sdimdef ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1658249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1659234285Sdim "$dst = and(#$src1, lsr($src2, #$src3))", 1660239462Sdim [(set (i32 IntRegs:$dst), 1661239462Sdim (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1662249423Sdim u8ExtPred:$src1))], 1663234285Sdim "$src2 = $dst">, 1664234285Sdim Requires<[HasV4T]>; 1665234285Sdim 1666234285Sdim//Rx=or(#u8,asl(Rx,#U5)) 1667249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1668249423SdimAddedComplexity = 30, validSubTargets = HasV4SubT in 1669234285Sdimdef ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1670249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1671234285Sdim "$dst = or(#$src1, asl($src2, #$src3))", 1672239462Sdim [(set (i32 IntRegs:$dst), 1673239462Sdim (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1674249423Sdim u8ExtPred:$src1))], 1675234285Sdim "$src2 = $dst">, 1676234285Sdim Requires<[HasV4T]>; 1677234285Sdim 1678234285Sdim//Rx=or(#u8,lsr(Rx,#U5)) 1679249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1680249423SdimAddedComplexity = 30, validSubTargets = HasV4SubT in 1681234285Sdimdef ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1682249423Sdim (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1683234285Sdim "$dst = or(#$src1, lsr($src2, #$src3))", 1684239462Sdim [(set (i32 IntRegs:$dst), 1685239462Sdim (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1686249423Sdim u8ExtPred:$src1))], 1687234285Sdim "$src2 = $dst">, 1688234285Sdim Requires<[HasV4T]>; 1689234285Sdim 1690234285Sdim 1691234285Sdim//Shift by register. 1692234285Sdim//Rd=lsl(#s6,Rt) 1693249423Sdimlet validSubTargets = HasV4SubT in { 1694234285Sdimdef LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2), 1695234285Sdim "$dst = lsl(#$src1, $src2)", 1696239462Sdim [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1, 1697239462Sdim (i32 IntRegs:$src2)))]>, 1698234285Sdim Requires<[HasV4T]>; 1699234285Sdim 1700234285Sdim 1701234285Sdim//Shift by register and logical. 1702234285Sdim//Rxx^=asl(Rss,Rt) 1703234285Sdimdef ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1704234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1705234285Sdim "$dst ^= asl($src2, $src3)", 1706239462Sdim [(set (i64 DoubleRegs:$dst), 1707239462Sdim (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2), 1708239462Sdim (i32 IntRegs:$src3))))], 1709234285Sdim "$src1 = $dst">, 1710234285Sdim Requires<[HasV4T]>; 1711234285Sdim 1712234285Sdim//Rxx^=asr(Rss,Rt) 1713234285Sdimdef ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1714234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1715234285Sdim "$dst ^= asr($src2, $src3)", 1716239462Sdim [(set (i64 DoubleRegs:$dst), 1717239462Sdim (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2), 1718239462Sdim (i32 IntRegs:$src3))))], 1719234285Sdim "$src1 = $dst">, 1720234285Sdim Requires<[HasV4T]>; 1721234285Sdim 1722234285Sdim//Rxx^=lsl(Rss,Rt) 1723234285Sdimdef LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1724234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1725234285Sdim "$dst ^= lsl($src2, $src3)", 1726239462Sdim [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), 1727239462Sdim (shl (i64 DoubleRegs:$src2), 1728239462Sdim (i32 IntRegs:$src3))))], 1729234285Sdim "$src1 = $dst">, 1730234285Sdim Requires<[HasV4T]>; 1731234285Sdim 1732234285Sdim//Rxx^=lsr(Rss,Rt) 1733234285Sdimdef LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1734234285Sdim (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1735234285Sdim "$dst ^= lsr($src2, $src3)", 1736239462Sdim [(set (i64 DoubleRegs:$dst), 1737239462Sdim (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2), 1738239462Sdim (i32 IntRegs:$src3))))], 1739234285Sdim "$src1 = $dst">, 1740234285Sdim Requires<[HasV4T]>; 1741249423Sdim} 1742234285Sdim 1743234285Sdim//===----------------------------------------------------------------------===// 1744234285Sdim// XTYPE/SHIFT - 1745234285Sdim//===----------------------------------------------------------------------===// 1746234285Sdim 1747234285Sdim//===----------------------------------------------------------------------===// 1748234285Sdim// MEMOP: Word, Half, Byte 1749234285Sdim//===----------------------------------------------------------------------===// 1750234285Sdim 1751249423Sdimdef MEMOPIMM : SDNodeXForm<imm, [{ 1752249423Sdim // Call the transformation function XformM5ToU5Imm to get the negative 1753249423Sdim // immediate's positive counterpart. 1754249423Sdim int32_t imm = N->getSExtValue(); 1755249423Sdim return XformM5ToU5Imm(imm); 1756249423Sdim}]>; 1757234285Sdim 1758249423Sdimdef MEMOPIMM_HALF : SDNodeXForm<imm, [{ 1759249423Sdim // -1 .. -31 represented as 65535..65515 1760249423Sdim // assigning to a short restores our desired signed value. 1761249423Sdim // Call the transformation function XformM5ToU5Imm to get the negative 1762249423Sdim // immediate's positive counterpart. 1763249423Sdim int16_t imm = N->getSExtValue(); 1764249423Sdim return XformM5ToU5Imm(imm); 1765249423Sdim}]>; 1766234285Sdim 1767249423Sdimdef MEMOPIMM_BYTE : SDNodeXForm<imm, [{ 1768249423Sdim // -1 .. -31 represented as 255..235 1769249423Sdim // assigning to a char restores our desired signed value. 1770249423Sdim // Call the transformation function XformM5ToU5Imm to get the negative 1771249423Sdim // immediate's positive counterpart. 1772249423Sdim int8_t imm = N->getSExtValue(); 1773249423Sdim return XformM5ToU5Imm(imm); 1774249423Sdim}]>; 1775234285Sdim 1776249423Sdimdef SETMEMIMM : SDNodeXForm<imm, [{ 1777249423Sdim // Return the bit position we will set [0-31]. 1778249423Sdim // As an SDNode. 1779249423Sdim int32_t imm = N->getSExtValue(); 1780249423Sdim return XformMskToBitPosU5Imm(imm); 1781249423Sdim}]>; 1782234285Sdim 1783249423Sdimdef CLRMEMIMM : SDNodeXForm<imm, [{ 1784249423Sdim // Return the bit position we will clear [0-31]. 1785249423Sdim // As an SDNode. 1786249423Sdim // we bit negate the value first 1787249423Sdim int32_t imm = ~(N->getSExtValue()); 1788249423Sdim return XformMskToBitPosU5Imm(imm); 1789249423Sdim}]>; 1790234285Sdim 1791249423Sdimdef SETMEMIMM_SHORT : SDNodeXForm<imm, [{ 1792249423Sdim // Return the bit position we will set [0-15]. 1793249423Sdim // As an SDNode. 1794249423Sdim int16_t imm = N->getSExtValue(); 1795249423Sdim return XformMskToBitPosU4Imm(imm); 1796249423Sdim}]>; 1797234285Sdim 1798249423Sdimdef CLRMEMIMM_SHORT : SDNodeXForm<imm, [{ 1799249423Sdim // Return the bit position we will clear [0-15]. 1800249423Sdim // As an SDNode. 1801249423Sdim // we bit negate the value first 1802249423Sdim int16_t imm = ~(N->getSExtValue()); 1803249423Sdim return XformMskToBitPosU4Imm(imm); 1804249423Sdim}]>; 1805234285Sdim 1806249423Sdimdef SETMEMIMM_BYTE : SDNodeXForm<imm, [{ 1807249423Sdim // Return the bit position we will set [0-7]. 1808249423Sdim // As an SDNode. 1809249423Sdim int8_t imm = N->getSExtValue(); 1810249423Sdim return XformMskToBitPosU3Imm(imm); 1811249423Sdim}]>; 1812234285Sdim 1813249423Sdimdef CLRMEMIMM_BYTE : SDNodeXForm<imm, [{ 1814249423Sdim // Return the bit position we will clear [0-7]. 1815249423Sdim // As an SDNode. 1816249423Sdim // we bit negate the value first 1817249423Sdim int8_t imm = ~(N->getSExtValue()); 1818249423Sdim return XformMskToBitPosU3Imm(imm); 1819249423Sdim}]>; 1820234285Sdim 1821249423Sdim//===----------------------------------------------------------------------===// 1822249423Sdim// Template class for MemOp instructions with the register value. 1823249423Sdim//===----------------------------------------------------------------------===// 1824249423Sdimclass MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp, 1825249423Sdim string memOp, bits<2> memOpBits> : 1826249423Sdim MEMInst_V4<(outs), 1827249423Sdim (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta), 1828249423Sdim opc#"($base+#$offset)"#memOp#"$delta", 1829249423Sdim []>, 1830249423Sdim Requires<[HasV4T, UseMEMOP]> { 1831234285Sdim 1832249423Sdim bits<5> base; 1833249423Sdim bits<5> delta; 1834249423Sdim bits<32> offset; 1835249423Sdim bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 1836234285Sdim 1837249423Sdim let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 1838249423Sdim !if (!eq(opcBits, 0b01), offset{6-1}, 1839249423Sdim !if (!eq(opcBits, 0b10), offset{7-2},0))); 1840234285Sdim 1841249423Sdim let IClass = 0b0011; 1842249423Sdim let Inst{27-24} = 0b1110; 1843249423Sdim let Inst{22-21} = opcBits; 1844249423Sdim let Inst{20-16} = base; 1845249423Sdim let Inst{13} = 0b0; 1846249423Sdim let Inst{12-7} = offsetBits; 1847249423Sdim let Inst{6-5} = memOpBits; 1848249423Sdim let Inst{4-0} = delta; 1849249423Sdim} 1850234285Sdim 1851234285Sdim//===----------------------------------------------------------------------===// 1852249423Sdim// Template class for MemOp instructions with the immediate value. 1853234285Sdim//===----------------------------------------------------------------------===// 1854249423Sdimclass MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp, 1855249423Sdim string memOp, bits<2> memOpBits> : 1856249423Sdim MEMInst_V4 <(outs), 1857249423Sdim (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta), 1858249423Sdim opc#"($base+#$offset)"#memOp#"#$delta" 1859249423Sdim #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')' 1860249423Sdim []>, 1861249423Sdim Requires<[HasV4T, UseMEMOP]> { 1862234285Sdim 1863249423Sdim bits<5> base; 1864249423Sdim bits<5> delta; 1865249423Sdim bits<32> offset; 1866249423Sdim bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 1867234285Sdim 1868249423Sdim let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 1869249423Sdim !if (!eq(opcBits, 0b01), offset{6-1}, 1870249423Sdim !if (!eq(opcBits, 0b10), offset{7-2},0))); 1871234285Sdim 1872249423Sdim let IClass = 0b0011; 1873249423Sdim let Inst{27-24} = 0b1111; 1874249423Sdim let Inst{22-21} = opcBits; 1875249423Sdim let Inst{20-16} = base; 1876249423Sdim let Inst{13} = 0b0; 1877249423Sdim let Inst{12-7} = offsetBits; 1878249423Sdim let Inst{6-5} = memOpBits; 1879249423Sdim let Inst{4-0} = delta; 1880249423Sdim} 1881234285Sdim 1882249423Sdim// multiclass to define MemOp instructions with register operand. 1883249423Sdimmulticlass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> { 1884249423Sdim def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add 1885249423Sdim def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub 1886249423Sdim def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and 1887249423Sdim def _OR#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or 1888249423Sdim} 1889234285Sdim 1890249423Sdim// multiclass to define MemOp instructions with immediate Operand. 1891249423Sdimmulticlass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> { 1892249423Sdim def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >; 1893249423Sdim def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >; 1894249423Sdim def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>; 1895249423Sdim def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>; 1896249423Sdim} 1897234285Sdim 1898249423Sdimmulticlass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> { 1899249423Sdim defm r : MemOp_rr <opc, opcBits, ImmOp>; 1900249423Sdim defm i : MemOp_ri <opc, opcBits, ImmOp>; 1901249423Sdim} 1902234285Sdim 1903249423Sdim// Define MemOp instructions. 1904249423Sdimlet isExtendable = 1, opExtendable = 1, isExtentSigned = 0, 1905249423SdimvalidSubTargets =HasV4SubT in { 1906249423Sdim let opExtentBits = 6, accessSize = ByteAccess in 1907249423Sdim defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>; 1908234285Sdim 1909249423Sdim let opExtentBits = 7, accessSize = HalfWordAccess in 1910249423Sdim defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>; 1911234285Sdim 1912249423Sdim let opExtentBits = 8, accessSize = WordAccess in 1913249423Sdim defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>; 1914249423Sdim} 1915234285Sdim 1916249423Sdim//===----------------------------------------------------------------------===// 1917249423Sdim// Multiclass to define 'Def Pats' for ALU operations on the memory 1918249423Sdim// Here value used for the ALU operation is an immediate value. 1919249423Sdim// mem[bh](Rs+#0) += #U5 1920249423Sdim// mem[bh](Rs+#u6) += #U5 1921249423Sdim//===----------------------------------------------------------------------===// 1922234285Sdim 1923249423Sdimmulticlass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 1924249423Sdim InstHexagon MI, SDNode OpNode> { 1925249423Sdim let AddedComplexity = 180 in 1926249423Sdim def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend), 1927249423Sdim IntRegs:$addr), 1928249423Sdim (MI IntRegs:$addr, #0, u5ImmPred:$addend )>; 1929234285Sdim 1930249423Sdim let AddedComplexity = 190 in 1931249423Sdim def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)), 1932249423Sdim u5ImmPred:$addend), 1933249423Sdim (add IntRegs:$base, ExtPred:$offset)), 1934249423Sdim (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>; 1935249423Sdim} 1936234285Sdim 1937249423Sdimmulticlass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 1938249423Sdim InstHexagon addMI, InstHexagon subMI> { 1939249423Sdim defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>; 1940249423Sdim defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>; 1941249423Sdim} 1942234285Sdim 1943249423Sdimmulticlass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 1944249423Sdim // Half Word 1945249423Sdim defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred, 1946249423Sdim MemOPh_ADDi_V4, MemOPh_SUBi_V4>; 1947249423Sdim // Byte 1948249423Sdim defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred, 1949249423Sdim MemOPb_ADDi_V4, MemOPb_SUBi_V4>; 1950249423Sdim} 1951234285Sdim 1952249423Sdimlet Predicates = [HasV4T, UseMEMOP] in { 1953249423Sdim defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend 1954249423Sdim defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend 1955249423Sdim defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend 1956234285Sdim 1957249423Sdim // Word 1958249423Sdim defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4, 1959249423Sdim MemOPw_SUBi_V4>; 1960249423Sdim} 1961234285Sdim 1962234285Sdim//===----------------------------------------------------------------------===// 1963249423Sdim// multiclass to define 'Def Pats' for ALU operations on the memory. 1964249423Sdim// Here value used for the ALU operation is a negative value. 1965249423Sdim// mem[bh](Rs+#0) += #m5 1966249423Sdim// mem[bh](Rs+#u6) += #m5 1967234285Sdim//===----------------------------------------------------------------------===// 1968234285Sdim 1969249423Sdimmulticlass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred, 1970249423Sdim PatLeaf immPred, ComplexPattern addrPred, 1971249423Sdim SDNodeXForm xformFunc, InstHexagon MI> { 1972249423Sdim let AddedComplexity = 190 in 1973249423Sdim def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend), 1974249423Sdim IntRegs:$addr), 1975249423Sdim (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>; 1976234285Sdim 1977249423Sdim let AddedComplexity = 195 in 1978249423Sdim def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)), 1979249423Sdim immPred:$subend), 1980249423Sdim (add IntRegs:$base, extPred:$offset)), 1981249423Sdim (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>; 1982249423Sdim} 1983234285Sdim 1984249423Sdimmulticlass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 1985249423Sdim // Half Word 1986249423Sdim defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred, 1987249423Sdim ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>; 1988249423Sdim // Byte 1989249423Sdim defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred, 1990249423Sdim ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>; 1991249423Sdim} 1992234285Sdim 1993249423Sdimlet Predicates = [HasV4T, UseMEMOP] in { 1994249423Sdim defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend 1995249423Sdim defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend 1996249423Sdim defm : MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend 1997234285Sdim 1998249423Sdim // Word 1999249423Sdim defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred, 2000249423Sdim ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>; 2001249423Sdim} 2002234285Sdim 2003249423Sdim//===----------------------------------------------------------------------===// 2004249423Sdim// Multiclass to define 'def Pats' for bit operations on the memory. 2005249423Sdim// mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2006249423Sdim// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5) 2007249423Sdim//===----------------------------------------------------------------------===// 2008234285Sdim 2009249423Sdimmulticlass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred, 2010249423Sdim PatLeaf extPred, ComplexPattern addrPred, 2011249423Sdim SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> { 2012234285Sdim 2013249423Sdim // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5) 2014249423Sdim let AddedComplexity = 250 in 2015249423Sdim def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2016249423Sdim immPred:$bitend), 2017249423Sdim (add IntRegs:$base, extPred:$offset)), 2018249423Sdim (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>; 2019234285Sdim 2020249423Sdim // mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2021249423Sdim let AddedComplexity = 225 in 2022249423Sdim def : Pat <(stOp (OpNode (ldOp addrPred:$addr), immPred:$bitend), 2023249423Sdim addrPred:$addr), 2024249423Sdim (MI IntRegs:$addr, #0, (xformFunc immPred:$bitend))>; 2025249423Sdim} 2026234285Sdim 2027249423Sdimmulticlass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2028249423Sdim // Byte - clrbit 2029249423Sdim defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred, 2030249423Sdim ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>; 2031249423Sdim // Byte - setbit 2032249423Sdim defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred, 2033249423Sdim ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>; 2034249423Sdim // Half Word - clrbit 2035249423Sdim defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred, 2036249423Sdim ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>; 2037249423Sdim // Half Word - setbit 2038249423Sdim defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred, 2039249423Sdim ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>; 2040249423Sdim} 2041234285Sdim 2042249423Sdimlet Predicates = [HasV4T, UseMEMOP] in { 2043249423Sdim // mem[bh](Rs+#0) = [clrbit|setbit](#U5) 2044249423Sdim // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5) 2045249423Sdim defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend 2046249423Sdim defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend 2047249423Sdim defm : MemOpi_bitExtType<extloadi8, extloadi16>; // any extend 2048234285Sdim 2049249423Sdim // memw(Rs+#0) = [clrbit|setbit](#U5) 2050249423Sdim // memw(Rs+#u6:2) = [clrbit|setbit](#U5) 2051249423Sdim defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2, 2052249423Sdim CLRMEMIMM, MemOPw_CLRBITi_V4, and>; 2053249423Sdim defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2, 2054249423Sdim SETMEMIMM, MemOPw_SETBITi_V4, or>; 2055249423Sdim} 2056234285Sdim 2057249423Sdim//===----------------------------------------------------------------------===// 2058249423Sdim// Multiclass to define 'def Pats' for ALU operations on the memory 2059249423Sdim// where addend is a register. 2060249423Sdim// mem[bhw](Rs+#0) [+-&|]= Rt 2061249423Sdim// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2062249423Sdim//===----------------------------------------------------------------------===// 2063234285Sdim 2064249423Sdimmulticlass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred, 2065249423Sdim PatLeaf extPred, InstHexagon MI, SDNode OpNode> { 2066249423Sdim let AddedComplexity = 141 in 2067249423Sdim // mem[bhw](Rs+#0) [+-&|]= Rt 2068249423Sdim def : Pat <(stOp (OpNode (ldOp addrPred:$addr), (i32 IntRegs:$addend)), 2069249423Sdim addrPred:$addr), 2070249423Sdim (MI IntRegs:$addr, #0, (i32 IntRegs:$addend) )>; 2071234285Sdim 2072249423Sdim // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2073249423Sdim let AddedComplexity = 150 in 2074249423Sdim def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2075249423Sdim (i32 IntRegs:$orend)), 2076249423Sdim (add IntRegs:$base, extPred:$offset)), 2077249423Sdim (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>; 2078249423Sdim} 2079234285Sdim 2080249423Sdimmulticlass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp, 2081249423Sdim ComplexPattern addrPred, PatLeaf extPred, 2082249423Sdim InstHexagon addMI, InstHexagon subMI, 2083249423Sdim InstHexagon andMI, InstHexagon orMI > { 2084234285Sdim 2085249423Sdim defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>; 2086249423Sdim defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>; 2087249423Sdim defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>; 2088249423Sdim defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI, or>; 2089249423Sdim} 2090249423Sdim 2091249423Sdimmulticlass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2092249423Sdim // Half Word 2093249423Sdim defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred, 2094249423Sdim MemOPh_ADDr_V4, MemOPh_SUBr_V4, 2095249423Sdim MemOPh_ANDr_V4, MemOPh_ORr_V4>; 2096249423Sdim // Byte 2097249423Sdim defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred, 2098249423Sdim MemOPb_ADDr_V4, MemOPb_SUBr_V4, 2099249423Sdim MemOPb_ANDr_V4, MemOPb_ORr_V4>; 2100249423Sdim} 2101249423Sdim 2102249423Sdim// Define 'def Pats' for MemOps with register addend. 2103249423Sdimlet Predicates = [HasV4T, UseMEMOP] in { 2104249423Sdim // Byte, Half Word 2105249423Sdim defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend 2106249423Sdim defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend 2107249423Sdim defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend 2108249423Sdim // Word 2109249423Sdim defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4, 2110249423Sdim MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >; 2111249423Sdim} 2112249423Sdim 2113234285Sdim//===----------------------------------------------------------------------===// 2114234285Sdim// XTYPE/PRED + 2115234285Sdim//===----------------------------------------------------------------------===// 2116234285Sdim 2117234285Sdim// Hexagon V4 only supports these flavors of byte/half compare instructions: 2118234285Sdim// EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by 2119234285Sdim// hardware. However, compiler can still implement these patterns through 2120234285Sdim// appropriate patterns combinations based on current implemented patterns. 2121234285Sdim// The implemented patterns are: EQ/GT/GTU. 2122234285Sdim// Missing patterns are: GE/GEU/LT/LTU/LE/LEU. 2123234285Sdim 2124239462Sdim// Following instruction is not being extended as it results into the 2125239462Sdim// incorrect code for negative numbers. 2126234285Sdim// Pd=cmpb.eq(Rs,#u8) 2127239462Sdim 2128249423Sdim// p=!cmp.eq(r1,r2) 2129249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2130249423Sdimdef CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst), 2131249423Sdim (ins IntRegs:$src1, IntRegs:$src2), 2132249423Sdim "$dst = !cmp.eq($src1, $src2)", 2133249423Sdim [(set (i1 PredRegs:$dst), 2134249423Sdim (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>, 2135249423Sdim Requires<[HasV4T]>; 2136249423Sdim 2137249423Sdim// p=!cmp.eq(r1,#s10) 2138249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2139249423Sdimdef CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst), 2140249423Sdim (ins IntRegs:$src1, s10Ext:$src2), 2141249423Sdim "$dst = !cmp.eq($src1, #$src2)", 2142249423Sdim [(set (i1 PredRegs:$dst), 2143249423Sdim (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>, 2144249423Sdim Requires<[HasV4T]>; 2145249423Sdim 2146249423Sdim// p=!cmp.gt(r1,r2) 2147249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2148249423Sdimdef CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst), 2149249423Sdim (ins IntRegs:$src1, IntRegs:$src2), 2150249423Sdim "$dst = !cmp.gt($src1, $src2)", 2151249423Sdim [(set (i1 PredRegs:$dst), 2152249423Sdim (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2153249423Sdim Requires<[HasV4T]>; 2154249423Sdim 2155249423Sdim// p=!cmp.gt(r1,#s10) 2156249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2157249423Sdimdef CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst), 2158249423Sdim (ins IntRegs:$src1, s10Ext:$src2), 2159249423Sdim "$dst = !cmp.gt($src1, #$src2)", 2160249423Sdim [(set (i1 PredRegs:$dst), 2161249423Sdim (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>, 2162249423Sdim Requires<[HasV4T]>; 2163249423Sdim 2164249423Sdim// p=!cmp.gtu(r1,r2) 2165249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2166249423Sdimdef CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst), 2167249423Sdim (ins IntRegs:$src1, IntRegs:$src2), 2168249423Sdim "$dst = !cmp.gtu($src1, $src2)", 2169249423Sdim [(set (i1 PredRegs:$dst), 2170249423Sdim (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2171249423Sdim Requires<[HasV4T]>; 2172249423Sdim 2173249423Sdim// p=!cmp.gtu(r1,#u9) 2174249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2175249423Sdimdef CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst), 2176249423Sdim (ins IntRegs:$src1, u9Ext:$src2), 2177249423Sdim "$dst = !cmp.gtu($src1, #$src2)", 2178249423Sdim [(set (i1 PredRegs:$dst), 2179249423Sdim (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>, 2180249423Sdim Requires<[HasV4T]>; 2181249423Sdim 2182249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2183234285Sdimdef CMPbEQri_V4 : MInst<(outs PredRegs:$dst), 2184234285Sdim (ins IntRegs:$src1, u8Imm:$src2), 2185234285Sdim "$dst = cmpb.eq($src1, #$src2)", 2186239462Sdim [(set (i1 PredRegs:$dst), 2187239462Sdim (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>, 2188234285Sdim Requires<[HasV4T]>; 2189234285Sdim 2190249423Sdimdef : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)), 2191249423Sdim bb:$offset), 2192251662Sdim (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2), 2193249423Sdim bb:$offset)>, 2194249423Sdim Requires<[HasV4T]>; 2195249423Sdim 2196234285Sdim// Pd=cmpb.eq(Rs,Rt) 2197249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2198234285Sdimdef CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst), 2199234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2200234285Sdim "$dst = cmpb.eq($src1, $src2)", 2201239462Sdim [(set (i1 PredRegs:$dst), 2202239462Sdim (seteq (and (xor (i32 IntRegs:$src1), 2203239462Sdim (i32 IntRegs:$src2)), 255), 0))]>, 2204234285Sdim Requires<[HasV4T]>; 2205234285Sdim 2206234285Sdim// Pd=cmpb.eq(Rs,Rt) 2207249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2208234285Sdimdef CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst), 2209234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2210234285Sdim "$dst = cmpb.eq($src1, $src2)", 2211239462Sdim [(set (i1 PredRegs:$dst), 2212239462Sdim (seteq (shl (i32 IntRegs:$src1), (i32 24)), 2213239462Sdim (shl (i32 IntRegs:$src2), (i32 24))))]>, 2214234285Sdim Requires<[HasV4T]>; 2215234285Sdim 2216234285Sdim// Pd=cmpb.gt(Rs,Rt) 2217249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2218234285Sdimdef CMPbGTrr_V4 : MInst<(outs PredRegs:$dst), 2219234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2220234285Sdim "$dst = cmpb.gt($src1, $src2)", 2221239462Sdim [(set (i1 PredRegs:$dst), 2222239462Sdim (setgt (shl (i32 IntRegs:$src1), (i32 24)), 2223239462Sdim (shl (i32 IntRegs:$src2), (i32 24))))]>, 2224234285Sdim Requires<[HasV4T]>; 2225234285Sdim 2226234285Sdim// Pd=cmpb.gtu(Rs,#u7) 2227249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2228249423SdimisCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in 2229234285Sdimdef CMPbGTUri_V4 : MInst<(outs PredRegs:$dst), 2230249423Sdim (ins IntRegs:$src1, u7Ext:$src2), 2231234285Sdim "$dst = cmpb.gtu($src1, #$src2)", 2232239462Sdim [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 2233249423Sdim u7ExtPred:$src2))]>, 2234249423Sdim Requires<[HasV4T]>, ImmRegRel; 2235234285Sdim 2236249423Sdim// SDNode for converting immediate C to C-1. 2237249423Sdimdef DEC_CONST_BYTE : SDNodeXForm<imm, [{ 2238249423Sdim // Return the byte immediate const-1 as an SDNode. 2239249423Sdim int32_t imm = N->getSExtValue(); 2240249423Sdim return XformU7ToU7M1Imm(imm); 2241249423Sdim}]>; 2242249423Sdim 2243249423Sdim// For the sequence 2244249423Sdim// zext( seteq ( and(Rs, 255), u8)) 2245249423Sdim// Generate 2246249423Sdim// Pd=cmpb.eq(Rs, #u8) 2247249423Sdim// if (Pd.new) Rd=#1 2248249423Sdim// if (!Pd.new) Rd=#0 2249249423Sdimdef : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)), 2250249423Sdim u8ExtPred:$u8)))), 2251249423Sdim (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2252249423Sdim (u8ExtPred:$u8))), 2253249423Sdim 1, 0))>, 2254249423Sdim Requires<[HasV4T]>; 2255249423Sdim 2256249423Sdim// For the sequence 2257249423Sdim// zext( setne ( and(Rs, 255), u8)) 2258249423Sdim// Generate 2259249423Sdim// Pd=cmpb.eq(Rs, #u8) 2260249423Sdim// if (Pd.new) Rd=#0 2261249423Sdim// if (!Pd.new) Rd=#1 2262249423Sdimdef : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)), 2263249423Sdim u8ExtPred:$u8)))), 2264249423Sdim (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2265249423Sdim (u8ExtPred:$u8))), 2266249423Sdim 0, 1))>, 2267249423Sdim Requires<[HasV4T]>; 2268249423Sdim 2269249423Sdim// For the sequence 2270249423Sdim// zext( seteq (Rs, and(Rt, 255))) 2271249423Sdim// Generate 2272249423Sdim// Pd=cmpb.eq(Rs, Rt) 2273249423Sdim// if (Pd.new) Rd=#1 2274249423Sdim// if (!Pd.new) Rd=#0 2275249423Sdimdef : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt), 2276249423Sdim (i32 (and (i32 IntRegs:$Rs), 255)))))), 2277249423Sdim (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2278249423Sdim (i32 IntRegs:$Rt))), 2279249423Sdim 1, 0))>, 2280249423Sdim Requires<[HasV4T]>; 2281249423Sdim 2282249423Sdim// For the sequence 2283249423Sdim// zext( setne (Rs, and(Rt, 255))) 2284249423Sdim// Generate 2285249423Sdim// Pd=cmpb.eq(Rs, Rt) 2286249423Sdim// if (Pd.new) Rd=#0 2287249423Sdim// if (!Pd.new) Rd=#1 2288249423Sdimdef : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt), 2289249423Sdim (i32 (and (i32 IntRegs:$Rs), 255)))))), 2290249423Sdim (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2291249423Sdim (i32 IntRegs:$Rt))), 2292249423Sdim 0, 1))>, 2293249423Sdim Requires<[HasV4T]>; 2294249423Sdim 2295249423Sdim// For the sequence 2296249423Sdim// zext( setugt ( and(Rs, 255), u8)) 2297249423Sdim// Generate 2298249423Sdim// Pd=cmpb.gtu(Rs, #u8) 2299249423Sdim// if (Pd.new) Rd=#1 2300249423Sdim// if (!Pd.new) Rd=#0 2301249423Sdimdef : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)), 2302249423Sdim u8ExtPred:$u8)))), 2303249423Sdim (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2304249423Sdim (u8ExtPred:$u8))), 2305249423Sdim 1, 0))>, 2306249423Sdim Requires<[HasV4T]>; 2307249423Sdim 2308249423Sdim// For the sequence 2309249423Sdim// zext( setugt ( and(Rs, 254), u8)) 2310249423Sdim// Generate 2311249423Sdim// Pd=cmpb.gtu(Rs, #u8) 2312249423Sdim// if (Pd.new) Rd=#1 2313249423Sdim// if (!Pd.new) Rd=#0 2314249423Sdimdef : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)), 2315249423Sdim u8ExtPred:$u8)))), 2316249423Sdim (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2317249423Sdim (u8ExtPred:$u8))), 2318249423Sdim 1, 0))>, 2319249423Sdim Requires<[HasV4T]>; 2320249423Sdim 2321249423Sdim// For the sequence 2322249423Sdim// zext( setult ( Rs, Rt)) 2323249423Sdim// Generate 2324249423Sdim// Pd=cmp.ltu(Rs, Rt) 2325249423Sdim// if (Pd.new) Rd=#1 2326249423Sdim// if (!Pd.new) Rd=#0 2327249423Sdim// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2328249423Sdimdef : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2329249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt), 2330249423Sdim (i32 IntRegs:$Rs))), 2331249423Sdim 1, 0))>, 2332249423Sdim Requires<[HasV4T]>; 2333249423Sdim 2334249423Sdim// For the sequence 2335249423Sdim// zext( setlt ( Rs, Rt)) 2336249423Sdim// Generate 2337249423Sdim// Pd=cmp.lt(Rs, Rt) 2338249423Sdim// if (Pd.new) Rd=#1 2339249423Sdim// if (!Pd.new) Rd=#0 2340249423Sdim// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2341249423Sdimdef : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2342249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt), 2343249423Sdim (i32 IntRegs:$Rs))), 2344249423Sdim 1, 0))>, 2345249423Sdim Requires<[HasV4T]>; 2346249423Sdim 2347249423Sdim// For the sequence 2348249423Sdim// zext( setugt ( Rs, Rt)) 2349249423Sdim// Generate 2350249423Sdim// Pd=cmp.gtu(Rs, Rt) 2351249423Sdim// if (Pd.new) Rd=#1 2352249423Sdim// if (!Pd.new) Rd=#0 2353249423Sdimdef : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2354249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs), 2355249423Sdim (i32 IntRegs:$Rt))), 2356249423Sdim 1, 0))>, 2357249423Sdim Requires<[HasV4T]>; 2358249423Sdim 2359249423Sdim// This pattern interefers with coremark performance, not implementing at this 2360249423Sdim// time. 2361249423Sdim// For the sequence 2362249423Sdim// zext( setgt ( Rs, Rt)) 2363249423Sdim// Generate 2364249423Sdim// Pd=cmp.gt(Rs, Rt) 2365249423Sdim// if (Pd.new) Rd=#1 2366249423Sdim// if (!Pd.new) Rd=#0 2367249423Sdim 2368249423Sdim// For the sequence 2369249423Sdim// zext( setuge ( Rs, Rt)) 2370249423Sdim// Generate 2371249423Sdim// Pd=cmp.ltu(Rs, Rt) 2372249423Sdim// if (Pd.new) Rd=#0 2373249423Sdim// if (!Pd.new) Rd=#1 2374249423Sdim// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2375249423Sdimdef : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2376249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt), 2377249423Sdim (i32 IntRegs:$Rs))), 2378249423Sdim 0, 1))>, 2379249423Sdim Requires<[HasV4T]>; 2380249423Sdim 2381249423Sdim// For the sequence 2382249423Sdim// zext( setge ( Rs, Rt)) 2383249423Sdim// Generate 2384249423Sdim// Pd=cmp.lt(Rs, Rt) 2385249423Sdim// if (Pd.new) Rd=#0 2386249423Sdim// if (!Pd.new) Rd=#1 2387249423Sdim// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2388249423Sdimdef : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2389249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt), 2390249423Sdim (i32 IntRegs:$Rs))), 2391249423Sdim 0, 1))>, 2392249423Sdim Requires<[HasV4T]>; 2393249423Sdim 2394249423Sdim// For the sequence 2395249423Sdim// zext( setule ( Rs, Rt)) 2396249423Sdim// Generate 2397249423Sdim// Pd=cmp.gtu(Rs, Rt) 2398249423Sdim// if (Pd.new) Rd=#0 2399249423Sdim// if (!Pd.new) Rd=#1 2400249423Sdimdef : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2401249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs), 2402249423Sdim (i32 IntRegs:$Rt))), 2403249423Sdim 0, 1))>, 2404249423Sdim Requires<[HasV4T]>; 2405249423Sdim 2406249423Sdim// For the sequence 2407249423Sdim// zext( setle ( Rs, Rt)) 2408249423Sdim// Generate 2409249423Sdim// Pd=cmp.gt(Rs, Rt) 2410249423Sdim// if (Pd.new) Rd=#0 2411249423Sdim// if (!Pd.new) Rd=#1 2412249423Sdimdef : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2413249423Sdim (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs), 2414249423Sdim (i32 IntRegs:$Rt))), 2415249423Sdim 0, 1))>, 2416249423Sdim Requires<[HasV4T]>; 2417249423Sdim 2418249423Sdim// For the sequence 2419249423Sdim// zext( setult ( and(Rs, 255), u8)) 2420249423Sdim// Use the isdigit transformation below 2421249423Sdim 2422249423Sdim// Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)' 2423249423Sdim// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;. 2424249423Sdim// The isdigit transformation relies on two 'clever' aspects: 2425249423Sdim// 1) The data type is unsigned which allows us to eliminate a zero test after 2426249423Sdim// biasing the expression by 48. We are depending on the representation of 2427249423Sdim// the unsigned types, and semantics. 2428249423Sdim// 2) The front end has converted <= 9 into < 10 on entry to LLVM 2429249423Sdim// 2430249423Sdim// For the C code: 2431249423Sdim// retval = ((c>='0') & (c<='9')) ? 1 : 0; 2432249423Sdim// The code is transformed upstream of llvm into 2433249423Sdim// retval = (c-48) < 10 ? 1 : 0; 2434249423Sdimlet AddedComplexity = 139 in 2435249423Sdimdef : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)), 2436249423Sdim u7StrictPosImmPred:$src2)))), 2437249423Sdim (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1), 2438249423Sdim (DEC_CONST_BYTE u7StrictPosImmPred:$src2))), 2439249423Sdim 0, 1))>, 2440249423Sdim Requires<[HasV4T]>; 2441249423Sdim 2442234285Sdim// Pd=cmpb.gtu(Rs,Rt) 2443249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", 2444249423SdimInputType = "reg" in 2445234285Sdimdef CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst), 2446234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2447234285Sdim "$dst = cmpb.gtu($src1, $src2)", 2448239462Sdim [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 2449239462Sdim (and (i32 IntRegs:$src2), 255)))]>, 2450249423Sdim Requires<[HasV4T]>, ImmRegRel; 2451234285Sdim 2452239462Sdim// Following instruction is not being extended as it results into the incorrect 2453239462Sdim// code for negative numbers. 2454239462Sdim 2455234285Sdim// Signed half compare(.eq) ri. 2456234285Sdim// Pd=cmph.eq(Rs,#s8) 2457249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2458234285Sdimdef CMPhEQri_V4 : MInst<(outs PredRegs:$dst), 2459239462Sdim (ins IntRegs:$src1, s8Imm:$src2), 2460234285Sdim "$dst = cmph.eq($src1, #$src2)", 2461239462Sdim [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535), 2462239462Sdim s8ImmPred:$src2))]>, 2463234285Sdim Requires<[HasV4T]>; 2464234285Sdim 2465234285Sdim// Signed half compare(.eq) rr. 2466234285Sdim// Case 1: xor + and, then compare: 2467234285Sdim// r0=xor(r0,r1) 2468234285Sdim// r0=and(r0,#0xffff) 2469234285Sdim// p0=cmp.eq(r0,#0) 2470234285Sdim// Pd=cmph.eq(Rs,Rt) 2471249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2472234285Sdimdef CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst), 2473234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2474234285Sdim "$dst = cmph.eq($src1, $src2)", 2475239462Sdim [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1), 2476239462Sdim (i32 IntRegs:$src2)), 2477239462Sdim 65535), 0))]>, 2478234285Sdim Requires<[HasV4T]>; 2479234285Sdim 2480234285Sdim// Signed half compare(.eq) rr. 2481234285Sdim// Case 2: shift left 16 bits then compare: 2482234285Sdim// r0=asl(r0,16) 2483234285Sdim// r1=asl(r1,16) 2484234285Sdim// p0=cmp.eq(r0,r1) 2485234285Sdim// Pd=cmph.eq(Rs,Rt) 2486249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2487234285Sdimdef CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst), 2488234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2489234285Sdim "$dst = cmph.eq($src1, $src2)", 2490239462Sdim [(set (i1 PredRegs:$dst), 2491239462Sdim (seteq (shl (i32 IntRegs:$src1), (i32 16)), 2492239462Sdim (shl (i32 IntRegs:$src2), (i32 16))))]>, 2493234285Sdim Requires<[HasV4T]>; 2494234285Sdim 2495239462Sdim/* Incorrect Pattern -- immediate should be right shifted before being 2496239462Sdimused in the cmph.gt instruction. 2497234285Sdim// Signed half compare(.gt) ri. 2498234285Sdim// Pd=cmph.gt(Rs,#s8) 2499239462Sdim 2500249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 2501249423SdimisCompare = 1, validSubTargets = HasV4SubT in 2502234285Sdimdef CMPhGTri_V4 : MInst<(outs PredRegs:$dst), 2503249423Sdim (ins IntRegs:$src1, s8Ext:$src2), 2504234285Sdim "$dst = cmph.gt($src1, #$src2)", 2505239462Sdim [(set (i1 PredRegs:$dst), 2506239462Sdim (setgt (shl (i32 IntRegs:$src1), (i32 16)), 2507249423Sdim s8ExtPred:$src2))]>, 2508234285Sdim Requires<[HasV4T]>; 2509239462Sdim*/ 2510234285Sdim 2511234285Sdim// Signed half compare(.gt) rr. 2512234285Sdim// Pd=cmph.gt(Rs,Rt) 2513249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT in 2514234285Sdimdef CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst), 2515234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2516234285Sdim "$dst = cmph.gt($src1, $src2)", 2517239462Sdim [(set (i1 PredRegs:$dst), 2518239462Sdim (setgt (shl (i32 IntRegs:$src1), (i32 16)), 2519239462Sdim (shl (i32 IntRegs:$src2), (i32 16))))]>, 2520234285Sdim Requires<[HasV4T]>; 2521234285Sdim 2522234285Sdim// Unsigned half compare rr (.gtu). 2523234285Sdim// Pd=cmph.gtu(Rs,Rt) 2524249423Sdimlet isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2525249423SdimInputType = "reg" in 2526234285Sdimdef CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst), 2527234285Sdim (ins IntRegs:$src1, IntRegs:$src2), 2528234285Sdim "$dst = cmph.gtu($src1, $src2)", 2529239462Sdim [(set (i1 PredRegs:$dst), 2530239462Sdim (setugt (and (i32 IntRegs:$src1), 65535), 2531239462Sdim (and (i32 IntRegs:$src2), 65535)))]>, 2532249423Sdim Requires<[HasV4T]>, ImmRegRel; 2533234285Sdim 2534234285Sdim// Unsigned half compare ri (.gtu). 2535234285Sdim// Pd=cmph.gtu(Rs,#u7) 2536249423Sdimlet isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2537249423SdimisCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2538249423SdimInputType = "imm" in 2539234285Sdimdef CMPhGTUri_V4 : MInst<(outs PredRegs:$dst), 2540249423Sdim (ins IntRegs:$src1, u7Ext:$src2), 2541234285Sdim "$dst = cmph.gtu($src1, #$src2)", 2542239462Sdim [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535), 2543249423Sdim u7ExtPred:$src2))]>, 2544249423Sdim Requires<[HasV4T]>, ImmRegRel; 2545234285Sdim 2546249423Sdimlet validSubTargets = HasV4SubT in 2547249423Sdimdef NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 2548249423Sdim "$dst = !tstbit($src1, $src2)", 2549249423Sdim [(set (i1 PredRegs:$dst), 2550249423Sdim (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>, 2551249423Sdim Requires<[HasV4T]>; 2552249423Sdim 2553249423Sdimlet validSubTargets = HasV4SubT in 2554249423Sdimdef NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 2555249423Sdim "$dst = !tstbit($src1, $src2)", 2556249423Sdim [(set (i1 PredRegs:$dst), 2557249423Sdim (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>, 2558249423Sdim Requires<[HasV4T]>; 2559249423Sdim 2560234285Sdim//===----------------------------------------------------------------------===// 2561234285Sdim// XTYPE/PRED - 2562234285Sdim//===----------------------------------------------------------------------===// 2563234285Sdim 2564234285Sdim//Deallocate frame and return. 2565234285Sdim// dealloc_return 2566234285Sdimlet isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, 2567263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in { 2568263508Sdimlet validSubTargets = HasV4SubT in 2569263508Sdim def DEALLOC_RET_V4 : LD0Inst<(outs), (ins), 2570234285Sdim "dealloc_return", 2571234285Sdim []>, 2572234285Sdim Requires<[HasV4T]>; 2573234285Sdim} 2574234285Sdim 2575239462Sdim// Restore registers and dealloc return function call. 2576239462Sdimlet isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, 2577239462Sdim Defs = [R29, R30, R31, PC] in { 2578263508Sdimlet validSubTargets = HasV4SubT in 2579239462Sdim def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs), 2580239462Sdim (ins calltarget:$dst), 2581263508Sdim "jump $dst", 2582239462Sdim []>, 2583239462Sdim Requires<[HasV4T]>; 2584239462Sdim} 2585239462Sdim 2586239462Sdim// Restore registers and dealloc frame before a tail call. 2587239462Sdimlet isCall = 1, isBarrier = 1, 2588239462Sdim Defs = [R29, R30, R31, PC] in { 2589263508Sdimlet validSubTargets = HasV4SubT in 2590239462Sdim def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs), 2591239462Sdim (ins calltarget:$dst), 2592263508Sdim "call $dst", 2593239462Sdim []>, 2594239462Sdim Requires<[HasV4T]>; 2595239462Sdim} 2596239462Sdim 2597239462Sdim// Save registers function call. 2598239462Sdimlet isCall = 1, isBarrier = 1, 2599239462Sdim Uses = [R29, R31] in { 2600239462Sdim def SAVE_REGISTERS_CALL_V4 : JInst<(outs), 2601239462Sdim (ins calltarget:$dst), 2602239462Sdim "call $dst // Save_calle_saved_registers", 2603239462Sdim []>, 2604239462Sdim Requires<[HasV4T]>; 2605239462Sdim} 2606239462Sdim 2607234285Sdim// if (Ps) dealloc_return 2608234285Sdimlet isReturn = 1, isTerminator = 1, 2609263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2610239462Sdim isPredicated = 1 in { 2611263508Sdimlet validSubTargets = HasV4SubT in 2612263508Sdim def DEALLOC_RET_cPt_V4 : LD0Inst<(outs), 2613263508Sdim (ins PredRegs:$src1), 2614234285Sdim "if ($src1) dealloc_return", 2615234285Sdim []>, 2616234285Sdim Requires<[HasV4T]>; 2617234285Sdim} 2618234285Sdim 2619234285Sdim// if (!Ps) dealloc_return 2620234285Sdimlet isReturn = 1, isTerminator = 1, 2621263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2622263508Sdim isPredicated = 1, isPredicatedFalse = 1 in { 2623263508Sdimlet validSubTargets = HasV4SubT in 2624263508Sdim def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2625234285Sdim "if (!$src1) dealloc_return", 2626234285Sdim []>, 2627234285Sdim Requires<[HasV4T]>; 2628234285Sdim} 2629234285Sdim 2630234285Sdim// if (Ps.new) dealloc_return:nt 2631234285Sdimlet isReturn = 1, isTerminator = 1, 2632263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2633239462Sdim isPredicated = 1 in { 2634263508Sdimlet validSubTargets = HasV4SubT in 2635263508Sdim def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2636234285Sdim "if ($src1.new) dealloc_return:nt", 2637234285Sdim []>, 2638234285Sdim Requires<[HasV4T]>; 2639234285Sdim} 2640234285Sdim 2641234285Sdim// if (!Ps.new) dealloc_return:nt 2642234285Sdimlet isReturn = 1, isTerminator = 1, 2643263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2644263508Sdim isPredicated = 1, isPredicatedFalse = 1 in { 2645263508Sdimlet validSubTargets = HasV4SubT in 2646263508Sdim def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2647234285Sdim "if (!$src1.new) dealloc_return:nt", 2648234285Sdim []>, 2649234285Sdim Requires<[HasV4T]>; 2650234285Sdim} 2651234285Sdim 2652234285Sdim// if (Ps.new) dealloc_return:t 2653234285Sdimlet isReturn = 1, isTerminator = 1, 2654263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2655239462Sdim isPredicated = 1 in { 2656263508Sdimlet validSubTargets = HasV4SubT in 2657263508Sdim def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2658234285Sdim "if ($src1.new) dealloc_return:t", 2659234285Sdim []>, 2660234285Sdim Requires<[HasV4T]>; 2661234285Sdim} 2662234285Sdim 2663263508Sdim// if (!Ps.new) dealloc_return:nt 2664234285Sdimlet isReturn = 1, isTerminator = 1, 2665263508Sdim Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2666263508Sdim isPredicated = 1, isPredicatedFalse = 1 in { 2667263508Sdimlet validSubTargets = HasV4SubT in 2668263508Sdim def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2669234285Sdim "if (!$src1.new) dealloc_return:t", 2670234285Sdim []>, 2671234285Sdim Requires<[HasV4T]>; 2672234285Sdim} 2673239462Sdim 2674239462Sdim// Load/Store with absolute addressing mode 2675239462Sdim// memw(#u6)=Rt 2676239462Sdim 2677249423Sdimmulticlass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot, 2678249423Sdim bit isPredNew> { 2679251662Sdim let isPredicatedNew = isPredNew in 2680249423Sdim def NAME#_V4 : STInst2<(outs), 2681251662Sdim (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2), 2682249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2683249423Sdim ") ")#mnemonic#"(##$absaddr) = $src2", 2684239462Sdim []>, 2685239462Sdim Requires<[HasV4T]>; 2686249423Sdim} 2687239462Sdim 2688249423Sdimmulticlass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 2689251662Sdim let isPredicatedFalse = PredNot in { 2690249423Sdim defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>; 2691249423Sdim // Predicate new 2692249423Sdim defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>; 2693249423Sdim } 2694249423Sdim} 2695239462Sdim 2696249423Sdimlet isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in 2697249423Sdimmulticlass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> { 2698249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2699249423Sdim let opExtendable = 0, isPredicable = 1 in 2700249423Sdim def NAME#_V4 : STInst2<(outs), 2701251662Sdim (ins u0AlwaysExt:$absaddr, RC:$src), 2702249423Sdim mnemonic#"(##$absaddr) = $src", 2703239462Sdim []>, 2704239462Sdim Requires<[HasV4T]>; 2705239462Sdim 2706249423Sdim let opExtendable = 1, isPredicated = 1 in { 2707249423Sdim defm Pt : ST_Abs_Pred<mnemonic, RC, 0>; 2708249423Sdim defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>; 2709249423Sdim } 2710249423Sdim } 2711249423Sdim} 2712239462Sdim 2713249423Sdimmulticlass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot, 2714249423Sdim bit isPredNew> { 2715251662Sdim let isPredicatedNew = isPredNew in 2716249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 2717251662Sdim (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2), 2718249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2719249423Sdim ") ")#mnemonic#"(##$absaddr) = $src2.new", 2720239462Sdim []>, 2721239462Sdim Requires<[HasV4T]>; 2722249423Sdim} 2723239462Sdim 2724249423Sdimmulticlass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 2725251662Sdim let isPredicatedFalse = PredNot in { 2726249423Sdim defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>; 2727249423Sdim // Predicate new 2728249423Sdim defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>; 2729249423Sdim } 2730249423Sdim} 2731239462Sdim 2732249423Sdimlet mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in 2733249423Sdimmulticlass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> { 2734249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2735249423Sdim let opExtendable = 0, isPredicable = 1 in 2736249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 2737251662Sdim (ins u0AlwaysExt:$absaddr, RC:$src), 2738249423Sdim mnemonic#"(##$absaddr) = $src.new", 2739239462Sdim []>, 2740239462Sdim Requires<[HasV4T]>; 2741239462Sdim 2742249423Sdim let opExtendable = 1, isPredicated = 1 in { 2743249423Sdim defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>; 2744249423Sdim defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>; 2745249423Sdim } 2746249423Sdim } 2747239462Sdim} 2748239462Sdim 2749249423Sdimlet addrMode = Absolute in { 2750251662Sdim let accessSize = ByteAccess in 2751249423Sdim defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>, 2752249423Sdim ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel; 2753239462Sdim 2754251662Sdim let accessSize = HalfWordAccess in 2755249423Sdim defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>, 2756249423Sdim ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel; 2757239462Sdim 2758251662Sdim let accessSize = WordAccess in 2759249423Sdim defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>, 2760249423Sdim ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel; 2761239462Sdim 2762251662Sdim let accessSize = DoubleWordAccess, isNVStorable = 0 in 2763249423Sdim defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel; 2764249423Sdim} 2765239462Sdim 2766249423Sdimlet Predicates = [HasV4T], AddedComplexity = 30 in { 2767239462Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), 2768239462Sdim (HexagonCONST32 tglobaladdr:$absaddr)), 2769239462Sdim (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2770239462Sdim 2771239462Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), 2772239462Sdim (HexagonCONST32 tglobaladdr:$absaddr)), 2773239462Sdim (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2774239462Sdim 2775239462Sdimdef : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), 2776239462Sdim (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2777239462Sdim 2778249423Sdimdef : Pat<(store (i64 DoubleRegs:$src1), 2779249423Sdim (HexagonCONST32 tglobaladdr:$absaddr)), 2780249423Sdim (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>; 2781249423Sdim} 2782239462Sdim 2783249423Sdim//===----------------------------------------------------------------------===// 2784249423Sdim// multiclass for store instructions with GP-relative addressing mode. 2785249423Sdim// mem[bhwd](#global)=Rt 2786249423Sdim// if ([!]Pv[.new]) mem[bhwd](##global) = Rt 2787249423Sdim//===----------------------------------------------------------------------===// 2788251662Sdimlet mayStore = 1, isNVStorable = 1 in 2789249423Sdimmulticlass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> { 2790249423Sdim let BaseOpcode = BaseOp, isPredicable = 1 in 2791249423Sdim def NAME#_V4 : STInst2<(outs), 2792249423Sdim (ins globaladdress:$global, RC:$src), 2793249423Sdim mnemonic#"(#$global) = $src", 2794249423Sdim []>; 2795239462Sdim 2796249423Sdim // When GP-relative instructions are predicated, their addressing mode is 2797249423Sdim // changed to absolute and they are always constant extended. 2798249423Sdim let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1, 2799249423Sdim isPredicated = 1 in { 2800249423Sdim defm Pt : ST_Abs_Pred <mnemonic, RC, 0>; 2801249423Sdim defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>; 2802249423Sdim } 2803249423Sdim} 2804239462Sdim 2805249423Sdimlet mayStore = 1, isNVStore = 1 in 2806249423Sdimmulticlass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> { 2807249423Sdim let BaseOpcode = BaseOp, isPredicable = 1 in 2808249423Sdim def NAME#_nv_V4 : NVInst_V4<(outs), 2809249423Sdim (ins u0AlwaysExt:$global, RC:$src), 2810249423Sdim mnemonic#"(#$global) = $src.new", 2811249423Sdim []>, 2812249423Sdim Requires<[HasV4T]>; 2813239462Sdim 2814249423Sdim // When GP-relative instructions are predicated, their addressing mode is 2815249423Sdim // changed to absolute and they are always constant extended. 2816249423Sdim let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1, 2817249423Sdim isPredicated = 1 in { 2818249423Sdim defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>; 2819249423Sdim defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>; 2820249423Sdim } 2821249423Sdim} 2822239462Sdim 2823251662Sdimlet validSubTargets = HasV4SubT, neverHasSideEffects = 1 in { 2824251662Sdim let isNVStorable = 0 in 2825251662Sdim defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel; 2826251662Sdim 2827251662Sdim defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>, 2828251662Sdim ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel; 2829251662Sdim defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>, 2830251662Sdim ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel; 2831251662Sdim defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>, 2832251662Sdim ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel; 2833239462Sdim} 2834239462Sdim 2835249423Sdim// 64 bit atomic store 2836249423Sdimdef : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global), 2837249423Sdim (i64 DoubleRegs:$src1)), 2838249423Sdim (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>, 2839249423Sdim Requires<[HasV4T]>; 2840239462Sdim 2841249423Sdim// Map from store(globaladdress) -> memd(#foo) 2842249423Sdimlet AddedComplexity = 100 in 2843249423Sdimdef : Pat <(store (i64 DoubleRegs:$src1), 2844249423Sdim (HexagonCONST32_GP tglobaladdr:$global)), 2845249423Sdim (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>; 2846239462Sdim 2847249423Sdim// 8 bit atomic store 2848249423Sdimdef : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global), 2849249423Sdim (i32 IntRegs:$src1)), 2850249423Sdim (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2851239462Sdim 2852249423Sdim// Map from store(globaladdress) -> memb(#foo) 2853249423Sdimlet AddedComplexity = 100 in 2854249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), 2855249423Sdim (HexagonCONST32_GP tglobaladdr:$global)), 2856249423Sdim (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2857239462Sdim 2858249423Sdim// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1" 2859249423Sdim// to "r0 = 1; memw(#foo) = r0" 2860249423Sdimlet AddedComplexity = 100 in 2861249423Sdimdef : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), 2862249423Sdim (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>; 2863239462Sdim 2864249423Sdimdef : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global), 2865249423Sdim (i32 IntRegs:$src1)), 2866249423Sdim (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2867239462Sdim 2868249423Sdim// Map from store(globaladdress) -> memh(#foo) 2869249423Sdimlet AddedComplexity = 100 in 2870249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), 2871249423Sdim (HexagonCONST32_GP tglobaladdr:$global)), 2872249423Sdim (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2873239462Sdim 2874249423Sdim// 32 bit atomic store 2875249423Sdimdef : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global), 2876249423Sdim (i32 IntRegs:$src1)), 2877249423Sdim (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2878249423Sdim 2879249423Sdim// Map from store(globaladdress) -> memw(#foo) 2880249423Sdimlet AddedComplexity = 100 in 2881249423Sdimdef : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)), 2882249423Sdim (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2883249423Sdim 2884249423Sdim//===----------------------------------------------------------------------===// 2885249423Sdim// Multiclass for the load instructions with absolute addressing mode. 2886249423Sdim//===----------------------------------------------------------------------===// 2887249423Sdimmulticlass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot, 2888249423Sdim bit isPredNew> { 2889251662Sdim let isPredicatedNew = isPredNew in 2890249423Sdim def NAME : LDInst2<(outs RC:$dst), 2891251662Sdim (ins PredRegs:$src1, u0AlwaysExt:$absaddr), 2892249423Sdim !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2893249423Sdim ") ")#"$dst = "#mnemonic#"(##$absaddr)", 2894249423Sdim []>, 2895249423Sdim Requires<[HasV4T]>; 2896249423Sdim} 2897249423Sdim 2898249423Sdimmulticlass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 2899251662Sdim let isPredicatedFalse = PredNot in { 2900249423Sdim defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>; 2901249423Sdim // Predicate new 2902249423Sdim defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>; 2903249423Sdim } 2904249423Sdim} 2905249423Sdim 2906249423Sdimlet isExtended = 1, neverHasSideEffects = 1 in 2907249423Sdimmulticlass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> { 2908249423Sdim let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2909249423Sdim let opExtendable = 1, isPredicable = 1 in 2910249423Sdim def NAME#_V4 : LDInst2<(outs RC:$dst), 2911251662Sdim (ins u0AlwaysExt:$absaddr), 2912249423Sdim "$dst = "#mnemonic#"(##$absaddr)", 2913249423Sdim []>, 2914249423Sdim Requires<[HasV4T]>; 2915249423Sdim 2916249423Sdim let opExtendable = 2, isPredicated = 1 in { 2917249423Sdim defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>; 2918249423Sdim defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>; 2919249423Sdim } 2920249423Sdim } 2921249423Sdim} 2922249423Sdim 2923249423Sdimlet addrMode = Absolute in { 2924251662Sdim let accessSize = ByteAccess in { 2925249423Sdim defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel; 2926249423Sdim defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel; 2927251662Sdim } 2928251662Sdim let accessSize = HalfWordAccess in { 2929249423Sdim defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel; 2930249423Sdim defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel; 2931251662Sdim } 2932251662Sdim let accessSize = WordAccess in 2933249423Sdim defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel; 2934251662Sdim 2935251662Sdim let accessSize = DoubleWordAccess in 2936249423Sdim defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel; 2937249423Sdim} 2938249423Sdim 2939251662Sdimlet Predicates = [HasV4T], AddedComplexity = 30 in { 2940239462Sdimdef : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))), 2941239462Sdim (LDriw_abs_V4 tglobaladdr: $absaddr)>; 2942239462Sdim 2943239462Sdimdef : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2944239462Sdim (LDrib_abs_V4 tglobaladdr:$absaddr)>; 2945239462Sdim 2946239462Sdimdef : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2947239462Sdim (LDriub_abs_V4 tglobaladdr:$absaddr)>; 2948239462Sdim 2949239462Sdimdef : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 2950239462Sdim (LDrih_abs_V4 tglobaladdr:$absaddr)>; 2951239462Sdim 2952239462Sdimdef : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 2953239462Sdim (LDriuh_abs_V4 tglobaladdr:$absaddr)>; 2954251662Sdim} 2955239462Sdim 2956249423Sdim//===----------------------------------------------------------------------===// 2957249423Sdim// multiclass for load instructions with GP-relative addressing mode. 2958249423Sdim// Rx=mem[bhwd](##global) 2959249423Sdim// if ([!]Pv[.new]) Rx=mem[bhwd](##global) 2960249423Sdim//===----------------------------------------------------------------------===// 2961249423Sdimlet neverHasSideEffects = 1, validSubTargets = HasV4SubT in 2962249423Sdimmulticlass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> { 2963249423Sdim let BaseOpcode = BaseOp in { 2964249423Sdim let isPredicable = 1 in 2965249423Sdim def NAME#_V4 : LDInst2<(outs RC:$dst), 2966249423Sdim (ins globaladdress:$global), 2967249423Sdim "$dst = "#mnemonic#"(#$global)", 2968249423Sdim []>; 2969249423Sdim 2970249423Sdim let isExtended = 1, opExtendable = 2, isPredicated = 1 in { 2971249423Sdim defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>; 2972249423Sdim defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>; 2973249423Sdim } 2974249423Sdim } 2975249423Sdim} 2976249423Sdim 2977251662Sdimdefm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel; 2978251662Sdimdefm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel; 2979251662Sdimdefm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel; 2980251662Sdimdefm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel; 2981251662Sdimdefm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel; 2982251662Sdimdefm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel; 2983249423Sdim 2984249423Sdimdef : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)), 2985249423Sdim (i64 (LDd_GP_V4 tglobaladdr:$global))>; 2986249423Sdim 2987249423Sdimdef : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)), 2988249423Sdim (i32 (LDw_GP_V4 tglobaladdr:$global))>; 2989249423Sdim 2990249423Sdimdef : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)), 2991249423Sdim (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 2992249423Sdim 2993249423Sdimdef : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)), 2994249423Sdim (i32 (LDub_GP_V4 tglobaladdr:$global))>; 2995249423Sdim 2996249423Sdim// Map from load(globaladdress) -> memw(#foo + 0) 2997249423Sdimlet AddedComplexity = 100 in 2998249423Sdimdef : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))), 2999249423Sdim (i64 (LDd_GP_V4 tglobaladdr:$global))>; 3000249423Sdim 3001249423Sdim// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd 3002249423Sdimlet AddedComplexity = 100 in 3003249423Sdimdef : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))), 3004249423Sdim (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>; 3005249423Sdim 3006249423Sdim// When the Interprocedural Global Variable optimizer realizes that a certain 3007249423Sdim// global variable takes only two constant values, it shrinks the global to 3008249423Sdim// a boolean. Catch those loads here in the following 3 patterns. 3009249423Sdimlet AddedComplexity = 100 in 3010249423Sdimdef : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3011249423Sdim (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3012249423Sdim 3013249423Sdimlet AddedComplexity = 100 in 3014249423Sdimdef : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3015249423Sdim (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3016249423Sdim 3017249423Sdim// Map from load(globaladdress) -> memb(#foo) 3018249423Sdimlet AddedComplexity = 100 in 3019249423Sdimdef : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3020249423Sdim (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3021249423Sdim 3022249423Sdim// Map from load(globaladdress) -> memb(#foo) 3023249423Sdimlet AddedComplexity = 100 in 3024249423Sdimdef : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3025249423Sdim (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3026249423Sdim 3027249423Sdimlet AddedComplexity = 100 in 3028249423Sdimdef : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3029249423Sdim (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3030249423Sdim 3031249423Sdim// Map from load(globaladdress) -> memub(#foo) 3032249423Sdimlet AddedComplexity = 100 in 3033249423Sdimdef : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3034249423Sdim (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3035249423Sdim 3036249423Sdim// Map from load(globaladdress) -> memh(#foo) 3037249423Sdimlet AddedComplexity = 100 in 3038249423Sdimdef : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3039249423Sdim (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3040249423Sdim 3041249423Sdim// Map from load(globaladdress) -> memh(#foo) 3042249423Sdimlet AddedComplexity = 100 in 3043249423Sdimdef : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3044249423Sdim (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3045249423Sdim 3046249423Sdim// Map from load(globaladdress) -> memuh(#foo) 3047249423Sdimlet AddedComplexity = 100 in 3048249423Sdimdef : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3049249423Sdim (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 3050249423Sdim 3051249423Sdim// Map from load(globaladdress) -> memw(#foo) 3052249423Sdimlet AddedComplexity = 100 in 3053249423Sdimdef : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), 3054249423Sdim (i32 (LDw_GP_V4 tglobaladdr:$global))>; 3055249423Sdim 3056249423Sdim 3057239462Sdim// Transfer global address into a register 3058251662Sdimlet isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1, 3059251662SdimisAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in 3060251662Sdimdef TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), 3061251662Sdim "$dst = #$src1", 3062239462Sdim [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>, 3063239462Sdim Requires<[HasV4T]>; 3064239462Sdim 3065249423Sdim// Transfer a block address into a register 3066249423Sdimdef : Pat<(HexagonCONST32_GP tblockaddress:$src1), 3067249423Sdim (TFRI_V4 tblockaddress:$src1)>, 3068249423Sdim Requires<[HasV4T]>; 3069249423Sdim 3070263508Sdimlet isExtended = 1, opExtendable = 2, AddedComplexity=50, 3071263508SdimneverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3072239462Sdimdef TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3073263508Sdim (ins PredRegs:$src1, s16Ext:$src2), 3074263508Sdim "if($src1) $dst = #$src2", 3075239462Sdim []>, 3076239462Sdim Requires<[HasV4T]>; 3077239462Sdim 3078263508Sdimlet isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3079263508SdimneverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3080239462Sdimdef TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3081263508Sdim (ins PredRegs:$src1, s16Ext:$src2), 3082263508Sdim "if(!$src1) $dst = #$src2", 3083239462Sdim []>, 3084239462Sdim Requires<[HasV4T]>; 3085239462Sdim 3086263508Sdimlet isExtended = 1, opExtendable = 2, AddedComplexity=50, 3087263508SdimneverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3088239462Sdimdef TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3089263508Sdim (ins PredRegs:$src1, s16Ext:$src2), 3090263508Sdim "if($src1.new) $dst = #$src2", 3091239462Sdim []>, 3092239462Sdim Requires<[HasV4T]>; 3093239462Sdim 3094263508Sdimlet isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3095263508SdimneverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3096239462Sdimdef TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3097263508Sdim (ins PredRegs:$src1, s16Ext:$src2), 3098263508Sdim "if(!$src1.new) $dst = #$src2", 3099239462Sdim []>, 3100239462Sdim Requires<[HasV4T]>; 3101239462Sdim 3102239462Sdimlet AddedComplexity = 50, Predicates = [HasV4T] in 3103239462Sdimdef : Pat<(HexagonCONST32_GP tglobaladdr:$src1), 3104263508Sdim (TFRI_V4 tglobaladdr:$src1)>, 3105263508Sdim Requires<[HasV4T]>; 3106239462Sdim 3107239462Sdim 3108239462Sdim// Load - Indirect with long offset: These instructions take global address 3109239462Sdim// as an operand 3110251662Sdimlet isExtended = 1, opExtendable = 3, AddedComplexity = 40, 3111251662SdimvalidSubTargets = HasV4SubT in 3112239462Sdimdef LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst), 3113251662Sdim (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3114239462Sdim "$dst=memd($src1<<#$src2+##$offset)", 3115239462Sdim [(set (i64 DoubleRegs:$dst), 3116239462Sdim (load (add (shl IntRegs:$src1, u2ImmPred:$src2), 3117239462Sdim (HexagonCONST32 tglobaladdr:$offset))))]>, 3118239462Sdim Requires<[HasV4T]>; 3119239462Sdim 3120251662Sdimlet AddedComplexity = 40 in 3121239462Sdimmulticlass LD_indirect_lo<string OpcStr, PatFrag OpNode> { 3122251662Sdimlet isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in 3123239462Sdim def _lo_V4 : LDInst<(outs IntRegs:$dst), 3124251662Sdim (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3125239462Sdim !strconcat("$dst = ", 3126239462Sdim !strconcat(OpcStr, "($src1<<#$src2+##$offset)")), 3127239462Sdim [(set IntRegs:$dst, 3128239462Sdim (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2), 3129239462Sdim (HexagonCONST32 tglobaladdr:$offset)))))]>, 3130239462Sdim Requires<[HasV4T]>; 3131239462Sdim} 3132239462Sdim 3133239462Sdimdefm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>; 3134239462Sdimdefm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>; 3135251662Sdimdefm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>; 3136239462Sdimdefm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>; 3137239462Sdimdefm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>; 3138251662Sdimdefm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>; 3139239462Sdimdefm LDriw_ind : LD_indirect_lo<"memw", load>; 3140239462Sdim 3141251662Sdimlet AddedComplexity = 40 in 3142251662Sdimdef : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 3143251662Sdim (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3144251662Sdim (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3145251662Sdim Requires<[HasV4T]>; 3146239462Sdim 3147251662Sdimlet AddedComplexity = 40 in 3148251662Sdimdef : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 3149251662Sdim (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3150251662Sdim (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3151251662Sdim Requires<[HasV4T]>; 3152239462Sdim 3153249423Sdimlet Predicates = [HasV4T], AddedComplexity = 30 in { 3154249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3155251662Sdim (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3156239462Sdim 3157249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3158251662Sdim (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3159239462Sdim 3160249423Sdimdef : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3161251662Sdim (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3162249423Sdim} 3163239462Sdim 3164249423Sdimlet Predicates = [HasV4T], AddedComplexity = 30 in { 3165249423Sdimdef : Pat<(i32 (load u0AlwaysExtPred:$src)), 3166251662Sdim (LDriw_abs_V4 u0AlwaysExtPred:$src)>; 3167239462Sdim 3168249423Sdimdef : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)), 3169251662Sdim (LDrib_abs_V4 u0AlwaysExtPred:$src)>; 3170239462Sdim 3171249423Sdimdef : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)), 3172251662Sdim (LDriub_abs_V4 u0AlwaysExtPred:$src)>; 3173239462Sdim 3174249423Sdimdef : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)), 3175251662Sdim (LDrih_abs_V4 u0AlwaysExtPred:$src)>; 3176239462Sdim 3177249423Sdimdef : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)), 3178251662Sdim (LDriuh_abs_V4 u0AlwaysExtPred:$src)>; 3179249423Sdim} 3180239462Sdim 3181251662Sdim// Indexed store word - global address. 3182239462Sdim// memw(Rs+#u6:2)=#S8 3183239462Sdimlet AddedComplexity = 10 in 3184239462Sdimdef STriw_offset_ext_V4 : STInst<(outs), 3185239462Sdim (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3), 3186239462Sdim "memw($src1+#$src2) = ##$src3", 3187239462Sdim [(store (HexagonCONST32 tglobaladdr:$src3), 3188239462Sdim (add IntRegs:$src1, u6_2ImmPred:$src2))]>, 3189239462Sdim Requires<[HasV4T]>; 3190239462Sdim 3191263508Sdimdef : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))), 3192263508Sdim (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>, 3193263508Sdim Requires<[HasV4T]>; 3194239462Sdim 3195263508Sdimdef : Pat<(i64 (cttz (i64 DoubleRegs:$src1))), 3196263508Sdim (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>, 3197263508Sdim Requires<[HasV4T]>; 3198263508Sdim 3199263508Sdim 3200263508Sdim// i8 -> i64 loads 3201263508Sdim// We need a complexity of 120 here to overide preceeding handling of 3202263508Sdim// zextloadi8. 3203263508Sdimlet Predicates = [HasV4T], AddedComplexity = 120 in { 3204263508Sdimdef: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3205263508Sdim (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>; 3206263508Sdim 3207263508Sdimdef: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3208263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>; 3209263508Sdim 3210263508Sdimdef: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3211263508Sdim (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>; 3212263508Sdim 3213263508Sdimdef: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)), 3214263508Sdim (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; 3215263508Sdim 3216263508Sdimdef: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)), 3217263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>; 3218263508Sdim 3219263508Sdimdef: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)), 3220263508Sdim (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; 3221263508Sdim} 3222263508Sdim// i16 -> i64 loads 3223263508Sdim// We need a complexity of 120 here to overide preceeding handling of 3224263508Sdim// zextloadi16. 3225263508Sdimlet AddedComplexity = 120 in { 3226263508Sdimdef: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3227263508Sdim (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>, 3228263508Sdim Requires<[HasV4T]>; 3229263508Sdim 3230263508Sdimdef: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3231263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>, 3232263508Sdim Requires<[HasV4T]>; 3233263508Sdim 3234263508Sdimdef: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3235263508Sdim (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>, 3236263508Sdim Requires<[HasV4T]>; 3237263508Sdim 3238263508Sdimdef: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)), 3239263508Sdim (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, 3240263508Sdim Requires<[HasV4T]>; 3241263508Sdim 3242263508Sdimdef: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)), 3243263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>, 3244263508Sdim Requires<[HasV4T]>; 3245263508Sdim 3246263508Sdimdef: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)), 3247263508Sdim (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, 3248263508Sdim Requires<[HasV4T]>; 3249263508Sdim} 3250263508Sdim// i32->i64 loads 3251263508Sdim// We need a complexity of 120 here to overide preceeding handling of 3252263508Sdim// zextloadi32. 3253263508Sdimlet AddedComplexity = 120 in { 3254263508Sdimdef: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3255263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3256263508Sdim Requires<[HasV4T]>; 3257263508Sdim 3258263508Sdimdef: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3259263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3260263508Sdim Requires<[HasV4T]>; 3261263508Sdim 3262263508Sdimdef: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3263263508Sdim (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>, 3264263508Sdim Requires<[HasV4T]>; 3265263508Sdim 3266263508Sdimdef: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)), 3267263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3268263508Sdim Requires<[HasV4T]>; 3269263508Sdim 3270263508Sdimdef: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)), 3271263508Sdim (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3272263508Sdim Requires<[HasV4T]>; 3273263508Sdim 3274263508Sdimdef: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)), 3275263508Sdim (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3276263508Sdim Requires<[HasV4T]>; 3277263508Sdim} 3278263508Sdim 3279239462Sdim// Indexed store double word - global address. 3280239462Sdim// memw(Rs+#u6:2)=#S8 3281239462Sdimlet AddedComplexity = 10 in 3282239462Sdimdef STrih_offset_ext_V4 : STInst<(outs), 3283239462Sdim (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3), 3284239462Sdim "memh($src1+#$src2) = ##$src3", 3285239462Sdim [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3), 3286239462Sdim (add IntRegs:$src1, u6_1ImmPred:$src2))]>, 3287239462Sdim Requires<[HasV4T]>; 3288249423Sdim// Map from store(globaladdress + x) -> memd(#foo + x) 3289249423Sdimlet AddedComplexity = 100 in 3290249423Sdimdef : Pat<(store (i64 DoubleRegs:$src1), 3291249423Sdim FoldGlobalAddrGP:$addr), 3292249423Sdim (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 3293249423Sdim Requires<[HasV4T]>; 3294249423Sdim 3295249423Sdimdef : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr, 3296249423Sdim (i64 DoubleRegs:$src1)), 3297249423Sdim (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 3298249423Sdim Requires<[HasV4T]>; 3299249423Sdim 3300249423Sdim// Map from store(globaladdress + x) -> memb(#foo + x) 3301249423Sdimlet AddedComplexity = 100 in 3302249423Sdimdef : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3303249423Sdim (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3304249423Sdim Requires<[HasV4T]>; 3305249423Sdim 3306249423Sdimdef : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3307249423Sdim (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3308249423Sdim Requires<[HasV4T]>; 3309249423Sdim 3310249423Sdim// Map from store(globaladdress + x) -> memh(#foo + x) 3311249423Sdimlet AddedComplexity = 100 in 3312249423Sdimdef : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3313249423Sdim (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3314249423Sdim Requires<[HasV4T]>; 3315249423Sdim 3316249423Sdimdef : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3317249423Sdim (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3318249423Sdim Requires<[HasV4T]>; 3319249423Sdim 3320249423Sdim// Map from store(globaladdress + x) -> memw(#foo + x) 3321249423Sdimlet AddedComplexity = 100 in 3322249423Sdimdef : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3323249423Sdim (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3324249423Sdim Requires<[HasV4T]>; 3325249423Sdim 3326249423Sdimdef : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3327249423Sdim (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3328249423Sdim Requires<[HasV4T]>; 3329249423Sdim 3330249423Sdim// Map from load(globaladdress + x) -> memd(#foo + x) 3331249423Sdimlet AddedComplexity = 100 in 3332249423Sdimdef : Pat<(i64 (load FoldGlobalAddrGP:$addr)), 3333249423Sdim (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>, 3334249423Sdim Requires<[HasV4T]>; 3335249423Sdim 3336249423Sdimdef : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr), 3337249423Sdim (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>, 3338249423Sdim Requires<[HasV4T]>; 3339249423Sdim 3340249423Sdim// Map from load(globaladdress + x) -> memb(#foo + x) 3341249423Sdimlet AddedComplexity = 100 in 3342249423Sdimdef : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)), 3343249423Sdim (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>, 3344249423Sdim Requires<[HasV4T]>; 3345249423Sdim 3346249423Sdim// Map from load(globaladdress + x) -> memb(#foo + x) 3347249423Sdimlet AddedComplexity = 100 in 3348249423Sdimdef : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)), 3349249423Sdim (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>, 3350249423Sdim Requires<[HasV4T]>; 3351249423Sdim 3352249423Sdim//let AddedComplexity = 100 in 3353249423Sdimlet AddedComplexity = 100 in 3354249423Sdimdef : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)), 3355249423Sdim (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>, 3356249423Sdim Requires<[HasV4T]>; 3357249423Sdim 3358249423Sdim// Map from load(globaladdress + x) -> memh(#foo + x) 3359249423Sdimlet AddedComplexity = 100 in 3360249423Sdimdef : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)), 3361249423Sdim (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>, 3362249423Sdim Requires<[HasV4T]>; 3363249423Sdim 3364249423Sdim// Map from load(globaladdress + x) -> memuh(#foo + x) 3365249423Sdimlet AddedComplexity = 100 in 3366249423Sdimdef : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)), 3367249423Sdim (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>, 3368249423Sdim Requires<[HasV4T]>; 3369249423Sdim 3370249423Sdimdef : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr), 3371249423Sdim (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>, 3372249423Sdim Requires<[HasV4T]>; 3373249423Sdim 3374249423Sdim// Map from load(globaladdress + x) -> memub(#foo + x) 3375249423Sdimlet AddedComplexity = 100 in 3376249423Sdimdef : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)), 3377249423Sdim (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>, 3378249423Sdim Requires<[HasV4T]>; 3379249423Sdim 3380249423Sdimdef : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr), 3381249423Sdim (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>, 3382249423Sdim Requires<[HasV4T]>; 3383249423Sdim 3384249423Sdim// Map from load(globaladdress + x) -> memw(#foo + x) 3385249423Sdimlet AddedComplexity = 100 in 3386249423Sdimdef : Pat<(i32 (load FoldGlobalAddrGP:$addr)), 3387249423Sdim (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3388249423Sdim Requires<[HasV4T]>; 3389249423Sdim 3390249423Sdimdef : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr), 3391249423Sdim (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3392249423Sdim Requires<[HasV4T]>; 3393