1 //=- HexagonInstrInfoV4.td - Target Desc. for Hexagon Target -*- tablegen -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file describes the Hexagon V4 instructions in TableGen format. 11 // 12 //===----------------------------------------------------------------------===// 13 14 let neverHasSideEffects = 1 in 15 class T_Immext<dag ins> : 16 EXTENDERInst<(outs), ins, "immext(#$imm)", []>, 17 Requires<[HasV4T]>; 18 19 def IMMEXT_b : T_Immext<(ins brtarget:$imm)>; 20 def IMMEXT_c : T_Immext<(ins calltarget:$imm)>; 21 def IMMEXT_g : T_Immext<(ins globaladdress:$imm)>; 22 def IMMEXT_i : T_Immext<(ins u26_6Imm:$imm)>; 23 24 // Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address. 25 def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>; 26 27 // Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address. 28 def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>; 29 30 def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr), 31 (HexagonCONST32 node:$addr), [{ 32 return hasNumUsesBelowThresGA(N->getOperand(0).getNode()); 33 }]>; 34 35 // Hexagon V4 Architecture spec defines 8 instruction classes: 36 // LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the 37 // compiler) 38 39 // LD Instructions: 40 // ======================================== 41 // Loads (8/16/32/64 bit) 42 // Deallocframe 43 44 // ST Instructions: 45 // ======================================== 46 // Stores (8/16/32/64 bit) 47 // Allocframe 48 49 // ALU32 Instructions: 50 // ======================================== 51 // Arithmetic / Logical (32 bit) 52 // Vector Halfword 53 54 // XTYPE Instructions (32/64 bit): 55 // ======================================== 56 // Arithmetic, Logical, Bit Manipulation 57 // Multiply (Integer, Fractional, Complex) 58 // Permute / Vector Permute Operations 59 // Predicate Operations 60 // Shift / Shift with Add/Sub/Logical 61 // Vector Byte ALU 62 // Vector Halfword (ALU, Shift, Multiply) 63 // Vector Word (ALU, Shift) 64 65 // J Instructions: 66 // ======================================== 67 // Jump/Call PC-relative 68 69 // JR Instructions: 70 // ======================================== 71 // Jump/Call Register 72 73 // MEMOP Instructions: 74 // ======================================== 75 // Operation on memory (8/16/32 bit) 76 77 // NV Instructions: 78 // ======================================== 79 // New-value Jumps 80 // New-value Stores 81 82 // CR Instructions: 83 // ======================================== 84 // Control-Register Transfers 85 // Hardware Loop Setup 86 // Predicate Logicals & Reductions 87 88 // SYSTEM Instructions (not implemented in the compiler): 89 // ======================================== 90 // Prefetch 91 // Cache Maintenance 92 // Bus Operations 93 94 95 //===----------------------------------------------------------------------===// 96 // ALU32 + 97 //===----------------------------------------------------------------------===// 98 // Generate frame index addresses. 99 let neverHasSideEffects = 1, isReMaterializable = 1, 100 isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in 101 def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst), 102 (ins IntRegs:$src1, s32Imm:$offset), 103 "$dst = add($src1, ##$offset)", 104 []>, 105 Requires<[HasV4T]>; 106 107 // Rd=cmp.eq(Rs,#s8) 108 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2, 109 isExtentSigned = 1, opExtentBits = 8 in 110 def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd), 111 (ins IntRegs:$Rs, s8Ext:$s8), 112 "$Rd = cmp.eq($Rs, #$s8)", 113 [(set (i32 IntRegs:$Rd), 114 (i32 (zext (i1 (seteq (i32 IntRegs:$Rs), 115 s8ExtPred:$s8)))))]>, 116 Requires<[HasV4T]>; 117 118 // Preserve the TSTBIT generation 119 def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))), 120 (i32 IntRegs:$src1))), 0)))), 121 (i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))), 122 1, 0))>; 123 124 // Interfered with tstbit generation, above pattern preserves, see : tstbit.ll 125 // Rd=cmp.ne(Rs,#s8) 126 let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2, 127 isExtentSigned = 1, opExtentBits = 8 in 128 def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd), 129 (ins IntRegs:$Rs, s8Ext:$s8), 130 "$Rd = !cmp.eq($Rs, #$s8)", 131 [(set (i32 IntRegs:$Rd), 132 (i32 (zext (i1 (setne (i32 IntRegs:$Rs), 133 s8ExtPred:$s8)))))]>, 134 Requires<[HasV4T]>; 135 136 // Rd=cmp.eq(Rs,Rt) 137 let validSubTargets = HasV4SubT in 138 def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd), 139 (ins IntRegs:$Rs, IntRegs:$Rt), 140 "$Rd = cmp.eq($Rs, $Rt)", 141 [(set (i32 IntRegs:$Rd), 142 (i32 (zext (i1 (seteq (i32 IntRegs:$Rs), 143 IntRegs:$Rt)))))]>, 144 Requires<[HasV4T]>; 145 146 // Rd=cmp.ne(Rs,Rt) 147 let validSubTargets = HasV4SubT in 148 def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd), 149 (ins IntRegs:$Rs, IntRegs:$Rt), 150 "$Rd = !cmp.eq($Rs, $Rt)", 151 [(set (i32 IntRegs:$Rd), 152 (i32 (zext (i1 (setne (i32 IntRegs:$Rs), 153 IntRegs:$Rt)))))]>, 154 Requires<[HasV4T]>; 155 156 //===----------------------------------------------------------------------===// 157 // ALU32 - 158 //===----------------------------------------------------------------------===// 159 160 161 //===----------------------------------------------------------------------===// 162 // ALU32/PERM + 163 //===----------------------------------------------------------------------===// 164 165 // Combine 166 // Rdd=combine(Rs, #s8) 167 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 168 neverHasSideEffects = 1, validSubTargets = HasV4SubT in 169 def COMBINE_rI_V4 : ALU32_ri<(outs DoubleRegs:$dst), 170 (ins IntRegs:$src1, s8Ext:$src2), 171 "$dst = combine($src1, #$src2)", 172 []>, 173 Requires<[HasV4T]>; 174 175 // Rdd=combine(#s8, Rs) 176 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 8, 177 neverHasSideEffects = 1, validSubTargets = HasV4SubT in 178 def COMBINE_Ir_V4 : ALU32_ir<(outs DoubleRegs:$dst), 179 (ins s8Ext:$src1, IntRegs:$src2), 180 "$dst = combine(#$src1, $src2)", 181 []>, 182 Requires<[HasV4T]>; 183 184 def HexagonWrapperCombineRI_V4 : 185 SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>; 186 def HexagonWrapperCombineIR_V4 : 187 SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>; 188 189 def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i), 190 (COMBINE_rI_V4 IntRegs:$r, s8ExtPred:$i)>, 191 Requires<[HasV4T]>; 192 193 def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r), 194 (COMBINE_Ir_V4 s8ExtPred:$i, IntRegs:$r)>, 195 Requires<[HasV4T]>; 196 197 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 6, 198 neverHasSideEffects = 1, validSubTargets = HasV4SubT in 199 def COMBINE_iI_V4 : ALU32_ii<(outs DoubleRegs:$dst), 200 (ins s8Imm:$src1, u6Ext:$src2), 201 "$dst = combine(#$src1, #$src2)", 202 []>, 203 Requires<[HasV4T]>; 204 205 //===----------------------------------------------------------------------===// 206 // ALU32/PERM + 207 //===----------------------------------------------------------------------===// 208 209 //===----------------------------------------------------------------------===// 210 // LD + 211 //===----------------------------------------------------------------------===// 212 //===----------------------------------------------------------------------===// 213 // Template class for load instructions with Absolute set addressing mode. 214 //===----------------------------------------------------------------------===// 215 let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1, 216 validSubTargets = HasV4SubT, addrMode = AbsoluteSet in 217 class T_LD_abs_set<string mnemonic, RegisterClass RC>: 218 LDInst2<(outs RC:$dst1, IntRegs:$dst2), 219 (ins u0AlwaysExt:$addr), 220 "$dst1 = "#mnemonic#"($dst2=##$addr)", 221 []>, 222 Requires<[HasV4T]>; 223 224 def LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>; 225 def LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>; 226 def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>; 227 def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>; 228 def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>; 229 def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>; 230 231 232 // multiclass for load instructions with base + register offset 233 // addressing mode 234 multiclass ld_idxd_shl_pbase<string mnemonic, RegisterClass RC, bit isNot, 235 bit isPredNew> { 236 let isPredicatedNew = isPredNew in 237 def NAME : LDInst2<(outs RC:$dst), 238 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), 239 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 240 ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$offset)", 241 []>, Requires<[HasV4T]>; 242 } 243 244 multiclass ld_idxd_shl_pred<string mnemonic, RegisterClass RC, bit PredNot> { 245 let isPredicatedFalse = PredNot in { 246 defm _c#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 0>; 247 // Predicate new 248 defm _cdn#NAME : ld_idxd_shl_pbase<mnemonic, RC, PredNot, 1>; 249 } 250 } 251 252 let neverHasSideEffects = 1 in 253 multiclass ld_idxd_shl<string mnemonic, string CextOp, RegisterClass RC> { 254 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 255 let isPredicable = 1 in 256 def NAME#_V4 : LDInst2<(outs RC:$dst), 257 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$offset), 258 "$dst = "#mnemonic#"($src1+$src2<<#$offset)", 259 []>, Requires<[HasV4T]>; 260 261 let isPredicated = 1 in { 262 defm Pt_V4 : ld_idxd_shl_pred<mnemonic, RC, 0 >; 263 defm NotPt_V4 : ld_idxd_shl_pred<mnemonic, RC, 1>; 264 } 265 } 266 } 267 268 let addrMode = BaseRegOffset in { 269 let accessSize = ByteAccess in { 270 defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, 271 AddrModeRel; 272 defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, 273 AddrModeRel; 274 } 275 let accessSize = HalfWordAccess in { 276 defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel; 277 defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, 278 AddrModeRel; 279 } 280 let accessSize = WordAccess in 281 defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel; 282 283 let accessSize = DoubleWordAccess in 284 defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, 285 AddrModeRel; 286 } 287 288 // 'def pats' for load instructions with base + register offset and non-zero 289 // immediate value. Immediate value is used to left-shift the second 290 // register operand. 291 let AddedComplexity = 40 in { 292 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 293 (shl IntRegs:$src2, u2ImmPred:$offset)))), 294 (LDrib_indexed_shl_V4 IntRegs:$src1, 295 IntRegs:$src2, u2ImmPred:$offset)>, 296 Requires<[HasV4T]>; 297 298 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 299 (shl IntRegs:$src2, u2ImmPred:$offset)))), 300 (LDriub_indexed_shl_V4 IntRegs:$src1, 301 IntRegs:$src2, u2ImmPred:$offset)>, 302 Requires<[HasV4T]>; 303 304 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, 305 (shl IntRegs:$src2, u2ImmPred:$offset)))), 306 (LDriub_indexed_shl_V4 IntRegs:$src1, 307 IntRegs:$src2, u2ImmPred:$offset)>, 308 Requires<[HasV4T]>; 309 310 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, 311 (shl IntRegs:$src2, u2ImmPred:$offset)))), 312 (LDrih_indexed_shl_V4 IntRegs:$src1, 313 IntRegs:$src2, u2ImmPred:$offset)>, 314 Requires<[HasV4T]>; 315 316 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, 317 (shl IntRegs:$src2, u2ImmPred:$offset)))), 318 (LDriuh_indexed_shl_V4 IntRegs:$src1, 319 IntRegs:$src2, u2ImmPred:$offset)>, 320 Requires<[HasV4T]>; 321 322 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, 323 (shl IntRegs:$src2, u2ImmPred:$offset)))), 324 (LDriuh_indexed_shl_V4 IntRegs:$src1, 325 IntRegs:$src2, u2ImmPred:$offset)>, 326 Requires<[HasV4T]>; 327 328 def : Pat <(i32 (load (add IntRegs:$src1, 329 (shl IntRegs:$src2, u2ImmPred:$offset)))), 330 (LDriw_indexed_shl_V4 IntRegs:$src1, 331 IntRegs:$src2, u2ImmPred:$offset)>, 332 Requires<[HasV4T]>; 333 334 def : Pat <(i64 (load (add IntRegs:$src1, 335 (shl IntRegs:$src2, u2ImmPred:$offset)))), 336 (LDrid_indexed_shl_V4 IntRegs:$src1, 337 IntRegs:$src2, u2ImmPred:$offset)>, 338 Requires<[HasV4T]>; 339 } 340 341 342 // 'def pats' for load instruction base + register offset and 343 // zero immediate value. 344 let AddedComplexity = 10 in { 345 def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))), 346 (LDrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 347 Requires<[HasV4T]>; 348 349 def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 350 (LDrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 351 Requires<[HasV4T]>; 352 353 def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 354 (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 355 Requires<[HasV4T]>; 356 357 def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))), 358 (LDriub_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 359 Requires<[HasV4T]>; 360 361 def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 362 (LDrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 363 Requires<[HasV4T]>; 364 365 def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 366 (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 367 Requires<[HasV4T]>; 368 369 def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))), 370 (LDriuh_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 371 Requires<[HasV4T]>; 372 373 def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))), 374 (LDriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 0)>, 375 Requires<[HasV4T]>; 376 } 377 378 // zext i1->i64 379 def : Pat <(i64 (zext (i1 PredRegs:$src1))), 380 (i64 (COMBINE_Ir_V4 0, (MUX_ii (i1 PredRegs:$src1), 1, 0)))>, 381 Requires<[HasV4T]>; 382 383 // zext i32->i64 384 def : Pat <(i64 (zext (i32 IntRegs:$src1))), 385 (i64 (COMBINE_Ir_V4 0, (i32 IntRegs:$src1)))>, 386 Requires<[HasV4T]>; 387 // zext i8->i64 388 def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)), 389 (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>, 390 Requires<[HasV4T]>; 391 392 let AddedComplexity = 20 in 393 def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1), 394 s11_0ExtPred:$offset))), 395 (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1, 396 s11_0ExtPred:$offset)))>, 397 Requires<[HasV4T]>; 398 399 // zext i1->i64 400 def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)), 401 (i64 (COMBINE_Ir_V4 0, (LDriub ADDRriS11_0:$src1)))>, 402 Requires<[HasV4T]>; 403 404 let AddedComplexity = 20 in 405 def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1), 406 s11_0ExtPred:$offset))), 407 (i64 (COMBINE_Ir_V4 0, (LDriub_indexed IntRegs:$src1, 408 s11_0ExtPred:$offset)))>, 409 Requires<[HasV4T]>; 410 411 // zext i16->i64 412 def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)), 413 (i64 (COMBINE_Ir_V4 0, (LDriuh ADDRriS11_1:$src1)))>, 414 Requires<[HasV4T]>; 415 416 let AddedComplexity = 20 in 417 def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1), 418 s11_1ExtPred:$offset))), 419 (i64 (COMBINE_Ir_V4 0, (LDriuh_indexed IntRegs:$src1, 420 s11_1ExtPred:$offset)))>, 421 Requires<[HasV4T]>; 422 423 // anyext i16->i64 424 def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)), 425 (i64 (COMBINE_Ir_V4 0, (LDrih ADDRriS11_2:$src1)))>, 426 Requires<[HasV4T]>; 427 428 let AddedComplexity = 20 in 429 def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1), 430 s11_1ExtPred:$offset))), 431 (i64 (COMBINE_Ir_V4 0, (LDrih_indexed IntRegs:$src1, 432 s11_1ExtPred:$offset)))>, 433 Requires<[HasV4T]>; 434 435 // zext i32->i64 436 def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)), 437 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>, 438 Requires<[HasV4T]>; 439 440 let AddedComplexity = 100 in 441 def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 442 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1, 443 s11_2ExtPred:$offset)))>, 444 Requires<[HasV4T]>; 445 446 // anyext i32->i64 447 def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)), 448 (i64 (COMBINE_Ir_V4 0, (LDriw ADDRriS11_2:$src1)))>, 449 Requires<[HasV4T]>; 450 451 let AddedComplexity = 100 in 452 def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 453 (i64 (COMBINE_Ir_V4 0, (LDriw_indexed IntRegs:$src1, 454 s11_2ExtPred:$offset)))>, 455 Requires<[HasV4T]>; 456 457 458 459 //===----------------------------------------------------------------------===// 460 // LD - 461 //===----------------------------------------------------------------------===// 462 463 //===----------------------------------------------------------------------===// 464 // ST + 465 //===----------------------------------------------------------------------===// 466 /// 467 //===----------------------------------------------------------------------===// 468 // Template class for store instructions with Absolute set addressing mode. 469 //===----------------------------------------------------------------------===// 470 let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT, 471 addrMode = AbsoluteSet in 472 class T_ST_abs_set<string mnemonic, RegisterClass RC>: 473 STInst2<(outs IntRegs:$dst1), 474 (ins RC:$src1, u0AlwaysExt:$src2), 475 mnemonic#"($dst1=##$src2) = $src1", 476 []>, 477 Requires<[HasV4T]>; 478 479 def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>; 480 def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>; 481 def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>; 482 def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>; 483 484 //===----------------------------------------------------------------------===// 485 // multiclass for store instructions with base + register offset addressing 486 // mode 487 //===----------------------------------------------------------------------===// 488 multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot, 489 bit isPredNew> { 490 let isPredicatedNew = isPredNew in 491 def NAME : STInst2<(outs), 492 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, 493 RC:$src5), 494 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 495 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5", 496 []>, 497 Requires<[HasV4T]>; 498 } 499 500 multiclass ST_Idxd_shl_Pred<string mnemonic, RegisterClass RC, bit PredNot> { 501 let isPredicatedFalse = PredNot in { 502 defm _c#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 0>; 503 // Predicate new 504 defm _cdn#NAME : ST_Idxd_shl_Pbase<mnemonic, RC, PredNot, 1>; 505 } 506 } 507 508 let isNVStorable = 1 in 509 multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC> { 510 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 511 let isPredicable = 1 in 512 def NAME#_V4 : STInst2<(outs), 513 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4), 514 mnemonic#"($src1+$src2<<#$src3) = $src4", 515 []>, 516 Requires<[HasV4T]>; 517 518 let isPredicated = 1 in { 519 defm Pt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 0 >; 520 defm NotPt_V4 : ST_Idxd_shl_Pred<mnemonic, RC, 1>; 521 } 522 } 523 } 524 525 // multiclass for new-value store instructions with base + register offset 526 // addressing mode. 527 multiclass ST_Idxd_shl_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot, 528 bit isPredNew> { 529 let isPredicatedNew = isPredNew in 530 def NAME#_nv_V4 : NVInst_V4<(outs), 531 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$src4, 532 RC:$src5), 533 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 534 ") ")#mnemonic#"($src2+$src3<<#$src4) = $src5.new", 535 []>, 536 Requires<[HasV4T]>; 537 } 538 539 multiclass ST_Idxd_shl_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 540 let isPredicatedFalse = PredNot in { 541 defm _c#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 0>; 542 // Predicate new 543 defm _cdn#NAME : ST_Idxd_shl_Pbase_nv<mnemonic, RC, PredNot, 1>; 544 } 545 } 546 547 let mayStore = 1, isNVStore = 1 in 548 multiclass ST_Idxd_shl_nv<string mnemonic, string CextOp, RegisterClass RC> { 549 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 550 let isPredicable = 1 in 551 def NAME#_nv_V4 : NVInst_V4<(outs), 552 (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$src3, RC:$src4), 553 mnemonic#"($src1+$src2<<#$src3) = $src4.new", 554 []>, 555 Requires<[HasV4T]>; 556 557 let isPredicated = 1 in { 558 defm Pt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 0 >; 559 defm NotPt : ST_Idxd_shl_Pred_nv<mnemonic, RC, 1>; 560 } 561 } 562 } 563 564 let addrMode = BaseRegOffset, neverHasSideEffects = 1, 565 validSubTargets = HasV4SubT in { 566 let accessSize = ByteAccess in 567 defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>, 568 ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel; 569 570 let accessSize = HalfWordAccess in 571 defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>, 572 ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel; 573 574 let accessSize = WordAccess in 575 defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>, 576 ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel; 577 578 let isNVStorable = 0, accessSize = DoubleWordAccess in 579 defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel; 580 } 581 582 let Predicates = [HasV4T], AddedComplexity = 10 in { 583 def : Pat<(truncstorei8 (i32 IntRegs:$src4), 584 (add IntRegs:$src1, (shl IntRegs:$src2, 585 u2ImmPred:$src3))), 586 (STrib_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 587 u2ImmPred:$src3, IntRegs:$src4)>; 588 589 def : Pat<(truncstorei16 (i32 IntRegs:$src4), 590 (add IntRegs:$src1, (shl IntRegs:$src2, 591 u2ImmPred:$src3))), 592 (STrih_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 593 u2ImmPred:$src3, IntRegs:$src4)>; 594 595 def : Pat<(store (i32 IntRegs:$src4), 596 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 597 (STriw_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 598 u2ImmPred:$src3, IntRegs:$src4)>; 599 600 def : Pat<(store (i64 DoubleRegs:$src4), 601 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 602 (STrid_indexed_shl_V4 IntRegs:$src1, IntRegs:$src2, 603 u2ImmPred:$src3, DoubleRegs:$src4)>; 604 } 605 606 let isExtended = 1, opExtendable = 2 in 607 class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> : 608 STInst<(outs), 609 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4), 610 mnemonic#"($src1<<#$src2+##$src3) = $src4", 611 [(stOp (VT RC:$src4), 612 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), 613 u0AlwaysExtPred:$src3))]>, 614 Requires<[HasV4T]>; 615 616 let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in 617 class T_ST_LongOff_nv <string mnemonic> : 618 NVInst_V4<(outs), 619 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4), 620 mnemonic#"($src1<<#$src2+##$src3) = $src4.new", 621 []>, 622 Requires<[HasV4T]>; 623 624 multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> { 625 let BaseOpcode = BaseOp#"_shl" in { 626 let isNVStorable = 1 in 627 def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>; 628 629 def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>; 630 } 631 } 632 633 let AddedComplexity = 10, validSubTargets = HasV4SubT in { 634 def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>; 635 defm STrib_shl : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel; 636 defm STrih_shl : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel; 637 defm STriw_shl : ST_LongOff <"memw", "STriw", store>, NewValueRel; 638 } 639 640 let AddedComplexity = 40 in 641 multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT, 642 PatFrag stOp> { 643 def : Pat<(stOp (VT RC:$src4), 644 (add (shl IntRegs:$src1, u2ImmPred:$src2), 645 (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 646 (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>; 647 648 def : Pat<(stOp (VT RC:$src4), 649 (add IntRegs:$src1, 650 (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 651 (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>; 652 } 653 654 defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>; 655 defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>; 656 defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>; 657 defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>; 658 659 // memd(Rx++#s4:3)=Rtt 660 // memd(Rx++#s4:3:circ(Mu))=Rtt 661 // memd(Rx++I:circ(Mu))=Rtt 662 // memd(Rx++Mu)=Rtt 663 // memd(Rx++Mu:brev)=Rtt 664 // memd(gp+#u16:3)=Rtt 665 666 // Store doubleword conditionally. 667 // if ([!]Pv[.new]) memd(#u6)=Rtt 668 // TODO: needs to be implemented. 669 670 //===----------------------------------------------------------------------===// 671 // multiclass for store instructions with base + immediate offset 672 // addressing mode and immediate stored value. 673 // mem[bhw](Rx++#s4:3)=#s8 674 // if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6 675 //===----------------------------------------------------------------------===// 676 multiclass ST_Imm_Pbase<string mnemonic, Operand OffsetOp, bit isNot, 677 bit isPredNew> { 678 let isPredicatedNew = isPredNew in 679 def NAME : STInst2<(outs), 680 (ins PredRegs:$src1, IntRegs:$src2, OffsetOp:$src3, s6Ext:$src4), 681 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 682 ") ")#mnemonic#"($src2+#$src3) = #$src4", 683 []>, 684 Requires<[HasV4T]>; 685 } 686 687 multiclass ST_Imm_Pred<string mnemonic, Operand OffsetOp, bit PredNot> { 688 let isPredicatedFalse = PredNot in { 689 defm _c#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 0>; 690 // Predicate new 691 defm _cdn#NAME : ST_Imm_Pbase<mnemonic, OffsetOp, PredNot, 1>; 692 } 693 } 694 695 let isExtendable = 1, isExtentSigned = 1, neverHasSideEffects = 1 in 696 multiclass ST_Imm<string mnemonic, string CextOp, Operand OffsetOp> { 697 let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in { 698 let opExtendable = 2, opExtentBits = 8, isPredicable = 1 in 699 def NAME#_V4 : STInst2<(outs), 700 (ins IntRegs:$src1, OffsetOp:$src2, s8Ext:$src3), 701 mnemonic#"($src1+#$src2) = #$src3", 702 []>, 703 Requires<[HasV4T]>; 704 705 let opExtendable = 3, opExtentBits = 6, isPredicated = 1 in { 706 defm Pt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 0>; 707 defm NotPt_V4 : ST_Imm_Pred<mnemonic, OffsetOp, 1 >; 708 } 709 } 710 } 711 712 let addrMode = BaseImmOffset, InputType = "imm", 713 validSubTargets = HasV4SubT in { 714 let accessSize = ByteAccess in 715 defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel; 716 717 let accessSize = HalfWordAccess in 718 defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel; 719 720 let accessSize = WordAccess in 721 defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel; 722 } 723 724 let Predicates = [HasV4T], AddedComplexity = 10 in { 725 def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)), 726 (STrib_imm_V4 IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>; 727 728 def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1, 729 u6_1ImmPred:$src2)), 730 (STrih_imm_V4 IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>; 731 732 def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)), 733 (STriw_imm_V4 IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>; 734 } 735 736 let AddedComplexity = 6 in 737 def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)), 738 (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 739 Requires<[HasV4T]>; 740 741 // memb(Rx++#s4:0:circ(Mu))=Rt 742 // memb(Rx++I:circ(Mu))=Rt 743 // memb(Rx++Mu)=Rt 744 // memb(Rx++Mu:brev)=Rt 745 // memb(gp+#u16:0)=Rt 746 747 748 // Store halfword. 749 // TODO: needs to be implemented 750 // memh(Re=#U6)=Rt.H 751 // memh(Rs+#s11:1)=Rt.H 752 let AddedComplexity = 6 in 753 def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)), 754 (STrih_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 755 Requires<[HasV4T]>; 756 757 // memh(Rs+Ru<<#u2)=Rt.H 758 // TODO: needs to be implemented. 759 760 // memh(Ru<<#u2+#U6)=Rt.H 761 // memh(Rx++#s4:1:circ(Mu))=Rt.H 762 // memh(Rx++#s4:1:circ(Mu))=Rt 763 // memh(Rx++I:circ(Mu))=Rt.H 764 // memh(Rx++I:circ(Mu))=Rt 765 // memh(Rx++Mu)=Rt.H 766 // memh(Rx++Mu)=Rt 767 // memh(Rx++Mu:brev)=Rt.H 768 // memh(Rx++Mu:brev)=Rt 769 // memh(gp+#u16:1)=Rt 770 // if ([!]Pv[.new]) memh(#u6)=Rt.H 771 // if ([!]Pv[.new]) memh(#u6)=Rt 772 773 774 // if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H 775 // TODO: needs to be implemented. 776 777 // if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H 778 // TODO: Needs to be implemented. 779 780 // Store word. 781 // memw(Re=#U6)=Rt 782 // TODO: Needs to be implemented. 783 784 // Store predicate: 785 let neverHasSideEffects = 1 in 786 def STriw_pred_V4 : STInst2<(outs), 787 (ins MEMri:$addr, PredRegs:$src1), 788 "Error; should not emit", 789 []>, 790 Requires<[HasV4T]>; 791 792 let AddedComplexity = 6 in 793 def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)), 794 (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>, 795 Requires<[HasV4T]>; 796 797 // memw(Rx++#s4:2)=Rt 798 // memw(Rx++#s4:2:circ(Mu))=Rt 799 // memw(Rx++I:circ(Mu))=Rt 800 // memw(Rx++Mu)=Rt 801 // memw(Rx++Mu:brev)=Rt 802 803 //===----------------------------------------------------------------------=== 804 // ST - 805 //===----------------------------------------------------------------------=== 806 807 808 //===----------------------------------------------------------------------===// 809 // NV/ST + 810 //===----------------------------------------------------------------------===// 811 812 // multiclass for new-value store instructions with base + immediate offset. 813 // 814 multiclass ST_Idxd_Pbase_nv<string mnemonic, RegisterClass RC, 815 Operand predImmOp, bit isNot, bit isPredNew> { 816 let isPredicatedNew = isPredNew in 817 def NAME#_nv_V4 : NVInst_V4<(outs), 818 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC: $src4), 819 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 820 ") ")#mnemonic#"($src2+#$src3) = $src4.new", 821 []>, 822 Requires<[HasV4T]>; 823 } 824 825 multiclass ST_Idxd_Pred_nv<string mnemonic, RegisterClass RC, Operand predImmOp, 826 bit PredNot> { 827 let isPredicatedFalse = PredNot in { 828 defm _c#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 0>; 829 // Predicate new 830 defm _cdn#NAME : ST_Idxd_Pbase_nv<mnemonic, RC, predImmOp, PredNot, 1>; 831 } 832 } 833 834 let mayStore = 1, isNVStore = 1, neverHasSideEffects = 1, isExtendable = 1 in 835 multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC, 836 Operand ImmOp, Operand predImmOp, bits<5> ImmBits, 837 bits<5> PredImmBits> { 838 839 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 840 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 841 isPredicable = 1 in 842 def NAME#_nv_V4 : NVInst_V4<(outs), 843 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3), 844 mnemonic#"($src1+#$src2) = $src3.new", 845 []>, 846 Requires<[HasV4T]>; 847 848 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 849 isPredicated = 1 in { 850 defm Pt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 0>; 851 defm NotPt : ST_Idxd_Pred_nv<mnemonic, RC, predImmOp, 1>; 852 } 853 } 854 } 855 856 let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in { 857 let accessSize = ByteAccess in 858 defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext, 859 u6_0Ext, 11, 6>, AddrModeRel; 860 861 let accessSize = HalfWordAccess in 862 defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext, 863 u6_1Ext, 12, 7>, AddrModeRel; 864 865 let accessSize = WordAccess in 866 defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext, 867 u6_2Ext, 13, 8>, AddrModeRel; 868 } 869 870 // multiclass for new-value store instructions with base + immediate offset. 871 // and MEMri operand. 872 multiclass ST_MEMri_Pbase_nv<string mnemonic, RegisterClass RC, bit isNot, 873 bit isPredNew> { 874 let isPredicatedNew = isPredNew in 875 def NAME#_nv_V4 : NVInst_V4<(outs), 876 (ins PredRegs:$src1, MEMri:$addr, RC: $src2), 877 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 878 ") ")#mnemonic#"($addr) = $src2.new", 879 []>, 880 Requires<[HasV4T]>; 881 } 882 883 multiclass ST_MEMri_Pred_nv<string mnemonic, RegisterClass RC, bit PredNot> { 884 let isPredicatedFalse = PredNot in { 885 defm _c#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 0>; 886 887 // Predicate new 888 defm _cdn#NAME : ST_MEMri_Pbase_nv<mnemonic, RC, PredNot, 1>; 889 } 890 } 891 892 let mayStore = 1, isNVStore = 1, isExtendable = 1, neverHasSideEffects = 1 in 893 multiclass ST_MEMri_nv<string mnemonic, string CextOp, RegisterClass RC, 894 bits<5> ImmBits, bits<5> PredImmBits> { 895 896 let CextOpcode = CextOp, BaseOpcode = CextOp in { 897 let opExtendable = 1, isExtentSigned = 1, opExtentBits = ImmBits, 898 isPredicable = 1 in 899 def NAME#_nv_V4 : NVInst_V4<(outs), 900 (ins MEMri:$addr, RC:$src), 901 mnemonic#"($addr) = $src.new", 902 []>, 903 Requires<[HasV4T]>; 904 905 let opExtendable = 2, isExtentSigned = 0, opExtentBits = PredImmBits, 906 neverHasSideEffects = 1, isPredicated = 1 in { 907 defm Pt : ST_MEMri_Pred_nv<mnemonic, RC, 0>; 908 defm NotPt : ST_MEMri_Pred_nv<mnemonic, RC, 1>; 909 } 910 } 911 } 912 913 let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT, 914 mayStore = 1 in { 915 let accessSize = ByteAccess in 916 defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel; 917 918 let accessSize = HalfWordAccess in 919 defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel; 920 921 let accessSize = WordAccess in 922 defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel; 923 } 924 925 //===----------------------------------------------------------------------===// 926 // Post increment store 927 // mem[bhwd](Rx++#s4:[0123])=Nt.new 928 //===----------------------------------------------------------------------===// 929 930 multiclass ST_PostInc_Pbase_nv<string mnemonic, RegisterClass RC, Operand ImmOp, 931 bit isNot, bit isPredNew> { 932 let isPredicatedNew = isPredNew in 933 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), 934 (ins PredRegs:$src1, IntRegs:$src2, ImmOp:$offset, RC:$src3), 935 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 936 ") ")#mnemonic#"($src2++#$offset) = $src3.new", 937 [], 938 "$src2 = $dst">, 939 Requires<[HasV4T]>; 940 } 941 942 multiclass ST_PostInc_Pred_nv<string mnemonic, RegisterClass RC, 943 Operand ImmOp, bit PredNot> { 944 let isPredicatedFalse = PredNot in { 945 defm _c#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 0>; 946 // Predicate new 947 let Predicates = [HasV4T], validSubTargets = HasV4SubT in 948 defm _cdn#NAME : ST_PostInc_Pbase_nv<mnemonic, RC, ImmOp, PredNot, 1>; 949 } 950 } 951 952 let hasCtrlDep = 1, isNVStore = 1, neverHasSideEffects = 1 in 953 multiclass ST_PostInc_nv<string mnemonic, string BaseOp, RegisterClass RC, 954 Operand ImmOp> { 955 956 let BaseOpcode = "POST_"#BaseOp in { 957 let isPredicable = 1 in 958 def NAME#_nv_V4 : NVInstPI_V4<(outs IntRegs:$dst), 959 (ins IntRegs:$src1, ImmOp:$offset, RC:$src2), 960 mnemonic#"($src1++#$offset) = $src2.new", 961 [], 962 "$src1 = $dst">, 963 Requires<[HasV4T]>; 964 965 let isPredicated = 1 in { 966 defm Pt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 0 >; 967 defm NotPt : ST_PostInc_Pred_nv<mnemonic, RC, ImmOp, 1 >; 968 } 969 } 970 } 971 972 let addrMode = PostInc, validSubTargets = HasV4SubT in { 973 defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel; 974 defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel; 975 defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel; 976 } 977 978 // memb(Rx++#s4:0:circ(Mu))=Nt.new 979 // memb(Rx++I:circ(Mu))=Nt.new 980 // memb(Rx++Mu)=Nt.new 981 // memb(Rx++Mu:brev)=Nt.new 982 // memh(Rx++#s4:1:circ(Mu))=Nt.new 983 // memh(Rx++I:circ(Mu))=Nt.new 984 // memh(Rx++Mu)=Nt.new 985 // memh(Rx++Mu:brev)=Nt.new 986 987 // memw(Rx++#s4:2:circ(Mu))=Nt.new 988 // memw(Rx++I:circ(Mu))=Nt.new 989 // memw(Rx++Mu)=Nt.new 990 // memw(Rx++Mu:brev)=Nt.new 991 992 //===----------------------------------------------------------------------===// 993 // NV/ST - 994 //===----------------------------------------------------------------------===// 995 996 //===----------------------------------------------------------------------===// 997 // NV/J + 998 //===----------------------------------------------------------------------===// 999 1000 //===----------------------------------------------------------------------===// 1001 // multiclass/template class for the new-value compare jumps with the register 1002 // operands. 1003 //===----------------------------------------------------------------------===// 1004 1005 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in 1006 class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum, 1007 bit isNegCond, bit 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 1040 multiclass 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 1051 multiclass 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 1065 let 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 1079 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in 1080 class 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 1106 multiclass 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 1113 multiclass 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 1124 let 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 1136 let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in 1137 class 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 1161 multiclass 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 1169 multiclass 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 1181 let 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)) 1194 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 6, 1195 validSubTargets = HasV4SubT in 1196 def 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)) 1205 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1206 validSubTargets = HasV4SubT in 1207 def 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)) 1218 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 6, 1219 validSubTargets = HasV4SubT in 1220 def 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) 1238 let validSubTargets = HasV4SubT in 1239 def 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) 1247 let validSubTargets = HasV4SubT in 1248 def 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) 1258 let validSubTargets = HasV4SubT in 1259 def 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)) 1271 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1272 validSubTargets = HasV4SubT in 1273 def 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) 1284 let validSubTargets = HasV4SubT in 1285 def 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) 1295 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "reg" in 1296 def 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) 1306 let validSubTargets = HasV4SubT in 1307 def 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) 1318 let validSubTargets = HasV4SubT in 1319 def 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) 1329 let validSubTargets = HasV4SubT in 1330 def 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) 1340 let validSubTargets = HasV4SubT in 1341 def 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) 1352 let validSubTargets = HasV4SubT in 1353 def 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) 1363 let validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "reg" in 1364 def 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) 1374 let validSubTargets = HasV4SubT in 1375 def 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) 1386 let validSubTargets = HasV4SubT in 1387 def 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) 1397 let validSubTargets = HasV4SubT in 1398 def 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) 1408 let validSubTargets = HasV4SubT in 1409 def 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) 1419 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1420 validSubTargets = HasV4SubT, CextOpcode = "ORr_ANDr", InputType = "imm" in 1421 def 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) 1431 let isExtendable = 1, opExtendable = 3, isExtentSigned = 1, opExtentBits = 10, 1432 validSubTargets = HasV4SubT, CextOpcode = "ORr_ORr", InputType = "imm" in 1433 def 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)) 1487 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1488 validSubTargets = HasV4SubT in 1489 def 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)) 1498 def : 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)) 1504 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 6, 1505 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1506 def 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)) 1515 def : 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)) 1521 let validSubTargets = HasV4SubT in 1522 def 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)) 1531 let isExtendable = 1, opExtendable = 3, isExtentSigned = 0, opExtentBits = 6, 1532 validSubTargets = HasV4SubT, InputType = "imm", CextOpcode = "ADD_MPY" in 1533 def 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)) 1542 let validSubTargets = HasV4SubT, InputType = "reg", CextOpcode = "ADD_MPY" in 1543 def 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)) 1593 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1594 validSubTargets = HasV4SubT in 1595 def 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)) 1605 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1606 validSubTargets = HasV4SubT in 1607 def 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)) 1617 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1618 validSubTargets = HasV4SubT in 1619 def 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)) 1629 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1630 validSubTargets = HasV4SubT in 1631 def 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)) 1643 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1644 validSubTargets = HasV4SubT in 1645 def 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)) 1655 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1656 validSubTargets = HasV4SubT in 1657 def 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)) 1667 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1668 AddedComplexity = 30, validSubTargets = HasV4SubT in 1669 def 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)) 1679 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 1680 AddedComplexity = 30, validSubTargets = HasV4SubT in 1681 def 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) 1693 let validSubTargets = HasV4SubT in { 1694 def 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) 1703 def 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) 1713 def 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) 1723 def 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) 1733 def 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 1751 def 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 1758 def 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 1767 def 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 1776 def 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 1783 def 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 1791 def 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 1798 def 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 1806 def 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 1813 def 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 //===----------------------------------------------------------------------===// 1824 class 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 //===----------------------------------------------------------------------===// 1854 class 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. 1883 multiclass 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. 1891 multiclass 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 1898 multiclass 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. 1904 let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, 1905 validSubTargets =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 1923 multiclass 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 1937 multiclass 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 1943 multiclass 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 1952 let 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 1969 multiclass 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 1984 multiclass 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 1993 let 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 2009 multiclass 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 2027 multiclass 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 2042 let 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 2064 multiclass 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 2080 multiclass 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 2091 multiclass 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. 2103 let 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) 2129 let isCompare = 1, validSubTargets = HasV4SubT in 2130 def 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) 2138 let isCompare = 1, validSubTargets = HasV4SubT in 2139 def 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) 2147 let isCompare = 1, validSubTargets = HasV4SubT in 2148 def 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) 2156 let isCompare = 1, validSubTargets = HasV4SubT in 2157 def 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) 2165 let isCompare = 1, validSubTargets = HasV4SubT in 2166 def 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) 2174 let isCompare = 1, validSubTargets = HasV4SubT in 2175 def 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 2182 let isCompare = 1, validSubTargets = HasV4SubT in 2183 def 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 2190 def : 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) 2197 let isCompare = 1, validSubTargets = HasV4SubT in 2198 def 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) 2207 let isCompare = 1, validSubTargets = HasV4SubT in 2208 def 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) 2217 let isCompare = 1, validSubTargets = HasV4SubT in 2218 def 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) 2227 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2228 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in 2229 def 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. 2237 def 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 2249 def : 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 2262 def : 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 2275 def : 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 2288 def : 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 2301 def : 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 2314 def : 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) 2328 def : 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) 2341 def : 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 2353 def : 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) 2375 def : 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) 2388 def : 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 2400 def : 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 2412 def : 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; 2434 let AddedComplexity = 139 in 2435 def : 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) 2443 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", 2444 InputType = "reg" in 2445 def 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) 2457 let isCompare = 1, validSubTargets = HasV4SubT in 2458 def 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) 2471 let isCompare = 1, validSubTargets = HasV4SubT in 2472 def 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) 2486 let isCompare = 1, validSubTargets = HasV4SubT in 2487 def 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 2496 used in the cmph.gt instruction. 2497 // Signed half compare(.gt) ri. 2498 // Pd=cmph.gt(Rs,#s8) 2499 2500 let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 2501 isCompare = 1, validSubTargets = HasV4SubT in 2502 def 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) 2513 let isCompare = 1, validSubTargets = HasV4SubT in 2514 def 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) 2524 let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2525 InputType = "reg" in 2526 def 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) 2536 let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2537 isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 2538 InputType = "imm" in 2539 def 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 2546 let validSubTargets = HasV4SubT in 2547 def 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 2553 let validSubTargets = HasV4SubT in 2554 def 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 2566 let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1, 2567 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in { 2568 let 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. 2576 let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, 2577 Defs = [R29, R30, R31, PC] in { 2578 let 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. 2587 let isCall = 1, isBarrier = 1, 2588 Defs = [R29, R30, R31, PC] in { 2589 let 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. 2598 let 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 2608 let isReturn = 1, isTerminator = 1, 2609 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2610 isPredicated = 1 in { 2611 let 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 2620 let isReturn = 1, isTerminator = 1, 2621 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2622 isPredicated = 1, isPredicatedFalse = 1 in { 2623 let 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 2631 let isReturn = 1, isTerminator = 1, 2632 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2633 isPredicated = 1 in { 2634 let 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 2642 let isReturn = 1, isTerminator = 1, 2643 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2644 isPredicated = 1, isPredicatedFalse = 1 in { 2645 let 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 2653 let isReturn = 1, isTerminator = 1, 2654 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2655 isPredicated = 1 in { 2656 let 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 2664 let isReturn = 1, isTerminator = 1, 2665 Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1, 2666 isPredicated = 1, isPredicatedFalse = 1 in { 2667 let 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 2677 multiclass 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 2688 multiclass 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 2696 let isNVStorable = 1, isExtended = 1, neverHasSideEffects = 1 in 2697 multiclass 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 2713 multiclass 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 2724 multiclass 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 2732 let mayStore = 1, isNVStore = 1, isExtended = 1, neverHasSideEffects = 1 in 2733 multiclass 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 2749 let 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 2766 let Predicates = [HasV4T], AddedComplexity = 30 in { 2767 def : Pat<(truncstorei8 (i32 IntRegs:$src1), 2768 (HexagonCONST32 tglobaladdr:$absaddr)), 2769 (STrib_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2770 2771 def : Pat<(truncstorei16 (i32 IntRegs:$src1), 2772 (HexagonCONST32 tglobaladdr:$absaddr)), 2773 (STrih_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2774 2775 def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), 2776 (STriw_abs_V4 tglobaladdr: $absaddr, IntRegs: $src1)>; 2777 2778 def : 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 //===----------------------------------------------------------------------===// 2788 let mayStore = 1, isNVStorable = 1 in 2789 multiclass 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 2805 let mayStore = 1, isNVStore = 1 in 2806 multiclass 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 2823 let 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 2836 def : 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) 2842 let AddedComplexity = 100 in 2843 def : 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 2848 def : 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) 2853 let AddedComplexity = 100 in 2854 def : 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" 2860 let AddedComplexity = 100 in 2861 def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), 2862 (STb_GP_V4 tglobaladdr:$global, (TFRI 1))>; 2863 2864 def : 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) 2869 let AddedComplexity = 100 in 2870 def : 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 2875 def : 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) 2880 let AddedComplexity = 100 in 2881 def : 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 //===----------------------------------------------------------------------===// 2887 multiclass 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 2898 multiclass 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 2906 let isExtended = 1, neverHasSideEffects = 1 in 2907 multiclass 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 2923 let 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 2939 let Predicates = [HasV4T], AddedComplexity = 30 in { 2940 def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))), 2941 (LDriw_abs_V4 tglobaladdr: $absaddr)>; 2942 2943 def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2944 (LDrib_abs_V4 tglobaladdr:$absaddr)>; 2945 2946 def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 2947 (LDriub_abs_V4 tglobaladdr:$absaddr)>; 2948 2949 def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 2950 (LDrih_abs_V4 tglobaladdr:$absaddr)>; 2951 2952 def : 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 //===----------------------------------------------------------------------===// 2961 let neverHasSideEffects = 1, validSubTargets = HasV4SubT in 2962 multiclass 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 2977 defm LDd_GP : LD_GP<"memd", "LDd_GP", DoubleRegs>, PredNewRel; 2978 defm LDb_GP : LD_GP<"memb", "LDb_GP", IntRegs>, PredNewRel; 2979 defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel; 2980 defm LDh_GP : LD_GP<"memh", "LDh_GP", IntRegs>, PredNewRel; 2981 defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel; 2982 defm LDw_GP : LD_GP<"memw", "LDw_GP", IntRegs>, PredNewRel; 2983 2984 def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)), 2985 (i64 (LDd_GP_V4 tglobaladdr:$global))>; 2986 2987 def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)), 2988 (i32 (LDw_GP_V4 tglobaladdr:$global))>; 2989 2990 def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)), 2991 (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 2992 2993 def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)), 2994 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 2995 2996 // Map from load(globaladdress) -> memw(#foo + 0) 2997 let AddedComplexity = 100 in 2998 def : 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 3002 let AddedComplexity = 100 in 3003 def : 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. 3009 let AddedComplexity = 100 in 3010 def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3011 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3012 3013 let AddedComplexity = 100 in 3014 def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3015 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3016 3017 // Map from load(globaladdress) -> memb(#foo) 3018 let AddedComplexity = 100 in 3019 def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3020 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3021 3022 // Map from load(globaladdress) -> memb(#foo) 3023 let AddedComplexity = 100 in 3024 def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3025 (i32 (LDb_GP_V4 tglobaladdr:$global))>; 3026 3027 let AddedComplexity = 100 in 3028 def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3029 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3030 3031 // Map from load(globaladdress) -> memub(#foo) 3032 let AddedComplexity = 100 in 3033 def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3034 (i32 (LDub_GP_V4 tglobaladdr:$global))>; 3035 3036 // Map from load(globaladdress) -> memh(#foo) 3037 let AddedComplexity = 100 in 3038 def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3039 (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3040 3041 // Map from load(globaladdress) -> memh(#foo) 3042 let AddedComplexity = 100 in 3043 def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3044 (i32 (LDh_GP_V4 tglobaladdr:$global))>; 3045 3046 // Map from load(globaladdress) -> memuh(#foo) 3047 let AddedComplexity = 100 in 3048 def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3049 (i32 (LDuh_GP_V4 tglobaladdr:$global))>; 3050 3051 // Map from load(globaladdress) -> memw(#foo) 3052 let AddedComplexity = 100 in 3053 def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), 3054 (i32 (LDw_GP_V4 tglobaladdr:$global))>; 3055 3056 3057 // Transfer global address into a register 3058 let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1, 3059 isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in 3060 def 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 3066 def : Pat<(HexagonCONST32_GP tblockaddress:$src1), 3067 (TFRI_V4 tblockaddress:$src1)>, 3068 Requires<[HasV4T]>; 3069 3070 let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3071 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3072 def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3073 (ins PredRegs:$src1, s16Ext:$src2), 3074 "if($src1) $dst = #$src2", 3075 []>, 3076 Requires<[HasV4T]>; 3077 3078 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3079 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3080 def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3081 (ins PredRegs:$src1, s16Ext:$src2), 3082 "if(!$src1) $dst = #$src2", 3083 []>, 3084 Requires<[HasV4T]>; 3085 3086 let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3087 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3088 def 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 3094 let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3095 neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in 3096 def 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 3102 let AddedComplexity = 50, Predicates = [HasV4T] in 3103 def : 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 3110 let isExtended = 1, opExtendable = 3, AddedComplexity = 40, 3111 validSubTargets = HasV4SubT in 3112 def 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 3120 let AddedComplexity = 40 in 3121 multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> { 3122 let 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 3133 defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>; 3134 defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>; 3135 defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>; 3136 defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>; 3137 defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>; 3138 defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>; 3139 defm LDriw_ind : LD_indirect_lo<"memw", load>; 3140 3141 let AddedComplexity = 40 in 3142 def : 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 3147 let AddedComplexity = 40 in 3148 def : 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 3153 let Predicates = [HasV4T], AddedComplexity = 30 in { 3154 def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3155 (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3156 3157 def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3158 (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3159 3160 def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3161 (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3162 } 3163 3164 let Predicates = [HasV4T], AddedComplexity = 30 in { 3165 def : Pat<(i32 (load u0AlwaysExtPred:$src)), 3166 (LDriw_abs_V4 u0AlwaysExtPred:$src)>; 3167 3168 def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)), 3169 (LDrib_abs_V4 u0AlwaysExtPred:$src)>; 3170 3171 def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)), 3172 (LDriub_abs_V4 u0AlwaysExtPred:$src)>; 3173 3174 def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)), 3175 (LDrih_abs_V4 u0AlwaysExtPred:$src)>; 3176 3177 def : 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 3183 let AddedComplexity = 10 in 3184 def 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 3191 def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))), 3192 (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>, 3193 Requires<[HasV4T]>; 3194 3195 def : 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. 3203 let Predicates = [HasV4T], AddedComplexity = 120 in { 3204 def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3205 (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>; 3206 3207 def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3208 (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>; 3209 3210 def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3211 (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>; 3212 3213 def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)), 3214 (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>; 3215 3216 def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)), 3217 (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>; 3218 3219 def: 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. 3225 let AddedComplexity = 120 in { 3226 def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3227 (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>, 3228 Requires<[HasV4T]>; 3229 3230 def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3231 (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>, 3232 Requires<[HasV4T]>; 3233 3234 def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3235 (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>, 3236 Requires<[HasV4T]>; 3237 3238 def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)), 3239 (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>, 3240 Requires<[HasV4T]>; 3241 3242 def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)), 3243 (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>, 3244 Requires<[HasV4T]>; 3245 3246 def: 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. 3253 let AddedComplexity = 120 in { 3254 def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3255 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3256 Requires<[HasV4T]>; 3257 3258 def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3259 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>, 3260 Requires<[HasV4T]>; 3261 3262 def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3263 (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>, 3264 Requires<[HasV4T]>; 3265 3266 def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)), 3267 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3268 Requires<[HasV4T]>; 3269 3270 def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)), 3271 (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>, 3272 Requires<[HasV4T]>; 3273 3274 def: 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 3281 let AddedComplexity = 10 in 3282 def 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) 3289 let AddedComplexity = 100 in 3290 def : Pat<(store (i64 DoubleRegs:$src1), 3291 FoldGlobalAddrGP:$addr), 3292 (STrid_abs_V4 FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 3293 Requires<[HasV4T]>; 3294 3295 def : 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) 3301 let AddedComplexity = 100 in 3302 def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3303 (STrib_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3304 Requires<[HasV4T]>; 3305 3306 def : 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) 3311 let AddedComplexity = 100 in 3312 def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3313 (STrih_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3314 Requires<[HasV4T]>; 3315 3316 def : 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) 3321 let AddedComplexity = 100 in 3322 def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 3323 (STriw_abs_V4 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 3324 Requires<[HasV4T]>; 3325 3326 def : 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) 3331 let AddedComplexity = 100 in 3332 def : Pat<(i64 (load FoldGlobalAddrGP:$addr)), 3333 (i64 (LDrid_abs_V4 FoldGlobalAddrGP:$addr))>, 3334 Requires<[HasV4T]>; 3335 3336 def : 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) 3341 let AddedComplexity = 100 in 3342 def : 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) 3347 let AddedComplexity = 100 in 3348 def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)), 3349 (i32 (LDrib_abs_V4 FoldGlobalAddrGP:$addr))>, 3350 Requires<[HasV4T]>; 3351 3352 //let AddedComplexity = 100 in 3353 let AddedComplexity = 100 in 3354 def : 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) 3359 let AddedComplexity = 100 in 3360 def : 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) 3365 let AddedComplexity = 100 in 3366 def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)), 3367 (i32 (LDriuh_abs_V4 FoldGlobalAddrGP:$addr))>, 3368 Requires<[HasV4T]>; 3369 3370 def : 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) 3375 let AddedComplexity = 100 in 3376 def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)), 3377 (i32 (LDriub_abs_V4 FoldGlobalAddrGP:$addr))>, 3378 Requires<[HasV4T]>; 3379 3380 def : 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) 3385 let AddedComplexity = 100 in 3386 def : Pat<(i32 (load FoldGlobalAddrGP:$addr)), 3387 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3388 Requires<[HasV4T]>; 3389 3390 def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr), 3391 (i32 (LDriw_abs_V4 FoldGlobalAddrGP:$addr))>, 3392 Requires<[HasV4T]>; 3393 3394