106c3fb27SDimitry Andric//===-- RISCVInstrInfo.td - Target Description for RISC-V --*- tablegen -*-===//
20b57cec5SDimitry Andric//
30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric//
70b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric//
90b57cec5SDimitry Andric// This file describes the RISC-V instructions in TableGen format.
100b57cec5SDimitry Andric//
110b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric// RISC-V specific DAG Nodes.
150b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric// Target-independent type requirements, but with target-specific formats.
180b57cec5SDimitry Andricdef SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
190b57cec5SDimitry Andric                                       SDTCisVT<1, i32>]>;
200b57cec5SDimitry Andricdef SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
210b57cec5SDimitry Andric                                     SDTCisVT<1, i32>]>;
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric// Target-dependent type requirements.
240b57cec5SDimitry Andricdef SDT_RISCVCall     : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;
250b57cec5SDimitry Andricdef SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
26349cc55cSDimitry Andric                                             SDTCisVT<3, OtherVT>,
270b57cec5SDimitry Andric                                             SDTCisSameAs<0, 4>,
280b57cec5SDimitry Andric                                             SDTCisSameAs<4, 5>]>;
29fe6060f1SDimitry Andricdef SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
30fe6060f1SDimitry Andric                                         SDTCisVT<2, OtherVT>,
31fe6060f1SDimitry Andric                                         SDTCisVT<3, OtherVT>]>;
32fe6060f1SDimitry Andricdef SDT_RISCVReadCSR  : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
33fe6060f1SDimitry Andricdef SDT_RISCVWriteCSR : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>;
34fe6060f1SDimitry Andricdef SDT_RISCVSwapCSR  : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
35fe6060f1SDimitry Andric                                             SDTCisInt<2>]>;
36e8d8bef9SDimitry Andricdef SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>,
37e8d8bef9SDimitry Andric                                                  SDTCisVT<1, i32>]>;
38fe6060f1SDimitry Andricdef SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [
39fe6060f1SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisVT<0, i64>
40fe6060f1SDimitry Andric]>;
41fe6060f1SDimitry Andricdef SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
42fe6060f1SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>
43fe6060f1SDimitry Andric]>;
44fe6060f1SDimitry Andricdef SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [
45fe6060f1SDimitry Andric  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64>
46fe6060f1SDimitry Andric]>;
470b57cec5SDimitry Andric
480b57cec5SDimitry Andric// Target-independent nodes, but with target-specific formats.
490b57cec5SDimitry Andricdef callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
500b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOutGlue]>;
510b57cec5SDimitry Andricdef callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
520b57cec5SDimitry Andric                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric// Target-dependent nodes.
550b57cec5SDimitry Andricdef riscv_call      : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
560b57cec5SDimitry Andric                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
570b57cec5SDimitry Andric                              SDNPVariadic]>;
5806c3fb27SDimitry Andricdef riscv_ret_glue  : SDNode<"RISCVISD::RET_GLUE", SDTNone,
590b57cec5SDimitry Andric                             [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
6006c3fb27SDimitry Andricdef riscv_sret_glue : SDNode<"RISCVISD::SRET_GLUE", SDTNone,
610b57cec5SDimitry Andric                             [SDNPHasChain, SDNPOptInGlue]>;
6206c3fb27SDimitry Andricdef riscv_mret_glue : SDNode<"RISCVISD::MRET_GLUE", SDTNone,
630b57cec5SDimitry Andric                             [SDNPHasChain, SDNPOptInGlue]>;
64e8d8bef9SDimitry Andricdef riscv_selectcc  : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC>;
65fe6060f1SDimitry Andricdef riscv_brcc      : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
66fe6060f1SDimitry Andric                             [SDNPHasChain]>;
670b57cec5SDimitry Andricdef riscv_tail      : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
680b57cec5SDimitry Andric                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
690b57cec5SDimitry Andric                              SDNPVariadic]>;
70fe6060f1SDimitry Andricdef riscv_sllw      : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
71fe6060f1SDimitry Andricdef riscv_sraw      : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
72fe6060f1SDimitry Andricdef riscv_srlw      : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
73fe6060f1SDimitry Andricdef riscv_read_csr  : SDNode<"RISCVISD::READ_CSR", SDT_RISCVReadCSR,
74fe6060f1SDimitry Andric                             [SDNPHasChain]>;
75fe6060f1SDimitry Andricdef riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_RISCVWriteCSR,
76fe6060f1SDimitry Andric                             [SDNPHasChain]>;
77fe6060f1SDimitry Andricdef riscv_swap_csr  : SDNode<"RISCVISD::SWAP_CSR", SDT_RISCVSwapCSR,
78fe6060f1SDimitry Andric                             [SDNPHasChain]>;
790b57cec5SDimitry Andric
80e8d8bef9SDimitry Andricdef riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE",
81e8d8bef9SDimitry Andric                                   SDT_RISCVReadCycleWide,
82e8d8bef9SDimitry Andric                                   [SDNPHasChain, SDNPSideEffect]>;
83e8d8bef9SDimitry Andric
8481ad6265SDimitry Andricdef riscv_add_lo : SDNode<"RISCVISD::ADD_LO", SDTIntBinOp>;
8581ad6265SDimitry Andricdef riscv_hi : SDNode<"RISCVISD::HI", SDTIntUnaryOp>;
8681ad6265SDimitry Andricdef riscv_lla : SDNode<"RISCVISD::LLA", SDTIntUnaryOp>;
8781ad6265SDimitry Andricdef riscv_add_tprel : SDNode<"RISCVISD::ADD_TPREL",
8881ad6265SDimitry Andric                             SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
8981ad6265SDimitry Andric                                                  SDTCisSameAs<0, 2>,
9081ad6265SDimitry Andric                                                  SDTCisSameAs<0, 3>,
9181ad6265SDimitry Andric                                                  SDTCisInt<0>]>>;
9281ad6265SDimitry Andric
930b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
940b57cec5SDimitry Andric// Operand and SDNode transformation definitions.
950b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
960b57cec5SDimitry Andric
970b57cec5SDimitry Andricclass ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
980b57cec5SDimitry Andric  let Name = prefix # "ImmXLen" # suffix;
990b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
1000b57cec5SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
1010b57cec5SDimitry Andric}
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andricclass ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
1040b57cec5SDimitry Andric  let Name = prefix # "Imm" # width # suffix;
1050b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
1060b57cec5SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
1070b57cec5SDimitry Andric}
1080b57cec5SDimitry Andric
1098bcb0991SDimitry Andricdef ImmZeroAsmOperand : AsmOperandClass {
1108bcb0991SDimitry Andric  let Name = "ImmZero";
1118bcb0991SDimitry Andric  let RenderMethod = "addImmOperands";
1128bcb0991SDimitry Andric  let DiagnosticType = !strconcat("Invalid", Name);
1138bcb0991SDimitry Andric}
1148bcb0991SDimitry Andric
11581ad6265SDimitry Andric// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored.
11681ad6265SDimitry Andricdef ZeroOffsetMemOpOperand : AsmOperandClass {
11781ad6265SDimitry Andric  let Name = "ZeroOffsetMemOpOperand";
11881ad6265SDimitry Andric  let RenderMethod = "addRegOperands";
11981ad6265SDimitry Andric  let PredicateMethod = "isGPR";
12081ad6265SDimitry Andric  let ParserMethod = "parseZeroOffsetMemOp";
12181ad6265SDimitry Andric}
12281ad6265SDimitry Andric
123bdd1243dSDimitry Andricclass MemOperand<RegisterClass regClass> : RegisterOperand<regClass>{
124bdd1243dSDimitry Andric  let OperandType = "OPERAND_MEMORY";
125bdd1243dSDimitry Andric}
126bdd1243dSDimitry Andric
127bdd1243dSDimitry Andricdef GPRMemZeroOffset : MemOperand<GPR> {
12881ad6265SDimitry Andric  let ParserMatchClass = ZeroOffsetMemOpOperand;
12981ad6265SDimitry Andric  let PrintMethod = "printZeroOffsetMemOp";
13081ad6265SDimitry Andric}
13181ad6265SDimitry Andric
132bdd1243dSDimitry Andricdef GPRMem : MemOperand<GPR>;
133bdd1243dSDimitry Andric
134bdd1243dSDimitry Andricdef SPMem : MemOperand<SP>;
135bdd1243dSDimitry Andric
136bdd1243dSDimitry Andricdef GPRCMem : MemOperand<GPRC>;
137bdd1243dSDimitry Andric
1380b57cec5SDimitry Andricclass SImmAsmOperand<int width, string suffix = "">
1390b57cec5SDimitry Andric    : ImmAsmOperand<"S", width, suffix> {
1400b57cec5SDimitry Andric}
1410b57cec5SDimitry Andric
1420b57cec5SDimitry Andricclass UImmAsmOperand<int width, string suffix = "">
1430b57cec5SDimitry Andric    : ImmAsmOperand<"U", width, suffix> {
1440b57cec5SDimitry Andric}
1450b57cec5SDimitry Andric
1465f757f3fSDimitry Andricclass RISCVOp<ValueType vt = XLenVT> : Operand<vt> {
1475f757f3fSDimitry Andric  let OperandNamespace = "RISCVOp";
1485f757f3fSDimitry Andric}
1495f757f3fSDimitry Andric
1505f757f3fSDimitry Andricclass RISCVUImmOp<int bitsNum> : RISCVOp {
1515f757f3fSDimitry Andric  let ParserMatchClass = UImmAsmOperand<bitsNum>;
1525f757f3fSDimitry Andric  let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">";
1535f757f3fSDimitry Andric  let OperandType = "OPERAND_UIMM" # bitsNum;
1545f757f3fSDimitry Andric}
1555f757f3fSDimitry Andric
1565f757f3fSDimitry Andricclass RISCVUImmLeafOp<int bitsNum> :
1575f757f3fSDimitry Andric  RISCVUImmOp<bitsNum>, ImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);">;
1585f757f3fSDimitry Andric
1595f757f3fSDimitry Andricclass RISCVSImmOp<int bitsNum> : RISCVOp {
1605f757f3fSDimitry Andric  let ParserMatchClass = SImmAsmOperand<bitsNum>;
1615f757f3fSDimitry Andric  let EncoderMethod = "getImmOpValue";
1625f757f3fSDimitry Andric  let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">";
1635f757f3fSDimitry Andric  let OperandType = "OPERAND_SIMM" # bitsNum;
1645f757f3fSDimitry Andric}
1655f757f3fSDimitry Andric
1665f757f3fSDimitry Andricclass RISCVSImmLeafOp<int bitsNum> :
1675f757f3fSDimitry Andric  RISCVSImmOp<bitsNum>, ImmLeaf<XLenVT, "return isInt<" # bitsNum # ">(Imm);">;
1685f757f3fSDimitry Andric
1690b57cec5SDimitry Andricdef FenceArg : AsmOperandClass {
1700b57cec5SDimitry Andric  let Name = "FenceArg";
1710b57cec5SDimitry Andric  let RenderMethod = "addFenceArgOperands";
17206c3fb27SDimitry Andric  let ParserMethod = "parseFenceArg";
1730b57cec5SDimitry Andric}
1740b57cec5SDimitry Andric
1755f757f3fSDimitry Andricdef fencearg : RISCVOp {
1760b57cec5SDimitry Andric  let ParserMatchClass = FenceArg;
1770b57cec5SDimitry Andric  let PrintMethod = "printFenceArg";
1780b57cec5SDimitry Andric  let DecoderMethod = "decodeUImmOperand<4>";
1798bcb0991SDimitry Andric  let OperandType = "OPERAND_UIMM4";
1800b57cec5SDimitry Andric}
1810b57cec5SDimitry Andric
1820b57cec5SDimitry Andricdef UImmLog2XLenAsmOperand : AsmOperandClass {
1830b57cec5SDimitry Andric  let Name = "UImmLog2XLen";
1840b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
1850b57cec5SDimitry Andric  let DiagnosticType = "InvalidUImmLog2XLen";
1860b57cec5SDimitry Andric}
1870b57cec5SDimitry Andric
1885f757f3fSDimitry Andricdef uimmlog2xlen : RISCVOp, ImmLeaf<XLenVT, [{
1890b57cec5SDimitry Andric  if (Subtarget->is64Bit())
1900b57cec5SDimitry Andric    return isUInt<6>(Imm);
1910b57cec5SDimitry Andric  return isUInt<5>(Imm);
1920b57cec5SDimitry Andric}]> {
1930b57cec5SDimitry Andric  let ParserMatchClass = UImmLog2XLenAsmOperand;
1940b57cec5SDimitry Andric  // TODO: should ensure invalid shamt is rejected when decoding.
1950b57cec5SDimitry Andric  let DecoderMethod = "decodeUImmOperand<6>";
1960b57cec5SDimitry Andric  let MCOperandPredicate = [{
1970b57cec5SDimitry Andric    int64_t Imm;
1980b57cec5SDimitry Andric    if (!MCOp.evaluateAsConstantImm(Imm))
1990b57cec5SDimitry Andric      return false;
2000b57cec5SDimitry Andric    if (STI.getTargetTriple().isArch64Bit())
2010b57cec5SDimitry Andric      return isUInt<6>(Imm);
2020b57cec5SDimitry Andric    return isUInt<5>(Imm);
2030b57cec5SDimitry Andric  }];
2048bcb0991SDimitry Andric  let OperandType = "OPERAND_UIMMLOG2XLEN";
2050b57cec5SDimitry Andric}
2060b57cec5SDimitry Andric
2070eae32dcSDimitry Andricdef InsnDirectiveOpcode : AsmOperandClass {
2080eae32dcSDimitry Andric  let Name = "InsnDirectiveOpcode";
2090eae32dcSDimitry Andric  let ParserMethod = "parseInsnDirectiveOpcode";
2100eae32dcSDimitry Andric  let RenderMethod = "addImmOperands";
2110eae32dcSDimitry Andric  let PredicateMethod = "isImm";
2120eae32dcSDimitry Andric}
2130eae32dcSDimitry Andric
2145f757f3fSDimitry Andricdef uimm1 : RISCVUImmLeafOp<1>;
2155f757f3fSDimitry Andricdef uimm2 : RISCVUImmLeafOp<2> {
2165f757f3fSDimitry Andric  let MCOperandPredicate = [{
2175f757f3fSDimitry Andric    int64_t Imm;
2185f757f3fSDimitry Andric    if (!MCOp.evaluateAsConstantImm(Imm))
2195f757f3fSDimitry Andric      return false;
2205f757f3fSDimitry Andric    return isUInt<2>(Imm);
2215f757f3fSDimitry Andric  }];
22206c3fb27SDimitry Andric}
2235f757f3fSDimitry Andricdef uimm3 : RISCVUImmOp<3>;
2245f757f3fSDimitry Andricdef uimm4 : RISCVUImmOp<4>;
2255f757f3fSDimitry Andricdef uimm5 : RISCVUImmLeafOp<5>;
2265f757f3fSDimitry Andricdef uimm6 : RISCVUImmLeafOp<6>;
2275f757f3fSDimitry Andricdef uimm7_opcode : RISCVUImmOp<7> {
2280eae32dcSDimitry Andric  let ParserMatchClass = InsnDirectiveOpcode;
2290eae32dcSDimitry Andric}
2305f757f3fSDimitry Andricdef uimm7 : RISCVUImmOp<7>;
2315f757f3fSDimitry Andricdef uimm8 : RISCVUImmOp<8>;
2325f757f3fSDimitry Andricdef simm12 : RISCVSImmLeafOp<12> {
2330b57cec5SDimitry Andric  let MCOperandPredicate = [{
2340b57cec5SDimitry Andric    int64_t Imm;
2350b57cec5SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2360b57cec5SDimitry Andric      return isInt<12>(Imm);
2370b57cec5SDimitry Andric    return MCOp.isBareSymbolRef();
2380b57cec5SDimitry Andric  }];
2390b57cec5SDimitry Andric}
2400b57cec5SDimitry Andric
241bdd1243dSDimitry Andric// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,
242bdd1243dSDimitry Andric// but even negative value fit in 12-bit.
243bdd1243dSDimitry Andricdef simm12_no6 : ImmLeaf<XLenVT, [{
244bdd1243dSDimitry Andric  return isInt<12>(Imm) && !isInt<6>(Imm) && isInt<12>(-Imm);}]>;
245bdd1243dSDimitry Andric
2460b57cec5SDimitry Andric// A 13-bit signed immediate where the least significant bit is zero.
2470b57cec5SDimitry Andricdef simm13_lsb0 : Operand<OtherVT> {
2480b57cec5SDimitry Andric  let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
249e8d8bef9SDimitry Andric  let PrintMethod = "printBranchOperand";
2500b57cec5SDimitry Andric  let EncoderMethod = "getImmOpValueAsr1";
2510b57cec5SDimitry Andric  let DecoderMethod = "decodeSImmOperandAndLsl1<13>";
2520b57cec5SDimitry Andric  let MCOperandPredicate = [{
2530b57cec5SDimitry Andric    int64_t Imm;
2540b57cec5SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2550b57cec5SDimitry Andric      return isShiftedInt<12, 1>(Imm);
2560b57cec5SDimitry Andric    return MCOp.isBareSymbolRef();
2570b57cec5SDimitry Andric  }];
258e8d8bef9SDimitry Andric  let OperandType = "OPERAND_PCREL";
2590b57cec5SDimitry Andric}
2600b57cec5SDimitry Andric
2615f757f3fSDimitry Andricclass UImm20Operand : RISCVOp {
2620b57cec5SDimitry Andric  let EncoderMethod = "getImmOpValue";
2630b57cec5SDimitry Andric  let DecoderMethod = "decodeUImmOperand<20>";
2645f757f3fSDimitry Andric  let OperandType = "OPERAND_UIMM20";
2655f757f3fSDimitry Andric}
2665f757f3fSDimitry Andric
2675f757f3fSDimitry Andricclass UImm20OperandMaybeSym : UImm20Operand {
2680b57cec5SDimitry Andric  let MCOperandPredicate = [{
2690b57cec5SDimitry Andric    int64_t Imm;
2700b57cec5SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
2710b57cec5SDimitry Andric      return isUInt<20>(Imm);
2720b57cec5SDimitry Andric    return MCOp.isBareSymbolRef();
2730b57cec5SDimitry Andric  }];
2740b57cec5SDimitry Andric}
2750b57cec5SDimitry Andric
2765f757f3fSDimitry Andricdef uimm20_lui : UImm20OperandMaybeSym {
2770b57cec5SDimitry Andric  let ParserMatchClass = UImmAsmOperand<20, "LUI">;
2780b57cec5SDimitry Andric}
2795f757f3fSDimitry Andricdef uimm20_auipc : UImm20OperandMaybeSym {
2800b57cec5SDimitry Andric  let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;
2810b57cec5SDimitry Andric}
2820b57cec5SDimitry Andric
2835f757f3fSDimitry Andricdef uimm20 : UImm20Operand {
2845f757f3fSDimitry Andric  let ParserMatchClass = UImmAsmOperand<20>;
2855f757f3fSDimitry Andric  let MCOperandPredicate = [{
2865f757f3fSDimitry Andric    int64_t Imm;
2875f757f3fSDimitry Andric    if (!MCOp.evaluateAsConstantImm(Imm))
2885f757f3fSDimitry Andric      return false;
2895f757f3fSDimitry Andric    return isUInt<20>(Imm);
2905f757f3fSDimitry Andric  }];
2915f757f3fSDimitry Andric}
2925f757f3fSDimitry Andric
2930b57cec5SDimitry Andricdef Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> {
2940b57cec5SDimitry Andric  let ParserMethod = "parseJALOffset";
2950b57cec5SDimitry Andric}
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric// A 21-bit signed immediate where the least significant bit is zero.
2980b57cec5SDimitry Andricdef simm21_lsb0_jal : Operand<OtherVT> {
2990b57cec5SDimitry Andric  let ParserMatchClass = Simm21Lsb0JALAsmOperand;
300e8d8bef9SDimitry Andric  let PrintMethod = "printBranchOperand";
3010b57cec5SDimitry Andric  let EncoderMethod = "getImmOpValueAsr1";
3020b57cec5SDimitry Andric  let DecoderMethod = "decodeSImmOperandAndLsl1<21>";
3030b57cec5SDimitry Andric  let MCOperandPredicate = [{
3040b57cec5SDimitry Andric    int64_t Imm;
3050b57cec5SDimitry Andric    if (MCOp.evaluateAsConstantImm(Imm))
3060b57cec5SDimitry Andric      return isShiftedInt<20, 1>(Imm);
3070b57cec5SDimitry Andric    return MCOp.isBareSymbolRef();
3080b57cec5SDimitry Andric  }];
309e8d8bef9SDimitry Andric  let OperandType = "OPERAND_PCREL";
3100b57cec5SDimitry Andric}
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andricdef BareSymbol : AsmOperandClass {
3130b57cec5SDimitry Andric  let Name = "BareSymbol";
3140b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
3150b57cec5SDimitry Andric  let DiagnosticType = "InvalidBareSymbol";
3160b57cec5SDimitry Andric  let ParserMethod = "parseBareSymbol";
3170b57cec5SDimitry Andric}
3180b57cec5SDimitry Andric
3190b57cec5SDimitry Andric// A bare symbol.
3200b57cec5SDimitry Andricdef bare_symbol : Operand<XLenVT> {
3210b57cec5SDimitry Andric  let ParserMatchClass = BareSymbol;
3220b57cec5SDimitry Andric}
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andricdef CallSymbol : AsmOperandClass {
3250b57cec5SDimitry Andric  let Name = "CallSymbol";
3260b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
3270b57cec5SDimitry Andric  let DiagnosticType = "InvalidCallSymbol";
3280b57cec5SDimitry Andric  let ParserMethod = "parseCallSymbol";
3290b57cec5SDimitry Andric}
3300b57cec5SDimitry Andric
3310b57cec5SDimitry Andric// A bare symbol used in call/tail only.
3320b57cec5SDimitry Andricdef call_symbol : Operand<XLenVT> {
3330b57cec5SDimitry Andric  let ParserMatchClass = CallSymbol;
3340b57cec5SDimitry Andric}
3350b57cec5SDimitry Andric
3365ffd83dbSDimitry Andricdef PseudoJumpSymbol : AsmOperandClass {
3375ffd83dbSDimitry Andric  let Name = "PseudoJumpSymbol";
3385ffd83dbSDimitry Andric  let RenderMethod = "addImmOperands";
3395ffd83dbSDimitry Andric  let DiagnosticType = "InvalidPseudoJumpSymbol";
3405ffd83dbSDimitry Andric  let ParserMethod = "parsePseudoJumpSymbol";
3415ffd83dbSDimitry Andric}
3425ffd83dbSDimitry Andric
3435ffd83dbSDimitry Andric// A bare symbol used for pseudo jumps only.
3445ffd83dbSDimitry Andricdef pseudo_jump_symbol : Operand<XLenVT> {
3455ffd83dbSDimitry Andric  let ParserMatchClass = PseudoJumpSymbol;
3465ffd83dbSDimitry Andric}
3475ffd83dbSDimitry Andric
3480b57cec5SDimitry Andricdef TPRelAddSymbol : AsmOperandClass {
3490b57cec5SDimitry Andric  let Name = "TPRelAddSymbol";
3500b57cec5SDimitry Andric  let RenderMethod = "addImmOperands";
3510b57cec5SDimitry Andric  let DiagnosticType = "InvalidTPRelAddSymbol";
3520b57cec5SDimitry Andric  let ParserMethod = "parseOperandWithModifier";
3530b57cec5SDimitry Andric}
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric// A bare symbol with the %tprel_add variant.
3560b57cec5SDimitry Andricdef tprel_add_symbol : Operand<XLenVT> {
3570b57cec5SDimitry Andric  let ParserMatchClass = TPRelAddSymbol;
3580b57cec5SDimitry Andric}
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andricdef CSRSystemRegister : AsmOperandClass {
3610b57cec5SDimitry Andric  let Name = "CSRSystemRegister";
3620b57cec5SDimitry Andric  let ParserMethod = "parseCSRSystemRegister";
3630b57cec5SDimitry Andric  let DiagnosticType = "InvalidCSRSystemRegister";
3640b57cec5SDimitry Andric}
3650b57cec5SDimitry Andric
3665f757f3fSDimitry Andricdef csr_sysreg : RISCVOp {
3670b57cec5SDimitry Andric  let ParserMatchClass = CSRSystemRegister;
3680b57cec5SDimitry Andric  let PrintMethod = "printCSRSystemRegister";
3690b57cec5SDimitry Andric  let DecoderMethod = "decodeUImmOperand<12>";
3708bcb0991SDimitry Andric  let OperandType = "OPERAND_UIMM12";
3710b57cec5SDimitry Andric}
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric// A parameterized register class alternative to i32imm/i64imm from Target.td.
3740b57cec5SDimitry Andricdef ixlenimm : Operand<XLenVT>;
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andricdef ixlenimm_li : Operand<XLenVT> {
3770b57cec5SDimitry Andric  let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;
3780b57cec5SDimitry Andric}
3790b57cec5SDimitry Andric
38006c3fb27SDimitry Andric// Accepts subset of LI operands, used by LAImm and LLAImm
38106c3fb27SDimitry Andricdef ixlenimm_li_restricted : Operand<XLenVT> {
38206c3fb27SDimitry Andric  let ParserMatchClass = ImmXLenAsmOperand<"", "LI_Restricted">;
38306c3fb27SDimitry Andric}
384fe6060f1SDimitry Andric
38506c3fb27SDimitry Andric// Standalone (codegen-only) immleaf patterns.
3860b57cec5SDimitry Andric
387e8d8bef9SDimitry Andric// A 6-bit constant greater than 32.
388e8d8bef9SDimitry Andricdef uimm6gt32 : ImmLeaf<XLenVT, [{
389e8d8bef9SDimitry Andric  return isUInt<6>(Imm) && Imm > 32;
390e8d8bef9SDimitry Andric}]>;
391e8d8bef9SDimitry Andric
3920b57cec5SDimitry Andric// Addressing modes.
3930b57cec5SDimitry Andric// Necessary because a frameindex can't be matched directly in a pattern.
39481ad6265SDimitry Andricdef FrameAddrRegImm : ComplexPattern<iPTR, 2, "SelectFrameAddrRegImm",
39581ad6265SDimitry Andric                                     [frameindex, or, add]>;
39681ad6265SDimitry Andricdef AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;
3970b57cec5SDimitry Andric
3985ffd83dbSDimitry Andric// Return the negation of an immediate value.
3995ffd83dbSDimitry Andricdef NegImm : SDNodeXForm<imm, [{
4005ffd83dbSDimitry Andric  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N),
4015ffd83dbSDimitry Andric                                   N->getValueType(0));
4025ffd83dbSDimitry Andric}]>;
4035ffd83dbSDimitry Andric
404e8d8bef9SDimitry Andric// Return an immediate value minus 32.
405e8d8bef9SDimitry Andricdef ImmSub32 : SDNodeXForm<imm, [{
406e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(N->getSExtValue() - 32, SDLoc(N),
407e8d8bef9SDimitry Andric                                   N->getValueType(0));
408e8d8bef9SDimitry Andric}]>;
409e8d8bef9SDimitry Andric
410e8d8bef9SDimitry Andric// Return an immediate subtracted from XLen.
411e8d8bef9SDimitry Andricdef ImmSubFromXLen : SDNodeXForm<imm, [{
412e8d8bef9SDimitry Andric  uint64_t XLen = Subtarget->getXLen();
413e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),
414e8d8bef9SDimitry Andric                                   N->getValueType(0));
415e8d8bef9SDimitry Andric}]>;
416e8d8bef9SDimitry Andric
417e8d8bef9SDimitry Andric// Return an immediate subtracted from 32.
418e8d8bef9SDimitry Andricdef ImmSubFrom32 : SDNodeXForm<imm, [{
419e8d8bef9SDimitry Andric  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
420e8d8bef9SDimitry Andric                                   N->getValueType(0));
421e8d8bef9SDimitry Andric}]>;
422e8d8bef9SDimitry Andric
423fe6060f1SDimitry Andric// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
42481ad6265SDimitry Andric// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0
42581ad6265SDimitry Andric// as large as possible and imm1 as small as possible so that we might be able
42681ad6265SDimitry Andric// to use c.addi for the small immediate.
427fe6060f1SDimitry Andricdef AddiPair : PatLeaf<(imm), [{
428fe6060f1SDimitry Andric  if (!N->hasOneUse())
429fe6060f1SDimitry Andric    return false;
430fe6060f1SDimitry Andric  // The immediate operand must be in range [-4096,-2049] or [2048,4094].
431fe6060f1SDimitry Andric  int64_t Imm = N->getSExtValue();
432fe6060f1SDimitry Andric  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
433fe6060f1SDimitry Andric}]>;
434fe6060f1SDimitry Andric
43581ad6265SDimitry Andric// Return imm - (imm < 0 ? -2048 : 2047).
43681ad6265SDimitry Andricdef AddiPairImmSmall : SDNodeXForm<imm, [{
43781ad6265SDimitry Andric  int64_t Imm = N->getSExtValue();
43881ad6265SDimitry Andric  int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047;
43981ad6265SDimitry Andric  return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N),
440fe6060f1SDimitry Andric                                   N->getValueType(0));
441fe6060f1SDimitry Andric}]>;
442fe6060f1SDimitry Andric
44381ad6265SDimitry Andric// Return -2048 if immediate is negative or 2047 if positive. These are the
44481ad6265SDimitry Andric// largest simm12 values.
44581ad6265SDimitry Andricdef AddiPairImmLarge : SDNodeXForm<imm, [{
44681ad6265SDimitry Andric  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;
44781ad6265SDimitry Andric  return CurDAG->getTargetConstant(Imm, SDLoc(N),
448fe6060f1SDimitry Andric                                   N->getValueType(0));
449fe6060f1SDimitry Andric}]>;
450fe6060f1SDimitry Andric
45181ad6265SDimitry Andricdef TrailingZeros : SDNodeXForm<imm, [{
45206c3fb27SDimitry Andric  return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),
45381ad6265SDimitry Andric                                   SDLoc(N), N->getValueType(0));
45481ad6265SDimitry Andric}]>;
45581ad6265SDimitry Andric
45604eeddc0SDimitry Andricdef XLenSubTrailingOnes : SDNodeXForm<imm, [{
45704eeddc0SDimitry Andric  uint64_t XLen = Subtarget->getXLen();
45806c3fb27SDimitry Andric  uint64_t TrailingOnes = llvm::countr_one(N->getZExtValue());
45904eeddc0SDimitry Andric  return CurDAG->getTargetConstant(XLen - TrailingOnes, SDLoc(N),
46004eeddc0SDimitry Andric                                   N->getValueType(0));
46104eeddc0SDimitry Andric}]>;
46204eeddc0SDimitry Andric
46304eeddc0SDimitry Andric// Checks if this mask is a non-empty sequence of ones starting at the
46481ad6265SDimitry Andric// most/least significant bit with the remainder zero and exceeds simm32/simm12.
46581ad6265SDimitry Andricdef LeadingOnesMask : PatLeaf<(imm), [{
46681ad6265SDimitry Andric  if (!N->hasOneUse())
46781ad6265SDimitry Andric    return false;
46881ad6265SDimitry Andric  return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue());
46981ad6265SDimitry Andric}], TrailingZeros>;
47081ad6265SDimitry Andric
47104eeddc0SDimitry Andricdef TrailingOnesMask : PatLeaf<(imm), [{
47204eeddc0SDimitry Andric  if (!N->hasOneUse())
47304eeddc0SDimitry Andric    return false;
47404eeddc0SDimitry Andric  return !isInt<12>(N->getSExtValue()) && isMask_64(N->getZExtValue());
47504eeddc0SDimitry Andric}], XLenSubTrailingOnes>;
47604eeddc0SDimitry Andric
477bdd1243dSDimitry Andric// Similar to LeadingOnesMask, but only consider leading ones in the lower 32
478bdd1243dSDimitry Andric// bits.
479bdd1243dSDimitry Andricdef LeadingOnesWMask : PatLeaf<(imm), [{
480bdd1243dSDimitry Andric  if (!N->hasOneUse())
481bdd1243dSDimitry Andric    return false;
482bdd1243dSDimitry Andric  // If the value is a uint32 but not an int32, it must have bit 31 set and
483bdd1243dSDimitry Andric  // bits 63:32 cleared. After that we're looking for a shifted mask but not
484bdd1243dSDimitry Andric  // an all ones mask.
485bdd1243dSDimitry Andric  int64_t Imm = N->getSExtValue();
486bdd1243dSDimitry Andric  return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
487bdd1243dSDimitry Andric         Imm != UINT64_C(0xffffffff);
488bdd1243dSDimitry Andric}], TrailingZeros>;
489bdd1243dSDimitry Andric
4900b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4910b57cec5SDimitry Andric// Instruction Formats
4920b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andricinclude "RISCVInstrFormats.td"
4950b57cec5SDimitry Andric
4960b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4970b57cec5SDimitry Andric// Instruction Class Templates
4980b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
4990b57cec5SDimitry Andric
5000b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
5010b57cec5SDimitry Andricclass BranchCC_rri<bits<3> funct3, string opcodestr>
5020b57cec5SDimitry Andric    : RVInstB<funct3, OPC_BRANCH, (outs),
5030b57cec5SDimitry Andric              (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12),
50413138422SDimitry Andric              opcodestr, "$rs1, $rs2, $imm12">,
5055ffd83dbSDimitry Andric      Sched<[WriteJmp, ReadJmp, ReadJmp]> {
5060b57cec5SDimitry Andric  let isBranch = 1;
5070b57cec5SDimitry Andric  let isTerminator = 1;
5080b57cec5SDimitry Andric}
5090b57cec5SDimitry Andric
51081ad6265SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
5110b57cec5SDimitry Andricclass Load_ri<bits<3> funct3, string opcodestr>
512bdd1243dSDimitry Andric    : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPRMem:$rs1, simm12:$imm12),
5130b57cec5SDimitry Andric              opcodestr, "$rd, ${imm12}(${rs1})">;
5140b57cec5SDimitry Andric
51581ad6265SDimitry Andricclass HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr>
51681ad6265SDimitry Andric    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs GPR:$rd),
51781ad6265SDimitry Andric              (ins GPRMemZeroOffset:$rs1), opcodestr, "$rd, $rs1"> {
51881ad6265SDimitry Andric  let rs2 = funct5;
51981ad6265SDimitry Andric}
52081ad6265SDimitry Andric}
52181ad6265SDimitry Andric
5220b57cec5SDimitry Andric// Operands for stores are in the order srcreg, base, offset rather than
5230b57cec5SDimitry Andric// reflecting the order these fields are specified in the instruction
5240b57cec5SDimitry Andric// encoding.
52581ad6265SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
5260b57cec5SDimitry Andricclass Store_rri<bits<3> funct3, string opcodestr>
5270b57cec5SDimitry Andric    : RVInstS<funct3, OPC_STORE, (outs),
528bdd1243dSDimitry Andric              (ins GPR:$rs2, GPRMem:$rs1, simm12:$imm12),
5290b57cec5SDimitry Andric              opcodestr, "$rs2, ${imm12}(${rs1})">;
5300b57cec5SDimitry Andric
53181ad6265SDimitry Andricclass HStore_rr<bits<7> funct7, string opcodestr>
53281ad6265SDimitry Andric    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs),
53381ad6265SDimitry Andric              (ins GPR:$rs2, GPRMemZeroOffset:$rs1),
53481ad6265SDimitry Andric               opcodestr, "$rs2, $rs1"> {
53581ad6265SDimitry Andric  let rd = 0;
53681ad6265SDimitry Andric}
53781ad6265SDimitry Andric}
53881ad6265SDimitry Andric
5390b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
5400b57cec5SDimitry Andricclass ALU_ri<bits<3> funct3, string opcodestr>
5410b57cec5SDimitry Andric    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
54213138422SDimitry Andric              opcodestr, "$rd, $rs1, $imm12">,
54313138422SDimitry Andric      Sched<[WriteIALU, ReadIALU]>;
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
546fe6060f1SDimitry Andricclass Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr>
547fe6060f1SDimitry Andric    : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd),
5480b57cec5SDimitry Andric                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
54913138422SDimitry Andric                   "$rd, $rs1, $shamt">,
550fe6060f1SDimitry Andric      Sched<[WriteShiftImm, ReadShiftImm]>;
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
55381ad6265SDimitry Andricclass ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
55481ad6265SDimitry Andric             bit Commutable = 0>
5550b57cec5SDimitry Andric    : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
55681ad6265SDimitry Andric              opcodestr, "$rd, $rs1, $rs2"> {
55781ad6265SDimitry Andric  let isCommutable = Commutable;
55881ad6265SDimitry Andric}
5590b57cec5SDimitry Andric
560e8d8bef9SDimitry Andriclet hasNoSchedulingInfo = 1,
561e8d8bef9SDimitry Andric    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
5620b57cec5SDimitry Andricclass CSR_ir<bits<3> funct3, string opcodestr>
5630b57cec5SDimitry Andric    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),
56413138422SDimitry Andric              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>;
5650b57cec5SDimitry Andric
566e8d8bef9SDimitry Andriclet hasNoSchedulingInfo = 1,
567e8d8bef9SDimitry Andric    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
5680b57cec5SDimitry Andricclass CSR_ii<bits<3> funct3, string opcodestr>
5690b57cec5SDimitry Andric    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),
5700b57cec5SDimitry Andric              (ins csr_sysreg:$imm12, uimm5:$rs1),
57113138422SDimitry Andric              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>;
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
574fe6060f1SDimitry Andricclass ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr>
575fe6060f1SDimitry Andric    : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
5760b57cec5SDimitry Andric                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,
57713138422SDimitry Andric                    "$rd, $rs1, $shamt">,
578fe6060f1SDimitry Andric      Sched<[WriteShiftImm32, ReadShiftImm32]>;
5790b57cec5SDimitry Andric
5800b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
58181ad6265SDimitry Andricclass ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
58281ad6265SDimitry Andric              bit Commutable = 0>
5830b57cec5SDimitry Andric    : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
58481ad6265SDimitry Andric              (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
58581ad6265SDimitry Andric  let isCommutable = Commutable;
58681ad6265SDimitry Andric}
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
5890b57cec5SDimitry Andricclass Priv<string opcodestr, bits<7> funct7>
5900b57cec5SDimitry Andric    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
5910b57cec5SDimitry Andric              opcodestr, "">;
5920b57cec5SDimitry Andric
59381ad6265SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
59481ad6265SDimitry Andricclass Priv_rr<string opcodestr, bits<7> funct7>
59581ad6265SDimitry Andric    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
59681ad6265SDimitry Andric              opcodestr, "$rs1, $rs2"> {
59781ad6265SDimitry Andric  let rd = 0;
59881ad6265SDimitry Andric}
59981ad6265SDimitry Andric
6000b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6010b57cec5SDimitry Andric// Instructions
6020b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
6030b57cec5SDimitry Andric
6040b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
605bdd1243dSDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1,
606bdd1243dSDimitry Andric    IsSignExtendingOpW = 1 in
6070b57cec5SDimitry Andricdef LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
60813138422SDimitry Andric                  "lui", "$rd, $imm20">, Sched<[WriteIALU]>;
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andricdef AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20),
61113138422SDimitry Andric                    "auipc", "$rd, $imm20">, Sched<[WriteIALU]>;
6120b57cec5SDimitry Andric
6130b57cec5SDimitry Andricdef JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20),
61413138422SDimitry Andric                  "jal", "$rd, $imm20">, Sched<[WriteJal]>;
6150b57cec5SDimitry Andric
6160b57cec5SDimitry Andricdef JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),
6170b57cec5SDimitry Andric                   (ins GPR:$rs1, simm12:$imm12),
61813138422SDimitry Andric                   "jalr", "$rd, ${imm12}(${rs1})">,
61913138422SDimitry Andric           Sched<[WriteJalr, ReadJalr]>;
6200b57cec5SDimitry Andric} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
6210b57cec5SDimitry Andric
6220b57cec5SDimitry Andricdef BEQ  : BranchCC_rri<0b000, "beq">;
6230b57cec5SDimitry Andricdef BNE  : BranchCC_rri<0b001, "bne">;
6240b57cec5SDimitry Andricdef BLT  : BranchCC_rri<0b100, "blt">;
6250b57cec5SDimitry Andricdef BGE  : BranchCC_rri<0b101, "bge">;
6260b57cec5SDimitry Andricdef BLTU : BranchCC_rri<0b110, "bltu">;
6270b57cec5SDimitry Andricdef BGEU : BranchCC_rri<0b111, "bgeu">;
6280b57cec5SDimitry Andric
629bdd1243dSDimitry Andriclet IsSignExtendingOpW = 1 in {
63013138422SDimitry Andricdef LB  : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>;
63113138422SDimitry Andricdef LH  : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>;
63213138422SDimitry Andricdef LW  : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>;
63313138422SDimitry Andricdef LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>;
63413138422SDimitry Andricdef LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>;
635bdd1243dSDimitry Andric}
6360b57cec5SDimitry Andric
63713138422SDimitry Andricdef SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
63813138422SDimitry Andricdef SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
63913138422SDimitry Andricdef SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andric// ADDI isn't always rematerializable, but isReMaterializable will be used as
6420b57cec5SDimitry Andric// a hint which is verified in isReallyTriviallyReMaterializable.
6430b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in
6440b57cec5SDimitry Andricdef ADDI  : ALU_ri<0b000, "addi">;
6450b57cec5SDimitry Andric
646bdd1243dSDimitry Andriclet IsSignExtendingOpW = 1 in {
6470b57cec5SDimitry Andricdef SLTI  : ALU_ri<0b010, "slti">;
6480b57cec5SDimitry Andricdef SLTIU : ALU_ri<0b011, "sltiu">;
649bdd1243dSDimitry Andric}
6500b57cec5SDimitry Andric
6510b57cec5SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1 in {
6520b57cec5SDimitry Andricdef XORI  : ALU_ri<0b100, "xori">;
6530b57cec5SDimitry Andricdef ORI   : ALU_ri<0b110, "ori">;
6540b57cec5SDimitry Andric}
6550b57cec5SDimitry Andric
6560b57cec5SDimitry Andricdef ANDI  : ALU_ri<0b111, "andi">;
6570b57cec5SDimitry Andric
658fe6060f1SDimitry Andricdef SLLI : Shift_ri<0b00000, 0b001, "slli">;
659fe6060f1SDimitry Andricdef SRLI : Shift_ri<0b00000, 0b101, "srli">;
660fe6060f1SDimitry Andricdef SRAI : Shift_ri<0b01000, 0b101, "srai">;
6610b57cec5SDimitry Andric
66206c3fb27SDimitry Andricdef ADD  : ALU_rr<0b0000000, 0b000, "add", Commutable=1>,
66381ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
66481ad6265SDimitry Andricdef SUB  : ALU_rr<0b0100000, 0b000, "sub">,
66581ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
66681ad6265SDimitry Andricdef SLL  : ALU_rr<0b0000000, 0b001, "sll">,
66781ad6265SDimitry Andric           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
668bdd1243dSDimitry Andriclet IsSignExtendingOpW = 1 in {
66981ad6265SDimitry Andricdef SLT  : ALU_rr<0b0000000, 0b010, "slt">,
67081ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
67181ad6265SDimitry Andricdef SLTU : ALU_rr<0b0000000, 0b011, "sltu">,
67281ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
673bdd1243dSDimitry Andric}
67406c3fb27SDimitry Andricdef XOR  : ALU_rr<0b0000000, 0b100, "xor", Commutable=1>,
67581ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
67681ad6265SDimitry Andricdef SRL  : ALU_rr<0b0000000, 0b101, "srl">,
67781ad6265SDimitry Andric           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
67881ad6265SDimitry Andricdef SRA  : ALU_rr<0b0100000, 0b101, "sra">,
67981ad6265SDimitry Andric           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
68006c3fb27SDimitry Andricdef OR   : ALU_rr<0b0000000, 0b110, "or", Commutable=1>,
68181ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
68206c3fb27SDimitry Andricdef AND  : ALU_rr<0b0000000, 0b111, "and", Commutable=1>,
68381ad6265SDimitry Andric           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
6840b57cec5SDimitry Andric
6850b57cec5SDimitry Andriclet hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
6860b57cec5SDimitry Andricdef FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),
6870b57cec5SDimitry Andric                    (ins fencearg:$pred, fencearg:$succ),
68813138422SDimitry Andric                    "fence", "$pred, $succ">, Sched<[]> {
6890b57cec5SDimitry Andric  bits<4> pred;
6900b57cec5SDimitry Andric  bits<4> succ;
6910b57cec5SDimitry Andric
6920b57cec5SDimitry Andric  let rs1 = 0;
6930b57cec5SDimitry Andric  let rd = 0;
6940b57cec5SDimitry Andric  let imm12 = {0b0000,pred,succ};
6950b57cec5SDimitry Andric}
6960b57cec5SDimitry Andric
69713138422SDimitry Andricdef FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> {
6980b57cec5SDimitry Andric  let rs1 = 0;
6990b57cec5SDimitry Andric  let rd = 0;
7000b57cec5SDimitry Andric  let imm12 = {0b1000,0b0011,0b0011};
7010b57cec5SDimitry Andric}
7020b57cec5SDimitry Andric
70313138422SDimitry Andricdef FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> {
7040b57cec5SDimitry Andric  let rs1 = 0;
7050b57cec5SDimitry Andric  let rd = 0;
7060b57cec5SDimitry Andric  let imm12 = 0;
7070b57cec5SDimitry Andric}
7080b57cec5SDimitry Andric
70913138422SDimitry Andricdef ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> {
7100b57cec5SDimitry Andric  let rs1 = 0;
7110b57cec5SDimitry Andric  let rd = 0;
7120b57cec5SDimitry Andric  let imm12 = 0;
7130b57cec5SDimitry Andric}
7140b57cec5SDimitry Andric
71513138422SDimitry Andricdef EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">,
71613138422SDimitry Andric             Sched<[]> {
7170b57cec5SDimitry Andric  let rs1 = 0;
7180b57cec5SDimitry Andric  let rd = 0;
7190b57cec5SDimitry Andric  let imm12 = 1;
7200b57cec5SDimitry Andric}
7210b57cec5SDimitry Andric
7220b57cec5SDimitry Andric// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
7230b57cec5SDimitry Andric// instruction (i.e., it should always trap, if your implementation has invalid
7240b57cec5SDimitry Andric// instruction traps).
72513138422SDimitry Andricdef UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">,
72613138422SDimitry Andric            Sched<[]> {
7270b57cec5SDimitry Andric  let rs1 = 0;
7280b57cec5SDimitry Andric  let rd = 0;
7290b57cec5SDimitry Andric  let imm12 = 0b110000000000;
7300b57cec5SDimitry Andric}
731bdd1243dSDimitry Andric
7320b57cec5SDimitry Andric} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
7330b57cec5SDimitry Andric
7340b57cec5SDimitry Andricdef CSRRW : CSR_ir<0b001, "csrrw">;
7350b57cec5SDimitry Andricdef CSRRS : CSR_ir<0b010, "csrrs">;
7360b57cec5SDimitry Andricdef CSRRC : CSR_ir<0b011, "csrrc">;
7370b57cec5SDimitry Andric
7380b57cec5SDimitry Andricdef CSRRWI : CSR_ii<0b101, "csrrwi">;
7390b57cec5SDimitry Andricdef CSRRSI : CSR_ii<0b110, "csrrsi">;
7400b57cec5SDimitry Andricdef CSRRCI : CSR_ii<0b111, "csrrci">;
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andric/// RV64I instructions
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andriclet Predicates = [IsRV64] in {
745bdd1243dSDimitry Andricdef LWU   : Load_ri<0b110, "lwu">, Sched<[WriteLDW, ReadMemBase]>;
74613138422SDimitry Andricdef LD    : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>;
74713138422SDimitry Andricdef SD    : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>;
7480b57cec5SDimitry Andric
749bdd1243dSDimitry Andriclet IsSignExtendingOpW = 1 in {
7500b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
7510b57cec5SDimitry Andricdef ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
7520b57cec5SDimitry Andric                    (ins GPR:$rs1, simm12:$imm12),
75313138422SDimitry Andric                    "addiw", "$rd, $rs1, $imm12">,
75413138422SDimitry Andric            Sched<[WriteIALU32, ReadIALU32]>;
7550b57cec5SDimitry Andric
756fe6060f1SDimitry Andricdef SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">;
757fe6060f1SDimitry Andricdef SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">;
758fe6060f1SDimitry Andricdef SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">;
7590b57cec5SDimitry Andric
76006c3fb27SDimitry Andricdef ADDW  : ALUW_rr<0b0000000, 0b000, "addw", Commutable=1>,
76113138422SDimitry Andric            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
76213138422SDimitry Andricdef SUBW  : ALUW_rr<0b0100000, 0b000, "subw">,
76313138422SDimitry Andric            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
76413138422SDimitry Andricdef SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">,
765fe6060f1SDimitry Andric            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
76613138422SDimitry Andricdef SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">,
767fe6060f1SDimitry Andric            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
76813138422SDimitry Andricdef SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">,
769fe6060f1SDimitry Andric            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
770bdd1243dSDimitry Andric} // IsSignExtendingOpW = 1
7710b57cec5SDimitry Andric} // Predicates = [IsRV64]
7720b57cec5SDimitry Andric
7730b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7740b57cec5SDimitry Andric// Privileged instructions
7750b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
7760b57cec5SDimitry Andric
7770b57cec5SDimitry Andriclet isBarrier = 1, isReturn = 1, isTerminator = 1 in {
77813138422SDimitry Andricdef SRET : Priv<"sret", 0b0001000>, Sched<[]> {
7790b57cec5SDimitry Andric  let rd = 0;
7800b57cec5SDimitry Andric  let rs1 = 0;
7810b57cec5SDimitry Andric  let rs2 = 0b00010;
7820b57cec5SDimitry Andric}
7830b57cec5SDimitry Andric
78413138422SDimitry Andricdef MRET : Priv<"mret", 0b0011000>, Sched<[]> {
7850b57cec5SDimitry Andric  let rd = 0;
7860b57cec5SDimitry Andric  let rs1 = 0;
7870b57cec5SDimitry Andric  let rs2 = 0b00010;
7880b57cec5SDimitry Andric}
7890b57cec5SDimitry Andric} // isBarrier = 1, isReturn = 1, isTerminator = 1
7900b57cec5SDimitry Andric
79113138422SDimitry Andricdef WFI : Priv<"wfi", 0b0001000>, Sched<[]> {
7920b57cec5SDimitry Andric  let rd = 0;
7930b57cec5SDimitry Andric  let rs1 = 0;
7940b57cec5SDimitry Andric  let rs2 = 0b00101;
7950b57cec5SDimitry Andric}
7960b57cec5SDimitry Andric
797bdd1243dSDimitry Andriclet Predicates = [HasStdExtSvinval] in {
79881ad6265SDimitry Andricdef SFENCE_W_INVAL : Priv<"sfence.w.inval", 0b0001100>, Sched<[]> {
7990b57cec5SDimitry Andric  let rd = 0;
80081ad6265SDimitry Andric  let rs1 = 0;
80181ad6265SDimitry Andric  let rs2 = 0;
80281ad6265SDimitry Andric}
80381ad6265SDimitry Andric
80481ad6265SDimitry Andricdef SFENCE_INVAL_IR : Priv<"sfence.inval.ir", 0b0001100>, Sched<[]> {
80581ad6265SDimitry Andric  let rd = 0;
80681ad6265SDimitry Andric  let rs1 = 0;
80781ad6265SDimitry Andric  let rs2 = 0b00001;
80881ad6265SDimitry Andric}
80981ad6265SDimitry Andricdef SINVAL_VMA  : Priv_rr<"sinval.vma", 0b0001011>, Sched<[]>;
81081ad6265SDimitry Andricdef HINVAL_VVMA : Priv_rr<"hinval.vvma", 0b0010011>, Sched<[]>;
81181ad6265SDimitry Andricdef HINVAL_GVMA : Priv_rr<"hinval.gvma", 0b0110011>, Sched<[]>;
812bdd1243dSDimitry Andric} // Predicates = [HasStdExtSvinval]
813bdd1243dSDimitry Andric
814bdd1243dSDimitry Andricdef SFENCE_VMA  : Priv_rr<"sfence.vma", 0b0001001>, Sched<[]>;
815bdd1243dSDimitry Andric
816bdd1243dSDimitry Andriclet Predicates = [HasStdExtH] in {
817bdd1243dSDimitry Andricdef HFENCE_VVMA : Priv_rr<"hfence.vvma", 0b0010001>, Sched<[]>;
818bdd1243dSDimitry Andricdef HFENCE_GVMA : Priv_rr<"hfence.gvma", 0b0110001>, Sched<[]>;
81981ad6265SDimitry Andric
82081ad6265SDimitry Andricdef HLV_B   : HLoad_r<0b0110000, 0b00000, "hlv.b">, Sched<[]>;
82181ad6265SDimitry Andricdef HLV_BU  : HLoad_r<0b0110000, 0b00001, "hlv.bu">, Sched<[]>;
82281ad6265SDimitry Andricdef HLV_H   : HLoad_r<0b0110010, 0b00000, "hlv.h">, Sched<[]>;
82381ad6265SDimitry Andricdef HLV_HU  : HLoad_r<0b0110010, 0b00001, "hlv.hu">, Sched<[]>;
82481ad6265SDimitry Andricdef HLVX_HU : HLoad_r<0b0110010, 0b00011, "hlvx.hu">, Sched<[]>;
82581ad6265SDimitry Andricdef HLV_W   : HLoad_r<0b0110100, 0b00000, "hlv.w">, Sched<[]>;
82681ad6265SDimitry Andricdef HLVX_WU : HLoad_r<0b0110100, 0b00011, "hlvx.wu">, Sched<[]>;
82781ad6265SDimitry Andricdef HSV_B   : HStore_rr<0b0110001, "hsv.b">, Sched<[]>;
82881ad6265SDimitry Andricdef HSV_H   : HStore_rr<0b0110011, "hsv.h">, Sched<[]>;
82981ad6265SDimitry Andricdef HSV_W   : HStore_rr<0b0110101, "hsv.w">, Sched<[]>;
830bdd1243dSDimitry Andric}
831bdd1243dSDimitry Andriclet Predicates = [IsRV64, HasStdExtH] in {
83281ad6265SDimitry Andricdef HLV_WU  : HLoad_r<0b0110100, 0b00001, "hlv.wu">, Sched<[]>;
83381ad6265SDimitry Andricdef HLV_D   : HLoad_r<0b0110110, 0b00000, "hlv.d">, Sched<[]>;
83481ad6265SDimitry Andricdef HSV_D   : HStore_rr<0b0110111, "hsv.d">, Sched<[]>;
8350b57cec5SDimitry Andric}
8360b57cec5SDimitry Andric
8370b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8385ffd83dbSDimitry Andric// Debug instructions
8395ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
8405ffd83dbSDimitry Andric
8415ffd83dbSDimitry Andriclet isBarrier = 1, isReturn = 1, isTerminator = 1 in {
8425ffd83dbSDimitry Andricdef DRET : Priv<"dret", 0b0111101>, Sched<[]> {
8435ffd83dbSDimitry Andric  let rd = 0;
8445ffd83dbSDimitry Andric  let rs1 = 0;
8455ffd83dbSDimitry Andric  let rs2 = 0b10010;
8465ffd83dbSDimitry Andric}
8475ffd83dbSDimitry Andric} // isBarrier = 1, isReturn = 1, isTerminator = 1
8485ffd83dbSDimitry Andric
8495ffd83dbSDimitry Andric//===----------------------------------------------------------------------===//
8500b57cec5SDimitry Andric// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
8510b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
8520b57cec5SDimitry Andric
8530b57cec5SDimitry Andricdef : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
8540b57cec5SDimitry Andric
8550b57cec5SDimitry Andric// Note that the size is 32 because up to 8 32-bit instructions are needed to
8560b57cec5SDimitry Andric// generate an arbitrary 64-bit immediate. However, the size does not really
8570b57cec5SDimitry Andric// matter since PseudoLI is currently only used in the AsmParser where it gets
8580b57cec5SDimitry Andric// expanded to real instructions immediately.
8590b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
8600b57cec5SDimitry Andric    isCodeGenOnly = 0, isAsmParserOnly = 1 in
8610b57cec5SDimitry Andricdef PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
8620b57cec5SDimitry Andric                      "li", "$rd, $imm">;
8630b57cec5SDimitry Andric
8640b57cec5SDimitry Andricdef PseudoLB  : PseudoLoad<"lb">;
8650b57cec5SDimitry Andricdef PseudoLBU : PseudoLoad<"lbu">;
8660b57cec5SDimitry Andricdef PseudoLH  : PseudoLoad<"lh">;
8670b57cec5SDimitry Andricdef PseudoLHU : PseudoLoad<"lhu">;
8680b57cec5SDimitry Andricdef PseudoLW  : PseudoLoad<"lw">;
8690b57cec5SDimitry Andric
8700b57cec5SDimitry Andricdef PseudoSB  : PseudoStore<"sb">;
8710b57cec5SDimitry Andricdef PseudoSH  : PseudoStore<"sh">;
8720b57cec5SDimitry Andricdef PseudoSW  : PseudoStore<"sw">;
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andriclet Predicates = [IsRV64] in {
8750b57cec5SDimitry Andricdef PseudoLWU : PseudoLoad<"lwu">;
8760b57cec5SDimitry Andricdef PseudoLD  : PseudoLoad<"ld">;
8770b57cec5SDimitry Andricdef PseudoSD  : PseudoStore<"sd">;
8780b57cec5SDimitry Andric} // Predicates = [IsRV64]
8790b57cec5SDimitry Andric
8804824e7fdSDimitry Andricdef : InstAlias<"li $rd, $imm",  (ADDI GPR:$rd, X0, simm12:$imm)>;
8810b57cec5SDimitry Andricdef : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
8820b57cec5SDimitry Andricdef : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
8830b57cec5SDimitry Andricdef : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
8840b57cec5SDimitry Andric
8850b57cec5SDimitry Andriclet Predicates = [IsRV64] in {
8860b57cec5SDimitry Andricdef : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;
8870b57cec5SDimitry Andricdef : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;
8880b57cec5SDimitry Andric} // Predicates = [IsRV64]
8890b57cec5SDimitry Andric
8900b57cec5SDimitry Andricdef : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;
8910b57cec5SDimitry Andricdef : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;
8920b57cec5SDimitry Andricdef : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;
8930b57cec5SDimitry Andricdef : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;
8940b57cec5SDimitry Andric
8950b57cec5SDimitry Andric// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu
8960b57cec5SDimitry Andric// form will always be printed. Therefore, set a zero weight.
8970b57cec5SDimitry Andricdef : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;
8980b57cec5SDimitry Andricdef : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;
8990b57cec5SDimitry Andric
9000b57cec5SDimitry Andricdef : InstAlias<"beqz $rs, $offset",
9010b57cec5SDimitry Andric                (BEQ GPR:$rs,      X0, simm13_lsb0:$offset)>;
9020b57cec5SDimitry Andricdef : InstAlias<"bnez $rs, $offset",
9030b57cec5SDimitry Andric                (BNE GPR:$rs,      X0, simm13_lsb0:$offset)>;
9040b57cec5SDimitry Andricdef : InstAlias<"blez $rs, $offset",
9050b57cec5SDimitry Andric                (BGE      X0, GPR:$rs, simm13_lsb0:$offset)>;
9060b57cec5SDimitry Andricdef : InstAlias<"bgez $rs, $offset",
9070b57cec5SDimitry Andric                (BGE GPR:$rs,      X0, simm13_lsb0:$offset)>;
9080b57cec5SDimitry Andricdef : InstAlias<"bltz $rs, $offset",
9090b57cec5SDimitry Andric                (BLT GPR:$rs,      X0, simm13_lsb0:$offset)>;
9100b57cec5SDimitry Andricdef : InstAlias<"bgtz $rs, $offset",
9110b57cec5SDimitry Andric                (BLT      X0, GPR:$rs, simm13_lsb0:$offset)>;
9120b57cec5SDimitry Andric
9130b57cec5SDimitry Andric// Always output the canonical mnemonic for the pseudo branch instructions.
9140b57cec5SDimitry Andric// The GNU tools emit the canonical mnemonic for the branch pseudo instructions
9150b57cec5SDimitry Andric// as well (e.g. "bgt" will be recognised by the assembler but never printed by
9160b57cec5SDimitry Andric// objdump). Match this behaviour by setting a zero weight.
9170b57cec5SDimitry Andricdef : InstAlias<"bgt $rs, $rt, $offset",
9180b57cec5SDimitry Andric                (BLT  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
9190b57cec5SDimitry Andricdef : InstAlias<"ble $rs, $rt, $offset",
9200b57cec5SDimitry Andric                (BGE  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
9210b57cec5SDimitry Andricdef : InstAlias<"bgtu $rs, $rt, $offset",
9220b57cec5SDimitry Andric                (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
9230b57cec5SDimitry Andricdef : InstAlias<"bleu $rs, $rt, $offset",
9240b57cec5SDimitry Andric                (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andricdef : InstAlias<"j $offset",   (JAL X0, simm21_lsb0_jal:$offset)>;
9270b57cec5SDimitry Andricdef : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>;
9280b57cec5SDimitry Andric
9290b57cec5SDimitry Andric// Non-zero offset aliases of "jalr" are the lowest weight, followed by the
9300b57cec5SDimitry Andric// two-register form, then the one-register forms and finally "ret".
9310b57cec5SDimitry Andricdef : InstAlias<"jr $rs",                (JALR      X0, GPR:$rs, 0), 3>;
9320b57cec5SDimitry Andricdef : InstAlias<"jr ${offset}(${rs})",   (JALR      X0, GPR:$rs, simm12:$offset)>;
9330b57cec5SDimitry Andricdef : InstAlias<"jalr $rs",              (JALR      X1, GPR:$rs, 0), 3>;
9340b57cec5SDimitry Andricdef : InstAlias<"jalr ${offset}(${rs})", (JALR      X1, GPR:$rs, simm12:$offset)>;
9350b57cec5SDimitry Andricdef : InstAlias<"jalr $rd, $rs",         (JALR GPR:$rd, GPR:$rs, 0), 2>;
9360b57cec5SDimitry Andricdef : InstAlias<"ret",                   (JALR      X0,      X1, 0), 4>;
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andric// Non-canonical forms for jump targets also accepted by the assembler.
9390b57cec5SDimitry Andricdef : InstAlias<"jr $rs, $offset",        (JALR      X0, GPR:$rs, simm12:$offset), 0>;
9400b57cec5SDimitry Andricdef : InstAlias<"jalr $rs, $offset",      (JALR      X1, GPR:$rs, simm12:$offset), 0>;
9410b57cec5SDimitry Andricdef : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>;
9420b57cec5SDimitry Andric
9430b57cec5SDimitry Andricdef : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
9440b57cec5SDimitry Andric
94581ad6265SDimitry Andriclet Predicates = [HasStdExtZihintpause] in
94681ad6265SDimitry Andricdef : InstAlias<"pause", (FENCE 0x1, 0x0)>; // 0x1 == w
94781ad6265SDimitry Andric
9480b57cec5SDimitry Andricdef : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>;
9490b57cec5SDimitry Andricdef : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, CYCLE.Encoding, X0)>;
9500b57cec5SDimitry Andricdef : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, TIME.Encoding, X0)>;
9510b57cec5SDimitry Andric
9520b57cec5SDimitry Andriclet Predicates = [IsRV32] in {
9530b57cec5SDimitry Andricdef : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0)>;
9540b57cec5SDimitry Andricdef : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, CYCLEH.Encoding, X0)>;
9550b57cec5SDimitry Andricdef : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, TIMEH.Encoding, X0)>;
9560b57cec5SDimitry Andric} // Predicates = [IsRV32]
9570b57cec5SDimitry Andric
9580b57cec5SDimitry Andricdef : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;
9590b57cec5SDimitry Andricdef : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;
9600b57cec5SDimitry Andricdef : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;
9610b57cec5SDimitry Andricdef : InstAlias<"csrc $csr, $rs", (CSRRC      X0, csr_sysreg:$csr, GPR:$rs)>;
9620b57cec5SDimitry Andric
9630b57cec5SDimitry Andricdef : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
9640b57cec5SDimitry Andricdef : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
9650b57cec5SDimitry Andricdef : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
9660b57cec5SDimitry Andric
9670b57cec5SDimitry Andriclet EmitPriority = 0 in {
9680b57cec5SDimitry Andricdef : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
9690b57cec5SDimitry Andricdef : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
9700b57cec5SDimitry Andricdef : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
9710b57cec5SDimitry Andric
9720b57cec5SDimitry Andricdef : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
9730b57cec5SDimitry Andricdef : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
9740b57cec5SDimitry Andricdef : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
9750b57cec5SDimitry Andric}
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andricdef : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
9780b57cec5SDimitry Andricdef : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
9790b57cec5SDimitry Andric
98081ad6265SDimitry Andricdef : InstAlias<"hfence.gvma",     (HFENCE_GVMA      X0, X0)>;
98181ad6265SDimitry Andricdef : InstAlias<"hfence.gvma $rs", (HFENCE_GVMA GPR:$rs, X0)>;
98281ad6265SDimitry Andric
98381ad6265SDimitry Andricdef : InstAlias<"hfence.vvma",     (HFENCE_VVMA      X0, X0)>;
98481ad6265SDimitry Andricdef : InstAlias<"hfence.vvma $rs", (HFENCE_VVMA GPR:$rs, X0)>;
98581ad6265SDimitry Andric
986bdd1243dSDimitry Andriclet Predicates = [HasStdExtZihintntl] in {
987bdd1243dSDimitry Andric  def : InstAlias<"ntl.p1",     (ADD   X0, X0, X2)>;
988bdd1243dSDimitry Andric  def : InstAlias<"ntl.pall",   (ADD   X0, X0, X3)>;
989bdd1243dSDimitry Andric  def : InstAlias<"ntl.s1",     (ADD   X0, X0, X4)>;
990bdd1243dSDimitry Andric  def : InstAlias<"ntl.all",    (ADD   X0, X0, X5)>;
991bdd1243dSDimitry Andric} // Predicates = [HasStdExtZihintntl]
992bdd1243dSDimitry Andric
9930b57cec5SDimitry Andriclet EmitPriority = 0 in {
9940b57cec5SDimitry Andricdef : InstAlias<"lb $rd, (${rs1})",
9950b57cec5SDimitry Andric                (LB  GPR:$rd, GPR:$rs1, 0)>;
9960b57cec5SDimitry Andricdef : InstAlias<"lh $rd, (${rs1})",
9970b57cec5SDimitry Andric                (LH  GPR:$rd, GPR:$rs1, 0)>;
9980b57cec5SDimitry Andricdef : InstAlias<"lw $rd, (${rs1})",
9990b57cec5SDimitry Andric                (LW  GPR:$rd, GPR:$rs1, 0)>;
10000b57cec5SDimitry Andricdef : InstAlias<"lbu $rd, (${rs1})",
10010b57cec5SDimitry Andric                (LBU  GPR:$rd, GPR:$rs1, 0)>;
10020b57cec5SDimitry Andricdef : InstAlias<"lhu $rd, (${rs1})",
10030b57cec5SDimitry Andric                (LHU  GPR:$rd, GPR:$rs1, 0)>;
10040b57cec5SDimitry Andric
10050b57cec5SDimitry Andricdef : InstAlias<"sb $rs2, (${rs1})",
10060b57cec5SDimitry Andric                (SB  GPR:$rs2, GPR:$rs1, 0)>;
10070b57cec5SDimitry Andricdef : InstAlias<"sh $rs2, (${rs1})",
10080b57cec5SDimitry Andric                (SH  GPR:$rs2, GPR:$rs1, 0)>;
10090b57cec5SDimitry Andricdef : InstAlias<"sw $rs2, (${rs1})",
10100b57cec5SDimitry Andric                (SW  GPR:$rs2, GPR:$rs1, 0)>;
10110b57cec5SDimitry Andric
10120b57cec5SDimitry Andricdef : InstAlias<"add $rd, $rs1, $imm12",
10130b57cec5SDimitry Andric                (ADDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10140b57cec5SDimitry Andricdef : InstAlias<"and $rd, $rs1, $imm12",
10150b57cec5SDimitry Andric                (ANDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10160b57cec5SDimitry Andricdef : InstAlias<"xor $rd, $rs1, $imm12",
10170b57cec5SDimitry Andric                (XORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10180b57cec5SDimitry Andricdef : InstAlias<"or $rd, $rs1, $imm12",
10190b57cec5SDimitry Andric                (ORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10200b57cec5SDimitry Andricdef : InstAlias<"sll $rd, $rs1, $shamt",
10210b57cec5SDimitry Andric                (SLLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
10220b57cec5SDimitry Andricdef : InstAlias<"srl $rd, $rs1, $shamt",
10230b57cec5SDimitry Andric                (SRLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
10240b57cec5SDimitry Andricdef : InstAlias<"sra $rd, $rs1, $shamt",
10250b57cec5SDimitry Andric                (SRAI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
10260b57cec5SDimitry Andriclet Predicates = [IsRV64] in {
10270b57cec5SDimitry Andricdef : InstAlias<"lwu $rd, (${rs1})",
10280b57cec5SDimitry Andric                (LWU  GPR:$rd, GPR:$rs1, 0)>;
10290b57cec5SDimitry Andricdef : InstAlias<"ld $rd, (${rs1})",
10300b57cec5SDimitry Andric                (LD  GPR:$rd, GPR:$rs1, 0)>;
10310b57cec5SDimitry Andricdef : InstAlias<"sd $rs2, (${rs1})",
10320b57cec5SDimitry Andric                (SD  GPR:$rs2, GPR:$rs1, 0)>;
10330b57cec5SDimitry Andric
10340b57cec5SDimitry Andricdef : InstAlias<"addw $rd, $rs1, $imm12",
10350b57cec5SDimitry Andric                (ADDIW  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10360b57cec5SDimitry Andricdef : InstAlias<"sllw $rd, $rs1, $shamt",
10370b57cec5SDimitry Andric                (SLLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
10380b57cec5SDimitry Andricdef : InstAlias<"srlw $rd, $rs1, $shamt",
10390b57cec5SDimitry Andric                (SRLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
10400b57cec5SDimitry Andricdef : InstAlias<"sraw $rd, $rs1, $shamt",
10410b57cec5SDimitry Andric                (SRAIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
10420b57cec5SDimitry Andric} // Predicates = [IsRV64]
10430b57cec5SDimitry Andricdef : InstAlias<"slt $rd, $rs1, $imm12",
10440b57cec5SDimitry Andric                (SLTI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10450b57cec5SDimitry Andricdef : InstAlias<"sltu $rd, $rs1, $imm12",
10460b57cec5SDimitry Andric                (SLTIU  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
10470b57cec5SDimitry Andric}
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andricdef : MnemonicAlias<"move", "mv">;
10500b57cec5SDimitry Andric
10510b57cec5SDimitry Andric// The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in
10520b57cec5SDimitry Andric// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept
10530b57cec5SDimitry Andric// the old name for backwards compatibility.
10540b57cec5SDimitry Andricdef : MnemonicAlias<"scall", "ecall">;
10550b57cec5SDimitry Andricdef : MnemonicAlias<"sbreak", "ebreak">;
10560b57cec5SDimitry Andric
1057e8d8bef9SDimitry Andric// This alias was added to the spec in December 2020. Don't print it by default
1058e8d8bef9SDimitry Andric// to allow assembly we print to be compatible with versions of GNU assembler
1059e8d8bef9SDimitry Andric// that don't support this alias.
1060e8d8bef9SDimitry Andricdef : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF), 0>;
1061e8d8bef9SDimitry Andric
10625f757f3fSDimitry Andriclet Predicates = [HasStdExtZicfilp] in {
10635f757f3fSDimitry Andricdef : InstAlias<"lpad $imm20", (AUIPC X0, uimm20:$imm20)>;
10645f757f3fSDimitry Andric}
10655f757f3fSDimitry Andric
10660b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
1067349cc55cSDimitry Andric// .insn directive instructions
1068349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
1069349cc55cSDimitry Andric
107006c3fb27SDimitry Andricdef AnyRegOperand : AsmOperandClass {
107106c3fb27SDimitry Andric  let Name = "AnyRegOperand";
107206c3fb27SDimitry Andric  let RenderMethod = "addRegOperands";
107306c3fb27SDimitry Andric  let PredicateMethod = "isAnyReg";
107406c3fb27SDimitry Andric}
107506c3fb27SDimitry Andric
107606c3fb27SDimitry Andricdef AnyReg : Operand<XLenVT> {
107706c3fb27SDimitry Andric  let OperandType = "OPERAND_REGISTER";
107806c3fb27SDimitry Andric  let ParserMatchClass = AnyRegOperand;
107906c3fb27SDimitry Andric}
108006c3fb27SDimitry Andric
1081349cc55cSDimitry Andric// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
1082349cc55cSDimitry Andriclet isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
1083349cc55cSDimitry Andric    hasNoSchedulingInfo = 1 in {
10840eae32dcSDimitry Andricdef InsnR : DirectiveInsnR<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1085349cc55cSDimitry Andric                                                   uimm7:$funct7, AnyReg:$rs1,
1086349cc55cSDimitry Andric                                                   AnyReg:$rs2),
1087349cc55cSDimitry Andric                           "$opcode, $funct3, $funct7, $rd, $rs1, $rs2">;
10880eae32dcSDimitry Andricdef InsnR4 : DirectiveInsnR4<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1089349cc55cSDimitry Andric                                                     uimm3:$funct3,
1090349cc55cSDimitry Andric                                                     uimm2:$funct2,
1091349cc55cSDimitry Andric                                                     AnyReg:$rs1, AnyReg:$rs2,
1092349cc55cSDimitry Andric                                                     AnyReg:$rs3),
1093349cc55cSDimitry Andric                            "$opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3">;
10940eae32dcSDimitry Andricdef InsnI : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1095349cc55cSDimitry Andric                                                   AnyReg:$rs1, simm12:$imm12),
1096349cc55cSDimitry Andric                           "$opcode, $funct3, $rd, $rs1, $imm12">;
10970eae32dcSDimitry Andricdef InsnI_Mem : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1098349cc55cSDimitry Andric                                                       uimm3:$funct3,
1099349cc55cSDimitry Andric                                                       AnyReg:$rs1,
1100349cc55cSDimitry Andric                                                       simm12:$imm12),
1101349cc55cSDimitry Andric                               "$opcode, $funct3, $rd, ${imm12}(${rs1})">;
11020eae32dcSDimitry Andricdef InsnB : DirectiveInsnB<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1103349cc55cSDimitry Andric                                        AnyReg:$rs1, AnyReg:$rs2,
1104349cc55cSDimitry Andric                                        simm13_lsb0:$imm12),
1105349cc55cSDimitry Andric                           "$opcode, $funct3, $rs1, $rs2, $imm12">;
11060eae32dcSDimitry Andricdef InsnU : DirectiveInsnU<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1107349cc55cSDimitry Andric                                                   uimm20_lui:$imm20),
1108349cc55cSDimitry Andric                           "$opcode, $rd, $imm20">;
11090eae32dcSDimitry Andricdef InsnJ : DirectiveInsnJ<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1110349cc55cSDimitry Andric                                                   simm21_lsb0_jal:$imm20),
1111349cc55cSDimitry Andric                           "$opcode, $rd, $imm20">;
11120eae32dcSDimitry Andricdef InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1113349cc55cSDimitry Andric                                        AnyReg:$rs2, AnyReg:$rs1,
1114349cc55cSDimitry Andric                                        simm12:$imm12),
1115349cc55cSDimitry Andric                           "$opcode, $funct3, $rs2, ${imm12}(${rs1})">;
1116349cc55cSDimitry Andric}
1117349cc55cSDimitry Andric
1118349cc55cSDimitry Andric// Use InstAliases to match these so that we can combine the insn and format
1119349cc55cSDimitry Andric// into a mnemonic to use as the key for the tablegened asm matcher table. The
1120349cc55cSDimitry Andric// parser will take care of creating these fake mnemonics and will only do it
1121349cc55cSDimitry Andric// for known formats.
1122349cc55cSDimitry Andriclet EmitPriority = 0 in {
1123349cc55cSDimitry Andricdef : InstAlias<".insn_r $opcode, $funct3, $funct7, $rd, $rs1, $rs2",
11240eae32dcSDimitry Andric                (InsnR AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm7:$funct7,
1125349cc55cSDimitry Andric                       AnyReg:$rs1, AnyReg:$rs2)>;
1126349cc55cSDimitry Andric// Accept 4 register form of ".insn r" as alias for ".insn r4".
1127349cc55cSDimitry Andricdef : InstAlias<".insn_r $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",
11280eae32dcSDimitry Andric                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,
1129349cc55cSDimitry Andric                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;
1130349cc55cSDimitry Andricdef : InstAlias<".insn_r4 $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",
11310eae32dcSDimitry Andric                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,
1132349cc55cSDimitry Andric                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;
1133349cc55cSDimitry Andricdef : InstAlias<".insn_i $opcode, $funct3, $rd, $rs1, $imm12",
11340eae32dcSDimitry Andric                (InsnI AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1135349cc55cSDimitry Andric                       simm12:$imm12)>;
1136349cc55cSDimitry Andricdef : InstAlias<".insn_i $opcode, $funct3, $rd, ${imm12}(${rs1})",
11370eae32dcSDimitry Andric                (InsnI_Mem AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3,
1138349cc55cSDimitry Andric                           AnyReg:$rs1, simm12:$imm12)>;
1139349cc55cSDimitry Andricdef : InstAlias<".insn_b $opcode, $funct3, $rs1, $rs2, $imm12",
11400eae32dcSDimitry Andric                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1141349cc55cSDimitry Andric                       AnyReg:$rs2, simm13_lsb0:$imm12)>;
1142349cc55cSDimitry Andric// Accept sb as an alias for b.
1143349cc55cSDimitry Andricdef : InstAlias<".insn_sb $opcode, $funct3, $rs1, $rs2, $imm12",
11440eae32dcSDimitry Andric                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1145349cc55cSDimitry Andric                       AnyReg:$rs2, simm13_lsb0:$imm12)>;
1146349cc55cSDimitry Andricdef : InstAlias<".insn_u $opcode, $rd, $imm20",
11470eae32dcSDimitry Andric                (InsnU AnyReg:$rd, uimm7_opcode:$opcode, uimm20_lui:$imm20)>;
1148349cc55cSDimitry Andricdef : InstAlias<".insn_j $opcode, $rd, $imm20",
11490eae32dcSDimitry Andric                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;
1150349cc55cSDimitry Andric// Accept uj as an alias for j.
1151349cc55cSDimitry Andricdef : InstAlias<".insn_uj $opcode, $rd, $imm20",
11520eae32dcSDimitry Andric                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;
1153349cc55cSDimitry Andricdef : InstAlias<".insn_s $opcode, $funct3, $rs2, ${imm12}(${rs1})",
11540eae32dcSDimitry Andric                (InsnS uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,
1155349cc55cSDimitry Andric                       AnyReg:$rs1, simm12:$imm12)>;
1156349cc55cSDimitry Andric}
1157349cc55cSDimitry Andric
1158349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
11590b57cec5SDimitry Andric// Pseudo-instructions and codegen patterns
11600b57cec5SDimitry Andric//
11610b57cec5SDimitry Andric// Naming convention: For 'generic' pattern classes, we use the naming
11620b57cec5SDimitry Andric// convention PatTy1Ty2. For pattern classes which offer a more complex
11635ffd83dbSDimitry Andric// expansion, prefix the class name, e.g. BccPat.
11640b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
11650b57cec5SDimitry Andric
11660b57cec5SDimitry Andric/// Generic pattern classes
11670b57cec5SDimitry Andric
116806c3fb27SDimitry Andricclass PatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
116906c3fb27SDimitry Andric    : Pat<(vt (OpNode (vt GPR:$rs1))), (Inst GPR:$rs1)>;
11705f757f3fSDimitry Andricclass PatGprGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt1 = XLenVT,
11715f757f3fSDimitry Andric                ValueType vt2 = XLenVT>
11725f757f3fSDimitry Andric    : Pat<(vt1 (OpNode (vt1 GPR:$rs1), (vt2 GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>;
1173fe6060f1SDimitry Andric
11745f757f3fSDimitry Andricclass PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType,
11755f757f3fSDimitry Andric                ValueType vt = XLenVT>
11765f757f3fSDimitry Andric    : Pat<(vt (OpNode (vt GPR:$rs1), ImmType:$imm)),
1177fe6060f1SDimitry Andric          (Inst GPR:$rs1, ImmType:$imm)>;
11780b57cec5SDimitry Andricclass PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
1179fe6060f1SDimitry Andric    : PatGprImm<OpNode, Inst, simm12>;
11800b57cec5SDimitry Andricclass PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
1181fe6060f1SDimitry Andric    : PatGprImm<OpNode, Inst, uimmlog2xlen>;
11820b57cec5SDimitry Andric
11830b57cec5SDimitry Andric/// Predicates
11840b57cec5SDimitry Andric
11850b57cec5SDimitry Andricdef assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
1186e8d8bef9SDimitry Andric  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
11870b57cec5SDimitry Andric}]>;
118806c3fb27SDimitry Andricdef sexti16 : ComplexPattern<XLenVT, 1, "selectSExtBits<16>">;
118906c3fb27SDimitry Andricdef sexti32 : ComplexPattern<i64, 1, "selectSExtBits<32>">;
11900b57cec5SDimitry Andricdef assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
1191e8d8bef9SDimitry Andric  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
11920b57cec5SDimitry Andric}]>;
1193bdd1243dSDimitry Andricdef zexti32 : ComplexPattern<i64, 1, "selectZExtBits<32>">;
1194bdd1243dSDimitry Andricdef zexti16 : ComplexPattern<XLenVT, 1, "selectZExtBits<16>">;
11955f757f3fSDimitry Andricdef zexti16i32 : ComplexPattern<i32, 1, "selectZExtBits<16>">;
1196bdd1243dSDimitry Andricdef zexti8 : ComplexPattern<XLenVT, 1, "selectZExtBits<8>">;
11975f757f3fSDimitry Andricdef zexti8i32 : ComplexPattern<i32, 1, "selectZExtBits<8>">;
11980b57cec5SDimitry Andric
119906c3fb27SDimitry Andricdef ext : PatFrags<(ops node:$A), [(sext node:$A), (zext node:$A)]>;
120006c3fb27SDimitry Andric
120181ad6265SDimitry Andricclass binop_oneuse<SDPatternOperator operator>
120281ad6265SDimitry Andric    : PatFrag<(ops node:$A, node:$B),
120381ad6265SDimitry Andric              (operator node:$A, node:$B), [{
1204fe6060f1SDimitry Andric  return N->hasOneUse();
1205e8d8bef9SDimitry Andric}]>;
1206e8d8bef9SDimitry Andric
1207bdd1243dSDimitry Andricdef and_oneuse : binop_oneuse<and>;
120881ad6265SDimitry Andricdef mul_oneuse : binop_oneuse<mul>;
1209e8d8bef9SDimitry Andric
1210349cc55cSDimitry Andricdef mul_const_oneuse : PatFrag<(ops node:$A, node:$B),
1211349cc55cSDimitry Andric                               (mul node:$A, node:$B), [{
1212349cc55cSDimitry Andric  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
121306c3fb27SDimitry Andric    return N1C->hasOneUse();
1214349cc55cSDimitry Andric  return false;
1215349cc55cSDimitry Andric}]>;
1216349cc55cSDimitry Andric
121781ad6265SDimitry Andricclass unop_oneuse<SDPatternOperator operator>
121881ad6265SDimitry Andric    : PatFrag<(ops node:$A),
121981ad6265SDimitry Andric              (operator node:$A), [{
122004eeddc0SDimitry Andric  return N->hasOneUse();
122104eeddc0SDimitry Andric}]>;
122204eeddc0SDimitry Andric
122381ad6265SDimitry Andricdef sext_oneuse   : unop_oneuse<sext>;
122481ad6265SDimitry Andricdef zext_oneuse   : unop_oneuse<zext>;
122581ad6265SDimitry Andricdef anyext_oneuse : unop_oneuse<anyext>;
122606c3fb27SDimitry Andricdef ext_oneuse    : unop_oneuse<ext>;
122781ad6265SDimitry Andricdef fpext_oneuse  : unop_oneuse<any_fpextend>;
122804eeddc0SDimitry Andric
12295f757f3fSDimitry Andricdef 33signbits_node : PatLeaf<(i64 GPR:$src), [{
12305f757f3fSDimitry Andric  return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32;
12315f757f3fSDimitry Andric}]>;
12325f757f3fSDimitry Andric
12330b57cec5SDimitry Andric/// Simple arithmetic operations
12340b57cec5SDimitry Andric
12350b57cec5SDimitry Andricdef : PatGprGpr<add, ADD>;
12360b57cec5SDimitry Andricdef : PatGprSimm12<add, ADDI>;
12370b57cec5SDimitry Andricdef : PatGprGpr<sub, SUB>;
12380b57cec5SDimitry Andricdef : PatGprGpr<or, OR>;
12390b57cec5SDimitry Andricdef : PatGprSimm12<or, ORI>;
12400b57cec5SDimitry Andricdef : PatGprGpr<and, AND>;
12410b57cec5SDimitry Andricdef : PatGprSimm12<and, ANDI>;
12420b57cec5SDimitry Andricdef : PatGprGpr<xor, XOR>;
12430b57cec5SDimitry Andricdef : PatGprSimm12<xor, XORI>;
12440b57cec5SDimitry Andricdef : PatGprUimmLog2XLen<shl, SLLI>;
12450b57cec5SDimitry Andricdef : PatGprUimmLog2XLen<srl, SRLI>;
12460b57cec5SDimitry Andricdef : PatGprUimmLog2XLen<sra, SRAI>;
12470b57cec5SDimitry Andric
1248bdd1243dSDimitry Andric// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This
1249bdd1243dSDimitry Andric// can improve compressibility.
1250bdd1243dSDimitry Andricdef or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
1251bdd1243dSDimitry Andric  KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
1252bdd1243dSDimitry Andric  KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
1253bdd1243dSDimitry Andric  return KnownBits::haveNoCommonBitsSet(Known0, Known1);
1254bdd1243dSDimitry Andric}]>;
1255bdd1243dSDimitry Andricdef : PatGprSimm12<or_is_add, ADDI>;
1256bdd1243dSDimitry Andric
1257bdd1243dSDimitry Andric// negate of low bit can be done via two (compressible) shifts.  The negate
1258bdd1243dSDimitry Andric// is never compressible since rs1 and rd can't be the same register.
1259bdd1243dSDimitry Andricdef : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))),
1260bdd1243dSDimitry Andric          (SRAI (SLLI $rs, (ImmSubFromXLen (XLenVT 1))),
1261bdd1243dSDimitry Andric                (ImmSubFromXLen (XLenVT 1)))>;
1262bdd1243dSDimitry Andric
126381ad6265SDimitry Andric// AND with leading/trailing ones mask exceeding simm32/simm12.
126481ad6265SDimitry Andricdef : Pat<(i64 (and GPR:$rs, LeadingOnesMask:$mask)),
126581ad6265SDimitry Andric          (SLLI (SRLI $rs, LeadingOnesMask:$mask), LeadingOnesMask:$mask)>;
126604eeddc0SDimitry Andricdef : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)),
126704eeddc0SDimitry Andric          (SRLI (SLLI $rs, TrailingOnesMask:$mask), TrailingOnesMask:$mask)>;
126804eeddc0SDimitry Andric
12690b57cec5SDimitry Andric// Match both a plain shift and one where the shift amount is masked (this is
12700b57cec5SDimitry Andric// typically introduced when the legalizer promotes the shift amount and
12710b57cec5SDimitry Andric// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base
12720b57cec5SDimitry Andric// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).
1273fe6060f1SDimitry Andricdef shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>;
1274fe6060f1SDimitry Andricdef shiftMask32   : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;
1275fe6060f1SDimitry Andric
12760b57cec5SDimitry Andricclass shiftop<SDPatternOperator operator>
1277fe6060f1SDimitry Andric    : PatFrag<(ops node:$val, node:$count),
1278fe6060f1SDimitry Andric              (operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>;
1279e8d8bef9SDimitry Andricclass shiftopw<SDPatternOperator operator>
1280fe6060f1SDimitry Andric    : PatFrag<(ops node:$val, node:$count),
1281fe6060f1SDimitry Andric              (operator node:$val, (i64 (shiftMask32 node:$count)))>;
12820b57cec5SDimitry Andric
12830b57cec5SDimitry Andricdef : PatGprGpr<shiftop<shl>, SLL>;
12840b57cec5SDimitry Andricdef : PatGprGpr<shiftop<srl>, SRL>;
12850b57cec5SDimitry Andricdef : PatGprGpr<shiftop<sra>, SRA>;
12860b57cec5SDimitry Andric
12870b57cec5SDimitry Andric// This is a special case of the ADD instruction used to facilitate the use of a
12880b57cec5SDimitry Andric// fourth operand to emit a relocation on a symbol relating to this instruction.
12890b57cec5SDimitry Andric// The relocation does not affect any bits of the instruction itself but is used
12900b57cec5SDimitry Andric// as a hint to the linker.
12910b57cec5SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in
12920b57cec5SDimitry Andricdef PseudoAddTPRel : Pseudo<(outs GPR:$rd),
12930b57cec5SDimitry Andric                            (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [],
12940b57cec5SDimitry Andric                            "add", "$rd, $rs1, $rs2, $src">;
12950b57cec5SDimitry Andric
12960b57cec5SDimitry Andric/// FrameIndex calculations
12970b57cec5SDimitry Andric
129806c3fb27SDimitry Andricdef : Pat<(FrameAddrRegImm (iPTR GPR:$rs1), simm12:$imm12),
129981ad6265SDimitry Andric          (ADDI GPR:$rs1, simm12:$imm12)>;
130081ad6265SDimitry Andric
130181ad6265SDimitry Andric/// HI and ADD_LO address nodes.
130281ad6265SDimitry Andric
130381ad6265SDimitry Andricdef : Pat<(riscv_hi tglobaladdr:$in), (LUI tglobaladdr:$in)>;
130481ad6265SDimitry Andricdef : Pat<(riscv_hi tblockaddress:$in), (LUI tblockaddress:$in)>;
130581ad6265SDimitry Andricdef : Pat<(riscv_hi tjumptable:$in), (LUI tjumptable:$in)>;
130681ad6265SDimitry Andricdef : Pat<(riscv_hi tconstpool:$in), (LUI tconstpool:$in)>;
130781ad6265SDimitry Andric
130881ad6265SDimitry Andricdef : Pat<(riscv_add_lo GPR:$hi, tglobaladdr:$lo),
130981ad6265SDimitry Andric          (ADDI GPR:$hi, tglobaladdr:$lo)>;
131081ad6265SDimitry Andricdef : Pat<(riscv_add_lo GPR:$hi, tblockaddress:$lo),
131181ad6265SDimitry Andric          (ADDI GPR:$hi, tblockaddress:$lo)>;
131281ad6265SDimitry Andricdef : Pat<(riscv_add_lo GPR:$hi, tjumptable:$lo),
131381ad6265SDimitry Andric          (ADDI GPR:$hi, tjumptable:$lo)>;
131481ad6265SDimitry Andricdef : Pat<(riscv_add_lo GPR:$hi, tconstpool:$lo),
131581ad6265SDimitry Andric          (ADDI GPR:$hi, tconstpool:$lo)>;
131681ad6265SDimitry Andric
131781ad6265SDimitry Andric/// TLS address nodes.
131881ad6265SDimitry Andric
131981ad6265SDimitry Andricdef : Pat<(riscv_hi tglobaltlsaddr:$in), (LUI tglobaltlsaddr:$in)>;
132081ad6265SDimitry Andricdef : Pat<(riscv_add_tprel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src),
132181ad6265SDimitry Andric          (PseudoAddTPRel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src)>;
132281ad6265SDimitry Andricdef : Pat<(riscv_add_lo GPR:$src, tglobaltlsaddr:$lo),
132381ad6265SDimitry Andric          (ADDI GPR:$src, tglobaltlsaddr:$lo)>;
13240b57cec5SDimitry Andric
13250b57cec5SDimitry Andric/// Setcc
13260b57cec5SDimitry Andric
13270b57cec5SDimitry Andricdef : PatGprGpr<setlt, SLT>;
13280b57cec5SDimitry Andricdef : PatGprSimm12<setlt, SLTI>;
13290b57cec5SDimitry Andricdef : PatGprGpr<setult, SLTU>;
13300b57cec5SDimitry Andricdef : PatGprSimm12<setult, SLTIU>;
13310b57cec5SDimitry Andric
133206c3fb27SDimitry Andric// RISC-V doesn't have general instructions for integer setne/seteq, but we can
133306c3fb27SDimitry Andric// check for equality with 0. These ComplexPatterns rewrite the setne/seteq into
133406c3fb27SDimitry Andric// something that can be compared with 0.
133506c3fb27SDimitry Andric// These ComplexPatterns must be used in pairs.
133606c3fb27SDimitry Andricdef riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;
133706c3fb27SDimitry Andricdef riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;
133806c3fb27SDimitry Andric
13390b57cec5SDimitry Andric// Define pattern expansions for setcc operations that aren't directly
13400b57cec5SDimitry Andric// handled by a RISC-V instruction.
134106c3fb27SDimitry Andricdef : Pat<(riscv_seteq (XLenVT GPR:$rs1)), (SLTIU GPR:$rs1, 1)>;
134206c3fb27SDimitry Andricdef : Pat<(riscv_setne (XLenVT GPR:$rs1)), (SLTU (XLenVT X0), GPR:$rs1)>;
134306c3fb27SDimitry Andricdef : Pat<(XLenVT (setne (XLenVT GPR:$rs1), -1)), (SLTIU GPR:$rs1, -1)>;
1344fcaf7f86SDimitry Andric
1345349cc55cSDimitry Andricdef IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{
1346349cc55cSDimitry Andric  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
1347349cc55cSDimitry Andric  RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC);
1348349cc55cSDimitry Andric  return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT());
1349349cc55cSDimitry Andric}]>;
1350349cc55cSDimitry Andric
1351349cc55cSDimitry Andricdef riscv_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc,
1352349cc55cSDimitry Andric                                       node:$truev, node:$falsev),
1353349cc55cSDimitry Andric                                  (riscv_selectcc node:$lhs, node:$rhs,
1354349cc55cSDimitry Andric                                                  node:$cc, node:$truev,
1355349cc55cSDimitry Andric                                                  node:$falsev), [{}],
1356349cc55cSDimitry Andric                                  IntCCtoRISCVCC>;
1357349cc55cSDimitry Andric
1358bdd1243dSDimitry Andriclet Predicates = [HasShortForwardBranchOpt], isSelect = 1,
1359bdd1243dSDimitry Andric    Constraints = "$dst = $falsev", isCommutable = 1, Size = 8 in {
1360bdd1243dSDimitry Andric// This instruction moves $truev to $dst when the condition is true. It will
1361bdd1243dSDimitry Andric// be expanded to control flow in RISCVExpandPseudoInsts.
1362bdd1243dSDimitry Andricdef PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
1363bdd1243dSDimitry Andric                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1364bdd1243dSDimitry Andric                             GPR:$falsev, GPR:$truev),
1365bdd1243dSDimitry Andric                            [(set GPR:$dst,
136606c3fb27SDimitry Andric                              (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs),
136706c3fb27SDimitry Andric                                                       GPR:$rhs, cond,
136806c3fb27SDimitry Andric                                                       (XLenVT GPR:$truev),
1369bdd1243dSDimitry Andric                                                       GPR:$falsev))]>,
137006c3fb27SDimitry Andric                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
137106c3fb27SDimitry Andric                            ReadSFBALU, ReadSFBALU]>;
1372bdd1243dSDimitry Andric}
1373bdd1243dSDimitry Andric
13741db9f3b2SDimitry Andric// This should always expand to a branch+c.mv so the size is 6 or 4 if the
13751db9f3b2SDimitry Andric// branch is compressible.
13761db9f3b2SDimitry Andriclet Predicates = [HasConditionalMoveFusion, NoShortForwardBranchOpt],
13771db9f3b2SDimitry Andric    Constraints = "$dst = $falsev", isCommutable = 1, Size = 6 in {
13781db9f3b2SDimitry Andric// This instruction moves $truev to $dst when the condition is true. It will
13791db9f3b2SDimitry Andric// be expanded to control flow in RISCVExpandPseudoInsts.
13801db9f3b2SDimitry Andric// We use GPRNoX0 because c.mv cannot encode X0.
13811db9f3b2SDimitry Andricdef PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
13821db9f3b2SDimitry Andric                                (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
13831db9f3b2SDimitry Andric                                 GPRNoX0:$falsev, GPRNoX0:$truev),
13841db9f3b2SDimitry Andric                                [(set GPRNoX0:$dst,
13851db9f3b2SDimitry Andric                                  (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs),
13861db9f3b2SDimitry Andric                                                           (XLenVT GPR:$rhs),
13871db9f3b2SDimitry Andric                                                           cond, (XLenVT GPRNoX0:$truev),
13881db9f3b2SDimitry Andric                                                           (XLenVT GPRNoX0:$falsev)))]>,
13891db9f3b2SDimitry Andric                         Sched<[]>;
13901db9f3b2SDimitry Andric}
13911db9f3b2SDimitry Andric
1392bdd1243dSDimitry Andric// Conditional binops, that updates update $dst to (op rs1, rs2) when condition
1393bdd1243dSDimitry Andric// is true. Returns $falsev otherwise. Selected by optimizeSelect.
1394bdd1243dSDimitry Andric// TODO: Can we use DefaultOperands on the regular binop to accomplish this more
1395bdd1243dSDimitry Andric// like how ARM does predication?
1396bdd1243dSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8,
1397bdd1243dSDimitry Andric    Constraints = "$dst = $falsev" in {
1398bdd1243dSDimitry Andricdef PseudoCCADD : Pseudo<(outs GPR:$dst),
1399bdd1243dSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1400bdd1243dSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
140106c3fb27SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
140206c3fb27SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1403bdd1243dSDimitry Andricdef PseudoCCSUB : Pseudo<(outs GPR:$dst),
1404bdd1243dSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1405bdd1243dSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
140606c3fb27SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
140706c3fb27SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
14085f757f3fSDimitry Andricdef PseudoCCSLL : Pseudo<(outs GPR:$dst),
14095f757f3fSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14105f757f3fSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14115f757f3fSDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14125f757f3fSDimitry Andric                         ReadSFBALU, ReadSFBALU]>;
14135f757f3fSDimitry Andricdef PseudoCCSRL : Pseudo<(outs GPR:$dst),
14145f757f3fSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14155f757f3fSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14165f757f3fSDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14175f757f3fSDimitry Andric                         ReadSFBALU, ReadSFBALU]>;
14185f757f3fSDimitry Andricdef PseudoCCSRA : Pseudo<(outs GPR:$dst),
14195f757f3fSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14205f757f3fSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14215f757f3fSDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14225f757f3fSDimitry Andric                         ReadSFBALU, ReadSFBALU]>;
1423bdd1243dSDimitry Andricdef PseudoCCAND : Pseudo<(outs GPR:$dst),
1424bdd1243dSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1425bdd1243dSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
142606c3fb27SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
142706c3fb27SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1428bdd1243dSDimitry Andricdef PseudoCCOR  : Pseudo<(outs GPR:$dst),
1429bdd1243dSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1430bdd1243dSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
143106c3fb27SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
143206c3fb27SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1433bdd1243dSDimitry Andricdef PseudoCCXOR : Pseudo<(outs GPR:$dst),
1434bdd1243dSDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1435bdd1243dSDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
143606c3fb27SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
143706c3fb27SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1438bdd1243dSDimitry Andric
14395f757f3fSDimitry Andricdef PseudoCCADDI : Pseudo<(outs GPR:$dst),
14405f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14415f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14425f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14435f757f3fSDimitry Andric                          ReadSFBALU]>;
14445f757f3fSDimitry Andricdef PseudoCCSLLI : Pseudo<(outs GPR:$dst),
14455f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14465f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14475f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14485f757f3fSDimitry Andric                          ReadSFBALU]>;
14495f757f3fSDimitry Andricdef PseudoCCSRLI : Pseudo<(outs GPR:$dst),
14505f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14515f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14525f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14535f757f3fSDimitry Andric                          ReadSFBALU]>;
14545f757f3fSDimitry Andricdef PseudoCCSRAI : Pseudo<(outs GPR:$dst),
14555f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14565f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14575f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14585f757f3fSDimitry Andric                          ReadSFBALU]>;
14595f757f3fSDimitry Andricdef PseudoCCANDI : Pseudo<(outs GPR:$dst),
14605f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14615f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14625f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14635f757f3fSDimitry Andric                          ReadSFBALU]>;
14645f757f3fSDimitry Andricdef PseudoCCORI  : Pseudo<(outs GPR:$dst),
14655f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14665f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14675f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14685f757f3fSDimitry Andric                          ReadSFBALU]>;
14695f757f3fSDimitry Andricdef PseudoCCXORI : Pseudo<(outs GPR:$dst),
14705f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14715f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
14725f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14735f757f3fSDimitry Andric                          ReadSFBALU]>;
14745f757f3fSDimitry Andric
1475bdd1243dSDimitry Andric// RV64I instructions
1476bdd1243dSDimitry Andricdef PseudoCCADDW : Pseudo<(outs GPR:$dst),
1477bdd1243dSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1478bdd1243dSDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
147906c3fb27SDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
148006c3fb27SDimitry Andric                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1481bdd1243dSDimitry Andricdef PseudoCCSUBW : Pseudo<(outs GPR:$dst),
1482bdd1243dSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1483bdd1243dSDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
148406c3fb27SDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
148506c3fb27SDimitry Andric                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
14865f757f3fSDimitry Andricdef PseudoCCSLLW : Pseudo<(outs GPR:$dst),
14875f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14885f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14895f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14905f757f3fSDimitry Andric                          ReadSFBALU, ReadSFBALU]>;
14915f757f3fSDimitry Andricdef PseudoCCSRLW : Pseudo<(outs GPR:$dst),
14925f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14935f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14945f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
14955f757f3fSDimitry Andric                          ReadSFBALU, ReadSFBALU]>;
14965f757f3fSDimitry Andricdef PseudoCCSRAW : Pseudo<(outs GPR:$dst),
14975f757f3fSDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
14985f757f3fSDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
14995f757f3fSDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
15005f757f3fSDimitry Andric                          ReadSFBALU, ReadSFBALU]>;
15015f757f3fSDimitry Andric
15025f757f3fSDimitry Andricdef PseudoCCADDIW : Pseudo<(outs GPR:$dst),
15035f757f3fSDimitry Andric                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15045f757f3fSDimitry Andric                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
15055f757f3fSDimitry Andric                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
15065f757f3fSDimitry Andric                           ReadSFBALU]>;
15075f757f3fSDimitry Andricdef PseudoCCSLLIW : Pseudo<(outs GPR:$dst),
15085f757f3fSDimitry Andric                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15095f757f3fSDimitry Andric                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
15105f757f3fSDimitry Andric                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
15115f757f3fSDimitry Andric                           ReadSFBALU]>;
15125f757f3fSDimitry Andricdef PseudoCCSRLIW : Pseudo<(outs GPR:$dst),
15135f757f3fSDimitry Andric                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15145f757f3fSDimitry Andric                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
15155f757f3fSDimitry Andric                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
15165f757f3fSDimitry Andric                           ReadSFBALU]>;
15175f757f3fSDimitry Andricdef PseudoCCSRAIW : Pseudo<(outs GPR:$dst),
15185f757f3fSDimitry Andric                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15195f757f3fSDimitry Andric                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
15205f757f3fSDimitry Andric                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
15215f757f3fSDimitry Andric                           ReadSFBALU]>;
15221db9f3b2SDimitry Andric
15231db9f3b2SDimitry Andric// Zbb/Zbkb instructions
15241db9f3b2SDimitry Andricdef PseudoCCANDN : Pseudo<(outs GPR:$dst),
15251db9f3b2SDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15261db9f3b2SDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
15271db9f3b2SDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
15281db9f3b2SDimitry Andric                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
15291db9f3b2SDimitry Andricdef PseudoCCORN : Pseudo<(outs GPR:$dst),
15301db9f3b2SDimitry Andric                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15311db9f3b2SDimitry Andric                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
15321db9f3b2SDimitry Andric                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
15331db9f3b2SDimitry Andric                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
15341db9f3b2SDimitry Andricdef PseudoCCXNOR : Pseudo<(outs GPR:$dst),
15351db9f3b2SDimitry Andric                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15361db9f3b2SDimitry Andric                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
15371db9f3b2SDimitry Andric                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
15381db9f3b2SDimitry Andric                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1539bdd1243dSDimitry Andric}
1540bdd1243dSDimitry Andric
154106c3fb27SDimitry Andricmulticlass SelectCC_GPR_rrirr<DAGOperand valty, ValueType vt> {
15420b57cec5SDimitry Andric  let usesCustomInserter = 1 in
1543bdd1243dSDimitry Andric  def _Using_CC_GPR : Pseudo<(outs valty:$dst),
1544bdd1243dSDimitry Andric                             (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
15450b57cec5SDimitry Andric                              valty:$truev, valty:$falsev),
1546349cc55cSDimitry Andric                             [(set valty:$dst,
154706c3fb27SDimitry Andric                               (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), GPR:$rhs, cond,
154806c3fb27SDimitry Andric                                                        (vt valty:$truev), valty:$falsev))]>;
1549bdd1243dSDimitry Andric  // Explicitly select 0 in the condition to X0. The register coalescer doesn't
1550bdd1243dSDimitry Andric  // always do it.
155106c3fb27SDimitry Andric  def : Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 0, cond, (vt valty:$truev),
1552bdd1243dSDimitry Andric                                     valty:$falsev),
155306c3fb27SDimitry Andric            (!cast<Instruction>(NAME#"_Using_CC_GPR") GPR:$lhs, (XLenVT X0),
1554bdd1243dSDimitry Andric             (IntCCtoRISCVCC $cc), valty:$truev, valty:$falsev)>;
1555bdd1243dSDimitry Andric}
15560b57cec5SDimitry Andric
15571db9f3b2SDimitry Andriclet Predicates = [NoConditionalMoveFusion] in
155806c3fb27SDimitry Andricdefm Select_GPR : SelectCC_GPR_rrirr<GPR, XLenVT>;
1559bdd1243dSDimitry Andric
156006c3fb27SDimitry Andricclass SelectCompressOpt<CondCode Cond>
156106c3fb27SDimitry Andric    : Pat<(riscv_selectcc_frag:$select (XLenVT GPR:$lhs), simm12_no6:$Constant, Cond,
156206c3fb27SDimitry Andric                                       (XLenVT GPR:$truev), GPR:$falsev),
156306c3fb27SDimitry Andric    (Select_GPR_Using_CC_GPR (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0),
1564bdd1243dSDimitry Andric                          (IntCCtoRISCVCC $select), GPR:$truev, GPR:$falsev)>;
1565bdd1243dSDimitry Andric
1566bdd1243dSDimitry Andricdef OptForMinSize : Predicate<"MF ? MF->getFunction().hasMinSize() : false">;
1567bdd1243dSDimitry Andric
1568bdd1243dSDimitry Andriclet Predicates = [HasStdExtC, OptForMinSize] in {
1569bdd1243dSDimitry Andric  def : SelectCompressOpt<SETEQ>;
1570bdd1243dSDimitry Andric  def : SelectCompressOpt<SETNE>;
1571bdd1243dSDimitry Andric}
15720b57cec5SDimitry Andric
15730b57cec5SDimitry Andric/// Branches and jumps
15740b57cec5SDimitry Andric
1575fe6060f1SDimitry Andric// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
1576bdd1243dSDimitry Andricmulticlass BccPat<CondCode Cond, RVInstB Inst> {
157706c3fb27SDimitry Andric  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), GPR:$rs2, Cond, bb:$imm12),
15780b57cec5SDimitry Andric            (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>;
1579bdd1243dSDimitry Andric  // Explicitly select 0 to X0. The register coalescer doesn't always do it.
158006c3fb27SDimitry Andric  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), 0, Cond, bb:$imm12),
158106c3fb27SDimitry Andric            (Inst GPR:$rs1, (XLenVT X0), simm13_lsb0:$imm12)>;
1582bdd1243dSDimitry Andric}
15830b57cec5SDimitry Andric
158406c3fb27SDimitry Andricclass BrccCompressOpt<CondCode Cond, RVInstB Inst>
158506c3fb27SDimitry Andric    : Pat<(riscv_brcc GPR:$lhs, simm12_no6:$Constant, Cond, bb:$place),
158606c3fb27SDimitry Andric          (Inst (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0), bb:$place)>;
1587bdd1243dSDimitry Andric
1588bdd1243dSDimitry Andricdefm : BccPat<SETEQ, BEQ>;
1589bdd1243dSDimitry Andricdefm : BccPat<SETNE, BNE>;
1590bdd1243dSDimitry Andricdefm : BccPat<SETLT, BLT>;
1591bdd1243dSDimitry Andricdefm : BccPat<SETGE, BGE>;
1592bdd1243dSDimitry Andricdefm : BccPat<SETULT, BLTU>;
1593bdd1243dSDimitry Andricdefm : BccPat<SETUGE, BGEU>;
1594bdd1243dSDimitry Andric
1595bdd1243dSDimitry Andriclet Predicates = [HasStdExtC, OptForMinSize] in {
159606c3fb27SDimitry Andric  def : BrccCompressOpt<SETEQ, BEQ>;
159706c3fb27SDimitry Andric  def : BrccCompressOpt<SETNE, BNE>;
1598bdd1243dSDimitry Andric}
15990b57cec5SDimitry Andric
160006c3fb27SDimitry Andricclass LongBccPseudo : Pseudo<(outs),
160106c3fb27SDimitry Andric                             (ins GPR:$rs1, GPR:$rs2, simm21_lsb0_jal:$imm20),
160206c3fb27SDimitry Andric                             []> {
160306c3fb27SDimitry Andric  let Size = 8;
160406c3fb27SDimitry Andric  let isBarrier = 1;
160506c3fb27SDimitry Andric  let isBranch = 1;
160606c3fb27SDimitry Andric  let hasSideEffects = 0;
160706c3fb27SDimitry Andric  let mayStore = 0;
160806c3fb27SDimitry Andric  let mayLoad = 0;
160906c3fb27SDimitry Andric  let isAsmParserOnly = 1;
161006c3fb27SDimitry Andric  let hasNoSchedulingInfo = 1;
161106c3fb27SDimitry Andric}
161206c3fb27SDimitry Andric
161306c3fb27SDimitry Andricdef PseudoLongBEQ : LongBccPseudo;
161406c3fb27SDimitry Andricdef PseudoLongBNE : LongBccPseudo;
161506c3fb27SDimitry Andricdef PseudoLongBLT : LongBccPseudo;
161606c3fb27SDimitry Andricdef PseudoLongBGE : LongBccPseudo;
161706c3fb27SDimitry Andricdef PseudoLongBLTU : LongBccPseudo;
161806c3fb27SDimitry Andricdef PseudoLongBGEU : LongBccPseudo;
161906c3fb27SDimitry Andric
16200b57cec5SDimitry Andriclet isBarrier = 1, isBranch = 1, isTerminator = 1 in
16210b57cec5SDimitry Andricdef PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
16220b57cec5SDimitry Andric               PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andriclet isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1625fe6060f1SDimitry Andricdef PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
16260b57cec5SDimitry Andric                  PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
16270b57cec5SDimitry Andric
1628fe6060f1SDimitry Andricdef : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;
1629fe6060f1SDimitry Andricdef : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)),
1630fe6060f1SDimitry Andric          (PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>;
16310b57cec5SDimitry Andric
1632480093f4SDimitry Andric// PseudoCALLReg is a generic pseudo instruction for calls which will eventually
16330b57cec5SDimitry Andric// expand to auipc and jalr while encoding, with any given register used as the
16340b57cec5SDimitry Andric// destination.
16350b57cec5SDimitry Andric// Define AsmString to print "call" when compile with -S flag.
16360b57cec5SDimitry Andric// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
16371fd87a68SDimitry Andriclet isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,
16380b57cec5SDimitry Andric    mayStore = 0, mayLoad = 0 in
163906c3fb27SDimitry Andricdef PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), [],
164006c3fb27SDimitry Andric                           "call", "$rd, $func">,
164106c3fb27SDimitry Andric                    Sched<[WriteIALU, WriteJalr, ReadJalr]>;
16420b57cec5SDimitry Andric
16430b57cec5SDimitry Andric// PseudoCALL is a pseudo instruction which will eventually expand to auipc
16440b57cec5SDimitry Andric// and jalr while encoding. This is desirable, as an auipc+jalr pair with
16450b57cec5SDimitry Andric// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
16460b57cec5SDimitry Andric// if the offset fits in a signed 21-bit immediate.
16470b57cec5SDimitry Andric// Define AsmString to print "call" when compile with -S flag.
16480b57cec5SDimitry Andric// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
16491fd87a68SDimitry Andriclet isCall = 1, Defs = [X1], isCodeGenOnly = 0, Size = 8 in
165006c3fb27SDimitry Andricdef PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), [],
165106c3fb27SDimitry Andric                        "call", "$func">,
165206c3fb27SDimitry Andric                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
16530b57cec5SDimitry Andric
16540b57cec5SDimitry Andricdef : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
16550b57cec5SDimitry Andricdef : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
16560b57cec5SDimitry Andric
165706c3fb27SDimitry Andricdef : Pat<(riscv_sret_glue), (SRET (XLenVT X0), (XLenVT X0))>;
165806c3fb27SDimitry Andricdef : Pat<(riscv_mret_glue), (MRET (XLenVT X0), (XLenVT X0))>;
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andriclet isCall = 1, Defs = [X1] in
1661fe6060f1SDimitry Andricdef PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
1662fe6060f1SDimitry Andric                                [(riscv_call GPRJALR:$rs1)]>,
16630b57cec5SDimitry Andric                         PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
16640b57cec5SDimitry Andric
16650b57cec5SDimitry Andriclet isBarrier = 1, isReturn = 1, isTerminator = 1 in
166606c3fb27SDimitry Andricdef PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>,
16670b57cec5SDimitry Andric                PseudoInstExpansion<(JALR X0, X1, 0)>;
16680b57cec5SDimitry Andric
16690b57cec5SDimitry Andric// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
16700b57cec5SDimitry Andric// expand to auipc and jalr while encoding.
16710b57cec5SDimitry Andric// Define AsmString to print "tail" when compile with -S flag.
16720b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
16731fd87a68SDimitry Andric    Size = 8, isCodeGenOnly = 0 in
167406c3fb27SDimitry Andricdef PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), [],
167506c3fb27SDimitry Andric                        "tail", "$dst">,
167606c3fb27SDimitry Andric                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andriclet isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
16790b57cec5SDimitry Andricdef PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
16800b57cec5SDimitry Andric                                [(riscv_tail GPRTC:$rs1)]>,
16810b57cec5SDimitry Andric                         PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
16820b57cec5SDimitry Andric
16830b57cec5SDimitry Andricdef : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
168481ad6265SDimitry Andric          (PseudoTAIL tglobaladdr:$dst)>;
16850b57cec5SDimitry Andricdef : Pat<(riscv_tail (iPTR texternalsym:$dst)),
16860b57cec5SDimitry Andric          (PseudoTAIL texternalsym:$dst)>;
16870b57cec5SDimitry Andric
16881fd87a68SDimitry Andriclet isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1, Size = 8,
168975b4d546SDimitry Andric    isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
169006c3fb27SDimitry Andricdef PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), [],
169106c3fb27SDimitry Andric                        "jump", "$target, $rd">,
169206c3fb27SDimitry Andric                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
16935ffd83dbSDimitry Andric
16945f757f3fSDimitry Andric// Pseudo for a rematerializable constant materialization sequence.
16955f757f3fSDimitry Andric// This is an experimental feature enabled by
16965f757f3fSDimitry Andric// -riscv-use-rematerializable-movimm in RISCVISelDAGToDAG.cpp
16975f757f3fSDimitry Andric// It will be expanded after register allocation.
16985f757f3fSDimitry Andric// FIXME: The scheduling information does not reflect the multiple instructions.
16995f757f3fSDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 1,
17005f757f3fSDimitry Andric    isPseudo = 1, isReMaterializable = 1, IsSignExtendingOpW = 1 in
17015f757f3fSDimitry Andricdef PseudoMovImm : Pseudo<(outs GPR:$dst), (ins i32imm:$imm), []>,
17025f757f3fSDimitry Andric                   Sched<[WriteIALU]>;
17035f757f3fSDimitry Andric
17041fd87a68SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
17050b57cec5SDimitry Andric    isAsmParserOnly = 1 in
17060b57cec5SDimitry Andricdef PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
17070b57cec5SDimitry Andric                       "lla", "$dst, $src">;
17080b57cec5SDimitry Andric
170906c3fb27SDimitry Andric// Refer to comment on PseudoLI for explanation of Size=32
171006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
171106c3fb27SDimitry Andric    isAsmParserOnly = 1 in
171206c3fb27SDimitry Andricdef PseudoLLAImm : Pseudo<(outs GPR:$dst), (ins ixlenimm_li_restricted:$imm), [],
171306c3fb27SDimitry Andric                          "lla", "$dst, $imm">;
171481ad6265SDimitry Andricdef : Pat<(riscv_lla tglobaladdr:$in), (PseudoLLA tglobaladdr:$in)>;
171581ad6265SDimitry Andricdef : Pat<(riscv_lla tblockaddress:$in), (PseudoLLA tblockaddress:$in)>;
171681ad6265SDimitry Andricdef : Pat<(riscv_lla tjumptable:$in), (PseudoLLA tjumptable:$in)>;
171781ad6265SDimitry Andricdef : Pat<(riscv_lla tconstpool:$in), (PseudoLLA tconstpool:$in)>;
171881ad6265SDimitry Andric
17191fd87a68SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
17200b57cec5SDimitry Andric    isAsmParserOnly = 1 in
172106c3fb27SDimitry Andricdef PseudoLGA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
172206c3fb27SDimitry Andric                       "lga", "$dst, $src">;
172306c3fb27SDimitry Andric
172406c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
172506c3fb27SDimitry Andric    isAsmParserOnly = 1 in
17260b57cec5SDimitry Andricdef PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
17270b57cec5SDimitry Andric                      "la", "$dst, $src">;
17280b57cec5SDimitry Andric
172906c3fb27SDimitry Andric// Refer to comment on PseudoLI for explanation of Size=32
173006c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
173106c3fb27SDimitry Andric    isCodeGenOnly = 0, isAsmParserOnly = 1 in
173206c3fb27SDimitry Andricdef PseudoLAImm : Pseudo<(outs GPR:$rd), (ins ixlenimm_li_restricted:$imm), [],
173306c3fb27SDimitry Andric                         "la", "$rd, $imm">;
173481ad6265SDimitry Andric
17351fd87a68SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
17360b57cec5SDimitry Andric    isAsmParserOnly = 1 in
17370b57cec5SDimitry Andricdef PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
17380b57cec5SDimitry Andric                             "la.tls.ie", "$dst, $src">;
17390b57cec5SDimitry Andric
174081ad6265SDimitry Andriclet hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
17410b57cec5SDimitry Andric    isAsmParserOnly = 1 in
17420b57cec5SDimitry Andricdef PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
17430b57cec5SDimitry Andric                             "la.tls.gd", "$dst, $src">;
17440b57cec5SDimitry Andric
17457a6dacacSDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0 in
17467a6dacacSDimitry Andricdef PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
17477a6dacacSDimitry Andric                             "la.tlsdesc", "$dst, $src">;
17487a6dacacSDimitry Andric
17497a6dacacSDimitry Andricdef TLSDESCCallSymbol : AsmOperandClass {
17507a6dacacSDimitry Andric  let Name = "TLSDESCCallSymbol";
17517a6dacacSDimitry Andric  let RenderMethod = "addImmOperands";
17527a6dacacSDimitry Andric  let DiagnosticType = "InvalidTLSDESCCallSymbol";
17537a6dacacSDimitry Andric  let ParserMethod = "parseOperandWithModifier";
17547a6dacacSDimitry Andric}
17557a6dacacSDimitry Andric
17567a6dacacSDimitry Andric// A bare symbol with the %tlsdesc_call variant.
17577a6dacacSDimitry Andricdef tlsdesc_call_symbol : Operand<XLenVT> {
17587a6dacacSDimitry Andric  let ParserMatchClass = TLSDESCCallSymbol;
17597a6dacacSDimitry Andric}
17607a6dacacSDimitry Andric// This is a special case of the JALR instruction used to facilitate the use of a
17617a6dacacSDimitry Andric// fourth operand to emit a relocation on a symbol relating to this instruction.
17627a6dacacSDimitry Andric// The relocation does not affect any bits of the instruction itself but is used
17637a6dacacSDimitry Andric// as a hint to the linker.
17647a6dacacSDimitry Andriclet isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,
17657a6dacacSDimitry Andric    mayStore = 0, mayLoad = 0 in
17667a6dacacSDimitry Andricdef PseudoTLSDESCCall : Pseudo<(outs GPR:$rd),
17677a6dacacSDimitry Andric                         (ins GPR:$rs1, simm12:$imm12, tlsdesc_call_symbol:$src), [],
17687a6dacacSDimitry Andric                         "jalr", "$rd, ${imm12}(${rs1}), $src">,
17697a6dacacSDimitry Andric                         Sched<[WriteJalr, ReadJalr]> {
17707a6dacacSDimitry Andric  let Defs = [X10];
17717a6dacacSDimitry Andric  let Uses = [X10];
17727a6dacacSDimitry Andric}
17737a6dacacSDimitry Andric
1774e8d8bef9SDimitry Andric
1775e8d8bef9SDimitry Andric/// Sign/Zero Extends
1776e8d8bef9SDimitry Andric
1777e8d8bef9SDimitry Andric// There are single-instruction versions of these in Zbb, so disable these
1778e8d8bef9SDimitry Andric// Pseudos if that extension is present.
1779e8d8bef9SDimitry Andriclet hasSideEffects = 0, mayLoad = 0,
1780e8d8bef9SDimitry Andric    mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1781e8d8bef9SDimitry Andricdef PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">;
1782e8d8bef9SDimitry Andricdef PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">;
1783e8d8bef9SDimitry Andric// rv64's sext.w is defined above, using InstAlias<"sext.w ...
1784e8d8bef9SDimitry Andric// zext.b is defined above, using InstAlias<"zext.b ...
1785e8d8bef9SDimitry Andricdef PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">;
1786e8d8bef9SDimitry Andric} // hasSideEffects = 0, ...
1787e8d8bef9SDimitry Andric
1788e8d8bef9SDimitry Andriclet Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
1789e8d8bef9SDimitry Andric  isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1790e8d8bef9SDimitry Andricdef PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">;
1791e8d8bef9SDimitry Andric} // Predicates = [IsRV64], ...
1792e8d8bef9SDimitry Andric
17930b57cec5SDimitry Andric/// Loads
17940b57cec5SDimitry Andric
179506c3fb27SDimitry Andricclass LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT>
179606c3fb27SDimitry Andric    : Pat<(vt (LoadOp (AddrRegImm (XLenVT GPR:$rs1), simm12:$imm12))),
179781ad6265SDimitry Andric          (Inst GPR:$rs1, simm12:$imm12)>;
17980b57cec5SDimitry Andric
179906c3fb27SDimitry Andricdef : LdPat<sextloadi8, LB>;
180006c3fb27SDimitry Andricdef : LdPat<extloadi8, LBU>; // Prefer unsigned due to no c.lb in Zcb.
180106c3fb27SDimitry Andricdef : LdPat<sextloadi16, LH>;
180206c3fb27SDimitry Andricdef : LdPat<extloadi16, LH>;
18035f757f3fSDimitry Andricdef : LdPat<load, LW, i32>;
180406c3fb27SDimitry Andricdef : LdPat<zextloadi8, LBU>;
180506c3fb27SDimitry Andricdef : LdPat<zextloadi16, LHU>;
18060b57cec5SDimitry Andric
18070b57cec5SDimitry Andric/// Stores
18080b57cec5SDimitry Andric
180906c3fb27SDimitry Andricclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
181006c3fb27SDimitry Andric            ValueType vt>
181106c3fb27SDimitry Andric    : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm (XLenVT GPR:$rs1),
181206c3fb27SDimitry Andric                   simm12:$imm12)),
181381ad6265SDimitry Andric          (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
18140b57cec5SDimitry Andric
181506c3fb27SDimitry Andricdef : StPat<truncstorei8, SB, GPR, XLenVT>;
181606c3fb27SDimitry Andricdef : StPat<truncstorei16, SH, GPR, XLenVT>;
18175f757f3fSDimitry Andricdef : StPat<store, SW, GPR, i32>;
18180b57cec5SDimitry Andric
18190b57cec5SDimitry Andric/// Fences
18200b57cec5SDimitry Andric
18210b57cec5SDimitry Andric// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
18220b57cec5SDimitry Andric// Manual: Volume I.
18230b57cec5SDimitry Andric
18240b57cec5SDimitry Andric// fence acquire -> fence r, rw
1825480093f4SDimitry Andricdef : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>;
18260b57cec5SDimitry Andric// fence release -> fence rw, w
1827480093f4SDimitry Andricdef : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>;
18280b57cec5SDimitry Andric// fence acq_rel -> fence.tso
1829480093f4SDimitry Andricdef : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>;
18300b57cec5SDimitry Andric// fence seq_cst -> fence rw, rw
1831480093f4SDimitry Andricdef : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>;
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andric// Lowering for atomic load and store is defined in RISCVInstrInfoA.td.
18340b57cec5SDimitry Andric// Although these are lowered to fence+load/store instructions defined in the
18350b57cec5SDimitry Andric// base RV32I/RV64I ISA, this lowering is only used when the A extension is
18360b57cec5SDimitry Andric// present. This is necessary as it isn't valid to mix __atomic_* libcalls
18370b57cec5SDimitry Andric// with inline atomic operations for the same object.
18380b57cec5SDimitry Andric
1839fe6060f1SDimitry Andric/// Access to system registers
1840fe6060f1SDimitry Andric
1841fe6060f1SDimitry Andric// Helpers for defining specific operations. They are defined for each system
1842fe6060f1SDimitry Andric// register separately. Side effect is not used because dependencies are
1843fe6060f1SDimitry Andric// expressed via use-def properties.
1844fe6060f1SDimitry Andric
1845fe6060f1SDimitry Andricclass ReadSysReg<SysReg SR, list<Register> Regs>
1846fe6060f1SDimitry Andric  : Pseudo<(outs GPR:$rd), (ins),
184706c3fb27SDimitry Andric           [(set GPR:$rd, (XLenVT (riscv_read_csr (XLenVT SR.Encoding))))]>,
1848fe6060f1SDimitry Andric    PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> {
1849fe6060f1SDimitry Andric  let hasSideEffects = 0;
1850fe6060f1SDimitry Andric  let Uses = Regs;
1851fe6060f1SDimitry Andric}
1852fe6060f1SDimitry Andric
1853fe6060f1SDimitry Andricclass WriteSysReg<SysReg SR, list<Register> Regs>
1854fe6060f1SDimitry Andric  : Pseudo<(outs), (ins GPR:$val),
185506c3fb27SDimitry Andric           [(riscv_write_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>,
1856fe6060f1SDimitry Andric    PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> {
1857fe6060f1SDimitry Andric  let hasSideEffects = 0;
1858fe6060f1SDimitry Andric  let Defs = Regs;
1859fe6060f1SDimitry Andric}
1860fe6060f1SDimitry Andric
1861fe6060f1SDimitry Andricclass WriteSysRegImm<SysReg SR, list<Register> Regs>
1862fe6060f1SDimitry Andric  : Pseudo<(outs), (ins uimm5:$val),
1863fe6060f1SDimitry Andric           [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>,
1864fe6060f1SDimitry Andric    PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> {
1865fe6060f1SDimitry Andric  let hasSideEffects = 0;
1866fe6060f1SDimitry Andric  let Defs = Regs;
1867fe6060f1SDimitry Andric}
1868fe6060f1SDimitry Andric
1869fe6060f1SDimitry Andricclass SwapSysReg<SysReg SR, list<Register> Regs>
1870fe6060f1SDimitry Andric  : Pseudo<(outs GPR:$rd), (ins GPR:$val),
187106c3fb27SDimitry Andric           [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), (XLenVT GPR:$val)))]>,
1872fe6060f1SDimitry Andric    PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> {
1873fe6060f1SDimitry Andric  let hasSideEffects = 0;
1874fe6060f1SDimitry Andric  let Uses = Regs;
1875fe6060f1SDimitry Andric  let Defs = Regs;
1876fe6060f1SDimitry Andric}
1877fe6060f1SDimitry Andric
1878fe6060f1SDimitry Andricclass SwapSysRegImm<SysReg SR, list<Register> Regs>
1879fe6060f1SDimitry Andric  : Pseudo<(outs GPR:$rd), (ins uimm5:$val),
188006c3fb27SDimitry Andric           [(set GPR:$rd, (XLenVT (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val)))]>,
1881fe6060f1SDimitry Andric    PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> {
1882fe6060f1SDimitry Andric  let hasSideEffects = 0;
1883fe6060f1SDimitry Andric  let Uses = Regs;
1884fe6060f1SDimitry Andric  let Defs = Regs;
1885fe6060f1SDimitry Andric}
1886fe6060f1SDimitry Andric
1887fe6060f1SDimitry Andricdef ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;
1888fe6060f1SDimitry Andricdef WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;
1889fe6060f1SDimitry Andricdef WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;
1890bdd1243dSDimitry Andricdef SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>;
1891fe6060f1SDimitry Andric
189206c3fb27SDimitry Andricdef WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>;
189306c3fb27SDimitry Andric
189404eeddc0SDimitry Andriclet hasSideEffects = true in {
189504eeddc0SDimitry Andricdef ReadFFLAGS : ReadSysReg<SysRegFFLAGS, [FFLAGS]>;
189604eeddc0SDimitry Andricdef WriteFFLAGS : WriteSysReg<SysRegFFLAGS, [FFLAGS]>;
189704eeddc0SDimitry Andric}
18980b57cec5SDimitry Andric/// Other pseudo-instructions
18990b57cec5SDimitry Andric
19000b57cec5SDimitry Andric// Pessimistically assume the stack pointer will be clobbered
19010b57cec5SDimitry Andriclet Defs = [X2], Uses = [X2] in {
19020b57cec5SDimitry Andricdef ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
19030b57cec5SDimitry Andric                              [(callseq_start timm:$amt1, timm:$amt2)]>;
19040b57cec5SDimitry Andricdef ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
19050b57cec5SDimitry Andric                              [(callseq_end timm:$amt1, timm:$amt2)]>;
19060b57cec5SDimitry Andric} // Defs = [X2], Uses = [X2]
19070b57cec5SDimitry Andric
19080b57cec5SDimitry Andric/// RV64 patterns
19090b57cec5SDimitry Andric
1910e8d8bef9SDimitry Andriclet Predicates = [IsRV64, NotHasStdExtZba] in {
1911fe6060f1SDimitry Andricdef : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (SLLI GPR:$rs1, 32), 32)>;
1912e8d8bef9SDimitry Andric
1913e8d8bef9SDimitry Andric// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2
1914e8d8bef9SDimitry Andric// shifts instead of 3. This can occur when unsigned is used to index an array.
1915fe6060f1SDimitry Andricdef : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1916e8d8bef9SDimitry Andric          (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>;
1917e8d8bef9SDimitry Andric}
1918e8d8bef9SDimitry Andric
19195f757f3fSDimitry Andricclass binop_allhusers<SDPatternOperator operator>
19205f757f3fSDimitry Andric    : PatFrag<(ops node:$lhs, node:$rhs),
19215f757f3fSDimitry Andric              (XLenVT (operator node:$lhs, node:$rhs)), [{
19225f757f3fSDimitry Andric  return hasAllHUsers(Node);
19235f757f3fSDimitry Andric}]>;
19245f757f3fSDimitry Andric
1925349cc55cSDimitry Andric// PatFrag to allow ADDW/SUBW/MULW/SLLW to be selected from i64 add/sub/mul/shl
1926349cc55cSDimitry Andric// if only the lower 32 bits of their result is used.
1927349cc55cSDimitry Andricclass binop_allwusers<SDPatternOperator operator>
1928349cc55cSDimitry Andric    : PatFrag<(ops node:$lhs, node:$rhs),
192981ad6265SDimitry Andric              (i64 (operator node:$lhs, node:$rhs)), [{
1930349cc55cSDimitry Andric  return hasAllWUsers(Node);
1931349cc55cSDimitry Andric}]>;
1932349cc55cSDimitry Andric
1933349cc55cSDimitry Andricdef sexti32_allwusers : PatFrag<(ops node:$src),
1934349cc55cSDimitry Andric                                (sext_inreg node:$src, i32), [{
1935349cc55cSDimitry Andric  return hasAllWUsers(Node);
1936349cc55cSDimitry Andric}]>;
1937349cc55cSDimitry Andric
1938bdd1243dSDimitry Andricdef ImmSExt32 : SDNodeXForm<imm, [{
1939bdd1243dSDimitry Andric  return CurDAG->getTargetConstant(SignExtend64<32>(N->getSExtValue()),
1940bdd1243dSDimitry Andric                                   SDLoc(N), N->getValueType(0));
1941bdd1243dSDimitry Andric}]>;
1942bdd1243dSDimitry Andric// Look for constants where the upper 32 bits are 0, but sign extending bit 31
1943bdd1243dSDimitry Andric// would be an simm12.
1944bdd1243dSDimitry Andricdef u32simm12 : ImmLeaf<XLenVT, [{
1945bdd1243dSDimitry Andric  return isUInt<32>(Imm) && isInt<12>(SignExtend64<32>(Imm));
1946bdd1243dSDimitry Andric}], ImmSExt32>;
1947bdd1243dSDimitry Andric
19480b57cec5SDimitry Andriclet Predicates = [IsRV64] in {
19490b57cec5SDimitry Andric
1950bdd1243dSDimitry Andricdef : Pat<(i64 (and GPR:$rs, LeadingOnesWMask:$mask)),
1951bdd1243dSDimitry Andric          (SLLI (SRLIW $rs, LeadingOnesWMask:$mask), LeadingOnesWMask:$mask)>;
1952bdd1243dSDimitry Andric
19530b57cec5SDimitry Andric/// sext and zext
19540b57cec5SDimitry Andric
1955349cc55cSDimitry Andric// Sign extend is not needed if all users are W instructions.
1956349cc55cSDimitry Andricdef : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>;
1957349cc55cSDimitry Andric
19580b57cec5SDimitry Andricdef : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric/// ALU operations
19610b57cec5SDimitry Andric
1962fe6060f1SDimitry Andricdef : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1963e8d8bef9SDimitry Andric          (SRLIW GPR:$rs1, uimm5:$shamt)>;
1964fe6060f1SDimitry Andricdef : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1965e8d8bef9SDimitry Andric          (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
19660b57cec5SDimitry Andricdef : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
19670b57cec5SDimitry Andric          (SRAIW GPR:$rs1, uimm5:$shamt)>;
1968fe6060f1SDimitry Andricdef : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1969e8d8bef9SDimitry Andric          (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
19700b57cec5SDimitry Andric
1971e8d8bef9SDimitry Andricdef : PatGprGpr<shiftopw<riscv_sllw>, SLLW>;
1972e8d8bef9SDimitry Andricdef : PatGprGpr<shiftopw<riscv_srlw>, SRLW>;
1973e8d8bef9SDimitry Andricdef : PatGprGpr<shiftopw<riscv_sraw>, SRAW>;
19740b57cec5SDimitry Andric
1975349cc55cSDimitry Andric// Select W instructions if only the lower 32 bits of the result are used.
1976349cc55cSDimitry Andricdef : PatGprGpr<binop_allwusers<add>, ADDW>;
1977349cc55cSDimitry Andricdef : PatGprSimm12<binop_allwusers<add>, ADDIW>;
1978349cc55cSDimitry Andricdef : PatGprGpr<binop_allwusers<sub>, SUBW>;
1979349cc55cSDimitry Andricdef : PatGprImm<binop_allwusers<shl>, SLLIW, uimm5>;
1980349cc55cSDimitry Andric
1981349cc55cSDimitry Andric// If this is a shr of a value sign extended from i32, and all the users only
1982349cc55cSDimitry Andric// use the lower 32 bits, we can use an sraiw to remove the sext_inreg. This
1983349cc55cSDimitry Andric// occurs because SimplifyDemandedBits prefers srl over sra.
1984349cc55cSDimitry Andricdef : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
1985349cc55cSDimitry Andric          (SRAIW GPR:$rs1, uimm5:$shamt)>;
1986349cc55cSDimitry Andric
1987bdd1243dSDimitry Andric// Use binop_allwusers to recover immediates that may have been broken by
1988bdd1243dSDimitry Andric// SimplifyDemandedBits.
1989bdd1243dSDimitry Andricdef : Pat<(binop_allwusers<and> GPR:$rs1, u32simm12:$imm),
1990bdd1243dSDimitry Andric          (ANDI GPR:$rs1, u32simm12:$imm)>;
1991bdd1243dSDimitry Andric
1992bdd1243dSDimitry Andricdef : Pat<(binop_allwusers<or> GPR:$rs1, u32simm12:$imm),
1993bdd1243dSDimitry Andric          (ORI GPR:$rs1, u32simm12:$imm)>;
1994bdd1243dSDimitry Andric
1995bdd1243dSDimitry Andricdef : Pat<(binop_allwusers<xor> GPR:$rs1, u32simm12:$imm),
1996bdd1243dSDimitry Andric          (XORI GPR:$rs1, u32simm12:$imm)>;
19970b57cec5SDimitry Andric/// Loads
19980b57cec5SDimitry Andric
199906c3fb27SDimitry Andricdef : LdPat<sextloadi32, LW, i64>;
200006c3fb27SDimitry Andricdef : LdPat<extloadi32, LW, i64>;
200106c3fb27SDimitry Andricdef : LdPat<zextloadi32, LWU, i64>;
200206c3fb27SDimitry Andricdef : LdPat<load, LD, i64>;
20030b57cec5SDimitry Andric
20040b57cec5SDimitry Andric/// Stores
20050b57cec5SDimitry Andric
200606c3fb27SDimitry Andricdef : StPat<truncstorei32, SW, GPR, i64>;
200706c3fb27SDimitry Andricdef : StPat<store, SD, GPR, i64>;
20080b57cec5SDimitry Andric} // Predicates = [IsRV64]
20090b57cec5SDimitry Andric
20100b57cec5SDimitry Andric/// readcyclecounter
20110b57cec5SDimitry Andric// On RV64, we can directly read the 64-bit "cycle" CSR.
20120b57cec5SDimitry Andriclet Predicates = [IsRV64] in
201306c3fb27SDimitry Andricdef : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, (XLenVT X0))>;
20140b57cec5SDimitry Andric// On RV32, ReadCycleWide will be expanded to the suggested loop reading both
20150b57cec5SDimitry Andric// halves of the 64-bit "cycle" CSR.
2016e8d8bef9SDimitry Andriclet Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in
2017e8d8bef9SDimitry Andricdef ReadCycleWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins),
2018e8d8bef9SDimitry Andric                           [(set GPR:$lo, GPR:$hi, (riscv_read_cycle_wide))],
2019e8d8bef9SDimitry Andric                           "", "">;
20200b57cec5SDimitry Andric
2021480093f4SDimitry Andric/// traps
2022480093f4SDimitry Andric
2023480093f4SDimitry Andric// We lower `trap` to `unimp`, as this causes a hard exception on nearly all
2024480093f4SDimitry Andric// systems.
2025480093f4SDimitry Andricdef : Pat<(trap), (UNIMP)>;
2026480093f4SDimitry Andric
2027480093f4SDimitry Andric// We lower `debugtrap` to `ebreak`, as this will get the attention of the
2028480093f4SDimitry Andric// debugger if possible.
2029480093f4SDimitry Andricdef : Pat<(debugtrap), (EBREAK)>;
2030480093f4SDimitry Andric
2031bdd1243dSDimitry Andriclet Predicates = [IsRV64], Uses = [X5],
2032bdd1243dSDimitry Andric    Defs = [X1, X6, X7, X28, X29, X30, X31] in
2033bdd1243dSDimitry Andricdef HWASAN_CHECK_MEMACCESS_SHORTGRANULES
2034bdd1243dSDimitry Andric  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$accessinfo),
20355f757f3fSDimitry Andric           [(int_hwasan_check_memaccess_shortgranules (i64 X5), GPRJALR:$ptr,
2036bdd1243dSDimitry Andric                                                      (i32 timm:$accessinfo))]>;
2037bdd1243dSDimitry Andric
203806c3fb27SDimitry Andric// This gets lowered into a 20-byte instruction sequence (at most)
203906c3fb27SDimitry Andriclet hasSideEffects = 0, mayLoad = 1, mayStore = 0,
204006c3fb27SDimitry Andric    Defs = [ X6, X7, X28, X29, X30, X31 ], Size = 20 in {
204106c3fb27SDimitry Andricdef KCFI_CHECK
204206c3fb27SDimitry Andric  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$type), []>, Sched<[]>;
204306c3fb27SDimitry Andric}
204406c3fb27SDimitry Andric
2045fe6060f1SDimitry Andric/// Simple optimization
204606c3fb27SDimitry Andricdef : Pat<(XLenVT (add GPR:$rs1, (AddiPair:$rs2))),
204781ad6265SDimitry Andric          (ADDI (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
204881ad6265SDimitry Andric                (AddiPairImmSmall GPR:$rs2))>;
2049fe6060f1SDimitry Andric
2050fe6060f1SDimitry Andriclet Predicates = [IsRV64] in {
2051349cc55cSDimitry Andric// Select W instructions if only the lower 32-bits of the result are used.
2052349cc55cSDimitry Andricdef : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
205381ad6265SDimitry Andric          (ADDIW (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
205481ad6265SDimitry Andric                 (AddiPairImmSmall AddiPair:$rs2))>;
2055fe6060f1SDimitry Andric}
2056fe6060f1SDimitry Andric
20575f757f3fSDimitry Andriclet Predicates = [HasShortForwardBranchOpt] in
20585f757f3fSDimitry Andricdef : Pat<(XLenVT (abs GPR:$rs1)),
20595f757f3fSDimitry Andric          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2,
20605f757f3fSDimitry Andric           (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>;
20615f757f3fSDimitry Andriclet Predicates = [HasShortForwardBranchOpt, IsRV64] in
20625f757f3fSDimitry Andricdef : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
20635f757f3fSDimitry Andric          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2,
20645f757f3fSDimitry Andric           (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>;
20655f757f3fSDimitry Andric
20665f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
20675f757f3fSDimitry Andric// Experimental RV64 i32 legalization patterns.
20685f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
20695f757f3fSDimitry Andric
20705f757f3fSDimitry Andricdef simm12i32 : ImmLeaf<i32, [{return isInt<12>(Imm);}]>;
20715f757f3fSDimitry Andric
20725f757f3fSDimitry Andric// Convert from i32 immediate to i64 target immediate to make SelectionDAG type
20735f757f3fSDimitry Andric// checking happy so we can use ADDIW which expects an XLen immediate.
20745f757f3fSDimitry Andricdef as_i64imm : SDNodeXForm<imm, [{
20755f757f3fSDimitry Andric  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
20765f757f3fSDimitry Andric}]>;
20775f757f3fSDimitry Andric
20785f757f3fSDimitry Andricdef zext_is_sext : PatFrag<(ops node:$src), (zext node:$src), [{
20795f757f3fSDimitry Andric  KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0), 0);
20805f757f3fSDimitry Andric  return Known.isNonNegative();
20815f757f3fSDimitry Andric}]>;
20825f757f3fSDimitry Andric
20835f757f3fSDimitry Andriclet Predicates = [IsRV64] in {
20845f757f3fSDimitry Andricdef : LdPat<sextloadi8, LB, i32>;
20855f757f3fSDimitry Andricdef : LdPat<extloadi8, LBU, i32>; // Prefer unsigned due to no c.lb in Zcb.
20865f757f3fSDimitry Andricdef : LdPat<sextloadi16, LH, i32>;
20875f757f3fSDimitry Andricdef : LdPat<extloadi16, LH, i32>;
20885f757f3fSDimitry Andricdef : LdPat<zextloadi8, LBU, i32>;
20895f757f3fSDimitry Andricdef : LdPat<zextloadi16, LHU, i32>;
20905f757f3fSDimitry Andric
20915f757f3fSDimitry Andricdef : StPat<truncstorei8, SB, GPR, i32>;
20925f757f3fSDimitry Andricdef : StPat<truncstorei16, SH, GPR, i32>;
20935f757f3fSDimitry Andric
20945f757f3fSDimitry Andricdef : Pat<(anyext GPR:$src), (COPY GPR:$src)>;
20955f757f3fSDimitry Andricdef : Pat<(sext GPR:$src), (ADDIW GPR:$src, 0)>;
20965f757f3fSDimitry Andricdef : Pat<(trunc GPR:$src), (COPY GPR:$src)>;
20975f757f3fSDimitry Andric
20985f757f3fSDimitry Andricdef : PatGprGpr<add, ADDW, i32, i32>;
20995f757f3fSDimitry Andricdef : PatGprGpr<sub, SUBW, i32, i32>;
21005f757f3fSDimitry Andricdef : PatGprGpr<and, AND, i32, i32>;
21015f757f3fSDimitry Andricdef : PatGprGpr<or, OR, i32, i32>;
21025f757f3fSDimitry Andricdef : PatGprGpr<xor, XOR, i32, i32>;
21035f757f3fSDimitry Andricdef : PatGprGpr<shiftopw<shl>, SLLW, i32, i64>;
21045f757f3fSDimitry Andricdef : PatGprGpr<shiftopw<srl>, SRLW, i32, i64>;
21055f757f3fSDimitry Andricdef : PatGprGpr<shiftopw<sra>, SRAW, i32, i64>;
21065f757f3fSDimitry Andric
21075f757f3fSDimitry Andricdef : Pat<(i32 (add GPR:$rs1, simm12i32:$imm)),
21085f757f3fSDimitry Andric          (ADDIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
21095f757f3fSDimitry Andricdef : Pat<(i32 (and GPR:$rs1, simm12i32:$imm)),
21105f757f3fSDimitry Andric          (ANDI GPR:$rs1, (i64 (as_i64imm $imm)))>;
21115f757f3fSDimitry Andricdef : Pat<(i32 (or GPR:$rs1, simm12i32:$imm)),
21125f757f3fSDimitry Andric          (ORI GPR:$rs1, (i64 (as_i64imm $imm)))>;
21135f757f3fSDimitry Andricdef : Pat<(i32 (xor GPR:$rs1, simm12i32:$imm)),
21145f757f3fSDimitry Andric          (XORI GPR:$rs1, (i64 (as_i64imm $imm)))>;
21155f757f3fSDimitry Andric
21165f757f3fSDimitry Andricdef : PatGprImm<shl, SLLIW, uimm5, i32>;
21175f757f3fSDimitry Andricdef : PatGprImm<srl, SRLIW, uimm5, i32>;
21185f757f3fSDimitry Andricdef : PatGprImm<sra, SRAIW, uimm5, i32>;
21195f757f3fSDimitry Andric
21205f757f3fSDimitry Andricdef : Pat<(i32 (and GPR:$rs, TrailingOnesMask:$mask)),
21215f757f3fSDimitry Andric          (SRLI (SLLI $rs, (i64 (XLenSubTrailingOnes $mask))),
21225f757f3fSDimitry Andric                (i64 (XLenSubTrailingOnes $mask)))>;
21235f757f3fSDimitry Andric
21245f757f3fSDimitry Andric// Use sext if the sign bit of the input is 0.
21255f757f3fSDimitry Andricdef : Pat<(zext_is_sext GPR:$src), (ADDIW GPR:$src, 0)>;
21265f757f3fSDimitry Andric}
21275f757f3fSDimitry Andric
21285f757f3fSDimitry Andriclet Predicates = [IsRV64, NotHasStdExtZba] in {
21295f757f3fSDimitry Andricdef : Pat<(zext GPR:$src), (SRLI (SLLI GPR:$src, 32), 32)>;
21305f757f3fSDimitry Andric
21315f757f3fSDimitry Andric// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2
21325f757f3fSDimitry Andric// shifts instead of 3. This can occur when unsigned is used to index an array.
21335f757f3fSDimitry Andricdef : Pat<(shl (zext GPR:$rs), uimm5:$shamt),
21345f757f3fSDimitry Andric          (SRLI (SLLI GPR:$rs, 32), (ImmSubFrom32 uimm5:$shamt))>;
21355f757f3fSDimitry Andric}
21365f757f3fSDimitry Andric
21370b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
21380b57cec5SDimitry Andric// Standard extensions
21390b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
21400b57cec5SDimitry Andric
214106c3fb27SDimitry Andric// Multiply and Division
21420b57cec5SDimitry Andricinclude "RISCVInstrInfoM.td"
214306c3fb27SDimitry Andric
214406c3fb27SDimitry Andric// Atomic
21450b57cec5SDimitry Andricinclude "RISCVInstrInfoA.td"
21461db9f3b2SDimitry Andricinclude "RISCVInstrInfoZa.td"
214706c3fb27SDimitry Andric
214806c3fb27SDimitry Andric// Scalar FP
21490b57cec5SDimitry Andricinclude "RISCVInstrInfoF.td"
21500b57cec5SDimitry Andricinclude "RISCVInstrInfoD.td"
215106c3fb27SDimitry Andricinclude "RISCVInstrInfoZfh.td"
215206c3fb27SDimitry Andricinclude "RISCVInstrInfoZfbfmin.td"
215306c3fb27SDimitry Andricinclude "RISCVInstrInfoZfa.td"
215406c3fb27SDimitry Andric
215506c3fb27SDimitry Andric// Scalar bitmanip and cryptography
2156349cc55cSDimitry Andricinclude "RISCVInstrInfoZb.td"
215704eeddc0SDimitry Andricinclude "RISCVInstrInfoZk.td"
215806c3fb27SDimitry Andric
215906c3fb27SDimitry Andric// Vector
21605ffd83dbSDimitry Andricinclude "RISCVInstrInfoV.td"
216106c3fb27SDimitry Andricinclude "RISCVInstrInfoZvk.td"
216206c3fb27SDimitry Andric
216306c3fb27SDimitry Andric// Compressed
216406c3fb27SDimitry Andricinclude "RISCVInstrInfoC.td"
216506c3fb27SDimitry Andricinclude "RISCVInstrInfoZc.td"
2166647cbc5dSDimitry Andricinclude "RISCVInstrInfoZcmop.td"
2167647cbc5dSDimitry Andric
2168647cbc5dSDimitry Andric// Integer
2169647cbc5dSDimitry Andricinclude "RISCVInstrInfoZimop.td"
2170647cbc5dSDimitry Andricinclude "RISCVInstrInfoZicbo.td"
2171647cbc5dSDimitry Andricinclude "RISCVInstrInfoZicond.td"
2172647cbc5dSDimitry Andricinclude "RISCVInstrInfoZicfiss.td"
2173bdd1243dSDimitry Andric
2174bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2175bdd1243dSDimitry Andric// Vendor extensions
2176bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
2177bdd1243dSDimitry Andric
2178bdd1243dSDimitry Andricinclude "RISCVInstrInfoXVentana.td"
2179bdd1243dSDimitry Andricinclude "RISCVInstrInfoXTHead.td"
218006c3fb27SDimitry Andricinclude "RISCVInstrInfoXSf.td"
218106c3fb27SDimitry Andricinclude "RISCVInstrInfoXCV.td"
21825f757f3fSDimitry Andric
21835f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
21845f757f3fSDimitry Andric// Global ISel
21855f757f3fSDimitry Andric//===----------------------------------------------------------------------===//
21865f757f3fSDimitry Andric
21875f757f3fSDimitry Andricinclude "RISCVInstrGISel.td"
2188