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