1//===-- RISCVInstrInfo.td - Target Description for RISCV ---*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the RISC-V instructions in TableGen format.
10//
11//===----------------------------------------------------------------------===//
12
13//===----------------------------------------------------------------------===//
14// RISC-V specific DAG Nodes.
15//===----------------------------------------------------------------------===//
16
17// Target-independent type requirements, but with target-specific formats.
18def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
19                                       SDTCisVT<1, i32>]>;
20def SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
21                                     SDTCisVT<1, i32>]>;
22
23// Target-dependent type requirements.
24def SDT_RISCVCall     : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;
25def SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
26                                             SDTCisSameAs<0, 4>,
27                                             SDTCisSameAs<4, 5>]>;
28def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
29                                         SDTCisVT<2, OtherVT>,
30                                         SDTCisVT<3, OtherVT>]>;
31def SDT_RISCVReadCSR  : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
32def SDT_RISCVWriteCSR : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>;
33def SDT_RISCVSwapCSR  : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
34                                             SDTCisInt<2>]>;
35def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>,
36                                                  SDTCisVT<1, i32>]>;
37def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [
38  SDTCisSameAs<0, 1>, SDTCisVT<0, i64>
39]>;
40def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
41  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>
42]>;
43def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [
44  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64>
45]>;
46
47// Target-independent nodes, but with target-specific formats.
48def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
49                           [SDNPHasChain, SDNPOutGlue]>;
50def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
51                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
52
53// Target-dependent nodes.
54def riscv_call      : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
55                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
56                              SDNPVariadic]>;
57def riscv_ret_flag  : SDNode<"RISCVISD::RET_FLAG", SDTNone,
58                             [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
59def riscv_uret_flag : SDNode<"RISCVISD::URET_FLAG", SDTNone,
60                             [SDNPHasChain, SDNPOptInGlue]>;
61def riscv_sret_flag : SDNode<"RISCVISD::SRET_FLAG", SDTNone,
62                             [SDNPHasChain, SDNPOptInGlue]>;
63def riscv_mret_flag : SDNode<"RISCVISD::MRET_FLAG", SDTNone,
64                             [SDNPHasChain, SDNPOptInGlue]>;
65def riscv_selectcc  : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC>;
66def riscv_brcc      : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
67                             [SDNPHasChain]>;
68def riscv_tail      : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
69                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
70                              SDNPVariadic]>;
71def riscv_sllw      : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
72def riscv_sraw      : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
73def riscv_srlw      : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
74def riscv_read_csr  : SDNode<"RISCVISD::READ_CSR", SDT_RISCVReadCSR,
75                             [SDNPHasChain]>;
76def riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_RISCVWriteCSR,
77                             [SDNPHasChain]>;
78def riscv_swap_csr  : SDNode<"RISCVISD::SWAP_CSR", SDT_RISCVSwapCSR,
79                             [SDNPHasChain]>;
80
81def riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE",
82                                   SDT_RISCVReadCycleWide,
83                                   [SDNPHasChain, SDNPSideEffect]>;
84
85//===----------------------------------------------------------------------===//
86// Operand and SDNode transformation definitions.
87//===----------------------------------------------------------------------===//
88
89class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
90  let Name = prefix # "ImmXLen" # suffix;
91  let RenderMethod = "addImmOperands";
92  let DiagnosticType = !strconcat("Invalid", Name);
93}
94
95class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
96  let Name = prefix # "Imm" # width # suffix;
97  let RenderMethod = "addImmOperands";
98  let DiagnosticType = !strconcat("Invalid", Name);
99}
100
101def ImmZeroAsmOperand : AsmOperandClass {
102  let Name = "ImmZero";
103  let RenderMethod = "addImmOperands";
104  let DiagnosticType = !strconcat("Invalid", Name);
105}
106
107class SImmAsmOperand<int width, string suffix = "">
108    : ImmAsmOperand<"S", width, suffix> {
109}
110
111class UImmAsmOperand<int width, string suffix = "">
112    : ImmAsmOperand<"U", width, suffix> {
113}
114
115def FenceArg : AsmOperandClass {
116  let Name = "FenceArg";
117  let RenderMethod = "addFenceArgOperands";
118  let DiagnosticType = "InvalidFenceArg";
119}
120
121def fencearg : Operand<XLenVT> {
122  let ParserMatchClass = FenceArg;
123  let PrintMethod = "printFenceArg";
124  let DecoderMethod = "decodeUImmOperand<4>";
125  let OperandType = "OPERAND_UIMM4";
126  let OperandNamespace = "RISCVOp";
127}
128
129def UImmLog2XLenAsmOperand : AsmOperandClass {
130  let Name = "UImmLog2XLen";
131  let RenderMethod = "addImmOperands";
132  let DiagnosticType = "InvalidUImmLog2XLen";
133}
134
135def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
136  if (Subtarget->is64Bit())
137    return isUInt<6>(Imm);
138  return isUInt<5>(Imm);
139}]> {
140  let ParserMatchClass = UImmLog2XLenAsmOperand;
141  // TODO: should ensure invalid shamt is rejected when decoding.
142  let DecoderMethod = "decodeUImmOperand<6>";
143  let MCOperandPredicate = [{
144    int64_t Imm;
145    if (!MCOp.evaluateAsConstantImm(Imm))
146      return false;
147    if (STI.getTargetTriple().isArch64Bit())
148      return isUInt<6>(Imm);
149    return isUInt<5>(Imm);
150  }];
151  let OperandType = "OPERAND_UIMMLOG2XLEN";
152  let OperandNamespace = "RISCVOp";
153}
154
155def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
156  let ParserMatchClass = UImmAsmOperand<5>;
157  let DecoderMethod = "decodeUImmOperand<5>";
158  let OperandType = "OPERAND_UIMM5";
159  let OperandNamespace = "RISCVOp";
160}
161
162def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
163  let ParserMatchClass = SImmAsmOperand<12>;
164  let EncoderMethod = "getImmOpValue";
165  let DecoderMethod = "decodeSImmOperand<12>";
166  let MCOperandPredicate = [{
167    int64_t Imm;
168    if (MCOp.evaluateAsConstantImm(Imm))
169      return isInt<12>(Imm);
170    return MCOp.isBareSymbolRef();
171  }];
172  let OperandType = "OPERAND_SIMM12";
173  let OperandNamespace = "RISCVOp";
174}
175
176// A 13-bit signed immediate where the least significant bit is zero.
177def simm13_lsb0 : Operand<OtherVT> {
178  let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
179  let PrintMethod = "printBranchOperand";
180  let EncoderMethod = "getImmOpValueAsr1";
181  let DecoderMethod = "decodeSImmOperandAndLsl1<13>";
182  let MCOperandPredicate = [{
183    int64_t Imm;
184    if (MCOp.evaluateAsConstantImm(Imm))
185      return isShiftedInt<12, 1>(Imm);
186    return MCOp.isBareSymbolRef();
187  }];
188  let OperandType = "OPERAND_PCREL";
189}
190
191class UImm20Operand : Operand<XLenVT> {
192  let EncoderMethod = "getImmOpValue";
193  let DecoderMethod = "decodeUImmOperand<20>";
194  let MCOperandPredicate = [{
195    int64_t Imm;
196    if (MCOp.evaluateAsConstantImm(Imm))
197      return isUInt<20>(Imm);
198    return MCOp.isBareSymbolRef();
199  }];
200  let OperandType = "OPERAND_UIMM20";
201  let OperandNamespace = "RISCVOp";
202}
203
204def uimm20_lui : UImm20Operand {
205  let ParserMatchClass = UImmAsmOperand<20, "LUI">;
206}
207def uimm20_auipc : UImm20Operand {
208  let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;
209}
210
211def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> {
212  let ParserMethod = "parseJALOffset";
213}
214
215// A 21-bit signed immediate where the least significant bit is zero.
216def simm21_lsb0_jal : Operand<OtherVT> {
217  let ParserMatchClass = Simm21Lsb0JALAsmOperand;
218  let PrintMethod = "printBranchOperand";
219  let EncoderMethod = "getImmOpValueAsr1";
220  let DecoderMethod = "decodeSImmOperandAndLsl1<21>";
221  let MCOperandPredicate = [{
222    int64_t Imm;
223    if (MCOp.evaluateAsConstantImm(Imm))
224      return isShiftedInt<20, 1>(Imm);
225    return MCOp.isBareSymbolRef();
226  }];
227  let OperandType = "OPERAND_PCREL";
228}
229
230def BareSymbol : AsmOperandClass {
231  let Name = "BareSymbol";
232  let RenderMethod = "addImmOperands";
233  let DiagnosticType = "InvalidBareSymbol";
234  let ParserMethod = "parseBareSymbol";
235}
236
237// A bare symbol.
238def bare_symbol : Operand<XLenVT> {
239  let ParserMatchClass = BareSymbol;
240}
241
242def CallSymbol : AsmOperandClass {
243  let Name = "CallSymbol";
244  let RenderMethod = "addImmOperands";
245  let DiagnosticType = "InvalidCallSymbol";
246  let ParserMethod = "parseCallSymbol";
247}
248
249// A bare symbol used in call/tail only.
250def call_symbol : Operand<XLenVT> {
251  let ParserMatchClass = CallSymbol;
252}
253
254def PseudoJumpSymbol : AsmOperandClass {
255  let Name = "PseudoJumpSymbol";
256  let RenderMethod = "addImmOperands";
257  let DiagnosticType = "InvalidPseudoJumpSymbol";
258  let ParserMethod = "parsePseudoJumpSymbol";
259}
260
261// A bare symbol used for pseudo jumps only.
262def pseudo_jump_symbol : Operand<XLenVT> {
263  let ParserMatchClass = PseudoJumpSymbol;
264}
265
266def TPRelAddSymbol : AsmOperandClass {
267  let Name = "TPRelAddSymbol";
268  let RenderMethod = "addImmOperands";
269  let DiagnosticType = "InvalidTPRelAddSymbol";
270  let ParserMethod = "parseOperandWithModifier";
271}
272
273// A bare symbol with the %tprel_add variant.
274def tprel_add_symbol : Operand<XLenVT> {
275  let ParserMatchClass = TPRelAddSymbol;
276}
277
278def CSRSystemRegister : AsmOperandClass {
279  let Name = "CSRSystemRegister";
280  let ParserMethod = "parseCSRSystemRegister";
281  let DiagnosticType = "InvalidCSRSystemRegister";
282}
283
284def csr_sysreg : Operand<XLenVT> {
285  let ParserMatchClass = CSRSystemRegister;
286  let PrintMethod = "printCSRSystemRegister";
287  let DecoderMethod = "decodeUImmOperand<12>";
288  let OperandType = "OPERAND_UIMM12";
289  let OperandNamespace = "RISCVOp";
290}
291
292// A parameterized register class alternative to i32imm/i64imm from Target.td.
293def ixlenimm : Operand<XLenVT>;
294
295def ixlenimm_li : Operand<XLenVT> {
296  let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;
297}
298
299// Standalone (codegen-only) immleaf patterns.
300
301// A 12-bit signed immediate plus one where the imm range will be -2047~2048.
302def simm12_plus1 : ImmLeaf<XLenVT,
303  [{return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
304
305// A 6-bit constant greater than 32.
306def uimm6gt32 : ImmLeaf<XLenVT, [{
307  return isUInt<6>(Imm) && Imm > 32;
308}]>;
309
310// Addressing modes.
311// Necessary because a frameindex can't be matched directly in a pattern.
312def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI", [frameindex], []>;
313def BaseAddr : ComplexPattern<iPTR, 1, "SelectBaseAddr">;
314
315// Return the negation of an immediate value.
316def NegImm : SDNodeXForm<imm, [{
317  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N),
318                                   N->getValueType(0));
319}]>;
320
321// Return an immediate value minus 32.
322def ImmSub32 : SDNodeXForm<imm, [{
323  return CurDAG->getTargetConstant(N->getSExtValue() - 32, SDLoc(N),
324                                   N->getValueType(0));
325}]>;
326
327// Return an immediate value plus 32.
328def ImmPlus32 : SDNodeXForm<imm, [{
329  return CurDAG->getTargetConstant(N->getSExtValue() + 32, SDLoc(N),
330                                   N->getValueType(0));
331}]>;
332
333// Return an immediate subtracted from XLen.
334def ImmSubFromXLen : SDNodeXForm<imm, [{
335  uint64_t XLen = Subtarget->getXLen();
336  return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),
337                                   N->getValueType(0));
338}]>;
339
340// Return an immediate subtracted from 32.
341def ImmSubFrom32 : SDNodeXForm<imm, [{
342  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
343                                   N->getValueType(0));
344}]>;
345
346// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
347// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12.
348def AddiPair : PatLeaf<(imm), [{
349  if (!N->hasOneUse())
350    return false;
351  // The immediate operand must be in range [-4096,-2049] or [2048,4094].
352  int64_t Imm = N->getSExtValue();
353  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
354}]>;
355
356// Return imm/2.
357def AddiPairImmA : SDNodeXForm<imm, [{
358  return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N),
359                                   N->getValueType(0));
360}]>;
361
362// Return imm - imm/2.
363def AddiPairImmB : SDNodeXForm<imm, [{
364  int64_t Imm = N->getSExtValue();
365  return CurDAG->getTargetConstant(Imm - Imm / 2, SDLoc(N),
366                                   N->getValueType(0));
367}]>;
368
369//===----------------------------------------------------------------------===//
370// Instruction Formats
371//===----------------------------------------------------------------------===//
372
373include "RISCVInstrFormats.td"
374
375//===----------------------------------------------------------------------===//
376// Instruction Class Templates
377//===----------------------------------------------------------------------===//
378
379let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
380class BranchCC_rri<bits<3> funct3, string opcodestr>
381    : RVInstB<funct3, OPC_BRANCH, (outs),
382              (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12),
383              opcodestr, "$rs1, $rs2, $imm12">,
384      Sched<[WriteJmp, ReadJmp, ReadJmp]> {
385  let isBranch = 1;
386  let isTerminator = 1;
387}
388
389let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
390class Load_ri<bits<3> funct3, string opcodestr>
391    : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
392              opcodestr, "$rd, ${imm12}(${rs1})">;
393
394// Operands for stores are in the order srcreg, base, offset rather than
395// reflecting the order these fields are specified in the instruction
396// encoding.
397let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
398class Store_rri<bits<3> funct3, string opcodestr>
399    : RVInstS<funct3, OPC_STORE, (outs),
400              (ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
401              opcodestr, "$rs2, ${imm12}(${rs1})">;
402
403let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
404class ALU_ri<bits<3> funct3, string opcodestr>
405    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
406              opcodestr, "$rd, $rs1, $imm12">,
407      Sched<[WriteIALU, ReadIALU]>;
408
409let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
410class Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr>
411    : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd),
412                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
413                   "$rd, $rs1, $shamt">,
414      Sched<[WriteShiftImm, ReadShiftImm]>;
415
416let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
417class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
418    : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
419              opcodestr, "$rd, $rs1, $rs2">;
420
421let hasNoSchedulingInfo = 1,
422    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
423class CSR_ir<bits<3> funct3, string opcodestr>
424    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),
425              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>;
426
427let hasNoSchedulingInfo = 1,
428    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
429class CSR_ii<bits<3> funct3, string opcodestr>
430    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),
431              (ins csr_sysreg:$imm12, uimm5:$rs1),
432              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>;
433
434let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
435class ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr>
436    : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
437                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,
438                    "$rd, $rs1, $shamt">,
439      Sched<[WriteShiftImm32, ReadShiftImm32]>;
440
441let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
442class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
443    : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
444              (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
445
446let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
447class Priv<string opcodestr, bits<7> funct7>
448    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
449              opcodestr, "">;
450
451//===----------------------------------------------------------------------===//
452// Instructions
453//===----------------------------------------------------------------------===//
454
455let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
456let isReMaterializable = 1, isAsCheapAsAMove = 1 in
457def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
458                  "lui", "$rd, $imm20">, Sched<[WriteIALU]>;
459
460def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20),
461                    "auipc", "$rd, $imm20">, Sched<[WriteIALU]>;
462
463let isCall = 1 in
464def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20),
465                  "jal", "$rd, $imm20">, Sched<[WriteJal]>;
466
467let isCall = 1 in
468def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),
469                   (ins GPR:$rs1, simm12:$imm12),
470                   "jalr", "$rd, ${imm12}(${rs1})">,
471           Sched<[WriteJalr, ReadJalr]>;
472} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
473
474def BEQ  : BranchCC_rri<0b000, "beq">;
475def BNE  : BranchCC_rri<0b001, "bne">;
476def BLT  : BranchCC_rri<0b100, "blt">;
477def BGE  : BranchCC_rri<0b101, "bge">;
478def BLTU : BranchCC_rri<0b110, "bltu">;
479def BGEU : BranchCC_rri<0b111, "bgeu">;
480
481def LB  : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>;
482def LH  : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>;
483def LW  : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>;
484def LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>;
485def LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>;
486
487def SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
488def SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
489def SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
490
491// ADDI isn't always rematerializable, but isReMaterializable will be used as
492// a hint which is verified in isReallyTriviallyReMaterializable.
493let isReMaterializable = 1, isAsCheapAsAMove = 1 in
494def ADDI  : ALU_ri<0b000, "addi">;
495
496def SLTI  : ALU_ri<0b010, "slti">;
497def SLTIU : ALU_ri<0b011, "sltiu">;
498
499let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
500def XORI  : ALU_ri<0b100, "xori">;
501def ORI   : ALU_ri<0b110, "ori">;
502}
503
504def ANDI  : ALU_ri<0b111, "andi">;
505
506def SLLI : Shift_ri<0b00000, 0b001, "slli">;
507def SRLI : Shift_ri<0b00000, 0b101, "srli">;
508def SRAI : Shift_ri<0b01000, 0b101, "srai">;
509
510def ADD  : ALU_rr<0b0000000, 0b000, "add">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
511def SUB  : ALU_rr<0b0100000, 0b000, "sub">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
512def SLL  : ALU_rr<0b0000000, 0b001, "sll">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
513def SLT  : ALU_rr<0b0000000, 0b010, "slt">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
514def SLTU : ALU_rr<0b0000000, 0b011, "sltu">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
515def XOR  : ALU_rr<0b0000000, 0b100, "xor">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
516def SRL  : ALU_rr<0b0000000, 0b101, "srl">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
517def SRA  : ALU_rr<0b0100000, 0b101, "sra">, Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
518def OR   : ALU_rr<0b0000000, 0b110, "or">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
519def AND  : ALU_rr<0b0000000, 0b111, "and">, Sched<[WriteIALU, ReadIALU, ReadIALU]>;
520
521let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
522def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),
523                    (ins fencearg:$pred, fencearg:$succ),
524                    "fence", "$pred, $succ">, Sched<[]> {
525  bits<4> pred;
526  bits<4> succ;
527
528  let rs1 = 0;
529  let rd = 0;
530  let imm12 = {0b0000,pred,succ};
531}
532
533def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> {
534  let rs1 = 0;
535  let rd = 0;
536  let imm12 = {0b1000,0b0011,0b0011};
537}
538
539def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> {
540  let rs1 = 0;
541  let rd = 0;
542  let imm12 = 0;
543}
544
545def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> {
546  let rs1 = 0;
547  let rd = 0;
548  let imm12 = 0;
549}
550
551def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">,
552             Sched<[]> {
553  let rs1 = 0;
554  let rd = 0;
555  let imm12 = 1;
556}
557
558// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
559// instruction (i.e., it should always trap, if your implementation has invalid
560// instruction traps).
561def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">,
562            Sched<[]> {
563  let rs1 = 0;
564  let rd = 0;
565  let imm12 = 0b110000000000;
566}
567} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
568
569def CSRRW : CSR_ir<0b001, "csrrw">;
570def CSRRS : CSR_ir<0b010, "csrrs">;
571def CSRRC : CSR_ir<0b011, "csrrc">;
572
573def CSRRWI : CSR_ii<0b101, "csrrwi">;
574def CSRRSI : CSR_ii<0b110, "csrrsi">;
575def CSRRCI : CSR_ii<0b111, "csrrci">;
576
577/// RV64I instructions
578
579let Predicates = [IsRV64] in {
580def LWU   : Load_ri<0b110, "lwu">, Sched<[WriteLDWU, ReadMemBase]>;
581def LD    : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>;
582def SD    : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>;
583
584let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
585def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
586                    (ins GPR:$rs1, simm12:$imm12),
587                    "addiw", "$rd, $rs1, $imm12">,
588            Sched<[WriteIALU32, ReadIALU32]>;
589
590def SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">;
591def SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">;
592def SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">;
593
594def ADDW  : ALUW_rr<0b0000000, 0b000, "addw">,
595            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
596def SUBW  : ALUW_rr<0b0100000, 0b000, "subw">,
597            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
598def SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">,
599            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
600def SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">,
601            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
602def SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">,
603            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
604} // Predicates = [IsRV64]
605
606//===----------------------------------------------------------------------===//
607// Privileged instructions
608//===----------------------------------------------------------------------===//
609
610let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
611def URET : Priv<"uret", 0b0000000>, Sched<[]> {
612  let rd = 0;
613  let rs1 = 0;
614  let rs2 = 0b00010;
615}
616
617def SRET : Priv<"sret", 0b0001000>, Sched<[]> {
618  let rd = 0;
619  let rs1 = 0;
620  let rs2 = 0b00010;
621}
622
623def MRET : Priv<"mret", 0b0011000>, Sched<[]> {
624  let rd = 0;
625  let rs1 = 0;
626  let rs2 = 0b00010;
627}
628} // isBarrier = 1, isReturn = 1, isTerminator = 1
629
630def WFI : Priv<"wfi", 0b0001000>, Sched<[]> {
631  let rd = 0;
632  let rs1 = 0;
633  let rs2 = 0b00101;
634}
635
636let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
637def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
638                         (ins GPR:$rs1, GPR:$rs2),
639                         "sfence.vma", "$rs1, $rs2">, Sched<[]> {
640  let rd = 0;
641}
642
643//===----------------------------------------------------------------------===//
644// Debug instructions
645//===----------------------------------------------------------------------===//
646
647let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
648def DRET : Priv<"dret", 0b0111101>, Sched<[]> {
649  let rd = 0;
650  let rs1 = 0;
651  let rs2 = 0b10010;
652}
653} // isBarrier = 1, isReturn = 1, isTerminator = 1
654
655//===----------------------------------------------------------------------===//
656// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
657//===----------------------------------------------------------------------===//
658
659def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
660
661// Note that the size is 32 because up to 8 32-bit instructions are needed to
662// generate an arbitrary 64-bit immediate. However, the size does not really
663// matter since PseudoLI is currently only used in the AsmParser where it gets
664// expanded to real instructions immediately.
665let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
666    isCodeGenOnly = 0, isAsmParserOnly = 1 in
667def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
668                      "li", "$rd, $imm">;
669
670def PseudoLB  : PseudoLoad<"lb">;
671def PseudoLBU : PseudoLoad<"lbu">;
672def PseudoLH  : PseudoLoad<"lh">;
673def PseudoLHU : PseudoLoad<"lhu">;
674def PseudoLW  : PseudoLoad<"lw">;
675
676def PseudoSB  : PseudoStore<"sb">;
677def PseudoSH  : PseudoStore<"sh">;
678def PseudoSW  : PseudoStore<"sw">;
679
680let Predicates = [IsRV64] in {
681def PseudoLWU : PseudoLoad<"lwu">;
682def PseudoLD  : PseudoLoad<"ld">;
683def PseudoSD  : PseudoStore<"sd">;
684} // Predicates = [IsRV64]
685
686def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
687def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
688def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
689
690let Predicates = [IsRV64] in {
691def : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;
692def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;
693} // Predicates = [IsRV64]
694
695def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;
696def : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;
697def : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;
698def : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;
699
700// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu
701// form will always be printed. Therefore, set a zero weight.
702def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;
703def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;
704
705def : InstAlias<"beqz $rs, $offset",
706                (BEQ GPR:$rs,      X0, simm13_lsb0:$offset)>;
707def : InstAlias<"bnez $rs, $offset",
708                (BNE GPR:$rs,      X0, simm13_lsb0:$offset)>;
709def : InstAlias<"blez $rs, $offset",
710                (BGE      X0, GPR:$rs, simm13_lsb0:$offset)>;
711def : InstAlias<"bgez $rs, $offset",
712                (BGE GPR:$rs,      X0, simm13_lsb0:$offset)>;
713def : InstAlias<"bltz $rs, $offset",
714                (BLT GPR:$rs,      X0, simm13_lsb0:$offset)>;
715def : InstAlias<"bgtz $rs, $offset",
716                (BLT      X0, GPR:$rs, simm13_lsb0:$offset)>;
717
718// Always output the canonical mnemonic for the pseudo branch instructions.
719// The GNU tools emit the canonical mnemonic for the branch pseudo instructions
720// as well (e.g. "bgt" will be recognised by the assembler but never printed by
721// objdump). Match this behaviour by setting a zero weight.
722def : InstAlias<"bgt $rs, $rt, $offset",
723                (BLT  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
724def : InstAlias<"ble $rs, $rt, $offset",
725                (BGE  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
726def : InstAlias<"bgtu $rs, $rt, $offset",
727                (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
728def : InstAlias<"bleu $rs, $rt, $offset",
729                (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
730
731def : InstAlias<"j $offset",   (JAL X0, simm21_lsb0_jal:$offset)>;
732def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>;
733
734// Non-zero offset aliases of "jalr" are the lowest weight, followed by the
735// two-register form, then the one-register forms and finally "ret".
736def : InstAlias<"jr $rs",                (JALR      X0, GPR:$rs, 0), 3>;
737def : InstAlias<"jr ${offset}(${rs})",   (JALR      X0, GPR:$rs, simm12:$offset)>;
738def : InstAlias<"jalr $rs",              (JALR      X1, GPR:$rs, 0), 3>;
739def : InstAlias<"jalr ${offset}(${rs})", (JALR      X1, GPR:$rs, simm12:$offset)>;
740def : InstAlias<"jalr $rd, $rs",         (JALR GPR:$rd, GPR:$rs, 0), 2>;
741def : InstAlias<"ret",                   (JALR      X0,      X1, 0), 4>;
742
743// Non-canonical forms for jump targets also accepted by the assembler.
744def : InstAlias<"jr $rs, $offset",        (JALR      X0, GPR:$rs, simm12:$offset), 0>;
745def : InstAlias<"jalr $rs, $offset",      (JALR      X1, GPR:$rs, simm12:$offset), 0>;
746def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>;
747
748def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
749
750def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>;
751def : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, CYCLE.Encoding, X0)>;
752def : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, TIME.Encoding, X0)>;
753
754let Predicates = [IsRV32] in {
755def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0)>;
756def : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, CYCLEH.Encoding, X0)>;
757def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, TIMEH.Encoding, X0)>;
758} // Predicates = [IsRV32]
759
760def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;
761def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;
762def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;
763def : InstAlias<"csrc $csr, $rs", (CSRRC      X0, csr_sysreg:$csr, GPR:$rs)>;
764
765def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
766def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
767def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
768
769let EmitPriority = 0 in {
770def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
771def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
772def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
773
774def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
775def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
776def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
777}
778
779def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
780def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
781
782let EmitPriority = 0 in {
783def : InstAlias<"lb $rd, (${rs1})",
784                (LB  GPR:$rd, GPR:$rs1, 0)>;
785def : InstAlias<"lh $rd, (${rs1})",
786                (LH  GPR:$rd, GPR:$rs1, 0)>;
787def : InstAlias<"lw $rd, (${rs1})",
788                (LW  GPR:$rd, GPR:$rs1, 0)>;
789def : InstAlias<"lbu $rd, (${rs1})",
790                (LBU  GPR:$rd, GPR:$rs1, 0)>;
791def : InstAlias<"lhu $rd, (${rs1})",
792                (LHU  GPR:$rd, GPR:$rs1, 0)>;
793
794def : InstAlias<"sb $rs2, (${rs1})",
795                (SB  GPR:$rs2, GPR:$rs1, 0)>;
796def : InstAlias<"sh $rs2, (${rs1})",
797                (SH  GPR:$rs2, GPR:$rs1, 0)>;
798def : InstAlias<"sw $rs2, (${rs1})",
799                (SW  GPR:$rs2, GPR:$rs1, 0)>;
800
801def : InstAlias<"add $rd, $rs1, $imm12",
802                (ADDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
803def : InstAlias<"and $rd, $rs1, $imm12",
804                (ANDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
805def : InstAlias<"xor $rd, $rs1, $imm12",
806                (XORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
807def : InstAlias<"or $rd, $rs1, $imm12",
808                (ORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
809def : InstAlias<"sll $rd, $rs1, $shamt",
810                (SLLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
811def : InstAlias<"srl $rd, $rs1, $shamt",
812                (SRLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
813def : InstAlias<"sra $rd, $rs1, $shamt",
814                (SRAI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
815let Predicates = [IsRV64] in {
816def : InstAlias<"lwu $rd, (${rs1})",
817                (LWU  GPR:$rd, GPR:$rs1, 0)>;
818def : InstAlias<"ld $rd, (${rs1})",
819                (LD  GPR:$rd, GPR:$rs1, 0)>;
820def : InstAlias<"sd $rs2, (${rs1})",
821                (SD  GPR:$rs2, GPR:$rs1, 0)>;
822
823def : InstAlias<"addw $rd, $rs1, $imm12",
824                (ADDIW  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
825def : InstAlias<"sllw $rd, $rs1, $shamt",
826                (SLLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
827def : InstAlias<"srlw $rd, $rs1, $shamt",
828                (SRLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
829def : InstAlias<"sraw $rd, $rs1, $shamt",
830                (SRAIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
831} // Predicates = [IsRV64]
832def : InstAlias<"slt $rd, $rs1, $imm12",
833                (SLTI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
834def : InstAlias<"sltu $rd, $rs1, $imm12",
835                (SLTIU  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
836}
837
838def : MnemonicAlias<"move", "mv">;
839
840// The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in
841// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept
842// the old name for backwards compatibility.
843def : MnemonicAlias<"scall", "ecall">;
844def : MnemonicAlias<"sbreak", "ebreak">;
845
846// This alias was added to the spec in December 2020. Don't print it by default
847// to allow assembly we print to be compatible with versions of GNU assembler
848// that don't support this alias.
849def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF), 0>;
850
851//===----------------------------------------------------------------------===//
852// Pseudo-instructions and codegen patterns
853//
854// Naming convention: For 'generic' pattern classes, we use the naming
855// convention PatTy1Ty2. For pattern classes which offer a more complex
856// expansion, prefix the class name, e.g. BccPat.
857//===----------------------------------------------------------------------===//
858
859/// Generic pattern classes
860
861class PatGpr<SDPatternOperator OpNode, RVInst Inst>
862    : Pat<(OpNode GPR:$rs1), (Inst GPR:$rs1)>;
863class PatGprGpr<SDPatternOperator OpNode, RVInst Inst>
864    : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
865
866class PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType>
867    : Pat<(XLenVT (OpNode (XLenVT GPR:$rs1), ImmType:$imm)),
868          (Inst GPR:$rs1, ImmType:$imm)>;
869class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
870    : PatGprImm<OpNode, Inst, simm12>;
871class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
872    : PatGprImm<OpNode, Inst, uimmlog2xlen>;
873
874/// Predicates
875
876def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
877  return isOrEquivalentToAdd(N);
878}]>;
879def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
880  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
881}]>;
882def sexti32 : ComplexPattern<i64, 1, "selectSExti32">;
883def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
884  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
885}]>;
886def zexti32 : ComplexPattern<i64, 1, "selectZExti32">;
887
888def add_oneuse : PatFrag<(ops node:$A, node:$B), (add node:$A, node:$B), [{
889  return N->hasOneUse();
890}]>;
891
892def mul_oneuse : PatFrag<(ops node:$A, node:$B), (mul node:$A, node:$B), [{
893  return N->hasOneUse();
894}]>;
895
896/// Simple arithmetic operations
897
898def : PatGprGpr<add, ADD>;
899def : PatGprSimm12<add, ADDI>;
900def : PatGprGpr<sub, SUB>;
901def : PatGprGpr<or, OR>;
902def : PatGprSimm12<or, ORI>;
903def : PatGprGpr<and, AND>;
904def : PatGprSimm12<and, ANDI>;
905def : PatGprGpr<xor, XOR>;
906def : PatGprSimm12<xor, XORI>;
907def : PatGprUimmLog2XLen<shl, SLLI>;
908def : PatGprUimmLog2XLen<srl, SRLI>;
909def : PatGprUimmLog2XLen<sra, SRAI>;
910
911// Match both a plain shift and one where the shift amount is masked (this is
912// typically introduced when the legalizer promotes the shift amount and
913// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base
914// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).
915def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>;
916def shiftMask32   : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;
917
918class shiftop<SDPatternOperator operator>
919    : PatFrag<(ops node:$val, node:$count),
920              (operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>;
921class shiftopw<SDPatternOperator operator>
922    : PatFrag<(ops node:$val, node:$count),
923              (operator node:$val, (i64 (shiftMask32 node:$count)))>;
924
925def : PatGprGpr<shiftop<shl>, SLL>;
926def : PatGprGpr<shiftop<srl>, SRL>;
927def : PatGprGpr<shiftop<sra>, SRA>;
928
929// This is a special case of the ADD instruction used to facilitate the use of a
930// fourth operand to emit a relocation on a symbol relating to this instruction.
931// The relocation does not affect any bits of the instruction itself but is used
932// as a hint to the linker.
933let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in
934def PseudoAddTPRel : Pseudo<(outs GPR:$rd),
935                            (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [],
936                            "add", "$rd, $rs1, $rs2, $src">;
937
938/// FrameIndex calculations
939
940def : Pat<(add (XLenVT AddrFI:$Rs), simm12:$imm12),
941          (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
942def : Pat<(IsOrAdd (XLenVT AddrFI:$Rs), simm12:$imm12),
943          (ADDI (XLenVT AddrFI:$Rs), simm12:$imm12)>;
944
945/// Setcc
946
947def : PatGprGpr<setlt, SLT>;
948def : PatGprSimm12<setlt, SLTI>;
949def : PatGprGpr<setult, SLTU>;
950def : PatGprSimm12<setult, SLTIU>;
951
952// Define pattern expansions for setcc operations that aren't directly
953// handled by a RISC-V instruction.
954def : Pat<(seteq GPR:$rs1, 0), (SLTIU GPR:$rs1, 1)>;
955def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
956def : Pat<(seteq GPR:$rs1, simm12_plus1:$imm12),
957          (SLTIU (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)), 1)>;
958def : Pat<(setne GPR:$rs1, 0), (SLTU X0, GPR:$rs1)>;
959def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
960def : Pat<(setne GPR:$rs1, simm12_plus1:$imm12),
961          (SLTU X0, (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)))>;
962def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>;
963def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
964def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
965def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>;
966def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
967def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
968
969let usesCustomInserter = 1 in
970class SelectCC_rrirr<RegisterClass valty, RegisterClass cmpty>
971    : Pseudo<(outs valty:$dst),
972             (ins cmpty:$lhs, cmpty:$rhs, ixlenimm:$imm,
973              valty:$truev, valty:$falsev),
974             [(set valty:$dst, (riscv_selectcc cmpty:$lhs, cmpty:$rhs,
975              (XLenVT timm:$imm), valty:$truev, valty:$falsev))]>;
976
977def Select_GPR_Using_CC_GPR : SelectCC_rrirr<GPR, GPR>;
978
979/// Branches and jumps
980
981// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
982class BccPat<CondCode Cond, RVInstB Inst>
983    : Pat<(riscv_brcc GPR:$rs1, GPR:$rs2, Cond, bb:$imm12),
984          (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>;
985
986def : BccPat<SETEQ, BEQ>;
987def : BccPat<SETNE, BNE>;
988def : BccPat<SETLT, BLT>;
989def : BccPat<SETGE, BGE>;
990def : BccPat<SETULT, BLTU>;
991def : BccPat<SETUGE, BGEU>;
992
993let isBarrier = 1, isBranch = 1, isTerminator = 1 in
994def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
995               PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;
996
997let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
998def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
999                  PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1000
1001def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;
1002def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)),
1003          (PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>;
1004
1005// PseudoCALLReg is a generic pseudo instruction for calls which will eventually
1006// expand to auipc and jalr while encoding, with any given register used as the
1007// destination.
1008// Define AsmString to print "call" when compile with -S flag.
1009// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
1010let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, hasSideEffects = 0,
1011    mayStore = 0, mayLoad = 0 in
1012def PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), []> {
1013  let AsmString = "call\t$rd, $func";
1014}
1015
1016// PseudoCALL is a pseudo instruction which will eventually expand to auipc
1017// and jalr while encoding. This is desirable, as an auipc+jalr pair with
1018// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
1019// if the offset fits in a signed 21-bit immediate.
1020// Define AsmString to print "call" when compile with -S flag.
1021// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
1022let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
1023def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), []> {
1024  let AsmString = "call\t$func";
1025}
1026
1027def : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
1028def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
1029
1030def : Pat<(riscv_uret_flag), (URET X0, X0)>;
1031def : Pat<(riscv_sret_flag), (SRET X0, X0)>;
1032def : Pat<(riscv_mret_flag), (MRET X0, X0)>;
1033
1034let isCall = 1, Defs = [X1] in
1035def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
1036                                [(riscv_call GPRJALR:$rs1)]>,
1037                         PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1038
1039let isBarrier = 1, isReturn = 1, isTerminator = 1 in
1040def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_flag)]>,
1041                PseudoInstExpansion<(JALR X0, X1, 0)>;
1042
1043// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
1044// expand to auipc and jalr while encoding.
1045// Define AsmString to print "tail" when compile with -S flag.
1046let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
1047    isCodeGenOnly = 0 in
1048def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), []> {
1049  let AsmString = "tail\t$dst";
1050}
1051
1052let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
1053def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
1054                                [(riscv_tail GPRTC:$rs1)]>,
1055                         PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1056
1057def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
1058          (PseudoTAIL texternalsym:$dst)>;
1059def : Pat<(riscv_tail (iPTR texternalsym:$dst)),
1060          (PseudoTAIL texternalsym:$dst)>;
1061
1062let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1,
1063    isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
1064def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), []> {
1065  let AsmString = "jump\t$target, $rd";
1066}
1067
1068let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
1069    isAsmParserOnly = 1 in
1070def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1071                       "lla", "$dst, $src">;
1072
1073let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
1074    isAsmParserOnly = 1 in
1075def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1076                      "la", "$dst, $src">;
1077
1078let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
1079    isAsmParserOnly = 1 in
1080def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1081                             "la.tls.ie", "$dst, $src">;
1082
1083let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
1084    isAsmParserOnly = 1 in
1085def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1086                             "la.tls.gd", "$dst, $src">;
1087
1088
1089/// Sign/Zero Extends
1090
1091// There are single-instruction versions of these in Zbb, so disable these
1092// Pseudos if that extension is present.
1093let hasSideEffects = 0, mayLoad = 0,
1094    mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1095def PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">;
1096def PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">;
1097// rv64's sext.w is defined above, using InstAlias<"sext.w ...
1098// zext.b is defined above, using InstAlias<"zext.b ...
1099def PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">;
1100} // hasSideEffects = 0, ...
1101
1102let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
1103  isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1104def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">;
1105} // Predicates = [IsRV64], ...
1106
1107/// Loads
1108
1109multiclass LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT> {
1110  def : Pat<(vt (LoadOp BaseAddr:$rs1)), (Inst BaseAddr:$rs1, 0)>;
1111  def : Pat<(vt (LoadOp (add BaseAddr:$rs1, simm12:$imm12))),
1112            (Inst BaseAddr:$rs1, simm12:$imm12)>;
1113  def : Pat<(vt (LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12))),
1114            (Inst AddrFI:$rs1, simm12:$imm12)>;
1115}
1116
1117defm : LdPat<sextloadi8, LB>;
1118defm : LdPat<extloadi8, LB>;
1119defm : LdPat<sextloadi16, LH>;
1120defm : LdPat<extloadi16, LH>;
1121defm : LdPat<load, LW, i32>, Requires<[IsRV32]>;
1122defm : LdPat<zextloadi8, LBU>;
1123defm : LdPat<zextloadi16, LHU>;
1124
1125/// Stores
1126
1127multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
1128                 ValueType vt> {
1129  def : Pat<(StoreOp (vt StTy:$rs2), BaseAddr:$rs1),
1130            (Inst StTy:$rs2, BaseAddr:$rs1, 0)>;
1131  def : Pat<(StoreOp (vt StTy:$rs2), (add BaseAddr:$rs1, simm12:$imm12)),
1132            (Inst StTy:$rs2, BaseAddr:$rs1, simm12:$imm12)>;
1133  def : Pat<(StoreOp (vt StTy:$rs2), (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
1134            (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
1135}
1136
1137defm : StPat<truncstorei8, SB, GPR, XLenVT>;
1138defm : StPat<truncstorei16, SH, GPR, XLenVT>;
1139defm : StPat<store, SW, GPR, i32>, Requires<[IsRV32]>;
1140
1141/// Fences
1142
1143// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
1144// Manual: Volume I.
1145
1146// fence acquire -> fence r, rw
1147def : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>;
1148// fence release -> fence rw, w
1149def : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>;
1150// fence acq_rel -> fence.tso
1151def : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>;
1152// fence seq_cst -> fence rw, rw
1153def : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>;
1154
1155// Lowering for atomic load and store is defined in RISCVInstrInfoA.td.
1156// Although these are lowered to fence+load/store instructions defined in the
1157// base RV32I/RV64I ISA, this lowering is only used when the A extension is
1158// present. This is necessary as it isn't valid to mix __atomic_* libcalls
1159// with inline atomic operations for the same object.
1160
1161/// Access to system registers
1162
1163// Helpers for defining specific operations. They are defined for each system
1164// register separately. Side effect is not used because dependencies are
1165// expressed via use-def properties.
1166
1167class ReadSysReg<SysReg SR, list<Register> Regs>
1168  : Pseudo<(outs GPR:$rd), (ins),
1169           [(set GPR:$rd, (riscv_read_csr (XLenVT SR.Encoding)))]>,
1170    PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> {
1171  let hasSideEffects = 0;
1172  let Uses = Regs;
1173}
1174
1175class WriteSysReg<SysReg SR, list<Register> Regs>
1176  : Pseudo<(outs), (ins GPR:$val),
1177           [(riscv_write_csr (XLenVT SR.Encoding), GPR:$val)]>,
1178    PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> {
1179  let hasSideEffects = 0;
1180  let Defs = Regs;
1181}
1182
1183class WriteSysRegImm<SysReg SR, list<Register> Regs>
1184  : Pseudo<(outs), (ins uimm5:$val),
1185           [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>,
1186    PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> {
1187  let hasSideEffects = 0;
1188  let Defs = Regs;
1189}
1190
1191class SwapSysReg<SysReg SR, list<Register> Regs>
1192  : Pseudo<(outs GPR:$rd), (ins GPR:$val),
1193           [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), GPR:$val))]>,
1194    PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> {
1195  let hasSideEffects = 0;
1196  let Uses = Regs;
1197  let Defs = Regs;
1198}
1199
1200class SwapSysRegImm<SysReg SR, list<Register> Regs>
1201  : Pseudo<(outs GPR:$rd), (ins uimm5:$val),
1202           [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val))]>,
1203    PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> {
1204  let hasSideEffects = 0;
1205  let Uses = Regs;
1206  let Defs = Regs;
1207}
1208
1209def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;
1210def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;
1211def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;
1212
1213/// Other pseudo-instructions
1214
1215// Pessimistically assume the stack pointer will be clobbered
1216let Defs = [X2], Uses = [X2] in {
1217def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1218                              [(callseq_start timm:$amt1, timm:$amt2)]>;
1219def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1220                              [(callseq_end timm:$amt1, timm:$amt2)]>;
1221} // Defs = [X2], Uses = [X2]
1222
1223/// RV64 patterns
1224
1225let Predicates = [IsRV64, NotHasStdExtZba] in {
1226def : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (SLLI GPR:$rs1, 32), 32)>;
1227
1228// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2
1229// shifts instead of 3. This can occur when unsigned is used to index an array.
1230def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1231          (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>;
1232}
1233
1234let Predicates = [IsRV64] in {
1235
1236/// sext and zext
1237
1238def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
1239
1240/// ALU operations
1241
1242def : Pat<(sext_inreg (add GPR:$rs1, GPR:$rs2), i32),
1243          (ADDW GPR:$rs1, GPR:$rs2)>;
1244def : Pat<(sext_inreg (add GPR:$rs1, simm12:$imm12), i32),
1245          (ADDIW GPR:$rs1, simm12:$imm12)>;
1246def : Pat<(sext_inreg (sub GPR:$rs1, GPR:$rs2), i32),
1247          (SUBW GPR:$rs1, GPR:$rs2)>;
1248def : Pat<(sext_inreg (shl GPR:$rs1, uimm5:$shamt), i32),
1249          (SLLIW GPR:$rs1, uimm5:$shamt)>;
1250def : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1251          (SRLIW GPR:$rs1, uimm5:$shamt)>;
1252def : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1253          (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
1254def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
1255          (SRAIW GPR:$rs1, uimm5:$shamt)>;
1256def : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1257          (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
1258
1259def : PatGprGpr<shiftopw<riscv_sllw>, SLLW>;
1260def : PatGprGpr<shiftopw<riscv_srlw>, SRLW>;
1261def : PatGprGpr<shiftopw<riscv_sraw>, SRAW>;
1262
1263/// Loads
1264
1265defm : LdPat<sextloadi32, LW, i64>;
1266defm : LdPat<extloadi32, LW, i64>;
1267defm : LdPat<zextloadi32, LWU, i64>;
1268defm : LdPat<load, LD, i64>;
1269
1270/// Stores
1271
1272defm : StPat<truncstorei32, SW, GPR, i64>;
1273defm : StPat<store, SD, GPR, i64>;
1274} // Predicates = [IsRV64]
1275
1276/// readcyclecounter
1277// On RV64, we can directly read the 64-bit "cycle" CSR.
1278let Predicates = [IsRV64] in
1279def : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, X0)>;
1280// On RV32, ReadCycleWide will be expanded to the suggested loop reading both
1281// halves of the 64-bit "cycle" CSR.
1282let Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in
1283def ReadCycleWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins),
1284                           [(set GPR:$lo, GPR:$hi, (riscv_read_cycle_wide))],
1285                           "", "">;
1286
1287/// traps
1288
1289// We lower `trap` to `unimp`, as this causes a hard exception on nearly all
1290// systems.
1291def : Pat<(trap), (UNIMP)>;
1292
1293// We lower `debugtrap` to `ebreak`, as this will get the attention of the
1294// debugger if possible.
1295def : Pat<(debugtrap), (EBREAK)>;
1296
1297/// Simple optimization
1298def : Pat<(add GPR:$rs1, (AddiPair:$rs2)),
1299          (ADDI (ADDI GPR:$rs1, (AddiPairImmB AddiPair:$rs2)),
1300                (AddiPairImmA GPR:$rs2))>;
1301
1302let Predicates = [IsRV64] in {
1303def : Pat<(sext_inreg (add_oneuse GPR:$rs1, (AddiPair:$rs2)), i32),
1304          (ADDIW (ADDIW GPR:$rs1, (AddiPairImmB AddiPair:$rs2)),
1305                 (AddiPairImmA AddiPair:$rs2))>;
1306}
1307
1308//===----------------------------------------------------------------------===//
1309// Standard extensions
1310//===----------------------------------------------------------------------===//
1311
1312include "RISCVInstrInfoM.td"
1313include "RISCVInstrInfoA.td"
1314include "RISCVInstrInfoF.td"
1315include "RISCVInstrInfoD.td"
1316include "RISCVInstrInfoC.td"
1317include "RISCVInstrInfoB.td"
1318include "RISCVInstrInfoV.td"
1319include "RISCVInstrInfoZfh.td"
1320