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