[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / lib / Target / RISCV / RISCVInstrInfoC.td
bloba8809a8fbad6b7e46ebd98ad54582aa703db4275
1 //===- RISCVInstrInfoC.td - Compressed RISCV instructions -*- tblgen-*-----===//
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 //===----------------------------------------------------------------------===//
9 include "RISCVInstrFormatsC.td"
11 //===----------------------------------------------------------------------===//
12 // Operand definitions.
13 //===----------------------------------------------------------------------===//
15 def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16   let Name = "UImmLog2XLenNonZero";
17   let RenderMethod = "addImmOperands";
18   let DiagnosticType = "InvalidUImmLog2XLenNonZero";
21 def uimmlog2xlennonzero : Operand<XLenVT>, ImmLeaf<XLenVT, [{
22   if (Subtarget->is64Bit())
23     return isUInt<6>(Imm) && (Imm != 0);
24   return isUInt<5>(Imm) && (Imm != 0);
25 }]> {
26   let ParserMatchClass = UImmLog2XLenNonZeroAsmOperand;
27   // TODO: should ensure invalid shamt is rejected when decoding.
28   let DecoderMethod = "decodeUImmOperand<6>";
29   let MCOperandPredicate = [{
30     int64_t Imm;
31     if (!MCOp.evaluateAsConstantImm(Imm))
32       return false;
33     if (STI.getTargetTriple().isArch64Bit())
34       return  isUInt<6>(Imm) && (Imm != 0);
35     return isUInt<5>(Imm) && (Imm != 0);
36   }];
39 def simm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
40   let ParserMatchClass = SImmAsmOperand<6>;
41   let EncoderMethod = "getImmOpValue";
42   let DecoderMethod = "decodeSImmOperand<6>";
43   let MCOperandPredicate = [{
44     int64_t Imm;
45     if (MCOp.evaluateAsConstantImm(Imm))
46       return isInt<6>(Imm);
47     return MCOp.isBareSymbolRef();
48   }];
51 def simm6nonzero : Operand<XLenVT>,
52                    ImmLeaf<XLenVT, [{return (Imm != 0) && isInt<6>(Imm);}]> {
53   let ParserMatchClass = SImmAsmOperand<6, "NonZero">;
54   let EncoderMethod = "getImmOpValue";
55   let DecoderMethod = "decodeSImmOperand<6>";
56   let MCOperandPredicate = [{
57     int64_t Imm;
58     if (MCOp.evaluateAsConstantImm(Imm))
59       return (Imm != 0) && isInt<6>(Imm);
60     return MCOp.isBareSymbolRef();
61   }];
64 def immzero : Operand<XLenVT>,
65               ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
66   let ParserMatchClass = ImmZeroAsmOperand;
69 def CLUIImmAsmOperand : AsmOperandClass {
70   let Name = "CLUIImm";
71   let RenderMethod = "addImmOperands";
72   let DiagnosticType = !strconcat("Invalid", Name);
76 // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
77 // The RISC-V ISA describes the constraint as [1, 63], with that value being
78 // loaded in to bits 17-12 of the destination register and sign extended from
79 // bit 17. Therefore, this 6-bit immediate can represent values in the ranges
80 // [1, 31] and [0xfffe0, 0xfffff].
81 def c_lui_imm : Operand<XLenVT>,
82                 ImmLeaf<XLenVT, [{return (Imm != 0) &&
83                                  (isUInt<5>(Imm) ||
84                                   (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
85   let ParserMatchClass = CLUIImmAsmOperand;
86   let EncoderMethod = "getImmOpValue";
87   let DecoderMethod = "decodeCLUIImmOperand";
88   let MCOperandPredicate = [{
89     int64_t Imm;
90     if (MCOp.evaluateAsConstantImm(Imm))
91       return (Imm != 0) && (isUInt<5>(Imm) ||
92              (Imm >= 0xfffe0 && Imm <= 0xfffff));
93     return MCOp.isBareSymbolRef();
94   }];
97 // A 7-bit unsigned immediate where the least significant two bits are zero.
98 def uimm7_lsb00 : Operand<XLenVT>,
99                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
100   let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
101   let EncoderMethod = "getImmOpValue";
102   let DecoderMethod = "decodeUImmOperand<7>";
103   let MCOperandPredicate = [{
104     int64_t Imm;
105     if (!MCOp.evaluateAsConstantImm(Imm))
106       return false;
107     return isShiftedUInt<5, 2>(Imm);
108   }];
111 // A 8-bit unsigned immediate where the least significant two bits are zero.
112 def uimm8_lsb00 : Operand<XLenVT>,
113                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
114   let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
115   let EncoderMethod = "getImmOpValue";
116   let DecoderMethod = "decodeUImmOperand<8>";
117   let MCOperandPredicate = [{
118     int64_t Imm;
119     if (!MCOp.evaluateAsConstantImm(Imm))
120       return false;
121     return isShiftedUInt<6, 2>(Imm);
122   }];
125 // A 8-bit unsigned immediate where the least significant three bits are zero.
126 def uimm8_lsb000 : Operand<XLenVT>,
127                    ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
128   let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
129   let EncoderMethod = "getImmOpValue";
130   let DecoderMethod = "decodeUImmOperand<8>";
131   let MCOperandPredicate = [{
132     int64_t Imm;
133     if (!MCOp.evaluateAsConstantImm(Imm))
134       return false;
135     return isShiftedUInt<5, 3>(Imm);
136   }];
139 // A 9-bit signed immediate where the least significant bit is zero.
140 def simm9_lsb0 : Operand<OtherVT> {
141   let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
142   let EncoderMethod = "getImmOpValueAsr1";
143   let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
144   let MCOperandPredicate = [{
145     int64_t Imm;
146     if (MCOp.evaluateAsConstantImm(Imm))
147       return isShiftedInt<8, 1>(Imm);
148     return MCOp.isBareSymbolRef();
150   }];
153 // A 9-bit unsigned immediate where the least significant three bits are zero.
154 def uimm9_lsb000 : Operand<XLenVT>,
155                    ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
156   let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
157   let EncoderMethod = "getImmOpValue";
158   let DecoderMethod = "decodeUImmOperand<9>";
159   let MCOperandPredicate = [{
160     int64_t Imm;
161     if (!MCOp.evaluateAsConstantImm(Imm))
162       return false;
163     return isShiftedUInt<6, 3>(Imm);
164   }];
167 // A 10-bit unsigned immediate where the least significant two bits are zero
168 // and the immediate can't be zero.
169 def uimm10_lsb00nonzero : Operand<XLenVT>,
170                           ImmLeaf<XLenVT,
171                           [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
172   let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
173   let EncoderMethod = "getImmOpValue";
174   let DecoderMethod = "decodeUImmNonZeroOperand<10>";
175   let MCOperandPredicate = [{
176     int64_t Imm;
177     if (!MCOp.evaluateAsConstantImm(Imm))
178       return false;
179     return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
180   }];
183 // A 10-bit signed immediate where the least significant four bits are zero.
184 def simm10_lsb0000nonzero : Operand<XLenVT>,
185                             ImmLeaf<XLenVT,
186                             [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
187   let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
188   let EncoderMethod = "getImmOpValue";
189   let DecoderMethod = "decodeSImmNonZeroOperand<10>";
190   let MCOperandPredicate = [{
191     int64_t Imm;
192     if (!MCOp.evaluateAsConstantImm(Imm))
193       return false;
194     return isShiftedInt<6, 4>(Imm) && (Imm != 0);
195   }];
198 // A 12-bit signed immediate where the least significant bit is zero.
199 def simm12_lsb0 : Operand<XLenVT> {
200   let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
201   let EncoderMethod = "getImmOpValueAsr1";
202   let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
203   let MCOperandPredicate = [{
204     int64_t Imm;
205     if (MCOp.evaluateAsConstantImm(Imm))
206       return isShiftedInt<11, 1>(Imm);
207     return MCOp.isBareSymbolRef();
208   }];
211 //===----------------------------------------------------------------------===//
212 // Instruction Class Templates
213 //===----------------------------------------------------------------------===//
215 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
216 class CStackLoad<bits<3> funct3, string OpcodeStr,
217                  RegisterClass cls, DAGOperand opnd>
218     : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
219                  OpcodeStr, "$rd, ${imm}(${rs1})">;
221 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
222 class CStackStore<bits<3> funct3, string OpcodeStr,
223                   RegisterClass cls, DAGOperand opnd>
224     : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
225                   OpcodeStr, "$rs2, ${imm}(${rs1})">;
227 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
228 class CLoad_ri<bits<3> funct3, string OpcodeStr,
229                RegisterClass cls, DAGOperand opnd>
230     : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
231                  OpcodeStr, "$rd, ${imm}(${rs1})">;
233 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
234 class CStore_rri<bits<3> funct3, string OpcodeStr,
235                  RegisterClass cls, DAGOperand opnd>
236     : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
237                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
239 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
240 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
241           RegisterClass cls>
242     : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
243                  OpcodeStr, "$rs1, $imm"> {
244   let isBranch = 1;
245   let isTerminator = 1;
246   let Inst{12} = imm{7};
247   let Inst{11-10} = imm{3-2};
248   let Inst{6-5} = imm{6-5};
249   let Inst{4-3} = imm{1-0};
250   let Inst{2} = imm{4};
253 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
254 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
255                   Operand ImmOpnd>
256     : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
257                  OpcodeStr, "$rs1, $imm"> {
258   let Constraints = "$rs1 = $rs1_wb";
259   let Inst{12} = imm{5};
260   let Inst{11-10} = funct2;
261   let Inst{6-2} = imm{4-0};
264 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
265 class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
266              RegisterClass cls>
267     : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
268                  OpcodeStr, "$rd, $rs2"> {
269   bits<3> rd;
270   let Constraints = "$rd = $rd_wb";
271   let Inst{9-7} = rd;
274 //===----------------------------------------------------------------------===//
275 // Instructions
276 //===----------------------------------------------------------------------===//
278 let Predicates = [HasStdExtC] in {
280 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
281 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
282                              (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
283                              "c.addi4spn", "$rd, $rs1, $imm"> {
284   bits<5> rs1;
285   let Inst{12-11} = imm{5-4};
286   let Inst{10-7} = imm{9-6};
287   let Inst{6} = imm{2};
288   let Inst{5} = imm{3};
291 let Predicates = [HasStdExtC, HasStdExtD] in
292 def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
293   bits<8> imm;
294   let Inst{12-10} = imm{5-3};
295   let Inst{6-5} = imm{7-6};
298 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
299   bits<7> imm;
300   let Inst{12-10} = imm{5-3};
301   let Inst{6} = imm{2};
302   let Inst{5} = imm{6};
305 let DecoderNamespace = "RISCV32Only_",
306     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
307 def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
308   bits<7> imm;
309   let Inst{12-10} = imm{5-3};
310   let Inst{6} = imm{2};
311   let Inst{5} = imm{6};
314 let Predicates = [HasStdExtC, IsRV64] in
315 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
316   bits<8> imm;
317   let Inst{12-10} = imm{5-3};
318   let Inst{6-5} = imm{7-6};
321 let Predicates = [HasStdExtC, HasStdExtD] in
322 def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
323   bits<8> imm;
324   let Inst{12-10} = imm{5-3};
325   let Inst{6-5} = imm{7-6};
328 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
329   bits<7> imm;
330   let Inst{12-10} = imm{5-3};
331   let Inst{6} = imm{2};
332   let Inst{5} = imm{6};
335 let DecoderNamespace = "RISCV32Only_",
336     Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
337 def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
338   bits<7> imm;
339   let Inst{12-10} = imm{5-3};
340   let Inst{6} = imm{2};
341   let Inst{5} = imm{6};
344 let Predicates = [HasStdExtC, IsRV64] in
345 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
346   bits<8> imm;
347   let Inst{12-10} = imm{5-3};
348   let Inst{6-5} = imm{7-6};
351 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
352 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">
354   let Inst{6-2} = 0;
357 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
358 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
359                         (ins GPRNoX0:$rd, simm6nonzero:$imm),
360                         "c.addi", "$rd, $imm"> {
361   let Constraints = "$rd = $rd_wb";
362   let Inst{6-2} = imm{4-0};
365 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
366 def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
367                             (ins GPRX0:$rd, immzero:$imm),
368                             "c.addi", "$rd, $imm"> {
369   let Constraints = "$rd = $rd_wb";
370   let Inst{6-2} = 0;
371   let isAsmParserOnly = 1;
374 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
375     DecoderNamespace = "RISCV32Only_", Defs = [X1],
376     Predicates = [HasStdExtC, IsRV32]  in
377 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
378                        "c.jal", "$offset">;
380 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
381     Predicates = [HasStdExtC, IsRV64] in
382 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
383                          (ins GPRNoX0:$rd, simm6:$imm),
384                          "c.addiw", "$rd, $imm"> {
385   let Constraints = "$rd = $rd_wb";
386   let Inst{6-2} = imm{4-0};
389 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
390 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
391                       "c.li", "$rd, $imm"> {
392   let Inst{6-2} = imm{4-0};
395 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
396 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
397                             (ins SP:$rd, simm10_lsb0000nonzero:$imm),
398                             "c.addi16sp", "$rd, $imm"> {
399   let Constraints = "$rd = $rd_wb";
400   let Inst{12} = imm{9};
401   let Inst{11-7} = 2;
402   let Inst{6} = imm{4};
403   let Inst{5} = imm{6};
404   let Inst{4-3} = imm{8-7};
405   let Inst{2} = imm{5};
408 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
409 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
410                        (ins c_lui_imm:$imm),
411                        "c.lui", "$rd, $imm"> {
412   let Inst{6-2} = imm{4-0};
415 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
416 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
418 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
419 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
420                         "c.andi", "$rs1, $imm"> {
421   let Constraints = "$rs1 = $rs1_wb";
422   let Inst{12} = imm{5};
423   let Inst{11-10} = 0b10;
424   let Inst{6-2} = imm{4-0};
427 def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
428 def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
429 def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
430 def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
432 let Predicates = [HasStdExtC, IsRV64] in {
433 def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
434 def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
437 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
438 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
439                      "c.j", "$offset"> {
440   let isBranch = 1;
441   let isTerminator=1;
442   let isBarrier=1;
445 def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
446 def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
448 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
449 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
450                         (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
451                         "c.slli" ,"$rd, $imm"> {
452   let Constraints = "$rd = $rd_wb";
453   let Inst{6-2} = imm{4-0};
456 let Predicates = [HasStdExtC, HasStdExtD] in
457 def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
458   let Inst{6-5} = imm{4-3};
459   let Inst{4-2} = imm{8-6};
462 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
463   let Inst{6-4} = imm{4-2};
464   let Inst{3-2} = imm{7-6};
467 let DecoderNamespace = "RISCV32Only_",
468     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
469 def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
470   let Inst{6-4} = imm{4-2};
471   let Inst{3-2} = imm{7-6};
474 let Predicates = [HasStdExtC, IsRV64] in
475 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
476   let Inst{6-5} = imm{4-3};
477   let Inst{4-2} = imm{8-6};
480 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
481 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
482                       "c.jr", "$rs1"> {
483   let isBranch = 1;
484   let isBarrier = 1;
485   let isTerminator = 1;
486   let isIndirectBranch = 1;
487   let rs2 = 0;
490 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
491 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
492                       "c.mv", "$rs1, $rs2">;
494 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
495 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
497 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
498     isCall=1, Defs=[X1], rs2 = 0 in
499 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
500                         "c.jalr", "$rs1">;
502 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
503 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
504                        (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
505                        "c.add", "$rs1, $rs2"> {
506   let Constraints = "$rs1 = $rs1_wb";
509 let Predicates = [HasStdExtC, HasStdExtD] in
510 def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
511   let Inst{12-10} = imm{5-3};
512   let Inst{9-7}   = imm{8-6};
515 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
516   let Inst{12-9} = imm{5-2};
517   let Inst{8-7}  = imm{7-6};
520 let DecoderNamespace = "RISCV32Only_",
521     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
522 def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
523   let Inst{12-9} = imm{5-2};
524   let Inst{8-7}  = imm{7-6};
527 let Predicates = [HasStdExtC, IsRV64] in
528 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
529   let Inst{12-10} = imm{5-3};
530   let Inst{9-7}   = imm{8-6};
533 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
534 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
535 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
536 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
537   let Inst{15-0} = 0;
540 } // Predicates = [HasStdExtC]
542 //===----------------------------------------------------------------------===//
543 // HINT Instructions
544 //===----------------------------------------------------------------------===//
546 let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
547     mayStore = 0 in
550 let rd = 0 in
551 def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
552                             "c.nop", "$imm"> {
553   let Inst{6-2} = imm{4-0};
554   let DecoderMethod = "decodeRVCInstrSImm";
557 // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
558 def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
559                                 (ins GPRX0:$rd, simm6nonzero:$imm),
560                                 "c.addi", "$rd, $imm"> {
561   let Constraints = "$rd = $rd_wb";
562   let Inst{6-2} = imm{4-0};
563   let isAsmParserOnly = 1;
566 def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
567                                       (ins GPRNoX0:$rd, immzero:$imm),
568                                       "c.addi", "$rd, $imm"> {
569   let Constraints = "$rd = $rd_wb";
570   let Inst{6-2} = 0;
571   let isAsmParserOnly = 1;
574 def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
575                            "c.li", "$rd, $imm"> {
576   let Inst{6-2} = imm{4-0};
577   let Inst{11-7} = 0;
578   let DecoderMethod = "decodeRVCInstrRdSImm";
581 def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
582                             (ins c_lui_imm:$imm),
583                             "c.lui", "$rd, $imm"> {
584   let Inst{6-2} = imm{4-0};
585   let Inst{11-7} = 0;
586   let DecoderMethod = "decodeRVCInstrRdSImm";
589 def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
590                            "c.mv", "$rs1, $rs2">
592   let Inst{11-7} = 0;
593   let DecoderMethod = "decodeRVCInstrRdRs2";
596 def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb),
597                             (ins GPRX0:$rs1, GPRNoX0:$rs2),
598                             "c.add", "$rs1, $rs2"> {
599   let Constraints = "$rs1 = $rs1_wb";
600   let Inst{11-7} = 0;
601   let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
604 def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
605                              (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
606                              "c.slli" ,"$rd, $imm"> {
607   let Constraints = "$rd = $rd_wb";
608   let Inst{6-2} = imm{4-0};
609   let Inst{11-7} = 0;
610   let DecoderMethod = "decodeRVCInstrRdRs1UImm";
613 def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
614                                "c.slli64" ,"$rd"> {
615   let Constraints = "$rd = $rd_wb";
616   let Inst{6-2} = 0;
617   let Inst{12} = 0;
620 def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
621                                (ins GPRC:$rd),
622                                "c.srli64", "$rd"> {
623   let Constraints = "$rd = $rd_wb";
624   let Inst{6-2} = 0;
625   let Inst{11-10} = 0;
626   let Inst{12} = 0;
629 def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
630                                (ins GPRC:$rd),
631                                "c.srai64", "$rd"> {
632   let Constraints = "$rd = $rd_wb";
633   let Inst{6-2} = 0;
634   let Inst{11-10} = 1;
635   let Inst{12} = 0;
638 } // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
639   // mayStore = 0
641 //===----------------------------------------------------------------------===//
642 // Assembler Pseudo Instructions
643 //===----------------------------------------------------------------------===//
645 let EmitPriority = 0 in {
646 let Predicates = [HasStdExtC, HasStdExtD] in
647 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
649 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
651 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
652 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
654 let Predicates = [HasStdExtC, IsRV64] in
655 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
657 let Predicates = [HasStdExtC, HasStdExtD] in
658 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
660 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
662 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
663 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
665 let Predicates = [HasStdExtC, IsRV64] in
666 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
668 let Predicates = [HasStdExtC, HasStdExtD] in
669 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
671 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
673 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
674 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
676 let Predicates = [HasStdExtC, IsRV64] in
677 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
679 let Predicates = [HasStdExtC, HasStdExtD] in
680 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
682 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
684 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
685 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
687 let Predicates = [HasStdExtC, IsRV64] in
688 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
691 //===----------------------------------------------------------------------===//
692 // Compress Instruction tablegen backend.
693 //===----------------------------------------------------------------------===//
695 class CompressPat<dag input, dag output> {
696   dag Input  = input;
697   dag Output    = output;
698   list<Predicate> Predicates = [];
701 // Patterns are defined in the same order the compressed instructions appear
702 // on page 82 of the ISA manual.
704 // Quadrant 0
705 let Predicates = [HasStdExtC] in {
706 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
707                   (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
708 } // Predicates = [HasStdExtC]
710 let Predicates = [HasStdExtC, HasStdExtD] in {
711 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
712                   (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
713 } // Predicates = [HasStdExtC, HasStdExtD]
715 let Predicates = [HasStdExtC] in {
716 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
717                   (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
718 } // Predicates = [HasStdExtC]
720 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
721 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
722                   (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
723 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
725 let Predicates = [HasStdExtC, IsRV64] in {
726 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
727                   (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
728 } // Predicates = [HasStdExtC, IsRV64]
730 let Predicates = [HasStdExtC, HasStdExtD] in {
731 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
732                   (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
733 } // Predicates = [HasStdExtC, HasStdExtD]
735 let Predicates = [HasStdExtC] in {
736 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
737                   (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
738 } // Predicates = [HasStdExtC]
740 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
741 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
742                   (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
743 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
745 let Predicates = [HasStdExtC, IsRV64] in {
746 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
747                   (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
748 } // Predicates = [HasStdExtC, IsRV64]
750 // Quadrant 1
751 let Predicates = [HasStdExtC] in {
752 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
753 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
754                   (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
755 } // Predicates = [HasStdExtC]
757 let Predicates = [HasStdExtC, IsRV32] in {
758 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
759                   (C_JAL simm12_lsb0:$offset)>;
760 } // Predicates = [HasStdExtC, IsRV32]
762 let Predicates = [HasStdExtC, IsRV64] in {
763 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
764                   (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
765 } // Predicates = [HasStdExtC, IsRV64]
767 let Predicates = [HasStdExtC] in {
768 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
769                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
770 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
771                   (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
772 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
773                   (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
774 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
775                   (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
776 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
777                   (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
778 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
779                   (C_ANDI GPRC:$rs1, simm6:$imm)>;
780 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
781                   (C_SUB GPRC:$rs1, GPRC:$rs2)>;
782 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
783                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
784 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
785                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
786 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
787                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
788 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
789                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
790 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
791                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
792 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
793                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
794 } //  Predicates = [HasStdExtC]
796 let Predicates = [HasStdExtC, IsRV64] in {
797 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
798                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
799 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
800                   (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
801 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
802                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
803 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
804                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
805 } // Predicates = [HasStdExtC, IsRV64]
807 let Predicates = [HasStdExtC] in {
808 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
809                   (C_J simm12_lsb0:$offset)>;
810 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
811                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
812 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
813                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
814 } //  Predicates = [HasStdExtC]
816 // Quadrant 2
817 let Predicates = [HasStdExtC] in {
818 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
819                   (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
820 } //  Predicates = [HasStdExtC]
822 let Predicates = [HasStdExtC, HasStdExtD] in {
823 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
824                   (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
825 } // Predicates = [HasStdExtC, HasStdExtD]
827 let Predicates = [HasStdExtC] in {
828 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
829                   (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
830 } // Predicates = [HasStdExtC]
832 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
833 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
834                   (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
835 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
837 let Predicates = [HasStdExtC, IsRV64] in {
838 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
839                   (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
840 } // Predicates = [HasStdExtC, IsRV64]
842 let Predicates = [HasStdExtC] in {
843 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
844                   (C_JR GPRNoX0:$rs1)>;
845 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
846                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
847 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
848                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
849 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
850                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
851 def : CompressPat<(EBREAK), (C_EBREAK)>;
852 def : CompressPat<(UNIMP), (C_UNIMP)>;
853 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
854                   (C_JALR GPRNoX0:$rs1)>;
855 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
856                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
857 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
858                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
859 } // Predicates = [HasStdExtC]
861 let Predicates = [HasStdExtC, HasStdExtD] in {
862 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
863                   (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
864 } // Predicates = [HasStdExtC, HasStdExtD]
866 let Predicates = [HasStdExtC] in {
867 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
868                   (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
869 } // Predicates = [HasStdExtC]
871 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
872 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
873                   (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
874 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
876 let Predicates = [HasStdExtC, IsRV64] in {
877 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
878                   (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
879 } //  Predicates = [HasStdExtC, IsRV64]