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