1//===-- RISCVInstrInfoXTHead.td ----------------------------*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the vendor extensions defined by T-Head of Alibaba. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// T-HEAD specific DAG Nodes. 15//===----------------------------------------------------------------------===// 16 17def SDT_LoadPair : SDTypeProfile<2, 2, 18 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 3>, SDTCisPtrTy<2>, SDTCisVT<3, XLenVT>]>; 19def SDT_StorePair : SDTypeProfile<0, 4, 20 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 3>, SDTCisPtrTy<2>, SDTCisVT<3, XLenVT>]>; 21 22def th_lwud : SDNode<"RISCVISD::TH_LWUD", SDT_LoadPair, 23 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 24def th_lwd : SDNode<"RISCVISD::TH_LWD", SDT_LoadPair, 25 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 26def th_ldd : SDNode<"RISCVISD::TH_LDD", SDT_LoadPair, 27 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 28def th_swd : SDNode<"RISCVISD::TH_SWD", SDT_StorePair, 29 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 30def th_sdd : SDNode<"RISCVISD::TH_SDD", SDT_StorePair, 31 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 32 33//===----------------------------------------------------------------------===// 34// Instruction class templates 35//===----------------------------------------------------------------------===// 36class THInstVdotVV<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins, 37 string opcodestr, string argstr> 38 : RVInstVV<funct6, opv, outs, ins, opcodestr, argstr> { 39 let Inst{26} = 0; 40 let Inst{6-0} = OPC_CUSTOM_0.Value; 41 let DecoderNamespace = "THeadV"; 42} 43 44class THInstVdotVX<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins, 45 string opcodestr, string argstr> 46 : RVInstVX<funct6, opv, outs, ins, opcodestr, argstr> { 47 let Inst{26} = 1; 48 let Inst{6-0} = OPC_CUSTOM_0.Value; 49 let DecoderNamespace = "THeadV"; 50} 51 52let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 53// op vd, vs1, vs2, vm (reverse the order of vs1 and vs2) 54class THVdotALUrVV<bits<6> funct6, RISCVVFormat opv, string opcodestr> 55 : THInstVdotVV<funct6, opv, (outs VR:$vd), 56 (ins VR:$vs1, VR:$vs2, VMaskOp:$vm), 57 opcodestr, "$vd, $vs1, $vs2$vm">; 58 59// op vd, rs1, vs2, vm (reverse the order of rs1 and vs2) 60class THVdotALUrVX<bits<6> funct6, RISCVVFormat opv, string opcodestr> 61 : THInstVdotVX<funct6, opv, (outs VR:$vd), 62 (ins GPR:$rs1, VR:$vs2, VMaskOp:$vm), 63 opcodestr, "$vd, $rs1, $vs2$vm">; 64} // hasSideEffects = 0, mayLoad = 0, mayStore = 0 65 66let Predicates = [HasVendorXTHeadBa], DecoderNamespace = "THeadBa", 67 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 68class THShiftALU_rri<bits<3> funct3, string opcodestr> 69 : RVInstR<0, funct3, OPC_CUSTOM_0, (outs GPR:$rd), 70 (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2), 71 opcodestr, "$rd, $rs1, $rs2, $uimm2"> { 72 bits<2> uimm2; 73 let Inst{31-27} = 0; 74 let Inst{26-25} = uimm2; 75} 76 77let Predicates = [HasVendorXTHeadBb], DecoderNamespace = "THeadBb", 78 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 79class THShift_ri<bits<5> funct5, bits<3> funct3, string opcodestr> 80 : RVInstIShift<funct5, funct3, OPC_CUSTOM_0, (outs GPR:$rd), 81 (ins GPR:$rs1, uimmlog2xlen:$shamt), 82 opcodestr, "$rd, $rs1, $shamt">; 83 84class THBitfieldExtract_rii<bits<3> funct3, string opcodestr> 85 : RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd), 86 (ins GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb), 87 opcodestr, "$rd, $rs1, $msb, $lsb"> { 88 bits<6> msb; 89 bits<6> lsb; 90 let Inst{31-26} = msb; 91 let Inst{25-20} = lsb; 92} 93 94class THRev_r<bits<5> funct5, bits<2> funct2, string opcodestr> 95 : RVInstR4<funct2, 0b001, OPC_CUSTOM_0, (outs GPR:$rd), (ins GPR:$rs1), 96 opcodestr, "$rd, $rs1"> { 97 let rs3 = funct5; 98 let rs2 = 0; 99} 100} 101 102let Predicates = [HasVendorXTHeadBb, IsRV64], DecoderNamespace = "THeadBb", 103 hasSideEffects = 0, mayLoad = 0, mayStore = 0 in 104class THShiftW_ri<bits<7> funct7, bits<3> funct3, string opcodestr> 105 : RVInstIShiftW<funct7, funct3, OPC_CUSTOM_0, (outs GPR:$rd), 106 (ins GPR:$rs1, uimm5:$shamt), 107 opcodestr, "$rd, $rs1, $shamt">; 108 109let Predicates = [HasVendorXTHeadCondMov], DecoderNamespace = "THeadCondMov", 110 hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in 111class THCondMov_rr<bits<7> funct7, string opcodestr> 112 : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb), 113 (ins GPR:$rd, GPR:$rs1, GPR:$rs2), 114 opcodestr, "$rd, $rs1, $rs2"> { 115 let Constraints = "$rd_wb = $rd"; 116} 117 118let Predicates = [HasVendorXTHeadMac], DecoderNamespace = "THeadMac", 119 hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in 120class THMulAccumulate_rr<bits<7> funct7, string opcodestr> 121 : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb), 122 (ins GPR:$rd, GPR:$rs1, GPR:$rs2), 123 opcodestr, "$rd, $rs1, $rs2"> { 124 let Constraints = "$rd_wb = $rd"; 125} 126 127let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "THeadMemPair", 128 hasSideEffects = 0, mayLoad = 1, mayStore = 0 in 129class THLoadPair<bits<5> funct5, string opcodestr> 130 : RVInstR<!shl(funct5, 2), 0b100, OPC_CUSTOM_0, 131 (outs GPR:$rd, GPR:$rs2), 132 (ins GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4), 133 opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> { 134 bits<2> uimm2; 135 let Inst{26-25} = uimm2; 136 let DecoderMethod = "decodeXTHeadMemPair"; 137 let Constraints = "@earlyclobber $rd,@earlyclobber $rs2"; 138} 139 140let Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "THeadMemPair", 141 hasSideEffects = 0, mayLoad = 0, mayStore = 1 in 142class THStorePair<bits<5> funct5, string opcodestr> 143 : RVInstR<!shl(funct5, 2), 0b101, OPC_CUSTOM_0, 144 (outs), 145 (ins GPR:$rd, GPR:$rs2, GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4), 146 opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> { 147 bits<2> uimm2; 148 let Inst{26-25} = uimm2; 149 let DecoderMethod = "decodeXTHeadMemPair"; 150} 151 152let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 153class THCacheInst_r<bits<5> funct5, string opcodestr> 154 : RVInstR<0b0000001, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1), 155 opcodestr, "$rs1"> { 156 let rd = 0; 157 let rs2 = funct5; 158} 159 160let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 161class THCacheInst_rr<bits<7> funct7, string opcodestr> 162 : RVInstR<funct7, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1, GPR:$rs2), 163 opcodestr, "$rs1, $rs2"> { 164 let rd = 0; 165} 166 167let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in 168class THCacheInst_void<bits<5> funct5, string opcodestr> 169 : RVInstR<0b0000000, 0, OPC_CUSTOM_0, (outs), (ins), opcodestr, ""> { 170 let rd = 0; 171 let rs1 = 0; 172 let rs2 = funct5; 173} 174 175let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { 176class THLoadIndexed<RegisterClass Ty, bits<5> funct5, string opcodestr> 177 : RVInstR<!shl(funct5, 2), !if(!eq(Ty, GPR), 0b100, 0b110), OPC_CUSTOM_0, 178 (outs Ty:$rd), (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2), 179 opcodestr, "$rd, $rs1, $rs2, $uimm2"> { 180 bits<2> uimm2; 181 let Inst{26-25} = uimm2; 182} 183 184class THLoadUpdate<bits<5> funct5, string opcodestr> 185 : RVInstI<0b100, OPC_CUSTOM_0, (outs GPR:$rd, GPR:$rs1_wb), 186 (ins GPR:$rs1, simm5:$simm5, uimm2:$uimm2), 187 opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> { 188 bits<5> simm5; 189 bits<2> uimm2; 190 let imm12{11-7} = funct5; 191 let imm12{6-5} = uimm2; 192 let imm12{4-0} = simm5; 193 let Constraints = "@earlyclobber $rd, $rs1_wb = $rs1"; 194} 195} 196 197let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { 198class THStoreIndexed<RegisterClass StTy, bits<5> funct5, string opcodestr> 199 : RVInstR<!shl(funct5, 2), !if(!eq(StTy, GPR), 0b101, 0b111), OPC_CUSTOM_0, 200 (outs), (ins StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2), 201 opcodestr, "$rd, $rs1, $rs2, $uimm2"> { 202 bits<2> uimm2; 203 let Inst{26-25} = uimm2; 204} 205 206class THStoreUpdate<bits<5> funct5, string opcodestr> 207 : RVInstI<0b101, OPC_CUSTOM_0, (outs GPR:$rs1_up), 208 (ins GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2), 209 opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> { 210 bits<5> simm5; 211 bits<2> uimm2; 212 let imm12{11-7} = funct5; 213 let imm12{6-5} = uimm2; 214 let imm12{4-0} = simm5; 215 let Constraints = "$rs1_up = $rs1"; 216} 217} 218 219//===----------------------------------------------------------------------===// 220// Combination of instruction classes. 221// Use these multiclasses to define instructions more easily. 222//===----------------------------------------------------------------------===// 223multiclass THVdotVMAQA_VX<string opcodestr, bits<6> funct6> { 224 def _VX : THVdotALUrVX<funct6, OPMVX, opcodestr # ".vx">; 225} 226 227multiclass THVdotVMAQA<string opcodestr, bits<6> funct6> { 228 def _VV : THVdotALUrVV<funct6, OPMVX, opcodestr # ".vv">; 229 defm "" : THVdotVMAQA_VX<opcodestr, funct6>; 230} 231 232//===----------------------------------------------------------------------===// 233// Instructions 234//===----------------------------------------------------------------------===// 235let Predicates = [HasVendorXTHeadBa] in { 236def TH_ADDSL : THShiftALU_rri<0b001, "th.addsl">, 237 Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>; 238} // Predicates = [HasVendorXTHeadBa] 239 240let Predicates = [HasVendorXTHeadBb] in { 241def TH_SRRI : THShift_ri<0b00010, 0b001, "th.srri">; 242def TH_EXT : THBitfieldExtract_rii<0b010, "th.ext">; 243def TH_EXTU : THBitfieldExtract_rii<0b011, "th.extu">; 244def TH_FF0 : THRev_r<0b10000, 0b10, "th.ff0">; 245def TH_FF1 : THRev_r<0b10000, 0b11, "th.ff1">; 246def TH_REV : THRev_r<0b10000, 0b01, "th.rev">; 247def TH_TSTNBZ : THRev_r<0b10000, 0b00, "th.tstnbz">; 248} // Predicates = [HasVendorXTHeadBb] 249 250let Predicates = [HasVendorXTHeadBb, IsRV64], IsSignExtendingOpW = 1 in { 251def TH_SRRIW : THShiftW_ri<0b0001010, 0b001, "th.srriw">; 252def TH_REVW : THRev_r<0b10010, 0b00, "th.revw">; 253} // Predicates = [HasVendorXTHeadBb, IsRV64] 254 255let Predicates = [HasVendorXTHeadBs], DecoderNamespace = "THeadBs" in { 256let IsSignExtendingOpW = 1 in 257def TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">, 258 Sched<[WriteSingleBitImm, ReadSingleBitImm]>; 259} // Predicates = [HasVendorXTHeadBs] 260 261let Predicates = [HasVendorXTHeadCondMov] in { 262def TH_MVEQZ : THCondMov_rr<0b0100000, "th.mveqz">; 263def TH_MVNEZ : THCondMov_rr<0b0100001, "th.mvnez">; 264} // Predicates = [HasVendorXTHeadCondMov] 265 266let Predicates = [HasVendorXTHeadMac] in { 267def TH_MULA : THMulAccumulate_rr<0b0010000, "th.mula">; 268def TH_MULS : THMulAccumulate_rr<0b0010001, "th.muls">; 269} // Predicates = [HasVendorXTHeadMac] 270 271let Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1 in { 272def TH_MULAH : THMulAccumulate_rr<0b0010100, "th.mulah">; 273def TH_MULSH : THMulAccumulate_rr<0b0010101, "th.mulsh">; 274} // Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1 275 276let Predicates = [HasVendorXTHeadMac, IsRV64], IsSignExtendingOpW = 1 in { 277def TH_MULAW : THMulAccumulate_rr<0b0010010, "th.mulaw">; 278def TH_MULSW : THMulAccumulate_rr<0b0010011, "th.mulsw">; 279} // Predicates = [HasVendorXTHeadMac, IsRV64] 280 281let Predicates = [HasVendorXTHeadMemPair] in { 282def TH_LWUD : THLoadPair<0b11110, "th.lwud">, 283 Sched<[WriteLDW, WriteLDW, ReadMemBase]>; 284def TH_SWD : THStorePair<0b11100, "th.swd">, 285 Sched<[WriteSTW, WriteSTW, ReadStoreData, ReadMemBase]>; 286let IsSignExtendingOpW = 1 in 287def TH_LWD : THLoadPair<0b11100, "th.lwd">, 288 Sched<[WriteLDW, WriteLDW, ReadMemBase]>; 289} 290 291let Predicates = [HasVendorXTHeadMemPair, IsRV64] in { 292def TH_LDD : THLoadPair<0b11111, "th.ldd">, 293 Sched<[WriteLDD, WriteLDD, ReadMemBase]>; 294def TH_SDD : THStorePair<0b11111, "th.sdd">, 295 Sched<[WriteSTD, WriteSTD, ReadStoreData, ReadMemBase]>; 296} 297 298let Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "THeadMemIdx" in { 299// T-Head Load/Store + Update instructions. 300def TH_LBIA : THLoadUpdate<0b00011, "th.lbia">, 301 Sched<[WriteLDB, ReadMemBase]>; 302def TH_LBIB : THLoadUpdate<0b00001, "th.lbib">, 303 Sched<[WriteLDB, ReadMemBase]>; 304def TH_LBUIA : THLoadUpdate<0b10011, "th.lbuia">, 305 Sched<[WriteLDB, ReadMemBase]>; 306def TH_LBUIB : THLoadUpdate<0b10001, "th.lbuib">, 307 Sched<[WriteLDB, ReadMemBase]>; 308 309def TH_LHIA : THLoadUpdate<0b00111, "th.lhia">, 310 Sched<[WriteLDH, ReadMemBase]>; 311def TH_LHIB : THLoadUpdate<0b00101, "th.lhib">, 312 Sched<[WriteLDH, ReadMemBase]>; 313def TH_LHUIA : THLoadUpdate<0b10111, "th.lhuia">, 314 Sched<[WriteLDH, ReadMemBase]>; 315def TH_LHUIB : THLoadUpdate<0b10101, "th.lhuib">, 316 Sched<[WriteLDH, ReadMemBase]>; 317 318def TH_LWIA : THLoadUpdate<0b01011, "th.lwia">, 319 Sched<[WriteLDW, ReadMemBase]>; 320def TH_LWIB : THLoadUpdate<0b01001, "th.lwib">, 321 Sched<[WriteLDW, ReadMemBase]>; 322 323def TH_SBIA : THStoreUpdate<0b00011, "th.sbia">, 324 Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 325def TH_SBIB : THStoreUpdate<0b00001, "th.sbib">, 326 Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 327 328def TH_SHIA : THStoreUpdate<0b00111, "th.shia">, 329 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 330def TH_SHIB : THStoreUpdate<0b00101, "th.shib">, 331 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 332 333def TH_SWIA : THStoreUpdate<0b01011, "th.swia">, 334 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 335def TH_SWIB : THStoreUpdate<0b01001, "th.swib">, 336 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 337 338// T-Head Load/Store Indexed instructions. 339def TH_LRB : THLoadIndexed<GPR, 0b00000, "th.lrb">, 340 Sched<[WriteLDB, ReadMemBase]>; 341def TH_LRBU : THLoadIndexed<GPR, 0b10000, "th.lrbu">, 342 Sched<[WriteLDB, ReadMemBase]>; 343def TH_LURB : THLoadIndexed<GPR, 0b00010, "th.lurb">, 344 Sched<[WriteLDB, ReadMemBase]>; 345def TH_LURBU : THLoadIndexed<GPR, 0b10010, "th.lurbu">, 346 Sched<[WriteLDB, ReadMemBase]>; 347 348def TH_LRH : THLoadIndexed<GPR, 0b00100, "th.lrh">, 349 Sched<[WriteLDH, ReadMemBase]>; 350def TH_LRHU : THLoadIndexed<GPR, 0b10100, "th.lrhu">, 351 Sched<[WriteLDH, ReadMemBase]>; 352def TH_LURH : THLoadIndexed<GPR, 0b00110, "th.lurh">, 353 Sched<[WriteLDB, ReadMemBase]>; 354def TH_LURHU : THLoadIndexed<GPR, 0b10110, "th.lurhu">, 355 Sched<[WriteLDB, ReadMemBase]>; 356 357def TH_LRW : THLoadIndexed<GPR, 0b01000, "th.lrw">, 358 Sched<[WriteLDW, ReadMemBase]>; 359def TH_LURW : THLoadIndexed<GPR, 0b01010, "th.lurw">, 360 Sched<[WriteLDB, ReadMemBase]>; 361 362def TH_SRB : THStoreIndexed<GPR, 0b00000, "th.srb">, 363 Sched<[WriteSTB, ReadStoreData, ReadMemBase]>; 364def TH_SURB : THStoreIndexed<GPR, 0b00010, "th.surb">, 365 Sched<[WriteLDB, ReadMemBase]>; 366 367def TH_SRH : THStoreIndexed<GPR, 0b00100, "th.srh">, 368 Sched<[WriteSTH, ReadStoreData, ReadMemBase]>; 369def TH_SURH : THStoreIndexed<GPR, 0b00110, "th.surh">, 370 Sched<[WriteLDB, ReadMemBase]>; 371 372def TH_SRW : THStoreIndexed<GPR, 0b01000, "th.srw">, 373 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 374def TH_SURW : THStoreIndexed<GPR, 0b01010, "th.surw">, 375 Sched<[WriteLDB, ReadMemBase]>; 376} 377 378let Predicates = [HasVendorXTHeadMemIdx, IsRV64], DecoderNamespace = "THeadMemIdx" in { 379// T-Head Load/Store + Update instructions. 380def TH_LWUIA : THLoadUpdate<0b11011, "th.lwuia">, 381 Sched<[WriteLDH, ReadMemBase]>; 382def TH_LWUIB : THLoadUpdate<0b11001, "th.lwuib">, 383 Sched<[WriteLDH, ReadMemBase]>; 384 385def TH_LDIA : THLoadUpdate<0b01111, "th.ldia">, 386 Sched<[WriteLDW, ReadMemBase]>; 387def TH_LDIB : THLoadUpdate<0b01101, "th.ldib">, 388 Sched<[WriteLDW, ReadMemBase]>; 389 390def TH_SDIA : THStoreUpdate<0b01111, "th.sdia">, 391 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 392def TH_SDIB : THStoreUpdate<0b01101, "th.sdib">, 393 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 394 395// T-Head Load/Store Indexed instructions. 396def TH_LRWU : THLoadIndexed<GPR, 0b11000, "th.lrwu">, 397 Sched<[WriteLDW, ReadMemBase]>; 398def TH_LURWU : THLoadIndexed<GPR, 0b11010, "th.lurwu">, 399 Sched<[WriteLDB, ReadMemBase]>; 400 401def TH_LRD : THLoadIndexed<GPR, 0b01100, "th.lrd">, 402 Sched<[WriteLDW, ReadMemBase]>; 403def TH_LURD : THLoadIndexed<GPR, 0b01110, "th.lurd">, 404 Sched<[WriteLDB, ReadMemBase]>; 405 406def TH_SRD : THStoreIndexed<GPR, 0b01100, "th.srd">, 407 Sched<[WriteSTW, ReadStoreData, ReadMemBase]>; 408def TH_SURD : THStoreIndexed<GPR, 0b01110, "th.surd">, 409 Sched<[WriteLDB, ReadMemBase]>; 410} 411 412// T-Head Load/Store Indexed instructions for floating point registers. 413 414let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF], 415 DecoderNamespace = "THeadFMemIdx" in { 416def TH_FLRW : THLoadIndexed<FPR32, 0b01000, "th.flrw">, 417 Sched<[WriteFLD32, ReadFMemBase]>; 418def TH_FSRW : THStoreIndexed<FPR32, 0b01000, "th.fsrw">, 419 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>; 420} 421 422let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD], 423 DecoderNamespace = "THeadFMemIdx" in { 424def TH_FLRD : THLoadIndexed<FPR64, 0b01100, "th.flrd">, 425 Sched<[WriteFLD64, ReadFMemBase]>; 426def TH_FSRD : THStoreIndexed<FPR64, 0b01100, "th.fsrd">, 427 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>; 428} 429 430let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64], 431 DecoderNamespace = "THeadFMemIdx" in { 432def TH_FLURW : THLoadIndexed<FPR32, 0b01010, "th.flurw">, 433 Sched<[WriteFLD32, ReadFMemBase]>; 434def TH_FSURW : THStoreIndexed<FPR32, 0b01010, "th.fsurw">, 435 Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>; 436} 437 438let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64], 439 DecoderNamespace = "THeadFMemIdx" in { 440def TH_FLURD : THLoadIndexed<FPR64, 0b01110, "th.flurd">, 441 Sched<[WriteFLD64, ReadFMemBase]>; 442def TH_FSURD : THStoreIndexed<FPR64, 0b01110, "th.fsurd">, 443 Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>; 444} 445 446let Predicates = [HasVendorXTHeadVdot], 447 Constraints = "@earlyclobber $vd", 448 RVVConstraint = WidenV in { 449defm THVdotVMAQA : THVdotVMAQA<"th.vmaqa", 0b100000>; 450defm THVdotVMAQAU : THVdotVMAQA<"th.vmaqau", 0b100010>; 451defm THVdotVMAQASU : THVdotVMAQA<"th.vmaqasu", 0b100100>; 452defm THVdotVMAQAUS : THVdotVMAQA_VX<"th.vmaqaus",0b100110>; 453} 454 455// Associate LMUL with tablegen records of register classes. 456def THVdotV_M1 : LMULInfo<0b000, 8, VR, VR, VR, VR, VR, "M1">; 457def THVdotV_M2 : LMULInfo<0b001, 16, VRM2, VRM2, VR, VR, VR, "M2">; 458def THVdotV_M4 : LMULInfo<0b010, 32, VRM4, VRM4, VRM2, VR, VR, "M4">; 459def THVdotV_M8 : LMULInfo<0b011, 64, VRM8, VRM8, VRM4, VRM2, VR, "M8">; 460 461defvar MxListTHVdot = [V_MF2, THVdotV_M1, THVdotV_M2, THVdotV_M4, THVdotV_M8]; 462 463defset list<VTypeInfoToWide> AllQuadWidenableInt8NoVLMulVectors = { 464 def : VTypeInfoToWide<VI8MF2, VI32MF2>; 465 def : VTypeInfoToWide<VI8M1, VI32M1>; 466 def : VTypeInfoToWide<VI8M2, VI32M2>; 467 def : VTypeInfoToWide<VI8M4, VI32M4>; 468 def : VTypeInfoToWide<VI8M8, VI32M8>; 469} 470 471//===----------------------------------------------------------------------===// 472// Combination of instruction classes. 473// Use these multiclasses to define instructions more easily. 474//===----------------------------------------------------------------------===// 475multiclass VPseudoVMAQA_VV_VX { 476 foreach m = MxListTHVdot in { 477 defm "" : VPseudoTernaryW_VV<m>; 478 defm "" : VPseudoTernaryW_VX<m>; 479 } 480} 481 482multiclass VPseudoVMAQA_VX { 483 foreach m = MxListTHVdot in { 484 defm "" : VPseudoTernaryW_VX<m>; 485 } 486} 487 488multiclass VPatTernaryVMAQA_VV<string intrinsic, string instruction, 489 list<VTypeInfoToWide> vtilist> { 490 foreach vtiToWti = vtilist in { 491 defvar vti = vtiToWti.Vti; 492 defvar wti = vtiToWti.Wti; 493 defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV", 494 wti.Vector, vti.Vector, vti.Vector, 495 vti.Mask, wti.Log2SEW, vti.LMul, 496 wti.RegClass, vti.RegClass, vti.RegClass>; 497 } 498} 499 500multiclass VPatTernaryVMAQA_VX<string intrinsic, string instruction, 501 list<VTypeInfoToWide> vtilist> { 502 foreach vtiToWti = vtilist in { 503 defvar vti = vtiToWti.Vti; 504 defvar wti = vtiToWti.Wti; 505 defm : VPatTernaryWithPolicy<intrinsic, instruction, 506 "V"#vti.ScalarSuffix, 507 wti.Vector, vti.Scalar, vti.Vector, 508 vti.Mask, wti.Log2SEW, vti.LMul, 509 wti.RegClass, vti.ScalarRegClass, vti.RegClass>; 510 } 511} 512 513multiclass VPatTernaryVMAQA_VV_VX<string intrinsic, string instruction, 514 list<VTypeInfoToWide> vtilist> 515 : VPatTernaryVMAQA_VV<intrinsic, instruction, vtilist>, 516 VPatTernaryVMAQA_VX<intrinsic, instruction, vtilist>; 517 518//===----------------------------------------------------------------------===// 519// Pseudo-instructions and codegen patterns 520//===----------------------------------------------------------------------===// 521let Predicates = [HasVendorXTHeadBa] in { 522def : Pat<(add (XLenVT GPR:$rs1), (shl GPR:$rs2, uimm2:$uimm2)), 523 (TH_ADDSL GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>; 524 525// Reuse complex patterns from StdExtZba 526def : Pat<(add sh1add_op:$rs1, non_imm12:$rs2), 527 (TH_ADDSL GPR:$rs2, sh1add_op:$rs1, 1)>; 528def : Pat<(add sh2add_op:$rs1, non_imm12:$rs2), 529 (TH_ADDSL GPR:$rs2, sh2add_op:$rs1, 2)>; 530def : Pat<(add sh3add_op:$rs1, non_imm12:$rs2), 531 (TH_ADDSL GPR:$rs2, sh3add_op:$rs1, 3)>; 532 533def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 6)), GPR:$rs2), 534 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 1)>; 535def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 10)), GPR:$rs2), 536 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 1)>; 537def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 18)), GPR:$rs2), 538 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 1)>; 539def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 12)), GPR:$rs2), 540 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 2)>; 541def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 20)), GPR:$rs2), 542 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 2)>; 543def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 36)), GPR:$rs2), 544 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 2)>; 545def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 24)), GPR:$rs2), 546 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 1), 3)>; 547def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 40)), GPR:$rs2), 548 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 2), 3)>; 549def : Pat<(add (mul_oneuse GPR:$rs1, (XLenVT 72)), GPR:$rs2), 550 (TH_ADDSL GPR:$rs2, (TH_ADDSL GPR:$rs1, GPR:$rs1, 3), 3)>; 551 552def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy4:$i), 553 (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy2XForm CSImm12MulBy4:$i)), 2)>; 554def : Pat<(add (XLenVT GPR:$r), CSImm12MulBy8:$i), 555 (TH_ADDSL GPR:$r, (ADDI (XLenVT X0), (SimmShiftRightBy3XForm CSImm12MulBy8:$i)), 3)>; 556 557def : Pat<(mul (XLenVT GPR:$r), C3LeftShift:$i), 558 (SLLI (TH_ADDSL GPR:$r, GPR:$r, 1), 559 (TrailingZeros C3LeftShift:$i))>; 560def : Pat<(mul (XLenVT GPR:$r), C5LeftShift:$i), 561 (SLLI (TH_ADDSL GPR:$r, GPR:$r, 2), 562 (TrailingZeros C5LeftShift:$i))>; 563def : Pat<(mul (XLenVT GPR:$r), C9LeftShift:$i), 564 (SLLI (TH_ADDSL GPR:$r, GPR:$r, 3), 565 (TrailingZeros C9LeftShift:$i))>; 566 567def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 11)), 568 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 1)>; 569def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 19)), 570 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>; 571def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 13)), 572 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 1), 2)>; 573def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 21)), 574 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>; 575def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 37)), 576 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>; 577def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 25)), 578 (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2), (TH_ADDSL GPR:$r, GPR:$r, 2), 2)>; 579def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 41)), 580 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 2), 3)>; 581def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 73)), 582 (TH_ADDSL GPR:$r, (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>; 583def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 27)), 584 (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 1)>; 585def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 45)), 586 (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 2)>; 587def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 81)), 588 (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 3), (TH_ADDSL GPR:$r, GPR:$r, 3), 3)>; 589 590def : Pat<(mul_const_oneuse GPR:$r, (XLenVT 200)), 591 (SLLI (TH_ADDSL (TH_ADDSL GPR:$r, GPR:$r, 2), 592 (TH_ADDSL GPR:$r, GPR:$r, 2), 2), 3)>; 593} // Predicates = [HasVendorXTHeadBa] 594 595let Predicates = [HasVendorXTHeadBb] in { 596def : PatGprImm<rotr, TH_SRRI, uimmlog2xlen>; 597// There's no encoding for a rotate-left-immediate in X-THead-Bb, as 598// it can be implemented with th.srri by negating the immediate. 599def : Pat<(rotl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt), 600 (TH_SRRI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>; 601def : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (TH_EXT GPR:$rs1, 31, 0)>; 602def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (TH_EXT GPR:$rs1, 15, 0)>; 603def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (TH_EXT GPR:$rs1, 7, 0)>; 604def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (TH_EXT GPR:$rs1, 0, 0)>; 605def : PatGpr<ctlz, TH_FF1>; 606def : Pat<(XLenVT (ctlz (xor (XLenVT GPR:$rs1), -1))), (TH_FF0 GPR:$rs1)>; 607def : PatGpr<bswap, TH_REV>; 608} // Predicates = [HasVendorXTHeadBb] 609 610let Predicates = [HasVendorXTHeadBb, IsRV64] in { 611def : PatGprImm<riscv_rorw, TH_SRRIW, uimm5>; 612def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2), 613 (TH_SRRIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>; 614def : Pat<(sra (bswap i64:$rs1), (i64 32)), 615 (TH_REVW i64:$rs1)>; 616def : Pat<(binop_allwusers<srl> (bswap i64:$rs1), (i64 32)), 617 (TH_REVW i64:$rs1)>; 618def : Pat<(riscv_clzw i64:$rs1), 619 (TH_FF0 (SLLI (XORI i64:$rs1, -1), 32))>; 620} // Predicates = [HasVendorXTHeadBb, IsRV64] 621 622let Predicates = [HasVendorXTHeadBs] in { 623def : Pat<(and (srl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt), 1), 624 (TH_TST GPR:$rs1, uimmlog2xlen:$shamt)>; 625def : Pat<(XLenVT (seteq (and (XLenVT GPR:$rs1), SingleBitSetMask:$mask), 0)), 626 (TH_TST (XORI GPR:$rs1, -1), SingleBitSetMask:$mask)>; 627} // Predicates = [HasVendorXTHeadBs] 628 629let Predicates = [HasVendorXTHeadCondMov] in { 630def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT GPR:$b)), 631 (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>; 632def : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT 0)), 633 (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>; 634def : Pat<(select (XLenVT GPR:$cond), (XLenVT 0), (XLenVT GPR:$b)), 635 (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>; 636 637def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)), 638 (TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>; 639def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)), 640 (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>; 641def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)), 642 (TH_MVNEZ GPR:$a, (XLenVT X0), GPR:$cond)>; 643def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)), 644 (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>; 645def : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT 0), (XLenVT GPR:$b)), 646 (TH_MVEQZ GPR:$b, (XLenVT X0), GPR:$cond)>; 647def : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT 0), (XLenVT GPR:$b)), 648 (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>; 649} // Predicates = [HasVendorXTHeadCondMov] 650 651let Predicates = [HasVendorXTHeadMac] in { 652def : Pat<(add GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))), 653 (TH_MULA GPR:$rd, GPR:$rs1, GPR:$rs2)>; 654def : Pat<(sub GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))), 655 (TH_MULS GPR:$rd, GPR:$rs1, GPR:$rs2)>; 656} // Predicates = [HasVendorXTHeadMac] 657 658let Predicates = [HasVendorXTHeadMac, IsRV64] in { 659// mulaw, mulsw are available only in RV64. 660def : Pat<(binop_allwusers<add> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)), 661 (TH_MULAW GPR:$rd, GPR:$rs1, GPR:$rs2)>; 662def : Pat<(binop_allwusers<sub> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)), 663 (TH_MULSW GPR:$rd, GPR:$rs1, GPR:$rs2)>; 664// mulah, mulsh produce a sign-extended result. 665def : Pat<(binop_allwusers<add> GPR:$rd, (mul 666 (sexti16 (i64 GPR:$rs1)), 667 (sexti16 (i64 GPR:$rs2)))), 668 (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>; 669def : Pat<(binop_allwusers<sub> GPR:$rd, (mul 670 (sexti16 (i64 GPR:$rs1)), 671 (sexti16 (i64 GPR:$rs2)))), 672 (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>; 673} // Predicates = [HasVendorXTHeadMac, IsRV64] 674 675let Predicates = [HasVendorXTHeadMac, IsRV32] in { 676def : Pat<(i32 (add GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)), 677 (sexti16 (i32 GPR:$rs2))))), 678 (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>; 679def : Pat<(i32 (sub GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)), 680 (sexti16 (i32 GPR:$rs2))))), 681 (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>; 682} // Predicates = [HasVendorXTHeadMac, IsRV32] 683 684defm PseudoTHVdotVMAQA : VPseudoVMAQA_VV_VX; 685defm PseudoTHVdotVMAQAU : VPseudoVMAQA_VV_VX; 686defm PseudoTHVdotVMAQASU : VPseudoVMAQA_VV_VX; 687defm PseudoTHVdotVMAQAUS : VPseudoVMAQA_VX; 688 689let Predicates = [HasVendorXTHeadVdot] in { 690defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqa", "PseudoTHVdotVMAQA", AllQuadWidenableInt8NoVLMulVectors>; 691defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqau", "PseudoTHVdotVMAQAU", AllQuadWidenableInt8NoVLMulVectors>; 692defm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqasu","PseudoTHVdotVMAQASU",AllQuadWidenableInt8NoVLMulVectors>; 693defm : VPatTernaryVMAQA_VX<"int_riscv_th_vmaqaus", "PseudoTHVdotVMAQAUS",AllQuadWidenableInt8NoVLMulVectors>; 694} 695 696def uimm2_3_XFORM : SDNodeXForm<imm, [{ 697 return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 0x3, 698 SDLoc(N), Subtarget->getXLenVT()); 699}]>; 700 701def uimm2_3 : Operand<XLenVT>, ImmLeaf<XLenVT, [{ 702 return isShiftedUInt<2, 3>(Imm); 703}], uimm2_3_XFORM>; 704 705def uimm2_4_XFORM : SDNodeXForm<imm, [{ 706 return CurDAG->getTargetConstant((N->getZExtValue() >> 4) & 0x3, 707 SDLoc(N), Subtarget->getXLenVT()); 708}]>; 709 710def uimm2_4 : Operand<XLenVT>, ImmLeaf<XLenVT, [{ 711 return isShiftedUInt<2, 4>(Imm); 712}], uimm2_4_XFORM>; 713 714let Predicates = [HasVendorXTHeadMemPair, IsRV64] in { 715def : Pat<(th_lwud i64:$rs1, uimm2_3:$uimm2_3), (TH_LWUD i64:$rs1, uimm2_3:$uimm2_3, 3)>; 716def : Pat<(th_ldd i64:$rs1, uimm2_4:$uimm2_4), (TH_LDD i64:$rs1, uimm2_4:$uimm2_4, 4)>; 717 718def : Pat<(th_sdd i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4), 719 (TH_SDD i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4, 4)>; 720} 721 722let Predicates = [HasVendorXTHeadMemPair] in { 723 def : Pat<(th_lwd GPR:$rs1, uimm2_3:$uimm2_3), (TH_LWD GPR:$rs1, uimm2_3:$uimm2_3, 3)>; 724 def : Pat<(th_swd GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3), 725 (TH_SWD GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3, 3)>; 726} 727 728let Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "THeadCmo" in { 729def TH_DCACHE_CSW : THCacheInst_r<0b00001, "th.dcache.csw">; 730def TH_DCACHE_ISW : THCacheInst_r<0b00010, "th.dcache.isw">; 731def TH_DCACHE_CISW : THCacheInst_r<0b00011, "th.dcache.cisw">; 732def TH_DCACHE_CVAL1 : THCacheInst_r<0b00100, "th.dcache.cval1">; 733def TH_DCACHE_CVA : THCacheInst_r<0b00101, "th.dcache.cva">; 734def TH_DCACHE_IVA : THCacheInst_r<0b00110, "th.dcache.iva">; 735def TH_DCACHE_CIVA : THCacheInst_r<0b00111, "th.dcache.civa">; 736def TH_DCACHE_CPAL1 : THCacheInst_r<0b01000, "th.dcache.cpal1">; 737def TH_DCACHE_CPA : THCacheInst_r<0b01001, "th.dcache.cpa">; 738def TH_DCACHE_IPA : THCacheInst_r<0b01010, "th.dcache.ipa">; 739def TH_DCACHE_CIPA : THCacheInst_r<0b01011, "th.dcache.cipa">; 740def TH_ICACHE_IVA : THCacheInst_r<0b10000, "th.icache.iva">; 741def TH_ICACHE_IPA : THCacheInst_r<0b11000, "th.icache.ipa">; 742 743def TH_DCACHE_CALL : THCacheInst_void<0b00001, "th.dcache.call">; 744def TH_DCACHE_IALL : THCacheInst_void<0b00010, "th.dcache.iall">; 745def TH_DCACHE_CIALL : THCacheInst_void<0b00011, "th.dcache.ciall">; 746def TH_ICACHE_IALL : THCacheInst_void<0b10000, "th.icache.iall">; 747def TH_ICACHE_IALLS : THCacheInst_void<0b10001, "th.icache.ialls">; 748def TH_L2CACHE_CALL : THCacheInst_void<0b10101, "th.l2cache.call">; 749def TH_L2CACHE_IALL : THCacheInst_void<0b10110, "th.l2cache.iall">; 750def TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">; 751} 752 753let Predicates = [HasVendorXTHeadSync], DecoderNamespace = "THeadSync" in { 754def TH_SFENCE_VMAS : THCacheInst_rr<0b0000010, "th.sfence.vmas">; 755def TH_SYNC : THCacheInst_void<0b11000, "th.sync">; 756def TH_SYNC_S : THCacheInst_void<0b11001, "th.sync.s">; 757def TH_SYNC_I : THCacheInst_void<0b11010, "th.sync.i">; 758def TH_SYNC_IS : THCacheInst_void<0b11011, "th.sync.is">; 759} 760 761def AddrRegRegScale : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<3>">; 762def AddrRegZextRegScale 763 : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<3, 32>", 764 [], [], 10>; 765 766multiclass LdIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> { 767def : Pat<(vt (LoadOp (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))), 768 (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>; 769} 770 771multiclass LdZextIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = i64> { 772def : Pat<(vt (LoadOp (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))), 773 (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>; 774} 775 776multiclass StIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy, 777 ValueType vt = XLenVT> { 778def : Pat<(StoreOp (vt StTy:$rd), 779 (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)), 780 (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>; 781} 782 783multiclass StZextIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy, 784 ValueType vt = i64> { 785def : Pat<(StoreOp (vt StTy:$rd), 786 (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)), 787 (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>; 788} 789 790let Predicates = [HasVendorXTHeadMemIdx] in { 791defm : LdIdxPat<extloadi8, TH_LRB>; 792defm : LdIdxPat<sextloadi8, TH_LRB>; 793defm : LdIdxPat<zextloadi8, TH_LRBU>; 794 795defm : LdIdxPat<extloadi16, TH_LRH>; 796defm : LdIdxPat<sextloadi16, TH_LRH>; 797defm : LdIdxPat<zextloadi16, TH_LRHU>; 798 799defm : StIdxPat<truncstorei8, TH_SRB, GPR>; 800defm : StIdxPat<truncstorei16, TH_SRH, GPR>; 801} 802 803let Predicates = [HasVendorXTHeadMemIdx, IsRV32] in { 804defm : LdIdxPat<load, TH_LRW, i32>; 805defm : StIdxPat<store, TH_SRW, GPR, i32>; 806} 807 808let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in { 809defm : LdZextIdxPat<extloadi8, TH_LURB>; 810defm : LdZextIdxPat<sextloadi8, TH_LURB>; 811defm : LdZextIdxPat<zextloadi8, TH_LURBU>; 812 813defm : LdZextIdxPat<extloadi16, TH_LURH>; 814defm : LdZextIdxPat<sextloadi16, TH_LURH>; 815defm : LdZextIdxPat<zextloadi16, TH_LURHU>; 816 817defm : LdIdxPat<extloadi32, TH_LRW, i64>; 818defm : LdIdxPat<sextloadi32, TH_LRW, i64>; 819defm : LdIdxPat<zextloadi32, TH_LRWU, i64>; 820 821defm : LdZextIdxPat<extloadi32, TH_LURW>; 822defm : LdZextIdxPat<sextloadi32, TH_LURW>; 823defm : LdZextIdxPat<zextloadi32, TH_LURWU>; 824 825defm : LdIdxPat<load, TH_LRD, i64>; 826defm : LdZextIdxPat<load, TH_LURD>; 827 828defm : StZextIdxPat<truncstorei8, TH_SURB, GPR>; 829defm : StZextIdxPat<truncstorei16, TH_SURH, GPR>; 830defm : StIdxPat<truncstorei32, TH_SRW, GPR, i64>; 831defm : StZextIdxPat<truncstorei32, TH_SURW, GPR, i64>; 832defm : StIdxPat<store, TH_SRD, GPR, i64>; 833defm : StZextIdxPat<store, TH_SURD, GPR>; 834} 835 836let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF] in { 837defm : LdIdxPat<load, TH_FLRW, f32>; 838defm : StIdxPat<store, TH_FSRW, FPR32, f32>; 839} 840 841let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD] in { 842defm : LdIdxPat<load, TH_FLRD, f64>; 843defm : StIdxPat<store, TH_FSRD, FPR64, f64>; 844} 845 846let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64] in { 847defm : LdZextIdxPat<load, TH_FLURW, f32>; 848defm : StZextIdxPat<store, TH_FSURW, FPR32, f32>; 849} 850 851let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64] in { 852defm : LdZextIdxPat<load, TH_FLURD, f64>; 853defm : StZextIdxPat<store, TH_FSURD, FPR64, f64>; 854} 855 856def simm5shl2 : ComplexPattern<XLenVT, 2, "selectSimm5Shl2">; 857 858multiclass StoreUpdatePat<PatFrag st, Instruction Inst, ValueType vt = XLenVT> { 859def : Pat<(st (vt GPR:$rd), GPR:$rs1, (simm5shl2 simm5:$simm5, uimm2:$uimm2)), 860 (Inst GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2)>; 861} 862 863let Predicates = [HasVendorXTHeadMemIdx] in { 864defm : StoreUpdatePat<post_truncsti8, TH_SBIA>; 865defm : StoreUpdatePat<pre_truncsti8, TH_SBIB>; 866defm : StoreUpdatePat<post_truncsti16, TH_SHIA>; 867defm : StoreUpdatePat<pre_truncsti16, TH_SHIB>; 868} 869 870let Predicates = [HasVendorXTHeadMemIdx, IsRV32] in { 871defm : StoreUpdatePat<post_store, TH_SWIA, i32>; 872defm : StoreUpdatePat<pre_store, TH_SWIB, i32>; 873} 874 875let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in { 876defm : StoreUpdatePat<post_truncsti32, TH_SWIA, i64>; 877defm : StoreUpdatePat<pre_truncsti32, TH_SWIB, i64>; 878defm : StoreUpdatePat<post_store, TH_SDIA, i64>; 879defm : StoreUpdatePat<pre_store, TH_SDIB, i64>; 880} 881