1//===-- RISCVInstrInfo.td - Target Description for RISC-V --*- 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                                             SDTCisVT<3, OtherVT>,
27                                             SDTCisSameAs<0, 4>,
28                                             SDTCisSameAs<4, 5>]>;
29def SDT_RISCVBrCC : SDTypeProfile<0, 4, [SDTCisSameAs<0, 1>,
30                                         SDTCisVT<2, OtherVT>,
31                                         SDTCisVT<3, OtherVT>]>;
32def SDT_RISCVReadCSR  : SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisInt<1>]>;
33def SDT_RISCVWriteCSR : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisInt<1>]>;
34def SDT_RISCVSwapCSR  : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisInt<1>,
35                                             SDTCisInt<2>]>;
36def SDT_RISCVReadCycleWide : SDTypeProfile<2, 0, [SDTCisVT<0, i32>,
37                                                  SDTCisVT<1, i32>]>;
38def SDT_RISCVIntUnaryOpW : SDTypeProfile<1, 1, [
39  SDTCisSameAs<0, 1>, SDTCisVT<0, i64>
40]>;
41def SDT_RISCVIntBinOpW : SDTypeProfile<1, 2, [
42  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>
43]>;
44def SDT_RISCVIntShiftDOpW : SDTypeProfile<1, 3, [
45  SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisVT<0, i64>, SDTCisVT<3, i64>
46]>;
47
48// Target-independent nodes, but with target-specific formats.
49def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
50                           [SDNPHasChain, SDNPOutGlue]>;
51def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
52                           [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
53
54// Target-dependent nodes.
55def riscv_call      : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
56                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
57                              SDNPVariadic]>;
58def riscv_ret_glue  : SDNode<"RISCVISD::RET_GLUE", SDTNone,
59                             [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
60def riscv_sret_glue : SDNode<"RISCVISD::SRET_GLUE", SDTNone,
61                             [SDNPHasChain, SDNPOptInGlue]>;
62def riscv_mret_glue : SDNode<"RISCVISD::MRET_GLUE", SDTNone,
63                             [SDNPHasChain, SDNPOptInGlue]>;
64def riscv_selectcc  : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC>;
65def riscv_brcc      : SDNode<"RISCVISD::BR_CC", SDT_RISCVBrCC,
66                             [SDNPHasChain]>;
67def riscv_tail      : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
68                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
69                              SDNPVariadic]>;
70def riscv_sllw      : SDNode<"RISCVISD::SLLW", SDT_RISCVIntBinOpW>;
71def riscv_sraw      : SDNode<"RISCVISD::SRAW", SDT_RISCVIntBinOpW>;
72def riscv_srlw      : SDNode<"RISCVISD::SRLW", SDT_RISCVIntBinOpW>;
73def riscv_read_csr  : SDNode<"RISCVISD::READ_CSR", SDT_RISCVReadCSR,
74                             [SDNPHasChain]>;
75def riscv_write_csr : SDNode<"RISCVISD::WRITE_CSR", SDT_RISCVWriteCSR,
76                             [SDNPHasChain]>;
77def riscv_swap_csr  : SDNode<"RISCVISD::SWAP_CSR", SDT_RISCVSwapCSR,
78                             [SDNPHasChain]>;
79
80def riscv_read_cycle_wide : SDNode<"RISCVISD::READ_CYCLE_WIDE",
81                                   SDT_RISCVReadCycleWide,
82                                   [SDNPHasChain, SDNPSideEffect]>;
83
84def riscv_add_lo : SDNode<"RISCVISD::ADD_LO", SDTIntBinOp>;
85def riscv_hi : SDNode<"RISCVISD::HI", SDTIntUnaryOp>;
86def riscv_lla : SDNode<"RISCVISD::LLA", SDTIntUnaryOp>;
87def riscv_add_tprel : SDNode<"RISCVISD::ADD_TPREL",
88                             SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
89                                                  SDTCisSameAs<0, 2>,
90                                                  SDTCisSameAs<0, 3>,
91                                                  SDTCisInt<0>]>>;
92
93//===----------------------------------------------------------------------===//
94// Operand and SDNode transformation definitions.
95//===----------------------------------------------------------------------===//
96
97class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
98  let Name = prefix # "ImmXLen" # suffix;
99  let RenderMethod = "addImmOperands";
100  let DiagnosticType = !strconcat("Invalid", Name);
101}
102
103class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
104  let Name = prefix # "Imm" # width # suffix;
105  let RenderMethod = "addImmOperands";
106  let DiagnosticType = !strconcat("Invalid", Name);
107}
108
109def ImmZeroAsmOperand : AsmOperandClass {
110  let Name = "ImmZero";
111  let RenderMethod = "addImmOperands";
112  let DiagnosticType = !strconcat("Invalid", Name);
113}
114
115// A parse method for (${gpr}) or 0(${gpr}), where the 0 is be silently ignored.
116def ZeroOffsetMemOpOperand : AsmOperandClass {
117  let Name = "ZeroOffsetMemOpOperand";
118  let RenderMethod = "addRegOperands";
119  let PredicateMethod = "isGPR";
120  let ParserMethod = "parseZeroOffsetMemOp";
121}
122
123class MemOperand<RegisterClass regClass> : RegisterOperand<regClass>{
124  let OperandType = "OPERAND_MEMORY";
125}
126
127def GPRMemZeroOffset : MemOperand<GPR> {
128  let ParserMatchClass = ZeroOffsetMemOpOperand;
129  let PrintMethod = "printZeroOffsetMemOp";
130}
131
132def GPRMem : MemOperand<GPR>;
133
134def SPMem : MemOperand<SP>;
135
136def GPRCMem : MemOperand<GPRC>;
137
138class SImmAsmOperand<int width, string suffix = "">
139    : ImmAsmOperand<"S", width, suffix> {
140}
141
142class UImmAsmOperand<int width, string suffix = "">
143    : ImmAsmOperand<"U", width, suffix> {
144}
145
146class RISCVOp<ValueType vt = XLenVT> : Operand<vt> {
147  let OperandNamespace = "RISCVOp";
148}
149
150class RISCVUImmOp<int bitsNum> : RISCVOp {
151  let ParserMatchClass = UImmAsmOperand<bitsNum>;
152  let DecoderMethod = "decodeUImmOperand<" # bitsNum # ">";
153  let OperandType = "OPERAND_UIMM" # bitsNum;
154}
155
156class RISCVUImmLeafOp<int bitsNum> :
157  RISCVUImmOp<bitsNum>, ImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);">;
158
159class RISCVSImmOp<int bitsNum> : RISCVOp {
160  let ParserMatchClass = SImmAsmOperand<bitsNum>;
161  let EncoderMethod = "getImmOpValue";
162  let DecoderMethod = "decodeSImmOperand<" # bitsNum # ">";
163  let OperandType = "OPERAND_SIMM" # bitsNum;
164}
165
166class RISCVSImmLeafOp<int bitsNum> :
167  RISCVSImmOp<bitsNum>, ImmLeaf<XLenVT, "return isInt<" # bitsNum # ">(Imm);">;
168
169def FenceArg : AsmOperandClass {
170  let Name = "FenceArg";
171  let RenderMethod = "addFenceArgOperands";
172  let ParserMethod = "parseFenceArg";
173}
174
175def fencearg : RISCVOp {
176  let ParserMatchClass = FenceArg;
177  let PrintMethod = "printFenceArg";
178  let DecoderMethod = "decodeUImmOperand<4>";
179  let OperandType = "OPERAND_UIMM4";
180}
181
182def UImmLog2XLenAsmOperand : AsmOperandClass {
183  let Name = "UImmLog2XLen";
184  let RenderMethod = "addImmOperands";
185  let DiagnosticType = "InvalidUImmLog2XLen";
186}
187
188def uimmlog2xlen : RISCVOp, ImmLeaf<XLenVT, [{
189  if (Subtarget->is64Bit())
190    return isUInt<6>(Imm);
191  return isUInt<5>(Imm);
192}]> {
193  let ParserMatchClass = UImmLog2XLenAsmOperand;
194  // TODO: should ensure invalid shamt is rejected when decoding.
195  let DecoderMethod = "decodeUImmOperand<6>";
196  let MCOperandPredicate = [{
197    int64_t Imm;
198    if (!MCOp.evaluateAsConstantImm(Imm))
199      return false;
200    if (STI.getTargetTriple().isArch64Bit())
201      return isUInt<6>(Imm);
202    return isUInt<5>(Imm);
203  }];
204  let OperandType = "OPERAND_UIMMLOG2XLEN";
205}
206
207def InsnDirectiveOpcode : AsmOperandClass {
208  let Name = "InsnDirectiveOpcode";
209  let ParserMethod = "parseInsnDirectiveOpcode";
210  let RenderMethod = "addImmOperands";
211  let PredicateMethod = "isImm";
212}
213
214def uimm1 : RISCVUImmLeafOp<1>;
215def uimm2 : RISCVUImmLeafOp<2> {
216  let MCOperandPredicate = [{
217    int64_t Imm;
218    if (!MCOp.evaluateAsConstantImm(Imm))
219      return false;
220    return isUInt<2>(Imm);
221  }];
222}
223def uimm3 : RISCVUImmOp<3>;
224def uimm4 : RISCVUImmOp<4>;
225def uimm5 : RISCVUImmLeafOp<5>;
226def uimm6 : RISCVUImmLeafOp<6>;
227def uimm7_opcode : RISCVUImmOp<7> {
228  let ParserMatchClass = InsnDirectiveOpcode;
229}
230def uimm7 : RISCVUImmOp<7>;
231def uimm8 : RISCVUImmOp<8>;
232def simm12 : RISCVSImmLeafOp<12> {
233  let MCOperandPredicate = [{
234    int64_t Imm;
235    if (MCOp.evaluateAsConstantImm(Imm))
236      return isInt<12>(Imm);
237    return MCOp.isBareSymbolRef();
238  }];
239}
240
241// A 12-bit signed immediate which cannot fit in 6-bit signed immediate,
242// but even negative value fit in 12-bit.
243def simm12_no6 : ImmLeaf<XLenVT, [{
244  return isInt<12>(Imm) && !isInt<6>(Imm) && isInt<12>(-Imm);}]>;
245
246// A 13-bit signed immediate where the least significant bit is zero.
247def simm13_lsb0 : Operand<OtherVT> {
248  let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
249  let PrintMethod = "printBranchOperand";
250  let EncoderMethod = "getImmOpValueAsr1";
251  let DecoderMethod = "decodeSImmOperandAndLsl1<13>";
252  let MCOperandPredicate = [{
253    int64_t Imm;
254    if (MCOp.evaluateAsConstantImm(Imm))
255      return isShiftedInt<12, 1>(Imm);
256    return MCOp.isBareSymbolRef();
257  }];
258  let OperandType = "OPERAND_PCREL";
259}
260
261class UImm20Operand : RISCVOp {
262  let EncoderMethod = "getImmOpValue";
263  let DecoderMethod = "decodeUImmOperand<20>";
264  let OperandType = "OPERAND_UIMM20";
265}
266
267class UImm20OperandMaybeSym : UImm20Operand {
268  let MCOperandPredicate = [{
269    int64_t Imm;
270    if (MCOp.evaluateAsConstantImm(Imm))
271      return isUInt<20>(Imm);
272    return MCOp.isBareSymbolRef();
273  }];
274}
275
276def uimm20_lui : UImm20OperandMaybeSym {
277  let ParserMatchClass = UImmAsmOperand<20, "LUI">;
278}
279def uimm20_auipc : UImm20OperandMaybeSym {
280  let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;
281}
282
283def uimm20 : UImm20Operand {
284  let ParserMatchClass = UImmAsmOperand<20>;
285  let MCOperandPredicate = [{
286    int64_t Imm;
287    if (!MCOp.evaluateAsConstantImm(Imm))
288      return false;
289    return isUInt<20>(Imm);
290  }];
291}
292
293def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> {
294  let ParserMethod = "parseJALOffset";
295}
296
297// A 21-bit signed immediate where the least significant bit is zero.
298def simm21_lsb0_jal : Operand<OtherVT> {
299  let ParserMatchClass = Simm21Lsb0JALAsmOperand;
300  let PrintMethod = "printBranchOperand";
301  let EncoderMethod = "getImmOpValueAsr1";
302  let DecoderMethod = "decodeSImmOperandAndLsl1<21>";
303  let MCOperandPredicate = [{
304    int64_t Imm;
305    if (MCOp.evaluateAsConstantImm(Imm))
306      return isShiftedInt<20, 1>(Imm);
307    return MCOp.isBareSymbolRef();
308  }];
309  let OperandType = "OPERAND_PCREL";
310}
311
312def BareSymbol : AsmOperandClass {
313  let Name = "BareSymbol";
314  let RenderMethod = "addImmOperands";
315  let DiagnosticType = "InvalidBareSymbol";
316  let ParserMethod = "parseBareSymbol";
317}
318
319// A bare symbol.
320def bare_symbol : Operand<XLenVT> {
321  let ParserMatchClass = BareSymbol;
322}
323
324def CallSymbol : AsmOperandClass {
325  let Name = "CallSymbol";
326  let RenderMethod = "addImmOperands";
327  let DiagnosticType = "InvalidCallSymbol";
328  let ParserMethod = "parseCallSymbol";
329}
330
331// A bare symbol used in call/tail only.
332def call_symbol : Operand<XLenVT> {
333  let ParserMatchClass = CallSymbol;
334}
335
336def PseudoJumpSymbol : AsmOperandClass {
337  let Name = "PseudoJumpSymbol";
338  let RenderMethod = "addImmOperands";
339  let DiagnosticType = "InvalidPseudoJumpSymbol";
340  let ParserMethod = "parsePseudoJumpSymbol";
341}
342
343// A bare symbol used for pseudo jumps only.
344def pseudo_jump_symbol : Operand<XLenVT> {
345  let ParserMatchClass = PseudoJumpSymbol;
346}
347
348def TPRelAddSymbol : AsmOperandClass {
349  let Name = "TPRelAddSymbol";
350  let RenderMethod = "addImmOperands";
351  let DiagnosticType = "InvalidTPRelAddSymbol";
352  let ParserMethod = "parseOperandWithModifier";
353}
354
355// A bare symbol with the %tprel_add variant.
356def tprel_add_symbol : Operand<XLenVT> {
357  let ParserMatchClass = TPRelAddSymbol;
358}
359
360def CSRSystemRegister : AsmOperandClass {
361  let Name = "CSRSystemRegister";
362  let ParserMethod = "parseCSRSystemRegister";
363  let DiagnosticType = "InvalidCSRSystemRegister";
364}
365
366def csr_sysreg : RISCVOp {
367  let ParserMatchClass = CSRSystemRegister;
368  let PrintMethod = "printCSRSystemRegister";
369  let DecoderMethod = "decodeUImmOperand<12>";
370  let OperandType = "OPERAND_UIMM12";
371}
372
373// A parameterized register class alternative to i32imm/i64imm from Target.td.
374def ixlenimm : Operand<XLenVT>;
375
376def ixlenimm_li : Operand<XLenVT> {
377  let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;
378}
379
380// Accepts subset of LI operands, used by LAImm and LLAImm
381def ixlenimm_li_restricted : Operand<XLenVT> {
382  let ParserMatchClass = ImmXLenAsmOperand<"", "LI_Restricted">;
383}
384
385// Standalone (codegen-only) immleaf patterns.
386
387// A 6-bit constant greater than 32.
388def uimm6gt32 : ImmLeaf<XLenVT, [{
389  return isUInt<6>(Imm) && Imm > 32;
390}]>;
391
392// Addressing modes.
393// Necessary because a frameindex can't be matched directly in a pattern.
394def FrameAddrRegImm : ComplexPattern<iPTR, 2, "SelectFrameAddrRegImm",
395                                     [frameindex, or, add]>;
396def AddrRegImm : ComplexPattern<iPTR, 2, "SelectAddrRegImm">;
397
398// Return the negation of an immediate value.
399def NegImm : SDNodeXForm<imm, [{
400  return CurDAG->getTargetConstant(-N->getSExtValue(), SDLoc(N),
401                                   N->getValueType(0));
402}]>;
403
404// Return an immediate value minus 32.
405def ImmSub32 : SDNodeXForm<imm, [{
406  return CurDAG->getTargetConstant(N->getSExtValue() - 32, SDLoc(N),
407                                   N->getValueType(0));
408}]>;
409
410// Return an immediate subtracted from XLen.
411def ImmSubFromXLen : SDNodeXForm<imm, [{
412  uint64_t XLen = Subtarget->getXLen();
413  return CurDAG->getTargetConstant(XLen - N->getZExtValue(), SDLoc(N),
414                                   N->getValueType(0));
415}]>;
416
417// Return an immediate subtracted from 32.
418def ImmSubFrom32 : SDNodeXForm<imm, [{
419  return CurDAG->getTargetConstant(32 - N->getZExtValue(), SDLoc(N),
420                                   N->getValueType(0));
421}]>;
422
423// Check if (add r, imm) can be optimized to (ADDI (ADDI r, imm0), imm1),
424// in which imm = imm0 + imm1 and both imm0 and imm1 are simm12. We make imm0
425// as large as possible and imm1 as small as possible so that we might be able
426// to use c.addi for the small immediate.
427def AddiPair : PatLeaf<(imm), [{
428  if (!N->hasOneUse())
429    return false;
430  // The immediate operand must be in range [-4096,-2049] or [2048,4094].
431  int64_t Imm = N->getSExtValue();
432  return (-4096 <= Imm && Imm <= -2049) || (2048 <= Imm && Imm <= 4094);
433}]>;
434
435// Return imm - (imm < 0 ? -2048 : 2047).
436def AddiPairImmSmall : SDNodeXForm<imm, [{
437  int64_t Imm = N->getSExtValue();
438  int64_t Adj = N->getSExtValue() < 0 ? -2048 : 2047;
439  return CurDAG->getTargetConstant(Imm - Adj, SDLoc(N),
440                                   N->getValueType(0));
441}]>;
442
443// Return -2048 if immediate is negative or 2047 if positive. These are the
444// largest simm12 values.
445def AddiPairImmLarge : SDNodeXForm<imm, [{
446  int64_t Imm = N->getSExtValue() < 0 ? -2048 : 2047;
447  return CurDAG->getTargetConstant(Imm, SDLoc(N),
448                                   N->getValueType(0));
449}]>;
450
451def TrailingZeros : SDNodeXForm<imm, [{
452  return CurDAG->getTargetConstant(llvm::countr_zero(N->getZExtValue()),
453                                   SDLoc(N), N->getValueType(0));
454}]>;
455
456def XLenSubTrailingOnes : SDNodeXForm<imm, [{
457  uint64_t XLen = Subtarget->getXLen();
458  uint64_t TrailingOnes = llvm::countr_one(N->getZExtValue());
459  return CurDAG->getTargetConstant(XLen - TrailingOnes, SDLoc(N),
460                                   N->getValueType(0));
461}]>;
462
463// Checks if this mask is a non-empty sequence of ones starting at the
464// most/least significant bit with the remainder zero and exceeds simm32/simm12.
465def LeadingOnesMask : PatLeaf<(imm), [{
466  if (!N->hasOneUse())
467    return false;
468  return !isInt<32>(N->getSExtValue()) && isMask_64(~N->getSExtValue());
469}], TrailingZeros>;
470
471def TrailingOnesMask : PatLeaf<(imm), [{
472  if (!N->hasOneUse())
473    return false;
474  return !isInt<12>(N->getSExtValue()) && isMask_64(N->getZExtValue());
475}], XLenSubTrailingOnes>;
476
477// Similar to LeadingOnesMask, but only consider leading ones in the lower 32
478// bits.
479def LeadingOnesWMask : PatLeaf<(imm), [{
480  if (!N->hasOneUse())
481    return false;
482  // If the value is a uint32 but not an int32, it must have bit 31 set and
483  // bits 63:32 cleared. After that we're looking for a shifted mask but not
484  // an all ones mask.
485  int64_t Imm = N->getSExtValue();
486  return !isInt<32>(Imm) && isUInt<32>(Imm) && isShiftedMask_64(Imm) &&
487         Imm != UINT64_C(0xffffffff);
488}], TrailingZeros>;
489
490//===----------------------------------------------------------------------===//
491// Instruction Formats
492//===----------------------------------------------------------------------===//
493
494include "RISCVInstrFormats.td"
495
496//===----------------------------------------------------------------------===//
497// Instruction Class Templates
498//===----------------------------------------------------------------------===//
499
500let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
501class BranchCC_rri<bits<3> funct3, string opcodestr>
502    : RVInstB<funct3, OPC_BRANCH, (outs),
503              (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12),
504              opcodestr, "$rs1, $rs2, $imm12">,
505      Sched<[WriteJmp, ReadJmp, ReadJmp]> {
506  let isBranch = 1;
507  let isTerminator = 1;
508}
509
510let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
511class Load_ri<bits<3> funct3, string opcodestr>
512    : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPRMem:$rs1, simm12:$imm12),
513              opcodestr, "$rd, ${imm12}(${rs1})">;
514
515class HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr>
516    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs GPR:$rd),
517              (ins GPRMemZeroOffset:$rs1), opcodestr, "$rd, $rs1"> {
518  let rs2 = funct5;
519}
520}
521
522// Operands for stores are in the order srcreg, base, offset rather than
523// reflecting the order these fields are specified in the instruction
524// encoding.
525let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
526class Store_rri<bits<3> funct3, string opcodestr>
527    : RVInstS<funct3, OPC_STORE, (outs),
528              (ins GPR:$rs2, GPRMem:$rs1, simm12:$imm12),
529              opcodestr, "$rs2, ${imm12}(${rs1})">;
530
531class HStore_rr<bits<7> funct7, string opcodestr>
532    : RVInstR<funct7, 0b100, OPC_SYSTEM, (outs),
533              (ins GPR:$rs2, GPRMemZeroOffset:$rs1),
534               opcodestr, "$rs2, $rs1"> {
535  let rd = 0;
536}
537}
538
539let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
540class ALU_ri<bits<3> funct3, string opcodestr>
541    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
542              opcodestr, "$rd, $rs1, $imm12">,
543      Sched<[WriteIALU, ReadIALU]>;
544
545let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
546class Shift_ri<bits<5> imm11_7, bits<3> funct3, string opcodestr>
547    : RVInstIShift<imm11_7, funct3, OPC_OP_IMM, (outs GPR:$rd),
548                   (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
549                   "$rd, $rs1, $shamt">,
550      Sched<[WriteShiftImm, ReadShiftImm]>;
551
552let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
553class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
554             bit Commutable = 0>
555    : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
556              opcodestr, "$rd, $rs1, $rs2"> {
557  let isCommutable = Commutable;
558}
559
560let hasNoSchedulingInfo = 1,
561    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
562class CSR_ir<bits<3> funct3, string opcodestr>
563    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),
564              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>;
565
566let hasNoSchedulingInfo = 1,
567    hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
568class CSR_ii<bits<3> funct3, string opcodestr>
569    : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),
570              (ins csr_sysreg:$imm12, uimm5:$rs1),
571              opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR]>;
572
573let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
574class ShiftW_ri<bits<7> imm11_5, bits<3> funct3, string opcodestr>
575    : RVInstIShiftW<imm11_5, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
576                    (ins GPR:$rs1, uimm5:$shamt), opcodestr,
577                    "$rd, $rs1, $shamt">,
578      Sched<[WriteShiftImm32, ReadShiftImm32]>;
579
580let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
581class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr,
582              bit Commutable = 0>
583    : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
584              (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
585  let isCommutable = Commutable;
586}
587
588let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
589class Priv<string opcodestr, bits<7> funct7>
590    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
591              opcodestr, "">;
592
593let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
594class Priv_rr<string opcodestr, bits<7> funct7>
595    : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
596              opcodestr, "$rs1, $rs2"> {
597  let rd = 0;
598}
599
600//===----------------------------------------------------------------------===//
601// Instructions
602//===----------------------------------------------------------------------===//
603
604let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
605let isReMaterializable = 1, isAsCheapAsAMove = 1,
606    IsSignExtendingOpW = 1 in
607def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
608                  "lui", "$rd, $imm20">, Sched<[WriteIALU]>;
609
610def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20),
611                    "auipc", "$rd, $imm20">, Sched<[WriteIALU]>;
612
613def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20),
614                  "jal", "$rd, $imm20">, Sched<[WriteJal]>;
615
616def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),
617                   (ins GPR:$rs1, simm12:$imm12),
618                   "jalr", "$rd, ${imm12}(${rs1})">,
619           Sched<[WriteJalr, ReadJalr]>;
620} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
621
622def BEQ  : BranchCC_rri<0b000, "beq">;
623def BNE  : BranchCC_rri<0b001, "bne">;
624def BLT  : BranchCC_rri<0b100, "blt">;
625def BGE  : BranchCC_rri<0b101, "bge">;
626def BLTU : BranchCC_rri<0b110, "bltu">;
627def BGEU : BranchCC_rri<0b111, "bgeu">;
628
629let IsSignExtendingOpW = 1 in {
630def LB  : Load_ri<0b000, "lb">, Sched<[WriteLDB, ReadMemBase]>;
631def LH  : Load_ri<0b001, "lh">, Sched<[WriteLDH, ReadMemBase]>;
632def LW  : Load_ri<0b010, "lw">, Sched<[WriteLDW, ReadMemBase]>;
633def LBU : Load_ri<0b100, "lbu">, Sched<[WriteLDB, ReadMemBase]>;
634def LHU : Load_ri<0b101, "lhu">, Sched<[WriteLDH, ReadMemBase]>;
635}
636
637def SB : Store_rri<0b000, "sb">, Sched<[WriteSTB, ReadStoreData, ReadMemBase]>;
638def SH : Store_rri<0b001, "sh">, Sched<[WriteSTH, ReadStoreData, ReadMemBase]>;
639def SW : Store_rri<0b010, "sw">, Sched<[WriteSTW, ReadStoreData, ReadMemBase]>;
640
641// ADDI isn't always rematerializable, but isReMaterializable will be used as
642// a hint which is verified in isReallyTriviallyReMaterializable.
643let isReMaterializable = 1, isAsCheapAsAMove = 1 in
644def ADDI  : ALU_ri<0b000, "addi">;
645
646let IsSignExtendingOpW = 1 in {
647def SLTI  : ALU_ri<0b010, "slti">;
648def SLTIU : ALU_ri<0b011, "sltiu">;
649}
650
651let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
652def XORI  : ALU_ri<0b100, "xori">;
653def ORI   : ALU_ri<0b110, "ori">;
654}
655
656def ANDI  : ALU_ri<0b111, "andi">;
657
658def SLLI : Shift_ri<0b00000, 0b001, "slli">;
659def SRLI : Shift_ri<0b00000, 0b101, "srli">;
660def SRAI : Shift_ri<0b01000, 0b101, "srai">;
661
662def ADD  : ALU_rr<0b0000000, 0b000, "add", Commutable=1>,
663           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
664def SUB  : ALU_rr<0b0100000, 0b000, "sub">,
665           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
666def SLL  : ALU_rr<0b0000000, 0b001, "sll">,
667           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
668let IsSignExtendingOpW = 1 in {
669def SLT  : ALU_rr<0b0000000, 0b010, "slt">,
670           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
671def SLTU : ALU_rr<0b0000000, 0b011, "sltu">,
672           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
673}
674def XOR  : ALU_rr<0b0000000, 0b100, "xor", Commutable=1>,
675           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
676def SRL  : ALU_rr<0b0000000, 0b101, "srl">,
677           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
678def SRA  : ALU_rr<0b0100000, 0b101, "sra">,
679           Sched<[WriteShiftReg, ReadShiftReg, ReadShiftReg]>;
680def OR   : ALU_rr<0b0000000, 0b110, "or", Commutable=1>,
681           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
682def AND  : ALU_rr<0b0000000, 0b111, "and", Commutable=1>,
683           Sched<[WriteIALU, ReadIALU, ReadIALU]>;
684
685let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
686def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),
687                    (ins fencearg:$pred, fencearg:$succ),
688                    "fence", "$pred, $succ">, Sched<[]> {
689  bits<4> pred;
690  bits<4> succ;
691
692  let rs1 = 0;
693  let rd = 0;
694  let imm12 = {0b0000,pred,succ};
695}
696
697def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", "">, Sched<[]> {
698  let rs1 = 0;
699  let rd = 0;
700  let imm12 = {0b1000,0b0011,0b0011};
701}
702
703def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> {
704  let rs1 = 0;
705  let rd = 0;
706  let imm12 = 0;
707}
708
709def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", "">, Sched<[WriteJmp]> {
710  let rs1 = 0;
711  let rd = 0;
712  let imm12 = 0;
713}
714
715def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", "">,
716             Sched<[]> {
717  let rs1 = 0;
718  let rd = 0;
719  let imm12 = 1;
720}
721
722// This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
723// instruction (i.e., it should always trap, if your implementation has invalid
724// instruction traps).
725def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">,
726            Sched<[]> {
727  let rs1 = 0;
728  let rd = 0;
729  let imm12 = 0b110000000000;
730}
731
732} // hasSideEffects = 1, mayLoad = 0, mayStore = 0
733
734def CSRRW : CSR_ir<0b001, "csrrw">;
735def CSRRS : CSR_ir<0b010, "csrrs">;
736def CSRRC : CSR_ir<0b011, "csrrc">;
737
738def CSRRWI : CSR_ii<0b101, "csrrwi">;
739def CSRRSI : CSR_ii<0b110, "csrrsi">;
740def CSRRCI : CSR_ii<0b111, "csrrci">;
741
742/// RV64I instructions
743
744let Predicates = [IsRV64] in {
745def LWU   : Load_ri<0b110, "lwu">, Sched<[WriteLDW, ReadMemBase]>;
746def LD    : Load_ri<0b011, "ld">, Sched<[WriteLDD, ReadMemBase]>;
747def SD    : Store_rri<0b011, "sd">, Sched<[WriteSTD, ReadStoreData, ReadMemBase]>;
748
749let IsSignExtendingOpW = 1 in {
750let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
751def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
752                    (ins GPR:$rs1, simm12:$imm12),
753                    "addiw", "$rd, $rs1, $imm12">,
754            Sched<[WriteIALU32, ReadIALU32]>;
755
756def SLLIW : ShiftW_ri<0b0000000, 0b001, "slliw">;
757def SRLIW : ShiftW_ri<0b0000000, 0b101, "srliw">;
758def SRAIW : ShiftW_ri<0b0100000, 0b101, "sraiw">;
759
760def ADDW  : ALUW_rr<0b0000000, 0b000, "addw", Commutable=1>,
761            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
762def SUBW  : ALUW_rr<0b0100000, 0b000, "subw">,
763            Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>;
764def SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">,
765            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
766def SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">,
767            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
768def SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">,
769            Sched<[WriteShiftReg32, ReadShiftReg32, ReadShiftReg32]>;
770} // IsSignExtendingOpW = 1
771} // Predicates = [IsRV64]
772
773//===----------------------------------------------------------------------===//
774// Privileged instructions
775//===----------------------------------------------------------------------===//
776
777let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
778def SRET : Priv<"sret", 0b0001000>, Sched<[]> {
779  let rd = 0;
780  let rs1 = 0;
781  let rs2 = 0b00010;
782}
783
784def MRET : Priv<"mret", 0b0011000>, Sched<[]> {
785  let rd = 0;
786  let rs1 = 0;
787  let rs2 = 0b00010;
788}
789} // isBarrier = 1, isReturn = 1, isTerminator = 1
790
791def WFI : Priv<"wfi", 0b0001000>, Sched<[]> {
792  let rd = 0;
793  let rs1 = 0;
794  let rs2 = 0b00101;
795}
796
797let Predicates = [HasStdExtSvinval] in {
798def SFENCE_W_INVAL : Priv<"sfence.w.inval", 0b0001100>, Sched<[]> {
799  let rd = 0;
800  let rs1 = 0;
801  let rs2 = 0;
802}
803
804def SFENCE_INVAL_IR : Priv<"sfence.inval.ir", 0b0001100>, Sched<[]> {
805  let rd = 0;
806  let rs1 = 0;
807  let rs2 = 0b00001;
808}
809def SINVAL_VMA  : Priv_rr<"sinval.vma", 0b0001011>, Sched<[]>;
810def HINVAL_VVMA : Priv_rr<"hinval.vvma", 0b0010011>, Sched<[]>;
811def HINVAL_GVMA : Priv_rr<"hinval.gvma", 0b0110011>, Sched<[]>;
812} // Predicates = [HasStdExtSvinval]
813
814def SFENCE_VMA  : Priv_rr<"sfence.vma", 0b0001001>, Sched<[]>;
815
816let Predicates = [HasStdExtH] in {
817def HFENCE_VVMA : Priv_rr<"hfence.vvma", 0b0010001>, Sched<[]>;
818def HFENCE_GVMA : Priv_rr<"hfence.gvma", 0b0110001>, Sched<[]>;
819
820def HLV_B   : HLoad_r<0b0110000, 0b00000, "hlv.b">, Sched<[]>;
821def HLV_BU  : HLoad_r<0b0110000, 0b00001, "hlv.bu">, Sched<[]>;
822def HLV_H   : HLoad_r<0b0110010, 0b00000, "hlv.h">, Sched<[]>;
823def HLV_HU  : HLoad_r<0b0110010, 0b00001, "hlv.hu">, Sched<[]>;
824def HLVX_HU : HLoad_r<0b0110010, 0b00011, "hlvx.hu">, Sched<[]>;
825def HLV_W   : HLoad_r<0b0110100, 0b00000, "hlv.w">, Sched<[]>;
826def HLVX_WU : HLoad_r<0b0110100, 0b00011, "hlvx.wu">, Sched<[]>;
827def HSV_B   : HStore_rr<0b0110001, "hsv.b">, Sched<[]>;
828def HSV_H   : HStore_rr<0b0110011, "hsv.h">, Sched<[]>;
829def HSV_W   : HStore_rr<0b0110101, "hsv.w">, Sched<[]>;
830}
831let Predicates = [IsRV64, HasStdExtH] in {
832def HLV_WU  : HLoad_r<0b0110100, 0b00001, "hlv.wu">, Sched<[]>;
833def HLV_D   : HLoad_r<0b0110110, 0b00000, "hlv.d">, Sched<[]>;
834def HSV_D   : HStore_rr<0b0110111, "hsv.d">, Sched<[]>;
835}
836
837//===----------------------------------------------------------------------===//
838// Debug instructions
839//===----------------------------------------------------------------------===//
840
841let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
842def DRET : Priv<"dret", 0b0111101>, Sched<[]> {
843  let rd = 0;
844  let rs1 = 0;
845  let rs2 = 0b10010;
846}
847} // isBarrier = 1, isReturn = 1, isTerminator = 1
848
849//===----------------------------------------------------------------------===//
850// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
851//===----------------------------------------------------------------------===//
852
853def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
854
855// Note that the size is 32 because up to 8 32-bit instructions are needed to
856// generate an arbitrary 64-bit immediate. However, the size does not really
857// matter since PseudoLI is currently only used in the AsmParser where it gets
858// expanded to real instructions immediately.
859let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
860    isCodeGenOnly = 0, isAsmParserOnly = 1 in
861def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
862                      "li", "$rd, $imm">;
863
864def PseudoLB  : PseudoLoad<"lb">;
865def PseudoLBU : PseudoLoad<"lbu">;
866def PseudoLH  : PseudoLoad<"lh">;
867def PseudoLHU : PseudoLoad<"lhu">;
868def PseudoLW  : PseudoLoad<"lw">;
869
870def PseudoSB  : PseudoStore<"sb">;
871def PseudoSH  : PseudoStore<"sh">;
872def PseudoSW  : PseudoStore<"sw">;
873
874let Predicates = [IsRV64] in {
875def PseudoLWU : PseudoLoad<"lwu">;
876def PseudoLD  : PseudoLoad<"ld">;
877def PseudoSD  : PseudoStore<"sd">;
878} // Predicates = [IsRV64]
879
880def : InstAlias<"li $rd, $imm",  (ADDI GPR:$rd, X0, simm12:$imm)>;
881def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
882def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
883def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
884
885let Predicates = [IsRV64] in {
886def : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;
887def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;
888} // Predicates = [IsRV64]
889
890def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;
891def : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;
892def : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;
893def : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;
894
895// sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu
896// form will always be printed. Therefore, set a zero weight.
897def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;
898def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;
899
900def : InstAlias<"beqz $rs, $offset",
901                (BEQ GPR:$rs,      X0, simm13_lsb0:$offset)>;
902def : InstAlias<"bnez $rs, $offset",
903                (BNE GPR:$rs,      X0, simm13_lsb0:$offset)>;
904def : InstAlias<"blez $rs, $offset",
905                (BGE      X0, GPR:$rs, simm13_lsb0:$offset)>;
906def : InstAlias<"bgez $rs, $offset",
907                (BGE GPR:$rs,      X0, simm13_lsb0:$offset)>;
908def : InstAlias<"bltz $rs, $offset",
909                (BLT GPR:$rs,      X0, simm13_lsb0:$offset)>;
910def : InstAlias<"bgtz $rs, $offset",
911                (BLT      X0, GPR:$rs, simm13_lsb0:$offset)>;
912
913// Always output the canonical mnemonic for the pseudo branch instructions.
914// The GNU tools emit the canonical mnemonic for the branch pseudo instructions
915// as well (e.g. "bgt" will be recognised by the assembler but never printed by
916// objdump). Match this behaviour by setting a zero weight.
917def : InstAlias<"bgt $rs, $rt, $offset",
918                (BLT  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
919def : InstAlias<"ble $rs, $rt, $offset",
920                (BGE  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
921def : InstAlias<"bgtu $rs, $rt, $offset",
922                (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
923def : InstAlias<"bleu $rs, $rt, $offset",
924                (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
925
926def : InstAlias<"j $offset",   (JAL X0, simm21_lsb0_jal:$offset)>;
927def : InstAlias<"jal $offset", (JAL X1, simm21_lsb0_jal:$offset)>;
928
929// Non-zero offset aliases of "jalr" are the lowest weight, followed by the
930// two-register form, then the one-register forms and finally "ret".
931def : InstAlias<"jr $rs",                (JALR      X0, GPR:$rs, 0), 3>;
932def : InstAlias<"jr ${offset}(${rs})",   (JALR      X0, GPR:$rs, simm12:$offset)>;
933def : InstAlias<"jalr $rs",              (JALR      X1, GPR:$rs, 0), 3>;
934def : InstAlias<"jalr ${offset}(${rs})", (JALR      X1, GPR:$rs, simm12:$offset)>;
935def : InstAlias<"jalr $rd, $rs",         (JALR GPR:$rd, GPR:$rs, 0), 2>;
936def : InstAlias<"ret",                   (JALR      X0,      X1, 0), 4>;
937
938// Non-canonical forms for jump targets also accepted by the assembler.
939def : InstAlias<"jr $rs, $offset",        (JALR      X0, GPR:$rs, simm12:$offset), 0>;
940def : InstAlias<"jalr $rs, $offset",      (JALR      X1, GPR:$rs, simm12:$offset), 0>;
941def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset), 0>;
942
943def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
944
945let Predicates = [HasStdExtZihintpause] in
946def : InstAlias<"pause", (FENCE 0x1, 0x0)>; // 0x1 == w
947
948def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>;
949def : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, CYCLE.Encoding, X0)>;
950def : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, TIME.Encoding, X0)>;
951
952let Predicates = [IsRV32] in {
953def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, INSTRETH.Encoding, X0)>;
954def : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, CYCLEH.Encoding, X0)>;
955def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, TIMEH.Encoding, X0)>;
956} // Predicates = [IsRV32]
957
958def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;
959def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;
960def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;
961def : InstAlias<"csrc $csr, $rs", (CSRRC      X0, csr_sysreg:$csr, GPR:$rs)>;
962
963def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
964def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
965def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
966
967let EmitPriority = 0 in {
968def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
969def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
970def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
971
972def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
973def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
974def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
975}
976
977def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
978def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
979
980def : InstAlias<"hfence.gvma",     (HFENCE_GVMA      X0, X0)>;
981def : InstAlias<"hfence.gvma $rs", (HFENCE_GVMA GPR:$rs, X0)>;
982
983def : InstAlias<"hfence.vvma",     (HFENCE_VVMA      X0, X0)>;
984def : InstAlias<"hfence.vvma $rs", (HFENCE_VVMA GPR:$rs, X0)>;
985
986let Predicates = [HasStdExtZihintntl] in {
987  def : InstAlias<"ntl.p1",     (ADD   X0, X0, X2)>;
988  def : InstAlias<"ntl.pall",   (ADD   X0, X0, X3)>;
989  def : InstAlias<"ntl.s1",     (ADD   X0, X0, X4)>;
990  def : InstAlias<"ntl.all",    (ADD   X0, X0, X5)>;
991} // Predicates = [HasStdExtZihintntl]
992
993let EmitPriority = 0 in {
994def : InstAlias<"lb $rd, (${rs1})",
995                (LB  GPR:$rd, GPR:$rs1, 0)>;
996def : InstAlias<"lh $rd, (${rs1})",
997                (LH  GPR:$rd, GPR:$rs1, 0)>;
998def : InstAlias<"lw $rd, (${rs1})",
999                (LW  GPR:$rd, GPR:$rs1, 0)>;
1000def : InstAlias<"lbu $rd, (${rs1})",
1001                (LBU  GPR:$rd, GPR:$rs1, 0)>;
1002def : InstAlias<"lhu $rd, (${rs1})",
1003                (LHU  GPR:$rd, GPR:$rs1, 0)>;
1004
1005def : InstAlias<"sb $rs2, (${rs1})",
1006                (SB  GPR:$rs2, GPR:$rs1, 0)>;
1007def : InstAlias<"sh $rs2, (${rs1})",
1008                (SH  GPR:$rs2, GPR:$rs1, 0)>;
1009def : InstAlias<"sw $rs2, (${rs1})",
1010                (SW  GPR:$rs2, GPR:$rs1, 0)>;
1011
1012def : InstAlias<"add $rd, $rs1, $imm12",
1013                (ADDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1014def : InstAlias<"and $rd, $rs1, $imm12",
1015                (ANDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1016def : InstAlias<"xor $rd, $rs1, $imm12",
1017                (XORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1018def : InstAlias<"or $rd, $rs1, $imm12",
1019                (ORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1020def : InstAlias<"sll $rd, $rs1, $shamt",
1021                (SLLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
1022def : InstAlias<"srl $rd, $rs1, $shamt",
1023                (SRLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
1024def : InstAlias<"sra $rd, $rs1, $shamt",
1025                (SRAI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
1026let Predicates = [IsRV64] in {
1027def : InstAlias<"lwu $rd, (${rs1})",
1028                (LWU  GPR:$rd, GPR:$rs1, 0)>;
1029def : InstAlias<"ld $rd, (${rs1})",
1030                (LD  GPR:$rd, GPR:$rs1, 0)>;
1031def : InstAlias<"sd $rs2, (${rs1})",
1032                (SD  GPR:$rs2, GPR:$rs1, 0)>;
1033
1034def : InstAlias<"addw $rd, $rs1, $imm12",
1035                (ADDIW  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1036def : InstAlias<"sllw $rd, $rs1, $shamt",
1037                (SLLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
1038def : InstAlias<"srlw $rd, $rs1, $shamt",
1039                (SRLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
1040def : InstAlias<"sraw $rd, $rs1, $shamt",
1041                (SRAIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
1042} // Predicates = [IsRV64]
1043def : InstAlias<"slt $rd, $rs1, $imm12",
1044                (SLTI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1045def : InstAlias<"sltu $rd, $rs1, $imm12",
1046                (SLTIU  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
1047}
1048
1049def : MnemonicAlias<"move", "mv">;
1050
1051// The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in
1052// version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept
1053// the old name for backwards compatibility.
1054def : MnemonicAlias<"scall", "ecall">;
1055def : MnemonicAlias<"sbreak", "ebreak">;
1056
1057// This alias was added to the spec in December 2020. Don't print it by default
1058// to allow assembly we print to be compatible with versions of GNU assembler
1059// that don't support this alias.
1060def : InstAlias<"zext.b $rd, $rs", (ANDI GPR:$rd, GPR:$rs, 0xFF), 0>;
1061
1062let Predicates = [HasStdExtZicfilp] in {
1063def : InstAlias<"lpad $imm20", (AUIPC X0, uimm20:$imm20)>;
1064}
1065
1066//===----------------------------------------------------------------------===//
1067// .insn directive instructions
1068//===----------------------------------------------------------------------===//
1069
1070def AnyRegOperand : AsmOperandClass {
1071  let Name = "AnyRegOperand";
1072  let RenderMethod = "addRegOperands";
1073  let PredicateMethod = "isAnyReg";
1074}
1075
1076def AnyReg : Operand<XLenVT> {
1077  let OperandType = "OPERAND_REGISTER";
1078  let ParserMatchClass = AnyRegOperand;
1079}
1080
1081// isCodeGenOnly = 1 to hide them from the tablegened assembly parser.
1082let isCodeGenOnly = 1, hasSideEffects = 1, mayLoad = 1, mayStore = 1,
1083    hasNoSchedulingInfo = 1 in {
1084def InsnR : DirectiveInsnR<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1085                                                   uimm7:$funct7, AnyReg:$rs1,
1086                                                   AnyReg:$rs2),
1087                           "$opcode, $funct3, $funct7, $rd, $rs1, $rs2">;
1088def InsnR4 : DirectiveInsnR4<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1089                                                     uimm3:$funct3,
1090                                                     uimm2:$funct2,
1091                                                     AnyReg:$rs1, AnyReg:$rs2,
1092                                                     AnyReg:$rs3),
1093                            "$opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3">;
1094def InsnI : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1095                                                   AnyReg:$rs1, simm12:$imm12),
1096                           "$opcode, $funct3, $rd, $rs1, $imm12">;
1097def InsnI_Mem : DirectiveInsnI<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1098                                                       uimm3:$funct3,
1099                                                       AnyReg:$rs1,
1100                                                       simm12:$imm12),
1101                               "$opcode, $funct3, $rd, ${imm12}(${rs1})">;
1102def InsnB : DirectiveInsnB<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1103                                        AnyReg:$rs1, AnyReg:$rs2,
1104                                        simm13_lsb0:$imm12),
1105                           "$opcode, $funct3, $rs1, $rs2, $imm12">;
1106def InsnU : DirectiveInsnU<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1107                                                   uimm20_lui:$imm20),
1108                           "$opcode, $rd, $imm20">;
1109def InsnJ : DirectiveInsnJ<(outs AnyReg:$rd), (ins uimm7_opcode:$opcode,
1110                                                   simm21_lsb0_jal:$imm20),
1111                           "$opcode, $rd, $imm20">;
1112def InsnS : DirectiveInsnS<(outs), (ins uimm7_opcode:$opcode, uimm3:$funct3,
1113                                        AnyReg:$rs2, AnyReg:$rs1,
1114                                        simm12:$imm12),
1115                           "$opcode, $funct3, $rs2, ${imm12}(${rs1})">;
1116}
1117
1118// Use InstAliases to match these so that we can combine the insn and format
1119// into a mnemonic to use as the key for the tablegened asm matcher table. The
1120// parser will take care of creating these fake mnemonics and will only do it
1121// for known formats.
1122let EmitPriority = 0 in {
1123def : InstAlias<".insn_r $opcode, $funct3, $funct7, $rd, $rs1, $rs2",
1124                (InsnR AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm7:$funct7,
1125                       AnyReg:$rs1, AnyReg:$rs2)>;
1126// Accept 4 register form of ".insn r" as alias for ".insn r4".
1127def : InstAlias<".insn_r $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",
1128                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,
1129                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;
1130def : InstAlias<".insn_r4 $opcode, $funct3, $funct2, $rd, $rs1, $rs2, $rs3",
1131                (InsnR4 AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, uimm2:$funct2,
1132                        AnyReg:$rs1, AnyReg:$rs2, AnyReg:$rs3)>;
1133def : InstAlias<".insn_i $opcode, $funct3, $rd, $rs1, $imm12",
1134                (InsnI AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1135                       simm12:$imm12)>;
1136def : InstAlias<".insn_i $opcode, $funct3, $rd, ${imm12}(${rs1})",
1137                (InsnI_Mem AnyReg:$rd, uimm7_opcode:$opcode, uimm3:$funct3,
1138                           AnyReg:$rs1, simm12:$imm12)>;
1139def : InstAlias<".insn_b $opcode, $funct3, $rs1, $rs2, $imm12",
1140                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1141                       AnyReg:$rs2, simm13_lsb0:$imm12)>;
1142// Accept sb as an alias for b.
1143def : InstAlias<".insn_sb $opcode, $funct3, $rs1, $rs2, $imm12",
1144                (InsnB uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs1,
1145                       AnyReg:$rs2, simm13_lsb0:$imm12)>;
1146def : InstAlias<".insn_u $opcode, $rd, $imm20",
1147                (InsnU AnyReg:$rd, uimm7_opcode:$opcode, uimm20_lui:$imm20)>;
1148def : InstAlias<".insn_j $opcode, $rd, $imm20",
1149                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;
1150// Accept uj as an alias for j.
1151def : InstAlias<".insn_uj $opcode, $rd, $imm20",
1152                (InsnJ AnyReg:$rd, uimm7_opcode:$opcode, simm21_lsb0_jal:$imm20)>;
1153def : InstAlias<".insn_s $opcode, $funct3, $rs2, ${imm12}(${rs1})",
1154                (InsnS uimm7_opcode:$opcode, uimm3:$funct3, AnyReg:$rs2,
1155                       AnyReg:$rs1, simm12:$imm12)>;
1156}
1157
1158//===----------------------------------------------------------------------===//
1159// Pseudo-instructions and codegen patterns
1160//
1161// Naming convention: For 'generic' pattern classes, we use the naming
1162// convention PatTy1Ty2. For pattern classes which offer a more complex
1163// expansion, prefix the class name, e.g. BccPat.
1164//===----------------------------------------------------------------------===//
1165
1166/// Generic pattern classes
1167
1168class PatGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
1169    : Pat<(vt (OpNode (vt GPR:$rs1))), (Inst GPR:$rs1)>;
1170class PatGprGpr<SDPatternOperator OpNode, RVInst Inst, ValueType vt1 = XLenVT,
1171                ValueType vt2 = XLenVT>
1172    : Pat<(vt1 (OpNode (vt1 GPR:$rs1), (vt2 GPR:$rs2))), (Inst GPR:$rs1, GPR:$rs2)>;
1173
1174class PatGprImm<SDPatternOperator OpNode, RVInst Inst, ImmLeaf ImmType,
1175                ValueType vt = XLenVT>
1176    : Pat<(vt (OpNode (vt GPR:$rs1), ImmType:$imm)),
1177          (Inst GPR:$rs1, ImmType:$imm)>;
1178class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
1179    : PatGprImm<OpNode, Inst, simm12>;
1180class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
1181    : PatGprImm<OpNode, Inst, uimmlog2xlen>;
1182
1183/// Predicates
1184
1185def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
1186  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
1187}]>;
1188def sexti16 : ComplexPattern<XLenVT, 1, "selectSExtBits<16>">;
1189def sexti32 : ComplexPattern<i64, 1, "selectSExtBits<32>">;
1190def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
1191  return cast<VTSDNode>(N->getOperand(1))->getVT().bitsLE(MVT::i32);
1192}]>;
1193def zexti32 : ComplexPattern<i64, 1, "selectZExtBits<32>">;
1194def zexti16 : ComplexPattern<XLenVT, 1, "selectZExtBits<16>">;
1195def zexti16i32 : ComplexPattern<i32, 1, "selectZExtBits<16>">;
1196def zexti8 : ComplexPattern<XLenVT, 1, "selectZExtBits<8>">;
1197def zexti8i32 : ComplexPattern<i32, 1, "selectZExtBits<8>">;
1198
1199def ext : PatFrags<(ops node:$A), [(sext node:$A), (zext node:$A)]>;
1200
1201class binop_oneuse<SDPatternOperator operator>
1202    : PatFrag<(ops node:$A, node:$B),
1203              (operator node:$A, node:$B), [{
1204  return N->hasOneUse();
1205}]>;
1206
1207def and_oneuse : binop_oneuse<and>;
1208def mul_oneuse : binop_oneuse<mul>;
1209
1210def mul_const_oneuse : PatFrag<(ops node:$A, node:$B),
1211                               (mul node:$A, node:$B), [{
1212  if (auto *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1)))
1213    return N1C->hasOneUse();
1214  return false;
1215}]>;
1216
1217class unop_oneuse<SDPatternOperator operator>
1218    : PatFrag<(ops node:$A),
1219              (operator node:$A), [{
1220  return N->hasOneUse();
1221}]>;
1222
1223def sext_oneuse   : unop_oneuse<sext>;
1224def zext_oneuse   : unop_oneuse<zext>;
1225def anyext_oneuse : unop_oneuse<anyext>;
1226def ext_oneuse    : unop_oneuse<ext>;
1227def fpext_oneuse  : unop_oneuse<any_fpextend>;
1228
1229def 33signbits_node : PatLeaf<(i64 GPR:$src), [{
1230  return CurDAG->ComputeNumSignBits(SDValue(N, 0)) > 32;
1231}]>;
1232
1233/// Simple arithmetic operations
1234
1235def : PatGprGpr<add, ADD>;
1236def : PatGprSimm12<add, ADDI>;
1237def : PatGprGpr<sub, SUB>;
1238def : PatGprGpr<or, OR>;
1239def : PatGprSimm12<or, ORI>;
1240def : PatGprGpr<and, AND>;
1241def : PatGprSimm12<and, ANDI>;
1242def : PatGprGpr<xor, XOR>;
1243def : PatGprSimm12<xor, XORI>;
1244def : PatGprUimmLog2XLen<shl, SLLI>;
1245def : PatGprUimmLog2XLen<srl, SRLI>;
1246def : PatGprUimmLog2XLen<sra, SRAI>;
1247
1248// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This
1249// can improve compressibility.
1250def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
1251  KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
1252  KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0);
1253  return KnownBits::haveNoCommonBitsSet(Known0, Known1);
1254}]>;
1255def : PatGprSimm12<or_is_add, ADDI>;
1256
1257// negate of low bit can be done via two (compressible) shifts.  The negate
1258// is never compressible since rs1 and rd can't be the same register.
1259def : Pat<(XLenVT (sub 0, (and_oneuse GPR:$rs, 1))),
1260          (SRAI (SLLI $rs, (ImmSubFromXLen (XLenVT 1))),
1261                (ImmSubFromXLen (XLenVT 1)))>;
1262
1263// AND with leading/trailing ones mask exceeding simm32/simm12.
1264def : Pat<(i64 (and GPR:$rs, LeadingOnesMask:$mask)),
1265          (SLLI (SRLI $rs, LeadingOnesMask:$mask), LeadingOnesMask:$mask)>;
1266def : Pat<(XLenVT (and GPR:$rs, TrailingOnesMask:$mask)),
1267          (SRLI (SLLI $rs, TrailingOnesMask:$mask), TrailingOnesMask:$mask)>;
1268
1269// Match both a plain shift and one where the shift amount is masked (this is
1270// typically introduced when the legalizer promotes the shift amount and
1271// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base
1272// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).
1273def shiftMaskXLen : ComplexPattern<XLenVT, 1, "selectShiftMaskXLen", [], [], 0>;
1274def shiftMask32   : ComplexPattern<i64, 1, "selectShiftMask32", [], [], 0>;
1275
1276class shiftop<SDPatternOperator operator>
1277    : PatFrag<(ops node:$val, node:$count),
1278              (operator node:$val, (XLenVT (shiftMaskXLen node:$count)))>;
1279class shiftopw<SDPatternOperator operator>
1280    : PatFrag<(ops node:$val, node:$count),
1281              (operator node:$val, (i64 (shiftMask32 node:$count)))>;
1282
1283def : PatGprGpr<shiftop<shl>, SLL>;
1284def : PatGprGpr<shiftop<srl>, SRL>;
1285def : PatGprGpr<shiftop<sra>, SRA>;
1286
1287// This is a special case of the ADD instruction used to facilitate the use of a
1288// fourth operand to emit a relocation on a symbol relating to this instruction.
1289// The relocation does not affect any bits of the instruction itself but is used
1290// as a hint to the linker.
1291let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0 in
1292def PseudoAddTPRel : Pseudo<(outs GPR:$rd),
1293                            (ins GPR:$rs1, GPR:$rs2, tprel_add_symbol:$src), [],
1294                            "add", "$rd, $rs1, $rs2, $src">;
1295
1296/// FrameIndex calculations
1297
1298def : Pat<(FrameAddrRegImm (iPTR GPR:$rs1), simm12:$imm12),
1299          (ADDI GPR:$rs1, simm12:$imm12)>;
1300
1301/// HI and ADD_LO address nodes.
1302
1303def : Pat<(riscv_hi tglobaladdr:$in), (LUI tglobaladdr:$in)>;
1304def : Pat<(riscv_hi tblockaddress:$in), (LUI tblockaddress:$in)>;
1305def : Pat<(riscv_hi tjumptable:$in), (LUI tjumptable:$in)>;
1306def : Pat<(riscv_hi tconstpool:$in), (LUI tconstpool:$in)>;
1307
1308def : Pat<(riscv_add_lo GPR:$hi, tglobaladdr:$lo),
1309          (ADDI GPR:$hi, tglobaladdr:$lo)>;
1310def : Pat<(riscv_add_lo GPR:$hi, tblockaddress:$lo),
1311          (ADDI GPR:$hi, tblockaddress:$lo)>;
1312def : Pat<(riscv_add_lo GPR:$hi, tjumptable:$lo),
1313          (ADDI GPR:$hi, tjumptable:$lo)>;
1314def : Pat<(riscv_add_lo GPR:$hi, tconstpool:$lo),
1315          (ADDI GPR:$hi, tconstpool:$lo)>;
1316
1317/// TLS address nodes.
1318
1319def : Pat<(riscv_hi tglobaltlsaddr:$in), (LUI tglobaltlsaddr:$in)>;
1320def : Pat<(riscv_add_tprel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src),
1321          (PseudoAddTPRel GPR:$rs1, GPR:$rs2, tglobaltlsaddr:$src)>;
1322def : Pat<(riscv_add_lo GPR:$src, tglobaltlsaddr:$lo),
1323          (ADDI GPR:$src, tglobaltlsaddr:$lo)>;
1324
1325/// Setcc
1326
1327def : PatGprGpr<setlt, SLT>;
1328def : PatGprSimm12<setlt, SLTI>;
1329def : PatGprGpr<setult, SLTU>;
1330def : PatGprSimm12<setult, SLTIU>;
1331
1332// RISC-V doesn't have general instructions for integer setne/seteq, but we can
1333// check for equality with 0. These ComplexPatterns rewrite the setne/seteq into
1334// something that can be compared with 0.
1335// These ComplexPatterns must be used in pairs.
1336def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;
1337def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;
1338
1339// Define pattern expansions for setcc operations that aren't directly
1340// handled by a RISC-V instruction.
1341def : Pat<(riscv_seteq (XLenVT GPR:$rs1)), (SLTIU GPR:$rs1, 1)>;
1342def : Pat<(riscv_setne (XLenVT GPR:$rs1)), (SLTU (XLenVT X0), GPR:$rs1)>;
1343def : Pat<(XLenVT (setne (XLenVT GPR:$rs1), -1)), (SLTIU GPR:$rs1, -1)>;
1344
1345def IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{
1346  ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
1347  RISCVCC::CondCode BrCC = getRISCVCCForIntCC(CC);
1348  return CurDAG->getTargetConstant(BrCC, SDLoc(N), Subtarget->getXLenVT());
1349}]>;
1350
1351def riscv_selectcc_frag : PatFrag<(ops node:$lhs, node:$rhs, node:$cc,
1352                                       node:$truev, node:$falsev),
1353                                  (riscv_selectcc node:$lhs, node:$rhs,
1354                                                  node:$cc, node:$truev,
1355                                                  node:$falsev), [{}],
1356                                  IntCCtoRISCVCC>;
1357
1358let Predicates = [HasShortForwardBranchOpt], isSelect = 1,
1359    Constraints = "$dst = $falsev", isCommutable = 1, Size = 8 in {
1360// This instruction moves $truev to $dst when the condition is true. It will
1361// be expanded to control flow in RISCVExpandPseudoInsts.
1362def PseudoCCMOVGPR : Pseudo<(outs GPR:$dst),
1363                            (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1364                             GPR:$falsev, GPR:$truev),
1365                            [(set GPR:$dst,
1366                              (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs),
1367                                                       GPR:$rhs, cond,
1368                                                       (XLenVT GPR:$truev),
1369                                                       GPR:$falsev))]>,
1370                     Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1371                            ReadSFBALU, ReadSFBALU]>;
1372}
1373
1374// This should always expand to a branch+c.mv so the size is 6 or 4 if the
1375// branch is compressible.
1376let Predicates = [HasConditionalMoveFusion, NoShortForwardBranchOpt],
1377    Constraints = "$dst = $falsev", isCommutable = 1, Size = 6 in {
1378// This instruction moves $truev to $dst when the condition is true. It will
1379// be expanded to control flow in RISCVExpandPseudoInsts.
1380// We use GPRNoX0 because c.mv cannot encode X0.
1381def PseudoCCMOVGPRNoX0 : Pseudo<(outs GPRNoX0:$dst),
1382                                (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1383                                 GPRNoX0:$falsev, GPRNoX0:$truev),
1384                                [(set GPRNoX0:$dst,
1385                                  (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs),
1386                                                           (XLenVT GPR:$rhs),
1387                                                           cond, (XLenVT GPRNoX0:$truev),
1388                                                           (XLenVT GPRNoX0:$falsev)))]>,
1389                         Sched<[]>;
1390}
1391
1392// Conditional binops, that updates update $dst to (op rs1, rs2) when condition
1393// is true. Returns $falsev otherwise. Selected by optimizeSelect.
1394// TODO: Can we use DefaultOperands on the regular binop to accomplish this more
1395// like how ARM does predication?
1396let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8,
1397    Constraints = "$dst = $falsev" in {
1398def PseudoCCADD : Pseudo<(outs GPR:$dst),
1399                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1400                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1401                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1402                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1403def PseudoCCSUB : Pseudo<(outs GPR:$dst),
1404                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1405                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1406                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1407                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1408def PseudoCCSLL : Pseudo<(outs GPR:$dst),
1409                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1410                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1411                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1412                         ReadSFBALU, ReadSFBALU]>;
1413def PseudoCCSRL : Pseudo<(outs GPR:$dst),
1414                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1415                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1416                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1417                         ReadSFBALU, ReadSFBALU]>;
1418def PseudoCCSRA : Pseudo<(outs GPR:$dst),
1419                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1420                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1421                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1422                         ReadSFBALU, ReadSFBALU]>;
1423def PseudoCCAND : Pseudo<(outs GPR:$dst),
1424                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1425                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1426                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1427                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1428def PseudoCCOR  : Pseudo<(outs GPR:$dst),
1429                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1430                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1431                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1432                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1433def PseudoCCXOR : Pseudo<(outs GPR:$dst),
1434                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1435                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1436                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1437                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1438
1439def PseudoCCADDI : Pseudo<(outs GPR:$dst),
1440                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1441                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1442                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1443                          ReadSFBALU]>;
1444def PseudoCCSLLI : Pseudo<(outs GPR:$dst),
1445                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1446                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1447                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1448                          ReadSFBALU]>;
1449def PseudoCCSRLI : Pseudo<(outs GPR:$dst),
1450                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1451                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1452                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1453                          ReadSFBALU]>;
1454def PseudoCCSRAI : Pseudo<(outs GPR:$dst),
1455                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1456                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1457                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1458                          ReadSFBALU]>;
1459def PseudoCCANDI : Pseudo<(outs GPR:$dst),
1460                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1461                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1462                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1463                          ReadSFBALU]>;
1464def PseudoCCORI  : Pseudo<(outs GPR:$dst),
1465                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1466                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1467                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1468                          ReadSFBALU]>;
1469def PseudoCCXORI : Pseudo<(outs GPR:$dst),
1470                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1471                           GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1472                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1473                          ReadSFBALU]>;
1474
1475// RV64I instructions
1476def PseudoCCADDW : Pseudo<(outs GPR:$dst),
1477                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1478                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1479                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1480                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1481def PseudoCCSUBW : Pseudo<(outs GPR:$dst),
1482                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1483                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1484                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1485                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1486def PseudoCCSLLW : Pseudo<(outs GPR:$dst),
1487                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1488                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1489                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1490                          ReadSFBALU, ReadSFBALU]>;
1491def PseudoCCSRLW : Pseudo<(outs GPR:$dst),
1492                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1493                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1494                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1495                          ReadSFBALU, ReadSFBALU]>;
1496def PseudoCCSRAW : Pseudo<(outs GPR:$dst),
1497                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1498                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1499                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1500                          ReadSFBALU, ReadSFBALU]>;
1501
1502def PseudoCCADDIW : Pseudo<(outs GPR:$dst),
1503                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1504                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1505                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1506                           ReadSFBALU]>;
1507def PseudoCCSLLIW : Pseudo<(outs GPR:$dst),
1508                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1509                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1510                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1511                           ReadSFBALU]>;
1512def PseudoCCSRLIW : Pseudo<(outs GPR:$dst),
1513                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1514                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1515                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1516                           ReadSFBALU]>;
1517def PseudoCCSRAIW : Pseudo<(outs GPR:$dst),
1518                           (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1519                            GPR:$falsev, GPR:$rs1, simm12:$rs2), []>,
1520                    Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
1521                           ReadSFBALU]>;
1522
1523// Zbb/Zbkb instructions
1524def PseudoCCANDN : Pseudo<(outs GPR:$dst),
1525                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1526                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1527                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1528                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1529def PseudoCCORN : Pseudo<(outs GPR:$dst),
1530                         (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1531                          GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1532                  Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1533                         ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1534def PseudoCCXNOR : Pseudo<(outs GPR:$dst),
1535                          (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1536                           GPR:$falsev, GPR:$rs1, GPR:$rs2), []>,
1537                   Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp,
1538                          ReadSFBALU, ReadSFBALU, ReadSFBALU]>;
1539}
1540
1541multiclass SelectCC_GPR_rrirr<DAGOperand valty, ValueType vt> {
1542  let usesCustomInserter = 1 in
1543  def _Using_CC_GPR : Pseudo<(outs valty:$dst),
1544                             (ins GPR:$lhs, GPR:$rhs, ixlenimm:$cc,
1545                              valty:$truev, valty:$falsev),
1546                             [(set valty:$dst,
1547                               (riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), GPR:$rhs, cond,
1548                                                        (vt valty:$truev), valty:$falsev))]>;
1549  // Explicitly select 0 in the condition to X0. The register coalescer doesn't
1550  // always do it.
1551  def : Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), 0, cond, (vt valty:$truev),
1552                                     valty:$falsev),
1553            (!cast<Instruction>(NAME#"_Using_CC_GPR") GPR:$lhs, (XLenVT X0),
1554             (IntCCtoRISCVCC $cc), valty:$truev, valty:$falsev)>;
1555}
1556
1557let Predicates = [NoConditionalMoveFusion] in
1558defm Select_GPR : SelectCC_GPR_rrirr<GPR, XLenVT>;
1559
1560class SelectCompressOpt<CondCode Cond>
1561    : Pat<(riscv_selectcc_frag:$select (XLenVT GPR:$lhs), simm12_no6:$Constant, Cond,
1562                                       (XLenVT GPR:$truev), GPR:$falsev),
1563    (Select_GPR_Using_CC_GPR (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0),
1564                          (IntCCtoRISCVCC $select), GPR:$truev, GPR:$falsev)>;
1565
1566def OptForMinSize : Predicate<"MF ? MF->getFunction().hasMinSize() : false">;
1567
1568let Predicates = [HasStdExtC, OptForMinSize] in {
1569  def : SelectCompressOpt<SETEQ>;
1570  def : SelectCompressOpt<SETNE>;
1571}
1572
1573/// Branches and jumps
1574
1575// Match `riscv_brcc` and lower to the appropriate RISC-V branch instruction.
1576multiclass BccPat<CondCode Cond, RVInstB Inst> {
1577  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), GPR:$rs2, Cond, bb:$imm12),
1578            (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>;
1579  // Explicitly select 0 to X0. The register coalescer doesn't always do it.
1580  def : Pat<(riscv_brcc (XLenVT GPR:$rs1), 0, Cond, bb:$imm12),
1581            (Inst GPR:$rs1, (XLenVT X0), simm13_lsb0:$imm12)>;
1582}
1583
1584class BrccCompressOpt<CondCode Cond, RVInstB Inst>
1585    : Pat<(riscv_brcc GPR:$lhs, simm12_no6:$Constant, Cond, bb:$place),
1586          (Inst (ADDI GPR:$lhs, (NegImm simm12:$Constant)), (XLenVT X0), bb:$place)>;
1587
1588defm : BccPat<SETEQ, BEQ>;
1589defm : BccPat<SETNE, BNE>;
1590defm : BccPat<SETLT, BLT>;
1591defm : BccPat<SETGE, BGE>;
1592defm : BccPat<SETULT, BLTU>;
1593defm : BccPat<SETUGE, BGEU>;
1594
1595let Predicates = [HasStdExtC, OptForMinSize] in {
1596  def : BrccCompressOpt<SETEQ, BEQ>;
1597  def : BrccCompressOpt<SETNE, BNE>;
1598}
1599
1600class LongBccPseudo : Pseudo<(outs),
1601                             (ins GPR:$rs1, GPR:$rs2, simm21_lsb0_jal:$imm20),
1602                             []> {
1603  let Size = 8;
1604  let isBarrier = 1;
1605  let isBranch = 1;
1606  let hasSideEffects = 0;
1607  let mayStore = 0;
1608  let mayLoad = 0;
1609  let isAsmParserOnly = 1;
1610  let hasNoSchedulingInfo = 1;
1611}
1612
1613def PseudoLongBEQ : LongBccPseudo;
1614def PseudoLongBNE : LongBccPseudo;
1615def PseudoLongBLT : LongBccPseudo;
1616def PseudoLongBGE : LongBccPseudo;
1617def PseudoLongBLTU : LongBccPseudo;
1618def PseudoLongBGEU : LongBccPseudo;
1619
1620let isBarrier = 1, isBranch = 1, isTerminator = 1 in
1621def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
1622               PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;
1623
1624let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
1625def PseudoBRIND : Pseudo<(outs), (ins GPRJALR:$rs1, simm12:$imm12), []>,
1626                  PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
1627
1628def : Pat<(brind GPRJALR:$rs1), (PseudoBRIND GPRJALR:$rs1, 0)>;
1629def : Pat<(brind (add GPRJALR:$rs1, simm12:$imm12)),
1630          (PseudoBRIND GPRJALR:$rs1, simm12:$imm12)>;
1631
1632// PseudoCALLReg is a generic pseudo instruction for calls which will eventually
1633// expand to auipc and jalr while encoding, with any given register used as the
1634// destination.
1635// Define AsmString to print "call" when compile with -S flag.
1636// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
1637let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,
1638    mayStore = 0, mayLoad = 0 in
1639def PseudoCALLReg : Pseudo<(outs GPR:$rd), (ins call_symbol:$func), [],
1640                           "call", "$rd, $func">,
1641                    Sched<[WriteIALU, WriteJalr, ReadJalr]>;
1642
1643// PseudoCALL is a pseudo instruction which will eventually expand to auipc
1644// and jalr while encoding. This is desirable, as an auipc+jalr pair with
1645// R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
1646// if the offset fits in a signed 21-bit immediate.
1647// Define AsmString to print "call" when compile with -S flag.
1648// Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
1649let isCall = 1, Defs = [X1], isCodeGenOnly = 0, Size = 8 in
1650def PseudoCALL : Pseudo<(outs), (ins call_symbol:$func), [],
1651                        "call", "$func">,
1652                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
1653
1654def : Pat<(riscv_call tglobaladdr:$func), (PseudoCALL tglobaladdr:$func)>;
1655def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
1656
1657def : Pat<(riscv_sret_glue), (SRET (XLenVT X0), (XLenVT X0))>;
1658def : Pat<(riscv_mret_glue), (MRET (XLenVT X0), (XLenVT X0))>;
1659
1660let isCall = 1, Defs = [X1] in
1661def PseudoCALLIndirect : Pseudo<(outs), (ins GPRJALR:$rs1),
1662                                [(riscv_call GPRJALR:$rs1)]>,
1663                         PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
1664
1665let isBarrier = 1, isReturn = 1, isTerminator = 1 in
1666def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_glue)]>,
1667                PseudoInstExpansion<(JALR X0, X1, 0)>;
1668
1669// PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
1670// expand to auipc and jalr while encoding.
1671// Define AsmString to print "tail" when compile with -S flag.
1672let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
1673    Size = 8, isCodeGenOnly = 0 in
1674def PseudoTAIL : Pseudo<(outs), (ins call_symbol:$dst), [],
1675                        "tail", "$dst">,
1676                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
1677
1678let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
1679def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
1680                                [(riscv_tail GPRTC:$rs1)]>,
1681                         PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
1682
1683def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
1684          (PseudoTAIL tglobaladdr:$dst)>;
1685def : Pat<(riscv_tail (iPTR texternalsym:$dst)),
1686          (PseudoTAIL texternalsym:$dst)>;
1687
1688let isCall = 0, isBarrier = 1, isBranch = 1, isTerminator = 1, Size = 8,
1689    isCodeGenOnly = 0, hasSideEffects = 0, mayStore = 0, mayLoad = 0 in
1690def PseudoJump : Pseudo<(outs GPR:$rd), (ins pseudo_jump_symbol:$target), [],
1691                        "jump", "$target, $rd">,
1692                 Sched<[WriteIALU, WriteJalr, ReadJalr]>;
1693
1694// Pseudo for a rematerializable constant materialization sequence.
1695// This is an experimental feature enabled by
1696// -riscv-use-rematerializable-movimm in RISCVISelDAGToDAG.cpp
1697// It will be expanded after register allocation.
1698// FIXME: The scheduling information does not reflect the multiple instructions.
1699let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 1,
1700    isPseudo = 1, isReMaterializable = 1, IsSignExtendingOpW = 1 in
1701def PseudoMovImm : Pseudo<(outs GPR:$dst), (ins i32imm:$imm), []>,
1702                   Sched<[WriteIALU]>;
1703
1704let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1705    isAsmParserOnly = 1 in
1706def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1707                       "lla", "$dst, $src">;
1708
1709// Refer to comment on PseudoLI for explanation of Size=32
1710let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1711    isAsmParserOnly = 1 in
1712def PseudoLLAImm : Pseudo<(outs GPR:$dst), (ins ixlenimm_li_restricted:$imm), [],
1713                          "lla", "$dst, $imm">;
1714def : Pat<(riscv_lla tglobaladdr:$in), (PseudoLLA tglobaladdr:$in)>;
1715def : Pat<(riscv_lla tblockaddress:$in), (PseudoLLA tblockaddress:$in)>;
1716def : Pat<(riscv_lla tjumptable:$in), (PseudoLLA tjumptable:$in)>;
1717def : Pat<(riscv_lla tconstpool:$in), (PseudoLLA tconstpool:$in)>;
1718
1719let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1720    isAsmParserOnly = 1 in
1721def PseudoLGA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1722                       "lga", "$dst, $src">;
1723
1724let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1725    isAsmParserOnly = 1 in
1726def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1727                      "la", "$dst, $src">;
1728
1729// Refer to comment on PseudoLI for explanation of Size=32
1730let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
1731    isCodeGenOnly = 0, isAsmParserOnly = 1 in
1732def PseudoLAImm : Pseudo<(outs GPR:$rd), (ins ixlenimm_li_restricted:$imm), [],
1733                         "la", "$rd, $imm">;
1734
1735let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1736    isAsmParserOnly = 1 in
1737def PseudoLA_TLS_IE : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1738                             "la.tls.ie", "$dst, $src">;
1739
1740let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 8, isCodeGenOnly = 0,
1741    isAsmParserOnly = 1 in
1742def PseudoLA_TLS_GD : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1743                             "la.tls.gd", "$dst, $src">;
1744
1745let hasSideEffects = 0, mayLoad = 1, mayStore = 0, Size = 32, isCodeGenOnly = 0 in
1746def PseudoLA_TLSDESC : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
1747                             "la.tlsdesc", "$dst, $src">;
1748
1749def TLSDESCCallSymbol : AsmOperandClass {
1750  let Name = "TLSDESCCallSymbol";
1751  let RenderMethod = "addImmOperands";
1752  let DiagnosticType = "InvalidTLSDESCCallSymbol";
1753  let ParserMethod = "parseOperandWithModifier";
1754}
1755
1756// A bare symbol with the %tlsdesc_call variant.
1757def tlsdesc_call_symbol : Operand<XLenVT> {
1758  let ParserMatchClass = TLSDESCCallSymbol;
1759}
1760// This is a special case of the JALR instruction used to facilitate the use of a
1761// fourth operand to emit a relocation on a symbol relating to this instruction.
1762// The relocation does not affect any bits of the instruction itself but is used
1763// as a hint to the linker.
1764let isCall = 1, isBarrier = 1, isCodeGenOnly = 0, Size = 8, hasSideEffects = 0,
1765    mayStore = 0, mayLoad = 0 in
1766def PseudoTLSDESCCall : Pseudo<(outs GPR:$rd),
1767                         (ins GPR:$rs1, simm12:$imm12, tlsdesc_call_symbol:$src), [],
1768                         "jalr", "$rd, ${imm12}(${rs1}), $src">,
1769                         Sched<[WriteJalr, ReadJalr]> {
1770  let Defs = [X10];
1771  let Uses = [X10];
1772}
1773
1774
1775/// Sign/Zero Extends
1776
1777// There are single-instruction versions of these in Zbb, so disable these
1778// Pseudos if that extension is present.
1779let hasSideEffects = 0, mayLoad = 0,
1780    mayStore = 0, isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1781def PseudoSEXT_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.b", "$rd, $rs">;
1782def PseudoSEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "sext.h", "$rd, $rs">;
1783// rv64's sext.w is defined above, using InstAlias<"sext.w ...
1784// zext.b is defined above, using InstAlias<"zext.b ...
1785def PseudoZEXT_H : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.h", "$rd, $rs">;
1786} // hasSideEffects = 0, ...
1787
1788let Predicates = [IsRV64], hasSideEffects = 0, mayLoad = 0, mayStore = 0,
1789  isCodeGenOnly = 0, isAsmParserOnly = 1 in {
1790def PseudoZEXT_W : Pseudo<(outs GPR:$rd), (ins GPR:$rs), [], "zext.w", "$rd, $rs">;
1791} // Predicates = [IsRV64], ...
1792
1793/// Loads
1794
1795class LdPat<PatFrag LoadOp, RVInst Inst, ValueType vt = XLenVT>
1796    : Pat<(vt (LoadOp (AddrRegImm (XLenVT GPR:$rs1), simm12:$imm12))),
1797          (Inst GPR:$rs1, simm12:$imm12)>;
1798
1799def : LdPat<sextloadi8, LB>;
1800def : LdPat<extloadi8, LBU>; // Prefer unsigned due to no c.lb in Zcb.
1801def : LdPat<sextloadi16, LH>;
1802def : LdPat<extloadi16, LH>;
1803def : LdPat<load, LW, i32>;
1804def : LdPat<zextloadi8, LBU>;
1805def : LdPat<zextloadi16, LHU>;
1806
1807/// Stores
1808
1809class StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy,
1810            ValueType vt>
1811    : Pat<(StoreOp (vt StTy:$rs2), (AddrRegImm (XLenVT GPR:$rs1),
1812                   simm12:$imm12)),
1813          (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
1814
1815def : StPat<truncstorei8, SB, GPR, XLenVT>;
1816def : StPat<truncstorei16, SH, GPR, XLenVT>;
1817def : StPat<store, SW, GPR, i32>;
1818
1819/// Fences
1820
1821// Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
1822// Manual: Volume I.
1823
1824// fence acquire -> fence r, rw
1825def : Pat<(atomic_fence (XLenVT 4), (timm)), (FENCE 0b10, 0b11)>;
1826// fence release -> fence rw, w
1827def : Pat<(atomic_fence (XLenVT 5), (timm)), (FENCE 0b11, 0b1)>;
1828// fence acq_rel -> fence.tso
1829def : Pat<(atomic_fence (XLenVT 6), (timm)), (FENCE_TSO)>;
1830// fence seq_cst -> fence rw, rw
1831def : Pat<(atomic_fence (XLenVT 7), (timm)), (FENCE 0b11, 0b11)>;
1832
1833// Lowering for atomic load and store is defined in RISCVInstrInfoA.td.
1834// Although these are lowered to fence+load/store instructions defined in the
1835// base RV32I/RV64I ISA, this lowering is only used when the A extension is
1836// present. This is necessary as it isn't valid to mix __atomic_* libcalls
1837// with inline atomic operations for the same object.
1838
1839/// Access to system registers
1840
1841// Helpers for defining specific operations. They are defined for each system
1842// register separately. Side effect is not used because dependencies are
1843// expressed via use-def properties.
1844
1845class ReadSysReg<SysReg SR, list<Register> Regs>
1846  : Pseudo<(outs GPR:$rd), (ins),
1847           [(set GPR:$rd, (XLenVT (riscv_read_csr (XLenVT SR.Encoding))))]>,
1848    PseudoInstExpansion<(CSRRS GPR:$rd, SR.Encoding, X0)> {
1849  let hasSideEffects = 0;
1850  let Uses = Regs;
1851}
1852
1853class WriteSysReg<SysReg SR, list<Register> Regs>
1854  : Pseudo<(outs), (ins GPR:$val),
1855           [(riscv_write_csr (XLenVT SR.Encoding), (XLenVT GPR:$val))]>,
1856    PseudoInstExpansion<(CSRRW X0, SR.Encoding, GPR:$val)> {
1857  let hasSideEffects = 0;
1858  let Defs = Regs;
1859}
1860
1861class WriteSysRegImm<SysReg SR, list<Register> Regs>
1862  : Pseudo<(outs), (ins uimm5:$val),
1863           [(riscv_write_csr (XLenVT SR.Encoding), uimm5:$val)]>,
1864    PseudoInstExpansion<(CSRRWI X0, SR.Encoding, uimm5:$val)> {
1865  let hasSideEffects = 0;
1866  let Defs = Regs;
1867}
1868
1869class SwapSysReg<SysReg SR, list<Register> Regs>
1870  : Pseudo<(outs GPR:$rd), (ins GPR:$val),
1871           [(set GPR:$rd, (riscv_swap_csr (XLenVT SR.Encoding), (XLenVT GPR:$val)))]>,
1872    PseudoInstExpansion<(CSRRW GPR:$rd, SR.Encoding, GPR:$val)> {
1873  let hasSideEffects = 0;
1874  let Uses = Regs;
1875  let Defs = Regs;
1876}
1877
1878class SwapSysRegImm<SysReg SR, list<Register> Regs>
1879  : Pseudo<(outs GPR:$rd), (ins uimm5:$val),
1880           [(set GPR:$rd, (XLenVT (riscv_swap_csr (XLenVT SR.Encoding), uimm5:$val)))]>,
1881    PseudoInstExpansion<(CSRRWI GPR:$rd, SR.Encoding, uimm5:$val)> {
1882  let hasSideEffects = 0;
1883  let Uses = Regs;
1884  let Defs = Regs;
1885}
1886
1887def ReadFRM : ReadSysReg<SysRegFRM, [FRM]>;
1888def WriteFRM : WriteSysReg<SysRegFRM, [FRM]>;
1889def WriteFRMImm : WriteSysRegImm<SysRegFRM, [FRM]>;
1890def SwapFRMImm : SwapSysRegImm<SysRegFRM, [FRM]>;
1891
1892def WriteVXRMImm : WriteSysRegImm<SysRegVXRM, [VXRM]>;
1893
1894let hasSideEffects = true in {
1895def ReadFFLAGS : ReadSysReg<SysRegFFLAGS, [FFLAGS]>;
1896def WriteFFLAGS : WriteSysReg<SysRegFFLAGS, [FFLAGS]>;
1897}
1898/// Other pseudo-instructions
1899
1900// Pessimistically assume the stack pointer will be clobbered
1901let Defs = [X2], Uses = [X2] in {
1902def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1903                              [(callseq_start timm:$amt1, timm:$amt2)]>;
1904def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
1905                              [(callseq_end timm:$amt1, timm:$amt2)]>;
1906} // Defs = [X2], Uses = [X2]
1907
1908/// RV64 patterns
1909
1910let Predicates = [IsRV64, NotHasStdExtZba] in {
1911def : Pat<(i64 (and GPR:$rs1, 0xffffffff)), (SRLI (SLLI GPR:$rs1, 32), 32)>;
1912
1913// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2
1914// shifts instead of 3. This can occur when unsigned is used to index an array.
1915def : Pat<(i64 (shl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1916          (SRLI (SLLI GPR:$rs1, 32), (ImmSubFrom32 uimm5:$shamt))>;
1917}
1918
1919class binop_allhusers<SDPatternOperator operator>
1920    : PatFrag<(ops node:$lhs, node:$rhs),
1921              (XLenVT (operator node:$lhs, node:$rhs)), [{
1922  return hasAllHUsers(Node);
1923}]>;
1924
1925// PatFrag to allow ADDW/SUBW/MULW/SLLW to be selected from i64 add/sub/mul/shl
1926// if only the lower 32 bits of their result is used.
1927class binop_allwusers<SDPatternOperator operator>
1928    : PatFrag<(ops node:$lhs, node:$rhs),
1929              (i64 (operator node:$lhs, node:$rhs)), [{
1930  return hasAllWUsers(Node);
1931}]>;
1932
1933def sexti32_allwusers : PatFrag<(ops node:$src),
1934                                (sext_inreg node:$src, i32), [{
1935  return hasAllWUsers(Node);
1936}]>;
1937
1938def ImmSExt32 : SDNodeXForm<imm, [{
1939  return CurDAG->getTargetConstant(SignExtend64<32>(N->getSExtValue()),
1940                                   SDLoc(N), N->getValueType(0));
1941}]>;
1942// Look for constants where the upper 32 bits are 0, but sign extending bit 31
1943// would be an simm12.
1944def u32simm12 : ImmLeaf<XLenVT, [{
1945  return isUInt<32>(Imm) && isInt<12>(SignExtend64<32>(Imm));
1946}], ImmSExt32>;
1947
1948let Predicates = [IsRV64] in {
1949
1950def : Pat<(i64 (and GPR:$rs, LeadingOnesWMask:$mask)),
1951          (SLLI (SRLIW $rs, LeadingOnesWMask:$mask), LeadingOnesWMask:$mask)>;
1952
1953/// sext and zext
1954
1955// Sign extend is not needed if all users are W instructions.
1956def : Pat<(sexti32_allwusers GPR:$rs1), (XLenVT GPR:$rs1)>;
1957
1958def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
1959
1960/// ALU operations
1961
1962def : Pat<(i64 (srl (and GPR:$rs1, 0xffffffff), uimm5:$shamt)),
1963          (SRLIW GPR:$rs1, uimm5:$shamt)>;
1964def : Pat<(i64 (srl (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1965          (SRLIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
1966def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
1967          (SRAIW GPR:$rs1, uimm5:$shamt)>;
1968def : Pat<(i64 (sra (shl GPR:$rs1, (i64 32)), uimm6gt32:$shamt)),
1969          (SRAIW GPR:$rs1, (ImmSub32 uimm6gt32:$shamt))>;
1970
1971def : PatGprGpr<shiftopw<riscv_sllw>, SLLW>;
1972def : PatGprGpr<shiftopw<riscv_srlw>, SRLW>;
1973def : PatGprGpr<shiftopw<riscv_sraw>, SRAW>;
1974
1975// Select W instructions if only the lower 32 bits of the result are used.
1976def : PatGprGpr<binop_allwusers<add>, ADDW>;
1977def : PatGprSimm12<binop_allwusers<add>, ADDIW>;
1978def : PatGprGpr<binop_allwusers<sub>, SUBW>;
1979def : PatGprImm<binop_allwusers<shl>, SLLIW, uimm5>;
1980
1981// If this is a shr of a value sign extended from i32, and all the users only
1982// use the lower 32 bits, we can use an sraiw to remove the sext_inreg. This
1983// occurs because SimplifyDemandedBits prefers srl over sra.
1984def : Pat<(binop_allwusers<srl> (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
1985          (SRAIW GPR:$rs1, uimm5:$shamt)>;
1986
1987// Use binop_allwusers to recover immediates that may have been broken by
1988// SimplifyDemandedBits.
1989def : Pat<(binop_allwusers<and> GPR:$rs1, u32simm12:$imm),
1990          (ANDI GPR:$rs1, u32simm12:$imm)>;
1991
1992def : Pat<(binop_allwusers<or> GPR:$rs1, u32simm12:$imm),
1993          (ORI GPR:$rs1, u32simm12:$imm)>;
1994
1995def : Pat<(binop_allwusers<xor> GPR:$rs1, u32simm12:$imm),
1996          (XORI GPR:$rs1, u32simm12:$imm)>;
1997/// Loads
1998
1999def : LdPat<sextloadi32, LW, i64>;
2000def : LdPat<extloadi32, LW, i64>;
2001def : LdPat<zextloadi32, LWU, i64>;
2002def : LdPat<load, LD, i64>;
2003
2004/// Stores
2005
2006def : StPat<truncstorei32, SW, GPR, i64>;
2007def : StPat<store, SD, GPR, i64>;
2008} // Predicates = [IsRV64]
2009
2010/// readcyclecounter
2011// On RV64, we can directly read the 64-bit "cycle" CSR.
2012let Predicates = [IsRV64] in
2013def : Pat<(i64 (readcyclecounter)), (CSRRS CYCLE.Encoding, (XLenVT X0))>;
2014// On RV32, ReadCycleWide will be expanded to the suggested loop reading both
2015// halves of the 64-bit "cycle" CSR.
2016let Predicates = [IsRV32], usesCustomInserter = 1, hasNoSchedulingInfo = 1 in
2017def ReadCycleWide : Pseudo<(outs GPR:$lo, GPR:$hi), (ins),
2018                           [(set GPR:$lo, GPR:$hi, (riscv_read_cycle_wide))],
2019                           "", "">;
2020
2021/// traps
2022
2023// We lower `trap` to `unimp`, as this causes a hard exception on nearly all
2024// systems.
2025def : Pat<(trap), (UNIMP)>;
2026
2027// We lower `debugtrap` to `ebreak`, as this will get the attention of the
2028// debugger if possible.
2029def : Pat<(debugtrap), (EBREAK)>;
2030
2031let Predicates = [IsRV64], Uses = [X5],
2032    Defs = [X1, X6, X7, X28, X29, X30, X31] in
2033def HWASAN_CHECK_MEMACCESS_SHORTGRANULES
2034  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$accessinfo),
2035           [(int_hwasan_check_memaccess_shortgranules (i64 X5), GPRJALR:$ptr,
2036                                                      (i32 timm:$accessinfo))]>;
2037
2038// This gets lowered into a 20-byte instruction sequence (at most)
2039let hasSideEffects = 0, mayLoad = 1, mayStore = 0,
2040    Defs = [ X6, X7, X28, X29, X30, X31 ], Size = 20 in {
2041def KCFI_CHECK
2042  : Pseudo<(outs), (ins GPRJALR:$ptr, i32imm:$type), []>, Sched<[]>;
2043}
2044
2045/// Simple optimization
2046def : Pat<(XLenVT (add GPR:$rs1, (AddiPair:$rs2))),
2047          (ADDI (ADDI GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
2048                (AddiPairImmSmall GPR:$rs2))>;
2049
2050let Predicates = [IsRV64] in {
2051// Select W instructions if only the lower 32-bits of the result are used.
2052def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
2053          (ADDIW (ADDIW GPR:$rs1, (AddiPairImmLarge AddiPair:$rs2)),
2054                 (AddiPairImmSmall AddiPair:$rs2))>;
2055}
2056
2057let Predicates = [HasShortForwardBranchOpt] in
2058def : Pat<(XLenVT (abs GPR:$rs1)),
2059          (PseudoCCSUB (XLenVT GPR:$rs1), (XLenVT X0), /* COND_LT */ 2,
2060           (XLenVT GPR:$rs1), (XLenVT X0), (XLenVT GPR:$rs1))>;
2061let Predicates = [HasShortForwardBranchOpt, IsRV64] in
2062def : Pat<(sext_inreg (abs 33signbits_node:$rs1), i32),
2063          (PseudoCCSUBW (i64 GPR:$rs1), (i64 X0), /* COND_LT */ 2,
2064           (i64 GPR:$rs1), (i64 X0), (i64 GPR:$rs1))>;
2065
2066//===----------------------------------------------------------------------===//
2067// Experimental RV64 i32 legalization patterns.
2068//===----------------------------------------------------------------------===//
2069
2070def simm12i32 : ImmLeaf<i32, [{return isInt<12>(Imm);}]>;
2071
2072// Convert from i32 immediate to i64 target immediate to make SelectionDAG type
2073// checking happy so we can use ADDIW which expects an XLen immediate.
2074def as_i64imm : SDNodeXForm<imm, [{
2075  return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
2076}]>;
2077
2078def zext_is_sext : PatFrag<(ops node:$src), (zext node:$src), [{
2079  KnownBits Known = CurDAG->computeKnownBits(N->getOperand(0), 0);
2080  return Known.isNonNegative();
2081}]>;
2082
2083let Predicates = [IsRV64] in {
2084def : LdPat<sextloadi8, LB, i32>;
2085def : LdPat<extloadi8, LBU, i32>; // Prefer unsigned due to no c.lb in Zcb.
2086def : LdPat<sextloadi16, LH, i32>;
2087def : LdPat<extloadi16, LH, i32>;
2088def : LdPat<zextloadi8, LBU, i32>;
2089def : LdPat<zextloadi16, LHU, i32>;
2090
2091def : StPat<truncstorei8, SB, GPR, i32>;
2092def : StPat<truncstorei16, SH, GPR, i32>;
2093
2094def : Pat<(anyext GPR:$src), (COPY GPR:$src)>;
2095def : Pat<(sext GPR:$src), (ADDIW GPR:$src, 0)>;
2096def : Pat<(trunc GPR:$src), (COPY GPR:$src)>;
2097
2098def : PatGprGpr<add, ADDW, i32, i32>;
2099def : PatGprGpr<sub, SUBW, i32, i32>;
2100def : PatGprGpr<and, AND, i32, i32>;
2101def : PatGprGpr<or, OR, i32, i32>;
2102def : PatGprGpr<xor, XOR, i32, i32>;
2103def : PatGprGpr<shiftopw<shl>, SLLW, i32, i64>;
2104def : PatGprGpr<shiftopw<srl>, SRLW, i32, i64>;
2105def : PatGprGpr<shiftopw<sra>, SRAW, i32, i64>;
2106
2107def : Pat<(i32 (add GPR:$rs1, simm12i32:$imm)),
2108          (ADDIW GPR:$rs1, (i64 (as_i64imm $imm)))>;
2109def : Pat<(i32 (and GPR:$rs1, simm12i32:$imm)),
2110          (ANDI GPR:$rs1, (i64 (as_i64imm $imm)))>;
2111def : Pat<(i32 (or GPR:$rs1, simm12i32:$imm)),
2112          (ORI GPR:$rs1, (i64 (as_i64imm $imm)))>;
2113def : Pat<(i32 (xor GPR:$rs1, simm12i32:$imm)),
2114          (XORI GPR:$rs1, (i64 (as_i64imm $imm)))>;
2115
2116def : PatGprImm<shl, SLLIW, uimm5, i32>;
2117def : PatGprImm<srl, SRLIW, uimm5, i32>;
2118def : PatGprImm<sra, SRAIW, uimm5, i32>;
2119
2120def : Pat<(i32 (and GPR:$rs, TrailingOnesMask:$mask)),
2121          (SRLI (SLLI $rs, (i64 (XLenSubTrailingOnes $mask))),
2122                (i64 (XLenSubTrailingOnes $mask)))>;
2123
2124// Use sext if the sign bit of the input is 0.
2125def : Pat<(zext_is_sext GPR:$src), (ADDIW GPR:$src, 0)>;
2126}
2127
2128let Predicates = [IsRV64, NotHasStdExtZba] in {
2129def : Pat<(zext GPR:$src), (SRLI (SLLI GPR:$src, 32), 32)>;
2130
2131// If we're shifting a 32-bit zero extended value left by 0-31 bits, use 2
2132// shifts instead of 3. This can occur when unsigned is used to index an array.
2133def : Pat<(shl (zext GPR:$rs), uimm5:$shamt),
2134          (SRLI (SLLI GPR:$rs, 32), (ImmSubFrom32 uimm5:$shamt))>;
2135}
2136
2137//===----------------------------------------------------------------------===//
2138// Standard extensions
2139//===----------------------------------------------------------------------===//
2140
2141// Multiply and Division
2142include "RISCVInstrInfoM.td"
2143
2144// Atomic
2145include "RISCVInstrInfoA.td"
2146include "RISCVInstrInfoZa.td"
2147
2148// Scalar FP
2149include "RISCVInstrInfoF.td"
2150include "RISCVInstrInfoD.td"
2151include "RISCVInstrInfoZfh.td"
2152include "RISCVInstrInfoZfbfmin.td"
2153include "RISCVInstrInfoZfa.td"
2154
2155// Scalar bitmanip and cryptography
2156include "RISCVInstrInfoZb.td"
2157include "RISCVInstrInfoZk.td"
2158
2159// Vector
2160include "RISCVInstrInfoV.td"
2161include "RISCVInstrInfoZvk.td"
2162
2163// Compressed
2164include "RISCVInstrInfoC.td"
2165include "RISCVInstrInfoZc.td"
2166include "RISCVInstrInfoZcmop.td"
2167
2168// Integer
2169include "RISCVInstrInfoZimop.td"
2170include "RISCVInstrInfoZicbo.td"
2171include "RISCVInstrInfoZicond.td"
2172include "RISCVInstrInfoZicfiss.td"
2173
2174//===----------------------------------------------------------------------===//
2175// Vendor extensions
2176//===----------------------------------------------------------------------===//
2177
2178include "RISCVInstrInfoXVentana.td"
2179include "RISCVInstrInfoXTHead.td"
2180include "RISCVInstrInfoXSf.td"
2181include "RISCVInstrInfoXCV.td"
2182
2183//===----------------------------------------------------------------------===//
2184// Global ISel
2185//===----------------------------------------------------------------------===//
2186
2187include "RISCVInstrGISel.td"
2188