xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td (revision 6e516c87b6d779911edde7481d8aef165b837a03)
181ad6265SDimitry Andric//== LoongArchInstrInfo.td - Target Description for LoongArch -*- tablegen -*-//
281ad6265SDimitry Andric//
381ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric//
781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
881ad6265SDimitry Andric//
981ad6265SDimitry Andric// This file describes the LoongArch instructions in TableGen format.
1081ad6265SDimitry Andric//
1181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1281ad6265SDimitry Andric
1381ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1481ad6265SDimitry Andric// LoongArch specific DAG Nodes.
1581ad6265SDimitry Andric//===----------------------------------------------------------------------===//
1681ad6265SDimitry Andric
17753f127fSDimitry Andric// Target-independent type requirements, but with target-specific formats.
18753f127fSDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
19753f127fSDimitry Andric                                       SDTCisVT<1, i32>]>;
20753f127fSDimitry Andricdef SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>,
21753f127fSDimitry Andric                                   SDTCisVT<1, i32>]>;
22753f127fSDimitry Andric
2381ad6265SDimitry Andric// Target-dependent type requirements.
24753f127fSDimitry Andricdef SDT_LoongArchCall : SDTypeProfile<0, -1, [SDTCisVT<0, GRLenVT>]>;
2581ad6265SDimitry Andricdef SDT_LoongArchIntBinOpW : SDTypeProfile<1, 2, [
2681ad6265SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>
2781ad6265SDimitry Andric]>;
2881ad6265SDimitry Andric
29753f127fSDimitry Andricdef SDT_LoongArchBStrIns: SDTypeProfile<1, 4, [
30753f127fSDimitry Andric  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<3>,
31753f127fSDimitry Andric  SDTCisSameAs<3, 4>
32753f127fSDimitry Andric]>;
33753f127fSDimitry Andric
3481ad6265SDimitry Andricdef SDT_LoongArchBStrPick: SDTypeProfile<1, 3, [
3581ad6265SDimitry Andric  SDTCisInt<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisSameAs<2, 3>
3681ad6265SDimitry Andric]>;
3781ad6265SDimitry Andric
38bdd1243dSDimitry Andric// "VI" means no output and an integer input.
39bdd1243dSDimitry Andricdef SDT_LoongArchVI : SDTypeProfile<0, 1, [SDTCisVT<0, GRLenVT>]>;
40bdd1243dSDimitry Andric
41bdd1243dSDimitry Andricdef SDT_LoongArchCsrrd : SDTypeProfile<1, 1, [SDTCisInt<0>,
42bdd1243dSDimitry Andric                                              SDTCisVT<1, GRLenVT>]>;
43bdd1243dSDimitry Andricdef SDT_LoongArchCsrwr : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>,
44bdd1243dSDimitry Andric                                              SDTCisVT<2, GRLenVT>]>;
45bdd1243dSDimitry Andricdef SDT_LoongArchCsrxchg : SDTypeProfile<1, 3, [SDTCisInt<0>,
46bdd1243dSDimitry Andric                                                SDTCisSameAs<0, 1>,
47bdd1243dSDimitry Andric                                                SDTCisSameAs<0, 2>,
48bdd1243dSDimitry Andric                                                SDTCisVT<3, GRLenVT>]>;
49bdd1243dSDimitry Andricdef SDT_LoongArchIocsrwr : SDTypeProfile<0, 2, [SDTCisInt<0>,
50bdd1243dSDimitry Andric                                                SDTCisSameAs<0, 1>]>;
51bdd1243dSDimitry Andricdef SDT_LoongArchMovgr2fcsr : SDTypeProfile<0, 2, [SDTCisVT<0, GRLenVT>,
52bdd1243dSDimitry Andric                                                   SDTCisSameAs<0, 1>]>;
53bdd1243dSDimitry Andricdef SDT_LoongArchMovfcsr2gr : SDTypeProfile<1, 1, [SDTCisVT<0, GRLenVT>,
54bdd1243dSDimitry Andric                                                   SDTCisSameAs<0, 1>]>;
55bdd1243dSDimitry Andric
5681ad6265SDimitry Andric// TODO: Add LoongArch specific DAG Nodes
57753f127fSDimitry Andric// Target-independent nodes, but with target-specific formats.
58753f127fSDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
59753f127fSDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
60753f127fSDimitry Andricdef callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
61753f127fSDimitry Andric                         [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
62753f127fSDimitry Andric
6381ad6265SDimitry Andric// Target-dependent nodes.
64753f127fSDimitry Andricdef loongarch_call : SDNode<"LoongArchISD::CALL", SDT_LoongArchCall,
65753f127fSDimitry Andric                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
66753f127fSDimitry Andric                             SDNPVariadic]>;
6781ad6265SDimitry Andricdef loongarch_ret : SDNode<"LoongArchISD::RET", SDTNone,
6881ad6265SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
69bdd1243dSDimitry Andricdef loongarch_tail : SDNode<"LoongArchISD::TAIL", SDT_LoongArchCall,
70bdd1243dSDimitry Andric                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
71bdd1243dSDimitry Andric                             SDNPVariadic]>;
721db9f3b2SDimitry Andricdef loongarch_call_medium : SDNode<"LoongArchISD::CALL_MEDIUM", SDT_LoongArchCall,
731db9f3b2SDimitry Andric                                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
741db9f3b2SDimitry Andric                                    SDNPVariadic]>;
751db9f3b2SDimitry Andricdef loongarch_tail_medium : SDNode<"LoongArchISD::TAIL_MEDIUM", SDT_LoongArchCall,
761db9f3b2SDimitry Andric                                   [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
771db9f3b2SDimitry Andric                                    SDNPVariadic]>;
781db9f3b2SDimitry Andricdef loongarch_call_large : SDNode<"LoongArchISD::CALL_LARGE", SDT_LoongArchCall,
791db9f3b2SDimitry Andric                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
801db9f3b2SDimitry Andric                                   SDNPVariadic]>;
811db9f3b2SDimitry Andricdef loongarch_tail_large : SDNode<"LoongArchISD::TAIL_LARGE", SDT_LoongArchCall,
821db9f3b2SDimitry Andric                                  [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
831db9f3b2SDimitry Andric                                   SDNPVariadic]>;
8481ad6265SDimitry Andricdef loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>;
8581ad6265SDimitry Andricdef loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>;
8681ad6265SDimitry Andricdef loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>;
87bdd1243dSDimitry Andricdef loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>;
880fca6ea1SDimitry Andricdef loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>;
890fca6ea1SDimitry Andricdef loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>;
90bdd1243dSDimitry Andricdef loongarch_crc_w_b_w
9106c3fb27SDimitry Andric    : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
92bdd1243dSDimitry Andricdef loongarch_crc_w_h_w
9306c3fb27SDimitry Andric    : SDNode<"LoongArchISD::CRC_W_H_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
94bdd1243dSDimitry Andricdef loongarch_crc_w_w_w
9506c3fb27SDimitry Andric    : SDNode<"LoongArchISD::CRC_W_W_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
96bdd1243dSDimitry Andricdef loongarch_crc_w_d_w
9706c3fb27SDimitry Andric    : SDNode<"LoongArchISD::CRC_W_D_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
9806c3fb27SDimitry Andricdef loongarch_crcc_w_b_w : SDNode<"LoongArchISD::CRCC_W_B_W",
9906c3fb27SDimitry Andric                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
10006c3fb27SDimitry Andricdef loongarch_crcc_w_h_w : SDNode<"LoongArchISD::CRCC_W_H_W",
10106c3fb27SDimitry Andric                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
10206c3fb27SDimitry Andricdef loongarch_crcc_w_w_w : SDNode<"LoongArchISD::CRCC_W_W_W",
10306c3fb27SDimitry Andric                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
10406c3fb27SDimitry Andricdef loongarch_crcc_w_d_w : SDNode<"LoongArchISD::CRCC_W_D_W",
10506c3fb27SDimitry Andric                                  SDT_LoongArchIntBinOpW, [SDNPHasChain]>;
106753f127fSDimitry Andricdef loongarch_bstrins
107753f127fSDimitry Andric    : SDNode<"LoongArchISD::BSTRINS", SDT_LoongArchBStrIns>;
10881ad6265SDimitry Andricdef loongarch_bstrpick
10981ad6265SDimitry Andric    : SDNode<"LoongArchISD::BSTRPICK", SDT_LoongArchBStrPick>;
110bdd1243dSDimitry Andricdef loongarch_revb_2h : SDNode<"LoongArchISD::REVB_2H", SDTUnaryOp>;
111bdd1243dSDimitry Andricdef loongarch_revb_2w : SDNode<"LoongArchISD::REVB_2W", SDTUnaryOp>;
112bdd1243dSDimitry Andricdef loongarch_bitrev_4b : SDNode<"LoongArchISD::BITREV_4B", SDTUnaryOp>;
113bdd1243dSDimitry Andricdef loongarch_bitrev_w : SDNode<"LoongArchISD::BITREV_W", SDTUnaryOp>;
114bdd1243dSDimitry Andricdef loongarch_clzw : SDNode<"LoongArchISD::CLZ_W", SDTIntBitCountUnaryOp>;
115bdd1243dSDimitry Andricdef loongarch_ctzw : SDNode<"LoongArchISD::CTZ_W", SDTIntBitCountUnaryOp>;
116bdd1243dSDimitry Andricdef loongarch_dbar : SDNode<"LoongArchISD::DBAR", SDT_LoongArchVI,
117bdd1243dSDimitry Andric                             [SDNPHasChain, SDNPSideEffect]>;
118bdd1243dSDimitry Andricdef loongarch_ibar : SDNode<"LoongArchISD::IBAR", SDT_LoongArchVI,
119bdd1243dSDimitry Andric                             [SDNPHasChain, SDNPSideEffect]>;
120bdd1243dSDimitry Andricdef loongarch_break : SDNode<"LoongArchISD::BREAK", SDT_LoongArchVI,
121bdd1243dSDimitry Andric                              [SDNPHasChain, SDNPSideEffect]>;
12206c3fb27SDimitry Andricdef loongarch_movfcsr2gr : SDNode<"LoongArchISD::MOVFCSR2GR",
12306c3fb27SDimitry Andric                                  SDT_LoongArchMovfcsr2gr, [SDNPHasChain]>;
12406c3fb27SDimitry Andricdef loongarch_movgr2fcsr : SDNode<"LoongArchISD::MOVGR2FCSR",
12506c3fb27SDimitry Andric                                  SDT_LoongArchMovgr2fcsr,
126bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
127bdd1243dSDimitry Andricdef loongarch_syscall : SDNode<"LoongArchISD::SYSCALL", SDT_LoongArchVI,
128bdd1243dSDimitry Andric                                [SDNPHasChain, SDNPSideEffect]>;
129bdd1243dSDimitry Andricdef loongarch_csrrd : SDNode<"LoongArchISD::CSRRD", SDT_LoongArchCsrrd,
130bdd1243dSDimitry Andric                              [SDNPHasChain, SDNPSideEffect]>;
131bdd1243dSDimitry Andricdef loongarch_csrwr : SDNode<"LoongArchISD::CSRWR", SDT_LoongArchCsrwr,
132bdd1243dSDimitry Andric                              [SDNPHasChain, SDNPSideEffect]>;
133bdd1243dSDimitry Andricdef loongarch_csrxchg : SDNode<"LoongArchISD::CSRXCHG",
134bdd1243dSDimitry Andric                                SDT_LoongArchCsrxchg,
135bdd1243dSDimitry Andric                                [SDNPHasChain, SDNPSideEffect]>;
136bdd1243dSDimitry Andricdef loongarch_iocsrrd_b : SDNode<"LoongArchISD::IOCSRRD_B", SDTUnaryOp,
137bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
138bdd1243dSDimitry Andricdef loongarch_iocsrrd_h : SDNode<"LoongArchISD::IOCSRRD_H", SDTUnaryOp,
139bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
140bdd1243dSDimitry Andricdef loongarch_iocsrrd_w : SDNode<"LoongArchISD::IOCSRRD_W", SDTUnaryOp,
141bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
142bdd1243dSDimitry Andricdef loongarch_iocsrrd_d : SDNode<"LoongArchISD::IOCSRRD_D", SDTUnaryOp,
143bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
144bdd1243dSDimitry Andricdef loongarch_iocsrwr_b : SDNode<"LoongArchISD::IOCSRWR_B",
145bdd1243dSDimitry Andric                                  SDT_LoongArchIocsrwr,
146bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
147bdd1243dSDimitry Andricdef loongarch_iocsrwr_h : SDNode<"LoongArchISD::IOCSRWR_H",
148bdd1243dSDimitry Andric                                  SDT_LoongArchIocsrwr,
149bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
150bdd1243dSDimitry Andricdef loongarch_iocsrwr_w : SDNode<"LoongArchISD::IOCSRWR_W",
151bdd1243dSDimitry Andric                                  SDT_LoongArchIocsrwr,
152bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
153bdd1243dSDimitry Andricdef loongarch_iocsrwr_d : SDNode<"LoongArchISD::IOCSRWR_D",
154bdd1243dSDimitry Andric                                  SDT_LoongArchIocsrwr,
155bdd1243dSDimitry Andric                                  [SDNPHasChain, SDNPSideEffect]>;
156bdd1243dSDimitry Andricdef loongarch_cpucfg : SDNode<"LoongArchISD::CPUCFG", SDTUnaryOp,
15706c3fb27SDimitry Andric                               [SDNPHasChain]>;
15881ad6265SDimitry Andric
1595f757f3fSDimitry Andricdef to_fclass_mask: SDNodeXForm<timm, [{
1605f757f3fSDimitry Andric  uint64_t Check = N->getZExtValue();
1615f757f3fSDimitry Andric  unsigned Mask = 0;
1625f757f3fSDimitry Andric  if (Check & fcSNan)
1635f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskSignalingNaN;
1645f757f3fSDimitry Andric  if (Check & fcQNan)
1655f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskQuietNaN;
1665f757f3fSDimitry Andric  if (Check & fcPosInf)
1675f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskPositiveInfinity;
1685f757f3fSDimitry Andric  if (Check & fcNegInf)
1695f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskNegativeInfinity;
1705f757f3fSDimitry Andric  if (Check & fcPosNormal)
1715f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskPositiveNormal;
1725f757f3fSDimitry Andric  if (Check & fcNegNormal)
1735f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskNegativeNormal;
1745f757f3fSDimitry Andric  if (Check & fcPosSubnormal)
1755f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskPositiveSubnormal;
1765f757f3fSDimitry Andric  if (Check & fcNegSubnormal)
1775f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskNegativeSubnormal;
1785f757f3fSDimitry Andric  if (Check & fcPosZero)
1795f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskPositiveZero;
1805f757f3fSDimitry Andric  if (Check & fcNegZero)
1815f757f3fSDimitry Andric    Mask |= LoongArch::FClassMaskNegativeZero;
1825f757f3fSDimitry Andric  return CurDAG->getTargetConstant(Mask, SDLoc(N), Subtarget->getGRLenVT());
1835f757f3fSDimitry Andric}]>;
1845f757f3fSDimitry Andric
18581ad6265SDimitry Andric//===----------------------------------------------------------------------===//
18681ad6265SDimitry Andric// Operand and SDNode transformation definitions.
18781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
18881ad6265SDimitry Andric
18981ad6265SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix>
19081ad6265SDimitry Andric    : AsmOperandClass {
19181ad6265SDimitry Andric  let Name = prefix # "Imm" # width # suffix;
19281ad6265SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
19381ad6265SDimitry Andric  let RenderMethod = "addImmOperands";
19481ad6265SDimitry Andric}
19581ad6265SDimitry Andric
19681ad6265SDimitry Andricclass SImmAsmOperand<int width, string suffix = "">
19781ad6265SDimitry Andric    : ImmAsmOperand<"S", width, suffix> {
19881ad6265SDimitry Andric}
19981ad6265SDimitry Andric
20081ad6265SDimitry Andricclass UImmAsmOperand<int width, string suffix = "">
20181ad6265SDimitry Andric    : ImmAsmOperand<"U", width, suffix> {
20281ad6265SDimitry Andric}
20381ad6265SDimitry Andric
204bdd1243dSDimitry Andric// A parse method for "$r*" or "$r*, 0", where the 0 is be silently ignored.
205bdd1243dSDimitry Andric// Only used for "AM*" instructions, in order to be compatible with GAS.
206bdd1243dSDimitry Andricdef AtomicMemAsmOperand : AsmOperandClass {
207bdd1243dSDimitry Andric  let Name = "AtomicMemAsmOperand";
208bdd1243dSDimitry Andric  let RenderMethod = "addRegOperands";
209bdd1243dSDimitry Andric  let PredicateMethod = "isGPR";
210bdd1243dSDimitry Andric  let ParserMethod = "parseAtomicMemOp";
211bdd1243dSDimitry Andric}
212bdd1243dSDimitry Andric
213bdd1243dSDimitry Andricdef GPRMemAtomic : RegisterOperand<GPR> {
214bdd1243dSDimitry Andric  let ParserMatchClass = AtomicMemAsmOperand;
215bdd1243dSDimitry Andric  let PrintMethod = "printAtomicMemOp";
216bdd1243dSDimitry Andric}
217bdd1243dSDimitry Andric
218bdd1243dSDimitry Andric// A parameterized register class alternative to i32imm/i64imm from Target.td.
219bdd1243dSDimitry Andricdef grlenimm : Operand<GRLenVT>;
220bdd1243dSDimitry Andricdef imm32 : Operand<GRLenVT> {
221bdd1243dSDimitry Andric  let ParserMatchClass = ImmAsmOperand<"", 32, "">;
222bdd1243dSDimitry Andric}
2230fca6ea1SDimitry Andricdef imm64 : Operand<i64> {
2240fca6ea1SDimitry Andric  let ParserMatchClass = ImmAsmOperand<"", 64, "">;
2250fca6ea1SDimitry Andric}
226bdd1243dSDimitry Andric
2275f757f3fSDimitry Andricdef uimm1 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<1>(Imm);}]>{
22806c3fb27SDimitry Andric  let ParserMatchClass = UImmAsmOperand<1>;
22906c3fb27SDimitry Andric}
23006c3fb27SDimitry Andric
231bdd1243dSDimitry Andricdef uimm2 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<2>(Imm);}]> {
23281ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<2>;
23381ad6265SDimitry Andric}
23481ad6265SDimitry Andric
235bdd1243dSDimitry Andricdef uimm2_plus1 : Operand<GRLenVT>,
236bdd1243dSDimitry Andric    ImmLeaf<GRLenVT, [{return isUInt<2>(Imm - 1);}]> {
23781ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<2, "plus1">;
23881ad6265SDimitry Andric  let EncoderMethod = "getImmOpValueSub1";
23981ad6265SDimitry Andric  let DecoderMethod = "decodeUImmOperand<2, 1>";
24081ad6265SDimitry Andric}
24181ad6265SDimitry Andric
2425f757f3fSDimitry Andricdef uimm3 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<3>(Imm);}]> {
24381ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<3>;
24481ad6265SDimitry Andric}
24581ad6265SDimitry Andric
2465f757f3fSDimitry Andricdef uimm4 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<4>(Imm);}]> {
24706c3fb27SDimitry Andric  let ParserMatchClass = UImmAsmOperand<4>;
24806c3fb27SDimitry Andric}
24906c3fb27SDimitry Andric
25081ad6265SDimitry Andricdef uimm5 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<5>(Imm);}]> {
25181ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<5>;
25281ad6265SDimitry Andric}
25381ad6265SDimitry Andric
25481ad6265SDimitry Andricdef uimm6 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<6>(Imm);}]> {
25581ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<6>;
25681ad6265SDimitry Andric}
25781ad6265SDimitry Andric
25806c3fb27SDimitry Andricdef uimm7 : Operand<GRLenVT> {
25906c3fb27SDimitry Andric  let ParserMatchClass = UImmAsmOperand<7>;
26006c3fb27SDimitry Andric}
26106c3fb27SDimitry Andric
262bdd1243dSDimitry Andricdef uimm8 : Operand<GRLenVT>, ImmLeaf<GRLenVT, [{return isUInt<8>(Imm);}]> {
26381ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<8>;
26481ad6265SDimitry Andric}
26581ad6265SDimitry Andric
266bdd1243dSDimitry Andricclass UImm12Operand : Operand<GRLenVT>,
267bdd1243dSDimitry Andric                      ImmLeaf <GRLenVT, [{return isUInt<12>(Imm);}]> {
268bdd1243dSDimitry Andric  let DecoderMethod = "decodeUImmOperand<12>";
269bdd1243dSDimitry Andric}
270bdd1243dSDimitry Andric
271bdd1243dSDimitry Andricdef uimm12 : UImm12Operand {
27281ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<12>;
27381ad6265SDimitry Andric}
27481ad6265SDimitry Andric
275bdd1243dSDimitry Andricdef uimm12_ori : UImm12Operand {
276bdd1243dSDimitry Andric  let ParserMatchClass = UImmAsmOperand<12, "ori">;
277bdd1243dSDimitry Andric}
278bdd1243dSDimitry Andric
279bdd1243dSDimitry Andricdef uimm14 : Operand<GRLenVT>,
280bdd1243dSDimitry Andric             ImmLeaf <GRLenVT, [{return isUInt<14>(Imm);}]> {
28181ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<14>;
28281ad6265SDimitry Andric}
28381ad6265SDimitry Andric
284bdd1243dSDimitry Andricdef uimm15 : Operand<GRLenVT>,
285bdd1243dSDimitry Andric             ImmLeaf <GRLenVT, [{return isUInt<15>(Imm);}]> {
28681ad6265SDimitry Andric  let ParserMatchClass = UImmAsmOperand<15>;
28781ad6265SDimitry Andric}
28881ad6265SDimitry Andric
28906c3fb27SDimitry Andricdef simm5 : Operand<GRLenVT> {
29006c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<5>;
29106c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<5>";
29206c3fb27SDimitry Andric}
29306c3fb27SDimitry Andric
29406c3fb27SDimitry Andricdef simm8 : Operand<GRLenVT> {
29506c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<8>;
29606c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<8>";
29706c3fb27SDimitry Andric}
29806c3fb27SDimitry Andric
29906c3fb27SDimitry Andricforeach I = [1, 2, 3] in {
30006c3fb27SDimitry Andricdef simm8_lsl # I : Operand<GRLenVT> {
30106c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<8, "lsl" # I>;
30206c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<" # I # ">";
30306c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<8," # I # ">";
30406c3fb27SDimitry Andric}
30506c3fb27SDimitry Andric}
30606c3fb27SDimitry Andric
30706c3fb27SDimitry Andricdef simm9_lsl3 : Operand<GRLenVT> {
30806c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<9, "lsl3">;
30906c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<3>";
31006c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<9, 3>";
31106c3fb27SDimitry Andric}
31206c3fb27SDimitry Andric
31306c3fb27SDimitry Andricdef simm10 : Operand<GRLenVT> {
31406c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<10>;
31506c3fb27SDimitry Andric}
31606c3fb27SDimitry Andric
31706c3fb27SDimitry Andricdef simm10_lsl2 : Operand<GRLenVT> {
31806c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<10, "lsl2">;
31906c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
32006c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<10, 2>";
32106c3fb27SDimitry Andric}
32206c3fb27SDimitry Andric
32306c3fb27SDimitry Andricdef simm11_lsl1 : Operand<GRLenVT> {
32406c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<11, "lsl1">;
32506c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<1>";
32606c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<11, 1>";
32706c3fb27SDimitry Andric}
32806c3fb27SDimitry Andric
329bdd1243dSDimitry Andricclass SImm12Operand : Operand<GRLenVT>,
330bdd1243dSDimitry Andric                      ImmLeaf <GRLenVT, [{return isInt<12>(Imm);}]> {
33181ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<12>";
33281ad6265SDimitry Andric}
33381ad6265SDimitry Andric
334bdd1243dSDimitry Andricdef simm12 : SImm12Operand {
335bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<12>;
336bdd1243dSDimitry Andric}
337bdd1243dSDimitry Andric
338bdd1243dSDimitry Andricdef simm12_addlike : SImm12Operand {
339bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<12, "addlike">;
340bdd1243dSDimitry Andric}
341bdd1243dSDimitry Andric
342bdd1243dSDimitry Andricdef simm12_lu52id : SImm12Operand {
343bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<12, "lu52id">;
344bdd1243dSDimitry Andric}
345bdd1243dSDimitry Andric
34606c3fb27SDimitry Andricdef simm13 : Operand<GRLenVT> {
34706c3fb27SDimitry Andric  let ParserMatchClass = SImmAsmOperand<13>;
34806c3fb27SDimitry Andric  let DecoderMethod = "decodeSImmOperand<13>";
34906c3fb27SDimitry Andric}
35006c3fb27SDimitry Andric
351bdd1243dSDimitry Andricdef simm14_lsl2 : Operand<GRLenVT>,
352bdd1243dSDimitry Andric    ImmLeaf<GRLenVT, [{return isShiftedInt<14,2>(Imm);}]> {
35381ad6265SDimitry Andric  let ParserMatchClass = SImmAsmOperand<14, "lsl2">;
35406c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
35581ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<14, 2>";
35681ad6265SDimitry Andric}
35781ad6265SDimitry Andric
35881ad6265SDimitry Andricdef simm16 : Operand<GRLenVT> {
35981ad6265SDimitry Andric  let ParserMatchClass = SImmAsmOperand<16>;
36081ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<16>";
36181ad6265SDimitry Andric}
36281ad6265SDimitry Andric
363753f127fSDimitry Andricdef simm16_lsl2 : Operand<GRLenVT>,
364753f127fSDimitry Andric    ImmLeaf<GRLenVT, [{return isInt<16>(Imm>>2);}]> {
365753f127fSDimitry Andric  let ParserMatchClass = SImmAsmOperand<16, "lsl2">;
36606c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
367753f127fSDimitry Andric  let DecoderMethod = "decodeSImmOperand<16, 2>";
368753f127fSDimitry Andric}
369753f127fSDimitry Andric
370753f127fSDimitry Andricdef simm16_lsl2_br : Operand<OtherVT> {
37181ad6265SDimitry Andric  let ParserMatchClass = SImmAsmOperand<16, "lsl2">;
37206c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
37381ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<16, 2>";
37481ad6265SDimitry Andric}
37581ad6265SDimitry Andric
376bdd1243dSDimitry Andricclass SImm20Operand : Operand<GRLenVT> {
37781ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<20>";
37881ad6265SDimitry Andric}
37981ad6265SDimitry Andric
380bdd1243dSDimitry Andricdef simm20 : SImm20Operand {
381bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<20>;
382bdd1243dSDimitry Andric}
383bdd1243dSDimitry Andric
384bdd1243dSDimitry Andricdef simm20_pcalau12i : SImm20Operand {
385bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<20, "pcalau12i">;
386bdd1243dSDimitry Andric}
387bdd1243dSDimitry Andric
388bdd1243dSDimitry Andricdef simm20_lu12iw : SImm20Operand {
389bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<20, "lu12iw">;
390bdd1243dSDimitry Andric}
391bdd1243dSDimitry Andric
392bdd1243dSDimitry Andricdef simm20_lu32id : SImm20Operand {
393bdd1243dSDimitry Andric  let ParserMatchClass = SImmAsmOperand<20, "lu32id">;
394bdd1243dSDimitry Andric}
395bdd1243dSDimitry Andric
3961db9f3b2SDimitry Andricdef simm20_pcaddu18i : SImm20Operand {
3971db9f3b2SDimitry Andric  let ParserMatchClass = SImmAsmOperand<20, "pcaddu18i">;
3981db9f3b2SDimitry Andric}
3991db9f3b2SDimitry Andric
40052418fc2SDimitry Andricdef simm20_pcaddi : SImm20Operand {
40152418fc2SDimitry Andric  let ParserMatchClass = SImmAsmOperand<20, "pcaddi">;
40252418fc2SDimitry Andric}
40352418fc2SDimitry Andric
404753f127fSDimitry Andricdef simm21_lsl2 : Operand<OtherVT> {
40581ad6265SDimitry Andric  let ParserMatchClass = SImmAsmOperand<21, "lsl2">;
40606c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
40781ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<21, 2>";
40881ad6265SDimitry Andric}
40981ad6265SDimitry Andric
410bdd1243dSDimitry Andricdef SImm26OperandB: AsmOperandClass {
411bdd1243dSDimitry Andric  let Name = "SImm26OperandB";
412bdd1243dSDimitry Andric  let PredicateMethod = "isSImm26Operand";
413bdd1243dSDimitry Andric  let RenderMethod = "addImmOperands";
414bdd1243dSDimitry Andric  let DiagnosticType = "InvalidSImm26Operand";
415bdd1243dSDimitry Andric  let ParserMethod = "parseImmediate";
416bdd1243dSDimitry Andric}
417bdd1243dSDimitry Andric
418bdd1243dSDimitry Andric// A symbol or an imm used in B/PseudoBR.
419bdd1243dSDimitry Andricdef simm26_b : Operand<OtherVT> {
420bdd1243dSDimitry Andric  let ParserMatchClass = SImm26OperandB;
42106c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
42281ad6265SDimitry Andric  let DecoderMethod = "decodeSImmOperand<26, 2>";
42381ad6265SDimitry Andric}
42481ad6265SDimitry Andric
425bdd1243dSDimitry Andricdef SImm26OperandBL: AsmOperandClass {
426bdd1243dSDimitry Andric  let Name = "SImm26OperandBL";
427bdd1243dSDimitry Andric  let PredicateMethod = "isSImm26Operand";
428bdd1243dSDimitry Andric  let RenderMethod = "addImmOperands";
429bdd1243dSDimitry Andric  let DiagnosticType = "InvalidSImm26Operand";
430bdd1243dSDimitry Andric  let ParserMethod = "parseSImm26Operand";
431bdd1243dSDimitry Andric}
432bdd1243dSDimitry Andric
433bdd1243dSDimitry Andric// A symbol or an imm used in BL/PseudoCALL/PseudoTAIL.
434bdd1243dSDimitry Andricdef simm26_symbol : Operand<GRLenVT> {
435bdd1243dSDimitry Andric  let ParserMatchClass = SImm26OperandBL;
43606c3fb27SDimitry Andric  let EncoderMethod = "getImmOpValueAsr<2>";
437bdd1243dSDimitry Andric  let DecoderMethod = "decodeSImmOperand<26, 2>";
438bdd1243dSDimitry Andric}
439bdd1243dSDimitry Andric
44006c3fb27SDimitry Andric// A 32-bit signed immediate with the lowest 16 bits zeroed, suitable for
44106c3fb27SDimitry Andric// direct use with `addu16i.d`.
44206c3fb27SDimitry Andricdef simm16_lsl16 : Operand<GRLenVT>,
44306c3fb27SDimitry Andric    ImmLeaf<GRLenVT, [{return isShiftedInt<16, 16>(Imm);}]>;
44406c3fb27SDimitry Andric
44506c3fb27SDimitry Andric// A 32-bit signed immediate expressible with a pair of `addu16i.d + addi` for
44606c3fb27SDimitry Andric// use in additions.
44706c3fb27SDimitry Andricdef simm32_hi16_lo12: Operand<GRLenVT>, ImmLeaf<GRLenVT, [{
4480fca6ea1SDimitry Andric  return !isInt<12>(Imm) && isShiftedInt<16, 16>(Imm - SignExtend64<12>(Imm));
44906c3fb27SDimitry Andric}]>;
45006c3fb27SDimitry Andric
451bdd1243dSDimitry Andricdef BareSymbol : AsmOperandClass {
452bdd1243dSDimitry Andric  let Name = "BareSymbol";
453bdd1243dSDimitry Andric  let RenderMethod = "addImmOperands";
454bdd1243dSDimitry Andric  let DiagnosticType = "InvalidBareSymbol";
455bdd1243dSDimitry Andric  let ParserMethod = "parseImmediate";
456bdd1243dSDimitry Andric}
457bdd1243dSDimitry Andric
458bdd1243dSDimitry Andric// A bare symbol used in "PseudoLA_*" instructions.
459bdd1243dSDimitry Andricdef bare_symbol : Operand<GRLenVT> {
460bdd1243dSDimitry Andric  let ParserMatchClass = BareSymbol;
461bdd1243dSDimitry Andric}
462bdd1243dSDimitry Andric
4630fca6ea1SDimitry Andricdef TPRelAddSymbol : AsmOperandClass {
4640fca6ea1SDimitry Andric  let Name = "TPRelAddSymbol";
4650fca6ea1SDimitry Andric  let RenderMethod = "addImmOperands";
4660fca6ea1SDimitry Andric  let DiagnosticType = "InvalidTPRelAddSymbol";
4670fca6ea1SDimitry Andric  let ParserMethod = "parseOperandWithModifier";
4680fca6ea1SDimitry Andric}
4690fca6ea1SDimitry Andric
4700fca6ea1SDimitry Andric// A bare symbol with the %le_add_r variant.
4710fca6ea1SDimitry Andricdef tprel_add_symbol : Operand<GRLenVT> {
4720fca6ea1SDimitry Andric  let ParserMatchClass = TPRelAddSymbol;
4730fca6ea1SDimitry Andric}
4740fca6ea1SDimitry Andric
4750fca6ea1SDimitry Andric
47681ad6265SDimitry Andric// Standalone (codegen-only) immleaf patterns.
47781ad6265SDimitry Andric
47881ad6265SDimitry Andric// A 12-bit signed immediate plus one where the imm range will be [-2047, 2048].
47981ad6265SDimitry Andricdef simm12_plus1 : ImmLeaf<GRLenVT,
48081ad6265SDimitry Andric  [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
48181ad6265SDimitry Andric
48281ad6265SDimitry Andric// Return the negation of an immediate value.
48381ad6265SDimitry Andricdef NegImm : SDNodeXForm<imm, [{
48481ad6265SDimitry Andric  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N),
48581ad6265SDimitry Andric                                   N->getValueType(0));
48681ad6265SDimitry Andric}]>;
48781ad6265SDimitry Andric
488753f127fSDimitry Andric// FP immediate patterns.
489753f127fSDimitry Andricdef fpimm0    : PatLeaf<(fpimm), [{return N->isExactlyValue(+0.0);}]>;
490753f127fSDimitry Andricdef fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;
491753f127fSDimitry Andricdef fpimm1    : PatLeaf<(fpimm), [{return N->isExactlyValue(+1.0);}]>;
492753f127fSDimitry Andric
493bdd1243dSDimitry Andric// Return an immediate subtracted from 32.
494bdd1243dSDimitry Andricdef ImmSubFrom32 : SDNodeXForm<imm, [{
495bdd1243dSDimitry Andric  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
496bdd1243dSDimitry Andric                                   N->getValueType(0));
497bdd1243dSDimitry Andric}]>;
498753f127fSDimitry Andric
49906c3fb27SDimitry Andric// Return the lowest 12 bits of the signed immediate.
50006c3fb27SDimitry Andricdef LO12: SDNodeXForm<imm, [{
50106c3fb27SDimitry Andric  return CurDAG->getTargetConstant(SignExtend64<12>(N->getSExtValue()),
50206c3fb27SDimitry Andric                                   SDLoc(N), N->getValueType(0));
50306c3fb27SDimitry Andric}]>;
50406c3fb27SDimitry Andric
50506c3fb27SDimitry Andric// Return the higher 16 bits of the signed immediate.
50606c3fb27SDimitry Andricdef HI16 : SDNodeXForm<imm, [{
50706c3fb27SDimitry Andric  return CurDAG->getTargetConstant(N->getSExtValue() >> 16, SDLoc(N),
50806c3fb27SDimitry Andric                                   N->getValueType(0));
50906c3fb27SDimitry Andric}]>;
51006c3fb27SDimitry Andric
51106c3fb27SDimitry Andric// Return the higher 16 bits of the signed immediate, adjusted for use within an
51206c3fb27SDimitry Andric// `addu16i.d + addi` pair.
51306c3fb27SDimitry Andricdef HI16ForAddu16idAddiPair: SDNodeXForm<imm, [{
51406c3fb27SDimitry Andric  auto Imm = N->getSExtValue();
51506c3fb27SDimitry Andric  return CurDAG->getTargetConstant((Imm - SignExtend64<12>(Imm)) >> 16,
51606c3fb27SDimitry Andric                                   SDLoc(N), N->getValueType(0));
51706c3fb27SDimitry Andric}]>;
51806c3fb27SDimitry Andric
519753f127fSDimitry Andricdef BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
52006c3fb27SDimitry Andricdef AddrConstant : ComplexPattern<iPTR, 2, "SelectAddrConstant">;
521bdd1243dSDimitry Andricdef NonFIBaseAddr : ComplexPattern<iPTR, 1, "selectNonFIBaseAddr">;
522bdd1243dSDimitry Andric
523bdd1243dSDimitry Andricdef fma_nsz : PatFrag<(ops node:$fj, node:$fk, node:$fa),
524bdd1243dSDimitry Andric                      (fma node:$fj, node:$fk, node:$fa), [{
525bdd1243dSDimitry Andric  return N->getFlags().hasNoSignedZeros();
526bdd1243dSDimitry Andric}]>;
527753f127fSDimitry Andric
52806c3fb27SDimitry Andric// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
52906c3fb27SDimitry Andric// in which imm = imm0 + imm1, and both imm0 & imm1 are simm12.
53006c3fb27SDimitry Andricdef AddiPair : PatLeaf<(imm), [{
53106c3fb27SDimitry Andric  if (!N->hasOneUse())
53206c3fb27SDimitry Andric    return false;
53306c3fb27SDimitry Andric  // The immediate operand must be in range [-4096,-2049] or [2048,4094].
53406c3fb27SDimitry Andric  int64_t Imm = N->getSExtValue();
53506c3fb27SDimitry Andric  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
53606c3fb27SDimitry Andric}]>;
53706c3fb27SDimitry Andric
53806c3fb27SDimitry Andric// Return -2048 if immediate is negative or 2047 if positive.
53906c3fb27SDimitry Andricdef AddiPairImmLarge : SDNodeXForm<imm, [{
54006c3fb27SDimitry Andric  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;
54106c3fb27SDimitry Andric  return CurDAG->getTargetConstant(Imm, SDLoc(N),
54206c3fb27SDimitry Andric                                   N->getValueType(0));
54306c3fb27SDimitry Andric}]>;
54406c3fb27SDimitry Andric
54506c3fb27SDimitry Andric// Return imm - (imm < 0 ? -2048 : 2047).
54606c3fb27SDimitry Andricdef AddiPairImmSmall : SDNodeXForm<imm, [{
54706c3fb27SDimitry Andric  int64_t Imm = N->getSExtValue();
54806c3fb27SDimitry Andric  int64_t Adj = Imm < 0 ? -2048 : 2047;
54906c3fb27SDimitry Andric  return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N),
55006c3fb27SDimitry Andric                                   N->getValueType(0));
55106c3fb27SDimitry Andric}]>;
55206c3fb27SDimitry Andric
55306c3fb27SDimitry Andric// Check if (mul r, imm) can be optimized to (SLLI (ALSL r, r, i0), i1),
55406c3fb27SDimitry Andric// in which imm = (1 + (1 << i0)) << i1.
55506c3fb27SDimitry Andricdef AlslSlliImm : PatLeaf<(imm), [{
55606c3fb27SDimitry Andric  if (!N->hasOneUse())
55706c3fb27SDimitry Andric    return false;
55806c3fb27SDimitry Andric  uint64_t Imm = N->getZExtValue();
55906c3fb27SDimitry Andric  unsigned I1 = llvm::countr_zero(Imm);
56006c3fb27SDimitry Andric  uint64_t Rem = Imm >> I1;
56106c3fb27SDimitry Andric  return Rem == 3 || Rem == 5 || Rem == 9 || Rem == 17;
56206c3fb27SDimitry Andric}]>;
56306c3fb27SDimitry Andric
56406c3fb27SDimitry Andricdef AlslSlliImmI1 : SDNodeXForm<imm, [{
56506c3fb27SDimitry Andric  uint64_t Imm = N->getZExtValue();
56606c3fb27SDimitry Andric  unsigned I1 = llvm::countr_zero(Imm);
56706c3fb27SDimitry Andric  return CurDAG->getTargetConstant(I1, SDLoc(N),
56806c3fb27SDimitry Andric                                   N->getValueType(0));
56906c3fb27SDimitry Andric}]>;
57006c3fb27SDimitry Andric
57106c3fb27SDimitry Andricdef AlslSlliImmI0 : SDNodeXForm<imm, [{
57206c3fb27SDimitry Andric  uint64_t Imm = N->getZExtValue();
57306c3fb27SDimitry Andric  unsigned I1 = llvm::countr_zero(Imm);
57406c3fb27SDimitry Andric  uint64_t I0;
57506c3fb27SDimitry Andric  switch (Imm >> I1) {
57606c3fb27SDimitry Andric  case 3:  I0 = 1; break;
57706c3fb27SDimitry Andric  case 5:  I0 = 2; break;
57806c3fb27SDimitry Andric  case 9:  I0 = 3; break;
57906c3fb27SDimitry Andric  default: I0 = 4; break;
58006c3fb27SDimitry Andric  }
58106c3fb27SDimitry Andric  return CurDAG->getTargetConstant(I0, SDLoc(N),
58206c3fb27SDimitry Andric                                   N->getValueType(0));
58306c3fb27SDimitry Andric}]>;
58406c3fb27SDimitry Andric
5855f757f3fSDimitry Andric// Check if (and r, imm) can be optimized to (BSTRINS r, R0, msb, lsb),
5865f757f3fSDimitry Andric// in which imm = ~((2^^(msb-lsb+1) - 1) << lsb).
5875f757f3fSDimitry Andricdef BstrinsImm : PatLeaf<(imm), [{
5885f757f3fSDimitry Andric  if (!N->hasOneUse())
5895f757f3fSDimitry Andric    return false;
5905f757f3fSDimitry Andric  uint64_t Imm = N->getZExtValue();
5915f757f3fSDimitry Andric  // andi can be used instead if Imm <= 0xfff.
5925f757f3fSDimitry Andric  if (Imm <= 0xfff)
5935f757f3fSDimitry Andric    return false;
5945f757f3fSDimitry Andric  unsigned MaskIdx, MaskLen;
5955f757f3fSDimitry Andric  return N->getValueType(0).getSizeInBits() == 32
5965f757f3fSDimitry Andric             ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)
5975f757f3fSDimitry Andric             : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);
5985f757f3fSDimitry Andric}]>;
5995f757f3fSDimitry Andric
6005f757f3fSDimitry Andricdef BstrinsMsb: SDNodeXForm<imm, [{
6015f757f3fSDimitry Andric  uint64_t Imm = N->getZExtValue();
6025f757f3fSDimitry Andric  unsigned MaskIdx, MaskLen;
6035f757f3fSDimitry Andric  N->getValueType(0).getSizeInBits() == 32
6045f757f3fSDimitry Andric      ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)
6055f757f3fSDimitry Andric      : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);
6065f757f3fSDimitry Andric  return CurDAG->getTargetConstant(MaskIdx + MaskLen - 1, SDLoc(N),
6075f757f3fSDimitry Andric                                   N->getValueType(0));
6085f757f3fSDimitry Andric}]>;
6095f757f3fSDimitry Andric
6105f757f3fSDimitry Andricdef BstrinsLsb: SDNodeXForm<imm, [{
6115f757f3fSDimitry Andric  uint64_t Imm = N->getZExtValue();
6125f757f3fSDimitry Andric  unsigned MaskIdx, MaskLen;
6135f757f3fSDimitry Andric  N->getValueType(0).getSizeInBits() == 32
6145f757f3fSDimitry Andric      ? llvm::isShiftedMask_32(~Imm, MaskIdx, MaskLen)
6155f757f3fSDimitry Andric      : llvm::isShiftedMask_64(~Imm, MaskIdx, MaskLen);
6165f757f3fSDimitry Andric  return CurDAG->getTargetConstant(MaskIdx, SDLoc(N), N->getValueType(0));
6175f757f3fSDimitry Andric}]>;
6185f757f3fSDimitry Andric
61981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
62081ad6265SDimitry Andric// Instruction Formats
62181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
62281ad6265SDimitry Andric
62381ad6265SDimitry Andricinclude "LoongArchInstrFormats.td"
62481ad6265SDimitry Andricinclude "LoongArchFloatInstrFormats.td"
62506c3fb27SDimitry Andricinclude "LoongArchLSXInstrFormats.td"
62606c3fb27SDimitry Andricinclude "LoongArchLASXInstrFormats.td"
62706c3fb27SDimitry Andricinclude "LoongArchLBTInstrFormats.td"
62881ad6265SDimitry Andric
62981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
63081ad6265SDimitry Andric// Instruction Class Templates
63181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
63281ad6265SDimitry Andric
63306c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
63406c3fb27SDimitry Andricclass ALU_3R<bits<32> op>
63506c3fb27SDimitry Andric    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">;
63606c3fb27SDimitry Andricclass ALU_2R<bits<32> op>
63706c3fb27SDimitry Andric    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;
63881ad6265SDimitry Andric
63906c3fb27SDimitry Andricclass ALU_3RI2<bits<32> op, Operand ImmOpnd>
64006c3fb27SDimitry Andric    : Fmt3RI2<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm2),
64181ad6265SDimitry Andric              "$rd, $rj, $rk, $imm2">;
64206c3fb27SDimitry Andricclass ALU_3RI3<bits<32> op, Operand ImmOpnd>
64306c3fb27SDimitry Andric    : Fmt3RI3<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk, ImmOpnd:$imm3),
64481ad6265SDimitry Andric              "$rd, $rj, $rk, $imm3">;
64506c3fb27SDimitry Andricclass ALU_2RI5<bits<32> op, Operand ImmOpnd>
64606c3fb27SDimitry Andric    : Fmt2RI5<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm5),
64781ad6265SDimitry Andric              "$rd, $rj, $imm5">;
64806c3fb27SDimitry Andricclass ALU_2RI6<bits<32> op, Operand ImmOpnd>
64906c3fb27SDimitry Andric    : Fmt2RI6<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm6),
65081ad6265SDimitry Andric              "$rd, $rj, $imm6">;
65106c3fb27SDimitry Andricclass ALU_2RI12<bits<32> op, Operand ImmOpnd>
65206c3fb27SDimitry Andric    : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm12),
65381ad6265SDimitry Andric               "$rd, $rj, $imm12">;
65406c3fb27SDimitry Andricclass ALU_2RI16<bits<32> op, Operand ImmOpnd>
65506c3fb27SDimitry Andric    : Fmt2RI16<op, (outs GPR:$rd), (ins GPR:$rj, ImmOpnd:$imm16),
65681ad6265SDimitry Andric               "$rd, $rj, $imm16">;
65706c3fb27SDimitry Andricclass ALU_1RI20<bits<32> op, Operand ImmOpnd>
65806c3fb27SDimitry Andric    : Fmt1RI20<op, (outs GPR:$rd), (ins ImmOpnd:$imm20), "$rd, $imm20">;
65906c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
66081ad6265SDimitry Andric
66106c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
66206c3fb27SDimitry Andricclass MISC_I15<bits<32> op>
66306c3fb27SDimitry Andric    : FmtI15<op, (outs), (ins uimm15:$imm15), "$imm15">;
66481ad6265SDimitry Andric
66506c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
66606c3fb27SDimitry Andricclass RDTIME_2R<bits<32> op>
66706c3fb27SDimitry Andric    : Fmt2R<op, (outs GPR:$rd, GPR:$rj), (ins), "$rd, $rj">;
66881ad6265SDimitry Andric
66906c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
67006c3fb27SDimitry Andricclass BrCC_2RI16<bits<32> op>
67106c3fb27SDimitry Andric    : Fmt2RI16<op, (outs), (ins GPR:$rj, GPR:$rd, simm16_lsl2_br:$imm16),
67281ad6265SDimitry Andric               "$rj, $rd, $imm16"> {
67381ad6265SDimitry Andric  let isBranch = 1;
67481ad6265SDimitry Andric  let isTerminator = 1;
67581ad6265SDimitry Andric}
67606c3fb27SDimitry Andricclass BrCCZ_1RI21<bits<32> op>
67706c3fb27SDimitry Andric    : Fmt1RI21<op, (outs), (ins GPR:$rj, simm21_lsl2:$imm21),
67881ad6265SDimitry Andric               "$rj, $imm21"> {
67981ad6265SDimitry Andric  let isBranch = 1;
68081ad6265SDimitry Andric  let isTerminator = 1;
68181ad6265SDimitry Andric}
68206c3fb27SDimitry Andricclass Br_I26<bits<32> op>
68306c3fb27SDimitry Andric    : FmtI26<op, (outs), (ins simm26_b:$imm26), "$imm26"> {
68481ad6265SDimitry Andric  let isBranch = 1;
68581ad6265SDimitry Andric  let isTerminator = 1;
6865f757f3fSDimitry Andric  let isBarrier = 1;
68781ad6265SDimitry Andric}
68806c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
68981ad6265SDimitry Andric
69006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
69106c3fb27SDimitry Andricclass LOAD_3R<bits<32> op>
69206c3fb27SDimitry Andric    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rj, GPR:$rk), "$rd, $rj, $rk">;
69306c3fb27SDimitry Andricclass LOAD_2RI12<bits<32> op>
69406c3fb27SDimitry Andric    : Fmt2RI12<op, (outs GPR:$rd), (ins GPR:$rj, simm12_addlike:$imm12),
69581ad6265SDimitry Andric               "$rd, $rj, $imm12">;
69606c3fb27SDimitry Andricclass LOAD_2RI14<bits<32> op>
69706c3fb27SDimitry Andric    : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),
69881ad6265SDimitry Andric               "$rd, $rj, $imm14">;
69906c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 1, mayStore = 0
70081ad6265SDimitry Andric
70106c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
70206c3fb27SDimitry Andricclass STORE_3R<bits<32> op>
70306c3fb27SDimitry Andric    : Fmt3R<op, (outs), (ins GPR:$rd, GPR:$rj, GPR:$rk),
70481ad6265SDimitry Andric            "$rd, $rj, $rk">;
70506c3fb27SDimitry Andricclass STORE_2RI12<bits<32> op>
70606c3fb27SDimitry Andric    : Fmt2RI12<op, (outs), (ins GPR:$rd, GPR:$rj, simm12_addlike:$imm12),
70781ad6265SDimitry Andric               "$rd, $rj, $imm12">;
70806c3fb27SDimitry Andricclass STORE_2RI14<bits<32> op>
70906c3fb27SDimitry Andric    : Fmt2RI14<op, (outs), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14),
71081ad6265SDimitry Andric               "$rd, $rj, $imm14">;
71106c3fb27SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 1
71281ad6265SDimitry Andric
71306c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in
71406c3fb27SDimitry Andricclass AM_3R<bits<32> op>
71506c3fb27SDimitry Andric    : Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj),
716bdd1243dSDimitry Andric            "$rd, $rk, $rj">;
71781ad6265SDimitry Andric
7187a6dacacSDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
71906c3fb27SDimitry Andricclass LLBase<bits<32> op>
72006c3fb27SDimitry Andric    : Fmt2RI14<op, (outs GPR:$rd), (ins GPR:$rj, simm14_lsl2:$imm14),
72181ad6265SDimitry Andric               "$rd, $rj, $imm14">;
7227a6dacacSDimitry Andricclass LLBase_ACQ<bits<32> op>
7237a6dacacSDimitry Andric    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;
7247a6dacacSDimitry Andric}
72581ad6265SDimitry Andric
7267a6dacacSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1, Constraints = "$rd = $dst" in {
72706c3fb27SDimitry Andricclass SCBase<bits<32> op>
72881ad6265SDimitry Andric    : Fmt2RI14<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj, simm14_lsl2:$imm14),
72906c3fb27SDimitry Andric               "$rd, $rj, $imm14">;
7307a6dacacSDimitry Andricclass SCBase_128<bits<32> op>
7317a6dacacSDimitry Andric    : Fmt3R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rk, GPR:$rj),
7327a6dacacSDimitry Andric               "$rd, $rk, $rj">;
7337a6dacacSDimitry Andricclass SCBase_REL<bits<32> op>
7347a6dacacSDimitry Andric    : Fmt2R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rj), "$rd, $rj">;
7357a6dacacSDimitry Andric}
73681ad6265SDimitry Andric
73706c3fb27SDimitry Andriclet hasSideEffects = 1 in
73806c3fb27SDimitry Andricclass IOCSRRD<bits<32> op>
73906c3fb27SDimitry Andric    : Fmt2R<op, (outs GPR:$rd), (ins GPR:$rj), "$rd, $rj">;
74081ad6265SDimitry Andric
74106c3fb27SDimitry Andriclet hasSideEffects = 1 in
74206c3fb27SDimitry Andricclass IOCSRWR<bits<32> op>
74306c3fb27SDimitry Andric    : Fmt2R<op, (outs), (ins GPR:$rd, GPR:$rj), "$rd, $rj">;
74481ad6265SDimitry Andric
74581ad6265SDimitry Andric//===----------------------------------------------------------------------===//
74681ad6265SDimitry Andric// Basic Integer Instructions
74781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
74881ad6265SDimitry Andric
74981ad6265SDimitry Andric// Arithmetic Operation Instructions
75006c3fb27SDimitry Andricdef ADD_W : ALU_3R<0x00100000>;
75106c3fb27SDimitry Andricdef SUB_W : ALU_3R<0x00110000>;
75206c3fb27SDimitry Andricdef ADDI_W : ALU_2RI12<0x02800000, simm12_addlike>;
75306c3fb27SDimitry Andricdef ALSL_W : ALU_3RI2<0x00040000, uimm2_plus1>;
7540fca6ea1SDimitry Andriclet isReMaterializable = 1 in {
75506c3fb27SDimitry Andricdef LU12I_W : ALU_1RI20<0x14000000, simm20_lu12iw>;
7560fca6ea1SDimitry Andric}
75706c3fb27SDimitry Andricdef SLT  : ALU_3R<0x00120000>;
75806c3fb27SDimitry Andricdef SLTU : ALU_3R<0x00128000>;
75906c3fb27SDimitry Andricdef SLTI  : ALU_2RI12<0x02000000, simm12>;
76006c3fb27SDimitry Andricdef SLTUI : ALU_2RI12<0x02400000, simm12>;
76152418fc2SDimitry Andricdef PCADDI    : ALU_1RI20<0x18000000, simm20_pcaddi>;
76206c3fb27SDimitry Andricdef PCADDU12I : ALU_1RI20<0x1c000000, simm20>;
76306c3fb27SDimitry Andricdef PCALAU12I : ALU_1RI20<0x1a000000, simm20_pcalau12i>;
76406c3fb27SDimitry Andricdef AND  : ALU_3R<0x00148000>;
76506c3fb27SDimitry Andricdef OR   : ALU_3R<0x00150000>;
76606c3fb27SDimitry Andricdef NOR  : ALU_3R<0x00140000>;
76706c3fb27SDimitry Andricdef XOR  : ALU_3R<0x00158000>;
76806c3fb27SDimitry Andricdef ANDN : ALU_3R<0x00168000>;
76906c3fb27SDimitry Andricdef ORN  : ALU_3R<0x00160000>;
77006c3fb27SDimitry Andricdef ANDI : ALU_2RI12<0x03400000, uimm12>;
7710fca6ea1SDimitry Andric// See LoongArchInstrInfo::isAsCheapAsAMove for more details.
7720fca6ea1SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in {
77306c3fb27SDimitry Andricdef ORI  : ALU_2RI12<0x03800000, uimm12_ori>;
77406c3fb27SDimitry Andricdef XORI : ALU_2RI12<0x03c00000, uimm12>;
7750fca6ea1SDimitry Andric}
77606c3fb27SDimitry Andricdef MUL_W   : ALU_3R<0x001c0000>;
77706c3fb27SDimitry Andricdef MULH_W  : ALU_3R<0x001c8000>;
77806c3fb27SDimitry Andricdef MULH_WU : ALU_3R<0x001d0000>;
779753f127fSDimitry Andriclet usesCustomInserter = true in {
78006c3fb27SDimitry Andricdef DIV_W   : ALU_3R<0x00200000>;
78106c3fb27SDimitry Andricdef MOD_W   : ALU_3R<0x00208000>;
78206c3fb27SDimitry Andricdef DIV_WU  : ALU_3R<0x00210000>;
78306c3fb27SDimitry Andricdef MOD_WU  : ALU_3R<0x00218000>;
784753f127fSDimitry Andric} // usesCustomInserter = true
78581ad6265SDimitry Andric
78681ad6265SDimitry Andric// Bit-shift Instructions
78706c3fb27SDimitry Andricdef SLL_W  : ALU_3R<0x00170000>;
78806c3fb27SDimitry Andricdef SRL_W  : ALU_3R<0x00178000>;
78906c3fb27SDimitry Andricdef SRA_W  : ALU_3R<0x00180000>;
79006c3fb27SDimitry Andricdef ROTR_W : ALU_3R<0x001b0000>;
79181ad6265SDimitry Andric
79206c3fb27SDimitry Andricdef SLLI_W  : ALU_2RI5<0x00408000, uimm5>;
79306c3fb27SDimitry Andricdef SRLI_W  : ALU_2RI5<0x00448000, uimm5>;
79406c3fb27SDimitry Andricdef SRAI_W  : ALU_2RI5<0x00488000, uimm5>;
79506c3fb27SDimitry Andricdef ROTRI_W : ALU_2RI5<0x004c8000, uimm5>;
79681ad6265SDimitry Andric
79781ad6265SDimitry Andric// Bit-manipulation Instructions
79806c3fb27SDimitry Andricdef EXT_W_B : ALU_2R<0x00005c00>;
79906c3fb27SDimitry Andricdef EXT_W_H : ALU_2R<0x00005800>;
80006c3fb27SDimitry Andricdef CLO_W   : ALU_2R<0x00001000>;
80106c3fb27SDimitry Andricdef CLZ_W   : ALU_2R<0x00001400>;
80206c3fb27SDimitry Andricdef CTO_W   : ALU_2R<0x00001800>;
80306c3fb27SDimitry Andricdef CTZ_W   : ALU_2R<0x00001c00>;
80406c3fb27SDimitry Andricdef BYTEPICK_W : ALU_3RI2<0x00080000, uimm2>;
80506c3fb27SDimitry Andricdef REVB_2H   : ALU_2R<0x00003000>;
80606c3fb27SDimitry Andricdef BITREV_4B : ALU_2R<0x00004800>;
80706c3fb27SDimitry Andricdef BITREV_W  : ALU_2R<0x00005000>;
80881ad6265SDimitry Andriclet Constraints = "$rd = $dst" in {
80906c3fb27SDimitry Andricdef BSTRINS_W  : FmtBSTR_W<0x00600000, (outs GPR:$dst),
81081ad6265SDimitry Andric                           (ins GPR:$rd, GPR:$rj, uimm5:$msbw, uimm5:$lsbw),
81106c3fb27SDimitry Andric                           "$rd, $rj, $msbw, $lsbw">;
81281ad6265SDimitry Andric}
81306c3fb27SDimitry Andricdef BSTRPICK_W : FmtBSTR_W<0x00608000, (outs GPR:$rd),
81481ad6265SDimitry Andric                           (ins GPR:$rj, uimm5:$msbw, uimm5:$lsbw),
81506c3fb27SDimitry Andric                           "$rd, $rj, $msbw, $lsbw">;
81606c3fb27SDimitry Andricdef MASKEQZ : ALU_3R<0x00130000>;
81706c3fb27SDimitry Andricdef MASKNEZ : ALU_3R<0x00138000>;
81881ad6265SDimitry Andric
81981ad6265SDimitry Andric// Branch Instructions
82006c3fb27SDimitry Andricdef BEQ  : BrCC_2RI16<0x58000000>;
82106c3fb27SDimitry Andricdef BNE  : BrCC_2RI16<0x5c000000>;
82206c3fb27SDimitry Andricdef BLT  : BrCC_2RI16<0x60000000>;
82306c3fb27SDimitry Andricdef BGE  : BrCC_2RI16<0x64000000>;
82406c3fb27SDimitry Andricdef BLTU : BrCC_2RI16<0x68000000>;
82506c3fb27SDimitry Andricdef BGEU : BrCC_2RI16<0x6c000000>;
82606c3fb27SDimitry Andricdef BEQZ : BrCCZ_1RI21<0x40000000>;
82706c3fb27SDimitry Andricdef BNEZ : BrCCZ_1RI21<0x44000000>;
82806c3fb27SDimitry Andricdef B : Br_I26<0x50000000>;
82981ad6265SDimitry Andric
83006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, Defs=[R1] in
83106c3fb27SDimitry Andricdef BL : FmtI26<0x54000000, (outs), (ins simm26_symbol:$imm26), "$imm26">;
83206c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
83306c3fb27SDimitry Andricdef JIRL : Fmt2RI16<0x4c000000, (outs GPR:$rd),
83406c3fb27SDimitry Andric                    (ins GPR:$rj, simm16_lsl2:$imm16), "$rd, $rj, $imm16">;
83581ad6265SDimitry Andric
83681ad6265SDimitry Andric// Common Memory Access Instructions
83706c3fb27SDimitry Andricdef LD_B  : LOAD_2RI12<0x28000000>;
83806c3fb27SDimitry Andricdef LD_H  : LOAD_2RI12<0x28400000>;
83906c3fb27SDimitry Andricdef LD_W  : LOAD_2RI12<0x28800000>;
84006c3fb27SDimitry Andricdef LD_BU : LOAD_2RI12<0x2a000000>;
84106c3fb27SDimitry Andricdef LD_HU : LOAD_2RI12<0x2a400000>;
84206c3fb27SDimitry Andricdef ST_B : STORE_2RI12<0x29000000>;
84306c3fb27SDimitry Andricdef ST_H : STORE_2RI12<0x29400000>;
84406c3fb27SDimitry Andricdef ST_W : STORE_2RI12<0x29800000>;
84506c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
84606c3fb27SDimitry Andricdef PRELD : FmtPRELD<(outs), (ins uimm5:$imm5, GPR:$rj, simm12:$imm12),
84781ad6265SDimitry Andric                     "$imm5, $rj, $imm12">;
84881ad6265SDimitry Andric
84981ad6265SDimitry Andric// Atomic Memory Access Instructions
85006c3fb27SDimitry Andricdef LL_W : LLBase<0x20000000>;
85106c3fb27SDimitry Andricdef SC_W : SCBase<0x21000000>;
8527a6dacacSDimitry Andricdef LLACQ_W : LLBase_ACQ<0x38578000>;
8537a6dacacSDimitry Andricdef SCREL_W : SCBase_REL<0x38578400>;
85481ad6265SDimitry Andric
85581ad6265SDimitry Andric// Barrier Instructions
85606c3fb27SDimitry Andricdef DBAR : MISC_I15<0x38720000>;
85706c3fb27SDimitry Andricdef IBAR : MISC_I15<0x38728000>;
85881ad6265SDimitry Andric
85981ad6265SDimitry Andric// Other Miscellaneous Instructions
86006c3fb27SDimitry Andricdef SYSCALL : MISC_I15<0x002b0000>;
86106c3fb27SDimitry Andricdef BREAK   : MISC_I15<0x002a0000>;
86206c3fb27SDimitry Andricdef RDTIMEL_W : RDTIME_2R<0x00006000>;
86306c3fb27SDimitry Andricdef RDTIMEH_W : RDTIME_2R<0x00006400>;
86406c3fb27SDimitry Andricdef CPUCFG : ALU_2R<0x00006c00>;
86581ad6265SDimitry Andric
866bdd1243dSDimitry Andric// Cache Maintenance Instructions
86706c3fb27SDimitry Andricdef CACOP : FmtCACOP<(outs), (ins uimm5:$op, GPR:$rj, simm12:$imm12),
868bdd1243dSDimitry Andric                     "$op, $rj, $imm12">;
869bdd1243dSDimitry Andric
87081ad6265SDimitry Andric/// LA64 instructions
87181ad6265SDimitry Andric
87281ad6265SDimitry Andriclet Predicates = [IsLA64] in {
87381ad6265SDimitry Andric
87481ad6265SDimitry Andric// Arithmetic Operation Instructions for 64-bits
87506c3fb27SDimitry Andricdef ADD_D : ALU_3R<0x00108000>;
87606c3fb27SDimitry Andricdef SUB_D : ALU_3R<0x00118000>;
8770fca6ea1SDimitry Andric// ADDI_D isn't always rematerializable, but isReMaterializable will be used as
8780fca6ea1SDimitry Andric// a hint which is verified in isReallyTriviallyReMaterializable.
8790fca6ea1SDimitry Andric// See LoongArchInstrInfo::isAsCheapAsAMove for more details.
8800fca6ea1SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in {
88106c3fb27SDimitry Andricdef ADDI_D : ALU_2RI12<0x02c00000, simm12_addlike>;
8820fca6ea1SDimitry Andric}
88306c3fb27SDimitry Andricdef ADDU16I_D : ALU_2RI16<0x10000000, simm16>;
88406c3fb27SDimitry Andricdef ALSL_WU : ALU_3RI2<0x00060000, uimm2_plus1>;
88506c3fb27SDimitry Andricdef ALSL_D  : ALU_3RI2<0x002c0000, uimm2_plus1>;
88681ad6265SDimitry Andriclet Constraints = "$rd = $dst" in {
8870fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0,
8880fca6ea1SDimitry Andric    isReMaterializable = 1 in
88906c3fb27SDimitry Andricdef LU32I_D : Fmt1RI20<0x16000000, (outs GPR:$dst),
89006c3fb27SDimitry Andric                       (ins GPR:$rd, simm20_lu32id:$imm20),
89181ad6265SDimitry Andric                       "$rd, $imm20">;
89281ad6265SDimitry Andric}
8930fca6ea1SDimitry Andriclet isReMaterializable = 1 in {
89406c3fb27SDimitry Andricdef LU52I_D : ALU_2RI12<0x03000000, simm12_lu52id>;
8950fca6ea1SDimitry Andric}
8961db9f3b2SDimitry Andricdef PCADDU18I : ALU_1RI20<0x1e000000, simm20_pcaddu18i>;
89706c3fb27SDimitry Andricdef MUL_D     : ALU_3R<0x001d8000>;
89806c3fb27SDimitry Andricdef MULH_D    : ALU_3R<0x001e0000>;
89906c3fb27SDimitry Andricdef MULH_DU   : ALU_3R<0x001e8000>;
90006c3fb27SDimitry Andricdef MULW_D_W  : ALU_3R<0x001f0000>;
90106c3fb27SDimitry Andricdef MULW_D_WU : ALU_3R<0x001f8000>;
902753f127fSDimitry Andriclet usesCustomInserter = true in {
90306c3fb27SDimitry Andricdef DIV_D     : ALU_3R<0x00220000>;
90406c3fb27SDimitry Andricdef MOD_D     : ALU_3R<0x00228000>;
90506c3fb27SDimitry Andricdef DIV_DU    : ALU_3R<0x00230000>;
90606c3fb27SDimitry Andricdef MOD_DU    : ALU_3R<0x00238000>;
907753f127fSDimitry Andric} // usesCustomInserter = true
90881ad6265SDimitry Andric
90981ad6265SDimitry Andric// Bit-shift Instructions for 64-bits
91006c3fb27SDimitry Andricdef SLL_D  : ALU_3R<0x00188000>;
91106c3fb27SDimitry Andricdef SRL_D  : ALU_3R<0x00190000>;
91206c3fb27SDimitry Andricdef SRA_D  : ALU_3R<0x00198000>;
91306c3fb27SDimitry Andricdef ROTR_D : ALU_3R<0x001b8000>;
91406c3fb27SDimitry Andricdef SLLI_D  : ALU_2RI6<0x00410000, uimm6>;
91506c3fb27SDimitry Andricdef SRLI_D  : ALU_2RI6<0x00450000, uimm6>;
91606c3fb27SDimitry Andricdef SRAI_D  : ALU_2RI6<0x00490000, uimm6>;
91706c3fb27SDimitry Andricdef ROTRI_D : ALU_2RI6<0x004d0000, uimm6>;
91881ad6265SDimitry Andric
91981ad6265SDimitry Andric// Bit-manipulation Instructions for 64-bits
92006c3fb27SDimitry Andricdef CLO_D : ALU_2R<0x00002000>;
92106c3fb27SDimitry Andricdef CLZ_D : ALU_2R<0x00002400>;
92206c3fb27SDimitry Andricdef CTO_D : ALU_2R<0x00002800>;
92306c3fb27SDimitry Andricdef CTZ_D : ALU_2R<0x00002c00>;
92406c3fb27SDimitry Andricdef BYTEPICK_D : ALU_3RI3<0x000c0000, uimm3>;
92506c3fb27SDimitry Andricdef REVB_4H   : ALU_2R<0x00003400>;
92606c3fb27SDimitry Andricdef REVB_2W   : ALU_2R<0x00003800>;
92706c3fb27SDimitry Andricdef REVB_D    : ALU_2R<0x00003c00>;
92806c3fb27SDimitry Andricdef REVH_2W   : ALU_2R<0x00004000>;
92906c3fb27SDimitry Andricdef REVH_D    : ALU_2R<0x00004400>;
93006c3fb27SDimitry Andricdef BITREV_8B : ALU_2R<0x00004c00>;
93106c3fb27SDimitry Andricdef BITREV_D  : ALU_2R<0x00005400>;
93281ad6265SDimitry Andriclet Constraints = "$rd = $dst" in {
93306c3fb27SDimitry Andricdef BSTRINS_D  : FmtBSTR_D<0x00800000, (outs GPR:$dst),
93481ad6265SDimitry Andric                           (ins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd),
93506c3fb27SDimitry Andric                           "$rd, $rj, $msbd, $lsbd">;
93681ad6265SDimitry Andric}
93706c3fb27SDimitry Andricdef BSTRPICK_D : FmtBSTR_D<0x00c00000, (outs GPR:$rd),
93881ad6265SDimitry Andric                           (ins GPR:$rj, uimm6:$msbd, uimm6:$lsbd),
93906c3fb27SDimitry Andric                           "$rd, $rj, $msbd, $lsbd">;
94081ad6265SDimitry Andric
94181ad6265SDimitry Andric// Common Memory Access Instructions for 64-bits
94206c3fb27SDimitry Andricdef LD_WU : LOAD_2RI12<0x2a800000>;
94306c3fb27SDimitry Andricdef LD_D  : LOAD_2RI12<0x28c00000>;
94406c3fb27SDimitry Andricdef ST_D : STORE_2RI12<0x29c00000>;
94506c3fb27SDimitry Andricdef LDX_B  : LOAD_3R<0x38000000>;
94606c3fb27SDimitry Andricdef LDX_H  : LOAD_3R<0x38040000>;
94706c3fb27SDimitry Andricdef LDX_W  : LOAD_3R<0x38080000>;
94806c3fb27SDimitry Andricdef LDX_D  : LOAD_3R<0x380c0000>;
94906c3fb27SDimitry Andricdef LDX_BU : LOAD_3R<0x38200000>;
95006c3fb27SDimitry Andricdef LDX_HU : LOAD_3R<0x38240000>;
95106c3fb27SDimitry Andricdef LDX_WU : LOAD_3R<0x38280000>;
95206c3fb27SDimitry Andricdef STX_B : STORE_3R<0x38100000>;
95306c3fb27SDimitry Andricdef STX_H : STORE_3R<0x38140000>;
95406c3fb27SDimitry Andricdef STX_W : STORE_3R<0x38180000>;
95506c3fb27SDimitry Andricdef STX_D : STORE_3R<0x381c0000>;
95606c3fb27SDimitry Andricdef LDPTR_W : LOAD_2RI14<0x24000000>;
95706c3fb27SDimitry Andricdef LDPTR_D : LOAD_2RI14<0x26000000>;
95806c3fb27SDimitry Andricdef STPTR_W : STORE_2RI14<0x25000000>;
95906c3fb27SDimitry Andricdef STPTR_D : STORE_2RI14<0x27000000>;
96006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 1 in
96106c3fb27SDimitry Andricdef PRELDX : FmtPRELDX<(outs), (ins uimm5:$imm5, GPR:$rj, GPR:$rk),
96281ad6265SDimitry Andric                       "$imm5, $rj, $rk">;
96381ad6265SDimitry Andric
96481ad6265SDimitry Andric// Bound Check Memory Access Instructions
96506c3fb27SDimitry Andricdef LDGT_B : LOAD_3R<0x38780000>;
96606c3fb27SDimitry Andricdef LDGT_H : LOAD_3R<0x38788000>;
96706c3fb27SDimitry Andricdef LDGT_W : LOAD_3R<0x38790000>;
96806c3fb27SDimitry Andricdef LDGT_D : LOAD_3R<0x38798000>;
96906c3fb27SDimitry Andricdef LDLE_B : LOAD_3R<0x387a0000>;
97006c3fb27SDimitry Andricdef LDLE_H : LOAD_3R<0x387a8000>;
97106c3fb27SDimitry Andricdef LDLE_W : LOAD_3R<0x387b0000>;
97206c3fb27SDimitry Andricdef LDLE_D : LOAD_3R<0x387b8000>;
97306c3fb27SDimitry Andricdef STGT_B : STORE_3R<0x387c0000>;
97406c3fb27SDimitry Andricdef STGT_H : STORE_3R<0x387c8000>;
97506c3fb27SDimitry Andricdef STGT_W : STORE_3R<0x387d0000>;
97606c3fb27SDimitry Andricdef STGT_D : STORE_3R<0x387d8000>;
97706c3fb27SDimitry Andricdef STLE_B : STORE_3R<0x387e0000>;
97806c3fb27SDimitry Andricdef STLE_H : STORE_3R<0x387e8000>;
97906c3fb27SDimitry Andricdef STLE_W : STORE_3R<0x387f0000>;
98006c3fb27SDimitry Andricdef STLE_D : STORE_3R<0x387f8000>;
98181ad6265SDimitry Andric
98281ad6265SDimitry Andric// Atomic Memory Access Instructions for 64-bits
9837a6dacacSDimitry Andricdef AMSWAP_B     : AM_3R<0x385c0000>;
9847a6dacacSDimitry Andricdef AMSWAP_H     : AM_3R<0x385c8000>;
98506c3fb27SDimitry Andricdef AMSWAP_W     : AM_3R<0x38600000>;
98606c3fb27SDimitry Andricdef AMSWAP_D     : AM_3R<0x38608000>;
9877a6dacacSDimitry Andricdef AMADD_B      : AM_3R<0x385d0000>;
9887a6dacacSDimitry Andricdef AMADD_H      : AM_3R<0x385d8000>;
98906c3fb27SDimitry Andricdef AMADD_W      : AM_3R<0x38610000>;
99006c3fb27SDimitry Andricdef AMADD_D      : AM_3R<0x38618000>;
99106c3fb27SDimitry Andricdef AMAND_W      : AM_3R<0x38620000>;
99206c3fb27SDimitry Andricdef AMAND_D      : AM_3R<0x38628000>;
99306c3fb27SDimitry Andricdef AMOR_W       : AM_3R<0x38630000>;
99406c3fb27SDimitry Andricdef AMOR_D       : AM_3R<0x38638000>;
99506c3fb27SDimitry Andricdef AMXOR_W      : AM_3R<0x38640000>;
99606c3fb27SDimitry Andricdef AMXOR_D      : AM_3R<0x38648000>;
99706c3fb27SDimitry Andricdef AMMAX_W      : AM_3R<0x38650000>;
99806c3fb27SDimitry Andricdef AMMAX_D      : AM_3R<0x38658000>;
99906c3fb27SDimitry Andricdef AMMIN_W      : AM_3R<0x38660000>;
100006c3fb27SDimitry Andricdef AMMIN_D      : AM_3R<0x38668000>;
100106c3fb27SDimitry Andricdef AMMAX_WU     : AM_3R<0x38670000>;
100206c3fb27SDimitry Andricdef AMMAX_DU     : AM_3R<0x38678000>;
100306c3fb27SDimitry Andricdef AMMIN_WU     : AM_3R<0x38680000>;
100406c3fb27SDimitry Andricdef AMMIN_DU     : AM_3R<0x38688000>;
10057a6dacacSDimitry Andricdef AMSWAP__DB_B : AM_3R<0x385e0000>;
10067a6dacacSDimitry Andricdef AMSWAP__DB_H : AM_3R<0x385e8000>;
100706c3fb27SDimitry Andricdef AMSWAP__DB_W : AM_3R<0x38690000>;
100806c3fb27SDimitry Andricdef AMSWAP__DB_D : AM_3R<0x38698000>;
10097a6dacacSDimitry Andricdef AMADD__DB_B  : AM_3R<0x385f0000>;
10107a6dacacSDimitry Andricdef AMADD__DB_H  : AM_3R<0x385f8000>;
101106c3fb27SDimitry Andricdef AMADD__DB_W  : AM_3R<0x386a0000>;
101206c3fb27SDimitry Andricdef AMADD__DB_D  : AM_3R<0x386a8000>;
101306c3fb27SDimitry Andricdef AMAND__DB_W  : AM_3R<0x386b0000>;
101406c3fb27SDimitry Andricdef AMAND__DB_D  : AM_3R<0x386b8000>;
101506c3fb27SDimitry Andricdef AMOR__DB_W   : AM_3R<0x386c0000>;
101606c3fb27SDimitry Andricdef AMOR__DB_D   : AM_3R<0x386c8000>;
101706c3fb27SDimitry Andricdef AMXOR__DB_W  : AM_3R<0x386d0000>;
101806c3fb27SDimitry Andricdef AMXOR__DB_D  : AM_3R<0x386d8000>;
101906c3fb27SDimitry Andricdef AMMAX__DB_W  : AM_3R<0x386e0000>;
102006c3fb27SDimitry Andricdef AMMAX__DB_D  : AM_3R<0x386e8000>;
102106c3fb27SDimitry Andricdef AMMIN__DB_W  : AM_3R<0x386f0000>;
102206c3fb27SDimitry Andricdef AMMIN__DB_D  : AM_3R<0x386f8000>;
102306c3fb27SDimitry Andricdef AMMAX__DB_WU : AM_3R<0x38700000>;
102406c3fb27SDimitry Andricdef AMMAX__DB_DU : AM_3R<0x38708000>;
102506c3fb27SDimitry Andricdef AMMIN__DB_WU : AM_3R<0x38710000>;
102606c3fb27SDimitry Andricdef AMMIN__DB_DU : AM_3R<0x38718000>;
10277a6dacacSDimitry Andricdef AMCAS_B     : AM_3R<0x38580000>;
10287a6dacacSDimitry Andricdef AMCAS_H     : AM_3R<0x38588000>;
10297a6dacacSDimitry Andricdef AMCAS_W     : AM_3R<0x38590000>;
10307a6dacacSDimitry Andricdef AMCAS_D     : AM_3R<0x38598000>;
10317a6dacacSDimitry Andricdef AMCAS__DB_B     : AM_3R<0x385a0000>;
10327a6dacacSDimitry Andricdef AMCAS__DB_H     : AM_3R<0x385a8000>;
10337a6dacacSDimitry Andricdef AMCAS__DB_W     : AM_3R<0x385b0000>;
10347a6dacacSDimitry Andricdef AMCAS__DB_D     : AM_3R<0x385b8000>;
103506c3fb27SDimitry Andricdef LL_D : LLBase<0x22000000>;
103606c3fb27SDimitry Andricdef SC_D : SCBase<0x23000000>;
10377a6dacacSDimitry Andricdef SC_Q : SCBase_128<0x38570000>;
10387a6dacacSDimitry Andricdef LLACQ_D : LLBase_ACQ<0x38578800>;
10397a6dacacSDimitry Andricdef SCREL_D : SCBase_REL<0x38578C00>;
104081ad6265SDimitry Andric
104181ad6265SDimitry Andric// CRC Check Instructions
104206c3fb27SDimitry Andricdef CRC_W_B_W  : ALU_3R<0x00240000>;
104306c3fb27SDimitry Andricdef CRC_W_H_W  : ALU_3R<0x00248000>;
104406c3fb27SDimitry Andricdef CRC_W_W_W  : ALU_3R<0x00250000>;
104506c3fb27SDimitry Andricdef CRC_W_D_W  : ALU_3R<0x00258000>;
104606c3fb27SDimitry Andricdef CRCC_W_B_W : ALU_3R<0x00260000>;
104706c3fb27SDimitry Andricdef CRCC_W_H_W : ALU_3R<0x00268000>;
104806c3fb27SDimitry Andricdef CRCC_W_W_W : ALU_3R<0x00270000>;
104906c3fb27SDimitry Andricdef CRCC_W_D_W : ALU_3R<0x00278000>;
105081ad6265SDimitry Andric
105181ad6265SDimitry Andric// Other Miscellaneous Instructions for 64-bits
105206c3fb27SDimitry Andricdef ASRTLE_D : FmtASRT<0x00010000, (outs), (ins GPR:$rj, GPR:$rk),
105306c3fb27SDimitry Andric                       "$rj, $rk">;
105406c3fb27SDimitry Andricdef ASRTGT_D : FmtASRT<0x00018000, (outs), (ins GPR:$rj, GPR:$rk),
105506c3fb27SDimitry Andric                       "$rj, $rk">;
105606c3fb27SDimitry Andricdef RDTIME_D : RDTIME_2R<0x00006800>;
105781ad6265SDimitry Andric} // Predicates = [IsLA64]
105881ad6265SDimitry Andric
105981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
106081ad6265SDimitry Andric// Pseudo-instructions and codegen patterns
106181ad6265SDimitry Andric//
106281ad6265SDimitry Andric// Naming convention: For 'generic' pattern classes, we use the naming
106381ad6265SDimitry Andric// convention PatTy1Ty2.
106481ad6265SDimitry Andric//===----------------------------------------------------------------------===//
106581ad6265SDimitry Andric
106681ad6265SDimitry Andric/// Generic pattern classes
106781ad6265SDimitry Andric
1068*6e516c87SDimitry Andricdef assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
1069*6e516c87SDimitry Andric  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
1070*6e516c87SDimitry Andric}]>;
107181ad6265SDimitry Andricclass PatGprGpr<SDPatternOperator OpNode, LAInst Inst>
107281ad6265SDimitry Andric    : Pat<(OpNode GPR:$rj, GPR:$rk), (Inst GPR:$rj, GPR:$rk)>;
107381ad6265SDimitry Andricclass PatGprGpr_32<SDPatternOperator OpNode, LAInst Inst>
1074*6e516c87SDimitry Andric    : Pat<(sext_inreg (OpNode (assertsexti32 GPR:$rj), (assertsexti32 GPR:$rk)), i32), (Inst GPR:$rj, GPR:$rk)>;
1075bdd1243dSDimitry Andricclass PatGpr<SDPatternOperator OpNode, LAInst Inst>
1076bdd1243dSDimitry Andric    : Pat<(OpNode GPR:$rj), (Inst GPR:$rj)>;
107781ad6265SDimitry Andric
107881ad6265SDimitry Andricclass PatGprImm<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>
107981ad6265SDimitry Andric    : Pat<(OpNode GPR:$rj, ImmOpnd:$imm),
108081ad6265SDimitry Andric          (Inst GPR:$rj, ImmOpnd:$imm)>;
108181ad6265SDimitry Andricclass PatGprImm_32<SDPatternOperator OpNode, LAInst Inst, Operand ImmOpnd>
108281ad6265SDimitry Andric    : Pat<(sext_inreg (OpNode GPR:$rj, ImmOpnd:$imm), i32),
108381ad6265SDimitry Andric          (Inst GPR:$rj, ImmOpnd:$imm)>;
108481ad6265SDimitry Andric
1085bdd1243dSDimitry Andric/// Predicates
1086bdd1243dSDimitry Andricdef AddLike: PatFrags<(ops node:$A, node:$B),
1087bdd1243dSDimitry Andric                      [(add node:$A, node:$B), (or node:$A, node:$B)], [{
10880fca6ea1SDimitry Andric    return CurDAG->isBaseWithConstantOffset(SDValue(N, 0));
1089bdd1243dSDimitry Andric}]>;
1090bdd1243dSDimitry Andric
109181ad6265SDimitry Andric/// Simple arithmetic operations
109281ad6265SDimitry Andric
109381ad6265SDimitry Andric// Match both a plain shift and one where the shift amount is masked (this is
109481ad6265SDimitry Andric// typically introduced when the legalizer promotes the shift amount and
109581ad6265SDimitry Andric// zero-extends it). For LoongArch, the mask is unnecessary as shifts in the
109681ad6265SDimitry Andric// base ISA only read the least significant 5 bits (LA32) or 6 bits (LA64).
109781ad6265SDimitry Andricdef shiftMaskGRLen
109881ad6265SDimitry Andric    : ComplexPattern<GRLenVT, 1, "selectShiftMaskGRLen", [], [], 0>;
109981ad6265SDimitry Andricdef shiftMask32 : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;
110081ad6265SDimitry Andric
1101753f127fSDimitry Andricdef sexti32 : ComplexPattern<i64, 1, "selectSExti32">;
1102753f127fSDimitry Andricdef zexti32 : ComplexPattern<i64, 1, "selectZExti32">;
1103753f127fSDimitry Andric
110481ad6265SDimitry Andricclass shiftop<SDPatternOperator operator>
110581ad6265SDimitry Andric    : PatFrag<(ops node:$val, node:$count),
110681ad6265SDimitry Andric              (operator node:$val, (GRLenVT (shiftMaskGRLen node:$count)))>;
110781ad6265SDimitry Andricclass shiftopw<SDPatternOperator operator>
110881ad6265SDimitry Andric    : PatFrag<(ops node:$val, node:$count),
110981ad6265SDimitry Andric              (operator node:$val, (i64 (shiftMask32 node:$count)))>;
111081ad6265SDimitry Andric
111106c3fb27SDimitry Andricdef mul_const_oneuse : PatFrag<(ops node:$A, node:$B),
111206c3fb27SDimitry Andric                               (mul node:$A, node:$B), [{
111306c3fb27SDimitry Andric  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
111406c3fb27SDimitry Andric    return N1C->hasOneUse();
111506c3fb27SDimitry Andric  return false;
111606c3fb27SDimitry Andric}]>;
111706c3fb27SDimitry Andric
111881ad6265SDimitry Andriclet Predicates = [IsLA32] in {
111981ad6265SDimitry Andricdef : PatGprGpr<add, ADD_W>;
112081ad6265SDimitry Andricdef : PatGprImm<add, ADDI_W, simm12>;
112181ad6265SDimitry Andricdef : PatGprGpr<sub, SUB_W>;
1122753f127fSDimitry Andricdef : PatGprGpr<sdiv, DIV_W>;
1123753f127fSDimitry Andricdef : PatGprGpr<udiv, DIV_WU>;
1124753f127fSDimitry Andricdef : PatGprGpr<srem, MOD_W>;
1125753f127fSDimitry Andricdef : PatGprGpr<urem, MOD_WU>;
1126753f127fSDimitry Andricdef : PatGprGpr<mul, MUL_W>;
1127753f127fSDimitry Andricdef : PatGprGpr<mulhs, MULH_W>;
1128753f127fSDimitry Andricdef : PatGprGpr<mulhu, MULH_WU>;
1129bdd1243dSDimitry Andricdef : PatGprGpr<rotr, ROTR_W>;
1130bdd1243dSDimitry Andricdef : PatGprImm<rotr, ROTRI_W, uimm5>;
113106c3fb27SDimitry Andric
113206c3fb27SDimitry Andricforeach Idx = 1...3 in {
113306c3fb27SDimitry Andric  defvar ShamtA = !mul(8, Idx);
113406c3fb27SDimitry Andric  defvar ShamtB = !mul(8, !sub(4, Idx));
113506c3fb27SDimitry Andric  def : Pat<(or (shl GPR:$rk, (i32 ShamtA)), (srl GPR:$rj, (i32 ShamtB))),
113606c3fb27SDimitry Andric            (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>;
113706c3fb27SDimitry Andric}
113881ad6265SDimitry Andric} // Predicates = [IsLA32]
113981ad6265SDimitry Andric
114081ad6265SDimitry Andriclet Predicates = [IsLA64] in {
114181ad6265SDimitry Andricdef : PatGprGpr<add, ADD_D>;
114281ad6265SDimitry Andricdef : PatGprImm<add, ADDI_D, simm12>;
114381ad6265SDimitry Andricdef : PatGprGpr<sub, SUB_D>;
1144753f127fSDimitry Andricdef : PatGprGpr<sdiv, DIV_D>;
11450fca6ea1SDimitry Andricdef : PatGprGpr_32<sdiv, DIV_W>;
1146753f127fSDimitry Andricdef : PatGprGpr<udiv, DIV_DU>;
11470fca6ea1SDimitry Andricdef : PatGprGpr<loongarch_div_wu, DIV_WU>;
1148753f127fSDimitry Andricdef : PatGprGpr<srem, MOD_D>;
11490fca6ea1SDimitry Andricdef : PatGprGpr_32<srem, MOD_W>;
1150753f127fSDimitry Andricdef : PatGprGpr<urem, MOD_DU>;
11510fca6ea1SDimitry Andricdef : PatGprGpr<loongarch_mod_wu, MOD_WU>;
1152bdd1243dSDimitry Andricdef : PatGprGpr<rotr, ROTR_D>;
1153bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_rotr_w, ROTR_W>;
1154bdd1243dSDimitry Andricdef : PatGprImm<rotr, ROTRI_D, uimm6>;
1155bdd1243dSDimitry Andricdef : PatGprImm_32<rotr, ROTRI_W, uimm5>;
11560fca6ea1SDimitry Andricdef : PatGprImm<loongarch_rotr_w, ROTRI_W, uimm5>;
1157753f127fSDimitry Andric// TODO: Select "_W[U]" instructions for i32xi32 if only lower 32 bits of the
1158753f127fSDimitry Andric// product are used.
1159753f127fSDimitry Andricdef : PatGprGpr<mul, MUL_D>;
1160753f127fSDimitry Andricdef : PatGprGpr<mulhs, MULH_D>;
1161753f127fSDimitry Andricdef : PatGprGpr<mulhu, MULH_DU>;
1162753f127fSDimitry Andric// Select MULW_D_W for calculating the full 64 bits product of i32xi32 signed
1163753f127fSDimitry Andric// multiplication.
1164753f127fSDimitry Andricdef : Pat<(i64 (mul (sext_inreg GPR:$rj, i32), (sext_inreg GPR:$rk, i32))),
1165753f127fSDimitry Andric          (MULW_D_W GPR:$rj, GPR:$rk)>;
1166753f127fSDimitry Andric// Select MULW_D_WU for calculating the full 64 bits product of i32xi32
1167753f127fSDimitry Andric// unsigned multiplication.
1168753f127fSDimitry Andricdef : Pat<(i64 (mul (loongarch_bstrpick GPR:$rj, (i64 31), (i64 0)),
1169753f127fSDimitry Andric                    (loongarch_bstrpick GPR:$rk, (i64 31), (i64 0)))),
1170753f127fSDimitry Andric          (MULW_D_WU GPR:$rj, GPR:$rk)>;
117106c3fb27SDimitry Andric
117206c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, simm16_lsl16:$imm),
117306c3fb27SDimitry Andric          (ADDU16I_D GPR:$rj, (HI16 $imm))>;
117406c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, simm32_hi16_lo12:$imm),
117506c3fb27SDimitry Andric          (ADDI_D (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)),
117606c3fb27SDimitry Andric                  (LO12 $imm))>;
117706c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rj, simm32_hi16_lo12:$imm), i32),
117806c3fb27SDimitry Andric          (ADDI_W (ADDU16I_D GPR:$rj, (HI16ForAddu16idAddiPair $imm)),
117906c3fb27SDimitry Andric                  (LO12 $imm))>;
118006c3fb27SDimitry Andric
118106c3fb27SDimitry Andriclet Predicates = [IsLA32] in {
118206c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, (AddiPair:$im)),
118306c3fb27SDimitry Andric          (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)),
118406c3fb27SDimitry Andric                  (AddiPairImmSmall AddiPair:$im))>;
118506c3fb27SDimitry Andric} // Predicates = [IsLA32]
118606c3fb27SDimitry Andric
118706c3fb27SDimitry Andriclet Predicates = [IsLA64] in {
118806c3fb27SDimitry Andricdef : Pat<(add GPR:$rj, (AddiPair:$im)),
118906c3fb27SDimitry Andric          (ADDI_D (ADDI_D GPR:$rj, (AddiPairImmLarge AddiPair:$im)),
119006c3fb27SDimitry Andric                  (AddiPairImmSmall AddiPair:$im))>;
119106c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rj, (AddiPair:$im)), i32),
119206c3fb27SDimitry Andric          (ADDI_W (ADDI_W GPR:$rj, (AddiPairImmLarge AddiPair:$im)),
119306c3fb27SDimitry Andric                  (AddiPairImmSmall AddiPair:$im))>;
119406c3fb27SDimitry Andric} // Predicates = [IsLA64]
119506c3fb27SDimitry Andric
119606c3fb27SDimitry Andriclet Predicates = [IsLA32] in {
119706c3fb27SDimitry Andricforeach Idx0 = 1...4 in {
119806c3fb27SDimitry Andric  foreach Idx1 = 1...4 in {
119906c3fb27SDimitry Andric    defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1));
120006c3fb27SDimitry Andric    def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)),
120106c3fb27SDimitry Andric              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)),
120206c3fb27SDimitry Andric                      GPR:$r, (i32 Idx1))>;
120306c3fb27SDimitry Andric  }
120406c3fb27SDimitry Andric}
120506c3fb27SDimitry Andricforeach Idx0 = 1...4 in {
120606c3fb27SDimitry Andric  foreach Idx1 = 1...4 in {
120706c3fb27SDimitry Andric    defvar Cb = !add(1, !shl(1, Idx0));
120806c3fb27SDimitry Andric    defvar CImm = !add(Cb, !shl(Cb, Idx1));
120906c3fb27SDimitry Andric    def : Pat<(mul_const_oneuse GPR:$r, (i32 CImm)),
121006c3fb27SDimitry Andric              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)),
121106c3fb27SDimitry Andric                      (ALSL_W GPR:$r, GPR:$r, (i32 Idx0)), (i32 Idx1))>;
121206c3fb27SDimitry Andric  }
121306c3fb27SDimitry Andric}
121406c3fb27SDimitry Andric} // Predicates = [IsLA32]
121506c3fb27SDimitry Andric
121606c3fb27SDimitry Andriclet Predicates = [IsLA64] in {
121706c3fb27SDimitry Andricforeach Idx0 = 1...4 in {
121806c3fb27SDimitry Andric  foreach Idx1 = 1...4 in {
121906c3fb27SDimitry Andric    defvar CImm = !add(1, !shl(!add(1, !shl(1, Idx0)), Idx1));
122006c3fb27SDimitry Andric    def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32),
122106c3fb27SDimitry Andric              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)),
122206c3fb27SDimitry Andric                      GPR:$r, (i64 Idx1))>;
122306c3fb27SDimitry Andric    def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)),
122406c3fb27SDimitry Andric              (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)),
122506c3fb27SDimitry Andric                      GPR:$r, (i64 Idx1))>;
122606c3fb27SDimitry Andric  }
122706c3fb27SDimitry Andric}
122806c3fb27SDimitry Andricforeach Idx0 = 1...4 in {
122906c3fb27SDimitry Andric  foreach Idx1 = 1...4 in {
123006c3fb27SDimitry Andric    defvar Cb = !add(1, !shl(1, Idx0));
123106c3fb27SDimitry Andric    defvar CImm = !add(Cb, !shl(Cb, Idx1));
123206c3fb27SDimitry Andric    def : Pat<(sext_inreg (mul_const_oneuse GPR:$r, (i64 CImm)), i32),
123306c3fb27SDimitry Andric              (ALSL_W (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)),
123406c3fb27SDimitry Andric                      (ALSL_W GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>;
123506c3fb27SDimitry Andric    def : Pat<(mul_const_oneuse GPR:$r, (i64 CImm)),
123606c3fb27SDimitry Andric              (ALSL_D (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)),
123706c3fb27SDimitry Andric                      (ALSL_D GPR:$r, GPR:$r, (i64 Idx0)), (i64 Idx1))>;
123806c3fb27SDimitry Andric  }
123906c3fb27SDimitry Andric}
124006c3fb27SDimitry Andric} // Predicates = [IsLA64]
124106c3fb27SDimitry Andric
124206c3fb27SDimitry Andriclet Predicates = [IsLA32] in {
124306c3fb27SDimitry Andricdef : Pat<(mul GPR:$rj, (AlslSlliImm:$im)),
124406c3fb27SDimitry Andric          (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),
124506c3fb27SDimitry Andric                  (AlslSlliImmI1 AlslSlliImm:$im))>;
124606c3fb27SDimitry Andric} // Predicates = [IsLA32]
124706c3fb27SDimitry Andric
124806c3fb27SDimitry Andriclet Predicates = [IsLA64] in {
124906c3fb27SDimitry Andricdef : Pat<(sext_inreg (mul GPR:$rj, (AlslSlliImm:$im)), i32),
125006c3fb27SDimitry Andric          (SLLI_W (ALSL_W GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),
125106c3fb27SDimitry Andric                  (AlslSlliImmI1 AlslSlliImm:$im))>;
125206c3fb27SDimitry Andricdef : Pat<(mul GPR:$rj, (AlslSlliImm:$im)),
125306c3fb27SDimitry Andric          (SLLI_D (ALSL_D GPR:$rj, GPR:$rj, (AlslSlliImmI0 AlslSlliImm:$im)),
125406c3fb27SDimitry Andric                  (AlslSlliImmI1 AlslSlliImm:$im))>;
125506c3fb27SDimitry Andric} // Predicates = [IsLA64]
125606c3fb27SDimitry Andric
125706c3fb27SDimitry Andricforeach Idx = 1...7 in {
125806c3fb27SDimitry Andric  defvar ShamtA = !mul(8, Idx);
125906c3fb27SDimitry Andric  defvar ShamtB = !mul(8, !sub(8, Idx));
126006c3fb27SDimitry Andric  def : Pat<(or (shl GPR:$rk, (i64 ShamtA)), (srl GPR:$rj, (i64 ShamtB))),
126106c3fb27SDimitry Andric            (BYTEPICK_D GPR:$rj, GPR:$rk, Idx)>;
126206c3fb27SDimitry Andric}
126306c3fb27SDimitry Andric
126406c3fb27SDimitry Andricforeach Idx = 1...3 in {
126506c3fb27SDimitry Andric  defvar ShamtA = !mul(8, Idx);
126606c3fb27SDimitry Andric  defvar ShamtB = !mul(8, !sub(4, Idx));
126706c3fb27SDimitry Andric  // NOTE: the srl node would already be transformed into a loongarch_bstrpick
126806c3fb27SDimitry Andric  // by the time this pattern gets to execute, hence the weird construction.
126906c3fb27SDimitry Andric  def : Pat<(sext_inreg (or (shl GPR:$rk, (i64 ShamtA)),
127006c3fb27SDimitry Andric                            (loongarch_bstrpick GPR:$rj, (i64 31),
127106c3fb27SDimitry Andric                                                         (i64 ShamtB))), i32),
127206c3fb27SDimitry Andric            (BYTEPICK_W GPR:$rj, GPR:$rk, Idx)>;
127306c3fb27SDimitry Andric}
127481ad6265SDimitry Andric} // Predicates = [IsLA64]
127581ad6265SDimitry Andric
127681ad6265SDimitry Andricdef : PatGprGpr<and, AND>;
127781ad6265SDimitry Andricdef : PatGprImm<and, ANDI, uimm12>;
127881ad6265SDimitry Andricdef : PatGprGpr<or, OR>;
127981ad6265SDimitry Andricdef : PatGprImm<or, ORI, uimm12>;
128081ad6265SDimitry Andricdef : PatGprGpr<xor, XOR>;
128181ad6265SDimitry Andricdef : PatGprImm<xor, XORI, uimm12>;
1282bdd1243dSDimitry Andricdef : Pat<(not GPR:$rj), (NOR GPR:$rj, R0)>;
1283bdd1243dSDimitry Andricdef : Pat<(not (or GPR:$rj, GPR:$rk)), (NOR GPR:$rj, GPR:$rk)>;
1284bdd1243dSDimitry Andricdef : Pat<(or GPR:$rj, (not GPR:$rk)), (ORN GPR:$rj, GPR:$rk)>;
1285bdd1243dSDimitry Andricdef : Pat<(and GPR:$rj, (not GPR:$rk)), (ANDN GPR:$rj, GPR:$rk)>;
1286bdd1243dSDimitry Andric
12875f757f3fSDimitry Andriclet Predicates = [IsLA32] in {
12885f757f3fSDimitry Andricdef : Pat<(and GPR:$rj, BstrinsImm:$imm),
12895f757f3fSDimitry Andric          (BSTRINS_W GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm),
12905f757f3fSDimitry Andric                     (BstrinsLsb BstrinsImm:$imm))>;
12915f757f3fSDimitry Andric} // Predicates = [IsLA32]
12925f757f3fSDimitry Andric
12935f757f3fSDimitry Andriclet Predicates = [IsLA64] in {
12945f757f3fSDimitry Andricdef : Pat<(and GPR:$rj, BstrinsImm:$imm),
12955f757f3fSDimitry Andric          (BSTRINS_D GPR:$rj, R0, (BstrinsMsb BstrinsImm:$imm),
12965f757f3fSDimitry Andric                     (BstrinsLsb BstrinsImm:$imm))>;
12975f757f3fSDimitry Andric} // Predicates = [IsLA64]
12985f757f3fSDimitry Andric
1299bdd1243dSDimitry Andric/// Traps
1300bdd1243dSDimitry Andric
1301bdd1243dSDimitry Andric// We lower `trap` to `amswap.w rd:$r0, rk:$r1, rj:$r0`, as this is guaranteed
1302bdd1243dSDimitry Andric// to trap with an INE (non-existent on LA32, explicitly documented to INE on
1303bdd1243dSDimitry Andric// LA64). And the resulting signal is different from `debugtrap` like on some
1304bdd1243dSDimitry Andric// other existing ports so programs/porters might have an easier time.
1305bdd1243dSDimitry Andricdef PseudoUNIMP : Pseudo<(outs), (ins), [(trap)]>,
1306bdd1243dSDimitry Andric                  PseudoInstExpansion<(AMSWAP_W R0, R1, R0)>;
1307bdd1243dSDimitry Andric
1308bdd1243dSDimitry Andric// We lower `debugtrap` to `break 0`, as this is guaranteed to exist and work,
1309bdd1243dSDimitry Andric// even for LA32 Primary. Also, because so far the ISA does not provide a
1310bdd1243dSDimitry Andric// specific trap instruction/kind exclusively for alerting the debugger,
1311bdd1243dSDimitry Andric// every other project uses the generic immediate of 0 for this.
1312bdd1243dSDimitry Andricdef : Pat<(debugtrap), (BREAK 0)>;
1313bdd1243dSDimitry Andric
1314bdd1243dSDimitry Andric/// Bit counting operations
1315bdd1243dSDimitry Andric
1316bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1317bdd1243dSDimitry Andricdef : PatGpr<ctlz, CLZ_D>;
1318bdd1243dSDimitry Andricdef : PatGpr<cttz, CTZ_D>;
1319bdd1243dSDimitry Andricdef : Pat<(ctlz (not GPR:$rj)), (CLO_D GPR:$rj)>;
1320bdd1243dSDimitry Andricdef : Pat<(cttz (not GPR:$rj)), (CTO_D GPR:$rj)>;
1321bdd1243dSDimitry Andricdef : PatGpr<loongarch_clzw, CLZ_W>;
1322bdd1243dSDimitry Andricdef : PatGpr<loongarch_ctzw, CTZ_W>;
1323bdd1243dSDimitry Andricdef : Pat<(loongarch_clzw (not GPR:$rj)), (CLO_W GPR:$rj)>;
1324bdd1243dSDimitry Andricdef : Pat<(loongarch_ctzw (not GPR:$rj)), (CTO_W GPR:$rj)>;
1325bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1326bdd1243dSDimitry Andric
1327bdd1243dSDimitry Andriclet Predicates = [IsLA32] in {
1328bdd1243dSDimitry Andricdef : PatGpr<ctlz, CLZ_W>;
1329bdd1243dSDimitry Andricdef : PatGpr<cttz, CTZ_W>;
1330bdd1243dSDimitry Andricdef : Pat<(ctlz (not GPR:$rj)), (CLO_W GPR:$rj)>;
1331bdd1243dSDimitry Andricdef : Pat<(cttz (not GPR:$rj)), (CTO_W GPR:$rj)>;
1332bdd1243dSDimitry Andric} // Predicates = [IsLA32]
1333bdd1243dSDimitry Andric
1334bdd1243dSDimitry Andric/// FrameIndex calculations
1335bdd1243dSDimitry Andriclet Predicates = [IsLA32] in {
1336bdd1243dSDimitry Andricdef : Pat<(AddLike (i32 BaseAddr:$rj), simm12:$imm12),
1337bdd1243dSDimitry Andric          (ADDI_W (i32 BaseAddr:$rj), simm12:$imm12)>;
1338bdd1243dSDimitry Andric} // Predicates = [IsLA32]
1339bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1340bdd1243dSDimitry Andricdef : Pat<(AddLike (i64 BaseAddr:$rj), simm12:$imm12),
1341bdd1243dSDimitry Andric          (ADDI_D (i64 BaseAddr:$rj), simm12:$imm12)>;
1342bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1343bdd1243dSDimitry Andric
1344bdd1243dSDimitry Andric/// Shifted addition
1345bdd1243dSDimitry Andriclet Predicates = [IsLA32] in {
1346bdd1243dSDimitry Andricdef : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),
1347bdd1243dSDimitry Andric          (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;
1348bdd1243dSDimitry Andric} // Predicates = [IsLA32]
1349bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1350bdd1243dSDimitry Andricdef : Pat<(add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),
1351bdd1243dSDimitry Andric          (ALSL_D GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;
135206c3fb27SDimitry Andricdef : Pat<(sext_inreg (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)), i32),
135306c3fb27SDimitry Andric          (ALSL_W GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;
1354bdd1243dSDimitry Andricdef : Pat<(loongarch_bstrpick (add GPR:$rk, (shl GPR:$rj, uimm2_plus1:$imm2)),
1355bdd1243dSDimitry Andric                              (i64 31), (i64 0)),
1356bdd1243dSDimitry Andric          (ALSL_WU GPR:$rj, GPR:$rk, uimm2_plus1:$imm2)>;
1357bdd1243dSDimitry Andric} // Predicates = [IsLA64]
135881ad6265SDimitry Andric
135981ad6265SDimitry Andric/// Shift
136081ad6265SDimitry Andric
136181ad6265SDimitry Andriclet Predicates = [IsLA32] in {
136281ad6265SDimitry Andricdef : PatGprGpr<shiftop<shl>, SLL_W>;
136381ad6265SDimitry Andricdef : PatGprGpr<shiftop<sra>, SRA_W>;
136481ad6265SDimitry Andricdef : PatGprGpr<shiftop<srl>, SRL_W>;
136581ad6265SDimitry Andricdef : PatGprImm<shl, SLLI_W, uimm5>;
136681ad6265SDimitry Andricdef : PatGprImm<sra, SRAI_W, uimm5>;
136781ad6265SDimitry Andricdef : PatGprImm<srl, SRLI_W, uimm5>;
136881ad6265SDimitry Andric} // Predicates = [IsLA32]
136981ad6265SDimitry Andric
137081ad6265SDimitry Andriclet Predicates = [IsLA64] in {
137181ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_sll_w>, SLL_W>;
137281ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_sra_w>, SRA_W>;
137381ad6265SDimitry Andricdef : PatGprGpr<shiftopw<loongarch_srl_w>, SRL_W>;
137481ad6265SDimitry Andricdef : PatGprGpr<shiftop<shl>, SLL_D>;
137581ad6265SDimitry Andricdef : PatGprGpr<shiftop<sra>, SRA_D>;
137681ad6265SDimitry Andricdef : PatGprGpr<shiftop<srl>, SRL_D>;
137781ad6265SDimitry Andricdef : PatGprImm<shl, SLLI_D, uimm6>;
137881ad6265SDimitry Andricdef : PatGprImm<sra, SRAI_D, uimm6>;
137981ad6265SDimitry Andricdef : PatGprImm<srl, SRLI_D, uimm6>;
138081ad6265SDimitry Andric} // Predicates = [IsLA64]
138181ad6265SDimitry Andric
138281ad6265SDimitry Andric/// sext and zext
138381ad6265SDimitry Andric
138481ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i8), (EXT_W_B GPR:$rj)>;
138581ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i16), (EXT_W_H GPR:$rj)>;
138681ad6265SDimitry Andric
138781ad6265SDimitry Andriclet Predicates = [IsLA64] in {
138881ad6265SDimitry Andricdef : Pat<(sext_inreg GPR:$rj, i32), (ADDI_W GPR:$rj, 0)>;
138981ad6265SDimitry Andric} // Predicates = [IsLA64]
139081ad6265SDimitry Andric
139181ad6265SDimitry Andric/// Setcc
139281ad6265SDimitry Andric
139381ad6265SDimitry Andricdef : PatGprGpr<setlt, SLT>;
139481ad6265SDimitry Andricdef : PatGprImm<setlt, SLTI, simm12>;
139581ad6265SDimitry Andricdef : PatGprGpr<setult, SLTU>;
139681ad6265SDimitry Andricdef : PatGprImm<setult, SLTUI, simm12>;
139781ad6265SDimitry Andric
139881ad6265SDimitry Andric// Define pattern expansions for setcc operations that aren't directly
139981ad6265SDimitry Andric// handled by a LoongArch instruction.
140081ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, 0), (SLTUI GPR:$rj, 1)>;
140181ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, GPR:$rk), (SLTUI (XOR GPR:$rj, GPR:$rk), 1)>;
140281ad6265SDimitry Andriclet Predicates = [IsLA32] in {
140381ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, simm12_plus1:$imm12),
140481ad6265SDimitry Andric          (SLTUI (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>;
140581ad6265SDimitry Andric} // Predicates = [IsLA32]
140681ad6265SDimitry Andriclet Predicates = [IsLA64] in {
140781ad6265SDimitry Andricdef : Pat<(seteq GPR:$rj, simm12_plus1:$imm12),
140881ad6265SDimitry Andric          (SLTUI (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)), 1)>;
140981ad6265SDimitry Andric} // Predicates = [IsLA64]
141081ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, 0), (SLTU R0, GPR:$rj)>;
141181ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, GPR:$rk), (SLTU R0, (XOR GPR:$rj, GPR:$rk))>;
141281ad6265SDimitry Andriclet Predicates = [IsLA32] in {
141381ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, simm12_plus1:$imm12),
141481ad6265SDimitry Andric          (SLTU R0, (ADDI_W GPR:$rj, (NegImm simm12_plus1:$imm12)))>;
141581ad6265SDimitry Andric} // Predicates = [IsLA32]
141681ad6265SDimitry Andriclet Predicates = [IsLA64] in {
141781ad6265SDimitry Andricdef : Pat<(setne GPR:$rj, simm12_plus1:$imm12),
141881ad6265SDimitry Andric          (SLTU R0, (ADDI_D GPR:$rj, (NegImm simm12_plus1:$imm12)))>;
141981ad6265SDimitry Andric} // Predicates = [IsLA64]
142081ad6265SDimitry Andricdef : Pat<(setugt GPR:$rj, GPR:$rk), (SLTU GPR:$rk, GPR:$rj)>;
142181ad6265SDimitry Andricdef : Pat<(setuge GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rj, GPR:$rk), 1)>;
142281ad6265SDimitry Andricdef : Pat<(setule GPR:$rj, GPR:$rk), (XORI (SLTU GPR:$rk, GPR:$rj), 1)>;
142381ad6265SDimitry Andricdef : Pat<(setgt GPR:$rj, GPR:$rk), (SLT GPR:$rk, GPR:$rj)>;
142481ad6265SDimitry Andricdef : Pat<(setge GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rj, GPR:$rk), 1)>;
142581ad6265SDimitry Andricdef : Pat<(setle GPR:$rj, GPR:$rk), (XORI (SLT GPR:$rk, GPR:$rj), 1)>;
142681ad6265SDimitry Andric
142781ad6265SDimitry Andric/// Select
142881ad6265SDimitry Andric
142906c3fb27SDimitry Andricdef : Pat<(select GPR:$cond, GPR:$t, 0), (MASKEQZ GPR:$t, GPR:$cond)>;
143006c3fb27SDimitry Andricdef : Pat<(select GPR:$cond, 0, GPR:$f), (MASKNEZ GPR:$f, GPR:$cond)>;
143181ad6265SDimitry Andricdef : Pat<(select GPR:$cond, GPR:$t, GPR:$f),
143281ad6265SDimitry Andric          (OR (MASKEQZ GPR:$t, GPR:$cond), (MASKNEZ GPR:$f, GPR:$cond))>;
143381ad6265SDimitry Andric
143481ad6265SDimitry Andric/// Branches and jumps
143581ad6265SDimitry Andric
1436753f127fSDimitry Andricclass BccPat<PatFrag CondOp, LAInst Inst>
1437753f127fSDimitry Andric    : Pat<(brcond (GRLenVT (CondOp GPR:$rj, GPR:$rd)), bb:$imm16),
1438753f127fSDimitry Andric          (Inst GPR:$rj, GPR:$rd, bb:$imm16)>;
1439753f127fSDimitry Andric
1440753f127fSDimitry Andricdef : BccPat<seteq, BEQ>;
1441753f127fSDimitry Andricdef : BccPat<setne, BNE>;
1442753f127fSDimitry Andricdef : BccPat<setlt, BLT>;
1443753f127fSDimitry Andricdef : BccPat<setge, BGE>;
1444753f127fSDimitry Andricdef : BccPat<setult, BLTU>;
1445753f127fSDimitry Andricdef : BccPat<setuge, BGEU>;
1446753f127fSDimitry Andric
1447753f127fSDimitry Andricclass BccSwapPat<PatFrag CondOp, LAInst InstBcc>
1448753f127fSDimitry Andric    : Pat<(brcond (GRLenVT (CondOp GPR:$rd, GPR:$rj)), bb:$imm16),
1449753f127fSDimitry Andric          (InstBcc GPR:$rj, GPR:$rd, bb:$imm16)>;
1450753f127fSDimitry Andric
1451753f127fSDimitry Andric// Condition codes that don't have matching LoongArch branch instructions, but
1452753f127fSDimitry Andric// are trivially supported by swapping the two input operands.
1453753f127fSDimitry Andricdef : BccSwapPat<setgt, BLT>;
1454753f127fSDimitry Andricdef : BccSwapPat<setle, BGE>;
1455753f127fSDimitry Andricdef : BccSwapPat<setugt, BLTU>;
1456753f127fSDimitry Andricdef : BccSwapPat<setule, BGEU>;
1457753f127fSDimitry Andric
1458753f127fSDimitry Andric// An extra pattern is needed for a brcond without a setcc (i.e. where the
1459753f127fSDimitry Andric// condition was calculated elsewhere).
1460753f127fSDimitry Andricdef : Pat<(brcond GPR:$rj, bb:$imm21), (BNEZ GPR:$rj, bb:$imm21)>;
1461753f127fSDimitry Andric
1462bdd1243dSDimitry Andricdef : Pat<(brcond (GRLenVT (seteq GPR:$rj, 0)), bb:$imm21),
1463bdd1243dSDimitry Andric          (BEQZ GPR:$rj, bb:$imm21)>;
1464bdd1243dSDimitry Andricdef : Pat<(brcond (GRLenVT (setne GPR:$rj, 0)), bb:$imm21),
1465bdd1243dSDimitry Andric          (BNEZ GPR:$rj, bb:$imm21)>;
1466bdd1243dSDimitry Andric
1467753f127fSDimitry Andriclet isBarrier = 1, isBranch = 1, isTerminator = 1 in
1468bdd1243dSDimitry Andricdef PseudoBR : Pseudo<(outs), (ins simm26_b:$imm26), [(br bb:$imm26)]>,
1469bdd1243dSDimitry Andric               PseudoInstExpansion<(B simm26_b:$imm26)>;
1470753f127fSDimitry Andric
1471753f127fSDimitry Andriclet isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1472bdd1243dSDimitry Andricdef PseudoBRIND : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
1473753f127fSDimitry Andric                  PseudoInstExpansion<(JIRL R0, GPR:$rj, simm16_lsl2:$imm16)>;
1474753f127fSDimitry Andric
1475753f127fSDimitry Andricdef : Pat<(brind GPR:$rj), (PseudoBRIND GPR:$rj, 0)>;
1476753f127fSDimitry Andricdef : Pat<(brind (add GPR:$rj, simm16_lsl2:$imm16)),
1477753f127fSDimitry Andric          (PseudoBRIND GPR:$rj, simm16_lsl2:$imm16)>;
1478753f127fSDimitry Andric
14791db9f3b2SDimitry Andric// Function call with 'Small' code model.
1480753f127fSDimitry Andriclet isCall = 1, Defs = [R1] in
14811db9f3b2SDimitry Andricdef PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func)>;
1482753f127fSDimitry Andric
1483753f127fSDimitry Andricdef : Pat<(loongarch_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
1484753f127fSDimitry Andricdef : Pat<(loongarch_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
1485753f127fSDimitry Andric
14861db9f3b2SDimitry Andric// Function call with 'Medium' code model.
14871db9f3b2SDimitry Andriclet isCall = 1, Defs = [R1, R20], Size = 8 in
14881db9f3b2SDimitry Andricdef PseudoCALL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$func)>;
14891db9f3b2SDimitry Andric
14901db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
14911db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium tglobaladdr:$func),
14921db9f3b2SDimitry Andric          (PseudoCALL_MEDIUM tglobaladdr:$func)>;
14931db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium texternalsym:$func),
14941db9f3b2SDimitry Andric          (PseudoCALL_MEDIUM texternalsym:$func)>;
14951db9f3b2SDimitry Andric} // Predicates = [IsLA64]
14961db9f3b2SDimitry Andric
14971db9f3b2SDimitry Andric// Function call with 'Large' code model.
14981db9f3b2SDimitry Andriclet isCall = 1, Defs = [R1, R20], Size = 24 in
14991db9f3b2SDimitry Andricdef PseudoCALL_LARGE: Pseudo<(outs), (ins bare_symbol:$func)>;
15001db9f3b2SDimitry Andric
15011db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
15021db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large tglobaladdr:$func),
15031db9f3b2SDimitry Andric          (PseudoCALL_LARGE tglobaladdr:$func)>;
15041db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large texternalsym:$func),
15051db9f3b2SDimitry Andric          (PseudoCALL_LARGE texternalsym:$func)>;
15061db9f3b2SDimitry Andric} // Predicates = [IsLA64]
15071db9f3b2SDimitry Andric
1508753f127fSDimitry Andriclet isCall = 1, Defs = [R1] in
1509753f127fSDimitry Andricdef PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rj),
1510753f127fSDimitry Andric                                [(loongarch_call GPR:$rj)]>,
1511753f127fSDimitry Andric                         PseudoInstExpansion<(JIRL R1, GPR:$rj, 0)>;
15121db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
15131db9f3b2SDimitry Andricdef : Pat<(loongarch_call_medium GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
15141db9f3b2SDimitry Andricdef : Pat<(loongarch_call_large GPR:$rj), (PseudoCALLIndirect GPR:$rj)>;
15151db9f3b2SDimitry Andric}
1516753f127fSDimitry Andric
151706c3fb27SDimitry Andriclet isCall = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0, Defs = [R1] in
1518bdd1243dSDimitry Andricdef PseudoJIRL_CALL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
1519bdd1243dSDimitry Andric                      PseudoInstExpansion<(JIRL R1, GPR:$rj,
1520bdd1243dSDimitry Andric                                           simm16_lsl2:$imm16)>;
1521bdd1243dSDimitry Andric
152281ad6265SDimitry Andriclet isBarrier = 1, isReturn = 1, isTerminator = 1 in
152381ad6265SDimitry Andricdef PseudoRET : Pseudo<(outs), (ins), [(loongarch_ret)]>,
152481ad6265SDimitry Andric                PseudoInstExpansion<(JIRL R0, R1, 0)>;
152581ad6265SDimitry Andric
15261db9f3b2SDimitry Andric// Tail call with 'Small' code model.
1527bdd1243dSDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
15281db9f3b2SDimitry Andricdef PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst)>;
1529bdd1243dSDimitry Andric
1530bdd1243dSDimitry Andricdef : Pat<(loongarch_tail (iPTR tglobaladdr:$dst)),
1531bdd1243dSDimitry Andric          (PseudoTAIL tglobaladdr:$dst)>;
1532bdd1243dSDimitry Andricdef : Pat<(loongarch_tail (iPTR texternalsym:$dst)),
1533bdd1243dSDimitry Andric          (PseudoTAIL texternalsym:$dst)>;
1534bdd1243dSDimitry Andric
15351db9f3b2SDimitry Andric// Tail call with 'Medium' code model.
15361db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
15371db9f3b2SDimitry Andric    Uses = [R3], Defs = [R20], Size = 8 in
15381db9f3b2SDimitry Andricdef PseudoTAIL_MEDIUM : Pseudo<(outs), (ins bare_symbol:$dst)>;
15391db9f3b2SDimitry Andric
15401db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
15411db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium (iPTR tglobaladdr:$dst)),
15421db9f3b2SDimitry Andric          (PseudoTAIL_MEDIUM tglobaladdr:$dst)>;
15431db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium (iPTR texternalsym:$dst)),
15441db9f3b2SDimitry Andric          (PseudoTAIL_MEDIUM texternalsym:$dst)>;
15451db9f3b2SDimitry Andric} // Predicates = [IsLA64]
15461db9f3b2SDimitry Andric
15471db9f3b2SDimitry Andric// Tail call with 'Large' code model.
15481db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
15491db9f3b2SDimitry Andric    Uses = [R3], Defs = [R19, R20], Size = 24 in
15501db9f3b2SDimitry Andricdef PseudoTAIL_LARGE : Pseudo<(outs), (ins bare_symbol:$dst)>;
15511db9f3b2SDimitry Andric
15521db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
15531db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large (iPTR tglobaladdr:$dst)),
15541db9f3b2SDimitry Andric          (PseudoTAIL_LARGE tglobaladdr:$dst)>;
15551db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large (iPTR texternalsym:$dst)),
15561db9f3b2SDimitry Andric          (PseudoTAIL_LARGE texternalsym:$dst)>;
15571db9f3b2SDimitry Andric} // Predicates = [IsLA64]
15581db9f3b2SDimitry Andric
1559bdd1243dSDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3] in
1560bdd1243dSDimitry Andricdef PseudoTAILIndirect : Pseudo<(outs), (ins GPRT:$rj),
1561bdd1243dSDimitry Andric                                [(loongarch_tail GPRT:$rj)]>,
1562bdd1243dSDimitry Andric                         PseudoInstExpansion<(JIRL R0, GPR:$rj, 0)>;
15631db9f3b2SDimitry Andriclet Predicates = [IsLA64] in {
15641db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_medium GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
15651db9f3b2SDimitry Andricdef : Pat<(loongarch_tail_large GPR:$rj), (PseudoTAILIndirect GPR:$rj)>;
15661db9f3b2SDimitry Andric}
1567bdd1243dSDimitry Andric
156806c3fb27SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
156906c3fb27SDimitry Andric    hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in
1570bdd1243dSDimitry Andricdef PseudoB_TAIL : Pseudo<(outs), (ins simm26_b:$imm26)>,
1571bdd1243dSDimitry Andric                   PseudoInstExpansion<(B simm26_b:$imm26)>;
1572bdd1243dSDimitry Andric
157306c3fb27SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
157406c3fb27SDimitry Andric    hasSideEffects = 0, mayStore = 0, mayLoad = 0, Uses = [R3] in
1575bdd1243dSDimitry Andricdef PseudoJIRL_TAIL : Pseudo<(outs), (ins GPR:$rj, simm16_lsl2:$imm16)>,
1576bdd1243dSDimitry Andric                      PseudoInstExpansion<(JIRL R0, GPR:$rj,
1577bdd1243dSDimitry Andric                                           simm16_lsl2:$imm16)>;
1578bdd1243dSDimitry Andric
15791db9f3b2SDimitry Andric/// call36/taill36 macro instructions
15801db9f3b2SDimitry Andriclet isCall = 1, isBarrier = 1, isCodeGenOnly = 0, isAsmParserOnly = 1,
15811db9f3b2SDimitry Andric    Defs = [R1], Size = 8, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
15821db9f3b2SDimitry Andricdef PseudoCALL36 : Pseudo<(outs), (ins bare_symbol:$dst), [],
15831db9f3b2SDimitry Andric                          "call36", "$dst">,
15841db9f3b2SDimitry Andric                   Requires<[IsLA64]>;
15851db9f3b2SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [R3],
15861db9f3b2SDimitry Andric    isCodeGenOnly = 0, isAsmParserOnly = 1, Size = 8, hasSideEffects = 0,
15871db9f3b2SDimitry Andric    mayStore = 0, mayLoad = 0 in
15881db9f3b2SDimitry Andricdef PseudoTAIL36 : Pseudo<(outs), (ins GPR:$tmp, bare_symbol:$dst), [],
15891db9f3b2SDimitry Andric                          "tail36", "$tmp, $dst">,
15901db9f3b2SDimitry Andric                   Requires<[IsLA64]>;
15911db9f3b2SDimitry Andric
15920fca6ea1SDimitry Andric// This is a special case of the ADD_W/D instruction used to facilitate the use
15930fca6ea1SDimitry Andric// of a fourth operand to emit a relocation on a symbol relating to this
15940fca6ea1SDimitry Andric// instruction. The relocation does not affect any bits of the instruction itself
15950fca6ea1SDimitry Andric// but is used as a hint to the linker.
15960fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in {
15970fca6ea1SDimitry Andricdef PseudoAddTPRel_W : Pseudo<(outs GPR:$rd),
15980fca6ea1SDimitry Andric                              (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [],
15990fca6ea1SDimitry Andric                              "add.w", "$rd, $rj, $rk, $sym">,
16000fca6ea1SDimitry Andric                              Requires<[IsLA32]>;
16010fca6ea1SDimitry Andricdef PseudoAddTPRel_D : Pseudo<(outs GPR:$rd),
16020fca6ea1SDimitry Andric                              (ins GPR:$rj, GPR:$rk, tprel_add_symbol:$sym), [],
16030fca6ea1SDimitry Andric                              "add.d", "$rd, $rj, $rk, $sym">,
16040fca6ea1SDimitry Andric                              Requires<[IsLA64]>;
16050fca6ea1SDimitry Andric}
16060fca6ea1SDimitry Andric
1607bdd1243dSDimitry Andric/// Load address (la*) macro instructions.
1608bdd1243dSDimitry Andric
1609bdd1243dSDimitry Andric// Define isCodeGenOnly = 0 to expose them to tablegened assembly parser.
1610bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
1611bdd1243dSDimitry Andric    isAsmParserOnly = 1 in {
1612bdd1243dSDimitry Andricdef PseudoLA_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1613bdd1243dSDimitry Andric                          "la.abs", "$dst, $src">;
1614bdd1243dSDimitry Andricdef PseudoLA_ABS_LARGE : Pseudo<(outs GPR:$dst),
1615bdd1243dSDimitry Andric                                (ins GPR:$tmp, bare_symbol:$src), [],
1616bdd1243dSDimitry Andric                                "la.abs", "$dst, $src">;
1617bdd1243dSDimitry Andricdef PseudoLA_PCREL : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1618bdd1243dSDimitry Andric                            "la.pcrel", "$dst, $src">;
16190fca6ea1SDimitry Andricdef PseudoLA_TLS_LD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
16200fca6ea1SDimitry Andric                             "la.tls.ld", "$dst, $src">;
16210fca6ea1SDimitry Andricdef PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
16220fca6ea1SDimitry Andric                             "la.tls.gd", "$dst, $src">;
16230fca6ea1SDimitry Andriclet Defs = [R20], Size = 20 in {
1624bdd1243dSDimitry Andricdef PseudoLA_PCREL_LARGE : Pseudo<(outs GPR:$dst),
1625bdd1243dSDimitry Andric                                  (ins GPR:$tmp, bare_symbol:$src), [],
1626bdd1243dSDimitry Andric                                  "la.pcrel", "$dst, $tmp, $src">,
1627bdd1243dSDimitry Andric                           Requires<[IsLA64]>;
1628bdd1243dSDimitry Andricdef PseudoLA_TLS_LE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1629bdd1243dSDimitry Andric                             "la.tls.le", "$dst, $src">;
1630bdd1243dSDimitry Andricdef PseudoLA_TLS_LD_LARGE : Pseudo<(outs GPR:$dst),
1631bdd1243dSDimitry Andric                                   (ins GPR:$tmp, bare_symbol:$src), [],
1632bdd1243dSDimitry Andric                                   "la.tls.ld", "$dst, $tmp, $src">,
1633bdd1243dSDimitry Andric                            Requires<[IsLA64]>;
1634bdd1243dSDimitry Andricdef PseudoLA_TLS_GD_LARGE : Pseudo<(outs GPR:$dst),
1635bdd1243dSDimitry Andric                                   (ins GPR:$tmp, bare_symbol:$src), [],
1636bdd1243dSDimitry Andric                                   "la.tls.gd", "$dst, $tmp, $src">,
1637bdd1243dSDimitry Andric                            Requires<[IsLA64]>;
16381db9f3b2SDimitry Andric} // Defs = [R20], Size = 20
1639bdd1243dSDimitry Andric}
16400fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
16410fca6ea1SDimitry Andric    isAsmParserOnly = 1 in {
16420fca6ea1SDimitry Andricdef PseudoLA_GOT : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
16430fca6ea1SDimitry Andric                          "la.got", "$dst, $src">;
16440fca6ea1SDimitry Andricdef PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
16450fca6ea1SDimitry Andric                             "la.tls.ie", "$dst, $src">;
16460fca6ea1SDimitry Andriclet Defs = [R20], Size = 20 in {
16470fca6ea1SDimitry Andricdef PseudoLA_GOT_LARGE : Pseudo<(outs GPR:$dst),
16480fca6ea1SDimitry Andric                                (ins GPR:$tmp, bare_symbol:$src), [],
16490fca6ea1SDimitry Andric                                "la.got", "$dst, $tmp, $src">,
16500fca6ea1SDimitry Andric                         Requires<[IsLA64]>;
16510fca6ea1SDimitry Andricdef PseudoLA_TLS_IE_LARGE : Pseudo<(outs GPR:$dst),
16520fca6ea1SDimitry Andric                                   (ins GPR:$tmp, bare_symbol:$src), [],
16530fca6ea1SDimitry Andric                                   "la.tls.ie", "$dst, $tmp, $src">,
16540fca6ea1SDimitry Andric                            Requires<[IsLA64]>;
16550fca6ea1SDimitry Andric} // Defs = [R20], Size = 20
16560fca6ea1SDimitry Andric}
16570fca6ea1SDimitry Andric
16580fca6ea1SDimitry Andric// Used for expand PseudoLA_TLS_DESC_* instructions.
16590fca6ea1SDimitry Andriclet isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0,
16600fca6ea1SDimitry Andric    Defs = [R4], Uses = [R4] in
16610fca6ea1SDimitry Andricdef PseudoDESC_CALL : Pseudo<(outs GPR:$rd), (ins GPR:$rj, simm16_lsl2:$imm16)>,
16620fca6ea1SDimitry Andric                      PseudoInstExpansion<(JIRL GPR:$rd, GPR:$rj,
16630fca6ea1SDimitry Andric                                           simm16_lsl2:$imm16)>;
16640fca6ea1SDimitry Andric
16650fca6ea1SDimitry Andric// TLSDESC
16660fca6ea1SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
16670fca6ea1SDimitry Andric    isAsmParserOnly = 1, Defs = [R1] in {
16680fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_ABS : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src),
16690fca6ea1SDimitry Andric                                   [], "la.tls.desc", "$dst, $src">,
16700fca6ea1SDimitry Andric                                   Requires<[IsLA32, HasLaGlobalWithAbs]>;
16710fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_ABS_LARGE : Pseudo<(outs GPR:$dst),
16720fca6ea1SDimitry Andric                                         (ins GPR:$tmp, bare_symbol:$src), [],
16730fca6ea1SDimitry Andric                                         "la.tls.desc", "$dst, $src">,
16740fca6ea1SDimitry Andric                                  Requires<[IsLA64, HasLaGlobalWithAbs]>;
16750fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_PC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
16760fca6ea1SDimitry Andric                                  "la.tls.desc", "$dst, $src">;
16770fca6ea1SDimitry Andric}
16780fca6ea1SDimitry Andric
16790fca6ea1SDimitry Andriclet isCall = 1, isBarrier = 1, hasSideEffects = 0, mayStore = 0, mayLoad = 0,
16800fca6ea1SDimitry Andric    isCodeGenOnly = 0, isAsmParserOnly = 1, Defs = [R1, R4, R20], Size = 32 in
16810fca6ea1SDimitry Andricdef PseudoLA_TLS_DESC_PC_LARGE : Pseudo<(outs GPR:$dst),
16820fca6ea1SDimitry Andric                                        (ins GPR:$tmp, bare_symbol:$src), [],
16830fca6ea1SDimitry Andric                                        "la.tls.desc", "$dst, $tmp, $src">,
16840fca6ea1SDimitry Andric                                 Requires<[IsLA64]>;
1685bdd1243dSDimitry Andric
1686bdd1243dSDimitry Andric// Load address inst alias: "la", "la.global" and "la.local".
1687bdd1243dSDimitry Andric// Default:
1688bdd1243dSDimitry Andric//     la = la.global = la.got
1689bdd1243dSDimitry Andric//     la.local = la.pcrel
1690bdd1243dSDimitry Andric// With feature "+la-global-with-pcrel":
1691bdd1243dSDimitry Andric//     la = la.global = la.pcrel
1692bdd1243dSDimitry Andric// With feature "+la-global-with-abs":
1693bdd1243dSDimitry Andric//     la = la.global = la.abs
1694bdd1243dSDimitry Andric// With feature "+la-local-with-abs":
1695bdd1243dSDimitry Andric//     la.local = la.abs
1696bdd1243dSDimitry Andric// With features "+la-global-with-pcrel,+la-global-with-abs"(disorder):
1697bdd1243dSDimitry Andric//     la = la.global = la.pcrel
1698bdd1243dSDimitry Andric// Note: To keep consistent with gnu-as behavior, the "la" can only have one
1699bdd1243dSDimitry Andric//       register operand.
1700bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>;
1701bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src",
1702bdd1243dSDimitry Andric                (PseudoLA_GOT GPR:$dst, bare_symbol:$src)>;
1703bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src",
1704bdd1243dSDimitry Andric                (PseudoLA_GOT_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;
1705bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $src",
1706bdd1243dSDimitry Andric                (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;
1707bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $tmp, $src",
1708bdd1243dSDimitry Andric                (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;
1709bdd1243dSDimitry Andric
1710bdd1243dSDimitry Andric// Note: Keep HasLaGlobalWithPcrel before HasLaGlobalWithAbs to ensure
1711bdd1243dSDimitry Andric// "la-global-with-pcrel" takes effect when bose "la-global-with-pcrel" and
1712bdd1243dSDimitry Andric// "la-global-with-abs" are enabled.
1713bdd1243dSDimitry Andriclet Predicates = [HasLaGlobalWithPcrel] in {
1714bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;
1715bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src",
1716bdd1243dSDimitry Andric                (PseudoLA_PCREL GPR:$dst, bare_symbol:$src)>;
1717bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src",
1718bdd1243dSDimitry Andric                (PseudoLA_PCREL_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;
1719bdd1243dSDimitry Andric} // Predicates = [HasLaGlobalWithPcrel]
1720bdd1243dSDimitry Andric
1721bdd1243dSDimitry Andriclet Predicates = [HasLaGlobalWithAbs] in {
1722bdd1243dSDimitry Andricdef : InstAlias<"la $dst, $src", (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;
1723bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $src",
1724bdd1243dSDimitry Andric                (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;
1725bdd1243dSDimitry Andricdef : InstAlias<"la.global $dst, $tmp, $src",
1726bdd1243dSDimitry Andric                (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;
1727bdd1243dSDimitry Andric} // Predicates = [HasLaGlobalWithAbs]
1728bdd1243dSDimitry Andric
1729bdd1243dSDimitry Andriclet Predicates = [HasLaLocalWithAbs] in {
1730bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $src",
1731bdd1243dSDimitry Andric                (PseudoLA_ABS GPR:$dst, bare_symbol:$src)>;
1732bdd1243dSDimitry Andricdef : InstAlias<"la.local $dst, $tmp, $src",
1733bdd1243dSDimitry Andric                (PseudoLA_ABS_LARGE GPR:$dst, GPR:$tmp, bare_symbol:$src)>;
1734bdd1243dSDimitry Andric} // Predicates = [HasLaLocalWithAbs]
1735bdd1243dSDimitry Andric
1736753f127fSDimitry Andric/// BSTRINS and BSTRPICK
173781ad6265SDimitry Andric
1738753f127fSDimitry Andriclet Predicates = [IsLA32] in {
1739753f127fSDimitry Andricdef : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd),
1740753f127fSDimitry Andric          (BSTRINS_W GPR:$rd, GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>;
174181ad6265SDimitry Andricdef : Pat<(loongarch_bstrpick GPR:$rj, uimm5:$msbd, uimm5:$lsbd),
174281ad6265SDimitry Andric          (BSTRPICK_W GPR:$rj, uimm5:$msbd, uimm5:$lsbd)>;
1743753f127fSDimitry Andric} // Predicates = [IsLA32]
174481ad6265SDimitry Andric
1745753f127fSDimitry Andriclet Predicates = [IsLA64] in {
1746753f127fSDimitry Andricdef : Pat<(loongarch_bstrins GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd),
1747753f127fSDimitry Andric          (BSTRINS_D GPR:$rd, GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>;
174881ad6265SDimitry Andricdef : Pat<(loongarch_bstrpick GPR:$rj, uimm6:$msbd, uimm6:$lsbd),
174981ad6265SDimitry Andric          (BSTRPICK_D GPR:$rj, uimm6:$msbd, uimm6:$lsbd)>;
1750753f127fSDimitry Andric} // Predicates = [IsLA64]
1751753f127fSDimitry Andric
1752bdd1243dSDimitry Andric/// Byte-swapping and bit-reversal
1753bdd1243dSDimitry Andric
1754bdd1243dSDimitry Andricdef : Pat<(loongarch_revb_2h GPR:$rj), (REVB_2H GPR:$rj)>;
1755bdd1243dSDimitry Andricdef : Pat<(loongarch_bitrev_4b GPR:$rj), (BITREV_4B GPR:$rj)>;
1756bdd1243dSDimitry Andric
1757bdd1243dSDimitry Andriclet Predicates = [IsLA32] in {
1758bdd1243dSDimitry Andricdef : Pat<(bswap GPR:$rj), (ROTRI_W (REVB_2H GPR:$rj), 16)>;
1759bdd1243dSDimitry Andricdef : Pat<(bitreverse GPR:$rj), (BITREV_W GPR:$rj)>;
1760bdd1243dSDimitry Andricdef : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_4B GPR:$rj)>;
1761bdd1243dSDimitry Andricdef : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_4B GPR:$rj)>;
1762bdd1243dSDimitry Andric} // Predicates = [IsLA32]
1763bdd1243dSDimitry Andric
1764bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1765bdd1243dSDimitry Andricdef : Pat<(loongarch_revb_2w GPR:$rj), (REVB_2W GPR:$rj)>;
1766bdd1243dSDimitry Andricdef : Pat<(bswap GPR:$rj), (REVB_D GPR:$rj)>;
1767bdd1243dSDimitry Andricdef : Pat<(loongarch_bitrev_w GPR:$rj), (BITREV_W GPR:$rj)>;
1768bdd1243dSDimitry Andricdef : Pat<(bitreverse GPR:$rj), (BITREV_D GPR:$rj)>;
1769bdd1243dSDimitry Andricdef : Pat<(bswap (bitreverse GPR:$rj)), (BITREV_8B GPR:$rj)>;
1770bdd1243dSDimitry Andricdef : Pat<(bitreverse (bswap GPR:$rj)), (BITREV_8B GPR:$rj)>;
1771bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1772bdd1243dSDimitry Andric
1773753f127fSDimitry Andric/// Loads
1774753f127fSDimitry Andric
1775753f127fSDimitry Andricmulticlass LdPat<PatFrag LoadOp, LAInst Inst, ValueType vt = GRLenVT> {
1776753f127fSDimitry Andric  def : Pat<(vt (LoadOp BaseAddr:$rj)), (Inst BaseAddr:$rj, 0)>;
177706c3fb27SDimitry Andric  def : Pat<(vt (LoadOp (AddrConstant GPR:$rj, simm12:$imm12))),
177806c3fb27SDimitry Andric            (Inst GPR:$rj, simm12:$imm12)>;
1779bdd1243dSDimitry Andric  def : Pat<(vt (LoadOp (AddLike BaseAddr:$rj, simm12:$imm12))),
1780753f127fSDimitry Andric            (Inst BaseAddr:$rj, simm12:$imm12)>;
1781753f127fSDimitry Andric}
1782753f127fSDimitry Andric
1783753f127fSDimitry Andricdefm : LdPat<sextloadi8, LD_B>;
1784753f127fSDimitry Andricdefm : LdPat<extloadi8, LD_B>;
1785753f127fSDimitry Andricdefm : LdPat<sextloadi16, LD_H>;
1786753f127fSDimitry Andricdefm : LdPat<extloadi16, LD_H>;
1787753f127fSDimitry Andricdefm : LdPat<load, LD_W>, Requires<[IsLA32]>;
1788753f127fSDimitry Andricdefm : LdPat<zextloadi8, LD_BU>;
1789753f127fSDimitry Andricdefm : LdPat<zextloadi16, LD_HU>;
1790753f127fSDimitry Andriclet Predicates = [IsLA64] in {
1791753f127fSDimitry Andricdefm : LdPat<sextloadi32, LD_W, i64>;
1792753f127fSDimitry Andricdefm : LdPat<extloadi32, LD_W, i64>;
1793753f127fSDimitry Andricdefm : LdPat<zextloadi32, LD_WU, i64>;
1794753f127fSDimitry Andricdefm : LdPat<load, LD_D, i64>;
1795753f127fSDimitry Andric} // Predicates = [IsLA64]
1796753f127fSDimitry Andric
1797bdd1243dSDimitry Andric// LA64 register-register-addressed loads
1798bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1799bdd1243dSDimitry Andricclass RegRegLdPat<PatFrag LoadOp, LAInst Inst, ValueType vt>
1800bdd1243dSDimitry Andric  : Pat<(vt (LoadOp (add NonFIBaseAddr:$rj, GPR:$rk))),
1801bdd1243dSDimitry Andric        (Inst NonFIBaseAddr:$rj, GPR:$rk)>;
1802bdd1243dSDimitry Andric
1803bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi8, LDX_B, i64>;
1804bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi8, LDX_B, i64>;
1805bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi8, LDX_BU, i64>;
1806bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi16, LDX_H, i64>;
1807bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi16, LDX_H, i64>;
1808bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi16, LDX_HU, i64>;
1809bdd1243dSDimitry Andricdef : RegRegLdPat<extloadi32, LDX_W, i64>;
1810bdd1243dSDimitry Andricdef : RegRegLdPat<sextloadi32, LDX_W, i64>;
1811bdd1243dSDimitry Andricdef : RegRegLdPat<zextloadi32, LDX_WU, i64>;
1812bdd1243dSDimitry Andricdef : RegRegLdPat<load, LDX_D, i64>;
1813bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1814bdd1243dSDimitry Andric
1815753f127fSDimitry Andric/// Stores
1816753f127fSDimitry Andric
1817753f127fSDimitry Andricmulticlass StPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,
1818753f127fSDimitry Andric                 ValueType vt> {
1819753f127fSDimitry Andric  def : Pat<(StoreOp (vt StTy:$rd), BaseAddr:$rj),
1820753f127fSDimitry Andric            (Inst StTy:$rd, BaseAddr:$rj, 0)>;
182106c3fb27SDimitry Andric  def : Pat<(StoreOp (vt StTy:$rs2), (AddrConstant GPR:$rj, simm12:$imm12)),
182206c3fb27SDimitry Andric            (Inst StTy:$rs2, GPR:$rj, simm12:$imm12)>;
1823bdd1243dSDimitry Andric  def : Pat<(StoreOp (vt StTy:$rd), (AddLike BaseAddr:$rj, simm12:$imm12)),
1824753f127fSDimitry Andric            (Inst StTy:$rd, BaseAddr:$rj, simm12:$imm12)>;
1825753f127fSDimitry Andric}
1826753f127fSDimitry Andric
1827753f127fSDimitry Andricdefm : StPat<truncstorei8, ST_B, GPR, GRLenVT>;
1828753f127fSDimitry Andricdefm : StPat<truncstorei16, ST_H, GPR, GRLenVT>;
1829753f127fSDimitry Andricdefm : StPat<store, ST_W, GPR, i32>, Requires<[IsLA32]>;
1830753f127fSDimitry Andriclet Predicates = [IsLA64] in {
1831753f127fSDimitry Andricdefm : StPat<truncstorei32, ST_W, GPR, i64>;
1832753f127fSDimitry Andricdefm : StPat<store, ST_D, GPR, i64>;
1833753f127fSDimitry Andric} // Predicates = [IsLA64]
1834753f127fSDimitry Andric
1835bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1836bdd1243dSDimitry Andricdef : Pat<(i64 (sextloadi32 (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))),
1837bdd1243dSDimitry Andric          (LDPTR_W BaseAddr:$rj, simm14_lsl2:$imm14)>;
1838bdd1243dSDimitry Andricdef : Pat<(i64 (load (AddLike BaseAddr:$rj, simm14_lsl2:$imm14))),
1839bdd1243dSDimitry Andric          (LDPTR_D BaseAddr:$rj, simm14_lsl2:$imm14)>;
1840bdd1243dSDimitry Andricdef : Pat<(truncstorei32 (i64 GPR:$rd),
1841bdd1243dSDimitry Andric                         (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)),
1842bdd1243dSDimitry Andric          (STPTR_W GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>;
1843bdd1243dSDimitry Andricdef : Pat<(store (i64 GPR:$rd), (AddLike BaseAddr:$rj, simm14_lsl2:$imm14)),
1844bdd1243dSDimitry Andric          (STPTR_D GPR:$rd, BaseAddr:$rj, simm14_lsl2:$imm14)>;
1845bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1846bdd1243dSDimitry Andric
1847bdd1243dSDimitry Andric// LA64 register-register-addressed stores
1848bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
1849bdd1243dSDimitry Andricclass RegRegStPat<PatFrag StoreOp, LAInst Inst, RegisterClass StTy,
1850bdd1243dSDimitry Andric                  ValueType vt>
1851bdd1243dSDimitry Andric  : Pat<(StoreOp (vt StTy:$rd), (add NonFIBaseAddr:$rj, GPR:$rk)),
1852bdd1243dSDimitry Andric        (Inst StTy:$rd, NonFIBaseAddr:$rj, GPR:$rk)>;
1853bdd1243dSDimitry Andric
1854bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei8, STX_B, GPR, i64>;
1855bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei16, STX_H, GPR, i64>;
1856bdd1243dSDimitry Andricdef : RegRegStPat<truncstorei32, STX_W, GPR, i64>;
1857bdd1243dSDimitry Andricdef : RegRegStPat<store, STX_D, GPR, i64>;
1858bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1859bdd1243dSDimitry Andric
1860753f127fSDimitry Andric/// Atomic loads and stores
1861753f127fSDimitry Andric
18625f757f3fSDimitry Andric// DBAR hint encoding for LA664 and later micro-architectures, paraphrased from
18635f757f3fSDimitry Andric// the Linux patch revealing it [1]:
18645f757f3fSDimitry Andric//
18655f757f3fSDimitry Andric// - Bit 4: kind of constraint (0: completion, 1: ordering)
18665f757f3fSDimitry Andric// - Bit 3: barrier for previous read (0: true, 1: false)
18675f757f3fSDimitry Andric// - Bit 2: barrier for previous write (0: true, 1: false)
18685f757f3fSDimitry Andric// - Bit 1: barrier for succeeding read (0: true, 1: false)
18695f757f3fSDimitry Andric// - Bit 0: barrier for succeeding write (0: true, 1: false)
18705f757f3fSDimitry Andric//
18715f757f3fSDimitry Andric// Hint 0x700: barrier for "read after read" from the same address, which is
18725f757f3fSDimitry Andric// e.g. needed by LL-SC loops on older models. (DBAR 0x700 behaves the same as
18735f757f3fSDimitry Andric// nop if such reordering is disabled on supporting newer models.)
18745f757f3fSDimitry Andric//
18755f757f3fSDimitry Andric// [1]: https://lore.kernel.org/loongarch/20230516124536.535343-1-chenhuacai@loongson.cn/
18765f757f3fSDimitry Andric//
18775f757f3fSDimitry Andric// Implementations without support for the finer-granularity hints simply treat
18785f757f3fSDimitry Andric// all as the full barrier (DBAR 0), so we can unconditionally start emiting the
18795f757f3fSDimitry Andric// more precise hints right away.
18805f757f3fSDimitry Andric
18815f757f3fSDimitry Andricdef : Pat<(atomic_fence 4, timm), (DBAR 0b10100)>; // acquire
18825f757f3fSDimitry Andricdef : Pat<(atomic_fence 5, timm), (DBAR 0b10010)>; // release
18835f757f3fSDimitry Andricdef : Pat<(atomic_fence 6, timm), (DBAR 0b10000)>; // acqrel
18845f757f3fSDimitry Andricdef : Pat<(atomic_fence 7, timm), (DBAR 0b10000)>; // seqcst
1885753f127fSDimitry Andric
1886753f127fSDimitry Andricdefm : LdPat<atomic_load_8, LD_B>;
1887753f127fSDimitry Andricdefm : LdPat<atomic_load_16, LD_H>;
1888753f127fSDimitry Andricdefm : LdPat<atomic_load_32, LD_W>;
1889753f127fSDimitry Andric
1890bdd1243dSDimitry Andricclass release_seqcst_store<PatFrag base>
18915f757f3fSDimitry Andric    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{
1892bdd1243dSDimitry Andric  AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();
1893bdd1243dSDimitry Andric  return isReleaseOrStronger(Ordering);
1894bdd1243dSDimitry Andric}]>;
1895bdd1243dSDimitry Andric
1896bdd1243dSDimitry Andricclass unordered_monotonic_store<PatFrag base>
18975f757f3fSDimitry Andric    : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr), [{
1898bdd1243dSDimitry Andric  AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getSuccessOrdering();
1899bdd1243dSDimitry Andric  return !isReleaseOrStronger(Ordering);
1900bdd1243dSDimitry Andric}]>;
1901bdd1243dSDimitry Andric
1902bdd1243dSDimitry Andricdef atomic_store_release_seqcst_32 : release_seqcst_store<atomic_store_32>;
1903bdd1243dSDimitry Andricdef atomic_store_release_seqcst_64 : release_seqcst_store<atomic_store_64>;
1904bdd1243dSDimitry Andricdef atomic_store_unordered_monotonic_32
1905bdd1243dSDimitry Andric    : unordered_monotonic_store<atomic_store_32>;
1906bdd1243dSDimitry Andricdef atomic_store_unordered_monotonic_64
1907bdd1243dSDimitry Andric    : unordered_monotonic_store<atomic_store_64>;
1908bdd1243dSDimitry Andric
19095f757f3fSDimitry Andricdefm : StPat<atomic_store_8, ST_B, GPR, GRLenVT>;
19105f757f3fSDimitry Andricdefm : StPat<atomic_store_16, ST_H, GPR, GRLenVT>;
19115f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i32>,
1912bdd1243dSDimitry Andric                   Requires<[IsLA32]>;
1913bdd1243dSDimitry Andric
1914bdd1243dSDimitry Andricdef PseudoAtomicStoreW
19155f757f3fSDimitry Andric  : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>,
191606c3fb27SDimitry Andric           PseudoInstExpansion<(AMSWAP__DB_W R0, GPR:$rk, GPRMemAtomic:$rj)>;
1917bdd1243dSDimitry Andric
1918bdd1243dSDimitry Andricdef : Pat<(atomic_store_release_seqcst_32 GPR:$rj, GPR:$rk),
1919bdd1243dSDimitry Andric          (PseudoAtomicStoreW GPR:$rj, GPR:$rk)>;
1920bdd1243dSDimitry Andric
1921753f127fSDimitry Andriclet Predicates = [IsLA64] in {
1922bdd1243dSDimitry Andricdef PseudoAtomicStoreD
19235f757f3fSDimitry Andric  : Pseudo<(outs GPR:$dst), (ins GPR:$rk, GPR:$rj)>,
192406c3fb27SDimitry Andric           PseudoInstExpansion<(AMSWAP__DB_D R0, GPR:$rk, GPRMemAtomic:$rj)>;
1925bdd1243dSDimitry Andric
1926bdd1243dSDimitry Andricdef : Pat<(atomic_store_release_seqcst_64 GPR:$rj, GPR:$rk),
1927bdd1243dSDimitry Andric          (PseudoAtomicStoreD GPR:$rj, GPR:$rk)>;
1928bdd1243dSDimitry Andric
1929753f127fSDimitry Andricdefm : LdPat<atomic_load_64, LD_D>;
19305f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_32, ST_W, GPR, i64>;
19315f757f3fSDimitry Andricdefm : StPat<atomic_store_unordered_monotonic_64, ST_D, GPR, i64>;
1932bdd1243dSDimitry Andric} // Predicates = [IsLA64]
1933bdd1243dSDimitry Andric
1934bdd1243dSDimitry Andric/// Atomic Ops
1935bdd1243dSDimitry Andric
1936bdd1243dSDimitry Andricclass PseudoMaskedAM
1937bdd1243dSDimitry Andric    : Pseudo<(outs GPR:$res, GPR:$scratch),
1938bdd1243dSDimitry Andric             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> {
1939bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1940bdd1243dSDimitry Andric  let mayLoad = 1;
1941bdd1243dSDimitry Andric  let mayStore = 1;
1942bdd1243dSDimitry Andric  let hasSideEffects = 0;
1943bdd1243dSDimitry Andric  let Size = 36;
1944bdd1243dSDimitry Andric}
1945bdd1243dSDimitry Andric
1946bdd1243dSDimitry Andricdef PseudoMaskedAtomicSwap32 : PseudoMaskedAM;
1947bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadAdd32 : PseudoMaskedAM;
1948bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadSub32 : PseudoMaskedAM;
1949bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadNand32 : PseudoMaskedAM;
1950bdd1243dSDimitry Andric
1951bdd1243dSDimitry Andricclass PseudoAM : Pseudo<(outs GPR:$res, GPR:$scratch),
1952bdd1243dSDimitry Andric                        (ins GPR:$addr, GPR:$incr, grlenimm:$ordering)> {
1953bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1954bdd1243dSDimitry Andric  let mayLoad = 1;
1955bdd1243dSDimitry Andric  let mayStore = 1;
1956bdd1243dSDimitry Andric  let hasSideEffects = 0;
1957bdd1243dSDimitry Andric  let Size = 24;
1958bdd1243dSDimitry Andric}
1959bdd1243dSDimitry Andric
1960bdd1243dSDimitry Andricdef PseudoAtomicSwap32 : PseudoAM;
1961bdd1243dSDimitry Andricdef PseudoAtomicLoadNand32 : PseudoAM;
1962bdd1243dSDimitry Andricdef PseudoAtomicLoadNand64 : PseudoAM;
1963bdd1243dSDimitry Andricdef PseudoAtomicLoadAdd32 : PseudoAM;
1964bdd1243dSDimitry Andricdef PseudoAtomicLoadSub32 : PseudoAM;
1965bdd1243dSDimitry Andricdef PseudoAtomicLoadAnd32 : PseudoAM;
1966bdd1243dSDimitry Andricdef PseudoAtomicLoadOr32 : PseudoAM;
1967bdd1243dSDimitry Andricdef PseudoAtomicLoadXor32 : PseudoAM;
1968bdd1243dSDimitry Andric
1969bdd1243dSDimitry Andricmulticlass PseudoBinPat<string Op, Pseudo BinInst> {
1970bdd1243dSDimitry Andric  def : Pat<(!cast<PatFrag>(Op#"_monotonic") GPR:$addr, GPR:$incr),
1971bdd1243dSDimitry Andric            (BinInst GPR:$addr, GPR:$incr, 2)>;
1972bdd1243dSDimitry Andric  def : Pat<(!cast<PatFrag>(Op#"_acquire") GPR:$addr, GPR:$incr),
1973bdd1243dSDimitry Andric            (BinInst GPR:$addr, GPR:$incr, 4)>;
1974bdd1243dSDimitry Andric  def : Pat<(!cast<PatFrag>(Op#"_release") GPR:$addr, GPR:$incr),
1975bdd1243dSDimitry Andric            (BinInst GPR:$addr, GPR:$incr, 5)>;
1976bdd1243dSDimitry Andric  def : Pat<(!cast<PatFrag>(Op#"_acq_rel") GPR:$addr, GPR:$incr),
1977bdd1243dSDimitry Andric            (BinInst GPR:$addr, GPR:$incr, 6)>;
1978bdd1243dSDimitry Andric  def : Pat<(!cast<PatFrag>(Op#"_seq_cst") GPR:$addr, GPR:$incr),
1979bdd1243dSDimitry Andric            (BinInst GPR:$addr, GPR:$incr, 7)>;
1980bdd1243dSDimitry Andric}
1981bdd1243dSDimitry Andric
1982bdd1243dSDimitry Andricclass PseudoMaskedAMUMinUMax
1983bdd1243dSDimitry Andric    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
1984bdd1243dSDimitry Andric             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$ordering)> {
1985bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
1986bdd1243dSDimitry Andric                    "@earlyclobber $scratch2";
1987bdd1243dSDimitry Andric  let mayLoad = 1;
1988bdd1243dSDimitry Andric  let mayStore = 1;
1989bdd1243dSDimitry Andric  let hasSideEffects = 0;
1990bdd1243dSDimitry Andric  let Size = 48;
1991bdd1243dSDimitry Andric}
1992bdd1243dSDimitry Andric
1993bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadUMax32 : PseudoMaskedAMUMinUMax;
1994bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadUMin32 : PseudoMaskedAMUMinUMax;
1995bdd1243dSDimitry Andric
1996bdd1243dSDimitry Andricclass PseudoMaskedAMMinMax
1997bdd1243dSDimitry Andric    : Pseudo<(outs GPR:$res, GPR:$scratch1, GPR:$scratch2),
1998bdd1243dSDimitry Andric             (ins GPR:$addr, GPR:$incr, GPR:$mask, grlenimm:$sextshamt,
1999bdd1243dSDimitry Andric              grlenimm:$ordering)> {
2000bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch1,"
2001bdd1243dSDimitry Andric                    "@earlyclobber $scratch2";
2002bdd1243dSDimitry Andric  let mayLoad = 1;
2003bdd1243dSDimitry Andric  let mayStore = 1;
2004bdd1243dSDimitry Andric  let hasSideEffects = 0;
2005bdd1243dSDimitry Andric  let Size = 56;
2006bdd1243dSDimitry Andric}
2007bdd1243dSDimitry Andric
2008bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadMax32 : PseudoMaskedAMMinMax;
2009bdd1243dSDimitry Andricdef PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax;
2010bdd1243dSDimitry Andric
2011bdd1243dSDimitry Andric/// Compare and exchange
2012bdd1243dSDimitry Andric
2013bdd1243dSDimitry Andricclass PseudoCmpXchg
2014bdd1243dSDimitry Andric    : Pseudo<(outs GPR:$res, GPR:$scratch),
20155f757f3fSDimitry Andric             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order)> {
2016bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
2017bdd1243dSDimitry Andric  let mayLoad = 1;
2018bdd1243dSDimitry Andric  let mayStore = 1;
2019bdd1243dSDimitry Andric  let hasSideEffects = 0;
2020bdd1243dSDimitry Andric  let Size = 36;
2021bdd1243dSDimitry Andric}
2022bdd1243dSDimitry Andric
2023bdd1243dSDimitry Andricdef PseudoCmpXchg32 : PseudoCmpXchg;
2024bdd1243dSDimitry Andricdef PseudoCmpXchg64 : PseudoCmpXchg;
2025bdd1243dSDimitry Andric
2026bdd1243dSDimitry Andricdef PseudoMaskedCmpXchg32
2027bdd1243dSDimitry Andric    : Pseudo<(outs GPR:$res, GPR:$scratch),
2028bdd1243dSDimitry Andric             (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
20295f757f3fSDimitry Andric              grlenimm:$fail_order)> {
2030bdd1243dSDimitry Andric  let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
2031bdd1243dSDimitry Andric  let mayLoad = 1;
2032bdd1243dSDimitry Andric  let mayStore = 1;
2033bdd1243dSDimitry Andric  let hasSideEffects = 0;
2034bdd1243dSDimitry Andric  let Size = 44;
2035bdd1243dSDimitry Andric}
2036bdd1243dSDimitry Andric
2037bdd1243dSDimitry Andricclass PseudoMaskedAMMinMaxPat<Intrinsic intrin, Pseudo AMInst>
2038bdd1243dSDimitry Andric    : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
2039bdd1243dSDimitry Andric           timm:$ordering),
2040bdd1243dSDimitry Andric          (AMInst GPR:$addr, GPR:$incr, GPR:$mask, GPR:$shiftamt,
2041bdd1243dSDimitry Andric           timm:$ordering)>;
2042bdd1243dSDimitry Andric
2043bdd1243dSDimitry Andricclass AtomicPat<Intrinsic intrin, Pseudo AMInst>
2044bdd1243dSDimitry Andric    : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),
2045bdd1243dSDimitry Andric          (AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;
2046bdd1243dSDimitry Andric
20475f757f3fSDimitry Andric// These atomic cmpxchg PatFrags only care about the failure ordering.
20485f757f3fSDimitry Andric// The PatFrags defined by multiclass `ternary_atomic_op_ord` in
20495f757f3fSDimitry Andric// TargetSelectionDAG.td care about the merged memory ordering that is the
20505f757f3fSDimitry Andric// stronger one between success and failure. But for LoongArch LL-SC we only
20515f757f3fSDimitry Andric// need to care about the failure ordering as explained in PR #67391. So we
20525f757f3fSDimitry Andric// define these PatFrags that will be used to define cmpxchg pats below.
20535f757f3fSDimitry Andricmulticlass ternary_atomic_op_failure_ord {
20545f757f3fSDimitry Andric  def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
20555f757f3fSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
20565f757f3fSDimitry Andric    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
20575f757f3fSDimitry Andric    return Ordering == AtomicOrdering::Monotonic;
20585f757f3fSDimitry Andric  }]>;
20595f757f3fSDimitry Andric  def NAME#_failure_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
20605f757f3fSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
20615f757f3fSDimitry Andric    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
20625f757f3fSDimitry Andric    return Ordering == AtomicOrdering::Acquire;
20635f757f3fSDimitry Andric  }]>;
20645f757f3fSDimitry Andric  def NAME#_failure_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
20655f757f3fSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
20665f757f3fSDimitry Andric    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
20675f757f3fSDimitry Andric    return Ordering == AtomicOrdering::Release;
20685f757f3fSDimitry Andric  }]>;
20695f757f3fSDimitry Andric  def NAME#_failure_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
20705f757f3fSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
20715f757f3fSDimitry Andric    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
20725f757f3fSDimitry Andric    return Ordering == AtomicOrdering::AcquireRelease;
20735f757f3fSDimitry Andric  }]>;
20745f757f3fSDimitry Andric  def NAME#_failure_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
20755f757f3fSDimitry Andric      (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
20765f757f3fSDimitry Andric    AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
20775f757f3fSDimitry Andric    return Ordering == AtomicOrdering::SequentiallyConsistent;
20785f757f3fSDimitry Andric  }]>;
20795f757f3fSDimitry Andric}
20805f757f3fSDimitry Andric
20810fca6ea1SDimitry Andricdefm atomic_cmp_swap_i32 : ternary_atomic_op_failure_ord;
20820fca6ea1SDimitry Andricdefm atomic_cmp_swap_i64 : ternary_atomic_op_failure_ord;
20835f757f3fSDimitry Andric
2084bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
2085bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
2086bdd1243dSDimitry Andric                PseudoMaskedAtomicSwap32>;
20870fca6ea1SDimitry Andricdef : Pat<(atomic_swap_i32 GPR:$addr, GPR:$incr),
208806c3fb27SDimitry Andric          (AMSWAP__DB_W GPR:$incr, GPR:$addr)>;
20890fca6ea1SDimitry Andricdef : Pat<(atomic_swap_i64 GPR:$addr, GPR:$incr),
209006c3fb27SDimitry Andric          (AMSWAP__DB_D GPR:$incr, GPR:$addr)>;
20910fca6ea1SDimitry Andricdef : Pat<(atomic_load_add_i64 GPR:$rj, GPR:$rk),
209206c3fb27SDimitry Andric          (AMADD__DB_D GPR:$rk, GPR:$rj)>;
2093bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_add_i64,
2094bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadAdd32>;
20950fca6ea1SDimitry Andricdef : Pat<(atomic_load_sub_i32 GPR:$rj, GPR:$rk),
209606c3fb27SDimitry Andric          (AMADD__DB_W (SUB_W R0, GPR:$rk), GPR:$rj)>;
20970fca6ea1SDimitry Andricdef : Pat<(atomic_load_sub_i64 GPR:$rj, GPR:$rk),
209806c3fb27SDimitry Andric          (AMADD__DB_D (SUB_D R0, GPR:$rk), GPR:$rj)>;
2099bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_sub_i64,
2100bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadSub32>;
21010fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_nand_i64", PseudoAtomicLoadNand64>;
2102bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_nand_i64,
2103bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadNand32>;
21040fca6ea1SDimitry Andricdef : Pat<(atomic_load_add_i32 GPR:$rj, GPR:$rk),
210506c3fb27SDimitry Andric          (AMADD__DB_W GPR:$rk, GPR:$rj)>;
21060fca6ea1SDimitry Andricdef : Pat<(atomic_load_and_i32 GPR:$rj, GPR:$rk),
210706c3fb27SDimitry Andric          (AMAND__DB_W GPR:$rk, GPR:$rj)>;
21080fca6ea1SDimitry Andricdef : Pat<(atomic_load_and_i64 GPR:$rj, GPR:$rk),
210906c3fb27SDimitry Andric          (AMAND__DB_D GPR:$rk, GPR:$rj)>;
21100fca6ea1SDimitry Andricdef : Pat<(atomic_load_or_i32 GPR:$rj, GPR:$rk),
211106c3fb27SDimitry Andric          (AMOR__DB_W GPR:$rk, GPR:$rj)>;
21120fca6ea1SDimitry Andricdef : Pat<(atomic_load_or_i64 GPR:$rj, GPR:$rk),
211306c3fb27SDimitry Andric          (AMOR__DB_D GPR:$rk, GPR:$rj)>;
21140fca6ea1SDimitry Andricdef : Pat<(atomic_load_xor_i32 GPR:$rj, GPR:$rk),
211506c3fb27SDimitry Andric          (AMXOR__DB_W GPR:$rk, GPR:$rj)>;
21160fca6ea1SDimitry Andricdef : Pat<(atomic_load_xor_i64 GPR:$rj, GPR:$rk),
211706c3fb27SDimitry Andric          (AMXOR__DB_D GPR:$rk, GPR:$rj)>;
2118bdd1243dSDimitry Andric
21190fca6ea1SDimitry Andricdef : Pat<(atomic_load_umin_i32 GPR:$rj, GPR:$rk),
212006c3fb27SDimitry Andric          (AMMIN__DB_WU GPR:$rk, GPR:$rj)>;
21210fca6ea1SDimitry Andricdef : Pat<(atomic_load_umin_i64 GPR:$rj, GPR:$rk),
212206c3fb27SDimitry Andric          (AMMIN__DB_DU GPR:$rk, GPR:$rj)>;
21230fca6ea1SDimitry Andricdef : Pat<(atomic_load_umax_i32 GPR:$rj, GPR:$rk),
212406c3fb27SDimitry Andric          (AMMAX__DB_WU GPR:$rk, GPR:$rj)>;
21250fca6ea1SDimitry Andricdef : Pat<(atomic_load_umax_i64 GPR:$rj, GPR:$rk),
212606c3fb27SDimitry Andric          (AMMAX__DB_DU GPR:$rk, GPR:$rj)>;
2127bdd1243dSDimitry Andric
21280fca6ea1SDimitry Andricdef : Pat<(atomic_load_min_i32 GPR:$rj, GPR:$rk),
212906c3fb27SDimitry Andric          (AMMIN__DB_W GPR:$rk, GPR:$rj)>;
21300fca6ea1SDimitry Andricdef : Pat<(atomic_load_min_i64 GPR:$rj, GPR:$rk),
213106c3fb27SDimitry Andric          (AMMIN__DB_D GPR:$rk, GPR:$rj)>;
21320fca6ea1SDimitry Andricdef : Pat<(atomic_load_max_i32 GPR:$rj, GPR:$rk),
213306c3fb27SDimitry Andric          (AMMAX__DB_W GPR:$rk, GPR:$rj)>;
21340fca6ea1SDimitry Andricdef : Pat<(atomic_load_max_i64 GPR:$rj, GPR:$rk),
213506c3fb27SDimitry Andric          (AMMAX__DB_D GPR:$rk, GPR:$rj)>;
2136bdd1243dSDimitry Andric
2137bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_umax_i64,
2138bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadUMax32>;
2139bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64,
2140bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadUMin32>;
2141bdd1243dSDimitry Andric
21425f757f3fSDimitry Andric// Ordering constants must be kept in sync with the AtomicOrdering enum in
21435f757f3fSDimitry Andric// AtomicOrdering.h.
21445f757f3fSDimitry Andricmulticlass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,
21455f757f3fSDimitry Andric                            ValueType vt = GRLenVT> {
21465f757f3fSDimitry Andric  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_monotonic") GPR:$addr, GPR:$cmp, GPR:$new)),
21475f757f3fSDimitry Andric            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;
21485f757f3fSDimitry Andric  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acquire") GPR:$addr, GPR:$cmp, GPR:$new)),
21495f757f3fSDimitry Andric            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;
21505f757f3fSDimitry Andric  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_release") GPR:$addr, GPR:$cmp, GPR:$new)),
21515f757f3fSDimitry Andric            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;
21525f757f3fSDimitry Andric  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acq_rel") GPR:$addr, GPR:$cmp, GPR:$new)),
21535f757f3fSDimitry Andric            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;
21545f757f3fSDimitry Andric  def : Pat<(vt (!cast<PatFrag>(Op#"_failure_seq_cst") GPR:$addr, GPR:$cmp, GPR:$new)),
21555f757f3fSDimitry Andric            (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
21565f757f3fSDimitry Andric}
21575f757f3fSDimitry Andric
21580fca6ea1SDimitry Andricdefm : PseudoCmpXchgPat<"atomic_cmp_swap_i32", PseudoCmpXchg32>;
21590fca6ea1SDimitry Andricdefm : PseudoCmpXchgPat<"atomic_cmp_swap_i64", PseudoCmpXchg64, i64>;
2160bdd1243dSDimitry Andricdef : Pat<(int_loongarch_masked_cmpxchg_i64
21615f757f3fSDimitry Andric            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order),
2162bdd1243dSDimitry Andric          (PseudoMaskedCmpXchg32
21635f757f3fSDimitry Andric            GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order)>;
2164bdd1243dSDimitry Andric
2165bdd1243dSDimitry Andricdef : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64,
2166bdd1243dSDimitry Andric                              PseudoMaskedAtomicLoadMax32>;
2167bdd1243dSDimitry Andricdef : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_min_i64,
2168bdd1243dSDimitry Andric                              PseudoMaskedAtomicLoadMin32>;
2169bdd1243dSDimitry Andric} // Predicates = [IsLA64]
2170bdd1243dSDimitry Andric
21710fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_nand_i32", PseudoAtomicLoadNand32>;
2172bdd1243dSDimitry Andric
2173bdd1243dSDimitry Andriclet Predicates = [IsLA32] in {
2174bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i32,
2175bdd1243dSDimitry Andric                PseudoMaskedAtomicSwap32>;
21760fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_swap_i32", PseudoAtomicSwap32>;
2177bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_add_i32,
2178bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadAdd32>;
2179bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_sub_i32,
2180bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadSub32>;
2181bdd1243dSDimitry Andricdef : AtomicPat<int_loongarch_masked_atomicrmw_nand_i32,
2182bdd1243dSDimitry Andric                PseudoMaskedAtomicLoadNand32>;
21830fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_add_i32", PseudoAtomicLoadAdd32>;
21840fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_sub_i32", PseudoAtomicLoadSub32>;
21850fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_and_i32", PseudoAtomicLoadAnd32>;
21860fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_or_i32", PseudoAtomicLoadOr32>;
21870fca6ea1SDimitry Andricdefm : PseudoBinPat<"atomic_load_xor_i32", PseudoAtomicLoadXor32>;
2188bdd1243dSDimitry Andric} // Predicates = [IsLA32]
2189bdd1243dSDimitry Andric
2190bdd1243dSDimitry Andric/// Intrinsics
2191bdd1243dSDimitry Andric
2192bdd1243dSDimitry Andricdef : Pat<(int_loongarch_cacop_d timm:$op, i64:$rj, timm:$imm12),
21935f757f3fSDimitry Andric          (CACOP timm:$op, GPR:$rj, timm:$imm12)>;
2194bdd1243dSDimitry Andricdef : Pat<(int_loongarch_cacop_w i32:$op, i32:$rj, i32:$imm12),
21955f757f3fSDimitry Andric          (CACOP timm:$op, GPR:$rj, timm:$imm12)>;
2196bdd1243dSDimitry Andricdef : Pat<(loongarch_dbar uimm15:$imm15), (DBAR uimm15:$imm15)>;
2197bdd1243dSDimitry Andricdef : Pat<(loongarch_ibar uimm15:$imm15), (IBAR uimm15:$imm15)>;
2198bdd1243dSDimitry Andricdef : Pat<(loongarch_break uimm15:$imm15), (BREAK uimm15:$imm15)>;
2199bdd1243dSDimitry Andricdef : Pat<(loongarch_syscall uimm15:$imm15), (SYSCALL uimm15:$imm15)>;
2200bdd1243dSDimitry Andric
2201bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
2202bdd1243dSDimitry Andric// CRC Check Instructions
2203bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_b_w, CRC_W_B_W>;
2204bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_h_w, CRC_W_H_W>;
2205bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_w_w, CRC_W_W_W>;
2206bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crc_w_d_w, CRC_W_D_W>;
2207bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_b_w, CRCC_W_B_W>;
2208bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_h_w, CRCC_W_H_W>;
2209bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_w_w, CRCC_W_W_W>;
2210bdd1243dSDimitry Andricdef : PatGprGpr<loongarch_crcc_w_d_w, CRCC_W_D_W>;
2211753f127fSDimitry Andric} // Predicates = [IsLA64]
2212753f127fSDimitry Andric
2213753f127fSDimitry Andric/// Other pseudo-instructions
2214753f127fSDimitry Andric
2215753f127fSDimitry Andric// Pessimistically assume the stack pointer will be clobbered
2216753f127fSDimitry Andriclet Defs = [R3], Uses = [R3] in {
2217753f127fSDimitry Andricdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
2218753f127fSDimitry Andric                              [(callseq_start timm:$amt1, timm:$amt2)]>;
2219753f127fSDimitry Andricdef ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
2220753f127fSDimitry Andric                              [(callseq_end timm:$amt1, timm:$amt2)]>;
2221753f127fSDimitry Andric} // Defs = [R3], Uses = [R3]
222281ad6265SDimitry Andric
222381ad6265SDimitry Andric//===----------------------------------------------------------------------===//
222481ad6265SDimitry Andric// Assembler Pseudo Instructions
222581ad6265SDimitry Andric//===----------------------------------------------------------------------===//
222681ad6265SDimitry Andric
222781ad6265SDimitry Andricdef : InstAlias<"nop", (ANDI R0, R0, 0)>;
222881ad6265SDimitry Andricdef : InstAlias<"move $dst, $src", (OR GPR:$dst, GPR:$src, R0)>;
2229bdd1243dSDimitry Andric// `ret` is supported since binutils commit 20f2e2686c79a5ac (version 2.40 and
2230bdd1243dSDimitry Andric// later).
2231bdd1243dSDimitry Andricdef : InstAlias<"ret", (JIRL R0, R1, 0)>;
2232bdd1243dSDimitry Andricdef : InstAlias<"jr $rj", (JIRL R0, GPR:$rj, 0)>;
2233bdd1243dSDimitry Andric
2234bdd1243dSDimitry Andric// Branches implemented with alias.
2235bdd1243dSDimitry Andric// Always output the canonical mnemonic for the pseudo branch instructions.
2236bdd1243dSDimitry Andric// The GNU tools emit the canonical mnemonic for the branch pseudo instructions
2237bdd1243dSDimitry Andric// as well (e.g. "bgt" will be recognised by the assembler but never printed by
2238bdd1243dSDimitry Andric// objdump). Match this behaviour by setting a zero weight.
2239bdd1243dSDimitry Andricdef : InstAlias<"bgt $rj, $rd, $imm16",
2240bdd1243dSDimitry Andric                (BLT GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2241bdd1243dSDimitry Andricdef : InstAlias<"bgtu $rj, $rd, $imm16",
2242bdd1243dSDimitry Andric                (BLTU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2243bdd1243dSDimitry Andricdef : InstAlias<"ble $rj, $rd, $imm16",
2244bdd1243dSDimitry Andric                (BGE GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2245bdd1243dSDimitry Andricdef : InstAlias<"bleu $rj, $rd, $imm16",
2246bdd1243dSDimitry Andric                (BGEU GPR:$rd, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2247bdd1243dSDimitry Andricdef : InstAlias<"bltz $rd, $imm16",
2248bdd1243dSDimitry Andric                (BLT GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>;
2249bdd1243dSDimitry Andricdef : InstAlias<"bgtz $rj, $imm16",
2250bdd1243dSDimitry Andric                (BLT R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2251bdd1243dSDimitry Andricdef : InstAlias<"blez $rj, $imm16",
2252bdd1243dSDimitry Andric                (BGE R0, GPR:$rj, simm16_lsl2_br:$imm16), 0>;
2253bdd1243dSDimitry Andricdef : InstAlias<"bgez $rd, $imm16",
2254bdd1243dSDimitry Andric                (BGE GPR:$rd, R0, simm16_lsl2_br:$imm16), 0>;
2255bdd1243dSDimitry Andric
2256bdd1243dSDimitry Andric// Load immediate.
2257bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
2258bdd1243dSDimitry Andric    isAsmParserOnly = 1 in {
2259bdd1243dSDimitry Andricdef PseudoLI_W : Pseudo<(outs GPR:$rd), (ins imm32:$imm), [],
2260bdd1243dSDimitry Andric                        "li.w", "$rd, $imm">;
22610fca6ea1SDimitry Andricdef PseudoLI_D : Pseudo<(outs GPR:$rd), (ins imm64:$imm), [],
2262bdd1243dSDimitry Andric                        "li.d", "$rd, $imm">, Requires<[IsLA64]>;
2263bdd1243dSDimitry Andric}
226481ad6265SDimitry Andric
226581ad6265SDimitry Andric//===----------------------------------------------------------------------===//
226681ad6265SDimitry Andric// Basic Floating-Point Instructions
226781ad6265SDimitry Andric//===----------------------------------------------------------------------===//
226881ad6265SDimitry Andric
226981ad6265SDimitry Andricinclude "LoongArchFloat32InstrInfo.td"
227081ad6265SDimitry Andricinclude "LoongArchFloat64InstrInfo.td"
227181ad6265SDimitry Andric
2272bdd1243dSDimitry Andriclet Predicates = [HasBasicF], usesCustomInserter = 1 in {
2273bdd1243dSDimitry Andric  def WRFCSR : Pseudo<(outs), (ins uimm2:$fcsr, GPR:$src),
2274bdd1243dSDimitry Andric               [(loongarch_movgr2fcsr uimm2:$fcsr, GRLenVT:$src)]>;
2275bdd1243dSDimitry Andric  def RDFCSR : Pseudo<(outs GPR:$rd), (ins uimm2:$fcsr),
2276bdd1243dSDimitry Andric               [(set GPR:$rd, (loongarch_movfcsr2gr uimm2:$fcsr))]>;
2277bdd1243dSDimitry Andric}
2278bdd1243dSDimitry Andric
227981ad6265SDimitry Andric//===----------------------------------------------------------------------===//
228081ad6265SDimitry Andric// Privilege Instructions
228181ad6265SDimitry Andric//===----------------------------------------------------------------------===//
228281ad6265SDimitry Andric
228381ad6265SDimitry Andric// CSR Access Instructions
228406c3fb27SDimitry Andriclet hasSideEffects = 1 in
228506c3fb27SDimitry Andricdef CSRRD : FmtCSR<0x04000000, (outs GPR:$rd), (ins uimm14:$csr_num),
228606c3fb27SDimitry Andric                   "$rd, $csr_num">;
228706c3fb27SDimitry Andriclet hasSideEffects = 1, Constraints = "$rd = $dst" in {
228806c3fb27SDimitry Andricdef CSRWR : FmtCSR<0x04000020, (outs GPR:$dst),
228906c3fb27SDimitry Andric                   (ins GPR:$rd, uimm14:$csr_num), "$rd, $csr_num">;
229006c3fb27SDimitry Andricdef CSRXCHG : FmtCSRXCHG<0x04000000, (outs GPR:$dst),
229181ad6265SDimitry Andric                         (ins GPR:$rd, GPR:$rj, uimm14:$csr_num),
229206c3fb27SDimitry Andric                         "$rd, $rj, $csr_num">;
229306c3fb27SDimitry Andric} // hasSideEffects = 1, Constraints = "$rd = $dst"
229481ad6265SDimitry Andric
229581ad6265SDimitry Andric// IOCSR Access Instructions
229606c3fb27SDimitry Andricdef IOCSRRD_B : IOCSRRD<0x06480000>;
229706c3fb27SDimitry Andricdef IOCSRRD_H : IOCSRRD<0x06480400>;
229806c3fb27SDimitry Andricdef IOCSRRD_W : IOCSRRD<0x06480800>;
229906c3fb27SDimitry Andricdef IOCSRWR_B : IOCSRWR<0x06481000>;
230006c3fb27SDimitry Andricdef IOCSRWR_H : IOCSRWR<0x06481400>;
230106c3fb27SDimitry Andricdef IOCSRWR_W : IOCSRWR<0x06481800>;
230281ad6265SDimitry Andriclet Predicates = [IsLA64] in {
230306c3fb27SDimitry Andricdef IOCSRRD_D : IOCSRRD<0x06480c00>;
230406c3fb27SDimitry Andricdef IOCSRWR_D : IOCSRWR<0x06481c00>;
230581ad6265SDimitry Andric} // Predicates = [IsLA64]
230681ad6265SDimitry Andric
230781ad6265SDimitry Andric// TLB Maintenance Instructions
230806c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
230906c3fb27SDimitry Andricdef TLBSRCH  : FmtI32<0x06482800>;
231006c3fb27SDimitry Andricdef TLBRD    : FmtI32<0x06482c00>;
231106c3fb27SDimitry Andricdef TLBWR    : FmtI32<0x06483000>;
231206c3fb27SDimitry Andricdef TLBFILL  : FmtI32<0x06483400>;
231306c3fb27SDimitry Andricdef TLBCLR   : FmtI32<0x06482000>;
231406c3fb27SDimitry Andricdef TLBFLUSH : FmtI32<0x06482400>;
231506c3fb27SDimitry Andricdef INVTLB : FmtINVTLB<(outs), (ins GPR:$rk, GPR:$rj, uimm5:$op),
231681ad6265SDimitry Andric                       "$op, $rj, $rk">;
231706c3fb27SDimitry Andric} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
231881ad6265SDimitry Andric
231981ad6265SDimitry Andric// Software Page Walking Instructions
232006c3fb27SDimitry Andricdef LDDIR : Fmt2RI8<0x06400000, (outs GPR:$rd),
232106c3fb27SDimitry Andric                    (ins GPR:$rj, uimm8:$imm8), "$rd, $rj, $imm8">;
232206c3fb27SDimitry Andricdef LDPTE : FmtLDPTE<(outs), (ins GPR:$rj, uimm8:$seq), "$rj, $seq">;
232381ad6265SDimitry Andric
232481ad6265SDimitry Andric
232581ad6265SDimitry Andric// Other Miscellaneous Instructions
232606c3fb27SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
232706c3fb27SDimitry Andricdef ERTN : FmtI32<0x06483800>;
232806c3fb27SDimitry Andricdef DBCL : MISC_I15<0x002a8000>;
232906c3fb27SDimitry Andricdef IDLE : MISC_I15<0x06488000>;
2330bdd1243dSDimitry Andric
2331bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2332bdd1243dSDimitry Andric// Privilege Intrinsics
2333bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2334bdd1243dSDimitry Andric
2335bdd1243dSDimitry Andricdef : Pat<(loongarch_csrrd uimm14:$imm14), (CSRRD uimm14:$imm14)>;
2336bdd1243dSDimitry Andricdef : Pat<(loongarch_csrwr GPR:$rd, uimm14:$imm14),
2337bdd1243dSDimitry Andric          (CSRWR GPR:$rd, uimm14:$imm14)>;
2338bdd1243dSDimitry Andricdef : Pat<(loongarch_csrxchg GPR:$rd, GPR:$rj, uimm14:$imm14),
2339bdd1243dSDimitry Andric          (CSRXCHG GPR:$rd, GPR:$rj, uimm14:$imm14)>;
2340bdd1243dSDimitry Andric
2341bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_b GPR:$rj), (IOCSRRD_B GPR:$rj)>;
2342bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_h GPR:$rj), (IOCSRRD_H GPR:$rj)>;
2343bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_w GPR:$rj), (IOCSRRD_W GPR:$rj)>;
2344bdd1243dSDimitry Andric
2345bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_b GPR:$rd, GPR:$rj), (IOCSRWR_B GPR:$rd, GPR:$rj)>;
2346bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_h GPR:$rd, GPR:$rj), (IOCSRWR_H GPR:$rd, GPR:$rj)>;
2347bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_w GPR:$rd, GPR:$rj), (IOCSRWR_W GPR:$rd, GPR:$rj)>;
2348bdd1243dSDimitry Andric
2349bdd1243dSDimitry Andricdef : Pat<(loongarch_cpucfg GPR:$rj), (CPUCFG GPR:$rj)>;
2350bdd1243dSDimitry Andric
2351bdd1243dSDimitry Andriclet Predicates = [IsLA64] in {
2352bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrrd_d GPR:$rj), (IOCSRRD_D GPR:$rj)>;
2353bdd1243dSDimitry Andricdef : Pat<(loongarch_iocsrwr_d GPR:$rd, GPR:$rj), (IOCSRWR_D GPR:$rd, GPR:$rj)>;
2354bdd1243dSDimitry Andricdef : Pat<(int_loongarch_asrtle_d GPR:$rj, GPR:$rk),
2355bdd1243dSDimitry Andric          (ASRTLE_D GPR:$rj, GPR:$rk)>;
2356bdd1243dSDimitry Andricdef : Pat<(int_loongarch_asrtgt_d GPR:$rj, GPR:$rk),
2357bdd1243dSDimitry Andric          (ASRTGT_D GPR:$rj, GPR:$rk)>;
2358bdd1243dSDimitry Andricdef : Pat<(int_loongarch_lddir_d GPR:$rj, timm:$imm8),
23595f757f3fSDimitry Andric          (LDDIR GPR:$rj, timm:$imm8)>;
2360bdd1243dSDimitry Andricdef : Pat<(int_loongarch_ldpte_d GPR:$rj, timm:$imm8),
23615f757f3fSDimitry Andric          (LDPTE GPR:$rj, timm:$imm8)>;
2362bdd1243dSDimitry Andric} // Predicates = [IsLA64]
236306c3fb27SDimitry Andric
236406c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
236506c3fb27SDimitry Andric// LSX Instructions
236606c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
236706c3fb27SDimitry Andricinclude "LoongArchLSXInstrInfo.td"
236806c3fb27SDimitry Andric
236906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
237006c3fb27SDimitry Andric// LASX Instructions
237106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
237206c3fb27SDimitry Andricinclude "LoongArchLASXInstrInfo.td"
237306c3fb27SDimitry Andric
237406c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
237506c3fb27SDimitry Andric// LVZ Instructions
237606c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
237706c3fb27SDimitry Andricinclude "LoongArchLVZInstrInfo.td"
237806c3fb27SDimitry Andric
237906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
238006c3fb27SDimitry Andric// LBT Instructions
238106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
238206c3fb27SDimitry Andricinclude "LoongArchLBTInstrInfo.td"
2383