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