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 isTaken> 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(isTaken, "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 isBrTaken = !if(isTaken, "true", "false"); 1023 let isPredicatedFalse = isNegCond; 1024 1025 let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0}); 1026 let RegOp = !if(!eq(NvOpNum, 0), src2, src1); 1027 1028 let IClass = 0b0010; 1029 let Inst{26} = 0b0; 1030 let Inst{25-23} = majOp; 1031 let Inst{22} = isNegCond; 1032 let Inst{18-16} = Ns; 1033 let Inst{13} = isTaken; 1034 let Inst{12-8} = RegOp; 1035 let Inst{21-20} = offset{10-9}; 1036 let Inst{7-1} = offset{8-2}; 1037} 1038 1039 1040multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum, 1041 bit isNegCond> { 1042 // Branch not taken: 1043 def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>; 1044 // Branch taken: 1045 def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>; 1046} 1047 1048// NvOpNum = 0 -> First Operand is a new-value Register 1049// NvOpNum = 1 -> Second Operand is a new-value Register 1050 1051multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp, 1052 bit NvOpNum> { 1053 let BaseOpcode = BaseOp#_NVJ in { 1054 defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond 1055 defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond 1056 } 1057} 1058 1059// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2 1060// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2 1061// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2 1062// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2 1063// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2 1064 1065let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1066 Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { 1067 defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel; 1068 defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel; 1069 defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel; 1070 defm CMPLTrr : NVJrr_base<"cmp.gt", "CMPLT", 0b011, 1>, PredRel; 1071 defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel; 1072} 1073 1074//===----------------------------------------------------------------------===// 1075// multiclass/template class for the new-value compare jumps instruction 1076// with a register and an unsigned immediate (U5) operand. 1077//===----------------------------------------------------------------------===// 1078 1079let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in 1080class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond, 1081 bit isTaken> 1082 : NVInst_V4<(outs), 1083 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), 1084 "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:" 1085 #!if(isTaken, "t","nt")#" $offset", 1086 []>, Requires<[HasV4T]> { 1087 1088 let isPredicatedFalse = isNegCond; 1089 let isBrTaken = !if(isTaken, "true", "false"); 1090 1091 bits<3> src1; 1092 bits<5> src2; 1093 bits<11> offset; 1094 1095 let IClass = 0b0010; 1096 let Inst{26} = 0b1; 1097 let Inst{25-23} = majOp; 1098 let Inst{22} = isNegCond; 1099 let Inst{18-16} = src1; 1100 let Inst{13} = isTaken; 1101 let Inst{12-8} = src2; 1102 let Inst{21-20} = offset{10-9}; 1103 let Inst{7-1} = offset{8-2}; 1104} 1105 1106multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> { 1107 // Branch not taken: 1108 def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>; 1109 // Branch taken: 1110 def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>; 1111} 1112 1113multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> { 1114 let BaseOpcode = BaseOp#_NVJri in { 1115 defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond 1116 defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond 1117 } 1118} 1119 1120// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2 1121// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2 1122// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2 1123 1124let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1125 Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in { 1126 defm CMPEQri : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel; 1127 defm CMPGTri : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel; 1128 defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel; 1129} 1130 1131//===----------------------------------------------------------------------===// 1132// multiclass/template class for the new-value compare jumps instruction 1133// with a register and an hardcoded 0/-1 immediate value. 1134//===----------------------------------------------------------------------===// 1135 1136let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in 1137class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal, 1138 bit isNegCond, bit isTaken> 1139 : NVInst_V4<(outs), 1140 (ins IntRegs:$src1, brtarget:$offset), 1141 "if ("#!if(isNegCond, "!","")#mnemonic 1142 #"($src1.new, #"#ImmVal#")) jump:" 1143 #!if(isTaken, "t","nt")#" $offset", 1144 []>, Requires<[HasV4T]> { 1145 1146 let isPredicatedFalse = isNegCond; 1147 let isBrTaken = !if(isTaken, "true", "false"); 1148 1149 bits<3> src1; 1150 bits<11> offset; 1151 let IClass = 0b0010; 1152 let Inst{26} = 0b1; 1153 let Inst{25-23} = majOp; 1154 let Inst{22} = isNegCond; 1155 let Inst{18-16} = src1; 1156 let Inst{13} = isTaken; 1157 let Inst{21-20} = offset{10-9}; 1158 let Inst{7-1} = offset{8-2}; 1159} 1160 1161multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal, 1162 bit isNegCond> { 1163 // Branch not taken: 1164 def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>; 1165 // Branch taken: 1166 def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>; 1167} 1168 1169multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp, 1170 string ImmVal> { 1171 let BaseOpcode = BaseOp#_NVJ_ConstImm in { 1172 defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond 1173 defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond 1174 } 1175} 1176 1177// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2 1178// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2 1179// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2 1180 1181let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1, 1182 Defs = [PC], neverHasSideEffects = 1 in { 1183 defm TSTBIT0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel; 1184 defm CMPEQn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ", 0b100, "-1">, PredRel; 1185 defm CMPGTn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT", 0b101, "-1">, PredRel; 1186} 1187 1188//===----------------------------------------------------------------------===// 1189// XTYPE/ALU + 1190//===----------------------------------------------------------------------===// 1191 1192// Add and accumulate. 1193// Rd=add(Rs,add(Ru,#s6)) 1194let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6, 1195validSubTargets = HasV4SubT in 1196def ADDr_ADDri_V4 : MInst<(outs IntRegs:$dst), 1197 (ins IntRegs:$src1, IntRegs:$src2, s6Ext:$src3), 1198 "$dst = add($src1, add($src2, #$src3))", 1199 [(set (i32 IntRegs:$dst), 1200 (add (i32 IntRegs:$src1), (add (i32 IntRegs:$src2), 1201 s6_16ExtPred:$src3)))]>, 1202 Requires<[HasV4T]>; 1203 1204// Rd=add(Rs,sub(#s6,Ru)) 1205let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1206validSubTargets = HasV4SubT in 1207def ADDr_SUBri_V4 : MInst<(outs IntRegs:$dst), 1208 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3), 1209 "$dst = add($src1, sub(#$src2, $src3))", 1210 [(set (i32 IntRegs:$dst), 1211 (add (i32 IntRegs:$src1), (sub s6_10ExtPred:$src2, 1212 (i32 IntRegs:$src3))))]>, 1213 Requires<[HasV4T]>; 1214 1215// Generates the same instruction as ADDr_SUBri_V4 but matches different 1216// pattern. 1217// Rd=add(Rs,sub(#s6,Ru)) 1218let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1219validSubTargets = HasV4SubT in 1220def ADDri_SUBr_V4 : MInst<(outs IntRegs:$dst), 1221 (ins IntRegs:$src1, s6Ext:$src2, IntRegs:$src3), 1222 "$dst = add($src1, sub(#$src2, $src3))", 1223 [(set (i32 IntRegs:$dst), 1224 (sub (add (i32 IntRegs:$src1), s6_10ExtPred:$src2), 1225 (i32 IntRegs:$src3)))]>, 1226 Requires<[HasV4T]>; 1227 1228 1229// Add or subtract doublewords with carry. 1230//TODO: 1231// Rdd=add(Rss,Rtt,Px):carry 1232//TODO: 1233// Rdd=sub(Rss,Rtt,Px):carry 1234 1235 1236// Logical doublewords. 1237// Rdd=and(Rtt,~Rss) 1238let validSubTargets = HasV4SubT in 1239def ANDd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), 1240 (ins DoubleRegs:$src1, DoubleRegs:$src2), 1241 "$dst = and($src1, ~$src2)", 1242 [(set (i64 DoubleRegs:$dst), (and (i64 DoubleRegs:$src1), 1243 (not (i64 DoubleRegs:$src2))))]>, 1244 Requires<[HasV4T]>; 1245 1246// Rdd=or(Rtt,~Rss) 1247let validSubTargets = HasV4SubT in 1248def ORd_NOTd_V4 : MInst<(outs DoubleRegs:$dst), 1249 (ins DoubleRegs:$src1, DoubleRegs:$src2), 1250 "$dst = or($src1, ~$src2)", 1251 [(set (i64 DoubleRegs:$dst), 1252 (or (i64 DoubleRegs:$src1), (not (i64 DoubleRegs:$src2))))]>, 1253 Requires<[HasV4T]>; 1254 1255 1256// Logical-logical doublewords. 1257// Rxx^=xor(Rss,Rtt) 1258let validSubTargets = HasV4SubT in 1259def XORd_XORdd: MInst_acc<(outs DoubleRegs:$dst), 1260 (ins DoubleRegs:$src1, DoubleRegs:$src2, DoubleRegs:$src3), 1261 "$dst ^= xor($src2, $src3)", 1262 [(set (i64 DoubleRegs:$dst), 1263 (xor (i64 DoubleRegs:$src1), (xor (i64 DoubleRegs:$src2), 1264 (i64 DoubleRegs:$src3))))], 1265 "$src1 = $dst">, 1266 Requires<[HasV4T]>; 1267 1268 1269// Logical-logical words. 1270// Rx=or(Ru,and(Rx,#s10)) 1271let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1272validSubTargets = HasV4SubT in 1273def ORr_ANDri_V4 : MInst_acc<(outs IntRegs:$dst), 1274 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1275 "$dst = or($src1, and($src2, #$src3))", 1276 [(set (i32 IntRegs:$dst), 1277 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1278 s10ExtPred:$src3)))], 1279 "$src2 = $dst">, 1280 Requires<[HasV4T]>; 1281 1282// Rx[&|^]=and(Rs,Rt) 1283// Rx&=and(Rs,Rt) 1284let validSubTargets = HasV4SubT in 1285def ANDr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1286 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1287 "$dst &= and($src2, $src3)", 1288 [(set (i32 IntRegs:$dst), 1289 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1290 (i32 IntRegs:$src3))))], 1291 "$src1 = $dst">, 1292 Requires<[HasV4T]>; 1293 1294// Rx|=and(Rs,Rt) 1295let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in 1296def ORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1297 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1298 "$dst |= and($src2, $src3)", 1299 [(set (i32 IntRegs:$dst), 1300 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1301 (i32 IntRegs:$src3))))], 1302 "$src1 = $dst">, 1303 Requires<[HasV4T]>, ImmRegRel; 1304 1305// Rx^=and(Rs,Rt) 1306let validSubTargets = HasV4SubT in 1307def XORr_ANDrr_V4 : MInst_acc<(outs IntRegs:$dst), 1308 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1309 "$dst ^= and($src2, $src3)", 1310 [(set (i32 IntRegs:$dst), 1311 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1312 (i32 IntRegs:$src3))))], 1313 "$src1 = $dst">, 1314 Requires<[HasV4T]>; 1315 1316// Rx[&|^]=and(Rs,~Rt) 1317// Rx&=and(Rs,~Rt) 1318let validSubTargets = HasV4SubT in 1319def ANDr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1320 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1321 "$dst &= and($src2, ~$src3)", 1322 [(set (i32 IntRegs:$dst), 1323 (and (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1324 (not (i32 IntRegs:$src3)))))], 1325 "$src1 = $dst">, 1326 Requires<[HasV4T]>; 1327 1328// Rx|=and(Rs,~Rt) 1329let validSubTargets = HasV4SubT in 1330def ORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1331 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1332 "$dst |= and($src2, ~$src3)", 1333 [(set (i32 IntRegs:$dst), 1334 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1335 (not (i32 IntRegs:$src3)))))], 1336 "$src1 = $dst">, 1337 Requires<[HasV4T]>; 1338 1339// Rx^=and(Rs,~Rt) 1340let validSubTargets = HasV4SubT in 1341def XORr_ANDr_NOTr_V4 : MInst_acc<(outs IntRegs:$dst), 1342 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1343 "$dst ^= and($src2, ~$src3)", 1344 [(set (i32 IntRegs:$dst), 1345 (xor (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1346 (not (i32 IntRegs:$src3)))))], 1347 "$src1 = $dst">, 1348 Requires<[HasV4T]>; 1349 1350// Rx[&|^]=or(Rs,Rt) 1351// Rx&=or(Rs,Rt) 1352let validSubTargets = HasV4SubT in 1353def ANDr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1354 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1355 "$dst &= or($src2, $src3)", 1356 [(set (i32 IntRegs:$dst), 1357 (and (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1358 (i32 IntRegs:$src3))))], 1359 "$src1 = $dst">, 1360 Requires<[HasV4T]>; 1361 1362// Rx|=or(Rs,Rt) 1363let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in 1364def ORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1365 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1366 "$dst |= or($src2, $src3)", 1367 [(set (i32 IntRegs:$dst), 1368 (or (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1369 (i32 IntRegs:$src3))))], 1370 "$src1 = $dst">, 1371 Requires<[HasV4T]>, ImmRegRel; 1372 1373// Rx^=or(Rs,Rt) 1374let validSubTargets = HasV4SubT in 1375def XORr_ORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1376 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1377 "$dst ^= or($src2, $src3)", 1378 [(set (i32 IntRegs:$dst), 1379 (xor (i32 IntRegs:$src1), (or (i32 IntRegs:$src2), 1380 (i32 IntRegs:$src3))))], 1381 "$src1 = $dst">, 1382 Requires<[HasV4T]>; 1383 1384// Rx[&|^]=xor(Rs,Rt) 1385// Rx&=xor(Rs,Rt) 1386let validSubTargets = HasV4SubT in 1387def ANDr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1388 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1389 "$dst &= xor($src2, $src3)", 1390 [(set (i32 IntRegs:$dst), 1391 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1392 (i32 IntRegs:$src3))))], 1393 "$src1 = $dst">, 1394 Requires<[HasV4T]>; 1395 1396// Rx|=xor(Rs,Rt) 1397let validSubTargets = HasV4SubT in 1398def ORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1399 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1400 "$dst |= xor($src2, $src3)", 1401 [(set (i32 IntRegs:$dst), 1402 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1403 (i32 IntRegs:$src3))))], 1404 "$src1 = $dst">, 1405 Requires<[HasV4T]>; 1406 1407// Rx^=xor(Rs,Rt) 1408let validSubTargets = HasV4SubT in 1409def XORr_XORrr_V4 : MInst_acc<(outs IntRegs:$dst), 1410 (ins IntRegs:$src1, IntRegs: $src2, IntRegs:$src3), 1411 "$dst ^= xor($src2, $src3)", 1412 [(set (i32 IntRegs:$dst), 1413 (and (i32 IntRegs:$src1), (xor (i32 IntRegs:$src2), 1414 (i32 IntRegs:$src3))))], 1415 "$src1 = $dst">, 1416 Requires<[HasV4T]>; 1417 1418// Rx|=and(Rs,#s10) 1419let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1420validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in 1421def ORr_ANDri2_V4 : MInst_acc<(outs IntRegs:$dst), 1422 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1423 "$dst |= and($src2, #$src3)", 1424 [(set (i32 IntRegs:$dst), 1425 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1426 s10ExtPred:$src3)))], 1427 "$src1 = $dst">, 1428 Requires<[HasV4T]>, ImmRegRel; 1429 1430// Rx|=or(Rs,#s10) 1431let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1432validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in 1433def ORr_ORri_V4 : MInst_acc<(outs IntRegs:$dst), 1434 (ins IntRegs:$src1, IntRegs: $src2, s10Ext:$src3), 1435 "$dst |= or($src2, #$src3)", 1436 [(set (i32 IntRegs:$dst), 1437 (or (i32 IntRegs:$src1), (and (i32 IntRegs:$src2), 1438 s10ExtPred:$src3)))], 1439 "$src1 = $dst">, 1440 Requires<[HasV4T]>, ImmRegRel; 1441 1442 1443// Modulo wrap 1444// Rd=modwrap(Rs,Rt) 1445// Round 1446// Rd=cround(Rs,#u5) 1447// Rd=cround(Rs,Rt) 1448// Rd=round(Rs,#u5)[:sat] 1449// Rd=round(Rs,Rt)[:sat] 1450// Vector reduce add unsigned halfwords 1451// Rd=vraddh(Rss,Rtt) 1452// Vector add bytes 1453// Rdd=vaddb(Rss,Rtt) 1454// Vector conditional negate 1455// Rdd=vcnegh(Rss,Rt) 1456// Rxx+=vrcnegh(Rss,Rt) 1457// Vector maximum bytes 1458// Rdd=vmaxb(Rtt,Rss) 1459// Vector reduce maximum halfwords 1460// Rxx=vrmaxh(Rss,Ru) 1461// Rxx=vrmaxuh(Rss,Ru) 1462// Vector reduce maximum words 1463// Rxx=vrmaxuw(Rss,Ru) 1464// Rxx=vrmaxw(Rss,Ru) 1465// Vector minimum bytes 1466// Rdd=vminb(Rtt,Rss) 1467// Vector reduce minimum halfwords 1468// Rxx=vrminh(Rss,Ru) 1469// Rxx=vrminuh(Rss,Ru) 1470// Vector reduce minimum words 1471// Rxx=vrminuw(Rss,Ru) 1472// Rxx=vrminw(Rss,Ru) 1473// Vector subtract bytes 1474// Rdd=vsubb(Rss,Rtt) 1475 1476//===----------------------------------------------------------------------===// 1477// XTYPE/ALU - 1478//===----------------------------------------------------------------------===// 1479 1480 1481//===----------------------------------------------------------------------===// 1482// XTYPE/MPY + 1483//===----------------------------------------------------------------------===// 1484 1485// Multiply and user lower result. 1486// Rd=add(#u6,mpyi(Rs,#U6)) 1487let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1488validSubTargets = HasV4SubT in 1489def ADDi_MPYri_V4 : MInst<(outs IntRegs:$dst), 1490 (ins u6Ext:$src1, IntRegs:$src2, u6Imm:$src3), 1491 "$dst = add(#$src1, mpyi($src2, #$src3))", 1492 [(set (i32 IntRegs:$dst), 1493 (add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), 1494 u6ExtPred:$src1))]>, 1495 Requires<[HasV4T]>; 1496 1497// Rd=add(##,mpyi(Rs,#U6)) 1498def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), 1499 (HexagonCONST32 tglobaladdr:$src1)), 1500 (i32 (ADDi_MPYri_V4 tglobaladdr:$src1, IntRegs:$src2, 1501 u6ImmPred:$src3))>; 1502 1503// Rd=add(#u6,mpyi(Rs,Rt)) 1504let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1505validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1506def ADDi_MPYrr_V4 : MInst<(outs IntRegs:$dst), 1507 (ins u6Ext:$src1, IntRegs:$src2, IntRegs:$src3), 1508 "$dst = add(#$src1, mpyi($src2, $src3))", 1509 [(set (i32 IntRegs:$dst), 1510 (add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1511 u6ExtPred:$src1))]>, 1512 Requires<[HasV4T]>, ImmRegRel; 1513 1514// Rd=add(##,mpyi(Rs,Rt)) 1515def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 1516 (HexagonCONST32 tglobaladdr:$src1)), 1517 (i32 (ADDi_MPYrr_V4 tglobaladdr:$src1, IntRegs:$src2, 1518 IntRegs:$src3))>; 1519 1520// Rd=add(Ru,mpyi(#u6:2,Rs)) 1521let validSubTargets = HasV4SubT in 1522def ADDr_MPYir_V4 : MInst<(outs IntRegs:$dst), 1523 (ins IntRegs:$src1, u6Imm:$src2, IntRegs:$src3), 1524 "$dst = add($src1, mpyi(#$src2, $src3))", 1525 [(set (i32 IntRegs:$dst), 1526 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), 1527 u6_2ImmPred:$src2)))]>, 1528 Requires<[HasV4T]>; 1529 1530// Rd=add(Ru,mpyi(Rs,#u6)) 1531let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6, 1532validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1533def ADDr_MPYri_V4 : MInst<(outs IntRegs:$dst), 1534 (ins IntRegs:$src1, IntRegs:$src2, u6Ext:$src3), 1535 "$dst = add($src1, mpyi($src2, #$src3))", 1536 [(set (i32 IntRegs:$dst), 1537 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1538 u6ExtPred:$src3)))]>, 1539 Requires<[HasV4T]>, ImmRegRel; 1540 1541// Rx=add(Ru,mpyi(Rx,Rs)) 1542let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in 1543def ADDr_MPYrr_V4 : MInst_acc<(outs IntRegs:$dst), 1544 (ins IntRegs:$src1, IntRegs:$src2, IntRegs:$src3), 1545 "$dst = add($src1, mpyi($src2, $src3))", 1546 [(set (i32 IntRegs:$dst), 1547 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src2), 1548 (i32 IntRegs:$src3))))], 1549 "$src2 = $dst">, 1550 Requires<[HasV4T]>, ImmRegRel; 1551 1552 1553// Polynomial multiply words 1554// Rdd=pmpyw(Rs,Rt) 1555// Rxx^=pmpyw(Rs,Rt) 1556 1557// Vector reduce multiply word by signed half (32x16) 1558// Rdd=vrmpyweh(Rss,Rtt)[:<<1] 1559// Rdd=vrmpywoh(Rss,Rtt)[:<<1] 1560// Rxx+=vrmpyweh(Rss,Rtt)[:<<1] 1561// Rxx+=vrmpywoh(Rss,Rtt)[:<<1] 1562 1563// Multiply and use upper result 1564// Rd=mpy(Rs,Rt.H):<<1:sat 1565// Rd=mpy(Rs,Rt.L):<<1:sat 1566// Rd=mpy(Rs,Rt):<<1 1567// Rd=mpy(Rs,Rt):<<1:sat 1568// Rd=mpysu(Rs,Rt) 1569// Rx+=mpy(Rs,Rt):<<1:sat 1570// Rx-=mpy(Rs,Rt):<<1:sat 1571 1572// Vector multiply bytes 1573// Rdd=vmpybsu(Rs,Rt) 1574// Rdd=vmpybu(Rs,Rt) 1575// Rxx+=vmpybsu(Rs,Rt) 1576// Rxx+=vmpybu(Rs,Rt) 1577 1578// Vector polynomial multiply halfwords 1579// Rdd=vpmpyh(Rs,Rt) 1580// Rxx^=vpmpyh(Rs,Rt) 1581 1582//===----------------------------------------------------------------------===// 1583// XTYPE/MPY - 1584//===----------------------------------------------------------------------===// 1585 1586 1587//===----------------------------------------------------------------------===// 1588// XTYPE/SHIFT + 1589//===----------------------------------------------------------------------===// 1590 1591// Shift by immediate and accumulate. 1592// Rx=add(#u8,asl(Rx,#U5)) 1593let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1594validSubTargets = HasV4SubT in 1595def ADDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1596 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1597 "$dst = add(#$src1, asl($src2, #$src3))", 1598 [(set (i32 IntRegs:$dst), 1599 (add (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1600 u8ExtPred:$src1))], 1601 "$src2 = $dst">, 1602 Requires<[HasV4T]>; 1603 1604// Rx=add(#u8,lsr(Rx,#U5)) 1605let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1606validSubTargets = HasV4SubT in 1607def ADDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1608 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1609 "$dst = add(#$src1, lsr($src2, #$src3))", 1610 [(set (i32 IntRegs:$dst), 1611 (add (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1612 u8ExtPred:$src1))], 1613 "$src2 = $dst">, 1614 Requires<[HasV4T]>; 1615 1616// Rx=sub(#u8,asl(Rx,#U5)) 1617let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1618validSubTargets = HasV4SubT in 1619def SUBi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1620 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1621 "$dst = sub(#$src1, asl($src2, #$src3))", 1622 [(set (i32 IntRegs:$dst), 1623 (sub (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1624 u8ExtPred:$src1))], 1625 "$src2 = $dst">, 1626 Requires<[HasV4T]>; 1627 1628// Rx=sub(#u8,lsr(Rx,#U5)) 1629let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1630validSubTargets = HasV4SubT in 1631def SUBi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1632 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1633 "$dst = sub(#$src1, lsr($src2, #$src3))", 1634 [(set (i32 IntRegs:$dst), 1635 (sub (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1636 u8ExtPred:$src1))], 1637 "$src2 = $dst">, 1638 Requires<[HasV4T]>; 1639 1640 1641//Shift by immediate and logical. 1642//Rx=and(#u8,asl(Rx,#U5)) 1643let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1644validSubTargets = HasV4SubT in 1645def ANDi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1646 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1647 "$dst = and(#$src1, asl($src2, #$src3))", 1648 [(set (i32 IntRegs:$dst), 1649 (and (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1650 u8ExtPred:$src1))], 1651 "$src2 = $dst">, 1652 Requires<[HasV4T]>; 1653 1654//Rx=and(#u8,lsr(Rx,#U5)) 1655let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1656validSubTargets = HasV4SubT in 1657def ANDi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1658 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1659 "$dst = and(#$src1, lsr($src2, #$src3))", 1660 [(set (i32 IntRegs:$dst), 1661 (and (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1662 u8ExtPred:$src1))], 1663 "$src2 = $dst">, 1664 Requires<[HasV4T]>; 1665 1666//Rx=or(#u8,asl(Rx,#U5)) 1667let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1668AddedComplexity = 30, validSubTargets = HasV4SubT in 1669def ORi_ASLri_V4 : MInst_acc<(outs IntRegs:$dst), 1670 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1671 "$dst = or(#$src1, asl($src2, #$src3))", 1672 [(set (i32 IntRegs:$dst), 1673 (or (shl (i32 IntRegs:$src2), u5ImmPred:$src3), 1674 u8ExtPred:$src1))], 1675 "$src2 = $dst">, 1676 Requires<[HasV4T]>; 1677 1678//Rx=or(#u8,lsr(Rx,#U5)) 1679let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1680AddedComplexity = 30, validSubTargets = HasV4SubT in 1681def ORi_LSRri_V4 : MInst_acc<(outs IntRegs:$dst), 1682 (ins u8Ext:$src1, IntRegs:$src2, u5Imm:$src3), 1683 "$dst = or(#$src1, lsr($src2, #$src3))", 1684 [(set (i32 IntRegs:$dst), 1685 (or (srl (i32 IntRegs:$src2), u5ImmPred:$src3), 1686 u8ExtPred:$src1))], 1687 "$src2 = $dst">, 1688 Requires<[HasV4T]>; 1689 1690 1691//Shift by register. 1692//Rd=lsl(#s6,Rt) 1693let validSubTargets = HasV4SubT in { 1694def LSLi_V4 : MInst<(outs IntRegs:$dst), (ins s6Imm:$src1, IntRegs:$src2), 1695 "$dst = lsl(#$src1, $src2)", 1696 [(set (i32 IntRegs:$dst), (shl s6ImmPred:$src1, 1697 (i32 IntRegs:$src2)))]>, 1698 Requires<[HasV4T]>; 1699 1700 1701//Shift by register and logical. 1702//Rxx^=asl(Rss,Rt) 1703def ASLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1704 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1705 "$dst ^= asl($src2, $src3)", 1706 [(set (i64 DoubleRegs:$dst), 1707 (xor (i64 DoubleRegs:$src1), (shl (i64 DoubleRegs:$src2), 1708 (i32 IntRegs:$src3))))], 1709 "$src1 = $dst">, 1710 Requires<[HasV4T]>; 1711 1712//Rxx^=asr(Rss,Rt) 1713def ASRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1714 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1715 "$dst ^= asr($src2, $src3)", 1716 [(set (i64 DoubleRegs:$dst), 1717 (xor (i64 DoubleRegs:$src1), (sra (i64 DoubleRegs:$src2), 1718 (i32 IntRegs:$src3))))], 1719 "$src1 = $dst">, 1720 Requires<[HasV4T]>; 1721 1722//Rxx^=lsl(Rss,Rt) 1723def LSLd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1724 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1725 "$dst ^= lsl($src2, $src3)", 1726 [(set (i64 DoubleRegs:$dst), (xor (i64 DoubleRegs:$src1), 1727 (shl (i64 DoubleRegs:$src2), 1728 (i32 IntRegs:$src3))))], 1729 "$src1 = $dst">, 1730 Requires<[HasV4T]>; 1731 1732//Rxx^=lsr(Rss,Rt) 1733def LSRd_rr_xor_V4 : MInst_acc<(outs DoubleRegs:$dst), 1734 (ins DoubleRegs:$src1, DoubleRegs:$src2, IntRegs:$src3), 1735 "$dst ^= lsr($src2, $src3)", 1736 [(set (i64 DoubleRegs:$dst), 1737 (xor (i64 DoubleRegs:$src1), (srl (i64 DoubleRegs:$src2), 1738 (i32 IntRegs:$src3))))], 1739 "$src1 = $dst">, 1740 Requires<[HasV4T]>; 1741} 1742 1743//===----------------------------------------------------------------------===// 1744// XTYPE/SHIFT - 1745//===----------------------------------------------------------------------===// 1746 1747//===----------------------------------------------------------------------===// 1748// MEMOP: Word, Half, Byte 1749//===----------------------------------------------------------------------===// 1750 1751def MEMOPIMM : SDNodeXForm<imm, [{ 1752 // Call the transformation function XformM5ToU5Imm to get the negative 1753 // immediate's positive counterpart. 1754 int32_t imm = N->getSExtValue(); 1755 return XformM5ToU5Imm(imm); 1756}]>; 1757 1758def MEMOPIMM_HALF : SDNodeXForm<imm, [{ 1759 // -1 .. -31 represented as 65535..65515 1760 // assigning to a short restores our desired signed value. 1761 // Call the transformation function XformM5ToU5Imm to get the negative 1762 // immediate's positive counterpart. 1763 int16_t imm = N->getSExtValue(); 1764 return XformM5ToU5Imm(imm); 1765}]>; 1766 1767def MEMOPIMM_BYTE : SDNodeXForm<imm, [{ 1768 // -1 .. -31 represented as 255..235 1769 // assigning to a char restores our desired signed value. 1770 // Call the transformation function XformM5ToU5Imm to get the negative 1771 // immediate's positive counterpart. 1772 int8_t imm = N->getSExtValue(); 1773 return XformM5ToU5Imm(imm); 1774}]>; 1775 1776def SETMEMIMM : SDNodeXForm<imm, [{ 1777 // Return the bit position we will set [0-31]. 1778 // As an SDNode. 1779 int32_t imm = N->getSExtValue(); 1780 return XformMskToBitPosU5Imm(imm); 1781}]>; 1782 1783def CLRMEMIMM : SDNodeXForm<imm, [{ 1784 // Return the bit position we will clear [0-31]. 1785 // As an SDNode. 1786 // we bit negate the value first 1787 int32_t imm = ~(N->getSExtValue()); 1788 return XformMskToBitPosU5Imm(imm); 1789}]>; 1790 1791def SETMEMIMM_SHORT : SDNodeXForm<imm, [{ 1792 // Return the bit position we will set [0-15]. 1793 // As an SDNode. 1794 int16_t imm = N->getSExtValue(); 1795 return XformMskToBitPosU4Imm(imm); 1796}]>; 1797 1798def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{ 1799 // Return the bit position we will clear [0-15]. 1800 // As an SDNode. 1801 // we bit negate the value first 1802 int16_t imm = ~(N->getSExtValue()); 1803 return XformMskToBitPosU4Imm(imm); 1804}]>; 1805 1806def SETMEMIMM_BYTE : SDNodeXForm<imm, [{ 1807 // Return the bit position we will set [0-7]. 1808 // As an SDNode. 1809 int8_t imm = N->getSExtValue(); 1810 return XformMskToBitPosU3Imm(imm); 1811}]>; 1812 1813def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{ 1814 // Return the bit position we will clear [0-7]. 1815 // As an SDNode. 1816 // we bit negate the value first 1817 int8_t imm = ~(N->getSExtValue()); 1818 return XformMskToBitPosU3Imm(imm); 1819}]>; 1820 1821//===----------------------------------------------------------------------===// 1822// Template class for MemOp instructions with the register value. 1823//===----------------------------------------------------------------------===// 1824class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp, 1825 string memOp, bits<2> memOpBits> : 1826 MEMInst_V4<(outs), 1827 (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta), 1828 opc#"($base+#$offset)"#memOp#"$delta", 1829 []>, 1830 Requires<[HasV4T, UseMEMOP]> { 1831 1832 bits<5> base; 1833 bits<5> delta; 1834 bits<32> offset; 1835 bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 1836 1837 let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 1838 !if (!eq(opcBits, 0b01), offset{6-1}, 1839 !if (!eq(opcBits, 0b10), offset{7-2},0))); 1840 1841 let IClass = 0b0011; 1842 let Inst{27-24} = 0b1110; 1843 let Inst{22-21} = opcBits; 1844 let Inst{20-16} = base; 1845 let Inst{13} = 0b0; 1846 let Inst{12-7} = offsetBits; 1847 let Inst{6-5} = memOpBits; 1848 let Inst{4-0} = delta; 1849} 1850 1851//===----------------------------------------------------------------------===// 1852// Template class for MemOp instructions with the immediate value. 1853//===----------------------------------------------------------------------===// 1854class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp, 1855 string memOp, bits<2> memOpBits> : 1856 MEMInst_V4 <(outs), 1857 (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta), 1858 opc#"($base+#$offset)"#memOp#"#$delta" 1859 #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')' 1860 []>, 1861 Requires<[HasV4T, UseMEMOP]> { 1862 1863 bits<5> base; 1864 bits<5> delta; 1865 bits<32> offset; 1866 bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 1867 1868 let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 1869 !if (!eq(opcBits, 0b01), offset{6-1}, 1870 !if (!eq(opcBits, 0b10), offset{7-2},0))); 1871 1872 let IClass = 0b0011; 1873 let Inst{27-24} = 0b1111; 1874 let Inst{22-21} = opcBits; 1875 let Inst{20-16} = base; 1876 let Inst{13} = 0b0; 1877 let Inst{12-7} = offsetBits; 1878 let Inst{6-5} = memOpBits; 1879 let Inst{4-0} = delta; 1880} 1881 1882// multiclass to define MemOp instructions with register operand. 1883multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> { 1884 def _ADD#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add 1885 def _SUB#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub 1886 def _AND#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and 1887 def _OR#NAME#_V4 : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or 1888} 1889 1890// multiclass to define MemOp instructions with immediate Operand. 1891multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> { 1892 def _ADD#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >; 1893 def _SUB#NAME#_V4 : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >; 1894 def _CLRBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =clrbit(", 0b10>; 1895 def _SETBIT#NAME#_V4 : MemOp_ri_base<opc, opcBits, ImmOp, " =setbit(", 0b11>; 1896} 1897 1898multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> { 1899 defm r : MemOp_rr <opc, opcBits, ImmOp>; 1900 defm i : MemOp_ri <opc, opcBits, ImmOp>; 1901} 1902 1903// Define MemOp instructions. 1904let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, 1905validSubTargets =HasV4SubT in { 1906 let opExtentBits = 6, accessSize = ByteAccess in 1907 defm MemOPb : MemOp_base <"memb", 0b00, u6_0Ext>; 1908 1909 let opExtentBits = 7, accessSize = HalfWordAccess in 1910 defm MemOPh : MemOp_base <"memh", 0b01, u6_1Ext>; 1911 1912 let opExtentBits = 8, accessSize = WordAccess in 1913 defm MemOPw : MemOp_base <"memw", 0b10, u6_2Ext>; 1914} 1915 1916//===----------------------------------------------------------------------===// 1917// Multiclass to define 'Def Pats' for ALU operations on the memory 1918// Here value used for the ALU operation is an immediate value. 1919// mem[bh](Rs+#0) += #U5 1920// mem[bh](Rs+#u6) += #U5 1921//===----------------------------------------------------------------------===// 1922 1923multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 1924 InstHexagon MI, SDNode OpNode> { 1925 let AddedComplexity = 180 in 1926 def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend), 1927 IntRegs:$addr), 1928 (MI IntRegs:$addr, #0, u5ImmPred:$addend )>; 1929 1930 let AddedComplexity = 190 in 1931 def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)), 1932 u5ImmPred:$addend), 1933 (add IntRegs:$base, ExtPred:$offset)), 1934 (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>; 1935} 1936 1937multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 1938 InstHexagon addMI, InstHexagon subMI> { 1939 defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>; 1940 defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>; 1941} 1942 1943multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 1944 // Half Word 1945 defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred, 1946 MemOPh_ADDi_V4, MemOPh_SUBi_V4>; 1947 // Byte 1948 defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred, 1949 MemOPb_ADDi_V4, MemOPb_SUBi_V4>; 1950} 1951 1952let Predicates = [HasV4T, UseMEMOP] in { 1953 defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend 1954 defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend 1955 defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend 1956 1957 // Word 1958 defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, MemOPw_ADDi_V4, 1959 MemOPw_SUBi_V4>; 1960} 1961 1962//===----------------------------------------------------------------------===// 1963// multiclass to define 'Def Pats' for ALU operations on the memory. 1964// Here value used for the ALU operation is a negative value. 1965// mem[bh](Rs+#0) += #m5 1966// mem[bh](Rs+#u6) += #m5 1967//===----------------------------------------------------------------------===// 1968 1969multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred, 1970 PatLeaf immPred, ComplexPattern addrPred, 1971 SDNodeXForm xformFunc, InstHexagon MI> { 1972 let AddedComplexity = 190 in 1973 def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend), 1974 IntRegs:$addr), 1975 (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>; 1976 1977 let AddedComplexity = 195 in 1978 def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)), 1979 immPred:$subend), 1980 (add IntRegs:$base, extPred:$offset)), 1981 (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>; 1982} 1983 1984multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 1985 // Half Word 1986 defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred, 1987 ADDRriU6_1, MEMOPIMM_HALF, MemOPh_SUBi_V4>; 1988 // Byte 1989 defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred, 1990 ADDRriU6_0, MEMOPIMM_BYTE, MemOPb_SUBi_V4>; 1991} 1992 1993let Predicates = [HasV4T, UseMEMOP] in { 1994 defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend 1995 defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend 1996 defm : MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend 1997 1998 // Word 1999 defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred, 2000 ADDRriU6_2, MEMOPIMM, MemOPw_SUBi_V4>; 2001} 2002 2003//===----------------------------------------------------------------------===// 2004// Multiclass to define 'def Pats' for bit operations on the memory. 2005// mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2006// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5) 2007//===----------------------------------------------------------------------===// 2008 2009multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred, 2010 PatLeaf extPred, ComplexPattern addrPred, 2011 SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> { 2012 2013 // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5) 2014 let AddedComplexity = 250 in 2015 def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2016 immPred:$bitend), 2017 (add IntRegs:$base, extPred:$offset)), 2018 (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>; 2019 2020 // mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2021 let AddedComplexity = 225 in 2022 def : Pat <(stOp (OpNode (ldOp addrPred:$addr), immPred:$bitend), 2023 addrPred:$addr), 2024 (MI IntRegs:$addr, #0, (xformFunc immPred:$bitend))>; 2025} 2026 2027multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2028 // Byte - clrbit 2029 defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred, 2030 ADDRriU6_0, CLRMEMIMM_BYTE, MemOPb_CLRBITi_V4, and>; 2031 // Byte - setbit 2032 defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred, 2033 ADDRriU6_0, SETMEMIMM_BYTE, MemOPb_SETBITi_V4, or>; 2034 // Half Word - clrbit 2035 defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred, 2036 ADDRriU6_1, CLRMEMIMM_SHORT, MemOPh_CLRBITi_V4, and>; 2037 // Half Word - setbit 2038 defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred, 2039 ADDRriU6_1, SETMEMIMM_SHORT, MemOPh_SETBITi_V4, or>; 2040} 2041 2042let Predicates = [HasV4T, UseMEMOP] in { 2043 // mem[bh](Rs+#0) = [clrbit|setbit](#U5) 2044 // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5) 2045 defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend 2046 defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend 2047 defm : MemOpi_bitExtType<extloadi8, extloadi16>; // any extend 2048 2049 // memw(Rs+#0) = [clrbit|setbit](#U5) 2050 // memw(Rs+#u6:2) = [clrbit|setbit](#U5) 2051 defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2, 2052 CLRMEMIMM, MemOPw_CLRBITi_V4, and>; 2053 defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2, 2054 SETMEMIMM, MemOPw_SETBITi_V4, or>; 2055} 2056 2057//===----------------------------------------------------------------------===// 2058// Multiclass to define 'def Pats' for ALU operations on the memory 2059// where addend is a register. 2060// mem[bhw](Rs+#0) [+-&|]= Rt 2061// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2062//===----------------------------------------------------------------------===// 2063 2064multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred, 2065 PatLeaf extPred, InstHexagon MI, SDNode OpNode> { 2066 let AddedComplexity = 141 in 2067 // mem[bhw](Rs+#0) [+-&|]= Rt 2068 def : Pat <(stOp (OpNode (ldOp addrPred:$addr), (i32 IntRegs:$addend)), 2069 addrPred:$addr), 2070 (MI IntRegs:$addr, #0, (i32 IntRegs:$addend) )>; 2071 2072 // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2073 let AddedComplexity = 150 in 2074 def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2075 (i32 IntRegs:$orend)), 2076 (add IntRegs:$base, extPred:$offset)), 2077 (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>; 2078} 2079 2080multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp, 2081 ComplexPattern addrPred, PatLeaf extPred, 2082 InstHexagon addMI, InstHexagon subMI, 2083 InstHexagon andMI, InstHexagon orMI > { 2084 2085 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>; 2086 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>; 2087 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>; 2088 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI, or>; 2089} 2090 2091multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2092 // Half Word 2093 defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred, 2094 MemOPh_ADDr_V4, MemOPh_SUBr_V4, 2095 MemOPh_ANDr_V4, MemOPh_ORr_V4>; 2096 // Byte 2097 defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred, 2098 MemOPb_ADDr_V4, MemOPb_SUBr_V4, 2099 MemOPb_ANDr_V4, MemOPb_ORr_V4>; 2100} 2101 2102// Define 'def Pats' for MemOps with register addend. 2103let Predicates = [HasV4T, UseMEMOP] in { 2104 // Byte, Half Word 2105 defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend 2106 defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend 2107 defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend 2108 // Word 2109 defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, MemOPw_ADDr_V4, 2110 MemOPw_SUBr_V4, MemOPw_ANDr_V4, MemOPw_ORr_V4 >; 2111} 2112 2113//===----------------------------------------------------------------------===// 2114// XTYPE/PRED + 2115//===----------------------------------------------------------------------===// 2116 2117// Hexagon V4 only supports these flavors of byte/half compare instructions: 2118// EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by 2119// hardware. However, compiler can still implement these patterns through 2120// appropriate patterns combinations based on current implemented patterns. 2121// The implemented patterns are: EQ/GT/GTU. 2122// Missing patterns are: GE/GEU/LT/LTU/LE/LEU. 2123 2124// Following instruction is not being extended as it results into the 2125// incorrect code for negative numbers. 2126// Pd=cmpb.eq(Rs,#u8) 2127 2128// p=!cmp.eq(r1,r2) 2129let isCompare = 1, validSubTargets = HasV4SubT in 2130def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst), 2131 (ins IntRegs:$src1, IntRegs:$src2), 2132 "$dst = !cmp.eq($src1, $src2)", 2133 [(set (i1 PredRegs:$dst), 2134 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>, 2135 Requires<[HasV4T]>; 2136 2137// p=!cmp.eq(r1,#s10) 2138let isCompare = 1, validSubTargets = HasV4SubT in 2139def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst), 2140 (ins IntRegs:$src1, s10Ext:$src2), 2141 "$dst = !cmp.eq($src1, #$src2)", 2142 [(set (i1 PredRegs:$dst), 2143 (setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>, 2144 Requires<[HasV4T]>; 2145 2146// p=!cmp.gt(r1,r2) 2147let isCompare = 1, validSubTargets = HasV4SubT in 2148def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst), 2149 (ins IntRegs:$src1, IntRegs:$src2), 2150 "$dst = !cmp.gt($src1, $src2)", 2151 [(set (i1 PredRegs:$dst), 2152 (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2153 Requires<[HasV4T]>; 2154 2155// p=!cmp.gt(r1,#s10) 2156let isCompare = 1, validSubTargets = HasV4SubT in 2157def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst), 2158 (ins IntRegs:$src1, s10Ext:$src2), 2159 "$dst = !cmp.gt($src1, #$src2)", 2160 [(set (i1 PredRegs:$dst), 2161 (not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>, 2162 Requires<[HasV4T]>; 2163 2164// p=!cmp.gtu(r1,r2) 2165let isCompare = 1, validSubTargets = HasV4SubT in 2166def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst), 2167 (ins IntRegs:$src1, IntRegs:$src2), 2168 "$dst = !cmp.gtu($src1, $src2)", 2169 [(set (i1 PredRegs:$dst), 2170 (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2171 Requires<[HasV4T]>; 2172 2173// p=!cmp.gtu(r1,#u9) 2174let isCompare = 1, validSubTargets = HasV4SubT in 2175def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst), 2176 (ins IntRegs:$src1, u9Ext:$src2), 2177 "$dst = !cmp.gtu($src1, #$src2)", 2178 [(set (i1 PredRegs:$dst), 2179 (not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>, 2180 Requires<[HasV4T]>; 2181 2182let isCompare = 1, validSubTargets = HasV4SubT in 2183def CMPbEQri_V4 : MInst<(outs PredRegs:$dst), 2184 (ins IntRegs:$src1, u8Imm:$src2), 2185 "$dst = cmpb.eq($src1, #$src2)", 2186 [(set (i1 PredRegs:$dst), 2187 (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>, 2188 Requires<[HasV4T]>; 2189 2190def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)), 2191 bb:$offset), 2192 (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2), 2193 bb:$offset)>, 2194 Requires<[HasV4T]>; 2195 2196// Pd=cmpb.eq(Rs,Rt) 2197let isCompare = 1, validSubTargets = HasV4SubT in 2198def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst), 2199 (ins IntRegs:$src1, IntRegs:$src2), 2200 "$dst = cmpb.eq($src1, $src2)", 2201 [(set (i1 PredRegs:$dst), 2202 (seteq (and (xor (i32 IntRegs:$src1), 2203 (i32 IntRegs:$src2)), 255), 0))]>, 2204 Requires<[HasV4T]>; 2205 2206// Pd=cmpb.eq(Rs,Rt) 2207let isCompare = 1, validSubTargets = HasV4SubT in 2208def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst), 2209 (ins IntRegs:$src1, IntRegs:$src2), 2210 "$dst = cmpb.eq($src1, $src2)", 2211 [(set (i1 PredRegs:$dst), 2212 (seteq (shl (i32 IntRegs:$src1), (i32 24)), 2213 (shl (i32 IntRegs:$src2), (i32 24))))]>, 2214 Requires<[HasV4T]>; 2215 2216// Pd=cmpb.gt(Rs,Rt) 2217let isCompare = 1, validSubTargets = HasV4SubT in 2218def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst), 2219 (ins IntRegs:$src1, IntRegs:$src2), 2220 "$dst = cmpb.gt($src1, $src2)", 2221 [(set (i1 PredRegs:$dst), 2222 (setgt (shl (i32 IntRegs:$src1), (i32 24)), 2223 (shl (i32 IntRegs:$src2), (i32 24))))]>, 2224 Requires<[HasV4T]>; 2225 2226// Pd=cmpb.gtu(Rs,#u7) 2227let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2228isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in 2229def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst), 2230 (ins IntRegs:$src1, u7Ext:$src2), 2231 "$dst = cmpb.gtu($src1, #$src2)", 2232 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 2233 u7ExtPred:$src2))]>, 2234 Requires<[HasV4T]>, ImmRegRel; 2235 2236// SDNode for converting immediate C to C-1. 2237def DEC_CONST_BYTE : SDNodeXForm<imm, [{ 2238 // Return the byte immediate const-1 as an SDNode. 2239 int32_t imm = N->getSExtValue(); 2240 return XformU7ToU7M1Imm(imm); 2241}]>; 2242 2243// For the sequence 2244// zext( seteq ( and(Rs, 255), u8)) 2245// Generate 2246// Pd=cmpb.eq(Rs, #u8) 2247// if (Pd.new) Rd=#1 2248// if (!Pd.new) Rd=#0 2249def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)), 2250 u8ExtPred:$u8)))), 2251 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2252 (u8ExtPred:$u8))), 2253 1, 0))>, 2254 Requires<[HasV4T]>; 2255 2256// For the sequence 2257// zext( setne ( and(Rs, 255), u8)) 2258// Generate 2259// Pd=cmpb.eq(Rs, #u8) 2260// if (Pd.new) Rd=#0 2261// if (!Pd.new) Rd=#1 2262def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)), 2263 u8ExtPred:$u8)))), 2264 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2265 (u8ExtPred:$u8))), 2266 0, 1))>, 2267 Requires<[HasV4T]>; 2268 2269// For the sequence 2270// zext( seteq (Rs, and(Rt, 255))) 2271// Generate 2272// Pd=cmpb.eq(Rs, Rt) 2273// if (Pd.new) Rd=#1 2274// if (!Pd.new) Rd=#0 2275def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt), 2276 (i32 (and (i32 IntRegs:$Rs), 255)))))), 2277 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2278 (i32 IntRegs:$Rt))), 2279 1, 0))>, 2280 Requires<[HasV4T]>; 2281 2282// For the sequence 2283// zext( setne (Rs, and(Rt, 255))) 2284// Generate 2285// Pd=cmpb.eq(Rs, Rt) 2286// if (Pd.new) Rd=#0 2287// if (!Pd.new) Rd=#1 2288def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt), 2289 (i32 (and (i32 IntRegs:$Rs), 255)))))), 2290 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2291 (i32 IntRegs:$Rt))), 2292 0, 1))>, 2293 Requires<[HasV4T]>; 2294 2295// For the sequence 2296// zext( setugt ( and(Rs, 255), u8)) 2297// Generate 2298// Pd=cmpb.gtu(Rs, #u8) 2299// if (Pd.new) Rd=#1 2300// if (!Pd.new) Rd=#0 2301def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)), 2302 u8ExtPred:$u8)))), 2303 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2304 (u8ExtPred:$u8))), 2305 1, 0))>, 2306 Requires<[HasV4T]>; 2307 2308// For the sequence 2309// zext( setugt ( and(Rs, 254), u8)) 2310// Generate 2311// Pd=cmpb.gtu(Rs, #u8) 2312// if (Pd.new) Rd=#1 2313// if (!Pd.new) Rd=#0 2314def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)), 2315 u8ExtPred:$u8)))), 2316 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2317 (u8ExtPred:$u8))), 2318 1, 0))>, 2319 Requires<[HasV4T]>; 2320 2321// For the sequence 2322// zext( setult ( Rs, Rt)) 2323// Generate 2324// Pd=cmp.ltu(Rs, Rt) 2325// if (Pd.new) Rd=#1 2326// if (!Pd.new) Rd=#0 2327// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2328def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2329 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt), 2330 (i32 IntRegs:$Rs))), 2331 1, 0))>, 2332 Requires<[HasV4T]>; 2333 2334// For the sequence 2335// zext( setlt ( Rs, Rt)) 2336// Generate 2337// Pd=cmp.lt(Rs, Rt) 2338// if (Pd.new) Rd=#1 2339// if (!Pd.new) Rd=#0 2340// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2341def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2342 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt), 2343 (i32 IntRegs:$Rs))), 2344 1, 0))>, 2345 Requires<[HasV4T]>; 2346 2347// For the sequence 2348// zext( setugt ( Rs, Rt)) 2349// Generate 2350// Pd=cmp.gtu(Rs, Rt) 2351// if (Pd.new) Rd=#1 2352// if (!Pd.new) Rd=#0 2353def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2354 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs), 2355 (i32 IntRegs:$Rt))), 2356 1, 0))>, 2357 Requires<[HasV4T]>; 2358 2359// This pattern interefers with coremark performance, not implementing at this 2360// time. 2361// For the sequence 2362// zext( setgt ( Rs, Rt)) 2363// Generate 2364// Pd=cmp.gt(Rs, Rt) 2365// if (Pd.new) Rd=#1 2366// if (!Pd.new) Rd=#0 2367 2368// For the sequence 2369// zext( setuge ( Rs, Rt)) 2370// Generate 2371// Pd=cmp.ltu(Rs, Rt) 2372// if (Pd.new) Rd=#0 2373// if (!Pd.new) Rd=#1 2374// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2375def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2376 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rt), 2377 (i32 IntRegs:$Rs))), 2378 0, 1))>, 2379 Requires<[HasV4T]>; 2380 2381// For the sequence 2382// zext( setge ( Rs, Rt)) 2383// Generate 2384// Pd=cmp.lt(Rs, Rt) 2385// if (Pd.new) Rd=#0 2386// if (!Pd.new) Rd=#1 2387// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2388def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2389 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rt), 2390 (i32 IntRegs:$Rs))), 2391 0, 1))>, 2392 Requires<[HasV4T]>; 2393 2394// For the sequence 2395// zext( setule ( Rs, Rt)) 2396// Generate 2397// Pd=cmp.gtu(Rs, Rt) 2398// if (Pd.new) Rd=#0 2399// if (!Pd.new) Rd=#1 2400def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2401 (i32 (TFR_condset_ii (i1 (CMPGTUrr (i32 IntRegs:$Rs), 2402 (i32 IntRegs:$Rt))), 2403 0, 1))>, 2404 Requires<[HasV4T]>; 2405 2406// For the sequence 2407// zext( setle ( Rs, Rt)) 2408// Generate 2409// Pd=cmp.gt(Rs, Rt) 2410// if (Pd.new) Rd=#0 2411// if (!Pd.new) Rd=#1 2412def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2413 (i32 (TFR_condset_ii (i1 (CMPGTrr (i32 IntRegs:$Rs), 2414 (i32 IntRegs:$Rt))), 2415 0, 1))>, 2416 Requires<[HasV4T]>; 2417 2418// For the sequence 2419// zext( setult ( and(Rs, 255), u8)) 2420// Use the isdigit transformation below 2421 2422// Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)' 2423// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;. 2424// The isdigit transformation relies on two 'clever' aspects: 2425// 1) The data type is unsigned which allows us to eliminate a zero test after 2426// biasing the expression by 48. We are depending on the representation of 2427// the unsigned types, and semantics. 2428// 2) The front end has converted <= 9 into < 10 on entry to LLVM 2429// 2430// For the C code: 2431// retval = ((c>='0') & (c<='9')) ? 1 : 0; 2432// The code is transformed upstream of llvm into 2433// retval = (c-48) < 10 ? 1 : 0; 2434let AddedComplexity = 139 in 2435def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)), 2436 u7StrictPosImmPred:$src2)))), 2437 (i32 (MUX_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1), 2438 (DEC_CONST_BYTE u7StrictPosImmPred:$src2))), 2439 0, 1))>, 2440 Requires<[HasV4T]>; 2441 2442// Pd=cmpb.gtu(Rs,Rt) 2443let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", 2444InputType = "reg" in 2445def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst), 2446 (ins IntRegs:$src1, IntRegs:$src2), 2447 "$dst = cmpb.gtu($src1, $src2)", 2448 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 2449 (and (i32 IntRegs:$src2), 255)))]>, 2450 Requires<[HasV4T]>, ImmRegRel; 2451 2452// Following instruction is not being extended as it results into the incorrect 2453// code for negative numbers. 2454 2455// Signed half compare(.eq) ri. 2456// Pd=cmph.eq(Rs,#s8) 2457let isCompare = 1, validSubTargets = HasV4SubT in 2458def CMPhEQri_V4 : MInst<(outs PredRegs:$dst), 2459 (ins IntRegs:$src1, s8Imm:$src2), 2460 "$dst = cmph.eq($src1, #$src2)", 2461 [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535), 2462 s8ImmPred:$src2))]>, 2463 Requires<[HasV4T]>; 2464 2465// Signed half compare(.eq) rr. 2466// Case 1: xor + and, then compare: 2467// r0=xor(r0,r1) 2468// r0=and(r0,#0xffff) 2469// p0=cmp.eq(r0,#0) 2470// Pd=cmph.eq(Rs,Rt) 2471let isCompare = 1, validSubTargets = HasV4SubT in 2472def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst), 2473 (ins IntRegs:$src1, IntRegs:$src2), 2474 "$dst = cmph.eq($src1, $src2)", 2475 [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1), 2476 (i32 IntRegs:$src2)), 2477 65535), 0))]>, 2478 Requires<[HasV4T]>; 2479 2480// Signed half compare(.eq) rr. 2481// Case 2: shift left 16 bits then compare: 2482// r0=asl(r0,16) 2483// r1=asl(r1,16) 2484// p0=cmp.eq(r0,r1) 2485// Pd=cmph.eq(Rs,Rt) 2486let isCompare = 1, validSubTargets = HasV4SubT in 2487def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst), 2488 (ins IntRegs:$src1, IntRegs:$src2), 2489 "$dst = cmph.eq($src1, $src2)", 2490 [(set (i1 PredRegs:$dst), 2491 (seteq (shl (i32 IntRegs:$src1), (i32 16)), 2492 (shl (i32 IntRegs:$src2), (i32 16))))]>, 2493 Requires<[HasV4T]>; 2494 2495/* Incorrect Pattern -- immediate should be right shifted before being 2496used in the cmph.gt instruction. 2497// Signed half compare(.gt) ri. 2498// Pd=cmph.gt(Rs,#s8) 2499 2500let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 2501isCompare = 1, validSubTargets = HasV4SubT in 2502def CMPhGTri_V4 : MInst<(outs PredRegs:$dst), 2503 (ins IntRegs:$src1, s8Ext:$src2), 2504 "$dst = cmph.gt($src1, #$src2)", 2505 [(set (i1 PredRegs:$dst), 2506 (setgt (shl (i32 IntRegs:$src1), (i32 16)), 2507 s8ExtPred:$src2))]>, 2508 Requires<[HasV4T]>; 2509*/ 2510 2511// Signed half compare(.gt) rr. 2512// Pd=cmph.gt(Rs,Rt) 2513let isCompare = 1, validSubTargets = HasV4SubT in 2514def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst), 2515 (ins IntRegs:$src1, IntRegs:$src2), 2516 "$dst = cmph.gt($src1, $src2)", 2517 [(set (i1 PredRegs:$dst), 2518 (setgt (shl (i32 IntRegs:$src1), (i32 16)), 2519 (shl (i32 IntRegs:$src2), (i32 16))))]>, 2520 Requires<[HasV4T]>; 2521 2522// Unsigned half compare rr (.gtu). 2523// Pd=cmph.gtu(Rs,Rt) 2524let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2525InputType = "reg" in 2526def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst), 2527 (ins IntRegs:$src1, IntRegs:$src2), 2528 "$dst = cmph.gtu($src1, $src2)", 2529 [(set (i1 PredRegs:$dst), 2530 (setugt (and (i32 IntRegs:$src1), 65535), 2531 (and (i32 IntRegs:$src2), 65535)))]>, 2532 Requires<[HasV4T]>, ImmRegRel; 2533 2534// Unsigned half compare ri (.gtu). 2535// Pd=cmph.gtu(Rs,#u7) 2536let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2537isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2538InputType = "imm" in 2539def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst), 2540 (ins IntRegs:$src1, u7Ext:$src2), 2541 "$dst = cmph.gtu($src1, #$src2)", 2542 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535), 2543 u7ExtPred:$src2))]>, 2544 Requires<[HasV4T]>, ImmRegRel; 2545 2546let validSubTargets = HasV4SubT in 2547def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 2548 "$dst = !tstbit($src1, $src2)", 2549 [(set (i1 PredRegs:$dst), 2550 (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>, 2551 Requires<[HasV4T]>; 2552 2553let validSubTargets = HasV4SubT in 2554def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 2555 "$dst = !tstbit($src1, $src2)", 2556 [(set (i1 PredRegs:$dst), 2557 (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>, 2558 Requires<[HasV4T]>; 2559 2560//===----------------------------------------------------------------------===// 2561// XTYPE/PRED - 2562//===----------------------------------------------------------------------===// 2563 2564//Deallocate frame and return. 2565// dealloc_return 2566let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, 2567 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in { 2568let validSubTargets = HasV4SubT in 2569 def DEALLOC_RET_V4 : LD0Inst<(outs), (ins), 2570 "dealloc_return", 2571 []>, 2572 Requires<[HasV4T]>; 2573} 2574 2575// Restore registers and dealloc return function call. 2576let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, 2577 Defs = [R29, R30, R31, PC] in { 2578let validSubTargets = HasV4SubT in 2579 def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs), 2580 (ins calltarget:$dst), 2581 "jump $dst", 2582 []>, 2583 Requires<[HasV4T]>; 2584} 2585 2586// Restore registers and dealloc frame before a tail call. 2587let isCall = 1, isBarrier = 1, 2588 Defs = [R29, R30, R31, PC] in { 2589let validSubTargets = HasV4SubT in 2590 def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs), 2591 (ins calltarget:$dst), 2592 "call $dst", 2593 []>, 2594 Requires<[HasV4T]>; 2595} 2596 2597// Save registers function call. 2598let isCall = 1, isBarrier = 1, 2599 Uses = [R29, R31] in { 2600 def SAVE_REGISTERS_CALL_V4 : JInst<(outs), 2601 (ins calltarget:$dst), 2602 "call $dst // Save_calle_saved_registers", 2603 []>, 2604 Requires<[HasV4T]>; 2605} 2606 2607// if (Ps) dealloc_return 2608let isReturn = 1, isTerminator = 1, 2609 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2610 isPredicated = 1 in { 2611let validSubTargets = HasV4SubT in 2612 def DEALLOC_RET_cPt_V4 : LD0Inst<(outs), 2613 (ins PredRegs:$src1), 2614 "if ($src1) dealloc_return", 2615 []>, 2616 Requires<[HasV4T]>; 2617} 2618 2619// if (!Ps) dealloc_return 2620let isReturn = 1, isTerminator = 1, 2621 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2622 isPredicated = 1, isPredicatedFalse = 1 in { 2623let validSubTargets = HasV4SubT in 2624 def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2625 "if (!$src1) dealloc_return", 2626 []>, 2627 Requires<[HasV4T]>; 2628} 2629 2630// if (Ps.new) dealloc_return:nt 2631let isReturn = 1, isTerminator = 1, 2632 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2633 isPredicated = 1 in { 2634let validSubTargets = HasV4SubT in 2635 def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2636 "if ($src1.new) dealloc_return:nt", 2637 []>, 2638 Requires<[HasV4T]>; 2639} 2640 2641// if (!Ps.new) dealloc_return:nt 2642let isReturn = 1, isTerminator = 1, 2643 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2644 isPredicated = 1, isPredicatedFalse = 1 in { 2645let validSubTargets = HasV4SubT in 2646 def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2647 "if (!$src1.new) dealloc_return:nt", 2648 []>, 2649 Requires<[HasV4T]>; 2650} 2651 2652// if (Ps.new) dealloc_return:t 2653let isReturn = 1, isTerminator = 1, 2654 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2655 isPredicated = 1 in { 2656let validSubTargets = HasV4SubT in 2657 def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2658 "if ($src1.new) dealloc_return:t", 2659 []>, 2660 Requires<[HasV4T]>; 2661} 2662 2663// if (!Ps.new) dealloc_return:nt 2664let isReturn = 1, isTerminator = 1, 2665 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2666 isPredicated = 1, isPredicatedFalse = 1 in { 2667let validSubTargets = HasV4SubT in 2668 def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1), 2669 "if (!$src1.new) dealloc_return:t", 2670 []>, 2671 Requires<[HasV4T]>; 2672} 2673 2674// Load/Store with absolute addressing mode 2675// memw(#u6)=Rt 2676 2677multiclass ST_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot, 2678 bit isPredNew> { 2679 let isPredicatedNew = isPredNew in 2680 def NAME#_V4 : STInst2<(outs), 2681 (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2), 2682 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2683 ") ")#mnemonic#"(##$absaddr) = $src2", 2684 []>, 2685 Requires<[HasV4T]>; 2686} 2687 2688multiclass ST_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 2689 let isPredicatedFalse = PredNot in { 2690 defm _c#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 0>; 2691 // Predicate new 2692 defm _cdn#NAME : ST_Abs_Predbase<mnemonic, RC, PredNot, 1>; 2693 } 2694} 2695 2696let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in 2697multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC> { 2698 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2699 let opExtendable = 0, isPredicable = 1 in 2700 def NAME#_V4 : STInst2<(outs), 2701 (ins u0AlwaysExt:$absaddr, RC:$src), 2702 mnemonic#"(##$absaddr) = $src", 2703 []>, 2704 Requires<[HasV4T]>; 2705 2706 let opExtendable = 1, isPredicated = 1 in { 2707 defm Pt : ST_Abs_Pred<mnemonic, RC, 0>; 2708 defm NotPt : ST_Abs_Pred<mnemonic, RC, 1>; 2709 } 2710 } 2711} 2712 2713multiclass ST_Abs_Predbase_nv<string mnemonic, RegisterClass RC, bit isNot, 2714 bit isPredNew> { 2715 let isPredicatedNew = isPredNew in 2716 def NAME#_nv_V4 : NVInst_V4<(outs), 2717 (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2), 2718 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2719 ") ")#mnemonic#"(##$absaddr) = $src2.new", 2720 []>, 2721 Requires<[HasV4T]>; 2722} 2723 2724multiclass ST_Abs_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 2725 let isPredicatedFalse = PredNot in { 2726 defm _c#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 0>; 2727 // Predicate new 2728 defm _cdn#NAME : ST_Abs_Predbase_nv<mnemonic, RC, PredNot, 1>; 2729 } 2730} 2731 2732let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in 2733multiclass ST_Abs_nv<string mnemonic, string CextOp, RegisterClass RC> { 2734 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2735 let opExtendable = 0, isPredicable = 1 in 2736 def NAME#_nv_V4 : NVInst_V4<(outs), 2737 (ins u0AlwaysExt:$absaddr, RC:$src), 2738 mnemonic#"(##$absaddr) = $src.new", 2739 []>, 2740 Requires<[HasV4T]>; 2741 2742 let opExtendable = 1, isPredicated = 1 in { 2743 defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>; 2744 defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>; 2745 } 2746 } 2747} 2748 2749let addrMode = Absolute in { 2750 let accessSize = ByteAccess in 2751 defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>, 2752 ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel; 2753 2754 let accessSize = HalfWordAccess in 2755 defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>, 2756 ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel; 2757 2758 let accessSize = WordAccess in 2759 defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>, 2760 ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel; 2761 2762 let accessSize = DoubleWordAccess, isNVStorable = 0 in 2763 defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel; 2764} 2765 2766let Predicates = [HasV4T], AddedComplexity = 30 in { 2767def : Pat<(truncstorei8 (i32 IntRegs:$src1), 2768 (HexagonCONST32 tglobaladdr:$absaddr)), 2769 (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2770 2771def : Pat<(truncstorei16 (i32 IntRegs:$src1), 2772 (HexagonCONST32 tglobaladdr:$absaddr)), 2773 (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2774 2775def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), 2776 (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2777 2778def : Pat<(store (i64 DoubleRegs:$src1), 2779 (HexagonCONST32 tglobaladdr:$absaddr)), 2780 (STrid_abs_V4 tglobaladdr: $absaddr, DoubleRegs: $src1)>; 2781} 2782 2783//===----------------------------------------------------------------------===// 2784// multiclass for store instructions with GP-relative addressing mode. 2785// mem[bhwd](#global)=Rt 2786// if ([!]Pv[.new]) mem[bhwd](##global) = Rt 2787//===----------------------------------------------------------------------===// 2788let mayStore = 1, isNVStorable = 1 in 2789multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> { 2790 let BaseOpcode = BaseOp, isPredicable = 1 in 2791 def NAME#_V4 : STInst2<(outs), 2792 (ins globaladdress:$global, RC:$src), 2793 mnemonic#"(#$global) = $src", 2794 []>; 2795 2796 // When GP-relative instructions are predicated, their addressing mode is 2797 // changed to absolute and they are always constant extended. 2798 let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1, 2799 isPredicated = 1 in { 2800 defm Pt : ST_Abs_Pred <mnemonic, RC, 0>; 2801 defm NotPt : ST_Abs_Pred <mnemonic, RC, 1>; 2802 } 2803} 2804 2805let mayStore = 1, isNVStore = 1 in 2806multiclass ST_GP_nv<string mnemonic, string BaseOp, RegisterClass RC> { 2807 let BaseOpcode = BaseOp, isPredicable = 1 in 2808 def NAME#_nv_V4 : NVInst_V4<(outs), 2809 (ins u0AlwaysExt:$global, RC:$src), 2810 mnemonic#"(#$global) = $src.new", 2811 []>, 2812 Requires<[HasV4T]>; 2813 2814 // When GP-relative instructions are predicated, their addressing mode is 2815 // changed to absolute and they are always constant extended. 2816 let BaseOpcode = BaseOp, isExtended = 1, opExtendable = 1, 2817 isPredicated = 1 in { 2818 defm Pt : ST_Abs_Pred_nv<mnemonic, RC, 0>; 2819 defm NotPt : ST_Abs_Pred_nv<mnemonic, RC, 1>; 2820 } 2821} 2822 2823let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in { 2824 let isNVStorable = 0 in 2825 defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel; 2826 2827 defm STb_GP : ST_GP<"memb", "STb_GP", IntRegs>, 2828 ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel; 2829 defm STh_GP : ST_GP<"memh", "STh_GP", IntRegs>, 2830 ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel; 2831 defm STw_GP : ST_GP<"memw", "STw_GP", IntRegs>, 2832 ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel; 2833} 2834 2835// 64 bit atomic store 2836def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global), 2837 (i64 DoubleRegs:$src1)), 2838 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>, 2839 Requires<[HasV4T]>; 2840 2841// Map from store(globaladdress) -> memd(#foo) 2842let AddedComplexity = 100 in 2843def : Pat <(store (i64 DoubleRegs:$src1), 2844 (HexagonCONST32_GP tglobaladdr:$global)), 2845 (STd_GP_V4 tglobaladdr:$global, (i64 DoubleRegs:$src1))>; 2846 2847// 8 bit atomic store 2848def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global), 2849 (i32 IntRegs:$src1)), 2850 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2851 2852// Map from store(globaladdress) -> memb(#foo) 2853let AddedComplexity = 100 in 2854def : Pat<(truncstorei8 (i32 IntRegs:$src1), 2855 (HexagonCONST32_GP tglobaladdr:$global)), 2856 (STb_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2857 2858// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1" 2859// to "r0 = 1; memw(#foo) = r0" 2860let AddedComplexity = 100 in 2861def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), 2862 (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>; 2863 2864def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global), 2865 (i32 IntRegs:$src1)), 2866 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2867 2868// Map from store(globaladdress) -> memh(#foo) 2869let AddedComplexity = 100 in 2870def : Pat<(truncstorei16 (i32 IntRegs:$src1), 2871 (HexagonCONST32_GP tglobaladdr:$global)), 2872 (STh_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2873 2874// 32 bit atomic store 2875def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global), 2876 (i32 IntRegs:$src1)), 2877 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2878 2879// Map from store(globaladdress) -> memw(#foo) 2880let AddedComplexity = 100 in 2881def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)), 2882 (STw_GP_V4 tglobaladdr:$global, (i32 IntRegs:$src1))>; 2883 2884//===----------------------------------------------------------------------===// 2885// Multiclass for the load instructions with absolute addressing mode. 2886//===----------------------------------------------------------------------===// 2887multiclass LD_Abs_Predbase<string mnemonic, RegisterClass RC, bit isNot, 2888 bit isPredNew> { 2889 let isPredicatedNew = isPredNew in 2890 def NAME : LDInst2<(outs RC:$dst), 2891 (ins PredRegs:$src1, u0AlwaysExt:$absaddr), 2892 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 2893 ") ")#"$dst = "#mnemonic#"(##$absaddr)", 2894 []>, 2895 Requires<[HasV4T]>; 2896} 2897 2898multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 2899 let isPredicatedFalse = PredNot in { 2900 defm _c#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 0>; 2901 // Predicate new 2902 defm _cdn#NAME : LD_Abs_Predbase<mnemonic, RC, PredNot, 1>; 2903 } 2904} 2905 2906let isExtended = 1, neverHasSideEffects = 1 in 2907multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC> { 2908 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 2909 let opExtendable = 1, isPredicable = 1 in 2910 def NAME#_V4 : LDInst2<(outs RC:$dst), 2911 (ins u0AlwaysExt:$absaddr), 2912 "$dst = "#mnemonic#"(##$absaddr)", 2913 []>, 2914 Requires<[HasV4T]>; 2915 2916 let opExtendable = 2, isPredicated = 1 in { 2917 defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>; 2918 defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>; 2919 } 2920 } 2921} 2922 2923let addrMode = Absolute in { 2924 let accessSize = ByteAccess in { 2925 defm LDrib_abs : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel; 2926 defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel; 2927 } 2928 let accessSize = HalfWordAccess in { 2929 defm LDrih_abs : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel; 2930 defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel; 2931 } 2932 let accessSize = WordAccess in 2933 defm LDriw_abs : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel; 2934 2935 let accessSize = DoubleWordAccess in 2936 defm LDrid_abs : LD_Abs<"memd", "LDrid", DoubleRegs>, AddrModeRel; 2937} 2938 2939let Predicates = [HasV4T], AddedComplexity = 30 in { 2940def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))), 2941 (LDriw_abs_V4 tglobaladdr: $absaddr)>; 2942 2943def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2944 (LDrib_abs_V4 tglobaladdr:$absaddr)>; 2945 2946def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2947 (LDriub_abs_V4 tglobaladdr:$absaddr)>; 2948 2949def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 2950 (LDrih_abs_V4 tglobaladdr:$absaddr)>; 2951 2952def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 2953 (LDriuh_abs_V4 tglobaladdr:$absaddr)>; 2954} 2955 2956//===----------------------------------------------------------------------===// 2957// multiclass for load instructions with GP-relative addressing mode. 2958// Rx=mem[bhwd](##global) 2959// if ([!]Pv[.new]) Rx=mem[bhwd](##global) 2960//===----------------------------------------------------------------------===// 2961let neverHasSideEffects = 1, validSubTargets = HasV4SubT in 2962multiclass LD_GP<string mnemonic, string BaseOp, RegisterClass RC> { 2963 let BaseOpcode = BaseOp in { 2964 let isPredicable = 1 in 2965 def NAME#_V4 : LDInst2<(outs RC:$dst), 2966 (ins globaladdress:$global), 2967 "$dst = "#mnemonic#"(#$global)", 2968 []>; 2969 2970 let isExtended = 1, opExtendable = 2, isPredicated = 1 in { 2971 defm Pt_V4 : LD_Abs_Pred<mnemonic, RC, 0>; 2972 defm NotPt_V4 : LD_Abs_Pred<mnemonic, RC, 1>; 2973 } 2974 } 2975} 2976 2977defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel; 2978defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel; 2979defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel; 2980defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel; 2981defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel; 2982defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel; 2983 2984def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)), 2985 (i64 (LDd_GP_V4 tglobaladdr:$global))>; 2986 2987def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)), 2988 (i32 (LDw_GP_V4 tglobaladdr:$global))>; 2989 2990def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)), 2991 (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 2992 2993def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)), 2994 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 2995 2996// Map from load(globaladdress) -> memw(#foo + 0) 2997let AddedComplexity = 100 in 2998def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))), 2999 (i64 (LDd_GP_V4 tglobaladdr:$global))>; 3000 3001// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd 3002let AddedComplexity = 100 in 3003def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))), 3004 (i1 (TFR_PdRs (i32 (LDb_GP_V4 tglobaladdr:$global))))>; 3005 3006// When the Interprocedural Global Variable optimizer realizes that a certain 3007// global variable takes only two constant values, it shrinks the global to 3008// a boolean. Catch those loads here in the following 3 patterns. 3009let AddedComplexity = 100 in 3010def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3011 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3012 3013let AddedComplexity = 100 in 3014def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3015 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3016 3017// Map from load(globaladdress) -> memb(#foo) 3018let AddedComplexity = 100 in 3019def : Pat <(i32 (extloadi8 (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 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3025 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3026 3027let AddedComplexity = 100 in 3028def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3029 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3030 3031// Map from load(globaladdress) -> memub(#foo) 3032let AddedComplexity = 100 in 3033def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3034 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3035 3036// Map from load(globaladdress) -> memh(#foo) 3037let AddedComplexity = 100 in 3038def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3039 (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3040 3041// Map from load(globaladdress) -> memh(#foo) 3042let AddedComplexity = 100 in 3043def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3044 (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3045 3046// Map from load(globaladdress) -> memuh(#foo) 3047let AddedComplexity = 100 in 3048def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3049 (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 3050 3051// Map from load(globaladdress) -> memw(#foo) 3052let AddedComplexity = 100 in 3053def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), 3054 (i32 (LDw_GP_V4 tglobaladdr:$global))>; 3055 3056 3057// Transfer global address into a register 3058let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1, 3059isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in 3060def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), 3061 "$dst = #$src1", 3062 [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>, 3063 Requires<[HasV4T]>; 3064 3065// Transfer a block address into a register 3066def : Pat<(HexagonCONST32_GP tblockaddress:$src1), 3067 (TFRI_V4 tblockaddress:$src1)>, 3068 Requires<[HasV4T]>; 3069 3070let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3071neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3072def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3073 (ins PredRegs:$src1, s16Ext:$src2), 3074 "if($src1) $dst = #$src2", 3075 []>, 3076 Requires<[HasV4T]>; 3077 3078let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3079neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3080def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3081 (ins PredRegs:$src1, s16Ext:$src2), 3082 "if(!$src1) $dst = #$src2", 3083 []>, 3084 Requires<[HasV4T]>; 3085 3086let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3087neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3088def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3089 (ins PredRegs:$src1, s16Ext:$src2), 3090 "if($src1.new) $dst = #$src2", 3091 []>, 3092 Requires<[HasV4T]>; 3093 3094let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3095neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3096def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3097 (ins PredRegs:$src1, s16Ext:$src2), 3098 "if(!$src1.new) $dst = #$src2", 3099 []>, 3100 Requires<[HasV4T]>; 3101 3102let AddedComplexity = 50, Predicates = [HasV4T] in 3103def : Pat<(HexagonCONST32_GP tglobaladdr:$src1), 3104 (TFRI_V4 tglobaladdr:$src1)>, 3105 Requires<[HasV4T]>; 3106 3107 3108// Load - Indirect with long offset: These instructions take global address 3109// as an operand 3110let isExtended = 1, opExtendable = 3, AddedComplexity = 40, 3111validSubTargets = HasV4SubT in 3112def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst), 3113 (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3114 "$dst=memd($src1<<#$src2+##$offset)", 3115 [(set (i64 DoubleRegs:$dst), 3116 (load (add (shl IntRegs:$src1, u2ImmPred:$src2), 3117 (HexagonCONST32 tglobaladdr:$offset))))]>, 3118 Requires<[HasV4T]>; 3119 3120let AddedComplexity = 40 in 3121multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> { 3122let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in 3123 def _lo_V4 : LDInst<(outs IntRegs:$dst), 3124 (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3125 !strconcat("$dst = ", 3126 !strconcat(OpcStr, "($src1<<#$src2+##$offset)")), 3127 [(set IntRegs:$dst, 3128 (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2), 3129 (HexagonCONST32 tglobaladdr:$offset)))))]>, 3130 Requires<[HasV4T]>; 3131} 3132 3133defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>; 3134defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>; 3135defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>; 3136defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>; 3137defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>; 3138defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>; 3139defm LDriw_ind : LD_indirect_lo<"memw", load>; 3140 3141let AddedComplexity = 40 in 3142def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 3143 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3144 (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3145 Requires<[HasV4T]>; 3146 3147let AddedComplexity = 40 in 3148def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 3149 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3150 (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3151 Requires<[HasV4T]>; 3152 3153let Predicates = [HasV4T], AddedComplexity = 30 in { 3154def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3155 (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3156 3157def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3158 (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3159 3160def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3161 (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3162} 3163 3164let Predicates = [HasV4T], AddedComplexity = 30 in { 3165def : Pat<(i32 (load u0AlwaysExtPred:$src)), 3166 (LDriw_abs_V4 u0AlwaysExtPred:$src)>; 3167 3168def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)), 3169 (LDrib_abs_V4 u0AlwaysExtPred:$src)>; 3170 3171def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)), 3172 (LDriub_abs_V4 u0AlwaysExtPred:$src)>; 3173 3174def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)), 3175 (LDrih_abs_V4 u0AlwaysExtPred:$src)>; 3176 3177def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)), 3178 (LDriuh_abs_V4 u0AlwaysExtPred:$src)>; 3179} 3180 3181// Indexed store word - global address. 3182// memw(Rs+#u6:2)=#S8 3183let AddedComplexity = 10 in 3184def STriw_offset_ext_V4 : STInst<(outs), 3185 (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3), 3186 "memw($src1+#$src2) = ##$src3", 3187 [(store (HexagonCONST32 tglobaladdr:$src3), 3188 (add IntRegs:$src1, u6_2ImmPred:$src2))]>, 3189 Requires<[HasV4T]>; 3190 3191def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))), 3192 (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>, 3193 Requires<[HasV4T]>; 3194 3195def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))), 3196 (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>, 3197 Requires<[HasV4T]>; 3198 3199 3200// i8 -> i64 loads 3201// We need a complexity of 120 here to overide preceeding handling of 3202// zextloadi8. 3203let Predicates = [HasV4T], AddedComplexity = 120 in { 3204def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3205 (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>; 3206 3207def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3208 (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>; 3209 3210def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3211 (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>; 3212 3213def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)), 3214 (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; 3215 3216def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)), 3217 (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>; 3218 3219def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)), 3220 (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; 3221} 3222// i16 -> i64 loads 3223// We need a complexity of 120 here to overide preceeding handling of 3224// zextloadi16. 3225let AddedComplexity = 120 in { 3226def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3227 (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>, 3228 Requires<[HasV4T]>; 3229 3230def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3231 (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>, 3232 Requires<[HasV4T]>; 3233 3234def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3235 (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>, 3236 Requires<[HasV4T]>; 3237 3238def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)), 3239 (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, 3240 Requires<[HasV4T]>; 3241 3242def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)), 3243 (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>, 3244 Requires<[HasV4T]>; 3245 3246def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)), 3247 (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, 3248 Requires<[HasV4T]>; 3249} 3250// i32->i64 loads 3251// We need a complexity of 120 here to overide preceeding handling of 3252// zextloadi32. 3253let AddedComplexity = 120 in { 3254def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3255 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3256 Requires<[HasV4T]>; 3257 3258def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3259 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3260 Requires<[HasV4T]>; 3261 3262def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3263 (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>, 3264 Requires<[HasV4T]>; 3265 3266def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)), 3267 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3268 Requires<[HasV4T]>; 3269 3270def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)), 3271 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3272 Requires<[HasV4T]>; 3273 3274def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)), 3275 (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3276 Requires<[HasV4T]>; 3277} 3278 3279// Indexed store double word - global address. 3280// memw(Rs+#u6:2)=#S8 3281let AddedComplexity = 10 in 3282def STrih_offset_ext_V4 : STInst<(outs), 3283 (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3), 3284 "memh($src1+#$src2) = ##$src3", 3285 [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3), 3286 (add IntRegs:$src1, u6_1ImmPred:$src2))]>, 3287 Requires<[HasV4T]>; 3288// Map from store(globaladdress + x) -> memd(#foo + x) 3289let AddedComplexity = 100 in 3290def : Pat<(store (i64 DoubleRegs:$src1), 3291 FoldGlobalAddrGP:$addr), 3292 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 3293 Requires<[HasV4T]>; 3294 3295def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr, 3296 (i64 DoubleRegs:$src1)), 3297 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 3298 Requires<[HasV4T]>; 3299 3300// Map from store(globaladdress + x) -> memb(#foo + x) 3301let AddedComplexity = 100 in 3302def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3303 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3304 Requires<[HasV4T]>; 3305 3306def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3307 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3308 Requires<[HasV4T]>; 3309 3310// Map from store(globaladdress + x) -> memh(#foo + x) 3311let AddedComplexity = 100 in 3312def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3313 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3314 Requires<[HasV4T]>; 3315 3316def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3317 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3318 Requires<[HasV4T]>; 3319 3320// Map from store(globaladdress + x) -> memw(#foo + x) 3321let AddedComplexity = 100 in 3322def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3323 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3324 Requires<[HasV4T]>; 3325 3326def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 3327 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3328 Requires<[HasV4T]>; 3329 3330// Map from load(globaladdress + x) -> memd(#foo + x) 3331let AddedComplexity = 100 in 3332def : Pat<(i64 (load FoldGlobalAddrGP:$addr)), 3333 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>, 3334 Requires<[HasV4T]>; 3335 3336def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr), 3337 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>, 3338 Requires<[HasV4T]>; 3339 3340// Map from load(globaladdress + x) -> memb(#foo + x) 3341let AddedComplexity = 100 in 3342def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)), 3343 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>, 3344 Requires<[HasV4T]>; 3345 3346// Map from load(globaladdress + x) -> memb(#foo + x) 3347let AddedComplexity = 100 in 3348def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)), 3349 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>, 3350 Requires<[HasV4T]>; 3351 3352//let AddedComplexity = 100 in 3353let AddedComplexity = 100 in 3354def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)), 3355 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>, 3356 Requires<[HasV4T]>; 3357 3358// Map from load(globaladdress + x) -> memh(#foo + x) 3359let AddedComplexity = 100 in 3360def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)), 3361 (i32 (LDrih_abs_V4 FoldGlobalAddrGP:$addr))>, 3362 Requires<[HasV4T]>; 3363 3364// Map from load(globaladdress + x) -> memuh(#foo + x) 3365let AddedComplexity = 100 in 3366def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)), 3367 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>, 3368 Requires<[HasV4T]>; 3369 3370def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr), 3371 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>, 3372 Requires<[HasV4T]>; 3373 3374// Map from load(globaladdress + x) -> memub(#foo + x) 3375let AddedComplexity = 100 in 3376def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)), 3377 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>, 3378 Requires<[HasV4T]>; 3379 3380def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr), 3381 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>, 3382 Requires<[HasV4T]>; 3383 3384// Map from load(globaladdress + x) -> memw(#foo + x) 3385let AddedComplexity = 100 in 3386def : Pat<(i32 (load FoldGlobalAddrGP:$addr)), 3387 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3388 Requires<[HasV4T]>; 3389 3390def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr), 3391 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3392 Requires<[HasV4T]>; 3393