xref: /freebsd/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1bdd1243dSDimitry Andric//===-- RISCVInstrInfoXTHead.td ----------------------------*- tablegen -*-===//
2bdd1243dSDimitry Andric//
3bdd1243dSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric//
7bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric//
9bdd1243dSDimitry Andric// This file describes the vendor extensions defined by T-Head of Alibaba.
10bdd1243dSDimitry Andric//
11bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
12bdd1243dSDimitry Andric
13bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
1406c3fb27SDimitry Andric// T-HEAD specific DAG Nodes.
1506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1606c3fb27SDimitry Andric
175f757f3fSDimitry Andricdef SDT_LoadPair : SDTypeProfile<2, 2, [SDTCisSameAs<0, 1>,
185f757f3fSDimitry Andric                                        SDTCisSameAs<1, 3>,
195f757f3fSDimitry Andric                                        SDTCisPtrTy<2>,
205f757f3fSDimitry Andric                                        SDTCisVT<3, XLenVT>]>;
215f757f3fSDimitry Andricdef SDT_StorePair : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
225f757f3fSDimitry Andric                                         SDTCisSameAs<1, 3>,
235f757f3fSDimitry Andric                                         SDTCisPtrTy<2>,
245f757f3fSDimitry Andric                                         SDTCisVT<3, XLenVT>]>;
2506c3fb27SDimitry Andric
2606c3fb27SDimitry Andricdef th_lwud : SDNode<"RISCVISD::TH_LWUD", SDT_LoadPair,
2706c3fb27SDimitry Andric                     [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
2806c3fb27SDimitry Andricdef th_lwd : SDNode<"RISCVISD::TH_LWD", SDT_LoadPair,
2906c3fb27SDimitry Andric                    [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
3006c3fb27SDimitry Andricdef th_ldd : SDNode<"RISCVISD::TH_LDD", SDT_LoadPair,
3106c3fb27SDimitry Andric                    [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
3206c3fb27SDimitry Andricdef th_swd : SDNode<"RISCVISD::TH_SWD", SDT_StorePair,
3306c3fb27SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
3406c3fb27SDimitry Andricdef th_sdd : SDNode<"RISCVISD::TH_SDD", SDT_StorePair,
3506c3fb27SDimitry Andric                    [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
3606c3fb27SDimitry Andric
3706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
38bdd1243dSDimitry Andric// Instruction class templates
39bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
405f757f3fSDimitry Andric
41bdd1243dSDimitry Andricclass THInstVdotVV<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
42bdd1243dSDimitry Andric                   string opcodestr, string argstr>
43bdd1243dSDimitry Andric    : RVInstVV<funct6, opv, outs, ins, opcodestr, argstr> {
44bdd1243dSDimitry Andric  let Inst{26} = 0;
4506c3fb27SDimitry Andric  let Inst{6-0} = OPC_CUSTOM_0.Value;
465f757f3fSDimitry Andric  let DecoderNamespace = "XTHeadVdot";
47bdd1243dSDimitry Andric}
48bdd1243dSDimitry Andric
49bdd1243dSDimitry Andricclass THInstVdotVX<bits<6> funct6, RISCVVFormat opv, dag outs, dag ins,
50bdd1243dSDimitry Andric                   string opcodestr, string argstr>
51bdd1243dSDimitry Andric    : RVInstVX<funct6, opv, outs, ins, opcodestr, argstr> {
52bdd1243dSDimitry Andric  let Inst{26} = 1;
5306c3fb27SDimitry Andric  let Inst{6-0} = OPC_CUSTOM_0.Value;
545f757f3fSDimitry Andric  let DecoderNamespace = "XTHeadVdot";
55bdd1243dSDimitry Andric}
56bdd1243dSDimitry Andric
57bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
58bdd1243dSDimitry Andric// op vd, vs1, vs2, vm (reverse the order of vs1 and vs2)
595f757f3fSDimitry Andricclass THVdotALUrVV<bits<6> funct6, RISCVVFormat opv, string opcodestr,
605f757f3fSDimitry Andric                   bit EarlyClobber>
615f757f3fSDimitry Andric    : THInstVdotVV<funct6, opv, (outs VR:$vd_wb),
625f757f3fSDimitry Andric                   (ins VR:$vd, VR:$vs1, VR:$vs2, VMaskOp:$vm),
635f757f3fSDimitry Andric                   opcodestr, "$vd, $vs1, $vs2$vm"> {
645f757f3fSDimitry Andric  let Constraints = !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb",
655f757f3fSDimitry Andric                                      "$vd = $vd_wb");
665f757f3fSDimitry Andric}
67bdd1243dSDimitry Andric
68bdd1243dSDimitry Andric// op vd, rs1, vs2, vm (reverse the order of rs1 and vs2)
695f757f3fSDimitry Andricclass THVdotALUrVX<bits<6> funct6, RISCVVFormat opv, string opcodestr,
705f757f3fSDimitry Andric                   bit EarlyClobber>
715f757f3fSDimitry Andric    : THInstVdotVX<funct6, opv, (outs VR:$vd_wb),
725f757f3fSDimitry Andric                   (ins VR:$vd, GPR:$rs1, VR:$vs2, VMaskOp:$vm),
735f757f3fSDimitry Andric                   opcodestr, "$vd, $rs1, $vs2$vm"> {
745f757f3fSDimitry Andric  let Constraints = !if(EarlyClobber, "@earlyclobber $vd_wb, $vd = $vd_wb",
755f757f3fSDimitry Andric                                      "$vd = $vd_wb");
765f757f3fSDimitry Andric}
77bdd1243dSDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
78bdd1243dSDimitry Andric
795f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadBa], DecoderNamespace = "XTHeadBa",
8006c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
8106c3fb27SDimitry Andricclass THShiftALU_rri<bits<3> funct3, string opcodestr>
825f757f3fSDimitry Andric    : RVInstRBase<funct3, OPC_CUSTOM_0, (outs GPR:$rd),
8306c3fb27SDimitry Andric                  (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
8406c3fb27SDimitry Andric                  opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
8506c3fb27SDimitry Andric  bits<2> uimm2;
8606c3fb27SDimitry Andric  let Inst{31-27} = 0;
8706c3fb27SDimitry Andric  let Inst{26-25} = uimm2;
8806c3fb27SDimitry Andric}
8906c3fb27SDimitry Andric
905f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadBb], DecoderNamespace = "XTHeadBb",
9106c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
9206c3fb27SDimitry Andricclass THShift_ri<bits<5> funct5, bits<3> funct3, string opcodestr>
9306c3fb27SDimitry Andric    : RVInstIShift<funct5, funct3, OPC_CUSTOM_0, (outs GPR:$rd),
9406c3fb27SDimitry Andric                   (ins GPR:$rs1, uimmlog2xlen:$shamt),
9506c3fb27SDimitry Andric                   opcodestr, "$rd, $rs1, $shamt">;
9606c3fb27SDimitry Andric
9706c3fb27SDimitry Andricclass THBitfieldExtract_rii<bits<3> funct3, string opcodestr>
985f757f3fSDimitry Andric    : RVInstIBase<funct3, OPC_CUSTOM_0, (outs GPR:$rd),
9906c3fb27SDimitry Andric                  (ins GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb),
10006c3fb27SDimitry Andric                  opcodestr, "$rd, $rs1, $msb, $lsb"> {
10106c3fb27SDimitry Andric  bits<6> msb;
10206c3fb27SDimitry Andric  bits<6> lsb;
10306c3fb27SDimitry Andric  let Inst{31-26} = msb;
10406c3fb27SDimitry Andric  let Inst{25-20} = lsb;
10506c3fb27SDimitry Andric}
10606c3fb27SDimitry Andric
10706c3fb27SDimitry Andricclass THRev_r<bits<5> funct5, bits<2> funct2, string opcodestr>
1085f757f3fSDimitry Andric    : RVInstIUnary<{funct5, funct2, 0b00000}, 0b001, OPC_CUSTOM_0,
1095f757f3fSDimitry Andric                   (outs GPR:$rd), (ins GPR:$rs1), opcodestr, "$rd, $rs1">;
11006c3fb27SDimitry Andric}
11106c3fb27SDimitry Andric
1125f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadBb, IsRV64], DecoderNamespace = "XTHeadBb",
11306c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
11406c3fb27SDimitry Andricclass THShiftW_ri<bits<7> funct7, bits<3> funct3, string opcodestr>
11506c3fb27SDimitry Andric    : RVInstIShiftW<funct7, funct3, OPC_CUSTOM_0, (outs GPR:$rd),
11606c3fb27SDimitry Andric                    (ins GPR:$rs1, uimm5:$shamt),
11706c3fb27SDimitry Andric                    opcodestr, "$rd, $rs1, $shamt">;
11806c3fb27SDimitry Andric
1195f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadCondMov], DecoderNamespace = "XTHeadCondMov",
12006c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
12106c3fb27SDimitry Andricclass THCondMov_rr<bits<7> funct7, string opcodestr>
12206c3fb27SDimitry Andric    : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb),
12306c3fb27SDimitry Andric              (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
12406c3fb27SDimitry Andric              opcodestr, "$rd, $rs1, $rs2"> {
12506c3fb27SDimitry Andric  let Constraints = "$rd_wb = $rd";
12606c3fb27SDimitry Andric}
12706c3fb27SDimitry Andric
1285f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMac], DecoderNamespace = "XTHeadMac",
12906c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCommutable = 1 in
13006c3fb27SDimitry Andricclass THMulAccumulate_rr<bits<7> funct7, string opcodestr>
13106c3fb27SDimitry Andric    : RVInstR<funct7, 0b001, OPC_CUSTOM_0, (outs GPR:$rd_wb),
13206c3fb27SDimitry Andric              (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
13306c3fb27SDimitry Andric              opcodestr, "$rd, $rs1, $rs2"> {
13406c3fb27SDimitry Andric  let Constraints = "$rd_wb = $rd";
13506c3fb27SDimitry Andric}
13606c3fb27SDimitry Andric
1375f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "XTHeadMemPair",
13806c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
13906c3fb27SDimitry Andricclass THLoadPair<bits<5> funct5, string opcodestr>
1405f757f3fSDimitry Andric  : RVInstRBase<0b100, OPC_CUSTOM_0,
14106c3fb27SDimitry Andric                (outs GPR:$rd, GPR:$rs2),
14206c3fb27SDimitry Andric                (ins GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
14306c3fb27SDimitry Andric                 opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
14406c3fb27SDimitry Andric  bits<2> uimm2;
1455f757f3fSDimitry Andric  let Inst{31-27} = funct5;
14606c3fb27SDimitry Andric  let Inst{26-25} = uimm2;
14706c3fb27SDimitry Andric  let DecoderMethod = "decodeXTHeadMemPair";
14806c3fb27SDimitry Andric  let Constraints = "@earlyclobber $rd,@earlyclobber $rs2";
14906c3fb27SDimitry Andric}
15006c3fb27SDimitry Andric
1515f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMemPair], DecoderNamespace = "XTHeadMemPair",
15206c3fb27SDimitry Andric    hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
15306c3fb27SDimitry Andricclass THStorePair<bits<5> funct5, string opcodestr>
1545f757f3fSDimitry Andric  : RVInstRBase<0b101, OPC_CUSTOM_0, (outs),
15506c3fb27SDimitry Andric              (ins GPR:$rd, GPR:$rs2, GPR:$rs1, uimm2:$uimm2, uimm7:$const3or4),
15606c3fb27SDimitry Andric              opcodestr, "$rd, $rs2, (${rs1}), $uimm2, $const3or4"> {
15706c3fb27SDimitry Andric  bits<2> uimm2;
1585f757f3fSDimitry Andric  let Inst{31-27} = funct5;
15906c3fb27SDimitry Andric  let Inst{26-25} = uimm2;
16006c3fb27SDimitry Andric  let DecoderMethod = "decodeXTHeadMemPair";
16106c3fb27SDimitry Andric}
16206c3fb27SDimitry Andric
16306c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
16406c3fb27SDimitry Andricclass THCacheInst_r<bits<5> funct5, string opcodestr>
16506c3fb27SDimitry Andric    : RVInstR<0b0000001, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1),
16606c3fb27SDimitry Andric              opcodestr, "$rs1"> {
16706c3fb27SDimitry Andric  let rd = 0;
16806c3fb27SDimitry Andric  let rs2 = funct5;
16906c3fb27SDimitry Andric}
17006c3fb27SDimitry Andric
17106c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
17206c3fb27SDimitry Andricclass THCacheInst_rr<bits<7> funct7, string opcodestr>
17306c3fb27SDimitry Andric    : RVInstR<funct7, 0, OPC_CUSTOM_0, (outs), (ins GPR:$rs1, GPR:$rs2),
17406c3fb27SDimitry Andric      opcodestr, "$rs1, $rs2"> {
17506c3fb27SDimitry Andric  let rd = 0;
17606c3fb27SDimitry Andric}
17706c3fb27SDimitry Andric
17806c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
17906c3fb27SDimitry Andricclass THCacheInst_void<bits<5> funct5, string opcodestr>
18006c3fb27SDimitry Andric    : RVInstR<0b0000000, 0, OPC_CUSTOM_0, (outs), (ins), opcodestr, ""> {
18106c3fb27SDimitry Andric  let rd = 0;
18206c3fb27SDimitry Andric  let rs1 = 0;
18306c3fb27SDimitry Andric  let rs2 = funct5;
18406c3fb27SDimitry Andric}
18506c3fb27SDimitry Andric
18606c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
18706c3fb27SDimitry Andricclass THLoadIndexed<RegisterClass Ty, bits<5> funct5, string opcodestr>
1885f757f3fSDimitry Andric    : RVInstRBase<!if(!eq(Ty, GPR), 0b100, 0b110), OPC_CUSTOM_0,
18906c3fb27SDimitry Andric                  (outs Ty:$rd), (ins GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
19006c3fb27SDimitry Andric                  opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
19106c3fb27SDimitry Andric  bits<2> uimm2;
1925f757f3fSDimitry Andric  let Inst{31-27} = funct5;
19306c3fb27SDimitry Andric  let Inst{26-25} = uimm2;
19406c3fb27SDimitry Andric}
19506c3fb27SDimitry Andric
19606c3fb27SDimitry Andricclass THLoadUpdate<bits<5> funct5, string opcodestr>
1975f757f3fSDimitry Andric    : RVInstIBase<0b100, OPC_CUSTOM_0, (outs GPR:$rd, GPR:$rs1_wb),
19806c3fb27SDimitry Andric                  (ins GPR:$rs1, simm5:$simm5, uimm2:$uimm2),
19906c3fb27SDimitry Andric                  opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> {
20006c3fb27SDimitry Andric  bits<5> simm5;
20106c3fb27SDimitry Andric  bits<2> uimm2;
2025f757f3fSDimitry Andric  let Inst{31-27} = funct5;
2035f757f3fSDimitry Andric  let Inst{26-25} = uimm2;
2045f757f3fSDimitry Andric  let Inst{24-20} = simm5;
20506c3fb27SDimitry Andric  let Constraints = "@earlyclobber $rd, $rs1_wb = $rs1";
20606c3fb27SDimitry Andric}
20706c3fb27SDimitry Andric}
20806c3fb27SDimitry Andric
20906c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
21006c3fb27SDimitry Andricclass THStoreIndexed<RegisterClass StTy, bits<5> funct5, string opcodestr>
2115f757f3fSDimitry Andric    : RVInstRBase<!if(!eq(StTy, GPR), 0b101, 0b111), OPC_CUSTOM_0,
21206c3fb27SDimitry Andric                  (outs), (ins StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2),
21306c3fb27SDimitry Andric                  opcodestr, "$rd, $rs1, $rs2, $uimm2"> {
21406c3fb27SDimitry Andric  bits<2> uimm2;
2155f757f3fSDimitry Andric  let Inst{31-27} = funct5;
21606c3fb27SDimitry Andric  let Inst{26-25} = uimm2;
21706c3fb27SDimitry Andric}
21806c3fb27SDimitry Andric
21906c3fb27SDimitry Andricclass THStoreUpdate<bits<5> funct5, string opcodestr>
2205f757f3fSDimitry Andric    : RVInstIBase<0b101, OPC_CUSTOM_0, (outs GPR:$rs1_up),
22106c3fb27SDimitry Andric                  (ins GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2),
22206c3fb27SDimitry Andric                  opcodestr, "$rd, (${rs1}), $simm5, $uimm2"> {
22306c3fb27SDimitry Andric  bits<5> simm5;
22406c3fb27SDimitry Andric  bits<2> uimm2;
2255f757f3fSDimitry Andric  let Inst{31-27} = funct5;
2265f757f3fSDimitry Andric  let Inst{26-25} = uimm2;
2275f757f3fSDimitry Andric  let Inst{24-20} = simm5;
22806c3fb27SDimitry Andric  let Constraints = "$rs1_up = $rs1";
22906c3fb27SDimitry Andric}
23006c3fb27SDimitry Andric}
23106c3fb27SDimitry Andric
232bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
233bdd1243dSDimitry Andric// Combination of instruction classes.
234bdd1243dSDimitry Andric// Use these multiclasses to define instructions more easily.
235bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2365f757f3fSDimitry Andric
237bdd1243dSDimitry Andricmulticlass THVdotVMAQA_VX<string opcodestr, bits<6> funct6> {
2385f757f3fSDimitry Andric  let RVVConstraint = WidenV in
2395f757f3fSDimitry Andric  def _VX : THVdotALUrVX<funct6, OPMVX, opcodestr # ".vx", EarlyClobber=1>;
240bdd1243dSDimitry Andric}
241bdd1243dSDimitry Andric
2425f757f3fSDimitry Andricmulticlass THVdotVMAQA<string opcodestr, bits<6> funct6>
2435f757f3fSDimitry Andric    : THVdotVMAQA_VX<opcodestr, funct6> {
2445f757f3fSDimitry Andric  let RVVConstraint = WidenV in
2455f757f3fSDimitry Andric  def _VV   : THVdotALUrVV<funct6, OPMVX, opcodestr # ".vv", EarlyClobber=1>;
246bdd1243dSDimitry Andric}
247bdd1243dSDimitry Andric
248bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
249bdd1243dSDimitry Andric// Instructions
250bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2515f757f3fSDimitry Andric
2525f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadBa] in
25306c3fb27SDimitry Andricdef TH_ADDSL : THShiftALU_rri<0b001, "th.addsl">,
25406c3fb27SDimitry Andric               Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
25506c3fb27SDimitry Andric
25606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBb] in {
25706c3fb27SDimitry Andricdef TH_SRRI : THShift_ri<0b00010, 0b001, "th.srri">;
25806c3fb27SDimitry Andricdef TH_EXT : THBitfieldExtract_rii<0b010, "th.ext">;
25906c3fb27SDimitry Andricdef TH_EXTU : THBitfieldExtract_rii<0b011, "th.extu">;
26006c3fb27SDimitry Andricdef TH_FF0 : THRev_r<0b10000, 0b10, "th.ff0">;
26106c3fb27SDimitry Andricdef TH_FF1 : THRev_r<0b10000, 0b11, "th.ff1">;
26206c3fb27SDimitry Andricdef TH_REV : THRev_r<0b10000, 0b01, "th.rev">;
26306c3fb27SDimitry Andricdef TH_TSTNBZ : THRev_r<0b10000, 0b00, "th.tstnbz">;
26406c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBb]
26506c3fb27SDimitry Andric
26606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBb, IsRV64], IsSignExtendingOpW = 1 in {
26706c3fb27SDimitry Andricdef TH_SRRIW : THShiftW_ri<0b0001010, 0b001, "th.srriw">;
26806c3fb27SDimitry Andricdef TH_REVW : THRev_r<0b10010, 0b00, "th.revw">;
26906c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBb, IsRV64]
27006c3fb27SDimitry Andric
2715f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadBs], DecoderNamespace = "XTHeadBs",
2725f757f3fSDimitry Andric    IsSignExtendingOpW = 1 in
27306c3fb27SDimitry Andricdef TH_TST : RVBShift_ri<0b10001, 0b001, OPC_CUSTOM_0, "th.tst">,
27406c3fb27SDimitry Andric             Sched<[WriteSingleBitImm, ReadSingleBitImm]>;
27506c3fb27SDimitry Andric
27606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadCondMov] in {
27706c3fb27SDimitry Andricdef TH_MVEQZ : THCondMov_rr<0b0100000, "th.mveqz">;
27806c3fb27SDimitry Andricdef TH_MVNEZ : THCondMov_rr<0b0100001, "th.mvnez">;
27906c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadCondMov]
28006c3fb27SDimitry Andric
28106c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac] in {
28206c3fb27SDimitry Andricdef TH_MULA : THMulAccumulate_rr<0b0010000, "th.mula">;
28306c3fb27SDimitry Andricdef TH_MULS : THMulAccumulate_rr<0b0010001, "th.muls">;
28406c3fb27SDimitry Andric}  // Predicates = [HasVendorXTHeadMac]
28506c3fb27SDimitry Andric
28606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1 in {
28706c3fb27SDimitry Andricdef TH_MULAH : THMulAccumulate_rr<0b0010100, "th.mulah">;
28806c3fb27SDimitry Andricdef TH_MULSH : THMulAccumulate_rr<0b0010101, "th.mulsh">;
28906c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadMac], IsSignExtendingOpW = 1
29006c3fb27SDimitry Andric
29106c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac, IsRV64], IsSignExtendingOpW = 1 in {
29206c3fb27SDimitry Andricdef TH_MULAW : THMulAccumulate_rr<0b0010010, "th.mulaw">;
29306c3fb27SDimitry Andricdef TH_MULSW : THMulAccumulate_rr<0b0010011, "th.mulsw">;
29406c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadMac, IsRV64]
29506c3fb27SDimitry Andric
29606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemPair] in {
29706c3fb27SDimitry Andricdef TH_LWUD : THLoadPair<0b11110, "th.lwud">,
29806c3fb27SDimitry Andric              Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
29906c3fb27SDimitry Andricdef TH_SWD  : THStorePair<0b11100, "th.swd">,
30006c3fb27SDimitry Andric              Sched<[WriteSTW, WriteSTW, ReadStoreData, ReadMemBase]>;
30106c3fb27SDimitry Andriclet IsSignExtendingOpW = 1 in
30206c3fb27SDimitry Andricdef TH_LWD  : THLoadPair<0b11100, "th.lwd">,
30306c3fb27SDimitry Andric              Sched<[WriteLDW, WriteLDW, ReadMemBase]>;
30406c3fb27SDimitry Andric}
30506c3fb27SDimitry Andric
30606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
30706c3fb27SDimitry Andricdef TH_LDD : THLoadPair<0b11111, "th.ldd">,
30806c3fb27SDimitry Andric             Sched<[WriteLDD, WriteLDD, ReadMemBase]>;
30906c3fb27SDimitry Andricdef TH_SDD : THStorePair<0b11111, "th.sdd">,
31006c3fb27SDimitry Andric             Sched<[WriteSTD, WriteSTD, ReadStoreData, ReadMemBase]>;
31106c3fb27SDimitry Andric}
31206c3fb27SDimitry Andric
3135f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "XTHeadMemIdx" in {
31406c3fb27SDimitry Andric// T-Head Load/Store + Update instructions.
31506c3fb27SDimitry Andricdef TH_LBIA : THLoadUpdate<0b00011, "th.lbia">,
31606c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
31706c3fb27SDimitry Andricdef TH_LBIB : THLoadUpdate<0b00001, "th.lbib">,
31806c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
31906c3fb27SDimitry Andricdef TH_LBUIA : THLoadUpdate<0b10011, "th.lbuia">,
32006c3fb27SDimitry Andric               Sched<[WriteLDB, ReadMemBase]>;
32106c3fb27SDimitry Andricdef TH_LBUIB : THLoadUpdate<0b10001, "th.lbuib">,
32206c3fb27SDimitry Andric               Sched<[WriteLDB, ReadMemBase]>;
32306c3fb27SDimitry Andric
32406c3fb27SDimitry Andricdef TH_LHIA : THLoadUpdate<0b00111, "th.lhia">,
32506c3fb27SDimitry Andric              Sched<[WriteLDH, ReadMemBase]>;
32606c3fb27SDimitry Andricdef TH_LHIB : THLoadUpdate<0b00101, "th.lhib">,
32706c3fb27SDimitry Andric              Sched<[WriteLDH, ReadMemBase]>;
32806c3fb27SDimitry Andricdef TH_LHUIA : THLoadUpdate<0b10111, "th.lhuia">,
32906c3fb27SDimitry Andric               Sched<[WriteLDH, ReadMemBase]>;
33006c3fb27SDimitry Andricdef TH_LHUIB : THLoadUpdate<0b10101, "th.lhuib">,
33106c3fb27SDimitry Andric               Sched<[WriteLDH, ReadMemBase]>;
33206c3fb27SDimitry Andric
33306c3fb27SDimitry Andricdef TH_LWIA : THLoadUpdate<0b01011, "th.lwia">,
33406c3fb27SDimitry Andric              Sched<[WriteLDW, ReadMemBase]>;
33506c3fb27SDimitry Andricdef TH_LWIB : THLoadUpdate<0b01001, "th.lwib">,
33606c3fb27SDimitry Andric              Sched<[WriteLDW, ReadMemBase]>;
33706c3fb27SDimitry Andric
33806c3fb27SDimitry Andricdef TH_SBIA : THStoreUpdate<0b00011, "th.sbia">,
33906c3fb27SDimitry Andric              Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
34006c3fb27SDimitry Andricdef TH_SBIB : THStoreUpdate<0b00001, "th.sbib">,
34106c3fb27SDimitry Andric              Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
34206c3fb27SDimitry Andric
34306c3fb27SDimitry Andricdef TH_SHIA : THStoreUpdate<0b00111, "th.shia">,
34406c3fb27SDimitry Andric              Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
34506c3fb27SDimitry Andricdef TH_SHIB : THStoreUpdate<0b00101, "th.shib">,
34606c3fb27SDimitry Andric              Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
34706c3fb27SDimitry Andric
34806c3fb27SDimitry Andricdef TH_SWIA : THStoreUpdate<0b01011, "th.swia">,
34906c3fb27SDimitry Andric              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
35006c3fb27SDimitry Andricdef TH_SWIB : THStoreUpdate<0b01001, "th.swib">,
35106c3fb27SDimitry Andric              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
35206c3fb27SDimitry Andric
35306c3fb27SDimitry Andric// T-Head Load/Store Indexed instructions.
35406c3fb27SDimitry Andricdef TH_LRB : THLoadIndexed<GPR, 0b00000, "th.lrb">,
35506c3fb27SDimitry Andric             Sched<[WriteLDB, ReadMemBase]>;
35606c3fb27SDimitry Andricdef TH_LRBU : THLoadIndexed<GPR, 0b10000, "th.lrbu">,
35706c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
35806c3fb27SDimitry Andricdef TH_LURB : THLoadIndexed<GPR, 0b00010, "th.lurb">,
35906c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
36006c3fb27SDimitry Andricdef TH_LURBU : THLoadIndexed<GPR, 0b10010, "th.lurbu">,
36106c3fb27SDimitry Andric               Sched<[WriteLDB, ReadMemBase]>;
36206c3fb27SDimitry Andric
36306c3fb27SDimitry Andricdef TH_LRH : THLoadIndexed<GPR, 0b00100, "th.lrh">,
36406c3fb27SDimitry Andric             Sched<[WriteLDH, ReadMemBase]>;
36506c3fb27SDimitry Andricdef TH_LRHU : THLoadIndexed<GPR, 0b10100, "th.lrhu">,
36606c3fb27SDimitry Andric              Sched<[WriteLDH, ReadMemBase]>;
36706c3fb27SDimitry Andricdef TH_LURH : THLoadIndexed<GPR, 0b00110, "th.lurh">,
36806c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
36906c3fb27SDimitry Andricdef TH_LURHU : THLoadIndexed<GPR, 0b10110, "th.lurhu">,
37006c3fb27SDimitry Andric               Sched<[WriteLDB, ReadMemBase]>;
37106c3fb27SDimitry Andric
37206c3fb27SDimitry Andricdef TH_LRW : THLoadIndexed<GPR, 0b01000, "th.lrw">,
37306c3fb27SDimitry Andric             Sched<[WriteLDW, ReadMemBase]>;
37406c3fb27SDimitry Andricdef TH_LURW : THLoadIndexed<GPR, 0b01010, "th.lurw">,
37506c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
37606c3fb27SDimitry Andric
37706c3fb27SDimitry Andricdef TH_SRB : THStoreIndexed<GPR, 0b00000, "th.srb">,
37806c3fb27SDimitry Andric             Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
37906c3fb27SDimitry Andricdef TH_SURB : THStoreIndexed<GPR, 0b00010, "th.surb">,
38006c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
38106c3fb27SDimitry Andric
38206c3fb27SDimitry Andricdef TH_SRH : THStoreIndexed<GPR, 0b00100, "th.srh">,
38306c3fb27SDimitry Andric             Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
38406c3fb27SDimitry Andricdef TH_SURH : THStoreIndexed<GPR, 0b00110, "th.surh">,
38506c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
38606c3fb27SDimitry Andric
38706c3fb27SDimitry Andricdef TH_SRW : THStoreIndexed<GPR, 0b01000, "th.srw">,
38806c3fb27SDimitry Andric             Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
38906c3fb27SDimitry Andricdef TH_SURW : THStoreIndexed<GPR, 0b01010, "th.surw">,
39006c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
39106c3fb27SDimitry Andric}
39206c3fb27SDimitry Andric
3935f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx, IsRV64], DecoderNamespace = "XTHeadMemIdx" in {
39406c3fb27SDimitry Andric// T-Head Load/Store + Update instructions.
39506c3fb27SDimitry Andricdef TH_LWUIA : THLoadUpdate<0b11011, "th.lwuia">,
39606c3fb27SDimitry Andric               Sched<[WriteLDH, ReadMemBase]>;
39706c3fb27SDimitry Andricdef TH_LWUIB : THLoadUpdate<0b11001, "th.lwuib">,
39806c3fb27SDimitry Andric               Sched<[WriteLDH, ReadMemBase]>;
39906c3fb27SDimitry Andric
40006c3fb27SDimitry Andricdef TH_LDIA : THLoadUpdate<0b01111, "th.ldia">,
40106c3fb27SDimitry Andric              Sched<[WriteLDW, ReadMemBase]>;
40206c3fb27SDimitry Andricdef TH_LDIB : THLoadUpdate<0b01101, "th.ldib">,
40306c3fb27SDimitry Andric              Sched<[WriteLDW, ReadMemBase]>;
40406c3fb27SDimitry Andric
40506c3fb27SDimitry Andricdef TH_SDIA : THStoreUpdate<0b01111, "th.sdia">,
40606c3fb27SDimitry Andric              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
40706c3fb27SDimitry Andricdef TH_SDIB : THStoreUpdate<0b01101, "th.sdib">,
40806c3fb27SDimitry Andric              Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
40906c3fb27SDimitry Andric
41006c3fb27SDimitry Andric// T-Head Load/Store Indexed instructions.
41106c3fb27SDimitry Andricdef TH_LRWU : THLoadIndexed<GPR, 0b11000, "th.lrwu">,
41206c3fb27SDimitry Andric              Sched<[WriteLDW, ReadMemBase]>;
41306c3fb27SDimitry Andricdef TH_LURWU : THLoadIndexed<GPR, 0b11010, "th.lurwu">,
41406c3fb27SDimitry Andric               Sched<[WriteLDB, ReadMemBase]>;
41506c3fb27SDimitry Andric
41606c3fb27SDimitry Andricdef TH_LRD : THLoadIndexed<GPR, 0b01100, "th.lrd">,
41706c3fb27SDimitry Andric             Sched<[WriteLDW, ReadMemBase]>;
41806c3fb27SDimitry Andricdef TH_LURD : THLoadIndexed<GPR, 0b01110, "th.lurd">,
41906c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
42006c3fb27SDimitry Andric
42106c3fb27SDimitry Andricdef TH_SRD : THStoreIndexed<GPR, 0b01100, "th.srd">,
42206c3fb27SDimitry Andric             Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
42306c3fb27SDimitry Andricdef TH_SURD : THStoreIndexed<GPR, 0b01110, "th.surd">,
42406c3fb27SDimitry Andric              Sched<[WriteLDB, ReadMemBase]>;
42506c3fb27SDimitry Andric}
42606c3fb27SDimitry Andric
42706c3fb27SDimitry Andric// T-Head Load/Store Indexed instructions for floating point registers.
42806c3fb27SDimitry Andric
42906c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF],
4305f757f3fSDimitry Andric    DecoderNamespace = "XTHeadFMemIdx" in {
43106c3fb27SDimitry Andricdef TH_FLRW : THLoadIndexed<FPR32, 0b01000, "th.flrw">,
43206c3fb27SDimitry Andric              Sched<[WriteFLD32, ReadFMemBase]>;
43306c3fb27SDimitry Andricdef TH_FSRW : THStoreIndexed<FPR32, 0b01000, "th.fsrw">,
43406c3fb27SDimitry Andric              Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
43506c3fb27SDimitry Andric}
43606c3fb27SDimitry Andric
43706c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD],
4385f757f3fSDimitry Andric    DecoderNamespace = "XTHeadFMemIdx" in {
43906c3fb27SDimitry Andricdef TH_FLRD : THLoadIndexed<FPR64, 0b01100, "th.flrd">,
44006c3fb27SDimitry Andric              Sched<[WriteFLD64, ReadFMemBase]>;
44106c3fb27SDimitry Andricdef TH_FSRD : THStoreIndexed<FPR64, 0b01100, "th.fsrd">,
44206c3fb27SDimitry Andric              Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
44306c3fb27SDimitry Andric}
44406c3fb27SDimitry Andric
44506c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64],
4465f757f3fSDimitry Andric    DecoderNamespace = "XTHeadFMemIdx" in {
44706c3fb27SDimitry Andricdef TH_FLURW : THLoadIndexed<FPR32, 0b01010, "th.flurw">,
44806c3fb27SDimitry Andric               Sched<[WriteFLD32, ReadFMemBase]>;
44906c3fb27SDimitry Andricdef TH_FSURW : THStoreIndexed<FPR32, 0b01010, "th.fsurw">,
45006c3fb27SDimitry Andric               Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>;
45106c3fb27SDimitry Andric}
45206c3fb27SDimitry Andric
45306c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64],
4545f757f3fSDimitry Andric    DecoderNamespace = "XTHeadFMemIdx" in {
45506c3fb27SDimitry Andricdef TH_FLURD : THLoadIndexed<FPR64, 0b01110, "th.flurd">,
45606c3fb27SDimitry Andric               Sched<[WriteFLD64, ReadFMemBase]>;
45706c3fb27SDimitry Andricdef TH_FSURD : THStoreIndexed<FPR64, 0b01110, "th.fsurd">,
45806c3fb27SDimitry Andric               Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>;
45906c3fb27SDimitry Andric}
46006c3fb27SDimitry Andric
4615f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadVdot] in {
462bdd1243dSDimitry Andricdefm THVdotVMAQA      : THVdotVMAQA<"th.vmaqa",     0b100000>;
463bdd1243dSDimitry Andricdefm THVdotVMAQAU     : THVdotVMAQA<"th.vmaqau",    0b100010>;
464bdd1243dSDimitry Andricdefm THVdotVMAQASU    : THVdotVMAQA<"th.vmaqasu",   0b100100>;
465bdd1243dSDimitry Andricdefm THVdotVMAQAUS    : THVdotVMAQA_VX<"th.vmaqaus",0b100110>;
466bdd1243dSDimitry Andric}
467bdd1243dSDimitry Andric
468bdd1243dSDimitry Andric// Associate LMUL with tablegen records of register classes.
469bdd1243dSDimitry Andricdef THVdotV_M1  : LMULInfo<0b000,  8,   VR, VR,   VR,   VR,   VR, "M1">;
470bdd1243dSDimitry Andricdef THVdotV_M2  : LMULInfo<0b001, 16, VRM2, VRM2, VR,   VR,   VR, "M2">;
471bdd1243dSDimitry Andricdef THVdotV_M4  : LMULInfo<0b010, 32, VRM4, VRM4, VRM2, VR,   VR, "M4">;
472bdd1243dSDimitry Andricdef THVdotV_M8  : LMULInfo<0b011, 64, VRM8, VRM8, VRM4, VRM2, VR, "M8">;
473bdd1243dSDimitry Andric
474bdd1243dSDimitry Andricdefvar MxListTHVdot = [V_MF2, THVdotV_M1, THVdotV_M2, THVdotV_M4, THVdotV_M8];
475bdd1243dSDimitry Andric
476bdd1243dSDimitry Andricdefset list<VTypeInfoToWide> AllQuadWidenableInt8NoVLMulVectors = {
477bdd1243dSDimitry Andric  def : VTypeInfoToWide<VI8MF2,  VI32MF2>;
478bdd1243dSDimitry Andric  def : VTypeInfoToWide<VI8M1,   VI32M1>;
479bdd1243dSDimitry Andric  def : VTypeInfoToWide<VI8M2,   VI32M2>;
480bdd1243dSDimitry Andric  def : VTypeInfoToWide<VI8M4,   VI32M4>;
481bdd1243dSDimitry Andric  def : VTypeInfoToWide<VI8M8,   VI32M8>;
482bdd1243dSDimitry Andric}
483bdd1243dSDimitry Andric
484bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
485bdd1243dSDimitry Andric// Combination of instruction classes.
486bdd1243dSDimitry Andric// Use these multiclasses to define instructions more easily.
487bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
4885f757f3fSDimitry Andric
489bdd1243dSDimitry Andricmulticlass VPseudoVMAQA_VV_VX {
490bdd1243dSDimitry Andric  foreach m = MxListTHVdot in {
4915f757f3fSDimitry Andric    // TODO: Add Sched
492bdd1243dSDimitry Andric    defm "" : VPseudoTernaryW_VV<m>;
493bdd1243dSDimitry Andric    defm "" : VPseudoTernaryW_VX<m>;
494bdd1243dSDimitry Andric  }
495bdd1243dSDimitry Andric}
496bdd1243dSDimitry Andric
497bdd1243dSDimitry Andricmulticlass VPseudoVMAQA_VX {
498bdd1243dSDimitry Andric  foreach m = MxListTHVdot in {
4995f757f3fSDimitry Andric    // TODO: Add Sched
500bdd1243dSDimitry Andric    defm "" : VPseudoTernaryW_VX<m>;
501bdd1243dSDimitry Andric  }
502bdd1243dSDimitry Andric}
503bdd1243dSDimitry Andric
504bdd1243dSDimitry Andricmulticlass VPatTernaryVMAQA_VV<string intrinsic, string instruction,
505bdd1243dSDimitry Andric                               list<VTypeInfoToWide> vtilist> {
506bdd1243dSDimitry Andric  foreach vtiToWti = vtilist in {
507bdd1243dSDimitry Andric    defvar vti = vtiToWti.Vti;
508bdd1243dSDimitry Andric    defvar wti = vtiToWti.Wti;
509bdd1243dSDimitry Andric    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV",
510bdd1243dSDimitry Andric                                 wti.Vector, vti.Vector, vti.Vector,
511bdd1243dSDimitry Andric                                 vti.Mask, wti.Log2SEW, vti.LMul,
512bdd1243dSDimitry Andric                                 wti.RegClass, vti.RegClass, vti.RegClass>;
513bdd1243dSDimitry Andric  }
514bdd1243dSDimitry Andric}
515bdd1243dSDimitry Andric
516bdd1243dSDimitry Andricmulticlass VPatTernaryVMAQA_VX<string intrinsic, string instruction,
517bdd1243dSDimitry Andric                               list<VTypeInfoToWide> vtilist> {
518bdd1243dSDimitry Andric  foreach vtiToWti = vtilist in {
519bdd1243dSDimitry Andric    defvar vti = vtiToWti.Vti;
520bdd1243dSDimitry Andric    defvar wti = vtiToWti.Wti;
521bdd1243dSDimitry Andric    defm : VPatTernaryWithPolicy<intrinsic, instruction,
522bdd1243dSDimitry Andric                                 "V"#vti.ScalarSuffix,
523bdd1243dSDimitry Andric                                 wti.Vector, vti.Scalar, vti.Vector,
524bdd1243dSDimitry Andric                                 vti.Mask, wti.Log2SEW, vti.LMul,
525bdd1243dSDimitry Andric                                 wti.RegClass, vti.ScalarRegClass, vti.RegClass>;
526bdd1243dSDimitry Andric  }
527bdd1243dSDimitry Andric}
528bdd1243dSDimitry Andric
529bdd1243dSDimitry Andricmulticlass VPatTernaryVMAQA_VV_VX<string intrinsic, string instruction,
530bdd1243dSDimitry Andric                                  list<VTypeInfoToWide> vtilist>
531bdd1243dSDimitry Andric    : VPatTernaryVMAQA_VV<intrinsic, instruction, vtilist>,
532bdd1243dSDimitry Andric      VPatTernaryVMAQA_VX<intrinsic, instruction, vtilist>;
533bdd1243dSDimitry Andric
534bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
535bdd1243dSDimitry Andric// Pseudo-instructions and codegen patterns
536bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
5375f757f3fSDimitry Andric
53806c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBa] in {
53906c3fb27SDimitry Andricdef : Pat<(add (XLenVT GPR:$rs1), (shl GPR:$rs2, uimm2:$uimm2)),
54006c3fb27SDimitry Andric          (TH_ADDSL GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
541*0fca6ea1SDimitry Andricdef : Pat<(XLenVT (riscv_shl_add GPR:$rs1, uimm2:$uimm2, GPR:$rs2)),
542*0fca6ea1SDimitry Andric          (TH_ADDSL GPR:$rs2, GPR:$rs1, uimm2:$uimm2)>;
54306c3fb27SDimitry Andric
54406c3fb27SDimitry Andric// Reuse complex patterns from StdExtZba
5455f757f3fSDimitry Andricdef : Pat<(add_non_imm12 sh1add_op:$rs1, (XLenVT GPR:$rs2)),
54606c3fb27SDimitry Andric          (TH_ADDSL GPR:$rs2, sh1add_op:$rs1, 1)>;
5475f757f3fSDimitry Andricdef : Pat<(add_non_imm12 sh2add_op:$rs1, (XLenVT GPR:$rs2)),
54806c3fb27SDimitry Andric          (TH_ADDSL GPR:$rs2, sh2add_op:$rs1, 2)>;
5495f757f3fSDimitry Andricdef : Pat<(add_non_imm12 sh3add_op:$rs1, (XLenVT GPR:$rs2)),
55006c3fb27SDimitry Andric          (TH_ADDSL GPR:$rs2, sh3add_op:$rs1, 3)>;
55106c3fb27SDimitry Andric
55206c3fb27SDimitry Andricdef : Pat<(add (XLenVT GPR:$r), CSImm12MulBy4:$i),
553*0fca6ea1SDimitry Andric          (TH_ADDSL GPR:$r, (XLenVT (ADDI (XLenVT X0), (SimmShiftRightBy2XForm CSImm12MulBy4:$i))), 2)>;
55406c3fb27SDimitry Andricdef : Pat<(add (XLenVT GPR:$r), CSImm12MulBy8:$i),
555*0fca6ea1SDimitry Andric          (TH_ADDSL GPR:$r, (XLenVT (ADDI (XLenVT X0), (SimmShiftRightBy3XForm CSImm12MulBy8:$i))), 3)>;
55606c3fb27SDimitry Andric
55706c3fb27SDimitry Andricdef : Pat<(mul_const_oneuse GPR:$r, (XLenVT 200)),
558*0fca6ea1SDimitry Andric          (SLLI (XLenVT (TH_ADDSL (XLenVT (TH_ADDSL GPR:$r, GPR:$r, 2)),
559*0fca6ea1SDimitry Andric                                  (XLenVT (TH_ADDSL GPR:$r, GPR:$r, 2)), 2)), 3)>;
56006c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBa]
56106c3fb27SDimitry Andric
56206c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBb] in {
56306c3fb27SDimitry Andricdef : PatGprImm<rotr, TH_SRRI, uimmlog2xlen>;
56406c3fb27SDimitry Andric// There's no encoding for a rotate-left-immediate in X-THead-Bb, as
56506c3fb27SDimitry Andric// it can be implemented with th.srri by negating the immediate.
56606c3fb27SDimitry Andricdef : Pat<(rotl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt),
56706c3fb27SDimitry Andric          (TH_SRRI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
56806c3fb27SDimitry Andricdef : Pat<(sext_inreg (XLenVT GPR:$rs1), i32), (TH_EXT GPR:$rs1, 31, 0)>;
56906c3fb27SDimitry Andricdef : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (TH_EXT GPR:$rs1, 15, 0)>;
57006c3fb27SDimitry Andricdef : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (TH_EXT GPR:$rs1, 7, 0)>;
57106c3fb27SDimitry Andricdef : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (TH_EXT GPR:$rs1, 0, 0)>;
57206c3fb27SDimitry Andricdef : PatGpr<ctlz, TH_FF1>;
57306c3fb27SDimitry Andricdef : Pat<(XLenVT (ctlz (xor (XLenVT GPR:$rs1), -1))), (TH_FF0 GPR:$rs1)>;
57406c3fb27SDimitry Andricdef : PatGpr<bswap, TH_REV>;
57506c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBb]
57606c3fb27SDimitry Andric
57706c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBb, IsRV64] in {
57806c3fb27SDimitry Andricdef : PatGprImm<riscv_rorw, TH_SRRIW, uimm5>;
57906c3fb27SDimitry Andricdef : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
58006c3fb27SDimitry Andric          (TH_SRRIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
58106c3fb27SDimitry Andricdef : Pat<(sra (bswap i64:$rs1), (i64 32)),
58206c3fb27SDimitry Andric          (TH_REVW i64:$rs1)>;
58306c3fb27SDimitry Andricdef : Pat<(binop_allwusers<srl> (bswap i64:$rs1), (i64 32)),
58406c3fb27SDimitry Andric          (TH_REVW i64:$rs1)>;
58506c3fb27SDimitry Andricdef : Pat<(riscv_clzw i64:$rs1),
586*0fca6ea1SDimitry Andric          (TH_FF0 (i64 (SLLI (i64 (XORI i64:$rs1, -1)), 32)))>;
58706c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBb, IsRV64]
58806c3fb27SDimitry Andric
58906c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadBs] in {
59006c3fb27SDimitry Andricdef : Pat<(and (srl (XLenVT GPR:$rs1), uimmlog2xlen:$shamt), 1),
59106c3fb27SDimitry Andric          (TH_TST GPR:$rs1, uimmlog2xlen:$shamt)>;
59206c3fb27SDimitry Andricdef : Pat<(XLenVT (seteq (and (XLenVT GPR:$rs1), SingleBitSetMask:$mask), 0)),
593*0fca6ea1SDimitry Andric          (TH_TST (XLenVT (XORI GPR:$rs1, -1)), SingleBitSetMask:$mask)>;
59406c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadBs]
59506c3fb27SDimitry Andric
59606c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadCondMov] in {
59706c3fb27SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT GPR:$b)),
59806c3fb27SDimitry Andric          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
59906c3fb27SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (XLenVT GPR:$a), (XLenVT 0)),
60006c3fb27SDimitry Andric          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
60106c3fb27SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (XLenVT 0), (XLenVT GPR:$b)),
60206c3fb27SDimitry Andric          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
60306c3fb27SDimitry Andric
60406c3fb27SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
60506c3fb27SDimitry Andric          (TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>;
60606c3fb27SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT GPR:$b)),
60706c3fb27SDimitry Andric          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
60806c3fb27SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
60906c3fb27SDimitry Andric          (TH_MVNEZ GPR:$a, (XLenVT X0), GPR:$cond)>;
61006c3fb27SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (XLenVT GPR:$a), (XLenVT 0)),
61106c3fb27SDimitry Andric          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
61206c3fb27SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (XLenVT 0), (XLenVT GPR:$b)),
61306c3fb27SDimitry Andric          (TH_MVEQZ GPR:$b, (XLenVT X0), GPR:$cond)>;
61406c3fb27SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)),  (XLenVT 0), (XLenVT GPR:$b)),
61506c3fb27SDimitry Andric          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
61606c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadCondMov]
61706c3fb27SDimitry Andric
61806c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac] in {
61906c3fb27SDimitry Andricdef : Pat<(add GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
62006c3fb27SDimitry Andric          (TH_MULA GPR:$rd, GPR:$rs1, GPR:$rs2)>;
62106c3fb27SDimitry Andricdef : Pat<(sub GPR:$rd, (mul (XLenVT GPR:$rs1), (XLenVT GPR:$rs2))),
62206c3fb27SDimitry Andric          (TH_MULS GPR:$rd, GPR:$rs1, GPR:$rs2)>;
62306c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadMac]
62406c3fb27SDimitry Andric
62506c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac, IsRV64] in {
62606c3fb27SDimitry Andric// mulaw, mulsw are available only in RV64.
62706c3fb27SDimitry Andricdef : Pat<(binop_allwusers<add> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
62806c3fb27SDimitry Andric          (TH_MULAW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
62906c3fb27SDimitry Andricdef : Pat<(binop_allwusers<sub> GPR:$rd, (mul GPR:$rs1, GPR:$rs2)),
63006c3fb27SDimitry Andric          (TH_MULSW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
63106c3fb27SDimitry Andric// mulah, mulsh produce a sign-extended result.
63206c3fb27SDimitry Andricdef : Pat<(binop_allwusers<add> GPR:$rd, (mul
63306c3fb27SDimitry Andric            (sexti16 (i64 GPR:$rs1)),
63406c3fb27SDimitry Andric            (sexti16 (i64 GPR:$rs2)))),
63506c3fb27SDimitry Andric          (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
63606c3fb27SDimitry Andricdef : Pat<(binop_allwusers<sub> GPR:$rd, (mul
63706c3fb27SDimitry Andric            (sexti16 (i64 GPR:$rs1)),
63806c3fb27SDimitry Andric            (sexti16 (i64 GPR:$rs2)))),
63906c3fb27SDimitry Andric          (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
64006c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadMac, IsRV64]
64106c3fb27SDimitry Andric
64206c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMac, IsRV32] in {
64306c3fb27SDimitry Andricdef : Pat<(i32 (add GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
64406c3fb27SDimitry Andric                                  (sexti16 (i32 GPR:$rs2))))),
64506c3fb27SDimitry Andric          (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
64606c3fb27SDimitry Andricdef : Pat<(i32 (sub GPR:$rd, (mul (sexti16 (i32 GPR:$rs1)),
64706c3fb27SDimitry Andric                                  (sexti16 (i32 GPR:$rs2))))),
64806c3fb27SDimitry Andric          (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
64906c3fb27SDimitry Andric} // Predicates = [HasVendorXTHeadMac, IsRV32]
65006c3fb27SDimitry Andric
651bdd1243dSDimitry Andricdefm PseudoTHVdotVMAQA      : VPseudoVMAQA_VV_VX;
652bdd1243dSDimitry Andricdefm PseudoTHVdotVMAQAU     : VPseudoVMAQA_VV_VX;
653bdd1243dSDimitry Andricdefm PseudoTHVdotVMAQASU    : VPseudoVMAQA_VV_VX;
654bdd1243dSDimitry Andricdefm PseudoTHVdotVMAQAUS    : VPseudoVMAQA_VX;
655bdd1243dSDimitry Andric
656bdd1243dSDimitry Andriclet Predicates = [HasVendorXTHeadVdot] in {
6575f757f3fSDimitry Andricdefm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqa",  "PseudoTHVdotVMAQA",
6585f757f3fSDimitry Andric                              AllQuadWidenableInt8NoVLMulVectors>;
6595f757f3fSDimitry Andricdefm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqau", "PseudoTHVdotVMAQAU",
6605f757f3fSDimitry Andric                              AllQuadWidenableInt8NoVLMulVectors>;
6615f757f3fSDimitry Andricdefm : VPatTernaryVMAQA_VV_VX<"int_riscv_th_vmaqasu","PseudoTHVdotVMAQASU",
6625f757f3fSDimitry Andric                              AllQuadWidenableInt8NoVLMulVectors>;
6635f757f3fSDimitry Andricdefm : VPatTernaryVMAQA_VX<"int_riscv_th_vmaqaus",   "PseudoTHVdotVMAQAUS",
6645f757f3fSDimitry Andric                           AllQuadWidenableInt8NoVLMulVectors>;
665bdd1243dSDimitry Andric}
66606c3fb27SDimitry Andric
66706c3fb27SDimitry Andricdef uimm2_3_XFORM : SDNodeXForm<imm, [{
66806c3fb27SDimitry Andric  return CurDAG->getTargetConstant((N->getZExtValue() >> 3) & 0x3,
66906c3fb27SDimitry Andric                                   SDLoc(N), Subtarget->getXLenVT());
67006c3fb27SDimitry Andric}]>;
67106c3fb27SDimitry Andric
67206c3fb27SDimitry Andricdef uimm2_3 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
67306c3fb27SDimitry Andric  return isShiftedUInt<2, 3>(Imm);
67406c3fb27SDimitry Andric}], uimm2_3_XFORM>;
67506c3fb27SDimitry Andric
67606c3fb27SDimitry Andricdef uimm2_4_XFORM : SDNodeXForm<imm, [{
67706c3fb27SDimitry Andric  return CurDAG->getTargetConstant((N->getZExtValue() >> 4) & 0x3,
67806c3fb27SDimitry Andric                                   SDLoc(N), Subtarget->getXLenVT());
67906c3fb27SDimitry Andric}]>;
68006c3fb27SDimitry Andric
68106c3fb27SDimitry Andricdef uimm2_4 : Operand<XLenVT>, ImmLeaf<XLenVT, [{
68206c3fb27SDimitry Andric  return isShiftedUInt<2, 4>(Imm);
68306c3fb27SDimitry Andric}], uimm2_4_XFORM>;
68406c3fb27SDimitry Andric
68506c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemPair, IsRV64] in {
68606c3fb27SDimitry Andricdef : Pat<(th_lwud i64:$rs1, uimm2_3:$uimm2_3), (TH_LWUD i64:$rs1, uimm2_3:$uimm2_3, 3)>;
68706c3fb27SDimitry Andricdef : Pat<(th_ldd i64:$rs1, uimm2_4:$uimm2_4), (TH_LDD i64:$rs1, uimm2_4:$uimm2_4, 4)>;
68806c3fb27SDimitry Andric
68906c3fb27SDimitry Andricdef : Pat<(th_sdd i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4),
69006c3fb27SDimitry Andric          (TH_SDD i64:$rd1, i64:$rd2, i64:$rs1, uimm2_4:$uimm2_4, 4)>;
69106c3fb27SDimitry Andric}
69206c3fb27SDimitry Andric
69306c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemPair] in {
69406c3fb27SDimitry Andric  def : Pat<(th_lwd GPR:$rs1, uimm2_3:$uimm2_3), (TH_LWD GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
69506c3fb27SDimitry Andric  def : Pat<(th_swd GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3),
69606c3fb27SDimitry Andric            (TH_SWD GPR:$rd1, GPR:$rd2, GPR:$rs1, uimm2_3:$uimm2_3, 3)>;
69706c3fb27SDimitry Andric}
69806c3fb27SDimitry Andric
6995f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadCmo], DecoderNamespace = "XTHeadCmo" in {
70006c3fb27SDimitry Andricdef TH_DCACHE_CSW    : THCacheInst_r<0b00001, "th.dcache.csw">;
70106c3fb27SDimitry Andricdef TH_DCACHE_ISW    : THCacheInst_r<0b00010, "th.dcache.isw">;
70206c3fb27SDimitry Andricdef TH_DCACHE_CISW   : THCacheInst_r<0b00011, "th.dcache.cisw">;
70306c3fb27SDimitry Andricdef TH_DCACHE_CVAL1  : THCacheInst_r<0b00100, "th.dcache.cval1">;
70406c3fb27SDimitry Andricdef TH_DCACHE_CVA    : THCacheInst_r<0b00101, "th.dcache.cva">;
70506c3fb27SDimitry Andricdef TH_DCACHE_IVA    : THCacheInst_r<0b00110, "th.dcache.iva">;
70606c3fb27SDimitry Andricdef TH_DCACHE_CIVA   : THCacheInst_r<0b00111, "th.dcache.civa">;
70706c3fb27SDimitry Andricdef TH_DCACHE_CPAL1  : THCacheInst_r<0b01000, "th.dcache.cpal1">;
70806c3fb27SDimitry Andricdef TH_DCACHE_CPA    : THCacheInst_r<0b01001, "th.dcache.cpa">;
70906c3fb27SDimitry Andricdef TH_DCACHE_IPA    : THCacheInst_r<0b01010, "th.dcache.ipa">;
71006c3fb27SDimitry Andricdef TH_DCACHE_CIPA   : THCacheInst_r<0b01011, "th.dcache.cipa">;
71106c3fb27SDimitry Andricdef TH_ICACHE_IVA    : THCacheInst_r<0b10000, "th.icache.iva">;
71206c3fb27SDimitry Andricdef TH_ICACHE_IPA    : THCacheInst_r<0b11000, "th.icache.ipa">;
71306c3fb27SDimitry Andric
71406c3fb27SDimitry Andricdef TH_DCACHE_CALL   : THCacheInst_void<0b00001, "th.dcache.call">;
71506c3fb27SDimitry Andricdef TH_DCACHE_IALL   : THCacheInst_void<0b00010, "th.dcache.iall">;
71606c3fb27SDimitry Andricdef TH_DCACHE_CIALL  : THCacheInst_void<0b00011, "th.dcache.ciall">;
71706c3fb27SDimitry Andricdef TH_ICACHE_IALL   : THCacheInst_void<0b10000, "th.icache.iall">;
71806c3fb27SDimitry Andricdef TH_ICACHE_IALLS  : THCacheInst_void<0b10001, "th.icache.ialls">;
71906c3fb27SDimitry Andricdef TH_L2CACHE_CALL  : THCacheInst_void<0b10101, "th.l2cache.call">;
72006c3fb27SDimitry Andricdef TH_L2CACHE_IALL  : THCacheInst_void<0b10110, "th.l2cache.iall">;
72106c3fb27SDimitry Andricdef TH_L2CACHE_CIALL : THCacheInst_void<0b10111, "th.l2cache.ciall">;
72206c3fb27SDimitry Andric}
72306c3fb27SDimitry Andric
7245f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadSync], DecoderNamespace = "XTHeadSync" in {
72506c3fb27SDimitry Andricdef TH_SFENCE_VMAS : THCacheInst_rr<0b0000010, "th.sfence.vmas">;
72606c3fb27SDimitry Andricdef TH_SYNC        : THCacheInst_void<0b11000, "th.sync">;
72706c3fb27SDimitry Andricdef TH_SYNC_S      : THCacheInst_void<0b11001, "th.sync.s">;
72806c3fb27SDimitry Andricdef TH_SYNC_I      : THCacheInst_void<0b11010, "th.sync.i">;
72906c3fb27SDimitry Andricdef TH_SYNC_IS     : THCacheInst_void<0b11011, "th.sync.is">;
73006c3fb27SDimitry Andric}
73106c3fb27SDimitry Andric
73206c3fb27SDimitry Andricdef AddrRegRegScale : ComplexPattern<iPTR, 3, "SelectAddrRegRegScale<3>">;
73306c3fb27SDimitry Andricdef AddrRegZextRegScale
73406c3fb27SDimitry Andric    : ComplexPattern<i64, 3, "SelectAddrRegZextRegScale<3, 32>",
73506c3fb27SDimitry Andric                     [], [], 10>;
73606c3fb27SDimitry Andric
73706c3fb27SDimitry Andricmulticlass LdIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
73806c3fb27SDimitry Andricdef : Pat<(vt (LoadOp (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2))),
73906c3fb27SDimitry Andric          (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
74006c3fb27SDimitry Andric}
74106c3fb27SDimitry Andric
74206c3fb27SDimitry Andricmulticlass LdZextIdxPat<PatFrag LoadOp, RVInst Inst, ValueType vt = i64> {
74306c3fb27SDimitry Andricdef : Pat<(vt (LoadOp (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2))),
74406c3fb27SDimitry Andric          (Inst GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
74506c3fb27SDimitry Andric}
74606c3fb27SDimitry Andric
74706c3fb27SDimitry Andricmulticlass StIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
74806c3fb27SDimitry Andric                    ValueType vt = XLenVT> {
74906c3fb27SDimitry Andricdef : Pat<(StoreOp (vt StTy:$rd),
75006c3fb27SDimitry Andric            (AddrRegRegScale (XLenVT GPR:$rs1), (XLenVT GPR:$rs2), uimm2:$uimm2)),
75106c3fb27SDimitry Andric          (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
75206c3fb27SDimitry Andric}
75306c3fb27SDimitry Andric
75406c3fb27SDimitry Andricmulticlass StZextIdxPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
75506c3fb27SDimitry Andric                        ValueType vt = i64> {
75606c3fb27SDimitry Andricdef : Pat<(StoreOp (vt StTy:$rd),
75706c3fb27SDimitry Andric            (AddrRegZextRegScale (i64 GPR:$rs1), (i64 GPR:$rs2), uimm2:$uimm2)),
75806c3fb27SDimitry Andric          (Inst StTy:$rd, GPR:$rs1, GPR:$rs2, uimm2:$uimm2)>;
75906c3fb27SDimitry Andric}
76006c3fb27SDimitry Andric
76106c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx] in {
76206c3fb27SDimitry Andricdefm : LdIdxPat<extloadi8, TH_LRB>;
76306c3fb27SDimitry Andricdefm : LdIdxPat<sextloadi8, TH_LRB>;
76406c3fb27SDimitry Andricdefm : LdIdxPat<zextloadi8, TH_LRBU>;
76506c3fb27SDimitry Andric
76606c3fb27SDimitry Andricdefm : LdIdxPat<extloadi16, TH_LRH>;
76706c3fb27SDimitry Andricdefm : LdIdxPat<sextloadi16, TH_LRH>;
76806c3fb27SDimitry Andricdefm : LdIdxPat<zextloadi16, TH_LRHU>;
76906c3fb27SDimitry Andric
77006c3fb27SDimitry Andricdefm : StIdxPat<truncstorei8, TH_SRB, GPR>;
77106c3fb27SDimitry Andricdefm : StIdxPat<truncstorei16, TH_SRH, GPR>;
77206c3fb27SDimitry Andric
77306c3fb27SDimitry Andricdefm : LdIdxPat<load, TH_LRW, i32>;
77406c3fb27SDimitry Andricdefm : StIdxPat<store, TH_SRW, GPR, i32>;
77506c3fb27SDimitry Andric}
77606c3fb27SDimitry Andric
77706c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
77806c3fb27SDimitry Andricdefm : LdZextIdxPat<extloadi8, TH_LURB>;
77906c3fb27SDimitry Andricdefm : LdZextIdxPat<sextloadi8, TH_LURB>;
78006c3fb27SDimitry Andricdefm : LdZextIdxPat<zextloadi8, TH_LURBU>;
78106c3fb27SDimitry Andric
78206c3fb27SDimitry Andricdefm : LdZextIdxPat<extloadi16, TH_LURH>;
78306c3fb27SDimitry Andricdefm : LdZextIdxPat<sextloadi16, TH_LURH>;
78406c3fb27SDimitry Andricdefm : LdZextIdxPat<zextloadi16, TH_LURHU>;
78506c3fb27SDimitry Andric
78606c3fb27SDimitry Andricdefm : LdIdxPat<extloadi32, TH_LRW, i64>;
78706c3fb27SDimitry Andricdefm : LdIdxPat<sextloadi32, TH_LRW, i64>;
78806c3fb27SDimitry Andricdefm : LdIdxPat<zextloadi32, TH_LRWU, i64>;
78906c3fb27SDimitry Andric
79006c3fb27SDimitry Andricdefm : LdZextIdxPat<extloadi32, TH_LURW>;
79106c3fb27SDimitry Andricdefm : LdZextIdxPat<sextloadi32, TH_LURW>;
79206c3fb27SDimitry Andricdefm : LdZextIdxPat<zextloadi32, TH_LURWU>;
79306c3fb27SDimitry Andric
79406c3fb27SDimitry Andricdefm : LdIdxPat<load, TH_LRD, i64>;
79506c3fb27SDimitry Andricdefm : LdZextIdxPat<load, TH_LURD>;
79606c3fb27SDimitry Andric
79706c3fb27SDimitry Andricdefm : StZextIdxPat<truncstorei8, TH_SURB, GPR>;
79806c3fb27SDimitry Andricdefm : StZextIdxPat<truncstorei16, TH_SURH, GPR>;
79906c3fb27SDimitry Andricdefm : StIdxPat<truncstorei32, TH_SRW, GPR, i64>;
80006c3fb27SDimitry Andricdefm : StZextIdxPat<truncstorei32, TH_SURW, GPR, i64>;
80106c3fb27SDimitry Andricdefm : StIdxPat<store, TH_SRD, GPR, i64>;
80206c3fb27SDimitry Andricdefm : StZextIdxPat<store, TH_SURD, GPR>;
80306c3fb27SDimitry Andric}
80406c3fb27SDimitry Andric
80506c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF] in {
80606c3fb27SDimitry Andricdefm : LdIdxPat<load, TH_FLRW, f32>;
80706c3fb27SDimitry Andricdefm : StIdxPat<store, TH_FSRW, FPR32, f32>;
80806c3fb27SDimitry Andric}
80906c3fb27SDimitry Andric
81006c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD] in {
81106c3fb27SDimitry Andricdefm : LdIdxPat<load, TH_FLRD, f64>;
81206c3fb27SDimitry Andricdefm : StIdxPat<store, TH_FSRD, FPR64, f64>;
81306c3fb27SDimitry Andric}
81406c3fb27SDimitry Andric
81506c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64] in {
81606c3fb27SDimitry Andricdefm : LdZextIdxPat<load, TH_FLURW, f32>;
81706c3fb27SDimitry Andricdefm : StZextIdxPat<store, TH_FSURW, FPR32, f32>;
81806c3fb27SDimitry Andric}
81906c3fb27SDimitry Andric
82006c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64] in {
82106c3fb27SDimitry Andricdefm : LdZextIdxPat<load, TH_FLURD, f64>;
82206c3fb27SDimitry Andricdefm : StZextIdxPat<store, TH_FSURD, FPR64, f64>;
82306c3fb27SDimitry Andric}
82406c3fb27SDimitry Andric
82506c3fb27SDimitry Andricdef simm5shl2 : ComplexPattern<XLenVT, 2, "selectSimm5Shl2">;
82606c3fb27SDimitry Andric
82706c3fb27SDimitry Andricmulticlass StoreUpdatePat<PatFrag st, Instruction Inst, ValueType vt = XLenVT> {
82806c3fb27SDimitry Andricdef : Pat<(st (vt GPR:$rd), GPR:$rs1, (simm5shl2 simm5:$simm5, uimm2:$uimm2)),
82906c3fb27SDimitry Andric          (Inst GPR:$rd, GPR:$rs1, simm5:$simm5, uimm2:$uimm2)>;
83006c3fb27SDimitry Andric}
83106c3fb27SDimitry Andric
83206c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx] in {
83306c3fb27SDimitry Andricdefm : StoreUpdatePat<post_truncsti8, TH_SBIA>;
83406c3fb27SDimitry Andricdefm : StoreUpdatePat<pre_truncsti8, TH_SBIB>;
83506c3fb27SDimitry Andricdefm : StoreUpdatePat<post_truncsti16, TH_SHIA>;
83606c3fb27SDimitry Andricdefm : StoreUpdatePat<pre_truncsti16, TH_SHIB>;
83706c3fb27SDimitry Andric
83806c3fb27SDimitry Andricdefm : StoreUpdatePat<post_store, TH_SWIA, i32>;
83906c3fb27SDimitry Andricdefm : StoreUpdatePat<pre_store, TH_SWIB, i32>;
84006c3fb27SDimitry Andric}
84106c3fb27SDimitry Andric
84206c3fb27SDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
84306c3fb27SDimitry Andricdefm : StoreUpdatePat<post_truncsti32, TH_SWIA, i64>;
84406c3fb27SDimitry Andricdefm : StoreUpdatePat<pre_truncsti32, TH_SWIB, i64>;
84506c3fb27SDimitry Andricdefm : StoreUpdatePat<post_store, TH_SDIA, i64>;
84606c3fb27SDimitry Andricdefm : StoreUpdatePat<pre_store, TH_SDIB, i64>;
84706c3fb27SDimitry Andric}
8485f757f3fSDimitry Andric
8495f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
8505f757f3fSDimitry Andric// Experimental RV64 i32 legalization patterns.
8515f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
8525f757f3fSDimitry Andric
8535f757f3fSDimitry Andriclet Predicates = [HasVendorXTHeadMemIdx, IsRV64] in {
8545f757f3fSDimitry Andricdefm : StoreUpdatePat<post_truncsti8, TH_SBIA, i32>;
8555f757f3fSDimitry Andricdefm : StoreUpdatePat<pre_truncsti8, TH_SBIB, i32>;
8565f757f3fSDimitry Andricdefm : StoreUpdatePat<post_truncsti16, TH_SHIA, i32>;
8575f757f3fSDimitry Andricdefm : StoreUpdatePat<pre_truncsti16, TH_SHIB, i32>;
858*0fca6ea1SDimitry Andric
859*0fca6ea1SDimitry Andricdefm : StIdxPat<truncstorei8, TH_SRB, GPR, i32>;
860*0fca6ea1SDimitry Andricdefm : StIdxPat<truncstorei16, TH_SRH, GPR, i32>;
861*0fca6ea1SDimitry Andric
862*0fca6ea1SDimitry Andricdefm : StZextIdxPat<truncstorei8, TH_SURB, GPR, i32>;
863*0fca6ea1SDimitry Andricdefm : StZextIdxPat<truncstorei16, TH_SURH, GPR, i32>;
864*0fca6ea1SDimitry Andricdefm : StZextIdxPat<store, TH_SURW, GPR, i32>;
8655f757f3fSDimitry Andric}
8665f757f3fSDimitry Andric
867*0fca6ea1SDimitry Andriclet Predicates = [HasVendorXTHeadCondMov, IsRV64] in {
868*0fca6ea1SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (i32 GPR:$a), (i32 GPR:$b)),
869*0fca6ea1SDimitry Andric          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
870*0fca6ea1SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (i32 GPR:$a), (i32 0)),
871*0fca6ea1SDimitry Andric          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
872*0fca6ea1SDimitry Andricdef : Pat<(select (XLenVT GPR:$cond), (i32 0), (i32 GPR:$b)),
873*0fca6ea1SDimitry Andric          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
874*0fca6ea1SDimitry Andric
875*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (i32 GPR:$a), (i32 GPR:$b)),
876*0fca6ea1SDimitry Andric          (TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>;
877*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (i32 GPR:$a), (i32 GPR:$b)),
878*0fca6ea1SDimitry Andric          (TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
879*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (i32 GPR:$a), (i32 0)),
880*0fca6ea1SDimitry Andric          (TH_MVNEZ GPR:$a, (XLenVT X0), GPR:$cond)>;
881*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)), (i32 GPR:$a), (i32 0)),
882*0fca6ea1SDimitry Andric          (TH_MVEQZ GPR:$a, (XLenVT X0), GPR:$cond)>;
883*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_seteq (XLenVT GPR:$cond)), (i32 0), (i32 GPR:$b)),
884*0fca6ea1SDimitry Andric          (TH_MVEQZ GPR:$b, (XLenVT X0), GPR:$cond)>;
885*0fca6ea1SDimitry Andricdef : Pat<(select (riscv_setne (XLenVT GPR:$cond)),  (i32 0), (i32 GPR:$b)),
886*0fca6ea1SDimitry Andric          (TH_MVNEZ GPR:$b, (XLenVT X0), GPR:$cond)>;
887*0fca6ea1SDimitry Andric} // Predicates = [HasVendorXTHeadCondMov]
888*0fca6ea1SDimitry Andric
889*0fca6ea1SDimitry Andriclet Predicates = [HasVendorXTHeadMac, IsRV64] in {
890*0fca6ea1SDimitry Andric// mulaw, mulsw are available only in RV64.
891*0fca6ea1SDimitry Andricdef : Pat<(i32 (add GPR:$rd, (mul GPR:$rs1, GPR:$rs2))),
892*0fca6ea1SDimitry Andric          (TH_MULAW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
893*0fca6ea1SDimitry Andricdef : Pat<(i32 (sub GPR:$rd, (mul GPR:$rs1, GPR:$rs2))),
894*0fca6ea1SDimitry Andric          (TH_MULSW GPR:$rd, GPR:$rs1, GPR:$rs2)>;
895*0fca6ea1SDimitry Andric// mulah, mulsh produce a sign-extended result.
896*0fca6ea1SDimitry Andricdef : Pat<(i32 (add GPR:$rd,
897*0fca6ea1SDimitry Andric                    (mul (sexti16i32 (i32 GPR:$rs1)),
898*0fca6ea1SDimitry Andric                         (sexti16i32 (i32 GPR:$rs2))))),
899*0fca6ea1SDimitry Andric          (TH_MULAH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
900*0fca6ea1SDimitry Andricdef : Pat<(i32 (sub GPR:$rd,
901*0fca6ea1SDimitry Andric                    (mul (sexti16i32 (i32 GPR:$rs1)),
902*0fca6ea1SDimitry Andric                         (sexti16i32 (i32 GPR:$rs2))))),
903*0fca6ea1SDimitry Andric          (TH_MULSH GPR:$rd, GPR:$rs1, GPR:$rs2)>;
904*0fca6ea1SDimitry Andric}
905