[DAGCombiner] Eliminate dead stores to stack.
[llvm-complete.git] / lib / Target / RISCV / RISCVInstrInfo.td
blobde9ea1990414aa006813859a6c17d1c129025f9d
1 //===-- RISCVInstrInfo.td - Target Description for RISCV ---*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the RISC-V instructions in TableGen format.
11 //===----------------------------------------------------------------------===//
13 include "RISCVInstrFormats.td"
15 //===----------------------------------------------------------------------===//
16 // RISC-V specific DAG Nodes.
17 //===----------------------------------------------------------------------===//
19 // Target-independent type requirements, but with target-specific formats.
20 def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>,
21                                        SDTCisVT<1, i32>]>;
22 def SDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
23                                      SDTCisVT<1, i32>]>;
25 // Target-dependent type requirements.
26 def SDT_RISCVCall     : SDTypeProfile<0, -1, [SDTCisVT<0, XLenVT>]>;
27 def SDT_RISCVSelectCC : SDTypeProfile<1, 5, [SDTCisSameAs<1, 2>,
28                                              SDTCisSameAs<0, 4>,
29                                              SDTCisSameAs<4, 5>]>;
31 // Target-independent nodes, but with target-specific formats.
32 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart,
33                            [SDNPHasChain, SDNPOutGlue]>;
34 def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd,
35                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
37 // Target-dependent nodes.
38 def riscv_call      : SDNode<"RISCVISD::CALL", SDT_RISCVCall,
39                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
40                               SDNPVariadic]>;
41 def riscv_ret_flag  : SDNode<"RISCVISD::RET_FLAG", SDTNone,
42                              [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
43 def riscv_uret_flag : SDNode<"RISCVISD::URET_FLAG", SDTNone,
44                              [SDNPHasChain, SDNPOptInGlue]>;
45 def riscv_sret_flag : SDNode<"RISCVISD::SRET_FLAG", SDTNone,
46                              [SDNPHasChain, SDNPOptInGlue]>;
47 def riscv_mret_flag : SDNode<"RISCVISD::MRET_FLAG", SDTNone,
48                              [SDNPHasChain, SDNPOptInGlue]>;
49 def riscv_selectcc  : SDNode<"RISCVISD::SELECT_CC", SDT_RISCVSelectCC,
50                              [SDNPInGlue]>;
51 def riscv_tail      : SDNode<"RISCVISD::TAIL", SDT_RISCVCall,
52                              [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue,
53                               SDNPVariadic]>;
54 def riscv_sllw      : SDNode<"RISCVISD::SLLW", SDTIntShiftOp>;
55 def riscv_sraw      : SDNode<"RISCVISD::SRAW", SDTIntShiftOp>;
56 def riscv_srlw      : SDNode<"RISCVISD::SRLW", SDTIntShiftOp>;
58 //===----------------------------------------------------------------------===//
59 // Operand and SDNode transformation definitions.
60 //===----------------------------------------------------------------------===//
62 class ImmXLenAsmOperand<string prefix, string suffix = ""> : AsmOperandClass {
63   let Name = prefix # "ImmXLen" # suffix;
64   let RenderMethod = "addImmOperands";
65   let DiagnosticType = !strconcat("Invalid", Name);
68 class ImmAsmOperand<string prefix, int width, string suffix> : AsmOperandClass {
69   let Name = prefix # "Imm" # width # suffix;
70   let RenderMethod = "addImmOperands";
71   let DiagnosticType = !strconcat("Invalid", Name);
74 class SImmAsmOperand<int width, string suffix = "">
75     : ImmAsmOperand<"S", width, suffix> {
78 class UImmAsmOperand<int width, string suffix = "">
79     : ImmAsmOperand<"U", width, suffix> {
82 def FenceArg : AsmOperandClass {
83   let Name = "FenceArg";
84   let RenderMethod = "addFenceArgOperands";
85   let DiagnosticType = "InvalidFenceArg";
88 def fencearg : Operand<XLenVT> {
89   let ParserMatchClass = FenceArg;
90   let PrintMethod = "printFenceArg";
91   let DecoderMethod = "decodeUImmOperand<4>";
94 def UImmLog2XLenAsmOperand : AsmOperandClass {
95   let Name = "UImmLog2XLen";
96   let RenderMethod = "addImmOperands";
97   let DiagnosticType = "InvalidUImmLog2XLen";
100 def uimmlog2xlen : Operand<XLenVT>, ImmLeaf<XLenVT, [{
101   if (Subtarget->is64Bit())
102     return isUInt<6>(Imm);
103   return isUInt<5>(Imm);
104 }]> {
105   let ParserMatchClass = UImmLog2XLenAsmOperand;
106   // TODO: should ensure invalid shamt is rejected when decoding.
107   let DecoderMethod = "decodeUImmOperand<6>";
108   let MCOperandPredicate = [{
109     int64_t Imm;
110     if (!MCOp.evaluateAsConstantImm(Imm))
111       return false;
112     if (STI.getTargetTriple().isArch64Bit())
113       return  isUInt<6>(Imm);
114     return isUInt<5>(Imm);
115   }];
118 def uimm5 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> {
119   let ParserMatchClass = UImmAsmOperand<5>;
120   let DecoderMethod = "decodeUImmOperand<5>";
123 def simm12 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<12>(Imm);}]> {
124   let ParserMatchClass = SImmAsmOperand<12>;
125   let EncoderMethod = "getImmOpValue";
126   let DecoderMethod = "decodeSImmOperand<12>";
127   let MCOperandPredicate = [{
128     int64_t Imm;
129     if (MCOp.evaluateAsConstantImm(Imm))
130       return isInt<12>(Imm);
131     return MCOp.isBareSymbolRef();
132   }];
135 // A 13-bit signed immediate where the least significant bit is zero.
136 def simm13_lsb0 : Operand<OtherVT> {
137   let ParserMatchClass = SImmAsmOperand<13, "Lsb0">;
138   let EncoderMethod = "getImmOpValueAsr1";
139   let DecoderMethod = "decodeSImmOperandAndLsl1<13>";
140   let MCOperandPredicate = [{
141     int64_t Imm;
142     if (MCOp.evaluateAsConstantImm(Imm))
143       return isShiftedInt<12, 1>(Imm);
144     return MCOp.isBareSymbolRef();
145   }];
148 class UImm20Operand : Operand<XLenVT> {
149   let EncoderMethod = "getImmOpValue";
150   let DecoderMethod = "decodeUImmOperand<20>";
151   let MCOperandPredicate = [{
152     int64_t Imm;
153     if (MCOp.evaluateAsConstantImm(Imm))
154       return isUInt<20>(Imm);
155     return MCOp.isBareSymbolRef();
156   }];
159 def uimm20_lui : UImm20Operand {
160   let ParserMatchClass = UImmAsmOperand<20, "LUI">;
162 def uimm20_auipc : UImm20Operand {
163   let ParserMatchClass = UImmAsmOperand<20, "AUIPC">;
166 def Simm21Lsb0JALAsmOperand : SImmAsmOperand<21, "Lsb0JAL"> {
167   let ParserMethod = "parseJALOffset";
170 // A 21-bit signed immediate where the least significant bit is zero.
171 def simm21_lsb0_jal : Operand<OtherVT> {
172   let ParserMatchClass = Simm21Lsb0JALAsmOperand;
173   let EncoderMethod = "getImmOpValueAsr1";
174   let DecoderMethod = "decodeSImmOperandAndLsl1<21>";
175   let MCOperandPredicate = [{
176     int64_t Imm;
177     if (MCOp.evaluateAsConstantImm(Imm))
178       return isShiftedInt<20, 1>(Imm);
179     return MCOp.isBareSymbolRef();
180   }];
183 def BareSymbol : AsmOperandClass {
184   let Name = "BareSymbol";
185   let RenderMethod = "addImmOperands";
186   let DiagnosticType = "InvalidBareSymbol";
187   let ParserMethod = "parseBareSymbol";
190 // A bare symbol.
191 def bare_symbol : Operand<XLenVT> {
192   let ParserMatchClass = BareSymbol;
195 def CSRSystemRegister : AsmOperandClass {
196   let Name = "CSRSystemRegister";
197   let ParserMethod = "parseCSRSystemRegister";
198   let DiagnosticType = "InvalidCSRSystemRegister";
201 def csr_sysreg : Operand<XLenVT> {
202   let ParserMatchClass = CSRSystemRegister;
203   let PrintMethod = "printCSRSystemRegister";
204   let DecoderMethod = "decodeUImmOperand<12>";
207 // A parameterized register class alternative to i32imm/i64imm from Target.td.
208 def ixlenimm : Operand<XLenVT>;
210 def ixlenimm_li : Operand<XLenVT> {
211   let ParserMatchClass = ImmXLenAsmOperand<"", "LI">;
214 // Standalone (codegen-only) immleaf patterns.
215 def simm32     : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>;
216 def simm32hi20 : ImmLeaf<XLenVT, [{return isShiftedInt<20, 12>(Imm);}]>;
217 // A mask value that won't affect significant shift bits.
218 def immbottomxlenset : ImmLeaf<XLenVT, [{
219   if (Subtarget->is64Bit())
220     return countTrailingOnes<uint64_t>(Imm) >= 6;
221   return countTrailingOnes<uint64_t>(Imm) >= 5;
222 }]>;
224 // Addressing modes.
225 // Necessary because a frameindex can't be matched directly in a pattern.
226 def AddrFI : ComplexPattern<iPTR, 1, "SelectAddrFI", [frameindex], []>;
228 // Extract least significant 12 bits from an immediate value and sign extend
229 // them.
230 def LO12Sext : SDNodeXForm<imm, [{
231   return CurDAG->getTargetConstant(SignExtend64<12>(N->getZExtValue()),
232                                    SDLoc(N), N->getValueType(0));
233 }]>;
235 // Extract the most significant 20 bits from an immediate value. Add 1 if bit
236 // 11 is 1, to compensate for the low 12 bits in the matching immediate addi
237 // or ld/st being negative.
238 def HI20 : SDNodeXForm<imm, [{
239   return CurDAG->getTargetConstant(((N->getZExtValue()+0x800) >> 12) & 0xfffff,
240                                    SDLoc(N), N->getValueType(0));
241 }]>;
243 //===----------------------------------------------------------------------===//
244 // Instruction Class Templates
245 //===----------------------------------------------------------------------===//
247 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
248 class BranchCC_rri<bits<3> funct3, string opcodestr>
249     : RVInstB<funct3, OPC_BRANCH, (outs),
250               (ins GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12),
251               opcodestr, "$rs1, $rs2, $imm12"> {
252   let isBranch = 1;
253   let isTerminator = 1;
256 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
257 class Load_ri<bits<3> funct3, string opcodestr>
258     : RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
259               opcodestr, "$rd, ${imm12}(${rs1})">;
261 // Operands for stores are in the order srcreg, base, offset rather than
262 // reflecting the order these fields are specified in the instruction
263 // encoding.
264 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
265 class Store_rri<bits<3> funct3, string opcodestr>
266     : RVInstS<funct3, OPC_STORE, (outs),
267               (ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
268               opcodestr, "$rs2, ${imm12}(${rs1})">;
270 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
271 class ALU_ri<bits<3> funct3, string opcodestr>
272     : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, simm12:$imm12),
273               opcodestr, "$rd, $rs1, $imm12">;
275 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
276 class Shift_ri<bit arithshift, bits<3> funct3, string opcodestr>
277     : RVInstIShift<arithshift, funct3, OPC_OP_IMM, (outs GPR:$rd),
278                    (ins GPR:$rs1, uimmlog2xlen:$shamt), opcodestr,
279                    "$rd, $rs1, $shamt">;
281 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
282 class ALU_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
283     : RVInstR<funct7, funct3, OPC_OP, (outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
284               opcodestr, "$rd, $rs1, $rs2">;
286 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
287 class CSR_ir<bits<3> funct3, string opcodestr>
288     : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),
289               opcodestr, "$rd, $imm12, $rs1">;
291 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
292 class CSR_ii<bits<3> funct3, string opcodestr>
293     : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd),
294               (ins csr_sysreg:$imm12, uimm5:$rs1),
295               opcodestr, "$rd, $imm12, $rs1">;
297 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
298 class ShiftW_ri<bit arithshift, bits<3> funct3, string opcodestr>
299     : RVInstIShiftW<arithshift, funct3, OPC_OP_IMM_32, (outs GPR:$rd),
300                     (ins GPR:$rs1, uimm5:$shamt), opcodestr,
301                     "$rd, $rs1, $shamt">;
303 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
304 class ALUW_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
305     : RVInstR<funct7, funct3, OPC_OP_32, (outs GPR:$rd),
306               (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
308 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
309 class Priv<string opcodestr, bits<7> funct7>
310     : RVInstR<funct7, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1, GPR:$rs2),
311               opcodestr, "">;
313 //===----------------------------------------------------------------------===//
314 // Instructions
315 //===----------------------------------------------------------------------===//
317 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
318 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
319 def LUI : RVInstU<OPC_LUI, (outs GPR:$rd), (ins uimm20_lui:$imm20),
320                   "lui", "$rd, $imm20">;
322 def AUIPC : RVInstU<OPC_AUIPC, (outs GPR:$rd), (ins uimm20_auipc:$imm20),
323                     "auipc", "$rd, $imm20">;
325 let isCall = 1 in
326 def JAL : RVInstJ<OPC_JAL, (outs GPR:$rd), (ins simm21_lsb0_jal:$imm20),
327                   "jal", "$rd, $imm20">;
329 let isCall = 1 in
330 def JALR : RVInstI<0b000, OPC_JALR, (outs GPR:$rd),
331                    (ins GPR:$rs1, simm12:$imm12),
332                    "jalr", "$rd, $rs1, $imm12">;
333 } // hasSideEffects = 0, mayLoad = 0, mayStore = 0
335 def BEQ  : BranchCC_rri<0b000, "beq">;
336 def BNE  : BranchCC_rri<0b001, "bne">;
337 def BLT  : BranchCC_rri<0b100, "blt">;
338 def BGE  : BranchCC_rri<0b101, "bge">;
339 def BLTU : BranchCC_rri<0b110, "bltu">;
340 def BGEU : BranchCC_rri<0b111, "bgeu">;
342 def LB  : Load_ri<0b000, "lb">;
343 def LH  : Load_ri<0b001, "lh">;
344 def LW  : Load_ri<0b010, "lw">;
345 def LBU : Load_ri<0b100, "lbu">;
346 def LHU : Load_ri<0b101, "lhu">;
348 def SB : Store_rri<0b000, "sb">;
349 def SH : Store_rri<0b001, "sh">;
350 def SW : Store_rri<0b010, "sw">;
352 // ADDI isn't always rematerializable, but isReMaterializable will be used as
353 // a hint which is verified in isReallyTriviallyReMaterializable.
354 let isReMaterializable = 1, isAsCheapAsAMove = 1 in
355 def ADDI  : ALU_ri<0b000, "addi">;
357 def SLTI  : ALU_ri<0b010, "slti">;
358 def SLTIU : ALU_ri<0b011, "sltiu">;
360 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
361 def XORI  : ALU_ri<0b100, "xori">;
362 def ORI   : ALU_ri<0b110, "ori">;
365 def ANDI  : ALU_ri<0b111, "andi">;
367 def SLLI : Shift_ri<0, 0b001, "slli">;
368 def SRLI : Shift_ri<0, 0b101, "srli">;
369 def SRAI : Shift_ri<1, 0b101, "srai">;
371 def ADD  : ALU_rr<0b0000000, 0b000, "add">;
372 def SUB  : ALU_rr<0b0100000, 0b000, "sub">;
373 def SLL  : ALU_rr<0b0000000, 0b001, "sll">;
374 def SLT  : ALU_rr<0b0000000, 0b010, "slt">;
375 def SLTU : ALU_rr<0b0000000, 0b011, "sltu">;
376 def XOR  : ALU_rr<0b0000000, 0b100, "xor">;
377 def SRL  : ALU_rr<0b0000000, 0b101, "srl">;
378 def SRA  : ALU_rr<0b0100000, 0b101, "sra">;
379 def OR   : ALU_rr<0b0000000, 0b110, "or">;
380 def AND  : ALU_rr<0b0000000, 0b111, "and">;
382 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in {
383 def FENCE : RVInstI<0b000, OPC_MISC_MEM, (outs),
384                     (ins fencearg:$pred, fencearg:$succ),
385                     "fence", "$pred, $succ"> {
386   bits<4> pred;
387   bits<4> succ;
389   let rs1 = 0;
390   let rd = 0;
391   let imm12 = {0b0000,pred,succ};
394 def FENCE_TSO : RVInstI<0b000, OPC_MISC_MEM, (outs), (ins), "fence.tso", ""> {
395   let rs1 = 0;
396   let rd = 0;
397   let imm12 = {0b1000,0b0011,0b0011};
400 def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", ""> {
401   let rs1 = 0;
402   let rd = 0;
403   let imm12 = 0;
406 def ECALL : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ecall", ""> {
407   let rs1 = 0;
408   let rd = 0;
409   let imm12 = 0;
412 def EBREAK : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "ebreak", ""> {
413   let rs1 = 0;
414   let rd = 0;
415   let imm12 = 1;
418 // This is a de facto standard (as set by GNU binutils) 32-bit unimplemented
419 // instruction (i.e., it should always trap, if your implementation has invalid
420 // instruction traps).
421 def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", ""> {
422   let rs1 = 0;
423   let rd = 0;
424   let imm12 = 0b110000000000;
426 } // hasSideEffects = 1, mayLoad = 0, mayStore = 0
428 def CSRRW : CSR_ir<0b001, "csrrw">;
429 def CSRRS : CSR_ir<0b010, "csrrs">;
430 def CSRRC : CSR_ir<0b011, "csrrc">;
432 def CSRRWI : CSR_ii<0b101, "csrrwi">;
433 def CSRRSI : CSR_ii<0b110, "csrrsi">;
434 def CSRRCI : CSR_ii<0b111, "csrrci">;
436 /// RV64I instructions
438 let Predicates = [IsRV64] in {
439 def LWU   : Load_ri<0b110, "lwu">;
440 def LD    : Load_ri<0b011, "ld">;
441 def SD    : Store_rri<0b011, "sd">;
443 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
444 def ADDIW : RVInstI<0b000, OPC_OP_IMM_32, (outs GPR:$rd),
445                     (ins GPR:$rs1, simm12:$imm12),
446                     "addiw", "$rd, $rs1, $imm12">;
448 def SLLIW : ShiftW_ri<0, 0b001, "slliw">;
449 def SRLIW : ShiftW_ri<0, 0b101, "srliw">;
450 def SRAIW : ShiftW_ri<1, 0b101, "sraiw">;
452 def ADDW  : ALUW_rr<0b0000000, 0b000, "addw">;
453 def SUBW  : ALUW_rr<0b0100000, 0b000, "subw">;
454 def SLLW  : ALUW_rr<0b0000000, 0b001, "sllw">;
455 def SRLW  : ALUW_rr<0b0000000, 0b101, "srlw">;
456 def SRAW  : ALUW_rr<0b0100000, 0b101, "sraw">;
457 } // Predicates = [IsRV64]
459 //===----------------------------------------------------------------------===//
460 // Privileged instructions
461 //===----------------------------------------------------------------------===//
463 let isBarrier = 1, isReturn = 1, isTerminator = 1 in {
464 def URET : Priv<"uret", 0b0000000> {
465   let rd = 0;
466   let rs1 = 0;
467   let rs2 = 0b00010;
470 def SRET : Priv<"sret", 0b0001000> {
471   let rd = 0;
472   let rs1 = 0;
473   let rs2 = 0b00010;
476 def MRET : Priv<"mret", 0b0011000> {
477   let rd = 0;
478   let rs1 = 0;
479   let rs2 = 0b00010;
481 } // isBarrier = 1, isReturn = 1, isTerminator = 1
483 def WFI : Priv<"wfi", 0b0001000> {
484   let rd = 0;
485   let rs1 = 0;
486   let rs2 = 0b00101;
489 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
490 def SFENCE_VMA : RVInstR<0b0001001, 0b000, OPC_SYSTEM, (outs),
491                          (ins GPR:$rs1, GPR:$rs2),
492                          "sfence.vma", "$rs1, $rs2"> {
493   let rd = 0;
496 //===----------------------------------------------------------------------===//
497 // Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
498 //===----------------------------------------------------------------------===//
500 // TODO lb lh lw
501 // TODO RV64I: ld
502 // TODO sb sh sw
503 // TODO RV64I: sd
505 def : InstAlias<"nop",           (ADDI      X0,      X0,       0)>;
507 // Note that the size is 32 because up to 8 32-bit instructions are needed to
508 // generate an arbitrary 64-bit immediate. However, the size does not really
509 // matter since PseudoLI is currently only used in the AsmParser where it gets
510 // expanded to real instructions immediately.
511 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 32,
512     isCodeGenOnly = 0, isAsmParserOnly = 1 in
513 def PseudoLI : Pseudo<(outs GPR:$rd), (ins ixlenimm_li:$imm), [],
514                       "li", "$rd, $imm">;
516 def : InstAlias<"mv $rd, $rs",   (ADDI GPR:$rd, GPR:$rs,       0)>;
517 def : InstAlias<"not $rd, $rs",  (XORI GPR:$rd, GPR:$rs,      -1)>;
518 def : InstAlias<"neg $rd, $rs",  (SUB  GPR:$rd,      X0, GPR:$rs)>;
520 let Predicates = [IsRV64] in {
521 def : InstAlias<"negw $rd, $rs",   (SUBW  GPR:$rd,      X0, GPR:$rs)>;
522 def : InstAlias<"sext.w $rd, $rs", (ADDIW GPR:$rd, GPR:$rs,       0)>;
523 } // Predicates = [IsRV64]
525 def : InstAlias<"seqz $rd, $rs", (SLTIU GPR:$rd, GPR:$rs,       1)>;
526 def : InstAlias<"snez $rd, $rs", (SLTU  GPR:$rd,      X0, GPR:$rs)>;
527 def : InstAlias<"sltz $rd, $rs", (SLT   GPR:$rd, GPR:$rs,      X0)>;
528 def : InstAlias<"sgtz $rd, $rs", (SLT   GPR:$rd,      X0, GPR:$rs)>;
530 // sgt/sgtu are recognised by the GNU assembler but the canonical slt/sltu
531 // form will always be printed. Therefore, set a zero weight.
532 def : InstAlias<"sgt $rd, $rs, $rt", (SLT GPR:$rd, GPR:$rt, GPR:$rs), 0>;
533 def : InstAlias<"sgtu $rd, $rs, $rt", (SLTU GPR:$rd, GPR:$rt, GPR:$rs), 0>;
535 def : InstAlias<"beqz $rs, $offset",
536                 (BEQ GPR:$rs,      X0, simm13_lsb0:$offset)>;
537 def : InstAlias<"bnez $rs, $offset",
538                 (BNE GPR:$rs,      X0, simm13_lsb0:$offset)>;
539 def : InstAlias<"blez $rs, $offset",
540                 (BGE      X0, GPR:$rs, simm13_lsb0:$offset)>;
541 def : InstAlias<"bgez $rs, $offset",
542                 (BGE GPR:$rs,      X0, simm13_lsb0:$offset)>;
543 def : InstAlias<"bltz $rs, $offset",
544                 (BLT GPR:$rs,      X0, simm13_lsb0:$offset)>;
545 def : InstAlias<"bgtz $rs, $offset",
546                 (BLT      X0, GPR:$rs, simm13_lsb0:$offset)>;
548 // Always output the canonical mnemonic for the pseudo branch instructions.
549 // The GNU tools emit the canonical mnemonic for the branch pseudo instructions
550 // as well (e.g. "bgt" will be recognised by the assembler but never printed by
551 // objdump). Match this behaviour by setting a zero weight.
552 def : InstAlias<"bgt $rs, $rt, $offset",
553                 (BLT  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
554 def : InstAlias<"ble $rs, $rt, $offset",
555                 (BGE  GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
556 def : InstAlias<"bgtu $rs, $rt, $offset",
557                 (BLTU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
558 def : InstAlias<"bleu $rs, $rt, $offset",
559                 (BGEU GPR:$rt, GPR:$rs, simm13_lsb0:$offset), 0>;
561 // "ret" has more weight since "ret" and "jr" alias the same "jalr" instruction.
562 def : InstAlias<"j $offset",   (JAL  X0, simm21_lsb0_jal:$offset)>;
563 def : InstAlias<"jal $offset", (JAL  X1, simm21_lsb0_jal:$offset)>;
564 def : InstAlias<"jr $rs",      (JALR X0, GPR:$rs, 0)>;
565 def : InstAlias<"jalr $rs",    (JALR X1, GPR:$rs, 0)>;
566 def : InstAlias<"ret",         (JALR X0,      X1, 0), 2>;
567 // TODO call
568 // TODO tail
570 def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
572 // CSR Addresses: 0xC00 == cycle,  0xC01 == time,  0xC02 == instret
573 //                0xC80 == cycleh, 0xC81 == timeh, 0xC82 == instreth
574 def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, 0xC02, X0)>;
575 def : InstAlias<"rdcycle $rd",   (CSRRS GPR:$rd, 0xC00, X0)>;
576 def : InstAlias<"rdtime $rd",    (CSRRS GPR:$rd, 0xC01, X0)>;
578 let Predicates = [IsRV32] in {
579 def : InstAlias<"rdinstreth $rd", (CSRRS GPR:$rd, 0xC82, X0)>;
580 def : InstAlias<"rdcycleh $rd",   (CSRRS GPR:$rd, 0xC80, X0)>;
581 def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, 0xC81, X0)>;
582 } // Predicates = [IsRV32]
584 def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;
585 def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;
586 def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;
587 def : InstAlias<"csrc $csr, $rs", (CSRRC      X0, csr_sysreg:$csr, GPR:$rs)>;
589 def : InstAlias<"csrwi $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
590 def : InstAlias<"csrsi $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
591 def : InstAlias<"csrci $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
593 let EmitPriority = 0 in {
594 def : InstAlias<"csrw $csr, $imm", (CSRRWI X0, csr_sysreg:$csr, uimm5:$imm)>;
595 def : InstAlias<"csrs $csr, $imm", (CSRRSI X0, csr_sysreg:$csr, uimm5:$imm)>;
596 def : InstAlias<"csrc $csr, $imm", (CSRRCI X0, csr_sysreg:$csr, uimm5:$imm)>;
598 def : InstAlias<"csrrw $rd, $csr, $imm", (CSRRWI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
599 def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
600 def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
603 def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
604 def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
606 let EmitPriority = 0 in {
607 def : InstAlias<"add $rd, $rs1, $imm12",
608                 (ADDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
609 def : InstAlias<"and $rd, $rs1, $imm12",
610                 (ANDI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
611 def : InstAlias<"xor $rd, $rs1, $imm12",
612                 (XORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
613 def : InstAlias<"or $rd, $rs1, $imm12",
614                 (ORI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
615 def : InstAlias<"sll $rd, $rs1, $shamt",
616                 (SLLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
617 def : InstAlias<"srl $rd, $rs1, $shamt",
618                 (SRLI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
619 def : InstAlias<"sra $rd, $rs1, $shamt",
620                 (SRAI  GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt)>;
621 let Predicates = [IsRV64] in {
622 def : InstAlias<"addw $rd, $rs1, $imm12",
623                 (ADDIW  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
624 def : InstAlias<"sllw $rd, $rs1, $shamt",
625                 (SLLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
626 def : InstAlias<"srlw $rd, $rs1, $shamt",
627                 (SRLIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
628 def : InstAlias<"sraw $rd, $rs1, $shamt",
629                 (SRAIW  GPR:$rd, GPR:$rs1, uimm5:$shamt)>;
630 } // Predicates = [IsRV64]
631 def : InstAlias<"slt $rd, $rs1, $imm12",
632                 (SLTI  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
633 def : InstAlias<"sltu $rd, $rs1, $imm12",
634                 (SLTIU  GPR:$rd, GPR:$rs1, simm12:$imm12)>;
637 def : MnemonicAlias<"move", "mv">;
639 // The SCALL and SBREAK instructions wererenamed to ECALL and EBREAK in
640 // version 2.1 of the user-level ISA. Like the GNU toolchain, we still accept
641 // the old name for backwards compatibility.
642 def : MnemonicAlias<"scall", "ecall">;
643 def : MnemonicAlias<"sbreak", "ebreak">;
645 //===----------------------------------------------------------------------===//
646 // Pseudo-instructions and codegen patterns
648 // Naming convention: For 'generic' pattern classes, we use the naming
649 // convention PatTy1Ty2. For pattern classes which offer a more complex
650 // expension, prefix the class name, e.g. BccPat.
651 //===----------------------------------------------------------------------===//
653 /// Generic pattern classes
655 class PatGprGpr<SDPatternOperator OpNode, RVInst Inst>
656     : Pat<(OpNode GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>;
657 class PatGprSimm12<SDPatternOperator OpNode, RVInstI Inst>
658     : Pat<(OpNode GPR:$rs1, simm12:$imm12), (Inst GPR:$rs1, simm12:$imm12)>;
659 class PatGprUimmLog2XLen<SDPatternOperator OpNode, RVInstIShift Inst>
660     : Pat<(OpNode GPR:$rs1, uimmlog2xlen:$shamt),
661           (Inst GPR:$rs1, uimmlog2xlen:$shamt)>;
663 /// Predicates
665 def IsOrAdd: PatFrag<(ops node:$A, node:$B), (or node:$A, node:$B), [{
666   return isOrEquivalentToAdd(N);
667 }]>;
668 def assertsexti32 : PatFrag<(ops node:$src), (assertsext node:$src), [{
669   return cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32;
670 }]>;
671 def sexti32 : PatFrags<(ops node:$src),
672                        [(sext_inreg node:$src, i32),
673                         (assertsexti32 node:$src)]>;
674 def assertzexti32 : PatFrag<(ops node:$src), (assertzext node:$src), [{
675   return cast<VTSDNode>(N->getOperand(1))->getVT() == MVT::i32;
676 }]>;
677 def zexti32 : PatFrags<(ops node:$src),
678                        [(and node:$src, 0xffffffff),
679                         (assertzexti32 node:$src)]>;
681 /// Immediates
683 def : Pat<(simm12:$imm), (ADDI X0, simm12:$imm)>;
684 def : Pat<(simm32hi20:$imm), (LUI (HI20 imm:$imm))>;
685 def : Pat<(simm32:$imm), (ADDI (LUI (HI20 imm:$imm)), (LO12Sext imm:$imm))>,
686       Requires<[IsRV32]>;
688 /// Simple arithmetic operations
690 def : PatGprGpr<add, ADD>;
691 def : PatGprSimm12<add, ADDI>;
692 def : PatGprGpr<sub, SUB>;
693 def : PatGprGpr<or, OR>;
694 def : PatGprSimm12<or, ORI>;
695 def : PatGprGpr<and, AND>;
696 def : PatGprSimm12<and, ANDI>;
697 def : PatGprGpr<xor, XOR>;
698 def : PatGprSimm12<xor, XORI>;
699 def : PatGprUimmLog2XLen<shl, SLLI>;
700 def : PatGprUimmLog2XLen<srl, SRLI>;
701 def : PatGprUimmLog2XLen<sra, SRAI>;
703 // Match both a plain shift and one where the shift amount is masked (this is
704 // typically introduced when the legalizer promotes the shift amount and
705 // zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base
706 // ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I).
707 class shiftop<SDPatternOperator operator>
708     : PatFrags<(ops node:$val, node:$count),
709                [(operator node:$val, node:$count),
710                 (operator node:$val, (and node:$count, immbottomxlenset))]>;
712 def : PatGprGpr<shiftop<shl>, SLL>;
713 def : PatGprGpr<shiftop<srl>, SRL>;
714 def : PatGprGpr<shiftop<sra>, SRA>;
716 /// FrameIndex calculations
718 def : Pat<(add (i32 AddrFI:$Rs), simm12:$imm12),
719           (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>;
720 def : Pat<(IsOrAdd (i32 AddrFI:$Rs), simm12:$imm12),
721           (ADDI (i32 AddrFI:$Rs), simm12:$imm12)>;
723 /// Setcc
725 def : PatGprGpr<setlt, SLT>;
726 def : PatGprSimm12<setlt, SLTI>;
727 def : PatGprGpr<setult, SLTU>;
728 def : PatGprSimm12<setult, SLTIU>;
730 // Define pattern expansions for setcc operations that aren't directly
731 // handled by a RISC-V instruction.
732 def : Pat<(seteq GPR:$rs1, 0), (SLTIU GPR:$rs1, 1)>;
733 def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
734 def : Pat<(setne GPR:$rs1, 0), (SLTU X0, GPR:$rs1)>;
735 def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
736 def : Pat<(setugt GPR:$rs1, GPR:$rs2), (SLTU GPR:$rs2, GPR:$rs1)>;
737 def : Pat<(setuge GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
738 def : Pat<(setule GPR:$rs1, GPR:$rs2), (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
739 def : Pat<(setgt GPR:$rs1, GPR:$rs2), (SLT GPR:$rs2, GPR:$rs1)>;
740 def : Pat<(setge GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
741 def : Pat<(setle GPR:$rs1, GPR:$rs2), (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
743 let usesCustomInserter = 1 in
744 class SelectCC_rrirr<RegisterClass valty, RegisterClass cmpty>
745     : Pseudo<(outs valty:$dst),
746              (ins cmpty:$lhs, cmpty:$rhs, ixlenimm:$imm,
747               valty:$truev, valty:$falsev),
748              [(set valty:$dst, (riscv_selectcc cmpty:$lhs, cmpty:$rhs,
749               (XLenVT imm:$imm), valty:$truev, valty:$falsev))]>;
751 def Select_GPR_Using_CC_GPR : SelectCC_rrirr<GPR, GPR>;
753 /// Branches and jumps
755 // Match `(brcond (CondOp ..), ..)` and lower to the appropriate RISC-V branch
756 // instruction.
757 class BccPat<PatFrag CondOp, RVInstB Inst>
758     : Pat<(brcond (XLenVT (CondOp GPR:$rs1, GPR:$rs2)), bb:$imm12),
759           (Inst GPR:$rs1, GPR:$rs2, simm13_lsb0:$imm12)>;
761 def : BccPat<seteq, BEQ>;
762 def : BccPat<setne, BNE>;
763 def : BccPat<setlt, BLT>;
764 def : BccPat<setge, BGE>;
765 def : BccPat<setult, BLTU>;
766 def : BccPat<setuge, BGEU>;
768 class BccSwapPat<PatFrag CondOp, RVInst InstBcc>
769     : Pat<(brcond (XLenVT (CondOp GPR:$rs1, GPR:$rs2)), bb:$imm12),
770           (InstBcc GPR:$rs2, GPR:$rs1, bb:$imm12)>;
772 // Condition codes that don't have matching RISC-V branch instructions, but
773 // are trivially supported by swapping the two input operands
774 def : BccSwapPat<setgt, BLT>;
775 def : BccSwapPat<setle, BGE>;
776 def : BccSwapPat<setugt, BLTU>;
777 def : BccSwapPat<setule, BGEU>;
779 // An extra pattern is needed for a brcond without a setcc (i.e. where the
780 // condition was calculated elsewhere).
781 def : Pat<(brcond GPR:$cond, bb:$imm12), (BNE GPR:$cond, X0, bb:$imm12)>;
783 let isBarrier = 1, isBranch = 1, isTerminator = 1 in
784 def PseudoBR : Pseudo<(outs), (ins simm21_lsb0_jal:$imm20), [(br bb:$imm20)]>,
785                PseudoInstExpansion<(JAL X0, simm21_lsb0_jal:$imm20)>;
787 let isCall = 1, Defs=[X1] in
788 let isBarrier = 1, isBranch = 1, isIndirectBranch = 1, isTerminator = 1 in
789 def PseudoBRIND : Pseudo<(outs), (ins GPR:$rs1, simm12:$imm12), []>,
790                   PseudoInstExpansion<(JALR X0, GPR:$rs1, simm12:$imm12)>;
792 def : Pat<(brind GPR:$rs1), (PseudoBRIND GPR:$rs1, 0)>;
793 def : Pat<(brind (add GPR:$rs1, simm12:$imm12)),
794           (PseudoBRIND GPR:$rs1, simm12:$imm12)>;
796 // PseudoCALL is a pseudo instruction which will eventually expand to auipc
797 // and jalr while encoding. This is desirable, as an auipc+jalr pair with
798 // R_RISCV_CALL and R_RISCV_RELAX relocations can be be relaxed by the linker
799 // if the offset fits in a signed 21-bit immediate.
800 // Define AsmString to print "call" when compile with -S flag.
801 // Define isCodeGenOnly = 0 to support parsing assembly "call" instruction.
802 let isCall = 1, Defs = [X1], isCodeGenOnly = 0 in
803 def PseudoCALL : Pseudo<(outs), (ins bare_symbol:$func),
804                         [(riscv_call tglobaladdr:$func)]> {
805   let AsmString = "call\t$func";
808 def : Pat<(riscv_call texternalsym:$func), (PseudoCALL texternalsym:$func)>;
810 def : Pat<(riscv_uret_flag), (URET X0, X0)>;
811 def : Pat<(riscv_sret_flag), (SRET X0, X0)>;
812 def : Pat<(riscv_mret_flag), (MRET X0, X0)>;
814 let isCall = 1, Defs = [X1] in
815 def PseudoCALLIndirect : Pseudo<(outs), (ins GPR:$rs1),
816                                 [(riscv_call GPR:$rs1)]>,
817                          PseudoInstExpansion<(JALR X1, GPR:$rs1, 0)>;
819 let isBarrier = 1, isReturn = 1, isTerminator = 1 in
820 def PseudoRET : Pseudo<(outs), (ins), [(riscv_ret_flag)]>,
821                 PseudoInstExpansion<(JALR X0, X1, 0)>;
823 // PseudoTAIL is a pseudo instruction similar to PseudoCALL and will eventually
824 // expand to auipc and jalr while encoding.
825 // Define AsmString to print "tail" when compile with -S flag.
826 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2],
827     isCodeGenOnly = 0 in
828 def PseudoTAIL : Pseudo<(outs), (ins bare_symbol:$dst), []> {
829   let AsmString = "tail\t$dst";
832 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, Uses = [X2] in
833 def PseudoTAILIndirect : Pseudo<(outs), (ins GPRTC:$rs1),
834                                 [(riscv_tail GPRTC:$rs1)]>,
835                          PseudoInstExpansion<(JALR X0, GPR:$rs1, 0)>;
837 def : Pat<(riscv_tail (iPTR tglobaladdr:$dst)),
838           (PseudoTAIL texternalsym:$dst)>;
839 def : Pat<(riscv_tail (iPTR texternalsym:$dst)),
840           (PseudoTAIL texternalsym:$dst)>;
842 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 0,
843     isAsmParserOnly = 1 in
844 def PseudoLLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
845                        "lla", "$dst, $src">;
847 let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 0,
848     isAsmParserOnly = 1 in
849 def PseudoLA : Pseudo<(outs GPR:$dst), (ins bare_symbol:$src), [],
850                       "la", "$dst, $src">;
852 /// Loads
854 multiclass LdPat<PatFrag LoadOp, RVInst Inst> {
855   def : Pat<(LoadOp GPR:$rs1), (Inst GPR:$rs1, 0)>;
856   def : Pat<(LoadOp AddrFI:$rs1), (Inst AddrFI:$rs1, 0)>;
857   def : Pat<(LoadOp (add GPR:$rs1, simm12:$imm12)),
858             (Inst GPR:$rs1, simm12:$imm12)>;
859   def : Pat<(LoadOp (add AddrFI:$rs1, simm12:$imm12)),
860             (Inst AddrFI:$rs1, simm12:$imm12)>;
861   def : Pat<(LoadOp (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
862             (Inst AddrFI:$rs1, simm12:$imm12)>;
865 defm : LdPat<sextloadi8, LB>;
866 defm : LdPat<extloadi8, LB>;
867 defm : LdPat<sextloadi16, LH>;
868 defm : LdPat<extloadi16, LH>;
869 defm : LdPat<load, LW>, Requires<[IsRV32]>;
870 defm : LdPat<zextloadi8, LBU>;
871 defm : LdPat<zextloadi16, LHU>;
873 /// Stores
875 multiclass StPat<PatFrag StoreOp, RVInst Inst, RegisterClass StTy> {
876   def : Pat<(StoreOp StTy:$rs2, GPR:$rs1), (Inst StTy:$rs2, GPR:$rs1, 0)>;
877   def : Pat<(StoreOp StTy:$rs2, AddrFI:$rs1), (Inst StTy:$rs2, AddrFI:$rs1, 0)>;
878   def : Pat<(StoreOp StTy:$rs2, (add GPR:$rs1, simm12:$imm12)),
879             (Inst StTy:$rs2, GPR:$rs1, simm12:$imm12)>;
880   def : Pat<(StoreOp StTy:$rs2, (add AddrFI:$rs1, simm12:$imm12)),
881             (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
882   def : Pat<(StoreOp StTy:$rs2, (IsOrAdd AddrFI:$rs1, simm12:$imm12)),
883             (Inst StTy:$rs2, AddrFI:$rs1, simm12:$imm12)>;
886 defm : StPat<truncstorei8, SB, GPR>;
887 defm : StPat<truncstorei16, SH, GPR>;
888 defm : StPat<store, SW, GPR>, Requires<[IsRV32]>;
890 /// Fences
892 // Refer to Table A.6 in the version 2.3 draft of the RISC-V Instruction Set
893 // Manual: Volume I.
895 // fence acquire -> fence r, rw
896 def : Pat<(atomic_fence (XLenVT 4), (imm)), (FENCE 0b10, 0b11)>;
897 // fence release -> fence rw, w
898 def : Pat<(atomic_fence (XLenVT 5), (imm)), (FENCE 0b11, 0b1)>;
899 // fence acq_rel -> fence.tso
900 def : Pat<(atomic_fence (XLenVT 6), (imm)), (FENCE_TSO)>;
901 // fence seq_cst -> fence rw, rw
902 def : Pat<(atomic_fence (XLenVT 7), (imm)), (FENCE 0b11, 0b11)>;
904 // Lowering for atomic load and store is defined in RISCVInstrInfoA.td.
905 // Although these are lowered to fence+load/store instructions defined in the
906 // base RV32I/RV64I ISA, this lowering is only used when the A extension is
907 // present. This is necessary as it isn't valid to mix __atomic_* libcalls
908 // with inline atomic operations for the same object.
910 /// Other pseudo-instructions
912 // Pessimistically assume the stack pointer will be clobbered
913 let Defs = [X2], Uses = [X2] in {
914 def ADJCALLSTACKDOWN : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
915                               [(callseq_start timm:$amt1, timm:$amt2)]>;
916 def ADJCALLSTACKUP   : Pseudo<(outs), (ins i32imm:$amt1, i32imm:$amt2),
917                               [(callseq_end timm:$amt1, timm:$amt2)]>;
918 } // Defs = [X2], Uses = [X2]
920 /// RV64 patterns
922 let Predicates = [IsRV64] in {
924 /// sext and zext
926 def : Pat<(sext_inreg GPR:$rs1, i32), (ADDIW GPR:$rs1, 0)>;
927 def : Pat<(and GPR:$rs1, 0xffffffff), (SRLI (SLLI GPR:$rs1, 32), 32)>;
929 /// ALU operations
931 def : Pat<(sext_inreg (add GPR:$rs1, GPR:$rs2), i32),
932           (ADDW GPR:$rs1, GPR:$rs2)>;
933 def : Pat<(sext_inreg (add GPR:$rs1, simm12:$imm12), i32),
934           (ADDIW GPR:$rs1, simm12:$imm12)>;
935 def : Pat<(sext_inreg (sub GPR:$rs1, GPR:$rs2), i32),
936           (SUBW GPR:$rs1, GPR:$rs2)>;
937 def : Pat<(sext_inreg (shl GPR:$rs1, uimm5:$shamt), i32),
938           (SLLIW GPR:$rs1, uimm5:$shamt)>;
939 // (srl (zexti32 ...), uimm5:$shamt) is matched with custom code due to the
940 // need to undo manipulation of the mask value performed by DAGCombine.
941 def : Pat<(sra (sext_inreg GPR:$rs1, i32), uimm5:$shamt),
942           (SRAIW GPR:$rs1, uimm5:$shamt)>;
944 def : PatGprGpr<riscv_sllw, SLLW>;
945 def : PatGprGpr<riscv_srlw, SRLW>;
946 def : PatGprGpr<riscv_sraw, SRAW>;
948 /// Loads
950 defm : LdPat<sextloadi32, LW>;
951 defm : LdPat<extloadi32, LW>;
952 defm : LdPat<zextloadi32, LWU>;
953 defm : LdPat<load, LD>;
955 /// Stores
957 defm : StPat<truncstorei32, SW, GPR>;
958 defm : StPat<store, SD, GPR>;
959 } // Predicates = [IsRV64]
961 //===----------------------------------------------------------------------===//
962 // Standard extensions
963 //===----------------------------------------------------------------------===//
965 include "RISCVInstrInfoM.td"
966 include "RISCVInstrInfoA.td"
967 include "RISCVInstrInfoF.td"
968 include "RISCVInstrInfoD.td"
969 include "RISCVInstrInfoC.td"