]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
Merge ^/head r357119 through r357178.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / RISCV / RISCVInstrInfoC.td
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 //===----------------------------------------------------------------------===//
8
9 include "RISCVInstrFormatsC.td"
10
11 //===----------------------------------------------------------------------===//
12 // Operand definitions.
13 //===----------------------------------------------------------------------===//
14
15 def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16   let Name = "UImmLog2XLenNonZero";
17   let RenderMethod = "addImmOperands";
18   let DiagnosticType = "InvalidUImmLog2XLenNonZero";
19 }
20
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   }];
37 }
38
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   }];
49 }
50
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   }];
62 }
63
64 def immzero : Operand<XLenVT>,
65               ImmLeaf<XLenVT, [{return (Imm == 0);}]> {
66   let ParserMatchClass = ImmZeroAsmOperand;
67 }
68
69 def CLUIImmAsmOperand : AsmOperandClass {
70   let Name = "CLUIImm";
71   let RenderMethod = "addImmOperands";
72   let DiagnosticType = !strconcat("Invalid", Name);
73 }
74
75
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   }];
95 }
96
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   }];
109 }
110
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   }];
123 }
124
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   }];
137 }
138
139 // A 9-bit signed immediate where the least significant bit is zero.
140 def simm9_lsb0 : Operand<OtherVT>,
141                  ImmLeaf<XLenVT, [{return isShiftedInt<8, 1>(Imm);}]> {
142   let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
143   let EncoderMethod = "getImmOpValueAsr1";
144   let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
145   let MCOperandPredicate = [{
146     int64_t Imm;
147     if (MCOp.evaluateAsConstantImm(Imm))
148       return isShiftedInt<8, 1>(Imm);
149     return MCOp.isBareSymbolRef();
150
151   }];
152 }
153
154 // A 9-bit unsigned immediate where the least significant three bits are zero.
155 def uimm9_lsb000 : Operand<XLenVT>,
156                    ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
157   let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
158   let EncoderMethod = "getImmOpValue";
159   let DecoderMethod = "decodeUImmOperand<9>";
160   let MCOperandPredicate = [{
161     int64_t Imm;
162     if (!MCOp.evaluateAsConstantImm(Imm))
163       return false;
164     return isShiftedUInt<6, 3>(Imm);
165   }];
166 }
167
168 // A 10-bit unsigned immediate where the least significant two bits are zero
169 // and the immediate can't be zero.
170 def uimm10_lsb00nonzero : Operand<XLenVT>,
171                           ImmLeaf<XLenVT,
172                           [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
173   let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
174   let EncoderMethod = "getImmOpValue";
175   let DecoderMethod = "decodeUImmNonZeroOperand<10>";
176   let MCOperandPredicate = [{
177     int64_t Imm;
178     if (!MCOp.evaluateAsConstantImm(Imm))
179       return false;
180     return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
181   }];
182 }
183
184 // A 10-bit signed immediate where the least significant four bits are zero.
185 def simm10_lsb0000nonzero : Operand<XLenVT>,
186                             ImmLeaf<XLenVT,
187                             [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
188   let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
189   let EncoderMethod = "getImmOpValue";
190   let DecoderMethod = "decodeSImmNonZeroOperand<10>";
191   let MCOperandPredicate = [{
192     int64_t Imm;
193     if (!MCOp.evaluateAsConstantImm(Imm))
194       return false;
195     return isShiftedInt<6, 4>(Imm) && (Imm != 0);
196   }];
197 }
198
199 // A 12-bit signed immediate where the least significant bit is zero.
200 def simm12_lsb0 : Operand<XLenVT>,
201                   ImmLeaf<XLenVT, [{return isShiftedInt<11, 1>(Imm);}]> {
202   let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
203   let EncoderMethod = "getImmOpValueAsr1";
204   let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
205   let MCOperandPredicate = [{
206     int64_t Imm;
207     if (MCOp.evaluateAsConstantImm(Imm))
208       return isShiftedInt<11, 1>(Imm);
209     return MCOp.isBareSymbolRef();
210   }];
211 }
212
213 //===----------------------------------------------------------------------===//
214 // Instruction Class Templates
215 //===----------------------------------------------------------------------===//
216
217 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
218 class CStackLoad<bits<3> funct3, string OpcodeStr,
219                  RegisterClass cls, DAGOperand opnd>
220     : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
221                  OpcodeStr, "$rd, ${imm}(${rs1})">;
222
223 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
224 class CStackStore<bits<3> funct3, string OpcodeStr,
225                   RegisterClass cls, DAGOperand opnd>
226     : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
227                   OpcodeStr, "$rs2, ${imm}(${rs1})">;
228
229 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
230 class CLoad_ri<bits<3> funct3, string OpcodeStr,
231                RegisterClass cls, DAGOperand opnd>
232     : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
233                  OpcodeStr, "$rd, ${imm}(${rs1})">;
234
235 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
236 class CStore_rri<bits<3> funct3, string OpcodeStr,
237                  RegisterClass cls, DAGOperand opnd>
238     : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
239                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
240
241 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
242 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
243           RegisterClass cls>
244     : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
245                  OpcodeStr, "$rs1, $imm"> {
246   let isBranch = 1;
247   let isTerminator = 1;
248   let Inst{12} = imm{7};
249   let Inst{11-10} = imm{3-2};
250   let Inst{6-5} = imm{6-5};
251   let Inst{4-3} = imm{1-0};
252   let Inst{2} = imm{4};
253 }
254
255 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
256 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
257                   Operand ImmOpnd>
258     : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
259                  OpcodeStr, "$rs1, $imm"> {
260   let Constraints = "$rs1 = $rs1_wb";
261   let Inst{12} = imm{5};
262   let Inst{11-10} = funct2;
263   let Inst{6-2} = imm{4-0};
264 }
265
266 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
267 class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
268              RegisterClass cls>
269     : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
270                  OpcodeStr, "$rd, $rs2"> {
271   bits<3> rd;
272   let Constraints = "$rd = $rd_wb";
273   let Inst{9-7} = rd;
274 }
275
276 //===----------------------------------------------------------------------===//
277 // Instructions
278 //===----------------------------------------------------------------------===//
279
280 let Predicates = [HasStdExtC] in {
281
282 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
283 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
284                              (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
285                              "c.addi4spn", "$rd, $rs1, $imm"> {
286   bits<5> rs1;
287   let Inst{12-11} = imm{5-4};
288   let Inst{10-7} = imm{9-6};
289   let Inst{6} = imm{2};
290   let Inst{5} = imm{3};
291 }
292
293 let Predicates = [HasStdExtC, HasStdExtD] in
294 def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
295   bits<8> imm;
296   let Inst{12-10} = imm{5-3};
297   let Inst{6-5} = imm{7-6};
298 }
299
300 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
301   bits<7> imm;
302   let Inst{12-10} = imm{5-3};
303   let Inst{6} = imm{2};
304   let Inst{5} = imm{6};
305 }
306
307 let DecoderNamespace = "RISCV32Only_",
308     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
309 def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
310   bits<7> imm;
311   let Inst{12-10} = imm{5-3};
312   let Inst{6} = imm{2};
313   let Inst{5} = imm{6};
314 }
315
316 let Predicates = [HasStdExtC, IsRV64] in
317 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
318   bits<8> imm;
319   let Inst{12-10} = imm{5-3};
320   let Inst{6-5} = imm{7-6};
321 }
322
323 let Predicates = [HasStdExtC, HasStdExtD] in
324 def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, uimm8_lsb000> {
325   bits<8> imm;
326   let Inst{12-10} = imm{5-3};
327   let Inst{6-5} = imm{7-6};
328 }
329
330 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
331   bits<7> imm;
332   let Inst{12-10} = imm{5-3};
333   let Inst{6} = imm{2};
334   let Inst{5} = imm{6};
335 }
336
337 let DecoderNamespace = "RISCV32Only_",
338     Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
339 def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
340   bits<7> imm;
341   let Inst{12-10} = imm{5-3};
342   let Inst{6} = imm{2};
343   let Inst{5} = imm{6};
344 }
345
346 let Predicates = [HasStdExtC, IsRV64] in
347 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
348   bits<8> imm;
349   let Inst{12-10} = imm{5-3};
350   let Inst{6-5} = imm{7-6};
351 }
352
353 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
354 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">
355 {
356   let Inst{6-2} = 0;
357 }
358
359 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
360 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
361                         (ins GPRNoX0:$rd, simm6nonzero:$imm),
362                         "c.addi", "$rd, $imm"> {
363   let Constraints = "$rd = $rd_wb";
364   let Inst{6-2} = imm{4-0};
365 }
366
367 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
368 def C_ADDI_NOP : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
369                             (ins GPRX0:$rd, immzero:$imm),
370                             "c.addi", "$rd, $imm"> {
371   let Constraints = "$rd = $rd_wb";
372   let Inst{6-2} = 0;
373   let isAsmParserOnly = 1;
374 }
375
376 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
377     DecoderNamespace = "RISCV32Only_", Defs = [X1],
378     Predicates = [HasStdExtC, IsRV32]  in
379 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
380                        "c.jal", "$offset">;
381
382 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
383     Predicates = [HasStdExtC, IsRV64] in
384 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
385                          (ins GPRNoX0:$rd, simm6:$imm),
386                          "c.addiw", "$rd, $imm"> {
387   let Constraints = "$rd = $rd_wb";
388   let Inst{6-2} = imm{4-0};
389 }
390
391 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
392 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
393                       "c.li", "$rd, $imm"> {
394   let Inst{6-2} = imm{4-0};
395 }
396
397 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
398 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
399                             (ins SP:$rd, simm10_lsb0000nonzero:$imm),
400                             "c.addi16sp", "$rd, $imm"> {
401   let Constraints = "$rd = $rd_wb";
402   let Inst{12} = imm{9};
403   let Inst{11-7} = 2;
404   let Inst{6} = imm{4};
405   let Inst{5} = imm{6};
406   let Inst{4-3} = imm{8-7};
407   let Inst{2} = imm{5};
408 }
409
410 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
411 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
412                        (ins c_lui_imm:$imm),
413                        "c.lui", "$rd, $imm"> {
414   let Inst{6-2} = imm{4-0};
415 }
416
417 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
418 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
419
420 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
421 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
422                         "c.andi", "$rs1, $imm"> {
423   let Constraints = "$rs1 = $rs1_wb";
424   let Inst{12} = imm{5};
425   let Inst{11-10} = 0b10;
426   let Inst{6-2} = imm{4-0};
427 }
428
429 def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
430 def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
431 def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
432 def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
433
434 let Predicates = [HasStdExtC, IsRV64] in {
435 def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
436 def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
437 }
438
439 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
440 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
441                      "c.j", "$offset"> {
442   let isBranch = 1;
443   let isTerminator=1;
444   let isBarrier=1;
445 }
446
447 def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
448 def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
449
450 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
451 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
452                         (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
453                         "c.slli" ,"$rd, $imm"> {
454   let Constraints = "$rd = $rd_wb";
455   let Inst{6-2} = imm{4-0};
456 }
457
458 let Predicates = [HasStdExtC, HasStdExtD] in
459 def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
460   let Inst{6-5} = imm{4-3};
461   let Inst{4-2} = imm{8-6};
462 }
463
464 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
465   let Inst{6-4} = imm{4-2};
466   let Inst{3-2} = imm{7-6};
467 }
468
469 let DecoderNamespace = "RISCV32Only_",
470     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
471 def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
472   let Inst{6-4} = imm{4-2};
473   let Inst{3-2} = imm{7-6};
474 }
475
476 let Predicates = [HasStdExtC, IsRV64] in
477 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
478   let Inst{6-5} = imm{4-3};
479   let Inst{4-2} = imm{8-6};
480 }
481
482 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
483 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
484                       "c.jr", "$rs1"> {
485   let isBranch = 1;
486   let isBarrier = 1;
487   let isTerminator = 1;
488   let isIndirectBranch = 1;
489   let rs2 = 0;
490 }
491
492 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
493 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
494                       "c.mv", "$rs1, $rs2">;
495
496 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
497 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
498
499 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
500     isCall=1, Defs=[X1], rs2 = 0 in
501 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
502                         "c.jalr", "$rs1">;
503
504 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
505 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
506                        (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
507                        "c.add", "$rs1, $rs2"> {
508   let Constraints = "$rs1 = $rs1_wb";
509 }
510
511 let Predicates = [HasStdExtC, HasStdExtD] in
512 def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
513   let Inst{12-10} = imm{5-3};
514   let Inst{9-7}   = imm{8-6};
515 }
516
517 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
518   let Inst{12-9} = imm{5-2};
519   let Inst{8-7}  = imm{7-6};
520 }
521
522 let DecoderNamespace = "RISCV32Only_",
523     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
524 def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
525   let Inst{12-9} = imm{5-2};
526   let Inst{8-7}  = imm{7-6};
527 }
528
529 let Predicates = [HasStdExtC, IsRV64] in
530 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
531   let Inst{12-10} = imm{5-3};
532   let Inst{9-7}   = imm{8-6};
533 }
534
535 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
536 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
537 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
538 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
539   let Inst{15-0} = 0;
540 }
541
542 } // Predicates = [HasStdExtC]
543
544 //===----------------------------------------------------------------------===//
545 // HINT Instructions
546 //===----------------------------------------------------------------------===//
547
548 let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
549     mayStore = 0 in
550 {
551
552 let rd = 0 in
553 def C_NOP_HINT : RVInst16CI<0b000, 0b01, (outs), (ins simm6nonzero:$imm),
554                             "c.nop", "$imm"> {
555   let Inst{6-2} = imm{4-0};
556   let DecoderMethod = "decodeRVCInstrSImm";
557 }
558
559 // Just a different syntax for the c.nop hint: c.addi x0, simm6 vs c.nop simm6.
560 def C_ADDI_HINT_X0 : RVInst16CI<0b000, 0b01, (outs GPRX0:$rd_wb),
561                                 (ins GPRX0:$rd, simm6nonzero:$imm),
562                                 "c.addi", "$rd, $imm"> {
563   let Constraints = "$rd = $rd_wb";
564   let Inst{6-2} = imm{4-0};
565   let isAsmParserOnly = 1;
566 }
567
568 def C_ADDI_HINT_IMM_ZERO : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
569                                       (ins GPRNoX0:$rd, immzero:$imm),
570                                       "c.addi", "$rd, $imm"> {
571   let Constraints = "$rd = $rd_wb";
572   let Inst{6-2} = 0;
573   let isAsmParserOnly = 1;
574 }
575
576 def C_LI_HINT : RVInst16CI<0b010, 0b01, (outs GPRX0:$rd), (ins simm6:$imm),
577                            "c.li", "$rd, $imm"> {
578   let Inst{6-2} = imm{4-0};
579   let Inst{11-7} = 0;
580   let DecoderMethod = "decodeRVCInstrRdSImm";
581 }
582
583 def C_LUI_HINT : RVInst16CI<0b011, 0b01, (outs GPRX0:$rd),
584                             (ins c_lui_imm:$imm),
585                             "c.lui", "$rd, $imm"> {
586   let Inst{6-2} = imm{4-0};
587   let Inst{11-7} = 0;
588   let DecoderMethod = "decodeRVCInstrRdSImm";
589 }
590
591 def C_MV_HINT : RVInst16CR<0b1000, 0b10, (outs GPRX0:$rs1), (ins GPRNoX0:$rs2),
592                            "c.mv", "$rs1, $rs2">
593 {
594   let Inst{11-7} = 0;
595   let DecoderMethod = "decodeRVCInstrRdRs2";
596 }
597
598 def C_ADD_HINT : RVInst16CR<0b1001, 0b10, (outs GPRX0:$rs1_wb),
599                             (ins GPRX0:$rs1, GPRNoX0:$rs2),
600                             "c.add", "$rs1, $rs2"> {
601   let Constraints = "$rs1 = $rs1_wb";
602   let Inst{11-7} = 0;
603   let DecoderMethod = "decodeRVCInstrRdRs1Rs2";
604 }
605
606 def C_SLLI_HINT : RVInst16CI<0b000, 0b10, (outs GPRX0:$rd_wb),
607                              (ins GPRX0:$rd, uimmlog2xlennonzero:$imm),
608                              "c.slli" ,"$rd, $imm"> {
609   let Constraints = "$rd = $rd_wb";
610   let Inst{6-2} = imm{4-0};
611   let Inst{11-7} = 0;
612   let DecoderMethod = "decodeRVCInstrRdRs1UImm";
613 }
614
615 def C_SLLI64_HINT : RVInst16CI<0b000, 0b10, (outs GPR:$rd_wb), (ins GPR:$rd),
616                                "c.slli64" ,"$rd"> {
617   let Constraints = "$rd = $rd_wb";
618   let Inst{6-2} = 0;
619   let Inst{12} = 0;
620 }
621
622 def C_SRLI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
623                                (ins GPRC:$rd),
624                                "c.srli64", "$rd"> {
625   let Constraints = "$rd = $rd_wb";
626   let Inst{6-2} = 0;
627   let Inst{11-10} = 0;
628   let Inst{12} = 0;
629 }
630
631 def C_SRAI64_HINT : RVInst16CI<0b100, 0b01, (outs GPRC:$rd_wb),
632                                (ins GPRC:$rd),
633                                "c.srai64", "$rd"> {
634   let Constraints = "$rd = $rd_wb";
635   let Inst{6-2} = 0;
636   let Inst{11-10} = 1;
637   let Inst{12} = 0;
638 }
639
640 } // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0,
641   // mayStore = 0
642
643 //===----------------------------------------------------------------------===//
644 // Assembler Pseudo Instructions
645 //===----------------------------------------------------------------------===//
646
647 let EmitPriority = 0 in {
648 let Predicates = [HasStdExtC, HasStdExtD] in
649 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
650
651 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
652
653 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
654 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
655
656 let Predicates = [HasStdExtC, IsRV64] in
657 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
658
659 let Predicates = [HasStdExtC, HasStdExtD] in
660 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
661
662 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
663
664 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
665 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
666
667 let Predicates = [HasStdExtC, IsRV64] in
668 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
669
670 let Predicates = [HasStdExtC, HasStdExtD] in
671 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
672
673 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
674
675 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
676 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
677
678 let Predicates = [HasStdExtC, IsRV64] in
679 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
680
681 let Predicates = [HasStdExtC, HasStdExtD] in
682 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
683
684 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
685
686 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
687 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
688
689 let Predicates = [HasStdExtC, IsRV64] in
690 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
691 }
692
693 //===----------------------------------------------------------------------===//
694 // Compress Instruction tablegen backend.
695 //===----------------------------------------------------------------------===//
696
697 class CompressPat<dag input, dag output> {
698   dag Input  = input;
699   dag Output    = output;
700   list<Predicate> Predicates = [];
701 }
702
703 // Patterns are defined in the same order the compressed instructions appear
704 // on page 82 of the ISA manual.
705
706 // Quadrant 0
707 let Predicates = [HasStdExtC] in {
708 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
709                   (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
710 } // Predicates = [HasStdExtC]
711
712 let Predicates = [HasStdExtC, HasStdExtD] in {
713 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
714                   (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
715 } // Predicates = [HasStdExtC, HasStdExtD]
716
717 let Predicates = [HasStdExtC] in {
718 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
719                   (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
720 } // Predicates = [HasStdExtC]
721
722 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
723 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
724                   (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
725 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
726
727 let Predicates = [HasStdExtC, IsRV64] in {
728 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
729                   (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
730 } // Predicates = [HasStdExtC, IsRV64]
731
732 let Predicates = [HasStdExtC, HasStdExtD] in {
733 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
734                   (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
735 } // Predicates = [HasStdExtC, HasStdExtD]
736
737 let Predicates = [HasStdExtC] in {
738 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
739                   (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
740 } // Predicates = [HasStdExtC]
741
742 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
743 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
744                   (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
745 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
746
747 let Predicates = [HasStdExtC, IsRV64] in {
748 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
749                   (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
750 } // Predicates = [HasStdExtC, IsRV64]
751
752 // Quadrant 1
753 let Predicates = [HasStdExtC] in {
754 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
755 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
756                   (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
757 } // Predicates = [HasStdExtC]
758
759 let Predicates = [HasStdExtC, IsRV32] in {
760 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
761                   (C_JAL simm12_lsb0:$offset)>;
762 } // Predicates = [HasStdExtC, IsRV32]
763
764 let Predicates = [HasStdExtC, IsRV64] in {
765 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
766                   (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
767 } // Predicates = [HasStdExtC, IsRV64]
768
769 let Predicates = [HasStdExtC] in {
770 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
771                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
772 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
773                   (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
774 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
775                   (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
776 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
777                   (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
778 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
779                   (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
780 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
781                   (C_ANDI GPRC:$rs1, simm6:$imm)>;
782 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
783                   (C_SUB GPRC:$rs1, GPRC:$rs2)>;
784 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
785                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
786 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
787                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
788 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
789                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
790 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
791                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
792 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
793                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
794 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
795                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
796 } //  Predicates = [HasStdExtC]
797
798 let Predicates = [HasStdExtC, IsRV64] in {
799 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
800                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
801 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
802                   (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
803 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
804                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
805 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
806                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
807 } // Predicates = [HasStdExtC, IsRV64]
808
809 let Predicates = [HasStdExtC] in {
810 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
811                   (C_J simm12_lsb0:$offset)>;
812 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
813                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
814 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
815                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
816 } //  Predicates = [HasStdExtC]
817
818 // Quadrant 2
819 let Predicates = [HasStdExtC] in {
820 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
821                   (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
822 } //  Predicates = [HasStdExtC]
823
824 let Predicates = [HasStdExtC, HasStdExtD] in {
825 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
826                   (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
827 } // Predicates = [HasStdExtC, HasStdExtD]
828
829 let Predicates = [HasStdExtC] in {
830 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
831                   (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
832 } // Predicates = [HasStdExtC]
833
834 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
835 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
836                   (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
837 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
838
839 let Predicates = [HasStdExtC, IsRV64] in {
840 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
841                   (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
842 } // Predicates = [HasStdExtC, IsRV64]
843
844 let Predicates = [HasStdExtC] in {
845 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
846                   (C_JR GPRNoX0:$rs1)>;
847 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
848                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
849 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
850                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
851 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
852                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
853 def : CompressPat<(EBREAK), (C_EBREAK)>;
854 def : CompressPat<(UNIMP), (C_UNIMP)>;
855 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
856                   (C_JALR GPRNoX0:$rs1)>;
857 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
858                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
859 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
860                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
861 } // Predicates = [HasStdExtC]
862
863 let Predicates = [HasStdExtC, HasStdExtD] in {
864 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
865                   (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
866 } // Predicates = [HasStdExtC, HasStdExtD]
867
868 let Predicates = [HasStdExtC] in {
869 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
870                   (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
871 } // Predicates = [HasStdExtC]
872
873 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
874 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
875                   (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
876 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
877
878 let Predicates = [HasStdExtC, IsRV64] in {
879 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
880                   (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
881 } //  Predicates = [HasStdExtC, IsRV64]