1//=- HexagonInstrInfoV4.td - Target Desc. for Hexagon Target -*- tablegen -*-=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the Hexagon V4 instructions in TableGen format. 11// 12//===----------------------------------------------------------------------===// 13 14let hasSideEffects = 0 in 15class T_Immext<Operand ImmType> 16 : EXTENDERInst<(outs), (ins ImmType:$imm), 17 "immext(#$imm)", []> { 18 bits<32> imm; 19 let IClass = 0b0000; 20 21 let Inst{27-16} = imm{31-20}; 22 let Inst{13-0} = imm{19-6}; 23 } 24 25def A4_ext : T_Immext<u26_6Imm>; 26let isCodeGenOnly = 1 in { 27 let isBranch = 1 in 28 def A4_ext_b : T_Immext<brtarget>; 29 let isCall = 1 in 30 def A4_ext_c : T_Immext<calltarget>; 31 def A4_ext_g : T_Immext<globaladdress>; 32} 33 34def BITPOS32 : SDNodeXForm<imm, [{ 35 // Return the bit position we will set [0-31]. 36 // As an SDNode. 37 int32_t imm = N->getSExtValue(); 38 return XformMskToBitPosU5Imm(imm); 39}]>; 40 41// Fold (add (CONST32 tglobaladdr:$addr) <offset>) into a global address. 42def FoldGlobalAddr : ComplexPattern<i32, 1, "foldGlobalAddress", [], []>; 43 44// Fold (add (CONST32_GP tglobaladdr:$addr) <offset>) into a global address. 45def FoldGlobalAddrGP : ComplexPattern<i32, 1, "foldGlobalAddressGP", [], []>; 46 47def NumUsesBelowThresCONST32 : PatFrag<(ops node:$addr), 48 (HexagonCONST32 node:$addr), [{ 49 return hasNumUsesBelowThresGA(N->getOperand(0).getNode()); 50}]>; 51 52// Hexagon V4 Architecture spec defines 8 instruction classes: 53// LD ST ALU32 XTYPE J JR MEMOP NV CR SYSTEM(system is not implemented in the 54// compiler) 55 56// LD Instructions: 57// ======================================== 58// Loads (8/16/32/64 bit) 59// Deallocframe 60 61// ST Instructions: 62// ======================================== 63// Stores (8/16/32/64 bit) 64// Allocframe 65 66// ALU32 Instructions: 67// ======================================== 68// Arithmetic / Logical (32 bit) 69// Vector Halfword 70 71// XTYPE Instructions (32/64 bit): 72// ======================================== 73// Arithmetic, Logical, Bit Manipulation 74// Multiply (Integer, Fractional, Complex) 75// Permute / Vector Permute Operations 76// Predicate Operations 77// Shift / Shift with Add/Sub/Logical 78// Vector Byte ALU 79// Vector Halfword (ALU, Shift, Multiply) 80// Vector Word (ALU, Shift) 81 82// J Instructions: 83// ======================================== 84// Jump/Call PC-relative 85 86// JR Instructions: 87// ======================================== 88// Jump/Call Register 89 90// MEMOP Instructions: 91// ======================================== 92// Operation on memory (8/16/32 bit) 93 94// NV Instructions: 95// ======================================== 96// New-value Jumps 97// New-value Stores 98 99// CR Instructions: 100// ======================================== 101// Control-Register Transfers 102// Hardware Loop Setup 103// Predicate Logicals & Reductions 104 105// SYSTEM Instructions (not implemented in the compiler): 106// ======================================== 107// Prefetch 108// Cache Maintenance 109// Bus Operations 110 111 112//===----------------------------------------------------------------------===// 113// ALU32 + 114//===----------------------------------------------------------------------===// 115 116class T_ALU32_3op_not<string mnemonic, bits<3> MajOp, bits<3> MinOp, 117 bit OpsRev> 118 : T_ALU32_3op<mnemonic, MajOp, MinOp, OpsRev, 0> { 119 let AsmString = "$Rd = "#mnemonic#"($Rs, ~$Rt)"; 120} 121 122let BaseOpcode = "andn_rr", CextOpcode = "andn", isCodeGenOnly = 0 in 123def A4_andn : T_ALU32_3op_not<"and", 0b001, 0b100, 1>; 124let BaseOpcode = "orn_rr", CextOpcode = "orn", isCodeGenOnly = 0 in 125def A4_orn : T_ALU32_3op_not<"or", 0b001, 0b101, 1>; 126 127let CextOpcode = "rcmp.eq", isCodeGenOnly = 0 in 128def A4_rcmpeq : T_ALU32_3op<"cmp.eq", 0b011, 0b010, 0, 1>; 129let CextOpcode = "!rcmp.eq", isCodeGenOnly = 0 in 130def A4_rcmpneq : T_ALU32_3op<"!cmp.eq", 0b011, 0b011, 0, 1>; 131 132let isCodeGenOnly = 0 in { 133def C4_cmpneq : T_ALU32_3op_cmp<"!cmp.eq", 0b00, 1, 1>; 134def C4_cmplte : T_ALU32_3op_cmp<"!cmp.gt", 0b10, 1, 0>; 135def C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>; 136} 137 138// Pats for instruction selection. 139 140// A class to embed the usual comparison patfrags within a zext to i32. 141// The seteq/setne frags use "lhs" and "rhs" as operands, so use the same 142// names, or else the frag's "body" won't match the operands. 143class CmpInReg<PatFrag Op> 144 : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>; 145 146def: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>; 147def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>; 148 149class T_CMP_rrbh<string mnemonic, bits<3> MinOp, bit IsComm> 150 : SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt), 151 "$Pd = "#mnemonic#"($Rs, $Rt)", [], "", S_3op_tc_2early_SLOT23>, 152 ImmRegRel { 153 let validSubTargets = HasV4SubT; 154 let InputType = "reg"; 155 let CextOpcode = mnemonic; 156 let isCompare = 1; 157 let isCommutable = IsComm; 158 let hasSideEffects = 0; 159 160 bits<2> Pd; 161 bits<5> Rs; 162 bits<5> Rt; 163 164 let IClass = 0b1100; 165 let Inst{27-21} = 0b0111110; 166 let Inst{20-16} = Rs; 167 let Inst{12-8} = Rt; 168 let Inst{7-5} = MinOp; 169 let Inst{1-0} = Pd; 170} 171 172let isCodeGenOnly = 0 in { 173def A4_cmpbeq : T_CMP_rrbh<"cmpb.eq", 0b110, 1>; 174def A4_cmpbgt : T_CMP_rrbh<"cmpb.gt", 0b010, 0>; 175def A4_cmpbgtu : T_CMP_rrbh<"cmpb.gtu", 0b111, 0>; 176def A4_cmpheq : T_CMP_rrbh<"cmph.eq", 0b011, 1>; 177def A4_cmphgt : T_CMP_rrbh<"cmph.gt", 0b100, 0>; 178def A4_cmphgtu : T_CMP_rrbh<"cmph.gtu", 0b101, 0>; 179} 180 181class T_CMP_ribh<string mnemonic, bits<2> MajOp, bit IsHalf, bit IsComm, 182 Operand ImmType, bit IsImmExt, bit IsImmSigned, int ImmBits> 183 : ALU64Inst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, ImmType:$Imm), 184 "$Pd = "#mnemonic#"($Rs, #$Imm)", [], "", ALU64_tc_2early_SLOT23>, 185 ImmRegRel { 186 let validSubTargets = HasV4SubT; 187 let InputType = "imm"; 188 let CextOpcode = mnemonic; 189 let isCompare = 1; 190 let isCommutable = IsComm; 191 let hasSideEffects = 0; 192 let isExtendable = IsImmExt; 193 let opExtendable = !if (IsImmExt, 2, 0); 194 let isExtentSigned = IsImmSigned; 195 let opExtentBits = ImmBits; 196 197 bits<2> Pd; 198 bits<5> Rs; 199 bits<8> Imm; 200 201 let IClass = 0b1101; 202 let Inst{27-24} = 0b1101; 203 let Inst{22-21} = MajOp; 204 let Inst{20-16} = Rs; 205 let Inst{12-5} = Imm; 206 let Inst{4} = 0b0; 207 let Inst{3} = IsHalf; 208 let Inst{1-0} = Pd; 209} 210 211let isCodeGenOnly = 0 in { 212def A4_cmpbeqi : T_CMP_ribh<"cmpb.eq", 0b00, 0, 1, u8Imm, 0, 0, 8>; 213def A4_cmpbgti : T_CMP_ribh<"cmpb.gt", 0b01, 0, 0, s8Imm, 0, 1, 8>; 214def A4_cmpbgtui : T_CMP_ribh<"cmpb.gtu", 0b10, 0, 0, u7Ext, 1, 0, 7>; 215def A4_cmpheqi : T_CMP_ribh<"cmph.eq", 0b00, 1, 1, s8Ext, 1, 1, 8>; 216def A4_cmphgti : T_CMP_ribh<"cmph.gt", 0b01, 1, 0, s8Ext, 1, 1, 8>; 217def A4_cmphgtui : T_CMP_ribh<"cmph.gtu", 0b10, 1, 0, u7Ext, 1, 0, 7>; 218} 219class T_RCMP_EQ_ri<string mnemonic, bit IsNeg> 220 : ALU32_ri<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s8Ext:$s8), 221 "$Rd = "#mnemonic#"($Rs, #$s8)", [], "", ALU32_2op_tc_1_SLOT0123>, 222 ImmRegRel { 223 let validSubTargets = HasV4SubT; 224 let InputType = "imm"; 225 let CextOpcode = !if (IsNeg, "!rcmp.eq", "rcmp.eq"); 226 let isExtendable = 1; 227 let opExtendable = 2; 228 let isExtentSigned = 1; 229 let opExtentBits = 8; 230 let hasNewValue = 1; 231 232 bits<5> Rd; 233 bits<5> Rs; 234 bits<8> s8; 235 236 let IClass = 0b0111; 237 let Inst{27-24} = 0b0011; 238 let Inst{22} = 0b1; 239 let Inst{21} = IsNeg; 240 let Inst{20-16} = Rs; 241 let Inst{13} = 0b1; 242 let Inst{12-5} = s8; 243 let Inst{4-0} = Rd; 244} 245 246let isCodeGenOnly = 0 in { 247def A4_rcmpeqi : T_RCMP_EQ_ri<"cmp.eq", 0>; 248def A4_rcmpneqi : T_RCMP_EQ_ri<"!cmp.eq", 1>; 249} 250 251def: Pat<(i32 (zext (i1 (seteq (i32 IntRegs:$Rs), s8ExtPred:$s8)))), 252 (A4_rcmpeqi IntRegs:$Rs, s8ExtPred:$s8)>; 253def: Pat<(i32 (zext (i1 (setne (i32 IntRegs:$Rs), s8ExtPred:$s8)))), 254 (A4_rcmpneqi IntRegs:$Rs, s8ExtPred:$s8)>; 255 256// Preserve the S2_tstbit_r generation 257def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))), 258 (i32 IntRegs:$src1))), 0)))), 259 (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>; 260 261 262//===----------------------------------------------------------------------===// 263// ALU32 - 264//===----------------------------------------------------------------------===// 265 266 267//===----------------------------------------------------------------------===// 268// ALU32/PERM + 269//===----------------------------------------------------------------------===// 270 271// Combine a word and an immediate into a register pair. 272let hasSideEffects = 0, isExtentSigned = 1, isExtendable = 1, 273 opExtentBits = 8 in 274class T_Combine1 <bits<2> MajOp, dag ins, string AsmStr> 275 : ALU32Inst <(outs DoubleRegs:$Rdd), ins, AsmStr> { 276 bits<5> Rdd; 277 bits<5> Rs; 278 bits<8> s8; 279 280 let IClass = 0b0111; 281 let Inst{27-24} = 0b0011; 282 let Inst{22-21} = MajOp; 283 let Inst{20-16} = Rs; 284 let Inst{13} = 0b1; 285 let Inst{12-5} = s8; 286 let Inst{4-0} = Rdd; 287 } 288 289let opExtendable = 2, isCodeGenOnly = 0 in 290def A4_combineri : T_Combine1<0b00, (ins IntRegs:$Rs, s8Ext:$s8), 291 "$Rdd = combine($Rs, #$s8)">; 292 293let opExtendable = 1, isCodeGenOnly = 0 in 294def A4_combineir : T_Combine1<0b01, (ins s8Ext:$s8, IntRegs:$Rs), 295 "$Rdd = combine(#$s8, $Rs)">; 296 297def HexagonWrapperCombineRI_V4 : 298 SDNode<"HexagonISD::WrapperCombineRI_V4", SDTHexagonI64I32I32>; 299def HexagonWrapperCombineIR_V4 : 300 SDNode<"HexagonISD::WrapperCombineIR_V4", SDTHexagonI64I32I32>; 301 302def : Pat <(HexagonWrapperCombineRI_V4 IntRegs:$r, s8ExtPred:$i), 303 (A4_combineri IntRegs:$r, s8ExtPred:$i)>, 304 Requires<[HasV4T]>; 305 306def : Pat <(HexagonWrapperCombineIR_V4 s8ExtPred:$i, IntRegs:$r), 307 (A4_combineir s8ExtPred:$i, IntRegs:$r)>, 308 Requires<[HasV4T]>; 309 310// A4_combineii: Set two small immediates. 311let hasSideEffects = 0, isExtendable = 1, opExtentBits = 6, opExtendable = 2 in 312def A4_combineii: ALU32Inst<(outs DoubleRegs:$Rdd), (ins s8Imm:$s8, u6Ext:$U6), 313 "$Rdd = combine(#$s8, #$U6)"> { 314 bits<5> Rdd; 315 bits<8> s8; 316 bits<6> U6; 317 318 let IClass = 0b0111; 319 let Inst{27-23} = 0b11001; 320 let Inst{20-16} = U6{5-1}; 321 let Inst{13} = U6{0}; 322 let Inst{12-5} = s8; 323 let Inst{4-0} = Rdd; 324 } 325 326//===----------------------------------------------------------------------===// 327// ALU32/PERM - 328//===----------------------------------------------------------------------===// 329 330//===----------------------------------------------------------------------===// 331// LD + 332//===----------------------------------------------------------------------===// 333//===----------------------------------------------------------------------===// 334// Template class for load instructions with Absolute set addressing mode. 335//===----------------------------------------------------------------------===// 336let isExtended = 1, opExtendable = 2, hasSideEffects = 0, 337validSubTargets = HasV4SubT, addrMode = AbsoluteSet in 338class T_LD_abs_set<string mnemonic, RegisterClass RC>: 339 LDInst2<(outs RC:$dst1, IntRegs:$dst2), 340 (ins u0AlwaysExt:$addr), 341 "$dst1 = "#mnemonic#"($dst2=##$addr)", 342 []>, 343 Requires<[HasV4T]>; 344 345def LDrid_abs_set_V4 : T_LD_abs_set <"memd", DoubleRegs>; 346def LDrib_abs_set_V4 : T_LD_abs_set <"memb", IntRegs>; 347def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>; 348def LDrih_abs_set_V4 : T_LD_abs_set <"memh", IntRegs>; 349def LDriw_abs_set_V4 : T_LD_abs_set <"memw", IntRegs>; 350def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>; 351 352//===----------------------------------------------------------------------===// 353// Template classes for the non-predicated load instructions with 354// base + register offset addressing mode 355//===----------------------------------------------------------------------===// 356class T_load_rr <string mnemonic, RegisterClass RC, bits<3> MajOp>: 357 LDInst<(outs RC:$dst), (ins IntRegs:$src1, IntRegs:$src2, u2Imm:$u2), 358 "$dst = "#mnemonic#"($src1 + $src2<<#$u2)", 359 [], "", V4LDST_tc_ld_SLOT01>, ImmRegShl, AddrModeRel { 360 bits<5> dst; 361 bits<5> src1; 362 bits<5> src2; 363 bits<2> u2; 364 365 let IClass = 0b0011; 366 367 let Inst{27-24} = 0b1010; 368 let Inst{23-21} = MajOp; 369 let Inst{20-16} = src1; 370 let Inst{12-8} = src2; 371 let Inst{13} = u2{1}; 372 let Inst{7} = u2{0}; 373 let Inst{4-0} = dst; 374 } 375 376//===----------------------------------------------------------------------===// 377// Template classes for the predicated load instructions with 378// base + register offset addressing mode 379//===----------------------------------------------------------------------===// 380let isPredicated = 1 in 381class T_pload_rr <string mnemonic, RegisterClass RC, bits<3> MajOp, 382 bit isNot, bit isPredNew>: 383 LDInst <(outs RC:$dst), 384 (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$u2), 385 !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 386 ") ")#"$dst = "#mnemonic#"($src2+$src3<<#$u2)", 387 [], "", V4LDST_tc_ld_SLOT01>, AddrModeRel { 388 bits<5> dst; 389 bits<2> src1; 390 bits<5> src2; 391 bits<5> src3; 392 bits<2> u2; 393 394 let isPredicatedFalse = isNot; 395 let isPredicatedNew = isPredNew; 396 397 let IClass = 0b0011; 398 399 let Inst{27-26} = 0b00; 400 let Inst{25} = isPredNew; 401 let Inst{24} = isNot; 402 let Inst{23-21} = MajOp; 403 let Inst{20-16} = src2; 404 let Inst{12-8} = src3; 405 let Inst{13} = u2{1}; 406 let Inst{7} = u2{0}; 407 let Inst{6-5} = src1; 408 let Inst{4-0} = dst; 409 } 410 411//===----------------------------------------------------------------------===// 412// multiclass for load instructions with base + register offset 413// addressing mode 414//===----------------------------------------------------------------------===// 415let hasSideEffects = 0, addrMode = BaseRegOffset in 416multiclass ld_idxd_shl <string mnemonic, string CextOp, RegisterClass RC, 417 bits<3> MajOp > { 418 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl, 419 InputType = "reg" in { 420 let isPredicable = 1 in 421 def L4_#NAME#_rr : T_load_rr <mnemonic, RC, MajOp>; 422 423 // Predicated 424 def L4_p#NAME#t_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 0>; 425 def L4_p#NAME#f_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 0>; 426 427 // Predicated new 428 def L4_p#NAME#tnew_rr : T_pload_rr <mnemonic, RC, MajOp, 0, 1>; 429 def L4_p#NAME#fnew_rr : T_pload_rr <mnemonic, RC, MajOp, 1, 1>; 430 } 431} 432 433let hasNewValue = 1, accessSize = ByteAccess, isCodeGenOnly = 0 in { 434 defm loadrb : ld_idxd_shl<"memb", "LDrib", IntRegs, 0b000>; 435 defm loadrub : ld_idxd_shl<"memub", "LDriub", IntRegs, 0b001>; 436} 437 438let hasNewValue = 1, accessSize = HalfWordAccess, isCodeGenOnly = 0 in { 439 defm loadrh : ld_idxd_shl<"memh", "LDrih", IntRegs, 0b010>; 440 defm loadruh : ld_idxd_shl<"memuh", "LDriuh", IntRegs, 0b011>; 441} 442 443let hasNewValue = 1, accessSize = WordAccess, isCodeGenOnly = 0 in 444defm loadri : ld_idxd_shl<"memw", "LDriw", IntRegs, 0b100>; 445 446let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in 447defm loadrd : ld_idxd_shl<"memd", "LDrid", DoubleRegs, 0b110>; 448 449// 'def pats' for load instructions with base + register offset and non-zero 450// immediate value. Immediate value is used to left-shift the second 451// register operand. 452let AddedComplexity = 40 in { 453def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 454 (shl IntRegs:$src2, u2ImmPred:$offset)))), 455 (L4_loadrb_rr IntRegs:$src1, 456 IntRegs:$src2, u2ImmPred:$offset)>, 457 Requires<[HasV4T]>; 458 459def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 460 (shl IntRegs:$src2, u2ImmPred:$offset)))), 461 (L4_loadrub_rr IntRegs:$src1, 462 IntRegs:$src2, u2ImmPred:$offset)>, 463 Requires<[HasV4T]>; 464 465def : Pat <(i32 (extloadi8 (add IntRegs:$src1, 466 (shl IntRegs:$src2, u2ImmPred:$offset)))), 467 (L4_loadrub_rr IntRegs:$src1, 468 IntRegs:$src2, u2ImmPred:$offset)>, 469 Requires<[HasV4T]>; 470 471def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, 472 (shl IntRegs:$src2, u2ImmPred:$offset)))), 473 (L4_loadrh_rr IntRegs:$src1, 474 IntRegs:$src2, u2ImmPred:$offset)>, 475 Requires<[HasV4T]>; 476 477def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, 478 (shl IntRegs:$src2, u2ImmPred:$offset)))), 479 (L4_loadruh_rr IntRegs:$src1, 480 IntRegs:$src2, u2ImmPred:$offset)>, 481 Requires<[HasV4T]>; 482 483def : Pat <(i32 (extloadi16 (add IntRegs:$src1, 484 (shl IntRegs:$src2, u2ImmPred:$offset)))), 485 (L4_loadruh_rr IntRegs:$src1, 486 IntRegs:$src2, u2ImmPred:$offset)>, 487 Requires<[HasV4T]>; 488 489def : Pat <(i32 (load (add IntRegs:$src1, 490 (shl IntRegs:$src2, u2ImmPred:$offset)))), 491 (L4_loadri_rr IntRegs:$src1, 492 IntRegs:$src2, u2ImmPred:$offset)>, 493 Requires<[HasV4T]>; 494 495def : Pat <(i64 (load (add IntRegs:$src1, 496 (shl IntRegs:$src2, u2ImmPred:$offset)))), 497 (L4_loadrd_rr IntRegs:$src1, 498 IntRegs:$src2, u2ImmPred:$offset)>, 499 Requires<[HasV4T]>; 500} 501 502 503// 'def pats' for load instruction base + register offset and 504// zero immediate value. 505let AddedComplexity = 10 in { 506def : Pat <(i64 (load (add IntRegs:$src1, IntRegs:$src2))), 507 (L4_loadrd_rr IntRegs:$src1, IntRegs:$src2, 0)>, 508 Requires<[HasV4T]>; 509 510def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 511 (L4_loadrb_rr IntRegs:$src1, IntRegs:$src2, 0)>, 512 Requires<[HasV4T]>; 513 514def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, IntRegs:$src2))), 515 (L4_loadrub_rr IntRegs:$src1, IntRegs:$src2, 0)>, 516 Requires<[HasV4T]>; 517 518def : Pat <(i32 (extloadi8 (add IntRegs:$src1, IntRegs:$src2))), 519 (L4_loadrub_rr IntRegs:$src1, IntRegs:$src2, 0)>, 520 Requires<[HasV4T]>; 521 522def : Pat <(i32 (sextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 523 (L4_loadrh_rr IntRegs:$src1, IntRegs:$src2, 0)>, 524 Requires<[HasV4T]>; 525 526def : Pat <(i32 (zextloadi16 (add IntRegs:$src1, IntRegs:$src2))), 527 (L4_loadruh_rr IntRegs:$src1, IntRegs:$src2, 0)>, 528 Requires<[HasV4T]>; 529 530def : Pat <(i32 (extloadi16 (add IntRegs:$src1, IntRegs:$src2))), 531 (L4_loadruh_rr IntRegs:$src1, IntRegs:$src2, 0)>, 532 Requires<[HasV4T]>; 533 534def : Pat <(i32 (load (add IntRegs:$src1, IntRegs:$src2))), 535 (L4_loadri_rr IntRegs:$src1, IntRegs:$src2, 0)>, 536 Requires<[HasV4T]>; 537} 538 539// zext i1->i64 540def : Pat <(i64 (zext (i1 PredRegs:$src1))), 541 (i64 (A4_combineir 0, (C2_muxii (i1 PredRegs:$src1), 1, 0)))>, 542 Requires<[HasV4T]>; 543 544// zext i32->i64 545def : Pat <(i64 (zext (i32 IntRegs:$src1))), 546 (i64 (A4_combineir 0, (i32 IntRegs:$src1)))>, 547 Requires<[HasV4T]>; 548// zext i8->i64 549def: Pat <(i64 (zextloadi8 ADDRriS11_0:$src1)), 550 (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>, 551 Requires<[HasV4T]>; 552 553let AddedComplexity = 20 in 554def: Pat <(i64 (zextloadi8 (add (i32 IntRegs:$src1), 555 s11_0ExtPred:$offset))), 556 (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1, 557 s11_0ExtPred:$offset)))>, 558 Requires<[HasV4T]>; 559 560// zext i1->i64 561def: Pat <(i64 (zextloadi1 ADDRriS11_0:$src1)), 562 (i64 (A4_combineir 0, (L2_loadrub_io AddrFI:$src1, 0)))>, 563 Requires<[HasV4T]>; 564 565let AddedComplexity = 20 in 566def: Pat <(i64 (zextloadi1 (add (i32 IntRegs:$src1), 567 s11_0ExtPred:$offset))), 568 (i64 (A4_combineir 0, (L2_loadrub_io IntRegs:$src1, 569 s11_0ExtPred:$offset)))>, 570 Requires<[HasV4T]>; 571 572// zext i16->i64 573def: Pat <(i64 (zextloadi16 ADDRriS11_1:$src1)), 574 (i64 (A4_combineir 0, (L2_loadruh_io AddrFI:$src1, 0)))>, 575 Requires<[HasV4T]>; 576 577let AddedComplexity = 20 in 578def: Pat <(i64 (zextloadi16 (add (i32 IntRegs:$src1), 579 s11_1ExtPred:$offset))), 580 (i64 (A4_combineir 0, (L2_loadruh_io IntRegs:$src1, 581 s11_1ExtPred:$offset)))>, 582 Requires<[HasV4T]>; 583 584// anyext i16->i64 585def: Pat <(i64 (extloadi16 ADDRriS11_2:$src1)), 586 (i64 (A4_combineir 0, (L2_loadrh_io AddrFI:$src1, 0)))>, 587 Requires<[HasV4T]>; 588 589let AddedComplexity = 20 in 590def: Pat <(i64 (extloadi16 (add (i32 IntRegs:$src1), 591 s11_1ExtPred:$offset))), 592 (i64 (A4_combineir 0, (L2_loadrh_io IntRegs:$src1, 593 s11_1ExtPred:$offset)))>, 594 Requires<[HasV4T]>; 595 596// zext i32->i64 597def: Pat <(i64 (zextloadi32 ADDRriS11_2:$src1)), 598 (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>, 599 Requires<[HasV4T]>; 600 601let AddedComplexity = 100 in 602def: Pat <(i64 (zextloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 603 (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1, 604 s11_2ExtPred:$offset)))>, 605 Requires<[HasV4T]>; 606 607// anyext i32->i64 608def: Pat <(i64 (extloadi32 ADDRriS11_2:$src1)), 609 (i64 (A4_combineir 0, (L2_loadri_io AddrFI:$src1, 0)))>, 610 Requires<[HasV4T]>; 611 612let AddedComplexity = 100 in 613def: Pat <(i64 (extloadi32 (i32 (add IntRegs:$src1, s11_2ExtPred:$offset)))), 614 (i64 (A4_combineir 0, (L2_loadri_io IntRegs:$src1, 615 s11_2ExtPred:$offset)))>, 616 Requires<[HasV4T]>; 617 618 619 620//===----------------------------------------------------------------------===// 621// LD - 622//===----------------------------------------------------------------------===// 623 624//===----------------------------------------------------------------------===// 625// ST + 626//===----------------------------------------------------------------------===// 627/// 628//===----------------------------------------------------------------------===// 629// Template class for store instructions with Absolute set addressing mode. 630//===----------------------------------------------------------------------===// 631let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT, 632addrMode = AbsoluteSet in 633class T_ST_abs_set<string mnemonic, RegisterClass RC>: 634 STInst2<(outs IntRegs:$dst1), 635 (ins RC:$src1, u0AlwaysExt:$src2), 636 mnemonic#"($dst1=##$src2) = $src1", 637 []>, 638 Requires<[HasV4T]>; 639 640def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>; 641def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>; 642def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>; 643def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>; 644 645//===----------------------------------------------------------------------===// 646// Template classes for the non-predicated store instructions with 647// base + register offset addressing mode 648//===----------------------------------------------------------------------===// 649let isPredicable = 1 in 650class T_store_rr <string mnemonic, RegisterClass RC, bits<3> MajOp, bit isH> 651 : STInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt), 652 mnemonic#"($Rs + $Ru<<#$u2) = $Rt"#!if(isH, ".h",""), 653 [],"",V4LDST_tc_st_SLOT01>, ImmRegShl, AddrModeRel { 654 655 bits<5> Rs; 656 bits<5> Ru; 657 bits<2> u2; 658 bits<5> Rt; 659 660 let IClass = 0b0011; 661 662 let Inst{27-24} = 0b1011; 663 let Inst{23-21} = MajOp; 664 let Inst{20-16} = Rs; 665 let Inst{12-8} = Ru; 666 let Inst{13} = u2{1}; 667 let Inst{7} = u2{0}; 668 let Inst{4-0} = Rt; 669 } 670 671//===----------------------------------------------------------------------===// 672// Template classes for the predicated store instructions with 673// base + register offset addressing mode 674//===----------------------------------------------------------------------===// 675let isPredicated = 1 in 676class T_pstore_rr <string mnemonic, RegisterClass RC, bits<3> MajOp, 677 bit isNot, bit isPredNew, bit isH> 678 : STInst <(outs), 679 (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, RC:$Rt), 680 681 !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ", 682 ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Rt"#!if(isH, ".h",""), 683 [], "", V4LDST_tc_st_SLOT01> , AddrModeRel{ 684 bits<2> Pv; 685 bits<5> Rs; 686 bits<5> Ru; 687 bits<2> u2; 688 bits<5> Rt; 689 690 let isPredicatedFalse = isNot; 691 let isPredicatedNew = isPredNew; 692 693 let IClass = 0b0011; 694 695 let Inst{27-26} = 0b01; 696 let Inst{25} = isPredNew; 697 let Inst{24} = isNot; 698 let Inst{23-21} = MajOp; 699 let Inst{20-16} = Rs; 700 let Inst{12-8} = Ru; 701 let Inst{13} = u2{1}; 702 let Inst{7} = u2{0}; 703 let Inst{6-5} = Pv; 704 let Inst{4-0} = Rt; 705 } 706 707//===----------------------------------------------------------------------===// 708// Template classes for the new-value store instructions with 709// base + register offset addressing mode 710//===----------------------------------------------------------------------===// 711let isPredicable = 1, isNewValue = 1, opNewValue = 3 in 712class T_store_new_rr <string mnemonic, bits<2> MajOp> : 713 NVInst < (outs ), (ins IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt), 714 mnemonic#"($Rs + $Ru<<#$u2) = $Nt.new", 715 [],"",V4LDST_tc_st_SLOT0>, ImmRegShl, AddrModeRel { 716 717 bits<5> Rs; 718 bits<5> Ru; 719 bits<2> u2; 720 bits<3> Nt; 721 722 let IClass = 0b0011; 723 724 let Inst{27-21} = 0b1011101; 725 let Inst{20-16} = Rs; 726 let Inst{12-8} = Ru; 727 let Inst{13} = u2{1}; 728 let Inst{7} = u2{0}; 729 let Inst{4-3} = MajOp; 730 let Inst{2-0} = Nt; 731 } 732 733//===----------------------------------------------------------------------===// 734// Template classes for the predicated new-value store instructions with 735// base + register offset addressing mode 736//===----------------------------------------------------------------------===// 737let isPredicated = 1, isNewValue = 1, opNewValue = 4 in 738class T_pstore_new_rr <string mnemonic, bits<2> MajOp, bit isNot, bit isPredNew> 739 : NVInst<(outs), 740 (ins PredRegs:$Pv, IntRegs:$Rs, IntRegs:$Ru, u2Imm:$u2, IntRegs:$Nt), 741 !if(isNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ", 742 ") ")#mnemonic#"($Rs+$Ru<<#$u2) = $Nt.new", 743 [], "", V4LDST_tc_st_SLOT0>, AddrModeRel { 744 bits<2> Pv; 745 bits<5> Rs; 746 bits<5> Ru; 747 bits<2> u2; 748 bits<3> Nt; 749 750 let isPredicatedFalse = isNot; 751 let isPredicatedNew = isPredNew; 752 753 let IClass = 0b0011; 754 let Inst{27-26} = 0b01; 755 let Inst{25} = isPredNew; 756 let Inst{24} = isNot; 757 let Inst{23-21} = 0b101; 758 let Inst{20-16} = Rs; 759 let Inst{12-8} = Ru; 760 let Inst{13} = u2{1}; 761 let Inst{7} = u2{0}; 762 let Inst{6-5} = Pv; 763 let Inst{4-3} = MajOp; 764 let Inst{2-0} = Nt; 765 } 766 767//===----------------------------------------------------------------------===// 768// multiclass for store instructions with base + register offset addressing 769// mode 770//===----------------------------------------------------------------------===// 771let isNVStorable = 1 in 772multiclass ST_Idxd_shl<string mnemonic, string CextOp, RegisterClass RC, 773 bits<3> MajOp, bit isH = 0> { 774 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 775 def S4_#NAME#_rr : T_store_rr <mnemonic, RC, MajOp, isH>; 776 777 // Predicated 778 def S4_p#NAME#t_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 0, isH>; 779 def S4_p#NAME#f_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 0, isH>; 780 781 // Predicated new 782 def S4_p#NAME#tnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 0, 1, isH>; 783 def S4_p#NAME#fnew_rr : T_pstore_rr <mnemonic, RC, MajOp, 1, 1, isH>; 784 } 785} 786 787//===----------------------------------------------------------------------===// 788// multiclass for new-value store instructions with base + register offset 789// addressing mode. 790//===----------------------------------------------------------------------===// 791let mayStore = 1, isNVStore = 1 in 792multiclass ST_Idxd_shl_nv <string mnemonic, string CextOp, RegisterClass RC, 793 bits<2> MajOp> { 794 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed_shl in { 795 def S4_#NAME#new_rr : T_store_new_rr<mnemonic, MajOp>; 796 797 // Predicated 798 def S4_p#NAME#newt_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 0>; 799 def S4_p#NAME#newf_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 0>; 800 801 // Predicated new 802 def S4_p#NAME#newtnew_rr : T_pstore_new_rr <mnemonic, MajOp, 0, 1>; 803 def S4_p#NAME#newfnew_rr : T_pstore_new_rr <mnemonic, MajOp, 1, 1>; 804 } 805} 806 807let addrMode = BaseRegOffset, InputType = "reg", hasSideEffects = 0, 808 isCodeGenOnly = 0 in { 809 let accessSize = ByteAccess in 810 defm storerb: ST_Idxd_shl<"memb", "STrib", IntRegs, 0b000>, 811 ST_Idxd_shl_nv<"memb", "STrib", IntRegs, 0b00>; 812 813 let accessSize = HalfWordAccess in 814 defm storerh: ST_Idxd_shl<"memh", "STrih", IntRegs, 0b010>, 815 ST_Idxd_shl_nv<"memh", "STrih", IntRegs, 0b01>; 816 817 let accessSize = WordAccess in 818 defm storeri: ST_Idxd_shl<"memw", "STriw", IntRegs, 0b100>, 819 ST_Idxd_shl_nv<"memw", "STriw", IntRegs, 0b10>; 820 821 let isNVStorable = 0, accessSize = DoubleWordAccess in 822 defm storerd: ST_Idxd_shl<"memd", "STrid", DoubleRegs, 0b110>; 823 824 let isNVStorable = 0, accessSize = HalfWordAccess in 825 defm storerf: ST_Idxd_shl<"memh", "STrif", IntRegs, 0b011, 1>; 826} 827 828let Predicates = [HasV4T], AddedComplexity = 10 in { 829def : Pat<(truncstorei8 (i32 IntRegs:$src4), 830 (add IntRegs:$src1, (shl IntRegs:$src2, 831 u2ImmPred:$src3))), 832 (S4_storerb_rr IntRegs:$src1, IntRegs:$src2, 833 u2ImmPred:$src3, IntRegs:$src4)>; 834 835def : Pat<(truncstorei16 (i32 IntRegs:$src4), 836 (add IntRegs:$src1, (shl IntRegs:$src2, 837 u2ImmPred:$src3))), 838 (S4_storerh_rr IntRegs:$src1, IntRegs:$src2, 839 u2ImmPred:$src3, IntRegs:$src4)>; 840 841def : Pat<(store (i32 IntRegs:$src4), 842 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 843 (S4_storeri_rr IntRegs:$src1, IntRegs:$src2, 844 u2ImmPred:$src3, IntRegs:$src4)>; 845 846def : Pat<(store (i64 DoubleRegs:$src4), 847 (add IntRegs:$src1, (shl IntRegs:$src2, u2ImmPred:$src3))), 848 (S4_storerd_rr IntRegs:$src1, IntRegs:$src2, 849 u2ImmPred:$src3, DoubleRegs:$src4)>; 850} 851 852let isExtended = 1, opExtendable = 2 in 853class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> : 854 STInst<(outs), 855 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4), 856 mnemonic#"($src1<<#$src2+##$src3) = $src4", 857 [(stOp (VT RC:$src4), 858 (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2), 859 u0AlwaysExtPred:$src3))]>, 860 Requires<[HasV4T]>; 861 862let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in 863class T_ST_LongOff_nv <string mnemonic> : 864 NVInst_V4<(outs), 865 (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4), 866 mnemonic#"($src1<<#$src2+##$src3) = $src4.new", 867 []>, 868 Requires<[HasV4T]>; 869 870multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> { 871 let BaseOpcode = BaseOp#"_shl" in { 872 let isNVStorable = 1 in 873 def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>; 874 875 def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>; 876 } 877} 878 879let AddedComplexity = 10, validSubTargets = HasV4SubT in { 880 def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>; 881 defm STrib_shl : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel; 882 defm STrih_shl : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel; 883 defm STriw_shl : ST_LongOff <"memw", "STriw", store>, NewValueRel; 884} 885 886let AddedComplexity = 40 in 887multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT, 888 PatFrag stOp> { 889 def : Pat<(stOp (VT RC:$src4), 890 (add (shl IntRegs:$src1, u2ImmPred:$src2), 891 (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 892 (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>; 893 894 def : Pat<(stOp (VT RC:$src4), 895 (add IntRegs:$src1, 896 (NumUsesBelowThresCONST32 tglobaladdr:$src3))), 897 (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>; 898} 899 900defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>; 901defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>; 902defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>; 903defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>; 904 905// memd(Rx++#s4:3)=Rtt 906// memd(Rx++#s4:3:circ(Mu))=Rtt 907// memd(Rx++I:circ(Mu))=Rtt 908// memd(Rx++Mu)=Rtt 909// memd(Rx++Mu:brev)=Rtt 910// memd(gp+#u16:3)=Rtt 911 912// Store doubleword conditionally. 913// if ([!]Pv[.new]) memd(#u6)=Rtt 914// TODO: needs to be implemented. 915 916//===----------------------------------------------------------------------===// 917// Template class 918//===----------------------------------------------------------------------===// 919let isPredicable = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 8, 920 opExtendable = 2 in 921class T_StoreImm <string mnemonic, Operand OffsetOp, bits<2> MajOp > 922 : STInst <(outs ), (ins IntRegs:$Rs, OffsetOp:$offset, s8Ext:$S8), 923 mnemonic#"($Rs+#$offset)=#$S8", 924 [], "", V4LDST_tc_st_SLOT01>, 925 ImmRegRel, PredNewRel { 926 bits<5> Rs; 927 bits<8> S8; 928 bits<8> offset; 929 bits<6> offsetBits; 930 931 string OffsetOpStr = !cast<string>(OffsetOp); 932 let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2}, 933 !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1}, 934 /* u6_0Imm */ offset{5-0})); 935 936 let IClass = 0b0011; 937 938 let Inst{27-25} = 0b110; 939 let Inst{22-21} = MajOp; 940 let Inst{20-16} = Rs; 941 let Inst{12-7} = offsetBits; 942 let Inst{13} = S8{7}; 943 let Inst{6-0} = S8{6-0}; 944 } 945 946let isPredicated = 1, isExtendable = 1, isExtentSigned = 1, opExtentBits = 6, 947 opExtendable = 3 in 948class T_StoreImm_pred <string mnemonic, Operand OffsetOp, bits<2> MajOp, 949 bit isPredNot, bit isPredNew > 950 : STInst <(outs ), 951 (ins PredRegs:$Pv, IntRegs:$Rs, OffsetOp:$offset, s6Ext:$S6), 952 !if(isPredNot, "if (!$Pv", "if ($Pv")#!if(isPredNew, ".new) ", 953 ") ")#mnemonic#"($Rs+#$offset)=#$S6", 954 [], "", V4LDST_tc_st_SLOT01>, 955 ImmRegRel, PredNewRel { 956 bits<2> Pv; 957 bits<5> Rs; 958 bits<6> S6; 959 bits<8> offset; 960 bits<6> offsetBits; 961 962 string OffsetOpStr = !cast<string>(OffsetOp); 963 let offsetBits = !if (!eq(OffsetOpStr, "u6_2Imm"), offset{7-2}, 964 !if (!eq(OffsetOpStr, "u6_1Imm"), offset{6-1}, 965 /* u6_0Imm */ offset{5-0})); 966 let isPredicatedNew = isPredNew; 967 let isPredicatedFalse = isPredNot; 968 969 let IClass = 0b0011; 970 971 let Inst{27-25} = 0b100; 972 let Inst{24} = isPredNew; 973 let Inst{23} = isPredNot; 974 let Inst{22-21} = MajOp; 975 let Inst{20-16} = Rs; 976 let Inst{13} = S6{5}; 977 let Inst{12-7} = offsetBits; 978 let Inst{6-5} = Pv; 979 let Inst{4-0} = S6{4-0}; 980 } 981 982 983//===----------------------------------------------------------------------===// 984// multiclass for store instructions with base + immediate offset 985// addressing mode and immediate stored value. 986// mem[bhw](Rx++#s4:3)=#s8 987// if ([!]Pv[.new]) mem[bhw](Rx++#s4:3)=#s6 988//===----------------------------------------------------------------------===// 989 990multiclass ST_Imm_Pred <string mnemonic, Operand OffsetOp, bits<2> MajOp, 991 bit PredNot> { 992 def _io : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 0>; 993 // Predicate new 994 def new_io : T_StoreImm_pred <mnemonic, OffsetOp, MajOp, PredNot, 1>; 995} 996 997multiclass ST_Imm <string mnemonic, string CextOp, Operand OffsetOp, 998 bits<2> MajOp> { 999 let CextOpcode = CextOp, BaseOpcode = CextOp#_imm in { 1000 def _io : T_StoreImm <mnemonic, OffsetOp, MajOp>; 1001 1002 defm t : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 0>; 1003 defm f : ST_Imm_Pred <mnemonic, OffsetOp, MajOp, 1>; 1004 } 1005} 1006 1007let hasSideEffects = 0, validSubTargets = HasV4SubT, addrMode = BaseImmOffset, 1008 InputType = "imm", isCodeGenOnly = 0 in { 1009 let accessSize = ByteAccess in 1010 defm S4_storeirb : ST_Imm<"memb", "STrib", u6_0Imm, 0b00>; 1011 1012 let accessSize = HalfWordAccess in 1013 defm S4_storeirh : ST_Imm<"memh", "STrih", u6_1Imm, 0b01>; 1014 1015 let accessSize = WordAccess in 1016 defm S4_storeiri : ST_Imm<"memw", "STriw", u6_2Imm, 0b10>; 1017} 1018 1019let Predicates = [HasV4T], AddedComplexity = 10 in { 1020def: Pat<(truncstorei8 s8ExtPred:$src3, (add IntRegs:$src1, u6_0ImmPred:$src2)), 1021 (S4_storeirb_io IntRegs:$src1, u6_0ImmPred:$src2, s8ExtPred:$src3)>; 1022 1023def: Pat<(truncstorei16 s8ExtPred:$src3, (add IntRegs:$src1, 1024 u6_1ImmPred:$src2)), 1025 (S4_storeirh_io IntRegs:$src1, u6_1ImmPred:$src2, s8ExtPred:$src3)>; 1026 1027def: Pat<(store s8ExtPred:$src3, (add IntRegs:$src1, u6_2ImmPred:$src2)), 1028 (S4_storeiri_io IntRegs:$src1, u6_2ImmPred:$src2, s8ExtPred:$src3)>; 1029} 1030 1031let AddedComplexity = 6 in 1032def : Pat <(truncstorei8 s8ExtPred:$src2, (i32 IntRegs:$src1)), 1033 (S4_storeirb_io IntRegs:$src1, 0, s8ExtPred:$src2)>, 1034 Requires<[HasV4T]>; 1035 1036// memb(Rx++#s4:0:circ(Mu))=Rt 1037// memb(Rx++I:circ(Mu))=Rt 1038// memb(Rx++Mu)=Rt 1039// memb(Rx++Mu:brev)=Rt 1040// memb(gp+#u16:0)=Rt 1041 1042 1043// Store halfword. 1044// TODO: needs to be implemented 1045// memh(Re=#U6)=Rt.H 1046// memh(Rs+#s11:1)=Rt.H 1047let AddedComplexity = 6 in 1048def : Pat <(truncstorei16 s8ExtPred:$src2, (i32 IntRegs:$src1)), 1049 (S4_storeirh_io IntRegs:$src1, 0, s8ExtPred:$src2)>, 1050 Requires<[HasV4T]>; 1051 1052// memh(Rs+Ru<<#u2)=Rt.H 1053// TODO: needs to be implemented. 1054 1055// memh(Ru<<#u2+#U6)=Rt.H 1056// memh(Rx++#s4:1:circ(Mu))=Rt.H 1057// memh(Rx++#s4:1:circ(Mu))=Rt 1058// memh(Rx++I:circ(Mu))=Rt.H 1059// memh(Rx++I:circ(Mu))=Rt 1060// memh(Rx++Mu)=Rt.H 1061// memh(Rx++Mu)=Rt 1062// memh(Rx++Mu:brev)=Rt.H 1063// memh(Rx++Mu:brev)=Rt 1064// memh(gp+#u16:1)=Rt 1065// if ([!]Pv[.new]) memh(#u6)=Rt.H 1066// if ([!]Pv[.new]) memh(#u6)=Rt 1067 1068 1069// if ([!]Pv[.new]) memh(Rs+#u6:1)=Rt.H 1070// TODO: needs to be implemented. 1071 1072// if ([!]Pv[.new]) memh(Rx++#s4:1)=Rt.H 1073// TODO: Needs to be implemented. 1074 1075// Store word. 1076// memw(Re=#U6)=Rt 1077// TODO: Needs to be implemented. 1078 1079// Store predicate: 1080let hasSideEffects = 0 in 1081def STriw_pred_V4 : STInst2<(outs), 1082 (ins MEMri:$addr, PredRegs:$src1), 1083 "Error; should not emit", 1084 []>, 1085 Requires<[HasV4T]>; 1086 1087let AddedComplexity = 6 in 1088def : Pat <(store s8ExtPred:$src2, (i32 IntRegs:$src1)), 1089 (S4_storeiri_io IntRegs:$src1, 0, s8ExtPred:$src2)>, 1090 Requires<[HasV4T]>; 1091 1092// memw(Rx++#s4:2)=Rt 1093// memw(Rx++#s4:2:circ(Mu))=Rt 1094// memw(Rx++I:circ(Mu))=Rt 1095// memw(Rx++Mu)=Rt 1096// memw(Rx++Mu:brev)=Rt 1097 1098//===----------------------------------------------------------------------=== 1099// ST - 1100//===----------------------------------------------------------------------=== 1101 1102 1103//===----------------------------------------------------------------------===// 1104// NV/ST + 1105//===----------------------------------------------------------------------===// 1106 1107let opNewValue = 2, opExtendable = 1, isExtentSigned = 1, isPredicable = 1 in 1108class T_store_io_nv <string mnemonic, RegisterClass RC, 1109 Operand ImmOp, bits<2>MajOp> 1110 : NVInst_V4 <(outs), 1111 (ins IntRegs:$src1, ImmOp:$src2, RC:$src3), 1112 mnemonic#"($src1+#$src2) = $src3.new", 1113 [],"",ST_tc_st_SLOT0> { 1114 bits<5> src1; 1115 bits<13> src2; // Actual address offset 1116 bits<3> src3; 1117 bits<11> offsetBits; // Represents offset encoding 1118 1119 let opExtentBits = !if (!eq(mnemonic, "memb"), 11, 1120 !if (!eq(mnemonic, "memh"), 12, 1121 !if (!eq(mnemonic, "memw"), 13, 0))); 1122 1123 let opExtentAlign = !if (!eq(mnemonic, "memb"), 0, 1124 !if (!eq(mnemonic, "memh"), 1, 1125 !if (!eq(mnemonic, "memw"), 2, 0))); 1126 1127 let offsetBits = !if (!eq(mnemonic, "memb"), src2{10-0}, 1128 !if (!eq(mnemonic, "memh"), src2{11-1}, 1129 !if (!eq(mnemonic, "memw"), src2{12-2}, 0))); 1130 1131 let IClass = 0b1010; 1132 1133 let Inst{27} = 0b0; 1134 let Inst{26-25} = offsetBits{10-9}; 1135 let Inst{24-21} = 0b1101; 1136 let Inst{20-16} = src1; 1137 let Inst{13} = offsetBits{8}; 1138 let Inst{12-11} = MajOp; 1139 let Inst{10-8} = src3; 1140 let Inst{7-0} = offsetBits{7-0}; 1141 } 1142 1143let opExtendable = 2, opNewValue = 3, isPredicated = 1 in 1144class T_pstore_io_nv <string mnemonic, RegisterClass RC, Operand predImmOp, 1145 bits<2>MajOp, bit PredNot, bit isPredNew> 1146 : NVInst_V4 <(outs), 1147 (ins PredRegs:$src1, IntRegs:$src2, predImmOp:$src3, RC:$src4), 1148 !if(PredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1149 ") ")#mnemonic#"($src2+#$src3) = $src4.new", 1150 [],"",V2LDST_tc_st_SLOT0> { 1151 bits<2> src1; 1152 bits<5> src2; 1153 bits<9> src3; 1154 bits<3> src4; 1155 bits<6> offsetBits; // Represents offset encoding 1156 1157 let isPredicatedNew = isPredNew; 1158 let isPredicatedFalse = PredNot; 1159 let opExtentBits = !if (!eq(mnemonic, "memb"), 6, 1160 !if (!eq(mnemonic, "memh"), 7, 1161 !if (!eq(mnemonic, "memw"), 8, 0))); 1162 1163 let opExtentAlign = !if (!eq(mnemonic, "memb"), 0, 1164 !if (!eq(mnemonic, "memh"), 1, 1165 !if (!eq(mnemonic, "memw"), 2, 0))); 1166 1167 let offsetBits = !if (!eq(mnemonic, "memb"), src3{5-0}, 1168 !if (!eq(mnemonic, "memh"), src3{6-1}, 1169 !if (!eq(mnemonic, "memw"), src3{7-2}, 0))); 1170 1171 let IClass = 0b0100; 1172 1173 let Inst{27} = 0b0; 1174 let Inst{26} = PredNot; 1175 let Inst{25} = isPredNew; 1176 let Inst{24-21} = 0b0101; 1177 let Inst{20-16} = src2; 1178 let Inst{13} = offsetBits{5}; 1179 let Inst{12-11} = MajOp; 1180 let Inst{10-8} = src4; 1181 let Inst{7-3} = offsetBits{4-0}; 1182 let Inst{2} = 0b0; 1183 let Inst{1-0} = src1; 1184 } 1185 1186// multiclass for new-value store instructions with base + immediate offset. 1187// 1188let mayStore = 1, isNVStore = 1, isNewValue = 1, hasSideEffects = 0, 1189 isExtendable = 1 in 1190multiclass ST_Idxd_nv<string mnemonic, string CextOp, RegisterClass RC, 1191 Operand ImmOp, Operand predImmOp, bits<2> MajOp> { 1192 1193 let CextOpcode = CextOp, BaseOpcode = CextOp#_indexed in { 1194 def S2_#NAME#new_io : T_store_io_nv <mnemonic, RC, ImmOp, MajOp>; 1195 // Predicated 1196 def S2_p#NAME#newt_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 0, 0>; 1197 def S2_p#NAME#newf_io :T_pstore_io_nv <mnemonic, RC, predImmOp, MajOp, 1, 0>; 1198 // Predicated new 1199 def S4_p#NAME#newtnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp, 1200 MajOp, 0, 1>; 1201 def S4_p#NAME#newfnew_io :T_pstore_io_nv <mnemonic, RC, predImmOp, 1202 MajOp, 1, 1>; 1203 } 1204} 1205 1206let addrMode = BaseImmOffset, InputType = "imm", isCodeGenOnly = 0 in { 1207 let accessSize = ByteAccess in 1208 defm storerb: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext, 1209 u6_0Ext, 0b00>, AddrModeRel; 1210 1211 let accessSize = HalfWordAccess, opExtentAlign = 1 in 1212 defm storerh: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext, 1213 u6_1Ext, 0b01>, AddrModeRel; 1214 1215 let accessSize = WordAccess, opExtentAlign = 2 in 1216 defm storeri: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext, 1217 u6_2Ext, 0b10>, AddrModeRel; 1218} 1219 1220//===----------------------------------------------------------------------===// 1221// Template class for non-predicated post increment .new stores 1222// mem[bhwd](Rx++#s4:[0123])=Nt.new 1223//===----------------------------------------------------------------------===// 1224let isPredicable = 1, hasSideEffects = 0, validSubTargets = HasV4SubT, 1225 addrMode = PostInc, isNVStore = 1, isNewValue = 1, opNewValue = 3 in 1226class T_StorePI_nv <string mnemonic, Operand ImmOp, bits<2> MajOp > 1227 : NVInstPI_V4 <(outs IntRegs:$_dst_), 1228 (ins IntRegs:$src1, ImmOp:$offset, IntRegs:$src2), 1229 mnemonic#"($src1++#$offset) = $src2.new", 1230 [], "$src1 = $_dst_">, 1231 AddrModeRel { 1232 bits<5> src1; 1233 bits<3> src2; 1234 bits<7> offset; 1235 bits<4> offsetBits; 1236 1237 string ImmOpStr = !cast<string>(ImmOp); 1238 let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2}, 1239 !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1}, 1240 /* s4_0Imm */ offset{3-0})); 1241 let IClass = 0b1010; 1242 1243 let Inst{27-21} = 0b1011101; 1244 let Inst{20-16} = src1; 1245 let Inst{13} = 0b0; 1246 let Inst{12-11} = MajOp; 1247 let Inst{10-8} = src2; 1248 let Inst{7} = 0b0; 1249 let Inst{6-3} = offsetBits; 1250 let Inst{1} = 0b0; 1251 } 1252 1253//===----------------------------------------------------------------------===// 1254// Template class for predicated post increment .new stores 1255// if([!]Pv[.new]) mem[bhwd](Rx++#s4:[0123])=Nt.new 1256//===----------------------------------------------------------------------===// 1257let isPredicated = 1, hasSideEffects = 0, validSubTargets = HasV4SubT, 1258 addrMode = PostInc, isNVStore = 1, isNewValue = 1, opNewValue = 4 in 1259class T_StorePI_nv_pred <string mnemonic, Operand ImmOp, 1260 bits<2> MajOp, bit isPredNot, bit isPredNew > 1261 : NVInstPI_V4 <(outs IntRegs:$_dst_), 1262 (ins PredRegs:$src1, IntRegs:$src2, 1263 ImmOp:$offset, IntRegs:$src3), 1264 !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 1265 ") ")#mnemonic#"($src2++#$offset) = $src3.new", 1266 [], "$src2 = $_dst_">, 1267 AddrModeRel { 1268 bits<2> src1; 1269 bits<5> src2; 1270 bits<3> src3; 1271 bits<7> offset; 1272 bits<4> offsetBits; 1273 1274 string ImmOpStr = !cast<string>(ImmOp); 1275 let offsetBits = !if (!eq(ImmOpStr, "s4_2Imm"), offset{5-2}, 1276 !if (!eq(ImmOpStr, "s4_1Imm"), offset{4-1}, 1277 /* s4_0Imm */ offset{3-0})); 1278 let isPredicatedNew = isPredNew; 1279 let isPredicatedFalse = isPredNot; 1280 1281 let IClass = 0b1010; 1282 1283 let Inst{27-21} = 0b1011101; 1284 let Inst{20-16} = src2; 1285 let Inst{13} = 0b1; 1286 let Inst{12-11} = MajOp; 1287 let Inst{10-8} = src3; 1288 let Inst{7} = isPredNew; 1289 let Inst{6-3} = offsetBits; 1290 let Inst{2} = isPredNot; 1291 let Inst{1-0} = src1; 1292 } 1293 1294multiclass ST_PostInc_Pred_nv<string mnemonic, Operand ImmOp, 1295 bits<2> MajOp, bit PredNot> { 1296 def _pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 0>; 1297 1298 // Predicate new 1299 def new_pi : T_StorePI_nv_pred <mnemonic, ImmOp, MajOp, PredNot, 1>; 1300} 1301 1302multiclass ST_PostInc_nv<string mnemonic, string BaseOp, Operand ImmOp, 1303 bits<2> MajOp> { 1304 let BaseOpcode = "POST_"#BaseOp in { 1305 def S2_#NAME#_pi : T_StorePI_nv <mnemonic, ImmOp, MajOp>; 1306 1307 // Predicated 1308 defm S2_p#NAME#t : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 0>; 1309 defm S2_p#NAME#f : ST_PostInc_Pred_nv <mnemonic, ImmOp, MajOp, 1>; 1310 } 1311} 1312 1313let accessSize = ByteAccess, isCodeGenOnly = 0 in 1314defm storerbnew: ST_PostInc_nv <"memb", "STrib", s4_0Imm, 0b00>; 1315 1316let accessSize = HalfWordAccess, isCodeGenOnly = 0 in 1317defm storerhnew: ST_PostInc_nv <"memh", "STrih", s4_1Imm, 0b01>; 1318 1319let accessSize = WordAccess, isCodeGenOnly = 0 in 1320defm storerinew: ST_PostInc_nv <"memw", "STriw", s4_2Imm, 0b10>; 1321 1322//===----------------------------------------------------------------------===// 1323// Template class for post increment .new stores with register offset 1324//===----------------------------------------------------------------------===// 1325let isNewValue = 1, mayStore = 1, isNVStore = 1, opNewValue = 3 in 1326class T_StorePI_RegNV <string mnemonic, bits<2> MajOp, MemAccessSize AccessSz> 1327 : NVInstPI_V4 <(outs IntRegs:$_dst_), 1328 (ins IntRegs:$src1, ModRegs:$src2, IntRegs:$src3), 1329 #mnemonic#"($src1++$src2) = $src3.new", 1330 [], "$src1 = $_dst_"> { 1331 bits<5> src1; 1332 bits<1> src2; 1333 bits<3> src3; 1334 let accessSize = AccessSz; 1335 1336 let IClass = 0b1010; 1337 1338 let Inst{27-21} = 0b1101101; 1339 let Inst{20-16} = src1; 1340 let Inst{13} = src2; 1341 let Inst{12-11} = MajOp; 1342 let Inst{10-8} = src3; 1343 let Inst{7} = 0b0; 1344 } 1345 1346let isCodeGenOnly = 0 in { 1347def S2_storerbnew_pr : T_StorePI_RegNV<"memb", 0b00, ByteAccess>; 1348def S2_storerhnew_pr : T_StorePI_RegNV<"memh", 0b01, HalfWordAccess>; 1349def S2_storerinew_pr : T_StorePI_RegNV<"memw", 0b10, WordAccess>; 1350} 1351 1352// memb(Rx++#s4:0:circ(Mu))=Nt.new 1353// memb(Rx++I:circ(Mu))=Nt.new 1354// memb(Rx++Mu)=Nt.new 1355// memb(Rx++Mu:brev)=Nt.new 1356// memh(Rx++#s4:1:circ(Mu))=Nt.new 1357// memh(Rx++I:circ(Mu))=Nt.new 1358// memh(Rx++Mu)=Nt.new 1359// memh(Rx++Mu:brev)=Nt.new 1360 1361// memw(Rx++#s4:2:circ(Mu))=Nt.new 1362// memw(Rx++I:circ(Mu))=Nt.new 1363// memw(Rx++Mu)=Nt.new 1364// memw(Rx++Mu:brev)=Nt.new 1365 1366//===----------------------------------------------------------------------===// 1367// NV/ST - 1368//===----------------------------------------------------------------------===// 1369 1370//===----------------------------------------------------------------------===// 1371// NV/J + 1372//===----------------------------------------------------------------------===// 1373 1374//===----------------------------------------------------------------------===// 1375// multiclass/template class for the new-value compare jumps with the register 1376// operands. 1377//===----------------------------------------------------------------------===// 1378 1379let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11, 1380 opExtentAlign = 2 in 1381class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum, 1382 bit isNegCond, bit isTak> 1383 : NVInst_V4<(outs), 1384 (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset), 1385 "if ("#!if(isNegCond, "!","")#mnemonic# 1386 "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")# 1387 "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:" 1388 #!if(isTak, "t","nt")#" $offset", []> { 1389 1390 bits<5> src1; 1391 bits<5> src2; 1392 bits<3> Ns; // New-Value Operand 1393 bits<5> RegOp; // Non-New-Value Operand 1394 bits<11> offset; 1395 1396 let isTaken = isTak; 1397 let isPredicatedFalse = isNegCond; 1398 let opNewValue{0} = NvOpNum; 1399 1400 let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0}); 1401 let RegOp = !if(!eq(NvOpNum, 0), src2, src1); 1402 1403 let IClass = 0b0010; 1404 let Inst{26} = 0b0; 1405 let Inst{25-23} = majOp; 1406 let Inst{22} = isNegCond; 1407 let Inst{18-16} = Ns; 1408 let Inst{13} = isTak; 1409 let Inst{12-8} = RegOp; 1410 let Inst{21-20} = offset{10-9}; 1411 let Inst{7-1} = offset{8-2}; 1412} 1413 1414 1415multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum, 1416 bit isNegCond> { 1417 // Branch not taken: 1418 def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>; 1419 // Branch taken: 1420 def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>; 1421} 1422 1423// NvOpNum = 0 -> First Operand is a new-value Register 1424// NvOpNum = 1 -> Second Operand is a new-value Register 1425 1426multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp, 1427 bit NvOpNum> { 1428 let BaseOpcode = BaseOp#_NVJ in { 1429 defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond 1430 defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond 1431 } 1432} 1433 1434// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2 1435// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2 1436// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2 1437// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2 1438// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2 1439 1440let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1441 Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT, 1442 isCodeGenOnly = 0 in { 1443 defm CMPEQrr : NVJrr_base<"cmp.eq", "CMPEQ", 0b000, 0>, PredRel; 1444 defm CMPGTrr : NVJrr_base<"cmp.gt", "CMPGT", 0b001, 0>, PredRel; 1445 defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel; 1446 defm CMPLTrr : NVJrr_base<"cmp.gt", "CMPLT", 0b011, 1>, PredRel; 1447 defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel; 1448} 1449 1450//===----------------------------------------------------------------------===// 1451// multiclass/template class for the new-value compare jumps instruction 1452// with a register and an unsigned immediate (U5) operand. 1453//===----------------------------------------------------------------------===// 1454 1455let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11, 1456 opExtentAlign = 2 in 1457class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond, 1458 bit isTak> 1459 : NVInst_V4<(outs), 1460 (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset), 1461 "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:" 1462 #!if(isTak, "t","nt")#" $offset", []> { 1463 1464 let isTaken = isTak; 1465 let isPredicatedFalse = isNegCond; 1466 let isTaken = isTak; 1467 1468 bits<3> src1; 1469 bits<5> src2; 1470 bits<11> offset; 1471 1472 let IClass = 0b0010; 1473 let Inst{26} = 0b1; 1474 let Inst{25-23} = majOp; 1475 let Inst{22} = isNegCond; 1476 let Inst{18-16} = src1; 1477 let Inst{13} = isTak; 1478 let Inst{12-8} = src2; 1479 let Inst{21-20} = offset{10-9}; 1480 let Inst{7-1} = offset{8-2}; 1481} 1482 1483multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> { 1484 // Branch not taken: 1485 def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>; 1486 // Branch taken: 1487 def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>; 1488} 1489 1490multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> { 1491 let BaseOpcode = BaseOp#_NVJri in { 1492 defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond 1493 defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond 1494 } 1495} 1496 1497// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2 1498// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2 1499// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2 1500 1501let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1, 1502 Defs = [PC], hasSideEffects = 0, validSubTargets = HasV4SubT, 1503 isCodeGenOnly = 0 in { 1504 defm CMPEQri : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel; 1505 defm CMPGTri : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel; 1506 defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel; 1507} 1508 1509//===----------------------------------------------------------------------===// 1510// multiclass/template class for the new-value compare jumps instruction 1511// with a register and an hardcoded 0/-1 immediate value. 1512//===----------------------------------------------------------------------===// 1513 1514let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11, 1515 opExtentAlign = 2 in 1516class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal, 1517 bit isNegCond, bit isTak> 1518 : NVInst_V4<(outs), 1519 (ins IntRegs:$src1, brtarget:$offset), 1520 "if ("#!if(isNegCond, "!","")#mnemonic 1521 #"($src1.new, #"#ImmVal#")) jump:" 1522 #!if(isTak, "t","nt")#" $offset", []> { 1523 1524 let isTaken = isTak; 1525 let isPredicatedFalse = isNegCond; 1526 let isTaken = isTak; 1527 1528 bits<3> src1; 1529 bits<11> offset; 1530 let IClass = 0b0010; 1531 let Inst{26} = 0b1; 1532 let Inst{25-23} = majOp; 1533 let Inst{22} = isNegCond; 1534 let Inst{18-16} = src1; 1535 let Inst{13} = isTak; 1536 let Inst{21-20} = offset{10-9}; 1537 let Inst{7-1} = offset{8-2}; 1538} 1539 1540multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal, 1541 bit isNegCond> { 1542 // Branch not taken: 1543 def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>; 1544 // Branch taken: 1545 def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>; 1546} 1547 1548multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp, 1549 string ImmVal> { 1550 let BaseOpcode = BaseOp#_NVJ_ConstImm in { 1551 defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True 1552 defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False 1553 } 1554} 1555 1556// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2 1557// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2 1558// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2 1559 1560let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1, 1561 Defs = [PC], hasSideEffects = 0, isCodeGenOnly = 0 in { 1562 defm TSTBIT0 : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel; 1563 defm CMPEQn1 : NVJ_ConstImm_base<"cmp.eq", "CMPEQ", 0b100, "-1">, PredRel; 1564 defm CMPGTn1 : NVJ_ConstImm_base<"cmp.gt", "CMPGT", 0b101, "-1">, PredRel; 1565} 1566 1567// J4_hintjumpr: Hint indirect conditional jump. 1568let isBranch = 1, isIndirectBranch = 1, hasSideEffects = 0, isCodeGenOnly = 0 in 1569def J4_hintjumpr: JRInst < 1570 (outs), 1571 (ins IntRegs:$Rs), 1572 "hintjr($Rs)"> { 1573 bits<5> Rs; 1574 let IClass = 0b0101; 1575 let Inst{27-21} = 0b0010101; 1576 let Inst{20-16} = Rs; 1577 } 1578 1579//===----------------------------------------------------------------------===// 1580// NV/J - 1581//===----------------------------------------------------------------------===// 1582 1583//===----------------------------------------------------------------------===// 1584// CR + 1585//===----------------------------------------------------------------------===// 1586 1587// PC-relative add 1588let hasNewValue = 1, isExtendable = 1, opExtendable = 1, 1589 isExtentSigned = 0, opExtentBits = 6, hasSideEffects = 0, 1590 Uses = [PC], validSubTargets = HasV4SubT in 1591def C4_addipc : CRInst <(outs IntRegs:$Rd), (ins u6Ext:$u6), 1592 "$Rd = add(pc, #$u6)", [], "", CR_tc_2_SLOT3 > { 1593 bits<5> Rd; 1594 bits<6> u6; 1595 1596 let IClass = 0b0110; 1597 let Inst{27-16} = 0b101001001001; 1598 let Inst{12-7} = u6; 1599 let Inst{4-0} = Rd; 1600 } 1601 1602 1603 1604let hasSideEffects = 0 in 1605class T_LOGICAL_3OP<string MnOp1, string MnOp2, bits<2> OpBits, bit IsNeg> 1606 : CRInst<(outs PredRegs:$Pd), 1607 (ins PredRegs:$Ps, PredRegs:$Pt, PredRegs:$Pu), 1608 "$Pd = " # MnOp1 # "($Ps, " # MnOp2 # "($Pt, " # 1609 !if (IsNeg,"!","") # "$Pu))", 1610 [], "", CR_tc_2early_SLOT23> { 1611 bits<2> Pd; 1612 bits<2> Ps; 1613 bits<2> Pt; 1614 bits<2> Pu; 1615 1616 let IClass = 0b0110; 1617 let Inst{27-24} = 0b1011; 1618 let Inst{23} = IsNeg; 1619 let Inst{22-21} = OpBits; 1620 let Inst{20} = 0b1; 1621 let Inst{17-16} = Ps; 1622 let Inst{13} = 0b0; 1623 let Inst{9-8} = Pt; 1624 let Inst{7-6} = Pu; 1625 let Inst{1-0} = Pd; 1626} 1627 1628let isCodeGenOnly = 0 in { 1629def C4_and_and : T_LOGICAL_3OP<"and", "and", 0b00, 0>; 1630def C4_and_or : T_LOGICAL_3OP<"and", "or", 0b01, 0>; 1631def C4_or_and : T_LOGICAL_3OP<"or", "and", 0b10, 0>; 1632def C4_or_or : T_LOGICAL_3OP<"or", "or", 0b11, 0>; 1633def C4_and_andn : T_LOGICAL_3OP<"and", "and", 0b00, 1>; 1634def C4_and_orn : T_LOGICAL_3OP<"and", "or", 0b01, 1>; 1635def C4_or_andn : T_LOGICAL_3OP<"or", "and", 0b10, 1>; 1636def C4_or_orn : T_LOGICAL_3OP<"or", "or", 0b11, 1>; 1637} 1638 1639//===----------------------------------------------------------------------===// 1640// CR - 1641//===----------------------------------------------------------------------===// 1642 1643//===----------------------------------------------------------------------===// 1644// XTYPE/ALU + 1645//===----------------------------------------------------------------------===// 1646 1647// Logical with-not instructions. 1648let validSubTargets = HasV4SubT, isCodeGenOnly = 0 in { 1649 def A4_andnp : T_ALU64_logical<"and", 0b001, 1, 0, 1>; 1650 def A4_ornp : T_ALU64_logical<"or", 0b011, 1, 0, 1>; 1651} 1652 1653let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in 1654def S4_parity: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt), 1655 "$Rd = parity($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> { 1656 bits<5> Rd; 1657 bits<5> Rs; 1658 bits<5> Rt; 1659 1660 let IClass = 0b1101; 1661 let Inst{27-21} = 0b0101111; 1662 let Inst{20-16} = Rs; 1663 let Inst{12-8} = Rt; 1664 let Inst{4-0} = Rd; 1665} 1666// Add and accumulate. 1667// Rd=add(Rs,add(Ru,#s6)) 1668let isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 6, 1669 opExtendable = 3, isCodeGenOnly = 0 in 1670def S4_addaddi : ALU64Inst <(outs IntRegs:$Rd), 1671 (ins IntRegs:$Rs, IntRegs:$Ru, s6Ext:$s6), 1672 "$Rd = add($Rs, add($Ru, #$s6))" , 1673 [(set (i32 IntRegs:$Rd), (add (i32 IntRegs:$Rs), 1674 (add (i32 IntRegs:$Ru), s6_16ExtPred:$s6)))], 1675 "", ALU64_tc_2_SLOT23> { 1676 bits<5> Rd; 1677 bits<5> Rs; 1678 bits<5> Ru; 1679 bits<6> s6; 1680 1681 let IClass = 0b1101; 1682 1683 let Inst{27-23} = 0b10110; 1684 let Inst{22-21} = s6{5-4}; 1685 let Inst{20-16} = Rs; 1686 let Inst{13} = s6{3}; 1687 let Inst{12-8} = Rd; 1688 let Inst{7-5} = s6{2-0}; 1689 let Inst{4-0} = Ru; 1690 } 1691 1692let isExtentSigned = 1, hasSideEffects = 0, hasNewValue = 1, isExtendable = 1, 1693 opExtentBits = 6, opExtendable = 2, isCodeGenOnly = 0 in 1694def S4_subaddi: ALU64Inst <(outs IntRegs:$Rd), 1695 (ins IntRegs:$Rs, s6Ext:$s6, IntRegs:$Ru), 1696 "$Rd = add($Rs, sub(#$s6, $Ru))", 1697 [], "", ALU64_tc_2_SLOT23> { 1698 bits<5> Rd; 1699 bits<5> Rs; 1700 bits<6> s6; 1701 bits<5> Ru; 1702 1703 let IClass = 0b1101; 1704 1705 let Inst{27-23} = 0b10111; 1706 let Inst{22-21} = s6{5-4}; 1707 let Inst{20-16} = Rs; 1708 let Inst{13} = s6{3}; 1709 let Inst{12-8} = Rd; 1710 let Inst{7-5} = s6{2-0}; 1711 let Inst{4-0} = Ru; 1712 } 1713 1714// Extract bitfield 1715// Rdd=extract(Rss,#u6,#U6) 1716// Rdd=extract(Rss,Rtt) 1717// Rd=extract(Rs,Rtt) 1718// Rd=extract(Rs,#u5,#U5) 1719 1720let isCodeGenOnly = 0 in { 1721def S4_extractp_rp : T_S3op_64 < "extract", 0b11, 0b100, 0>; 1722def S4_extractp : T_S2op_extract <"extract", 0b1010, DoubleRegs, u6Imm>; 1723} 1724 1725let hasNewValue = 1, isCodeGenOnly = 0 in { 1726 def S4_extract_rp : T_S3op_extract<"extract", 0b01>; 1727 def S4_extract : T_S2op_extract <"extract", 0b1101, IntRegs, u5Imm>; 1728} 1729 1730let Itinerary = M_tc_3x_SLOT23, Defs = [USR_OVF], isCodeGenOnly = 0 in { 1731 def M4_mac_up_s1_sat: T_MType_acc_rr<"+= mpy", 0b011, 0b000, 0, [], 0, 1, 1>; 1732 def M4_nac_up_s1_sat: T_MType_acc_rr<"-= mpy", 0b011, 0b001, 0, [], 0, 1, 1>; 1733} 1734 1735// Logical xor with xor accumulation. 1736// Rxx^=xor(Rss,Rtt) 1737let hasSideEffects = 0, isCodeGenOnly = 0 in 1738def M4_xor_xacc 1739 : SInst <(outs DoubleRegs:$Rxx), 1740 (ins DoubleRegs:$dst2, DoubleRegs:$Rss, DoubleRegs:$Rtt), 1741 "$Rxx ^= xor($Rss, $Rtt)", 1742 [(set (i64 DoubleRegs:$Rxx), 1743 (xor (i64 DoubleRegs:$dst2), (xor (i64 DoubleRegs:$Rss), 1744 (i64 DoubleRegs:$Rtt))))], 1745 "$dst2 = $Rxx", S_3op_tc_1_SLOT23> { 1746 bits<5> Rxx; 1747 bits<5> Rss; 1748 bits<5> Rtt; 1749 1750 let IClass = 0b1100; 1751 1752 let Inst{27-23} = 0b10101; 1753 let Inst{20-16} = Rss; 1754 let Inst{12-8} = Rtt; 1755 let Inst{4-0} = Rxx; 1756 } 1757 1758// Split bitfield 1759let isCodeGenOnly = 0 in 1760def A4_bitspliti : T_S2op_2_di <"bitsplit", 0b110, 0b100>; 1761 1762// Arithmetic/Convergent round 1763let isCodeGenOnly = 0 in 1764def A4_cround_ri : T_S2op_2_ii <"cround", 0b111, 0b000>; 1765 1766let isCodeGenOnly = 0 in 1767def A4_round_ri : T_S2op_2_ii <"round", 0b111, 0b100>; 1768 1769let Defs = [USR_OVF], isCodeGenOnly = 0 in 1770def A4_round_ri_sat : T_S2op_2_ii <"round", 0b111, 0b110, 1>; 1771 1772// Logical-logical words. 1773// Compound or-and -- Rx=or(Ru,and(Rx,#s10)) 1774let isExtentSigned = 1, hasNewValue = 1, isExtendable = 1, opExtentBits = 10, 1775 opExtendable = 3, isCodeGenOnly = 0 in 1776def S4_or_andix: 1777 ALU64Inst<(outs IntRegs:$Rx), 1778 (ins IntRegs:$Ru, IntRegs:$_src_, s10Ext:$s10), 1779 "$Rx = or($Ru, and($_src_, #$s10))" , 1780 [(set (i32 IntRegs:$Rx), 1781 (or (i32 IntRegs:$Ru), (and (i32 IntRegs:$_src_), s10ExtPred:$s10)))] , 1782 "$_src_ = $Rx", ALU64_tc_2_SLOT23> { 1783 bits<5> Rx; 1784 bits<5> Ru; 1785 bits<10> s10; 1786 1787 let IClass = 0b1101; 1788 1789 let Inst{27-22} = 0b101001; 1790 let Inst{20-16} = Rx; 1791 let Inst{21} = s10{9}; 1792 let Inst{13-5} = s10{8-0}; 1793 let Inst{4-0} = Ru; 1794 } 1795 1796// Miscellaneous ALU64 instructions. 1797// 1798let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in 1799def A4_modwrapu: ALU64Inst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, IntRegs:$Rt), 1800 "$Rd = modwrap($Rs, $Rt)", [], "", ALU64_tc_2_SLOT23> { 1801 bits<5> Rd; 1802 bits<5> Rs; 1803 bits<5> Rt; 1804 1805 let IClass = 0b1101; 1806 let Inst{27-21} = 0b0011111; 1807 let Inst{20-16} = Rs; 1808 let Inst{12-8} = Rt; 1809 let Inst{7-5} = 0b111; 1810 let Inst{4-0} = Rd; 1811} 1812 1813let hasSideEffects = 0, isCodeGenOnly = 0 in 1814def A4_bitsplit: ALU64Inst<(outs DoubleRegs:$Rd), 1815 (ins IntRegs:$Rs, IntRegs:$Rt), 1816 "$Rd = bitsplit($Rs, $Rt)", [], "", ALU64_tc_1_SLOT23> { 1817 bits<5> Rd; 1818 bits<5> Rs; 1819 bits<5> Rt; 1820 1821 let IClass = 0b1101; 1822 let Inst{27-24} = 0b0100; 1823 let Inst{21} = 0b1; 1824 let Inst{20-16} = Rs; 1825 let Inst{12-8} = Rt; 1826 let Inst{4-0} = Rd; 1827} 1828 1829let isCodeGenOnly = 0 in { 1830// Rx[&|]=xor(Rs,Rt) 1831def M4_or_xor : T_MType_acc_rr < "|= xor", 0b110, 0b001, 0>; 1832def M4_and_xor : T_MType_acc_rr < "&= xor", 0b010, 0b010, 0>; 1833 1834// Rx[&|^]=or(Rs,Rt) 1835def M4_xor_or : T_MType_acc_rr < "^= or", 0b110, 0b011, 0>; 1836 1837let CextOpcode = "ORr_ORr" in 1838def M4_or_or : T_MType_acc_rr < "|= or", 0b110, 0b000, 0>; 1839def M4_and_or : T_MType_acc_rr < "&= or", 0b010, 0b001, 0>; 1840 1841// Rx[&|^]=and(Rs,Rt) 1842def M4_xor_and : T_MType_acc_rr < "^= and", 0b110, 0b010, 0>; 1843 1844let CextOpcode = "ORr_ANDr" in 1845def M4_or_and : T_MType_acc_rr < "|= and", 0b010, 0b011, 0>; 1846def M4_and_and : T_MType_acc_rr < "&= and", 0b010, 0b000, 0>; 1847 1848// Rx[&|^]=and(Rs,~Rt) 1849def M4_xor_andn : T_MType_acc_rr < "^= and", 0b001, 0b010, 0, [], 1>; 1850def M4_or_andn : T_MType_acc_rr < "|= and", 0b001, 0b000, 0, [], 1>; 1851def M4_and_andn : T_MType_acc_rr < "&= and", 0b001, 0b001, 0, [], 1>; 1852} 1853 1854// Compound or-or and or-and 1855let isExtentSigned = 1, InputType = "imm", hasNewValue = 1, isExtendable = 1, 1856 opExtentBits = 10, opExtendable = 3 in 1857class T_CompOR <string mnemonic, bits<2> MajOp, SDNode OpNode> 1858 : MInst_acc <(outs IntRegs:$Rx), 1859 (ins IntRegs:$src1, IntRegs:$Rs, s10Ext:$s10), 1860 "$Rx |= "#mnemonic#"($Rs, #$s10)", 1861 [(set (i32 IntRegs:$Rx), (or (i32 IntRegs:$src1), 1862 (OpNode (i32 IntRegs:$Rs), s10ExtPred:$s10)))], 1863 "$src1 = $Rx", ALU64_tc_2_SLOT23>, ImmRegRel { 1864 bits<5> Rx; 1865 bits<5> Rs; 1866 bits<10> s10; 1867 1868 let IClass = 0b1101; 1869 1870 let Inst{27-24} = 0b1010; 1871 let Inst{23-22} = MajOp; 1872 let Inst{20-16} = Rs; 1873 let Inst{21} = s10{9}; 1874 let Inst{13-5} = s10{8-0}; 1875 let Inst{4-0} = Rx; 1876 } 1877 1878let CextOpcode = "ORr_ANDr", isCodeGenOnly = 0 in 1879def S4_or_andi : T_CompOR <"and", 0b00, and>; 1880 1881let CextOpcode = "ORr_ORr", isCodeGenOnly = 0 in 1882def S4_or_ori : T_CompOR <"or", 0b10, or>; 1883 1884// Modulo wrap 1885// Rd=modwrap(Rs,Rt) 1886// Round 1887// Rd=cround(Rs,#u5) 1888// Rd=cround(Rs,Rt) 1889// Rd=round(Rs,#u5)[:sat] 1890// Rd=round(Rs,Rt)[:sat] 1891// Vector reduce add unsigned halfwords 1892// Rd=vraddh(Rss,Rtt) 1893// Vector add bytes 1894// Rdd=vaddb(Rss,Rtt) 1895// Vector conditional negate 1896// Rdd=vcnegh(Rss,Rt) 1897// Rxx+=vrcnegh(Rss,Rt) 1898// Vector maximum bytes 1899// Rdd=vmaxb(Rtt,Rss) 1900// Vector reduce maximum halfwords 1901// Rxx=vrmaxh(Rss,Ru) 1902// Rxx=vrmaxuh(Rss,Ru) 1903// Vector reduce maximum words 1904// Rxx=vrmaxuw(Rss,Ru) 1905// Rxx=vrmaxw(Rss,Ru) 1906// Vector minimum bytes 1907// Rdd=vminb(Rtt,Rss) 1908// Vector reduce minimum halfwords 1909// Rxx=vrminh(Rss,Ru) 1910// Rxx=vrminuh(Rss,Ru) 1911// Vector reduce minimum words 1912// Rxx=vrminuw(Rss,Ru) 1913// Rxx=vrminw(Rss,Ru) 1914// Vector subtract bytes 1915// Rdd=vsubb(Rss,Rtt) 1916 1917//===----------------------------------------------------------------------===// 1918// XTYPE/ALU - 1919//===----------------------------------------------------------------------===// 1920 1921//===----------------------------------------------------------------------===// 1922// XTYPE/BIT + 1923//===----------------------------------------------------------------------===// 1924 1925// Bit reverse 1926let isCodeGenOnly = 0 in 1927def S2_brevp : T_S2op_3 <"brev", 0b11, 0b110>; 1928 1929// Bit count 1930let isCodeGenOnly = 0 in { 1931def S2_ct0p : T_COUNT_LEADING_64<"ct0", 0b111, 0b010>; 1932def S2_ct1p : T_COUNT_LEADING_64<"ct1", 0b111, 0b100>; 1933def S4_clbpnorm : T_COUNT_LEADING_64<"normamt", 0b011, 0b000>; 1934} 1935 1936def: Pat<(i32 (trunc (cttz (i64 DoubleRegs:$Rss)))), 1937 (S2_ct0p (i64 DoubleRegs:$Rss))>; 1938def: Pat<(i32 (trunc (cttz (not (i64 DoubleRegs:$Rss))))), 1939 (S2_ct1p (i64 DoubleRegs:$Rss))>; 1940 1941let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in 1942def S4_clbaddi : SInst<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s6Imm:$s6), 1943 "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> { 1944 bits<5> Rs; 1945 bits<5> Rd; 1946 bits<6> s6; 1947 let IClass = 0b1000; 1948 let Inst{27-24} = 0b1100; 1949 let Inst{23-21} = 0b001; 1950 let Inst{20-16} = Rs; 1951 let Inst{13-8} = s6; 1952 let Inst{7-5} = 0b000; 1953 let Inst{4-0} = Rd; 1954} 1955 1956let hasSideEffects = 0, hasNewValue = 1, isCodeGenOnly = 0 in 1957def S4_clbpaddi : SInst<(outs IntRegs:$Rd), (ins DoubleRegs:$Rs, s6Imm:$s6), 1958 "$Rd = add(clb($Rs), #$s6)", [], "", S_2op_tc_2_SLOT23> { 1959 bits<5> Rs; 1960 bits<5> Rd; 1961 bits<6> s6; 1962 let IClass = 0b1000; 1963 let Inst{27-24} = 0b1000; 1964 let Inst{23-21} = 0b011; 1965 let Inst{20-16} = Rs; 1966 let Inst{13-8} = s6; 1967 let Inst{7-5} = 0b010; 1968 let Inst{4-0} = Rd; 1969} 1970 1971 1972// Bit test/set/clear 1973let isCodeGenOnly = 0 in { 1974def S4_ntstbit_i : T_TEST_BIT_IMM<"!tstbit", 0b001>; 1975def S4_ntstbit_r : T_TEST_BIT_REG<"!tstbit", 1>; 1976} 1977 1978let AddedComplexity = 20 in { // Complexity greater than cmp reg-imm. 1979 def: Pat<(i1 (seteq (and (shl 1, u5ImmPred:$u5), (i32 IntRegs:$Rs)), 0)), 1980 (S4_ntstbit_i (i32 IntRegs:$Rs), u5ImmPred:$u5)>; 1981 def: Pat<(i1 (seteq (and (shl 1, (i32 IntRegs:$Rt)), (i32 IntRegs:$Rs)), 0)), 1982 (S4_ntstbit_r (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))>; 1983} 1984 1985// Add extra complexity to prefer these instructions over bitsset/bitsclr. 1986// The reason is that tstbit/ntstbit can be folded into a compound instruction: 1987// if ([!]tstbit(...)) jump ... 1988let AddedComplexity = 100 in 1989def: Pat<(i1 (setne (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))), 1990 (S2_tstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>; 1991 1992let AddedComplexity = 100 in 1993def: Pat<(i1 (seteq (and (i32 IntRegs:$Rs), (i32 Set5ImmPred:$u5)), (i32 0))), 1994 (S4_ntstbit_i (i32 IntRegs:$Rs), (BITPOS32 Set5ImmPred:$u5))>; 1995 1996let isCodeGenOnly = 0 in { 1997def C4_nbitsset : T_TEST_BITS_REG<"!bitsset", 0b01, 1>; 1998def C4_nbitsclr : T_TEST_BITS_REG<"!bitsclr", 0b10, 1>; 1999def C4_nbitsclri : T_TEST_BITS_IMM<"!bitsclr", 0b10, 1>; 2000} 2001 2002// Do not increase complexity of these patterns. In the DAG, "cmp i8" may be 2003// represented as a compare against "value & 0xFF", which is an exact match 2004// for cmpb (same for cmph). The patterns below do not contain any additional 2005// complexity that would make them preferable, and if they were actually used 2006// instead of cmpb/cmph, they would result in a compare against register that 2007// is loaded with the byte/half mask (i.e. 0xFF or 0xFFFF). 2008def: Pat<(i1 (setne (and I32:$Rs, u6ImmPred:$u6), 0)), 2009 (C4_nbitsclri I32:$Rs, u6ImmPred:$u6)>; 2010def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), 0)), 2011 (C4_nbitsclr I32:$Rs, I32:$Rt)>; 2012def: Pat<(i1 (setne (and I32:$Rs, I32:$Rt), I32:$Rt)), 2013 (C4_nbitsset I32:$Rs, I32:$Rt)>; 2014 2015//===----------------------------------------------------------------------===// 2016// XTYPE/BIT - 2017//===----------------------------------------------------------------------===// 2018 2019//===----------------------------------------------------------------------===// 2020// XTYPE/MPY + 2021//===----------------------------------------------------------------------===// 2022 2023// Rd=add(#u6,mpyi(Rs,#U6)) -- Multiply by immed and add immed. 2024 2025let hasNewValue = 1, isExtendable = 1, opExtentBits = 6, opExtendable = 1, 2026 isCodeGenOnly = 0 in 2027def M4_mpyri_addi : MInst<(outs IntRegs:$Rd), 2028 (ins u6Ext:$u6, IntRegs:$Rs, u6Imm:$U6), 2029 "$Rd = add(#$u6, mpyi($Rs, #$U6))" , 2030 [(set (i32 IntRegs:$Rd), 2031 (add (mul (i32 IntRegs:$Rs), u6ImmPred:$U6), 2032 u6ExtPred:$u6))] ,"",ALU64_tc_3x_SLOT23> { 2033 bits<5> Rd; 2034 bits<6> u6; 2035 bits<5> Rs; 2036 bits<6> U6; 2037 2038 let IClass = 0b1101; 2039 2040 let Inst{27-24} = 0b1000; 2041 let Inst{23} = U6{5}; 2042 let Inst{22-21} = u6{5-4}; 2043 let Inst{20-16} = Rs; 2044 let Inst{13} = u6{3}; 2045 let Inst{12-8} = Rd; 2046 let Inst{7-5} = u6{2-0}; 2047 let Inst{4-0} = U6{4-0}; 2048 } 2049 2050// Rd=add(#u6,mpyi(Rs,Rt)) 2051let CextOpcode = "ADD_MPY", InputType = "imm", hasNewValue = 1, 2052 isExtendable = 1, opExtentBits = 6, opExtendable = 1, isCodeGenOnly = 0 in 2053def M4_mpyrr_addi : MInst <(outs IntRegs:$Rd), 2054 (ins u6Ext:$u6, IntRegs:$Rs, IntRegs:$Rt), 2055 "$Rd = add(#$u6, mpyi($Rs, $Rt))" , 2056 [(set (i32 IntRegs:$Rd), 2057 (add (mul (i32 IntRegs:$Rs), (i32 IntRegs:$Rt)), u6ExtPred:$u6))], 2058 "", ALU64_tc_3x_SLOT23>, ImmRegRel { 2059 bits<5> Rd; 2060 bits<6> u6; 2061 bits<5> Rs; 2062 bits<5> Rt; 2063 2064 let IClass = 0b1101; 2065 2066 let Inst{27-23} = 0b01110; 2067 let Inst{22-21} = u6{5-4}; 2068 let Inst{20-16} = Rs; 2069 let Inst{13} = u6{3}; 2070 let Inst{12-8} = Rt; 2071 let Inst{7-5} = u6{2-0}; 2072 let Inst{4-0} = Rd; 2073 } 2074 2075let hasNewValue = 1 in 2076class T_AddMpy <bit MajOp, PatLeaf ImmPred, dag ins> 2077 : ALU64Inst <(outs IntRegs:$dst), ins, 2078 "$dst = add($src1, mpyi("#!if(MajOp,"$src3, #$src2))", 2079 "#$src2, $src3))"), 2080 [(set (i32 IntRegs:$dst), 2081 (add (i32 IntRegs:$src1), (mul (i32 IntRegs:$src3), ImmPred:$src2)))], 2082 "", ALU64_tc_3x_SLOT23> { 2083 bits<5> dst; 2084 bits<5> src1; 2085 bits<8> src2; 2086 bits<5> src3; 2087 2088 let IClass = 0b1101; 2089 2090 bits<6> ImmValue = !if(MajOp, src2{5-0}, src2{7-2}); 2091 2092 let Inst{27-24} = 0b1111; 2093 let Inst{23} = MajOp; 2094 let Inst{22-21} = ImmValue{5-4}; 2095 let Inst{20-16} = src3; 2096 let Inst{13} = ImmValue{3}; 2097 let Inst{12-8} = dst; 2098 let Inst{7-5} = ImmValue{2-0}; 2099 let Inst{4-0} = src1; 2100 } 2101 2102let isCodeGenOnly = 0 in 2103def M4_mpyri_addr_u2 : T_AddMpy<0b0, u6_2ImmPred, 2104 (ins IntRegs:$src1, u6_2Imm:$src2, IntRegs:$src3)>; 2105 2106let isExtendable = 1, opExtentBits = 6, opExtendable = 3, 2107 CextOpcode = "ADD_MPY", InputType = "imm", isCodeGenOnly = 0 in 2108def M4_mpyri_addr : T_AddMpy<0b1, u6ExtPred, 2109 (ins IntRegs:$src1, IntRegs:$src3, u6Ext:$src2)>, ImmRegRel; 2110 2111// Rx=add(Ru,mpyi(Rx,Rs)) 2112let validSubTargets = HasV4SubT, CextOpcode = "ADD_MPY", InputType = "reg", 2113 hasNewValue = 1, isCodeGenOnly = 0 in 2114def M4_mpyrr_addr: MInst_acc <(outs IntRegs:$Rx), 2115 (ins IntRegs:$Ru, IntRegs:$_src_, IntRegs:$Rs), 2116 "$Rx = add($Ru, mpyi($_src_, $Rs))", 2117 [(set (i32 IntRegs:$Rx), (add (i32 IntRegs:$Ru), 2118 (mul (i32 IntRegs:$_src_), (i32 IntRegs:$Rs))))], 2119 "$_src_ = $Rx", M_tc_3x_SLOT23>, ImmRegRel { 2120 bits<5> Rx; 2121 bits<5> Ru; 2122 bits<5> Rs; 2123 2124 let IClass = 0b1110; 2125 2126 let Inst{27-21} = 0b0011000; 2127 let Inst{12-8} = Rx; 2128 let Inst{4-0} = Ru; 2129 let Inst{20-16} = Rs; 2130 } 2131 2132// Rd=add(##,mpyi(Rs,#U6)) 2133def : Pat <(add (mul (i32 IntRegs:$src2), u6ImmPred:$src3), 2134 (HexagonCONST32 tglobaladdr:$src1)), 2135 (i32 (M4_mpyri_addi tglobaladdr:$src1, IntRegs:$src2, 2136 u6ImmPred:$src3))>; 2137 2138// Rd=add(##,mpyi(Rs,Rt)) 2139def : Pat <(add (mul (i32 IntRegs:$src2), (i32 IntRegs:$src3)), 2140 (HexagonCONST32 tglobaladdr:$src1)), 2141 (i32 (M4_mpyrr_addi tglobaladdr:$src1, IntRegs:$src2, 2142 IntRegs:$src3))>; 2143 2144// Polynomial multiply words 2145// Rdd=pmpyw(Rs,Rt) 2146// Rxx^=pmpyw(Rs,Rt) 2147 2148// Vector reduce multiply word by signed half (32x16) 2149// Rdd=vrmpyweh(Rss,Rtt)[:<<1] 2150// Rdd=vrmpywoh(Rss,Rtt)[:<<1] 2151// Rxx+=vrmpyweh(Rss,Rtt)[:<<1] 2152// Rxx+=vrmpywoh(Rss,Rtt)[:<<1] 2153 2154// Multiply and use upper result 2155// Rd=mpy(Rs,Rt.H):<<1:sat 2156// Rd=mpy(Rs,Rt.L):<<1:sat 2157// Rd=mpy(Rs,Rt):<<1 2158// Rd=mpy(Rs,Rt):<<1:sat 2159// Rd=mpysu(Rs,Rt) 2160// Rx+=mpy(Rs,Rt):<<1:sat 2161// Rx-=mpy(Rs,Rt):<<1:sat 2162 2163// Vector multiply bytes 2164// Rdd=vmpybsu(Rs,Rt) 2165// Rdd=vmpybu(Rs,Rt) 2166// Rxx+=vmpybsu(Rs,Rt) 2167// Rxx+=vmpybu(Rs,Rt) 2168 2169// Vector polynomial multiply halfwords 2170// Rdd=vpmpyh(Rs,Rt) 2171// Rxx^=vpmpyh(Rs,Rt) 2172 2173//===----------------------------------------------------------------------===// 2174// XTYPE/MPY - 2175//===----------------------------------------------------------------------===// 2176 2177 2178//===----------------------------------------------------------------------===// 2179// XTYPE/SHIFT + 2180//===----------------------------------------------------------------------===// 2181// Shift by immediate and accumulate/logical. 2182// Rx=add(#u8,asl(Rx,#U5)) Rx=add(#u8,lsr(Rx,#U5)) 2183// Rx=sub(#u8,asl(Rx,#U5)) Rx=sub(#u8,lsr(Rx,#U5)) 2184// Rx=and(#u8,asl(Rx,#U5)) Rx=and(#u8,lsr(Rx,#U5)) 2185// Rx=or(#u8,asl(Rx,#U5)) Rx=or(#u8,lsr(Rx,#U5)) 2186let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, opExtentBits = 8, 2187 hasNewValue = 1, opNewValue = 0, validSubTargets = HasV4SubT in 2188class T_S4_ShiftOperate<string MnOp, string MnSh, SDNode Op, SDNode Sh, 2189 bit asl_lsr, bits<2> MajOp, InstrItinClass Itin> 2190 : MInst_acc<(outs IntRegs:$Rd), (ins u8Ext:$u8, IntRegs:$Rx, u5Imm:$U5), 2191 "$Rd = "#MnOp#"(#$u8, "#MnSh#"($Rx, #$U5))", 2192 [(set (i32 IntRegs:$Rd), 2193 (Op (Sh I32:$Rx, u5ImmPred:$U5), u8ExtPred:$u8))], 2194 "$Rd = $Rx", Itin> { 2195 2196 bits<5> Rd; 2197 bits<8> u8; 2198 bits<5> Rx; 2199 bits<5> U5; 2200 2201 let IClass = 0b1101; 2202 let Inst{27-24} = 0b1110; 2203 let Inst{23-21} = u8{7-5}; 2204 let Inst{20-16} = Rd; 2205 let Inst{13} = u8{4}; 2206 let Inst{12-8} = U5; 2207 let Inst{7-5} = u8{3-1}; 2208 let Inst{4} = asl_lsr; 2209 let Inst{3} = u8{0}; 2210 let Inst{2-1} = MajOp; 2211} 2212 2213multiclass T_ShiftOperate<string mnemonic, SDNode Op, bits<2> MajOp, 2214 InstrItinClass Itin> { 2215 def _asl_ri : T_S4_ShiftOperate<mnemonic, "asl", Op, shl, 0, MajOp, Itin>; 2216 def _lsr_ri : T_S4_ShiftOperate<mnemonic, "lsr", Op, srl, 1, MajOp, Itin>; 2217} 2218 2219let AddedComplexity = 200, isCodeGenOnly = 0 in { 2220 defm S4_addi : T_ShiftOperate<"add", add, 0b10, ALU64_tc_2_SLOT23>; 2221 defm S4_andi : T_ShiftOperate<"and", and, 0b00, ALU64_tc_2_SLOT23>; 2222} 2223 2224let AddedComplexity = 30, isCodeGenOnly = 0 in 2225defm S4_ori : T_ShiftOperate<"or", or, 0b01, ALU64_tc_1_SLOT23>; 2226 2227let isCodeGenOnly = 0 in 2228defm S4_subi : T_ShiftOperate<"sub", sub, 0b11, ALU64_tc_1_SLOT23>; 2229 2230 2231// Rd=[cround|round](Rs,Rt) 2232let hasNewValue = 1, Itinerary = S_3op_tc_2_SLOT23, isCodeGenOnly = 0 in { 2233 def A4_cround_rr : T_S3op_3 < "cround", IntRegs, 0b11, 0b00>; 2234 def A4_round_rr : T_S3op_3 < "round", IntRegs, 0b11, 0b10>; 2235} 2236 2237// Rd=round(Rs,Rt):sat 2238let hasNewValue = 1, Defs = [USR_OVF], Itinerary = S_3op_tc_2_SLOT23, 2239 isCodeGenOnly = 0 in 2240def A4_round_rr_sat : T_S3op_3 < "round", IntRegs, 0b11, 0b11, 1>; 2241 2242// Rdd=[add|sub](Rss,Rtt,Px):carry 2243let isPredicateLate = 1, hasSideEffects = 0 in 2244class T_S3op_carry <string mnemonic, bits<3> MajOp> 2245 : SInst < (outs DoubleRegs:$Rdd, PredRegs:$Px), 2246 (ins DoubleRegs:$Rss, DoubleRegs:$Rtt, PredRegs:$Pu), 2247 "$Rdd = "#mnemonic#"($Rss, $Rtt, $Pu):carry", 2248 [], "$Px = $Pu", S_3op_tc_1_SLOT23 > { 2249 bits<5> Rdd; 2250 bits<5> Rss; 2251 bits<5> Rtt; 2252 bits<2> Pu; 2253 2254 let IClass = 0b1100; 2255 2256 let Inst{27-24} = 0b0010; 2257 let Inst{23-21} = MajOp; 2258 let Inst{20-16} = Rss; 2259 let Inst{12-8} = Rtt; 2260 let Inst{6-5} = Pu; 2261 let Inst{4-0} = Rdd; 2262 } 2263 2264let isCodeGenOnly = 0 in { 2265def A4_addp_c : T_S3op_carry < "add", 0b110 >; 2266def A4_subp_c : T_S3op_carry < "sub", 0b111 >; 2267} 2268 2269// Shift an immediate left by register amount. 2270let hasNewValue = 1, hasSideEffects = 0, isCodeGenOnly = 0 in 2271def S4_lsli: SInst <(outs IntRegs:$Rd), (ins s6Imm:$s6, IntRegs:$Rt), 2272 "$Rd = lsl(#$s6, $Rt)" , 2273 [(set (i32 IntRegs:$Rd), (shl s6ImmPred:$s6, 2274 (i32 IntRegs:$Rt)))], 2275 "", S_3op_tc_1_SLOT23> { 2276 bits<5> Rd; 2277 bits<6> s6; 2278 bits<5> Rt; 2279 2280 let IClass = 0b1100; 2281 2282 let Inst{27-22} = 0b011010; 2283 let Inst{20-16} = s6{5-1}; 2284 let Inst{12-8} = Rt; 2285 let Inst{7-6} = 0b11; 2286 let Inst{4-0} = Rd; 2287 let Inst{5} = s6{0}; 2288 } 2289 2290//===----------------------------------------------------------------------===// 2291// XTYPE/SHIFT - 2292//===----------------------------------------------------------------------===// 2293 2294//===----------------------------------------------------------------------===// 2295// MEMOP: Word, Half, Byte 2296//===----------------------------------------------------------------------===// 2297 2298def MEMOPIMM : SDNodeXForm<imm, [{ 2299 // Call the transformation function XformM5ToU5Imm to get the negative 2300 // immediate's positive counterpart. 2301 int32_t imm = N->getSExtValue(); 2302 return XformM5ToU5Imm(imm); 2303}]>; 2304 2305def MEMOPIMM_HALF : SDNodeXForm<imm, [{ 2306 // -1 .. -31 represented as 65535..65515 2307 // assigning to a short restores our desired signed value. 2308 // Call the transformation function XformM5ToU5Imm to get the negative 2309 // immediate's positive counterpart. 2310 int16_t imm = N->getSExtValue(); 2311 return XformM5ToU5Imm(imm); 2312}]>; 2313 2314def MEMOPIMM_BYTE : SDNodeXForm<imm, [{ 2315 // -1 .. -31 represented as 255..235 2316 // assigning to a char restores our desired signed value. 2317 // Call the transformation function XformM5ToU5Imm to get the negative 2318 // immediate's positive counterpart. 2319 int8_t imm = N->getSExtValue(); 2320 return XformM5ToU5Imm(imm); 2321}]>; 2322 2323def SETMEMIMM : SDNodeXForm<imm, [{ 2324 // Return the bit position we will set [0-31]. 2325 // As an SDNode. 2326 int32_t imm = N->getSExtValue(); 2327 return XformMskToBitPosU5Imm(imm); 2328}]>; 2329 2330def CLRMEMIMM : SDNodeXForm<imm, [{ 2331 // Return the bit position we will clear [0-31]. 2332 // As an SDNode. 2333 // we bit negate the value first 2334 int32_t imm = ~(N->getSExtValue()); 2335 return XformMskToBitPosU5Imm(imm); 2336}]>; 2337 2338def SETMEMIMM_SHORT : SDNodeXForm<imm, [{ 2339 // Return the bit position we will set [0-15]. 2340 // As an SDNode. 2341 int16_t imm = N->getSExtValue(); 2342 return XformMskToBitPosU4Imm(imm); 2343}]>; 2344 2345def CLRMEMIMM_SHORT : SDNodeXForm<imm, [{ 2346 // Return the bit position we will clear [0-15]. 2347 // As an SDNode. 2348 // we bit negate the value first 2349 int16_t imm = ~(N->getSExtValue()); 2350 return XformMskToBitPosU4Imm(imm); 2351}]>; 2352 2353def SETMEMIMM_BYTE : SDNodeXForm<imm, [{ 2354 // Return the bit position we will set [0-7]. 2355 // As an SDNode. 2356 int8_t imm = N->getSExtValue(); 2357 return XformMskToBitPosU3Imm(imm); 2358}]>; 2359 2360def CLRMEMIMM_BYTE : SDNodeXForm<imm, [{ 2361 // Return the bit position we will clear [0-7]. 2362 // As an SDNode. 2363 // we bit negate the value first 2364 int8_t imm = ~(N->getSExtValue()); 2365 return XformMskToBitPosU3Imm(imm); 2366}]>; 2367 2368//===----------------------------------------------------------------------===// 2369// Template class for MemOp instructions with the register value. 2370//===----------------------------------------------------------------------===// 2371class MemOp_rr_base <string opc, bits<2> opcBits, Operand ImmOp, 2372 string memOp, bits<2> memOpBits> : 2373 MEMInst_V4<(outs), 2374 (ins IntRegs:$base, ImmOp:$offset, IntRegs:$delta), 2375 opc#"($base+#$offset)"#memOp#"$delta", 2376 []>, 2377 Requires<[UseMEMOP]> { 2378 2379 bits<5> base; 2380 bits<5> delta; 2381 bits<32> offset; 2382 bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 2383 2384 let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 2385 !if (!eq(opcBits, 0b01), offset{6-1}, 2386 !if (!eq(opcBits, 0b10), offset{7-2},0))); 2387 2388 let opExtentAlign = opcBits; 2389 let IClass = 0b0011; 2390 let Inst{27-24} = 0b1110; 2391 let Inst{22-21} = opcBits; 2392 let Inst{20-16} = base; 2393 let Inst{13} = 0b0; 2394 let Inst{12-7} = offsetBits; 2395 let Inst{6-5} = memOpBits; 2396 let Inst{4-0} = delta; 2397} 2398 2399//===----------------------------------------------------------------------===// 2400// Template class for MemOp instructions with the immediate value. 2401//===----------------------------------------------------------------------===// 2402class MemOp_ri_base <string opc, bits<2> opcBits, Operand ImmOp, 2403 string memOp, bits<2> memOpBits> : 2404 MEMInst_V4 <(outs), 2405 (ins IntRegs:$base, ImmOp:$offset, u5Imm:$delta), 2406 opc#"($base+#$offset)"#memOp#"#$delta" 2407 #!if(memOpBits{1},")", ""), // clrbit, setbit - include ')' 2408 []>, 2409 Requires<[UseMEMOP]> { 2410 2411 bits<5> base; 2412 bits<5> delta; 2413 bits<32> offset; 2414 bits<6> offsetBits; // memb - u6:0 , memh - u6:1, memw - u6:2 2415 2416 let offsetBits = !if (!eq(opcBits, 0b00), offset{5-0}, 2417 !if (!eq(opcBits, 0b01), offset{6-1}, 2418 !if (!eq(opcBits, 0b10), offset{7-2},0))); 2419 2420 let opExtentAlign = opcBits; 2421 let IClass = 0b0011; 2422 let Inst{27-24} = 0b1111; 2423 let Inst{22-21} = opcBits; 2424 let Inst{20-16} = base; 2425 let Inst{13} = 0b0; 2426 let Inst{12-7} = offsetBits; 2427 let Inst{6-5} = memOpBits; 2428 let Inst{4-0} = delta; 2429} 2430 2431// multiclass to define MemOp instructions with register operand. 2432multiclass MemOp_rr<string opc, bits<2> opcBits, Operand ImmOp> { 2433 def L4_add#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " += ", 0b00>; // add 2434 def L4_sub#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " -= ", 0b01>; // sub 2435 def L4_and#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " &= ", 0b10>; // and 2436 def L4_or#NAME : MemOp_rr_base <opc, opcBits, ImmOp, " |= ", 0b11>; // or 2437} 2438 2439// multiclass to define MemOp instructions with immediate Operand. 2440multiclass MemOp_ri<string opc, bits<2> opcBits, Operand ImmOp> { 2441 def L4_iadd#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " += ", 0b00 >; 2442 def L4_isub#NAME : MemOp_ri_base <opc, opcBits, ImmOp, " -= ", 0b01 >; 2443 def L4_iand#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = clrbit(", 0b10>; 2444 def L4_ior#NAME : MemOp_ri_base<opc, opcBits, ImmOp, " = setbit(", 0b11>; 2445} 2446 2447multiclass MemOp_base <string opc, bits<2> opcBits, Operand ImmOp> { 2448 defm _#NAME : MemOp_rr <opc, opcBits, ImmOp>; 2449 defm _#NAME : MemOp_ri <opc, opcBits, ImmOp>; 2450} 2451 2452// Define MemOp instructions. 2453let isExtendable = 1, opExtendable = 1, isExtentSigned = 0, 2454 validSubTargets =HasV4SubT in { 2455 let opExtentBits = 6, accessSize = ByteAccess, isCodeGenOnly = 0 in 2456 defm memopb_io : MemOp_base <"memb", 0b00, u6_0Ext>; 2457 2458 let opExtentBits = 7, accessSize = HalfWordAccess, isCodeGenOnly = 0 in 2459 defm memoph_io : MemOp_base <"memh", 0b01, u6_1Ext>; 2460 2461 let opExtentBits = 8, accessSize = WordAccess, isCodeGenOnly = 0 in 2462 defm memopw_io : MemOp_base <"memw", 0b10, u6_2Ext>; 2463} 2464 2465//===----------------------------------------------------------------------===// 2466// Multiclass to define 'Def Pats' for ALU operations on the memory 2467// Here value used for the ALU operation is an immediate value. 2468// mem[bh](Rs+#0) += #U5 2469// mem[bh](Rs+#u6) += #U5 2470//===----------------------------------------------------------------------===// 2471 2472multiclass MemOpi_u5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 2473 InstHexagon MI, SDNode OpNode> { 2474 let AddedComplexity = 180 in 2475 def : Pat < (stOp (OpNode (ldOp IntRegs:$addr), u5ImmPred:$addend), 2476 IntRegs:$addr), 2477 (MI IntRegs:$addr, #0, u5ImmPred:$addend )>; 2478 2479 let AddedComplexity = 190 in 2480 def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, ExtPred:$offset)), 2481 u5ImmPred:$addend), 2482 (add IntRegs:$base, ExtPred:$offset)), 2483 (MI IntRegs:$base, ExtPred:$offset, u5ImmPred:$addend)>; 2484} 2485 2486multiclass MemOpi_u5ALUOp<PatFrag ldOp, PatFrag stOp, PatLeaf ExtPred, 2487 InstHexagon addMI, InstHexagon subMI> { 2488 defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, addMI, add>; 2489 defm : MemOpi_u5Pats<ldOp, stOp, ExtPred, subMI, sub>; 2490} 2491 2492multiclass MemOpi_u5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2493 // Half Word 2494 defm : MemOpi_u5ALUOp <ldOpHalf, truncstorei16, u6_1ExtPred, 2495 L4_iadd_memoph_io, L4_isub_memoph_io>; 2496 // Byte 2497 defm : MemOpi_u5ALUOp <ldOpByte, truncstorei8, u6ExtPred, 2498 L4_iadd_memopb_io, L4_isub_memopb_io>; 2499} 2500 2501let Predicates = [HasV4T, UseMEMOP] in { 2502 defm : MemOpi_u5ExtType<zextloadi8, zextloadi16>; // zero extend 2503 defm : MemOpi_u5ExtType<sextloadi8, sextloadi16>; // sign extend 2504 defm : MemOpi_u5ExtType<extloadi8, extloadi16>; // any extend 2505 2506 // Word 2507 defm : MemOpi_u5ALUOp <load, store, u6_2ExtPred, L4_iadd_memopw_io, 2508 L4_isub_memopw_io>; 2509} 2510 2511//===----------------------------------------------------------------------===// 2512// multiclass to define 'Def Pats' for ALU operations on the memory. 2513// Here value used for the ALU operation is a negative value. 2514// mem[bh](Rs+#0) += #m5 2515// mem[bh](Rs+#u6) += #m5 2516//===----------------------------------------------------------------------===// 2517 2518multiclass MemOpi_m5Pats <PatFrag ldOp, PatFrag stOp, PatLeaf extPred, 2519 PatLeaf immPred, ComplexPattern addrPred, 2520 SDNodeXForm xformFunc, InstHexagon MI> { 2521 let AddedComplexity = 190 in 2522 def : Pat <(stOp (add (ldOp IntRegs:$addr), immPred:$subend), 2523 IntRegs:$addr), 2524 (MI IntRegs:$addr, #0, (xformFunc immPred:$subend) )>; 2525 2526 let AddedComplexity = 195 in 2527 def : Pat<(stOp (add (ldOp (add IntRegs:$base, extPred:$offset)), 2528 immPred:$subend), 2529 (add IntRegs:$base, extPred:$offset)), 2530 (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$subend))>; 2531} 2532 2533multiclass MemOpi_m5ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2534 // Half Word 2535 defm : MemOpi_m5Pats <ldOpHalf, truncstorei16, u6_1ExtPred, m5HImmPred, 2536 ADDRriU6_1, MEMOPIMM_HALF, L4_isub_memoph_io>; 2537 // Byte 2538 defm : MemOpi_m5Pats <ldOpByte, truncstorei8, u6ExtPred, m5BImmPred, 2539 ADDRriU6_0, MEMOPIMM_BYTE, L4_isub_memopb_io>; 2540} 2541 2542let Predicates = [HasV4T, UseMEMOP] in { 2543 defm : MemOpi_m5ExtType<zextloadi8, zextloadi16>; // zero extend 2544 defm : MemOpi_m5ExtType<sextloadi8, sextloadi16>; // sign extend 2545 defm : MemOpi_m5ExtType<extloadi8, extloadi16>; // any extend 2546 2547 // Word 2548 defm : MemOpi_m5Pats <load, store, u6_2ExtPred, m5ImmPred, 2549 ADDRriU6_2, MEMOPIMM, L4_isub_memopw_io>; 2550} 2551 2552//===----------------------------------------------------------------------===// 2553// Multiclass to define 'def Pats' for bit operations on the memory. 2554// mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2555// mem[bhw](Rs+#u6) = [clrbit|setbit](#U5) 2556//===----------------------------------------------------------------------===// 2557 2558multiclass MemOpi_bitPats <PatFrag ldOp, PatFrag stOp, PatLeaf immPred, 2559 PatLeaf extPred, ComplexPattern addrPred, 2560 SDNodeXForm xformFunc, InstHexagon MI, SDNode OpNode> { 2561 2562 // mem[bhw](Rs+#u6:[012]) = [clrbit|setbit](#U5) 2563 let AddedComplexity = 250 in 2564 def : Pat<(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2565 immPred:$bitend), 2566 (add IntRegs:$base, extPred:$offset)), 2567 (MI IntRegs:$base, extPred:$offset, (xformFunc immPred:$bitend))>; 2568 2569 // mem[bhw](Rs+#0) = [clrbit|setbit](#U5) 2570 let AddedComplexity = 225 in 2571 def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)), 2572 immPred:$bitend), 2573 (addrPred (i32 IntRegs:$addr), extPred:$offset)), 2574 (MI IntRegs:$addr, extPred:$offset, (xformFunc immPred:$bitend))>; 2575} 2576 2577multiclass MemOpi_bitExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2578 // Byte - clrbit 2579 defm : MemOpi_bitPats<ldOpByte, truncstorei8, Clr3ImmPred, u6ExtPred, 2580 ADDRriU6_0, CLRMEMIMM_BYTE, L4_iand_memopb_io, and>; 2581 // Byte - setbit 2582 defm : MemOpi_bitPats<ldOpByte, truncstorei8, Set3ImmPred, u6ExtPred, 2583 ADDRriU6_0, SETMEMIMM_BYTE, L4_ior_memopb_io, or>; 2584 // Half Word - clrbit 2585 defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Clr4ImmPred, u6_1ExtPred, 2586 ADDRriU6_1, CLRMEMIMM_SHORT, L4_iand_memoph_io, and>; 2587 // Half Word - setbit 2588 defm : MemOpi_bitPats<ldOpHalf, truncstorei16, Set4ImmPred, u6_1ExtPred, 2589 ADDRriU6_1, SETMEMIMM_SHORT, L4_ior_memoph_io, or>; 2590} 2591 2592let Predicates = [HasV4T, UseMEMOP] in { 2593 // mem[bh](Rs+#0) = [clrbit|setbit](#U5) 2594 // mem[bh](Rs+#u6:[01]) = [clrbit|setbit](#U5) 2595 defm : MemOpi_bitExtType<zextloadi8, zextloadi16>; // zero extend 2596 defm : MemOpi_bitExtType<sextloadi8, sextloadi16>; // sign extend 2597 defm : MemOpi_bitExtType<extloadi8, extloadi16>; // any extend 2598 2599 // memw(Rs+#0) = [clrbit|setbit](#U5) 2600 // memw(Rs+#u6:2) = [clrbit|setbit](#U5) 2601 defm : MemOpi_bitPats<load, store, Clr5ImmPred, u6_2ExtPred, ADDRriU6_2, 2602 CLRMEMIMM, L4_iand_memopw_io, and>; 2603 defm : MemOpi_bitPats<load, store, Set5ImmPred, u6_2ExtPred, ADDRriU6_2, 2604 SETMEMIMM, L4_ior_memopw_io, or>; 2605} 2606 2607//===----------------------------------------------------------------------===// 2608// Multiclass to define 'def Pats' for ALU operations on the memory 2609// where addend is a register. 2610// mem[bhw](Rs+#0) [+-&|]= Rt 2611// mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2612//===----------------------------------------------------------------------===// 2613 2614multiclass MemOpr_Pats <PatFrag ldOp, PatFrag stOp, ComplexPattern addrPred, 2615 PatLeaf extPred, InstHexagon MI, SDNode OpNode> { 2616 let AddedComplexity = 141 in 2617 // mem[bhw](Rs+#0) [+-&|]= Rt 2618 def : Pat <(stOp (OpNode (ldOp (addrPred IntRegs:$addr, extPred:$offset)), 2619 (i32 IntRegs:$addend)), 2620 (addrPred (i32 IntRegs:$addr), extPred:$offset)), 2621 (MI IntRegs:$addr, extPred:$offset, (i32 IntRegs:$addend) )>; 2622 2623 // mem[bhw](Rs+#U6:[012]) [+-&|]= Rt 2624 let AddedComplexity = 150 in 2625 def : Pat <(stOp (OpNode (ldOp (add IntRegs:$base, extPred:$offset)), 2626 (i32 IntRegs:$orend)), 2627 (add IntRegs:$base, extPred:$offset)), 2628 (MI IntRegs:$base, extPred:$offset, (i32 IntRegs:$orend) )>; 2629} 2630 2631multiclass MemOPr_ALUOp<PatFrag ldOp, PatFrag stOp, 2632 ComplexPattern addrPred, PatLeaf extPred, 2633 InstHexagon addMI, InstHexagon subMI, 2634 InstHexagon andMI, InstHexagon orMI > { 2635 2636 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, addMI, add>; 2637 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, subMI, sub>; 2638 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, andMI, and>; 2639 defm : MemOpr_Pats <ldOp, stOp, addrPred, extPred, orMI, or>; 2640} 2641 2642multiclass MemOPr_ExtType<PatFrag ldOpByte, PatFrag ldOpHalf > { 2643 // Half Word 2644 defm : MemOPr_ALUOp <ldOpHalf, truncstorei16, ADDRriU6_1, u6_1ExtPred, 2645 L4_add_memoph_io, L4_sub_memoph_io, 2646 L4_and_memoph_io, L4_or_memoph_io>; 2647 // Byte 2648 defm : MemOPr_ALUOp <ldOpByte, truncstorei8, ADDRriU6_0, u6ExtPred, 2649 L4_add_memopb_io, L4_sub_memopb_io, 2650 L4_and_memopb_io, L4_or_memopb_io>; 2651} 2652 2653// Define 'def Pats' for MemOps with register addend. 2654let Predicates = [HasV4T, UseMEMOP] in { 2655 // Byte, Half Word 2656 defm : MemOPr_ExtType<zextloadi8, zextloadi16>; // zero extend 2657 defm : MemOPr_ExtType<sextloadi8, sextloadi16>; // sign extend 2658 defm : MemOPr_ExtType<extloadi8, extloadi16>; // any extend 2659 // Word 2660 defm : MemOPr_ALUOp <load, store, ADDRriU6_2, u6_2ExtPred, L4_add_memopw_io, 2661 L4_sub_memopw_io, L4_and_memopw_io, L4_or_memopw_io >; 2662} 2663 2664//===----------------------------------------------------------------------===// 2665// XTYPE/PRED + 2666//===----------------------------------------------------------------------===// 2667 2668// Hexagon V4 only supports these flavors of byte/half compare instructions: 2669// EQ/GT/GTU. Other flavors like GE/GEU/LT/LTU/LE/LEU are not supported by 2670// hardware. However, compiler can still implement these patterns through 2671// appropriate patterns combinations based on current implemented patterns. 2672// The implemented patterns are: EQ/GT/GTU. 2673// Missing patterns are: GE/GEU/LT/LTU/LE/LEU. 2674 2675// Following instruction is not being extended as it results into the 2676// incorrect code for negative numbers. 2677// Pd=cmpb.eq(Rs,#u8) 2678 2679let isCompare = 1, isExtendable = 1, opExtendable = 2, hasSideEffects = 0, 2680 validSubTargets = HasV4SubT in 2681class CMP_NOT_REG_IMM<string OpName, bits<2> op, Operand ImmOp, 2682 list<dag> Pattern> 2683 : ALU32Inst <(outs PredRegs:$dst), (ins IntRegs:$src1, ImmOp:$src2), 2684 "$dst = !cmp."#OpName#"($src1, #$src2)", 2685 Pattern, 2686 "", ALU32_2op_tc_2early_SLOT0123> { 2687 bits<2> dst; 2688 bits<5> src1; 2689 bits<10> src2; 2690 2691 let IClass = 0b0111; 2692 let Inst{27-24} = 0b0101; 2693 let Inst{23-22} = op; 2694 let Inst{20-16} = src1; 2695 let Inst{21} = !if (!eq(OpName, "gtu"), 0b0, src2{9}); 2696 let Inst{13-5} = src2{8-0}; 2697 let Inst{4-2} = 0b100; 2698 let Inst{1-0} = dst; 2699} 2700 2701let opExtentBits = 10, isExtentSigned = 1 in { 2702def C4_cmpneqi : CMP_NOT_REG_IMM <"eq", 0b00, s10Ext, [(set (i1 PredRegs:$dst), 2703 (setne (i32 IntRegs:$src1), s10ExtPred:$src2))]>; 2704 2705def C4_cmpltei : CMP_NOT_REG_IMM <"gt", 0b01, s10Ext, [(set (i1 PredRegs:$dst), 2706 (not (setgt (i32 IntRegs:$src1), s10ExtPred:$src2)))]>; 2707 2708} 2709let opExtentBits = 9 in 2710def C4_cmplteui : CMP_NOT_REG_IMM <"gtu", 0b10, u9Ext, [(set (i1 PredRegs:$dst), 2711 (not (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)))]>; 2712 2713 2714 2715// p=!cmp.eq(r1,r2) 2716let isCompare = 1, validSubTargets = HasV4SubT in 2717def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst), 2718 (ins IntRegs:$src1, IntRegs:$src2), 2719 "$dst = !cmp.eq($src1, $src2)", 2720 [(set (i1 PredRegs:$dst), 2721 (setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>, 2722 Requires<[HasV4T]>; 2723 2724// p=!cmp.gt(r1,r2) 2725let isCompare = 1, validSubTargets = HasV4SubT in 2726def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst), 2727 (ins IntRegs:$src1, IntRegs:$src2), 2728 "$dst = !cmp.gt($src1, $src2)", 2729 [(set (i1 PredRegs:$dst), 2730 (not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2731 Requires<[HasV4T]>; 2732 2733 2734// p=!cmp.gtu(r1,r2) 2735let isCompare = 1, validSubTargets = HasV4SubT in 2736def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst), 2737 (ins IntRegs:$src1, IntRegs:$src2), 2738 "$dst = !cmp.gtu($src1, $src2)", 2739 [(set (i1 PredRegs:$dst), 2740 (not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>, 2741 Requires<[HasV4T]>; 2742 2743let isCompare = 1, validSubTargets = HasV4SubT in 2744def CMPbEQri_V4 : MInst<(outs PredRegs:$dst), 2745 (ins IntRegs:$src1, u8Imm:$src2), 2746 "$dst = cmpb.eq($src1, #$src2)", 2747 [(set (i1 PredRegs:$dst), 2748 (seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>, 2749 Requires<[HasV4T]>; 2750 2751def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)), 2752 bb:$offset), 2753 (J2_jumpf (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2), 2754 bb:$offset)>, 2755 Requires<[HasV4T]>; 2756 2757// Pd=cmpb.eq(Rs,Rt) 2758let isCompare = 1, validSubTargets = HasV4SubT in 2759def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst), 2760 (ins IntRegs:$src1, IntRegs:$src2), 2761 "$dst = cmpb.eq($src1, $src2)", 2762 [(set (i1 PredRegs:$dst), 2763 (seteq (and (xor (i32 IntRegs:$src1), 2764 (i32 IntRegs:$src2)), 255), 0))]>, 2765 Requires<[HasV4T]>; 2766 2767// Pd=cmpb.eq(Rs,Rt) 2768let isCompare = 1, validSubTargets = HasV4SubT in 2769def CMPbEQrr_sbsb_V4 : MInst<(outs PredRegs:$dst), 2770 (ins IntRegs:$src1, IntRegs:$src2), 2771 "$dst = cmpb.eq($src1, $src2)", 2772 [(set (i1 PredRegs:$dst), 2773 (seteq (shl (i32 IntRegs:$src1), (i32 24)), 2774 (shl (i32 IntRegs:$src2), (i32 24))))]>, 2775 Requires<[HasV4T]>; 2776 2777// Pd=cmpb.gt(Rs,Rt) 2778let isCompare = 1, validSubTargets = HasV4SubT in 2779def CMPbGTrr_V4 : MInst<(outs PredRegs:$dst), 2780 (ins IntRegs:$src1, IntRegs:$src2), 2781 "$dst = cmpb.gt($src1, $src2)", 2782 [(set (i1 PredRegs:$dst), 2783 (setgt (shl (i32 IntRegs:$src1), (i32 24)), 2784 (shl (i32 IntRegs:$src2), (i32 24))))]>, 2785 Requires<[HasV4T]>; 2786 2787// Pd=cmpb.gtu(Rs,#u7) 2788let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 2789isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", InputType = "imm" in 2790def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst), 2791 (ins IntRegs:$src1, u7Ext:$src2), 2792 "$dst = cmpb.gtu($src1, #$src2)", 2793 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 2794 u7ExtPred:$src2))]>, 2795 Requires<[HasV4T]>, ImmRegRel; 2796 2797// SDNode for converting immediate C to C-1. 2798def DEC_CONST_BYTE : SDNodeXForm<imm, [{ 2799 // Return the byte immediate const-1 as an SDNode. 2800 int32_t imm = N->getSExtValue(); 2801 return XformU7ToU7M1Imm(imm); 2802}]>; 2803 2804// For the sequence 2805// zext( seteq ( and(Rs, 255), u8)) 2806// Generate 2807// Pd=cmpb.eq(Rs, #u8) 2808// if (Pd.new) Rd=#1 2809// if (!Pd.new) Rd=#0 2810def : Pat <(i32 (zext (i1 (seteq (i32 (and (i32 IntRegs:$Rs), 255)), 2811 u8ExtPred:$u8)))), 2812 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2813 (u8ExtPred:$u8))), 2814 1, 0))>, 2815 Requires<[HasV4T]>; 2816 2817// For the sequence 2818// zext( setne ( and(Rs, 255), u8)) 2819// Generate 2820// Pd=cmpb.eq(Rs, #u8) 2821// if (Pd.new) Rd=#0 2822// if (!Pd.new) Rd=#1 2823def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 IntRegs:$Rs), 255)), 2824 u8ExtPred:$u8)))), 2825 (i32 (TFR_condset_ii (i1 (CMPbEQri_V4 (i32 IntRegs:$Rs), 2826 (u8ExtPred:$u8))), 2827 0, 1))>, 2828 Requires<[HasV4T]>; 2829 2830// For the sequence 2831// zext( seteq (Rs, and(Rt, 255))) 2832// Generate 2833// Pd=cmpb.eq(Rs, Rt) 2834// if (Pd.new) Rd=#1 2835// if (!Pd.new) Rd=#0 2836def : Pat <(i32 (zext (i1 (seteq (i32 IntRegs:$Rt), 2837 (i32 (and (i32 IntRegs:$Rs), 255)))))), 2838 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2839 (i32 IntRegs:$Rt))), 2840 1, 0))>, 2841 Requires<[HasV4T]>; 2842 2843// For the sequence 2844// zext( setne (Rs, and(Rt, 255))) 2845// Generate 2846// Pd=cmpb.eq(Rs, Rt) 2847// if (Pd.new) Rd=#0 2848// if (!Pd.new) Rd=#1 2849def : Pat <(i32 (zext (i1 (setne (i32 IntRegs:$Rt), 2850 (i32 (and (i32 IntRegs:$Rs), 255)))))), 2851 (i32 (TFR_condset_ii (i1 (CMPbEQrr_ubub_V4 (i32 IntRegs:$Rs), 2852 (i32 IntRegs:$Rt))), 2853 0, 1))>, 2854 Requires<[HasV4T]>; 2855 2856// For the sequence 2857// zext( setugt ( and(Rs, 255), u8)) 2858// Generate 2859// Pd=cmpb.gtu(Rs, #u8) 2860// if (Pd.new) Rd=#1 2861// if (!Pd.new) Rd=#0 2862def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 255)), 2863 u8ExtPred:$u8)))), 2864 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2865 (u8ExtPred:$u8))), 2866 1, 0))>, 2867 Requires<[HasV4T]>; 2868 2869// For the sequence 2870// zext( setugt ( and(Rs, 254), u8)) 2871// Generate 2872// Pd=cmpb.gtu(Rs, #u8) 2873// if (Pd.new) Rd=#1 2874// if (!Pd.new) Rd=#0 2875def : Pat <(i32 (zext (i1 (setugt (i32 (and (i32 IntRegs:$Rs), 254)), 2876 u8ExtPred:$u8)))), 2877 (i32 (TFR_condset_ii (i1 (CMPbGTUri_V4 (i32 IntRegs:$Rs), 2878 (u8ExtPred:$u8))), 2879 1, 0))>, 2880 Requires<[HasV4T]>; 2881 2882// For the sequence 2883// zext( setult ( Rs, Rt)) 2884// Generate 2885// Pd=cmp.ltu(Rs, Rt) 2886// if (Pd.new) Rd=#1 2887// if (!Pd.new) Rd=#0 2888// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2889def : Pat <(i32 (zext (i1 (setult (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2890 (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt), 2891 (i32 IntRegs:$Rs))), 2892 1, 0))>, 2893 Requires<[HasV4T]>; 2894 2895// For the sequence 2896// zext( setlt ( Rs, Rt)) 2897// Generate 2898// Pd=cmp.lt(Rs, Rt) 2899// if (Pd.new) Rd=#1 2900// if (!Pd.new) Rd=#0 2901// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2902def : Pat <(i32 (zext (i1 (setlt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2903 (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt), 2904 (i32 IntRegs:$Rs))), 2905 1, 0))>, 2906 Requires<[HasV4T]>; 2907 2908// For the sequence 2909// zext( setugt ( Rs, Rt)) 2910// Generate 2911// Pd=cmp.gtu(Rs, Rt) 2912// if (Pd.new) Rd=#1 2913// if (!Pd.new) Rd=#0 2914def : Pat <(i32 (zext (i1 (setugt (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2915 (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs), 2916 (i32 IntRegs:$Rt))), 2917 1, 0))>, 2918 Requires<[HasV4T]>; 2919 2920// This pattern interefers with coremark performance, not implementing at this 2921// time. 2922// For the sequence 2923// zext( setgt ( Rs, Rt)) 2924// Generate 2925// Pd=cmp.gt(Rs, Rt) 2926// if (Pd.new) Rd=#1 2927// if (!Pd.new) Rd=#0 2928 2929// For the sequence 2930// zext( setuge ( Rs, Rt)) 2931// Generate 2932// Pd=cmp.ltu(Rs, Rt) 2933// if (Pd.new) Rd=#0 2934// if (!Pd.new) Rd=#1 2935// cmp.ltu(Rs, Rt) -> cmp.gtu(Rt, Rs) 2936def : Pat <(i32 (zext (i1 (setuge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2937 (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rt), 2938 (i32 IntRegs:$Rs))), 2939 0, 1))>, 2940 Requires<[HasV4T]>; 2941 2942// For the sequence 2943// zext( setge ( Rs, Rt)) 2944// Generate 2945// Pd=cmp.lt(Rs, Rt) 2946// if (Pd.new) Rd=#0 2947// if (!Pd.new) Rd=#1 2948// cmp.lt(Rs, Rt) -> cmp.gt(Rt, Rs) 2949def : Pat <(i32 (zext (i1 (setge (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2950 (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rt), 2951 (i32 IntRegs:$Rs))), 2952 0, 1))>, 2953 Requires<[HasV4T]>; 2954 2955// For the sequence 2956// zext( setule ( Rs, Rt)) 2957// Generate 2958// Pd=cmp.gtu(Rs, Rt) 2959// if (Pd.new) Rd=#0 2960// if (!Pd.new) Rd=#1 2961def : Pat <(i32 (zext (i1 (setule (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2962 (i32 (TFR_condset_ii (i1 (C2_cmpgtu (i32 IntRegs:$Rs), 2963 (i32 IntRegs:$Rt))), 2964 0, 1))>, 2965 Requires<[HasV4T]>; 2966 2967// For the sequence 2968// zext( setle ( Rs, Rt)) 2969// Generate 2970// Pd=cmp.gt(Rs, Rt) 2971// if (Pd.new) Rd=#0 2972// if (!Pd.new) Rd=#1 2973def : Pat <(i32 (zext (i1 (setle (i32 IntRegs:$Rs), (i32 IntRegs:$Rt))))), 2974 (i32 (TFR_condset_ii (i1 (C2_cmpgt (i32 IntRegs:$Rs), 2975 (i32 IntRegs:$Rt))), 2976 0, 1))>, 2977 Requires<[HasV4T]>; 2978 2979// For the sequence 2980// zext( setult ( and(Rs, 255), u8)) 2981// Use the isdigit transformation below 2982 2983// Generate code of the form 'mux_ii(cmpbgtu(Rdd, C-1),0,1)' 2984// for C code of the form r = ((c>='0') & (c<='9')) ? 1 : 0;. 2985// The isdigit transformation relies on two 'clever' aspects: 2986// 1) The data type is unsigned which allows us to eliminate a zero test after 2987// biasing the expression by 48. We are depending on the representation of 2988// the unsigned types, and semantics. 2989// 2) The front end has converted <= 9 into < 10 on entry to LLVM 2990// 2991// For the C code: 2992// retval = ((c>='0') & (c<='9')) ? 1 : 0; 2993// The code is transformed upstream of llvm into 2994// retval = (c-48) < 10 ? 1 : 0; 2995let AddedComplexity = 139 in 2996def : Pat <(i32 (zext (i1 (setult (i32 (and (i32 IntRegs:$src1), 255)), 2997 u7StrictPosImmPred:$src2)))), 2998 (i32 (C2_muxii (i1 (CMPbGTUri_V4 (i32 IntRegs:$src1), 2999 (DEC_CONST_BYTE u7StrictPosImmPred:$src2))), 3000 0, 1))>, 3001 Requires<[HasV4T]>; 3002 3003// Pd=cmpb.gtu(Rs,Rt) 3004let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU", 3005InputType = "reg" in 3006def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst), 3007 (ins IntRegs:$src1, IntRegs:$src2), 3008 "$dst = cmpb.gtu($src1, $src2)", 3009 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255), 3010 (and (i32 IntRegs:$src2), 255)))]>, 3011 Requires<[HasV4T]>, ImmRegRel; 3012 3013// Following instruction is not being extended as it results into the incorrect 3014// code for negative numbers. 3015 3016// Signed half compare(.eq) ri. 3017// Pd=cmph.eq(Rs,#s8) 3018let isCompare = 1, validSubTargets = HasV4SubT in 3019def CMPhEQri_V4 : MInst<(outs PredRegs:$dst), 3020 (ins IntRegs:$src1, s8Imm:$src2), 3021 "$dst = cmph.eq($src1, #$src2)", 3022 [(set (i1 PredRegs:$dst), (seteq (and (i32 IntRegs:$src1), 65535), 3023 s8ImmPred:$src2))]>, 3024 Requires<[HasV4T]>; 3025 3026// Signed half compare(.eq) rr. 3027// Case 1: xor + and, then compare: 3028// r0=xor(r0,r1) 3029// r0=and(r0,#0xffff) 3030// p0=cmp.eq(r0,#0) 3031// Pd=cmph.eq(Rs,Rt) 3032let isCompare = 1, validSubTargets = HasV4SubT in 3033def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst), 3034 (ins IntRegs:$src1, IntRegs:$src2), 3035 "$dst = cmph.eq($src1, $src2)", 3036 [(set (i1 PredRegs:$dst), (seteq (and (xor (i32 IntRegs:$src1), 3037 (i32 IntRegs:$src2)), 3038 65535), 0))]>, 3039 Requires<[HasV4T]>; 3040 3041// Signed half compare(.eq) rr. 3042// Case 2: shift left 16 bits then compare: 3043// r0=asl(r0,16) 3044// r1=asl(r1,16) 3045// p0=cmp.eq(r0,r1) 3046// Pd=cmph.eq(Rs,Rt) 3047let isCompare = 1, validSubTargets = HasV4SubT in 3048def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst), 3049 (ins IntRegs:$src1, IntRegs:$src2), 3050 "$dst = cmph.eq($src1, $src2)", 3051 [(set (i1 PredRegs:$dst), 3052 (seteq (shl (i32 IntRegs:$src1), (i32 16)), 3053 (shl (i32 IntRegs:$src2), (i32 16))))]>, 3054 Requires<[HasV4T]>; 3055 3056/* Incorrect Pattern -- immediate should be right shifted before being 3057used in the cmph.gt instruction. 3058// Signed half compare(.gt) ri. 3059// Pd=cmph.gt(Rs,#s8) 3060 3061let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8, 3062isCompare = 1, validSubTargets = HasV4SubT in 3063def CMPhGTri_V4 : MInst<(outs PredRegs:$dst), 3064 (ins IntRegs:$src1, s8Ext:$src2), 3065 "$dst = cmph.gt($src1, #$src2)", 3066 [(set (i1 PredRegs:$dst), 3067 (setgt (shl (i32 IntRegs:$src1), (i32 16)), 3068 s8ExtPred:$src2))]>, 3069 Requires<[HasV4T]>; 3070*/ 3071 3072// Signed half compare(.gt) rr. 3073// Pd=cmph.gt(Rs,Rt) 3074let isCompare = 1, validSubTargets = HasV4SubT in 3075def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst), 3076 (ins IntRegs:$src1, IntRegs:$src2), 3077 "$dst = cmph.gt($src1, $src2)", 3078 [(set (i1 PredRegs:$dst), 3079 (setgt (shl (i32 IntRegs:$src1), (i32 16)), 3080 (shl (i32 IntRegs:$src2), (i32 16))))]>, 3081 Requires<[HasV4T]>; 3082 3083// Unsigned half compare rr (.gtu). 3084// Pd=cmph.gtu(Rs,Rt) 3085let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 3086InputType = "reg" in 3087def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst), 3088 (ins IntRegs:$src1, IntRegs:$src2), 3089 "$dst = cmph.gtu($src1, $src2)", 3090 [(set (i1 PredRegs:$dst), 3091 (setugt (and (i32 IntRegs:$src1), 65535), 3092 (and (i32 IntRegs:$src2), 65535)))]>, 3093 Requires<[HasV4T]>, ImmRegRel; 3094 3095// Unsigned half compare ri (.gtu). 3096// Pd=cmph.gtu(Rs,#u7) 3097let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7, 3098isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU", 3099InputType = "imm" in 3100def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst), 3101 (ins IntRegs:$src1, u7Ext:$src2), 3102 "$dst = cmph.gtu($src1, #$src2)", 3103 [(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535), 3104 u7ExtPred:$src2))]>, 3105 Requires<[HasV4T]>, ImmRegRel; 3106 3107let validSubTargets = HasV4SubT in 3108def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2), 3109 "$dst = !tstbit($src1, $src2)", 3110 [(set (i1 PredRegs:$dst), 3111 (seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>, 3112 Requires<[HasV4T]>; 3113 3114let validSubTargets = HasV4SubT in 3115def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2), 3116 "$dst = !tstbit($src1, $src2)", 3117 [(set (i1 PredRegs:$dst), 3118 (seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>, 3119 Requires<[HasV4T]>; 3120 3121//===----------------------------------------------------------------------===// 3122// XTYPE/PRED - 3123//===----------------------------------------------------------------------===// 3124 3125//===----------------------------------------------------------------------===// 3126// Multiclass for DeallocReturn 3127//===----------------------------------------------------------------------===// 3128class L4_RETURN<string mnemonic, bit isNot, bit isPredNew, bit isTak> 3129 : LD0Inst<(outs), (ins PredRegs:$src), 3130 !if(isNot, "if (!$src", "if ($src")# 3131 !if(isPredNew, ".new) ", ") ")#mnemonic# 3132 !if(isPredNew, #!if(isTak,":t", ":nt"),""), 3133 [], "", LD_tc_3or4stall_SLOT0> { 3134 3135 bits<2> src; 3136 let BaseOpcode = "L4_RETURN"; 3137 let isPredicatedFalse = isNot; 3138 let isPredicatedNew = isPredNew; 3139 let isTaken = isTak; 3140 let IClass = 0b1001; 3141 3142 let Inst{27-16} = 0b011000011110; 3143 3144 let Inst{13} = isNot; 3145 let Inst{12} = isTak; 3146 let Inst{11} = isPredNew; 3147 let Inst{10} = 0b0; 3148 let Inst{9-8} = src; 3149 let Inst{4-0} = 0b11110; 3150 } 3151 3152// Produce all predicated forms, p, !p, p.new, !p.new, :t, :nt 3153multiclass L4_RETURN_PRED<string mnemonic, bit PredNot> { 3154 let isPredicated = 1 in { 3155 def _#NAME# : L4_RETURN <mnemonic, PredNot, 0, 1>; 3156 def _#NAME#new_pnt : L4_RETURN <mnemonic, PredNot, 1, 0>; 3157 def _#NAME#new_pt : L4_RETURN <mnemonic, PredNot, 1, 1>; 3158 } 3159} 3160 3161multiclass LD_MISC_L4_RETURN<string mnemonic> { 3162 let isBarrier = 1, isPredicable = 1 in 3163 def NAME : LD0Inst <(outs), (ins), mnemonic, [], "", 3164 LD_tc_3or4stall_SLOT0> { 3165 let BaseOpcode = "L4_RETURN"; 3166 let IClass = 0b1001; 3167 let Inst{27-16} = 0b011000011110; 3168 let Inst{13-10} = 0b0000; 3169 let Inst{4-0} = 0b11110; 3170 } 3171 defm t : L4_RETURN_PRED<mnemonic, 0 >; 3172 defm f : L4_RETURN_PRED<mnemonic, 1 >; 3173} 3174 3175let isReturn = 1, isTerminator = 1, 3176 Defs = [R29, R30, R31, PC], Uses = [R30], hasSideEffects = 0, 3177 validSubTargets = HasV4SubT, isCodeGenOnly = 0 in 3178defm L4_return: LD_MISC_L4_RETURN <"dealloc_return">, PredNewRel; 3179 3180// Restore registers and dealloc return function call. 3181let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1, 3182 Defs = [R29, R30, R31, PC] in { 3183let validSubTargets = HasV4SubT in 3184 def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs), 3185 (ins calltarget:$dst), 3186 "jump $dst", 3187 []>, 3188 Requires<[HasV4T]>; 3189} 3190 3191// Restore registers and dealloc frame before a tail call. 3192let isCall = 1, isBarrier = 1, 3193 Defs = [R29, R30, R31, PC] in { 3194let validSubTargets = HasV4SubT in 3195 def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs), 3196 (ins calltarget:$dst), 3197 "call $dst", 3198 []>, 3199 Requires<[HasV4T]>; 3200} 3201 3202// Save registers function call. 3203let isCall = 1, isBarrier = 1, 3204 Uses = [R29, R31] in { 3205 def SAVE_REGISTERS_CALL_V4 : JInst<(outs), 3206 (ins calltarget:$dst), 3207 "call $dst // Save_calle_saved_registers", 3208 []>, 3209 Requires<[HasV4T]>; 3210} 3211 3212//===----------------------------------------------------------------------===// 3213// Template class for non predicated store instructions with 3214// GP-Relative or absolute addressing. 3215//===----------------------------------------------------------------------===// 3216let hasSideEffects = 0, isPredicable = 1, isNVStorable = 1 in 3217class T_StoreAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp, 3218 bits<2>MajOp, Operand AddrOp, bit isAbs, bit isHalf> 3219 : STInst<(outs), (ins AddrOp:$addr, RC:$src), 3220 mnemonic # !if(isAbs, "(##", "(#")#"$addr) = $src"#!if(isHalf, ".h",""), 3221 [], "", V2LDST_tc_st_SLOT01> { 3222 bits<19> addr; 3223 bits<5> src; 3224 bits<16> offsetBits; 3225 3226 string ImmOpStr = !cast<string>(ImmOp); 3227 let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3}, 3228 !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, 3229 !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, 3230 /* u16_0Imm */ addr{15-0}))); 3231 let IClass = 0b0100; 3232 let Inst{27} = 1; 3233 let Inst{26-25} = offsetBits{15-14}; 3234 let Inst{24} = 0b0; 3235 let Inst{23-22} = MajOp; 3236 let Inst{21} = isHalf; 3237 let Inst{20-16} = offsetBits{13-9}; 3238 let Inst{13} = offsetBits{8}; 3239 let Inst{12-8} = src; 3240 let Inst{7-0} = offsetBits{7-0}; 3241 } 3242 3243//===----------------------------------------------------------------------===// 3244// Template class for predicated store instructions with 3245// GP-Relative or absolute addressing. 3246//===----------------------------------------------------------------------===// 3247let hasSideEffects = 0, isPredicated = 1, isNVStorable = 1, opExtentBits = 6, 3248 opExtendable = 1 in 3249class T_StoreAbs_Pred <string mnemonic, RegisterClass RC, bits<2> MajOp, 3250 bit isHalf, bit isNot, bit isNew> 3251 : STInst<(outs), (ins PredRegs:$src1, u6Ext:$absaddr, RC: $src2), 3252 !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ", 3253 ") ")#mnemonic#"(#$absaddr) = $src2"#!if(isHalf, ".h",""), 3254 [], "", ST_tc_st_SLOT01>, AddrModeRel { 3255 bits<2> src1; 3256 bits<6> absaddr; 3257 bits<5> src2; 3258 3259 let isPredicatedNew = isNew; 3260 let isPredicatedFalse = isNot; 3261 3262 let IClass = 0b1010; 3263 3264 let Inst{27-24} = 0b1111; 3265 let Inst{23-22} = MajOp; 3266 let Inst{21} = isHalf; 3267 let Inst{17-16} = absaddr{5-4}; 3268 let Inst{13} = isNew; 3269 let Inst{12-8} = src2; 3270 let Inst{7} = 0b1; 3271 let Inst{6-3} = absaddr{3-0}; 3272 let Inst{2} = isNot; 3273 let Inst{1-0} = src1; 3274 } 3275 3276//===----------------------------------------------------------------------===// 3277// Template class for predicated store instructions with absolute addressing. 3278//===----------------------------------------------------------------------===// 3279class T_StoreAbs <string mnemonic, RegisterClass RC, Operand ImmOp, 3280 bits<2> MajOp, bit isHalf> 3281 : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, u0AlwaysExt, 1, isHalf>, 3282 AddrModeRel { 3283 string ImmOpStr = !cast<string>(ImmOp); 3284 let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, 3285 !if (!eq(ImmOpStr, "u16_2Imm"), 18, 3286 !if (!eq(ImmOpStr, "u16_1Imm"), 17, 3287 /* u16_0Imm */ 16))); 3288 3289 let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, 3290 !if (!eq(ImmOpStr, "u16_2Imm"), 2, 3291 !if (!eq(ImmOpStr, "u16_1Imm"), 1, 3292 /* u16_0Imm */ 0))); 3293} 3294 3295//===----------------------------------------------------------------------===// 3296// Multiclass for store instructions with absolute addressing. 3297//===----------------------------------------------------------------------===// 3298let validSubTargets = HasV4SubT, addrMode = Absolute, isExtended = 1 in 3299multiclass ST_Abs<string mnemonic, string CextOp, RegisterClass RC, 3300 Operand ImmOp, bits<2> MajOp, bit isHalf = 0> { 3301 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 3302 let opExtendable = 0, isPredicable = 1 in 3303 def S2_#NAME#abs : T_StoreAbs <mnemonic, RC, ImmOp, MajOp, isHalf>; 3304 3305 // Predicated 3306 def S4_p#NAME#t_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 0>; 3307 def S4_p#NAME#f_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 0>; 3308 3309 // .new Predicated 3310 def S4_p#NAME#tnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 0, 1>; 3311 def S4_p#NAME#fnew_abs : T_StoreAbs_Pred<mnemonic, RC, MajOp, isHalf, 1, 1>; 3312 } 3313} 3314 3315//===----------------------------------------------------------------------===// 3316// Template class for non predicated new-value store instructions with 3317// GP-Relative or absolute addressing. 3318//===----------------------------------------------------------------------===// 3319let hasSideEffects = 0, isPredicable = 1, mayStore = 1, isNVStore = 1, 3320 isNewValue = 1, opNewValue = 1 in 3321class T_StoreAbsGP_NV <string mnemonic, Operand ImmOp, bits<2>MajOp, bit isAbs> 3322 : NVInst_V4<(outs), (ins u0AlwaysExt:$addr, IntRegs:$src), 3323 mnemonic # !if(isAbs, "(##", "(#")#"$addr) = $src.new", 3324 [], "", V2LDST_tc_st_SLOT0> { 3325 bits<19> addr; 3326 bits<3> src; 3327 bits<16> offsetBits; 3328 3329 string ImmOpStr = !cast<string>(ImmOp); 3330 let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3}, 3331 !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, 3332 !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, 3333 /* u16_0Imm */ addr{15-0}))); 3334 let IClass = 0b0100; 3335 3336 let Inst{27} = 1; 3337 let Inst{26-25} = offsetBits{15-14}; 3338 let Inst{24-21} = 0b0101; 3339 let Inst{20-16} = offsetBits{13-9}; 3340 let Inst{13} = offsetBits{8}; 3341 let Inst{12-11} = MajOp; 3342 let Inst{10-8} = src; 3343 let Inst{7-0} = offsetBits{7-0}; 3344 } 3345 3346//===----------------------------------------------------------------------===// 3347// Template class for predicated new-value store instructions with 3348// absolute addressing. 3349//===----------------------------------------------------------------------===// 3350let hasSideEffects = 0, isPredicated = 1, mayStore = 1, isNVStore = 1, 3351 isNewValue = 1, opNewValue = 2, opExtentBits = 6, opExtendable = 1 in 3352class T_StoreAbs_NV_Pred <string mnemonic, bits<2> MajOp, bit isNot, bit isNew> 3353 : NVInst_V4<(outs), (ins PredRegs:$src1, u6Ext:$absaddr, IntRegs:$src2), 3354 !if(isNot, "if (!$src1", "if ($src1")#!if(isNew, ".new) ", 3355 ") ")#mnemonic#"(#$absaddr) = $src2.new", 3356 [], "", ST_tc_st_SLOT0>, AddrModeRel { 3357 bits<2> src1; 3358 bits<6> absaddr; 3359 bits<3> src2; 3360 3361 let isPredicatedNew = isNew; 3362 let isPredicatedFalse = isNot; 3363 3364 let IClass = 0b1010; 3365 3366 let Inst{27-24} = 0b1111; 3367 let Inst{23-21} = 0b101; 3368 let Inst{17-16} = absaddr{5-4}; 3369 let Inst{13} = isNew; 3370 let Inst{12-11} = MajOp; 3371 let Inst{10-8} = src2; 3372 let Inst{7} = 0b1; 3373 let Inst{6-3} = absaddr{3-0}; 3374 let Inst{2} = isNot; 3375 let Inst{1-0} = src1; 3376} 3377 3378//===----------------------------------------------------------------------===// 3379// Template class for non-predicated new-value store instructions with 3380// absolute addressing. 3381//===----------------------------------------------------------------------===// 3382class T_StoreAbs_NV <string mnemonic, Operand ImmOp, bits<2> MajOp> 3383 : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp, 1>, AddrModeRel { 3384 3385 string ImmOpStr = !cast<string>(ImmOp); 3386 let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, 3387 !if (!eq(ImmOpStr, "u16_2Imm"), 18, 3388 !if (!eq(ImmOpStr, "u16_1Imm"), 17, 3389 /* u16_0Imm */ 16))); 3390 3391 let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, 3392 !if (!eq(ImmOpStr, "u16_2Imm"), 2, 3393 !if (!eq(ImmOpStr, "u16_1Imm"), 1, 3394 /* u16_0Imm */ 0))); 3395} 3396 3397//===----------------------------------------------------------------------===// 3398// Multiclass for new-value store instructions with absolute addressing. 3399//===----------------------------------------------------------------------===// 3400let validSubTargets = HasV4SubT, addrMode = Absolute, isExtended = 1 in 3401multiclass ST_Abs_NV <string mnemonic, string CextOp, Operand ImmOp, 3402 bits<2> MajOp> { 3403 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 3404 let opExtendable = 0, isPredicable = 1 in 3405 def S2_#NAME#newabs : T_StoreAbs_NV <mnemonic, ImmOp, MajOp>; 3406 3407 // Predicated 3408 def S4_p#NAME#newt_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 0>; 3409 def S4_p#NAME#newf_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 0>; 3410 3411 // .new Predicated 3412 def S4_p#NAME#newtnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 0, 1>; 3413 def S4_p#NAME#newfnew_abs : T_StoreAbs_NV_Pred <mnemonic, MajOp, 1, 1>; 3414 } 3415} 3416 3417//===----------------------------------------------------------------------===// 3418// Stores with absolute addressing 3419//===----------------------------------------------------------------------===// 3420let accessSize = ByteAccess, isCodeGenOnly = 0 in 3421defm storerb : ST_Abs <"memb", "STrib", IntRegs, u16_0Imm, 0b00>, 3422 ST_Abs_NV <"memb", "STrib", u16_0Imm, 0b00>; 3423 3424let accessSize = HalfWordAccess, isCodeGenOnly = 0 in 3425defm storerh : ST_Abs <"memh", "STrih", IntRegs, u16_1Imm, 0b01>, 3426 ST_Abs_NV <"memh", "STrih", u16_1Imm, 0b01>; 3427 3428let accessSize = WordAccess, isCodeGenOnly = 0 in 3429defm storeri : ST_Abs <"memw", "STriw", IntRegs, u16_2Imm, 0b10>, 3430 ST_Abs_NV <"memw", "STriw", u16_2Imm, 0b10>; 3431 3432let isNVStorable = 0, accessSize = DoubleWordAccess, isCodeGenOnly = 0 in 3433defm storerd : ST_Abs <"memd", "STrid", DoubleRegs, u16_3Imm, 0b11>; 3434 3435let isNVStorable = 0, accessSize = HalfWordAccess, isCodeGenOnly = 0 in 3436defm storerf : ST_Abs <"memh", "STrif", IntRegs, u16_1Imm, 0b01, 1>; 3437 3438//===----------------------------------------------------------------------===// 3439// GP-relative stores. 3440// mem[bhwd](#global)=Rt 3441// Once predicated, these instructions map to absolute addressing mode. 3442// if ([!]Pv[.new]) mem[bhwd](##global)=Rt 3443//===----------------------------------------------------------------------===// 3444 3445let validSubTargets = HasV4SubT in 3446class T_StoreGP <string mnemonic, string BaseOp, RegisterClass RC, 3447 Operand ImmOp, bits<2> MajOp, bit isHalf = 0> 3448 : T_StoreAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0, isHalf> { 3449 // Set BaseOpcode same as absolute addressing instructions so that 3450 // non-predicated GP-Rel instructions can have relate with predicated 3451 // Absolute instruction. 3452 let BaseOpcode = BaseOp#_abs; 3453 } 3454 3455let validSubTargets = HasV4SubT in 3456multiclass ST_GP <string mnemonic, string BaseOp, Operand ImmOp, 3457 bits<2> MajOp, bit isHalf = 0> { 3458 // Set BaseOpcode same as absolute addressing instructions so that 3459 // non-predicated GP-Rel instructions can have relate with predicated 3460 // Absolute instruction. 3461 let BaseOpcode = BaseOp#_abs in { 3462 def NAME#gp : T_StoreAbsGP <mnemonic, IntRegs, ImmOp, MajOp, 3463 globaladdress, 0, isHalf>; 3464 // New-value store 3465 def NAME#newgp : T_StoreAbsGP_NV <mnemonic, ImmOp, MajOp, 0> ; 3466 } 3467} 3468 3469let accessSize = ByteAccess in 3470defm S2_storerb : ST_GP<"memb", "STrib", u16_0Imm, 0b00>, NewValueRel; 3471 3472let accessSize = HalfWordAccess in 3473defm S2_storerh : ST_GP<"memh", "STrih", u16_1Imm, 0b01>, NewValueRel; 3474 3475let accessSize = WordAccess in 3476defm S2_storeri : ST_GP<"memw", "STriw", u16_2Imm, 0b10>, NewValueRel; 3477 3478let isNVStorable = 0, accessSize = DoubleWordAccess in 3479def S2_storerdgp : T_StoreGP <"memd", "STrid", DoubleRegs, 3480 u16_3Imm, 0b11>, PredNewRel; 3481 3482let isNVStorable = 0, accessSize = HalfWordAccess in 3483def S2_storerfgp : T_StoreGP <"memh", "STrif", IntRegs, 3484 u16_1Imm, 0b01, 1>, PredNewRel; 3485 3486let Predicates = [HasV4T], AddedComplexity = 30 in { 3487def : Pat<(truncstorei8 (i32 IntRegs:$src1), 3488 (HexagonCONST32 tglobaladdr:$absaddr)), 3489 (S2_storerbabs tglobaladdr: $absaddr, IntRegs: $src1)>; 3490 3491def : Pat<(truncstorei16 (i32 IntRegs:$src1), 3492 (HexagonCONST32 tglobaladdr:$absaddr)), 3493 (S2_storerhabs tglobaladdr: $absaddr, IntRegs: $src1)>; 3494 3495def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32 tglobaladdr:$absaddr)), 3496 (S2_storeriabs tglobaladdr: $absaddr, IntRegs: $src1)>; 3497 3498def : Pat<(store (i64 DoubleRegs:$src1), 3499 (HexagonCONST32 tglobaladdr:$absaddr)), 3500 (S2_storerdabs tglobaladdr: $absaddr, DoubleRegs: $src1)>; 3501} 3502 3503// 64 bit atomic store 3504def : Pat <(atomic_store_64 (HexagonCONST32_GP tglobaladdr:$global), 3505 (i64 DoubleRegs:$src1)), 3506 (S2_storerdgp tglobaladdr:$global, (i64 DoubleRegs:$src1))>, 3507 Requires<[HasV4T]>; 3508 3509// Map from store(globaladdress) -> memd(#foo) 3510let AddedComplexity = 100 in 3511def : Pat <(store (i64 DoubleRegs:$src1), 3512 (HexagonCONST32_GP tglobaladdr:$global)), 3513 (S2_storerdgp tglobaladdr:$global, (i64 DoubleRegs:$src1))>; 3514 3515// 8 bit atomic store 3516def : Pat < (atomic_store_8 (HexagonCONST32_GP tglobaladdr:$global), 3517 (i32 IntRegs:$src1)), 3518 (S2_storerbgp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3519 3520// Map from store(globaladdress) -> memb(#foo) 3521let AddedComplexity = 100 in 3522def : Pat<(truncstorei8 (i32 IntRegs:$src1), 3523 (HexagonCONST32_GP tglobaladdr:$global)), 3524 (S2_storerbgp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3525 3526// Map from "i1 = constant<-1>; memw(CONST32(#foo)) = i1" 3527// to "r0 = 1; memw(#foo) = r0" 3528let AddedComplexity = 100 in 3529def : Pat<(store (i1 -1), (HexagonCONST32_GP tglobaladdr:$global)), 3530 (S2_storerbgp tglobaladdr:$global, (A2_tfrsi 1))>; 3531 3532def : Pat<(atomic_store_16 (HexagonCONST32_GP tglobaladdr:$global), 3533 (i32 IntRegs:$src1)), 3534 (S2_storerhgp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3535 3536// Map from store(globaladdress) -> memh(#foo) 3537let AddedComplexity = 100 in 3538def : Pat<(truncstorei16 (i32 IntRegs:$src1), 3539 (HexagonCONST32_GP tglobaladdr:$global)), 3540 (S2_storerhgp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3541 3542// 32 bit atomic store 3543def : Pat<(atomic_store_32 (HexagonCONST32_GP tglobaladdr:$global), 3544 (i32 IntRegs:$src1)), 3545 (S2_storerigp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3546 3547// Map from store(globaladdress) -> memw(#foo) 3548let AddedComplexity = 100 in 3549def : Pat<(store (i32 IntRegs:$src1), (HexagonCONST32_GP tglobaladdr:$global)), 3550 (S2_storerigp tglobaladdr:$global, (i32 IntRegs:$src1))>; 3551 3552//===----------------------------------------------------------------------===// 3553// Template class for non predicated load instructions with 3554// absolute addressing mode. 3555//===----------------------------------------------------------------------===// 3556let isPredicable = 1, hasSideEffects = 0, validSubTargets = HasV4SubT in 3557class T_LoadAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp, 3558 bits<3> MajOp, Operand AddrOp, bit isAbs> 3559 : LDInst <(outs RC:$dst), (ins AddrOp:$addr), 3560 "$dst = "#mnemonic# !if(isAbs, "(##", "(#")#"$addr)", 3561 [], "", V2LDST_tc_ld_SLOT01> { 3562 bits<5> dst; 3563 bits<19> addr; 3564 bits<16> offsetBits; 3565 3566 string ImmOpStr = !cast<string>(ImmOp); 3567 let offsetBits = !if (!eq(ImmOpStr, "u16_3Imm"), addr{18-3}, 3568 !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, 3569 !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, 3570 /* u16_0Imm */ addr{15-0}))); 3571 3572 let IClass = 0b0100; 3573 3574 let Inst{27} = 0b1; 3575 let Inst{26-25} = offsetBits{15-14}; 3576 let Inst{24} = 0b1; 3577 let Inst{23-21} = MajOp; 3578 let Inst{20-16} = offsetBits{13-9}; 3579 let Inst{13-5} = offsetBits{8-0}; 3580 let Inst{4-0} = dst; 3581 } 3582 3583class T_LoadAbs <string mnemonic, RegisterClass RC, Operand ImmOp, 3584 bits<3> MajOp> 3585 : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, u0AlwaysExt, 1>, AddrModeRel { 3586 3587 string ImmOpStr = !cast<string>(ImmOp); 3588 let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, 3589 !if (!eq(ImmOpStr, "u16_2Imm"), 18, 3590 !if (!eq(ImmOpStr, "u16_1Imm"), 17, 3591 /* u16_0Imm */ 16))); 3592 3593 let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, 3594 !if (!eq(ImmOpStr, "u16_2Imm"), 2, 3595 !if (!eq(ImmOpStr, "u16_1Imm"), 1, 3596 /* u16_0Imm */ 0))); 3597 } 3598//===----------------------------------------------------------------------===// 3599// Template class for predicated load instructions with 3600// absolute addressing mode. 3601//===----------------------------------------------------------------------===// 3602let isPredicated = 1, hasNewValue = 1, opExtentBits = 6, opExtendable = 2 in 3603class T_LoadAbs_Pred <string mnemonic, RegisterClass RC, bits<3> MajOp, 3604 bit isPredNot, bit isPredNew> 3605 : LDInst <(outs RC:$dst), (ins PredRegs:$src1, u6Ext:$absaddr), 3606 !if(isPredNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ", 3607 ") ")#"$dst = "#mnemonic#"(#$absaddr)">, AddrModeRel { 3608 bits<5> dst; 3609 bits<2> src1; 3610 bits<6> absaddr; 3611 3612 let isPredicatedNew = isPredNew; 3613 let isPredicatedFalse = isPredNot; 3614 3615 let IClass = 0b1001; 3616 3617 let Inst{27-24} = 0b1111; 3618 let Inst{23-21} = MajOp; 3619 let Inst{20-16} = absaddr{5-1}; 3620 let Inst{13} = 0b1; 3621 let Inst{12} = isPredNew; 3622 let Inst{11} = isPredNot; 3623 let Inst{10-9} = src1; 3624 let Inst{8} = absaddr{0}; 3625 let Inst{7} = 0b1; 3626 let Inst{4-0} = dst; 3627 } 3628 3629//===----------------------------------------------------------------------===// 3630// Multiclass for the load instructions with absolute addressing mode. 3631//===----------------------------------------------------------------------===// 3632multiclass LD_Abs_Pred<string mnemonic, RegisterClass RC, bits<3> MajOp, 3633 bit PredNot> { 3634 def _abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 0>; 3635 // Predicate new 3636 def new_abs : T_LoadAbs_Pred <mnemonic, RC, MajOp, PredNot, 1>; 3637} 3638 3639let addrMode = Absolute, isExtended = 1 in 3640multiclass LD_Abs<string mnemonic, string CextOp, RegisterClass RC, 3641 Operand ImmOp, bits<3> MajOp> { 3642 let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in { 3643 let opExtendable = 1, isPredicable = 1 in 3644 def L4_#NAME#_abs: T_LoadAbs <mnemonic, RC, ImmOp, MajOp>; 3645 3646 // Predicated 3647 defm L4_p#NAME#t : LD_Abs_Pred<mnemonic, RC, MajOp, 0>; 3648 defm L4_p#NAME#f : LD_Abs_Pred<mnemonic, RC, MajOp, 1>; 3649 } 3650} 3651 3652let accessSize = ByteAccess, hasNewValue = 1, isCodeGenOnly = 0 in { 3653 defm loadrb : LD_Abs<"memb", "LDrib", IntRegs, u16_0Imm, 0b000>; 3654 defm loadrub : LD_Abs<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>; 3655} 3656 3657let accessSize = HalfWordAccess, hasNewValue = 1, isCodeGenOnly = 0 in { 3658 defm loadrh : LD_Abs<"memh", "LDrih", IntRegs, u16_1Imm, 0b010>; 3659 defm loadruh : LD_Abs<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>; 3660} 3661 3662let accessSize = WordAccess, hasNewValue = 1, isCodeGenOnly = 0 in 3663defm loadri : LD_Abs<"memw", "LDriw", IntRegs, u16_2Imm, 0b100>; 3664 3665let accessSize = DoubleWordAccess, isCodeGenOnly = 0 in 3666defm loadrd : LD_Abs<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>; 3667 3668//===----------------------------------------------------------------------===// 3669// multiclass for load instructions with GP-relative addressing mode. 3670// Rx=mem[bhwd](##global) 3671// Once predicated, these instructions map to absolute addressing mode. 3672// if ([!]Pv[.new]) Rx=mem[bhwd](##global) 3673//===----------------------------------------------------------------------===// 3674 3675class T_LoadGP <string mnemonic, string BaseOp, RegisterClass RC, Operand ImmOp, 3676 bits<3> MajOp> 3677 : T_LoadAbsGP <mnemonic, RC, ImmOp, MajOp, globaladdress, 0>, PredNewRel { 3678 let BaseOpcode = BaseOp#_abs; 3679 } 3680 3681let accessSize = ByteAccess, hasNewValue = 1 in { 3682 def L2_loadrbgp : T_LoadGP<"memb", "LDrib", IntRegs, u16_0Imm, 0b000>; 3683 def L2_loadrubgp : T_LoadGP<"memub", "LDriub", IntRegs, u16_0Imm, 0b001>; 3684} 3685 3686let accessSize = HalfWordAccess, hasNewValue = 1 in { 3687 def L2_loadrhgp : T_LoadGP<"memh", "LDrih", IntRegs, u16_1Imm, 0b010>; 3688 def L2_loadruhgp : T_LoadGP<"memuh", "LDriuh", IntRegs, u16_1Imm, 0b011>; 3689} 3690 3691let accessSize = WordAccess, hasNewValue = 1 in 3692def L2_loadrigp : T_LoadGP<"memw", "LDriw", IntRegs, u16_2Imm, 0b100>; 3693 3694let accessSize = DoubleWordAccess in 3695def L2_loadrdgp : T_LoadGP<"memd", "LDrid", DoubleRegs, u16_3Imm, 0b110>; 3696 3697let Predicates = [HasV4T], AddedComplexity = 30 in { 3698def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))), 3699 (L4_loadri_abs tglobaladdr: $absaddr)>; 3700 3701def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 3702 (L4_loadrb_abs tglobaladdr:$absaddr)>; 3703 3704def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))), 3705 (L4_loadrub_abs tglobaladdr:$absaddr)>; 3706 3707def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 3708 (L4_loadrh_abs tglobaladdr:$absaddr)>; 3709 3710def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))), 3711 (L4_loadruh_abs tglobaladdr:$absaddr)>; 3712} 3713 3714def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)), 3715 (i64 (L2_loadrdgp tglobaladdr:$global))>; 3716 3717def : Pat <(atomic_load_32 (HexagonCONST32_GP tglobaladdr:$global)), 3718 (i32 (L2_loadrigp tglobaladdr:$global))>; 3719 3720def : Pat <(atomic_load_16 (HexagonCONST32_GP tglobaladdr:$global)), 3721 (i32 (L2_loadruhgp tglobaladdr:$global))>; 3722 3723def : Pat <(atomic_load_8 (HexagonCONST32_GP tglobaladdr:$global)), 3724 (i32 (L2_loadrubgp tglobaladdr:$global))>; 3725 3726// Map from load(globaladdress) -> memw(#foo + 0) 3727let AddedComplexity = 100 in 3728def : Pat <(i64 (load (HexagonCONST32_GP tglobaladdr:$global))), 3729 (i64 (L2_loadrdgp tglobaladdr:$global))>; 3730 3731// Map from Pd = load(globaladdress) -> Rd = memb(globaladdress), Pd = Rd 3732let AddedComplexity = 100 in 3733def : Pat <(i1 (load (HexagonCONST32_GP tglobaladdr:$global))), 3734 (i1 (C2_tfrrp (i32 (L2_loadrbgp tglobaladdr:$global))))>; 3735 3736// When the Interprocedural Global Variable optimizer realizes that a certain 3737// global variable takes only two constant values, it shrinks the global to 3738// a boolean. Catch those loads here in the following 3 patterns. 3739let AddedComplexity = 100 in 3740def : Pat <(i32 (extloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3741 (i32 (L2_loadrbgp tglobaladdr:$global))>; 3742 3743let AddedComplexity = 100 in 3744def : Pat <(i32 (sextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3745 (i32 (L2_loadrbgp tglobaladdr:$global))>; 3746 3747// Map from load(globaladdress) -> memb(#foo) 3748let AddedComplexity = 100 in 3749def : Pat <(i32 (extloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3750 (i32 (L2_loadrbgp tglobaladdr:$global))>; 3751 3752// Map from load(globaladdress) -> memb(#foo) 3753let AddedComplexity = 100 in 3754def : Pat <(i32 (sextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3755 (i32 (L2_loadrbgp tglobaladdr:$global))>; 3756 3757let AddedComplexity = 100 in 3758def : Pat <(i32 (zextloadi1 (HexagonCONST32_GP tglobaladdr:$global))), 3759 (i32 (L2_loadrubgp tglobaladdr:$global))>; 3760 3761// Map from load(globaladdress) -> memub(#foo) 3762let AddedComplexity = 100 in 3763def : Pat <(i32 (zextloadi8 (HexagonCONST32_GP tglobaladdr:$global))), 3764 (i32 (L2_loadrubgp tglobaladdr:$global))>; 3765 3766// Map from load(globaladdress) -> memh(#foo) 3767let AddedComplexity = 100 in 3768def : Pat <(i32 (extloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3769 (i32 (L2_loadrhgp tglobaladdr:$global))>; 3770 3771// Map from load(globaladdress) -> memh(#foo) 3772let AddedComplexity = 100 in 3773def : Pat <(i32 (sextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3774 (i32 (L2_loadrhgp tglobaladdr:$global))>; 3775 3776// Map from load(globaladdress) -> memuh(#foo) 3777let AddedComplexity = 100 in 3778def : Pat <(i32 (zextloadi16 (HexagonCONST32_GP tglobaladdr:$global))), 3779 (i32 (L2_loadruhgp tglobaladdr:$global))>; 3780 3781// Map from load(globaladdress) -> memw(#foo) 3782let AddedComplexity = 100 in 3783def : Pat <(i32 (load (HexagonCONST32_GP tglobaladdr:$global))), 3784 (i32 (L2_loadrigp tglobaladdr:$global))>; 3785 3786 3787// Transfer global address into a register 3788let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1, 3789isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in 3790def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1), 3791 "$dst = #$src1", 3792 [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>, 3793 Requires<[HasV4T]>; 3794 3795// Transfer a block address into a register 3796def : Pat<(HexagonCONST32_GP tblockaddress:$src1), 3797 (TFRI_V4 tblockaddress:$src1)>, 3798 Requires<[HasV4T]>; 3799 3800let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3801hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in 3802def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3803 (ins PredRegs:$src1, s16Ext:$src2), 3804 "if($src1) $dst = #$src2", 3805 []>, 3806 Requires<[HasV4T]>; 3807 3808let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3809hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in 3810def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3811 (ins PredRegs:$src1, s16Ext:$src2), 3812 "if(!$src1) $dst = #$src2", 3813 []>, 3814 Requires<[HasV4T]>; 3815 3816let isExtended = 1, opExtendable = 2, AddedComplexity=50, 3817hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in 3818def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3819 (ins PredRegs:$src1, s16Ext:$src2), 3820 "if($src1.new) $dst = #$src2", 3821 []>, 3822 Requires<[HasV4T]>; 3823 3824let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1, 3825hasSideEffects = 0, isPredicated = 1, validSubTargets = HasV4SubT in 3826def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst), 3827 (ins PredRegs:$src1, s16Ext:$src2), 3828 "if(!$src1.new) $dst = #$src2", 3829 []>, 3830 Requires<[HasV4T]>; 3831 3832let AddedComplexity = 50, Predicates = [HasV4T] in 3833def : Pat<(HexagonCONST32_GP tglobaladdr:$src1), 3834 (TFRI_V4 tglobaladdr:$src1)>, 3835 Requires<[HasV4T]>; 3836 3837 3838// Load - Indirect with long offset: These instructions take global address 3839// as an operand 3840let isExtended = 1, opExtendable = 3, AddedComplexity = 40, 3841validSubTargets = HasV4SubT in 3842def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst), 3843 (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3844 "$dst=memd($src1<<#$src2+##$offset)", 3845 [(set (i64 DoubleRegs:$dst), 3846 (load (add (shl IntRegs:$src1, u2ImmPred:$src2), 3847 (HexagonCONST32 tglobaladdr:$offset))))]>, 3848 Requires<[HasV4T]>; 3849 3850let AddedComplexity = 40 in 3851multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> { 3852let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in 3853 def _lo_V4 : LDInst<(outs IntRegs:$dst), 3854 (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset), 3855 !strconcat("$dst = ", 3856 !strconcat(OpcStr, "($src1<<#$src2+##$offset)")), 3857 [(set IntRegs:$dst, 3858 (i32 (OpNode (add (shl IntRegs:$src1, u2ImmPred:$src2), 3859 (HexagonCONST32 tglobaladdr:$offset)))))]>, 3860 Requires<[HasV4T]>; 3861} 3862 3863defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>; 3864defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>; 3865defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>; 3866defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>; 3867defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>; 3868defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>; 3869defm LDriw_ind : LD_indirect_lo<"memw", load>; 3870 3871let AddedComplexity = 40 in 3872def : Pat <(i32 (sextloadi8 (add IntRegs:$src1, 3873 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3874 (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3875 Requires<[HasV4T]>; 3876 3877let AddedComplexity = 40 in 3878def : Pat <(i32 (zextloadi8 (add IntRegs:$src1, 3879 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))), 3880 (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>, 3881 Requires<[HasV4T]>; 3882 3883let Predicates = [HasV4T], AddedComplexity = 30 in { 3884def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3885 (S2_storerbabs u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3886 3887def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3888 (S2_storerhabs u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3889 3890def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2), 3891 (S2_storeriabs u0AlwaysExtPred:$src2, IntRegs: $src1)>; 3892} 3893 3894let Predicates = [HasV4T], AddedComplexity = 30 in { 3895def : Pat<(i32 (load u0AlwaysExtPred:$src)), 3896 (L4_loadri_abs u0AlwaysExtPred:$src)>; 3897 3898def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)), 3899 (L4_loadrb_abs u0AlwaysExtPred:$src)>; 3900 3901def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)), 3902 (L4_loadrub_abs u0AlwaysExtPred:$src)>; 3903 3904def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)), 3905 (L4_loadrh_abs u0AlwaysExtPred:$src)>; 3906 3907def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)), 3908 (L4_loadruh_abs u0AlwaysExtPred:$src)>; 3909} 3910 3911// Indexed store word - global address. 3912// memw(Rs+#u6:2)=#S8 3913let AddedComplexity = 10 in 3914def STriw_offset_ext_V4 : STInst<(outs), 3915 (ins IntRegs:$src1, u6_2Imm:$src2, globaladdress:$src3), 3916 "memw($src1+#$src2) = ##$src3", 3917 [(store (HexagonCONST32 tglobaladdr:$src3), 3918 (add IntRegs:$src1, u6_2ImmPred:$src2))]>, 3919 Requires<[HasV4T]>; 3920 3921def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))), 3922 (i64 (A4_combineir (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>, 3923 Requires<[HasV4T]>; 3924 3925def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))), 3926 (i64 (A4_combineir (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>, 3927 Requires<[HasV4T]>; 3928 3929 3930// i8 -> i64 loads 3931// We need a complexity of 120 here to override preceding handling of 3932// zextloadi8. 3933let Predicates = [HasV4T], AddedComplexity = 120 in { 3934def: Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3935 (i64 (A4_combineir 0, (L4_loadrb_abs tglobaladdr:$addr)))>; 3936 3937def: Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3938 (i64 (A4_combineir 0, (L4_loadrub_abs tglobaladdr:$addr)))>; 3939 3940def: Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3941 (i64 (A2_sxtw (L4_loadrb_abs tglobaladdr:$addr)))>; 3942 3943def: Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)), 3944 (i64 (A4_combineir 0, (L4_loadrb_abs FoldGlobalAddr:$addr)))>; 3945 3946def: Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)), 3947 (i64 (A4_combineir 0, (L4_loadrub_abs FoldGlobalAddr:$addr)))>; 3948 3949def: Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)), 3950 (i64 (A2_sxtw (L4_loadrb_abs FoldGlobalAddr:$addr)))>; 3951} 3952// i16 -> i64 loads 3953// We need a complexity of 120 here to override preceding handling of 3954// zextloadi16. 3955let AddedComplexity = 120 in { 3956def: Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3957 (i64 (A4_combineir 0, (L4_loadrh_abs tglobaladdr:$addr)))>, 3958 Requires<[HasV4T]>; 3959 3960def: Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3961 (i64 (A4_combineir 0, (L4_loadruh_abs tglobaladdr:$addr)))>, 3962 Requires<[HasV4T]>; 3963 3964def: Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3965 (i64 (A2_sxtw (L4_loadrh_abs tglobaladdr:$addr)))>, 3966 Requires<[HasV4T]>; 3967 3968def: Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)), 3969 (i64 (A4_combineir 0, (L4_loadrh_abs FoldGlobalAddr:$addr)))>, 3970 Requires<[HasV4T]>; 3971 3972def: Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)), 3973 (i64 (A4_combineir 0, (L4_loadruh_abs FoldGlobalAddr:$addr)))>, 3974 Requires<[HasV4T]>; 3975 3976def: Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)), 3977 (i64 (A2_sxtw (L4_loadrh_abs FoldGlobalAddr:$addr)))>, 3978 Requires<[HasV4T]>; 3979} 3980// i32->i64 loads 3981// We need a complexity of 120 here to override preceding handling of 3982// zextloadi32. 3983let AddedComplexity = 120 in { 3984def: Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3985 (i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>, 3986 Requires<[HasV4T]>; 3987 3988def: Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3989 (i64 (A4_combineir 0, (L4_loadri_abs tglobaladdr:$addr)))>, 3990 Requires<[HasV4T]>; 3991 3992def: Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))), 3993 (i64 (A2_sxtw (L4_loadri_abs tglobaladdr:$addr)))>, 3994 Requires<[HasV4T]>; 3995 3996def: Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)), 3997 (i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>, 3998 Requires<[HasV4T]>; 3999 4000def: Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)), 4001 (i64 (A4_combineir 0, (L4_loadri_abs FoldGlobalAddr:$addr)))>, 4002 Requires<[HasV4T]>; 4003 4004def: Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)), 4005 (i64 (A2_sxtw (L4_loadri_abs FoldGlobalAddr:$addr)))>, 4006 Requires<[HasV4T]>; 4007} 4008 4009// Indexed store double word - global address. 4010// memw(Rs+#u6:2)=#S8 4011let AddedComplexity = 10 in 4012def STrih_offset_ext_V4 : STInst<(outs), 4013 (ins IntRegs:$src1, u6_1Imm:$src2, globaladdress:$src3), 4014 "memh($src1+#$src2) = ##$src3", 4015 [(truncstorei16 (HexagonCONST32 tglobaladdr:$src3), 4016 (add IntRegs:$src1, u6_1ImmPred:$src2))]>, 4017 Requires<[HasV4T]>; 4018// Map from store(globaladdress + x) -> memd(#foo + x) 4019let AddedComplexity = 100 in 4020def : Pat<(store (i64 DoubleRegs:$src1), 4021 FoldGlobalAddrGP:$addr), 4022 (S2_storerdabs FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 4023 Requires<[HasV4T]>; 4024 4025def : Pat<(atomic_store_64 FoldGlobalAddrGP:$addr, 4026 (i64 DoubleRegs:$src1)), 4027 (S2_storerdabs FoldGlobalAddrGP:$addr, (i64 DoubleRegs:$src1))>, 4028 Requires<[HasV4T]>; 4029 4030// Map from store(globaladdress + x) -> memb(#foo + x) 4031let AddedComplexity = 100 in 4032def : Pat<(truncstorei8 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 4033 (S2_storerbabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4034 Requires<[HasV4T]>; 4035 4036def : Pat<(atomic_store_8 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 4037 (S2_storerbabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4038 Requires<[HasV4T]>; 4039 4040// Map from store(globaladdress + x) -> memh(#foo + x) 4041let AddedComplexity = 100 in 4042def : Pat<(truncstorei16 (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 4043 (S2_storerhabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4044 Requires<[HasV4T]>; 4045 4046def : Pat<(atomic_store_16 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 4047 (S2_storerhabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4048 Requires<[HasV4T]>; 4049 4050// Map from store(globaladdress + x) -> memw(#foo + x) 4051let AddedComplexity = 100 in 4052def : Pat<(store (i32 IntRegs:$src1), FoldGlobalAddrGP:$addr), 4053 (S2_storeriabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4054 Requires<[HasV4T]>; 4055 4056def : Pat<(atomic_store_32 FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1)), 4057 (S2_storeriabs FoldGlobalAddrGP:$addr, (i32 IntRegs:$src1))>, 4058 Requires<[HasV4T]>; 4059 4060// Map from load(globaladdress + x) -> memd(#foo + x) 4061let AddedComplexity = 100 in 4062def : Pat<(i64 (load FoldGlobalAddrGP:$addr)), 4063 (i64 (L4_loadrd_abs FoldGlobalAddrGP:$addr))>, 4064 Requires<[HasV4T]>; 4065 4066def : Pat<(atomic_load_64 FoldGlobalAddrGP:$addr), 4067 (i64 (L4_loadrd_abs FoldGlobalAddrGP:$addr))>, 4068 Requires<[HasV4T]>; 4069 4070// Map from load(globaladdress + x) -> memb(#foo + x) 4071let AddedComplexity = 100 in 4072def : Pat<(i32 (extloadi8 FoldGlobalAddrGP:$addr)), 4073 (i32 (L4_loadrb_abs FoldGlobalAddrGP:$addr))>, 4074 Requires<[HasV4T]>; 4075 4076// Map from load(globaladdress + x) -> memb(#foo + x) 4077let AddedComplexity = 100 in 4078def : Pat<(i32 (sextloadi8 FoldGlobalAddrGP:$addr)), 4079 (i32 (L4_loadrb_abs FoldGlobalAddrGP:$addr))>, 4080 Requires<[HasV4T]>; 4081 4082//let AddedComplexity = 100 in 4083let AddedComplexity = 100 in 4084def : Pat<(i32 (extloadi16 FoldGlobalAddrGP:$addr)), 4085 (i32 (L4_loadrh_abs FoldGlobalAddrGP:$addr))>, 4086 Requires<[HasV4T]>; 4087 4088// Map from load(globaladdress + x) -> memh(#foo + x) 4089let AddedComplexity = 100 in 4090def : Pat<(i32 (sextloadi16 FoldGlobalAddrGP:$addr)), 4091 (i32 (L4_loadrh_abs FoldGlobalAddrGP:$addr))>, 4092 Requires<[HasV4T]>; 4093 4094// Map from load(globaladdress + x) -> memuh(#foo + x) 4095let AddedComplexity = 100 in 4096def : Pat<(i32 (zextloadi16 FoldGlobalAddrGP:$addr)), 4097 (i32 (L4_loadruh_abs FoldGlobalAddrGP:$addr))>, 4098 Requires<[HasV4T]>; 4099 4100def : Pat<(atomic_load_16 FoldGlobalAddrGP:$addr), 4101 (i32 (L4_loadruh_abs FoldGlobalAddrGP:$addr))>, 4102 Requires<[HasV4T]>; 4103 4104// Map from load(globaladdress + x) -> memub(#foo + x) 4105let AddedComplexity = 100 in 4106def : Pat<(i32 (zextloadi8 FoldGlobalAddrGP:$addr)), 4107 (i32 (L4_loadrub_abs FoldGlobalAddrGP:$addr))>, 4108 Requires<[HasV4T]>; 4109 4110def : Pat<(atomic_load_8 FoldGlobalAddrGP:$addr), 4111 (i32 (L4_loadrub_abs FoldGlobalAddrGP:$addr))>, 4112 Requires<[HasV4T]>; 4113 4114// Map from load(globaladdress + x) -> memw(#foo + x) 4115let AddedComplexity = 100 in 4116def : Pat<(i32 (load FoldGlobalAddrGP:$addr)), 4117 (i32 (L4_loadri_abs FoldGlobalAddrGP:$addr))>, 4118 Requires<[HasV4T]>; 4119 4120def : Pat<(atomic_load_32 FoldGlobalAddrGP:$addr), 4121 (i32 (L4_loadri_abs FoldGlobalAddrGP:$addr))>, 4122 Requires<[HasV4T]>; 4123 4124//===----------------------------------------------------------------------===// 4125// :raw for of boundscheck:hi:lo insns 4126//===----------------------------------------------------------------------===// 4127 4128// A4_boundscheck_lo: Detect if a register is within bounds. 4129let hasSideEffects = 0, isCodeGenOnly = 0 in 4130def A4_boundscheck_lo: ALU64Inst < 4131 (outs PredRegs:$Pd), 4132 (ins DoubleRegs:$Rss, DoubleRegs:$Rtt), 4133 "$Pd = boundscheck($Rss, $Rtt):raw:lo"> { 4134 bits<2> Pd; 4135 bits<5> Rss; 4136 bits<5> Rtt; 4137 4138 let IClass = 0b1101; 4139 4140 let Inst{27-23} = 0b00100; 4141 let Inst{13} = 0b1; 4142 let Inst{7-5} = 0b100; 4143 let Inst{1-0} = Pd; 4144 let Inst{20-16} = Rss; 4145 let Inst{12-8} = Rtt; 4146 } 4147 4148// A4_boundscheck_hi: Detect if a register is within bounds. 4149let hasSideEffects = 0, isCodeGenOnly = 0 in 4150def A4_boundscheck_hi: ALU64Inst < 4151 (outs PredRegs:$Pd), 4152 (ins DoubleRegs:$Rss, DoubleRegs:$Rtt), 4153 "$Pd = boundscheck($Rss, $Rtt):raw:hi"> { 4154 bits<2> Pd; 4155 bits<5> Rss; 4156 bits<5> Rtt; 4157 4158 let IClass = 0b1101; 4159 4160 let Inst{27-23} = 0b00100; 4161 let Inst{13} = 0b1; 4162 let Inst{7-5} = 0b101; 4163 let Inst{1-0} = Pd; 4164 let Inst{20-16} = Rss; 4165 let Inst{12-8} = Rtt; 4166 } 4167 4168let hasSideEffects = 0 in 4169def A4_boundscheck : MInst < 4170 (outs PredRegs:$Pd), (ins IntRegs:$Rs, DoubleRegs:$Rtt), 4171 "$Pd=boundscheck($Rs,$Rtt)">; 4172 4173// A4_tlbmatch: Detect if a VA/ASID matches a TLB entry. 4174let isPredicateLate = 1, hasSideEffects = 0, isCodeGenOnly = 0 in 4175def A4_tlbmatch : ALU64Inst<(outs PredRegs:$Pd), 4176 (ins DoubleRegs:$Rs, IntRegs:$Rt), 4177 "$Pd = tlbmatch($Rs, $Rt)", 4178 [], "", ALU64_tc_2early_SLOT23> { 4179 bits<2> Pd; 4180 bits<5> Rs; 4181 bits<5> Rt; 4182 4183 let IClass = 0b1101; 4184 let Inst{27-23} = 0b00100; 4185 let Inst{20-16} = Rs; 4186 let Inst{13} = 0b1; 4187 let Inst{12-8} = Rt; 4188 let Inst{7-5} = 0b011; 4189 let Inst{1-0} = Pd; 4190 } 4191 4192// We need custom lowering of ISD::PREFETCH into HexagonISD::DCFETCH 4193// because the SDNode ISD::PREFETCH has properties MayLoad and MayStore. 4194// We don't really want either one here. 4195def SDTHexagonDCFETCH : SDTypeProfile<0, 2, [SDTCisPtrTy<0>,SDTCisInt<1>]>; 4196def HexagonDCFETCH : SDNode<"HexagonISD::DCFETCH", SDTHexagonDCFETCH, 4197 [SDNPHasChain]>; 4198 4199// Use LD0Inst for dcfetch, but set "mayLoad" to 0 because this doesn't 4200// really do a load. 4201let hasSideEffects = 1, mayLoad = 0, isCodeGenOnly = 0 in 4202def Y2_dcfetchbo : LD0Inst<(outs), (ins IntRegs:$Rs, u11_3Imm:$u11_3), 4203 "dcfetch($Rs + #$u11_3)", 4204 [(HexagonDCFETCH IntRegs:$Rs, u11_3ImmPred:$u11_3)], 4205 "", LD_tc_ld_SLOT0> { 4206 bits<5> Rs; 4207 bits<14> u11_3; 4208 4209 let IClass = 0b1001; 4210 let Inst{27-21} = 0b0100000; 4211 let Inst{20-16} = Rs; 4212 let Inst{13} = 0b0; 4213 let Inst{10-0} = u11_3{13-3}; 4214} 4215 4216//===----------------------------------------------------------------------===// 4217// Compound instructions 4218//===----------------------------------------------------------------------===// 4219 4220let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, 4221 isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, 4222 opExtentBits = 11, opExtentAlign = 2, opExtendable = 1, 4223 isTerminator = 1, validSubTargets = HasV4SubT in 4224class CJInst_tstbit_R0<string px, bit np, string tnt> 4225 : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2), 4226 ""#px#" = tstbit($Rs, #0); if (" 4227 #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", 4228 [], "", COMPOUND, TypeCOMPOUND> { 4229 bits<4> Rs; 4230 bits<11> r9_2; 4231 4232 // np: !p[01] 4233 let isPredicatedFalse = np; 4234 // tnt: Taken/Not Taken 4235 let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); 4236 let isTaken = !if (!eq(tnt, "t"), 1, 0); 4237 4238 let IClass = 0b0001; 4239 let Inst{27-26} = 0b00; 4240 let Inst{25} = !if (!eq(px, "!p1"), 1, 4241 !if (!eq(px, "p1"), 1, 0)); 4242 let Inst{24-23} = 0b11; 4243 let Inst{22} = np; 4244 let Inst{21-20} = r9_2{10-9}; 4245 let Inst{19-16} = Rs; 4246 let Inst{13} = !if (!eq(tnt, "t"), 1, 0); 4247 let Inst{9-8} = 0b11; 4248 let Inst{7-1} = r9_2{8-2}; 4249} 4250 4251let Defs = [PC, P0], Uses = [P0], isCodeGenOnly = 0 in { 4252 def J4_tstbit0_tp0_jump_nt : CJInst_tstbit_R0<"p0", 0, "nt">; 4253 def J4_tstbit0_tp0_jump_t : CJInst_tstbit_R0<"p0", 0, "t">; 4254 def J4_tstbit0_fp0_jump_nt : CJInst_tstbit_R0<"p0", 1, "nt">; 4255 def J4_tstbit0_fp0_jump_t : CJInst_tstbit_R0<"p0", 1, "t">; 4256} 4257 4258let Defs = [PC, P1], Uses = [P1], isCodeGenOnly = 0 in { 4259 def J4_tstbit0_tp1_jump_nt : CJInst_tstbit_R0<"p1", 0, "nt">; 4260 def J4_tstbit0_tp1_jump_t : CJInst_tstbit_R0<"p1", 0, "t">; 4261 def J4_tstbit0_fp1_jump_nt : CJInst_tstbit_R0<"p1", 1, "nt">; 4262 def J4_tstbit0_fp1_jump_t : CJInst_tstbit_R0<"p1", 1, "t">; 4263} 4264 4265 4266let isBranch = 1, hasSideEffects = 0, 4267 isExtentSigned = 1, isPredicated = 1, isPredicatedNew = 1, 4268 isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, 4269 opExtendable = 2, isTerminator = 1, validSubTargets = HasV4SubT in 4270class CJInst_RR<string px, string op, bit np, string tnt> 4271 : InstHexagon<(outs), (ins IntRegs:$Rs, IntRegs:$Rt, brtarget:$r9_2), 4272 ""#px#" = cmp."#op#"($Rs, $Rt); if (" 4273 #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", 4274 [], "", COMPOUND, TypeCOMPOUND> { 4275 bits<4> Rs; 4276 bits<4> Rt; 4277 bits<11> r9_2; 4278 4279 // np: !p[01] 4280 let isPredicatedFalse = np; 4281 // tnt: Taken/Not Taken 4282 let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); 4283 let isTaken = !if (!eq(tnt, "t"), 1, 0); 4284 4285 let IClass = 0b0001; 4286 let Inst{27-23} = !if (!eq(op, "eq"), 0b01000, 4287 !if (!eq(op, "gt"), 0b01001, 4288 !if (!eq(op, "gtu"), 0b01010, 0))); 4289 let Inst{22} = np; 4290 let Inst{21-20} = r9_2{10-9}; 4291 let Inst{19-16} = Rs; 4292 let Inst{13} = !if (!eq(tnt, "t"), 1, 0); 4293 // px: Predicate reg 0/1 4294 let Inst{12} = !if (!eq(px, "!p1"), 1, 4295 !if (!eq(px, "p1"), 1, 0)); 4296 let Inst{11-8} = Rt; 4297 let Inst{7-1} = r9_2{8-2}; 4298} 4299 4300// P[10] taken/not taken. 4301multiclass T_tnt_CJInst_RR<string op, bit np> { 4302 let Defs = [PC, P0], Uses = [P0] in { 4303 def NAME#p0_jump_nt : CJInst_RR<"p0", op, np, "nt">; 4304 def NAME#p0_jump_t : CJInst_RR<"p0", op, np, "t">; 4305 } 4306 let Defs = [PC, P1], Uses = [P1] in { 4307 def NAME#p1_jump_nt : CJInst_RR<"p1", op, np, "nt">; 4308 def NAME#p1_jump_t : CJInst_RR<"p1", op, np, "t">; 4309 } 4310} 4311// Predicate / !Predicate 4312multiclass T_pnp_CJInst_RR<string op>{ 4313 defm J4_cmp#NAME#_t : T_tnt_CJInst_RR<op, 0>; 4314 defm J4_cmp#NAME#_f : T_tnt_CJInst_RR<op, 1>; 4315} 4316// TypeCJ Instructions compare RR and jump 4317let isCodeGenOnly = 0 in { 4318defm eq : T_pnp_CJInst_RR<"eq">; 4319defm gt : T_pnp_CJInst_RR<"gt">; 4320defm gtu : T_pnp_CJInst_RR<"gtu">; 4321} 4322 4323let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, 4324 isPredicated = 1, isPredicatedNew = 1, isExtendable = 1, opExtentBits = 11, 4325 opExtentAlign = 2, opExtendable = 2, isTerminator = 1, 4326 validSubTargets = HasV4SubT in 4327class CJInst_RU5<string px, string op, bit np, string tnt> 4328 : InstHexagon<(outs), (ins IntRegs:$Rs, u5Imm:$U5, brtarget:$r9_2), 4329 ""#px#" = cmp."#op#"($Rs, #$U5); if (" 4330 #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", 4331 [], "", COMPOUND, TypeCOMPOUND> { 4332 bits<4> Rs; 4333 bits<5> U5; 4334 bits<11> r9_2; 4335 4336 // np: !p[01] 4337 let isPredicatedFalse = np; 4338 // tnt: Taken/Not Taken 4339 let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); 4340 let isTaken = !if (!eq(tnt, "t"), 1, 0); 4341 4342 let IClass = 0b0001; 4343 let Inst{27-26} = 0b00; 4344 // px: Predicate reg 0/1 4345 let Inst{25} = !if (!eq(px, "!p1"), 1, 4346 !if (!eq(px, "p1"), 1, 0)); 4347 let Inst{24-23} = !if (!eq(op, "eq"), 0b00, 4348 !if (!eq(op, "gt"), 0b01, 4349 !if (!eq(op, "gtu"), 0b10, 0))); 4350 let Inst{22} = np; 4351 let Inst{21-20} = r9_2{10-9}; 4352 let Inst{19-16} = Rs; 4353 let Inst{13} = !if (!eq(tnt, "t"), 1, 0); 4354 let Inst{12-8} = U5; 4355 let Inst{7-1} = r9_2{8-2}; 4356} 4357// P[10] taken/not taken. 4358multiclass T_tnt_CJInst_RU5<string op, bit np> { 4359 let Defs = [PC, P0], Uses = [P0] in { 4360 def NAME#p0_jump_nt : CJInst_RU5<"p0", op, np, "nt">; 4361 def NAME#p0_jump_t : CJInst_RU5<"p0", op, np, "t">; 4362 } 4363 let Defs = [PC, P1], Uses = [P1] in { 4364 def NAME#p1_jump_nt : CJInst_RU5<"p1", op, np, "nt">; 4365 def NAME#p1_jump_t : CJInst_RU5<"p1", op, np, "t">; 4366 } 4367} 4368// Predicate / !Predicate 4369multiclass T_pnp_CJInst_RU5<string op>{ 4370 defm J4_cmp#NAME#i_t : T_tnt_CJInst_RU5<op, 0>; 4371 defm J4_cmp#NAME#i_f : T_tnt_CJInst_RU5<op, 1>; 4372} 4373// TypeCJ Instructions compare RI and jump 4374let isCodeGenOnly = 0 in { 4375defm eq : T_pnp_CJInst_RU5<"eq">; 4376defm gt : T_pnp_CJInst_RU5<"gt">; 4377defm gtu : T_pnp_CJInst_RU5<"gtu">; 4378} 4379 4380let isBranch = 1, hasSideEffects = 0, isExtentSigned = 1, 4381 isPredicated = 1, isPredicatedFalse = 1, isPredicatedNew = 1, 4382 isExtendable = 1, opExtentBits = 11, opExtentAlign = 2, opExtendable = 1, 4383 isTerminator = 1, validSubTargets = HasV4SubT in 4384class CJInst_Rn1<string px, string op, bit np, string tnt> 4385 : InstHexagon<(outs), (ins IntRegs:$Rs, brtarget:$r9_2), 4386 ""#px#" = cmp."#op#"($Rs,#-1); if (" 4387 #!if(np, "!","")#""#px#".new) jump:"#tnt#" $r9_2", 4388 [], "", COMPOUND, TypeCOMPOUND> { 4389 bits<4> Rs; 4390 bits<11> r9_2; 4391 4392 // np: !p[01] 4393 let isPredicatedFalse = np; 4394 // tnt: Taken/Not Taken 4395 let isBrTaken = !if (!eq(tnt, "t"), "true", "false"); 4396 let isTaken = !if (!eq(tnt, "t"), 1, 0); 4397 4398 let IClass = 0b0001; 4399 let Inst{27-26} = 0b00; 4400 let Inst{25} = !if (!eq(px, "!p1"), 1, 4401 !if (!eq(px, "p1"), 1, 0)); 4402 4403 let Inst{24-23} = 0b11; 4404 let Inst{22} = np; 4405 let Inst{21-20} = r9_2{10-9}; 4406 let Inst{19-16} = Rs; 4407 let Inst{13} = !if (!eq(tnt, "t"), 1, 0); 4408 let Inst{9-8} = !if (!eq(op, "eq"), 0b00, 4409 !if (!eq(op, "gt"), 0b01, 0)); 4410 let Inst{7-1} = r9_2{8-2}; 4411} 4412 4413// P[10] taken/not taken. 4414multiclass T_tnt_CJInst_Rn1<string op, bit np> { 4415 let Defs = [PC, P0], Uses = [P0] in { 4416 def NAME#p0_jump_nt : CJInst_Rn1<"p0", op, np, "nt">; 4417 def NAME#p0_jump_t : CJInst_Rn1<"p0", op, np, "t">; 4418 } 4419 let Defs = [PC, P1], Uses = [P1] in { 4420 def NAME#p1_jump_nt : CJInst_Rn1<"p1", op, np, "nt">; 4421 def NAME#p1_jump_t : CJInst_Rn1<"p1", op, np, "t">; 4422 } 4423} 4424// Predicate / !Predicate 4425multiclass T_pnp_CJInst_Rn1<string op>{ 4426 defm J4_cmp#NAME#n1_t : T_tnt_CJInst_Rn1<op, 0>; 4427 defm J4_cmp#NAME#n1_f : T_tnt_CJInst_Rn1<op, 1>; 4428} 4429// TypeCJ Instructions compare -1 and jump 4430let isCodeGenOnly = 0 in { 4431defm eq : T_pnp_CJInst_Rn1<"eq">; 4432defm gt : T_pnp_CJInst_Rn1<"gt">; 4433} 4434 4435// J4_jumpseti: Direct unconditional jump and set register to immediate. 4436let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1, 4437 isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11, 4438 opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT, 4439 isCodeGenOnly = 0 in 4440def J4_jumpseti: CJInst < 4441 (outs IntRegs:$Rd), 4442 (ins u6Imm:$U6, brtarget:$r9_2), 4443 "$Rd = #$U6 ; jump $r9_2"> { 4444 bits<4> Rd; 4445 bits<6> U6; 4446 bits<11> r9_2; 4447 4448 let IClass = 0b0001; 4449 let Inst{27-24} = 0b0110; 4450 let Inst{21-20} = r9_2{10-9}; 4451 let Inst{19-16} = Rd; 4452 let Inst{13-8} = U6; 4453 let Inst{7-1} = r9_2{8-2}; 4454 } 4455 4456// J4_jumpsetr: Direct unconditional jump and transfer register. 4457let Defs = [PC], isBranch = 1, hasSideEffects = 0, hasNewValue = 1, 4458 isExtentSigned = 1, opNewValue = 0, isExtendable = 1, opExtentBits = 11, 4459 opExtentAlign = 2, opExtendable = 2, validSubTargets = HasV4SubT, 4460 isCodeGenOnly = 0 in 4461def J4_jumpsetr: CJInst < 4462 (outs IntRegs:$Rd), 4463 (ins IntRegs:$Rs, brtarget:$r9_2), 4464 "$Rd = $Rs ; jump $r9_2"> { 4465 bits<4> Rd; 4466 bits<4> Rs; 4467 bits<11> r9_2; 4468 4469 let IClass = 0b0001; 4470 let Inst{27-24} = 0b0111; 4471 let Inst{21-20} = r9_2{10-9}; 4472 let Inst{11-8} = Rd; 4473 let Inst{19-16} = Rs; 4474 let Inst{7-1} = r9_2{8-2}; 4475 } 4476