]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
MFV r358511,r358532:
[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 CLUIImmAsmOperand : AsmOperandClass {
65   let Name = "CLUIImm";
66   let RenderMethod = "addImmOperands";
67   let DiagnosticType = !strconcat("Invalid", Name);
68 }
69
70
71 // c_lui_imm checks the immediate range is in [1, 31] or [0xfffe0, 0xfffff].
72 // The RISC-V ISA describes the constraint as [1, 63], with that value being
73 // loaded in to bits 17-12 of the destination register and sign extended from
74 // bit 17. Therefore, this 6-bit immediate can represent values in the ranges
75 // [1, 31] and [0xfffe0, 0xfffff].
76 def c_lui_imm : Operand<XLenVT>,
77                 ImmLeaf<XLenVT, [{return (Imm != 0) &&
78                                  (isUInt<5>(Imm) ||
79                                   (Imm >= 0xfffe0 && Imm <= 0xfffff));}]> {
80   let ParserMatchClass = CLUIImmAsmOperand;
81   let EncoderMethod = "getImmOpValue";
82   let DecoderMethod = "decodeCLUIImmOperand";
83   let MCOperandPredicate = [{
84     int64_t Imm;
85     if (MCOp.evaluateAsConstantImm(Imm))
86       return (Imm != 0) && (isUInt<5>(Imm) ||
87              (Imm >= 0xfffe0 && Imm <= 0xfffff));
88     return MCOp.isBareSymbolRef();
89   }];
90 }
91
92 // A 7-bit unsigned immediate where the least significant two bits are zero.
93 def uimm7_lsb00 : Operand<XLenVT>,
94                   ImmLeaf<XLenVT, [{return isShiftedUInt<5, 2>(Imm);}]> {
95   let ParserMatchClass = UImmAsmOperand<7, "Lsb00">;
96   let EncoderMethod = "getImmOpValue";
97   let DecoderMethod = "decodeUImmOperand<7>";
98   let MCOperandPredicate = [{
99     int64_t Imm;
100     if (!MCOp.evaluateAsConstantImm(Imm))
101       return false;
102     return isShiftedUInt<5, 2>(Imm);
103   }];
104 }
105
106 // A 8-bit unsigned immediate where the least significant two bits are zero.
107 def uimm8_lsb00 : Operand<XLenVT>,
108                   ImmLeaf<XLenVT, [{return isShiftedUInt<6, 2>(Imm);}]> {
109   let ParserMatchClass = UImmAsmOperand<8, "Lsb00">;
110   let EncoderMethod = "getImmOpValue";
111   let DecoderMethod = "decodeUImmOperand<8>";
112   let MCOperandPredicate = [{
113     int64_t Imm;
114     if (!MCOp.evaluateAsConstantImm(Imm))
115       return false;
116     return isShiftedUInt<6, 2>(Imm);
117   }];
118 }
119
120 // A 8-bit unsigned immediate where the least significant three bits are zero.
121 def uimm8_lsb000 : Operand<XLenVT>,
122                    ImmLeaf<XLenVT, [{return isShiftedUInt<5, 3>(Imm);}]> {
123   let ParserMatchClass = UImmAsmOperand<8, "Lsb000">;
124   let EncoderMethod = "getImmOpValue";
125   let DecoderMethod = "decodeUImmOperand<8>";
126   let MCOperandPredicate = [{
127     int64_t Imm;
128     if (!MCOp.evaluateAsConstantImm(Imm))
129       return false;
130     return isShiftedUInt<5, 3>(Imm);
131   }];
132 }
133
134 // A 9-bit signed immediate where the least significant bit is zero.
135 def simm9_lsb0 : Operand<OtherVT> {
136   let ParserMatchClass = SImmAsmOperand<9, "Lsb0">;
137   let EncoderMethod = "getImmOpValueAsr1";
138   let DecoderMethod = "decodeSImmOperandAndLsl1<9>";
139   let MCOperandPredicate = [{
140     int64_t Imm;
141     if (MCOp.evaluateAsConstantImm(Imm))
142       return isShiftedInt<8, 1>(Imm);
143     return MCOp.isBareSymbolRef();
144
145   }];
146 }
147
148 // A 9-bit unsigned immediate where the least significant three bits are zero.
149 def uimm9_lsb000 : Operand<XLenVT>,
150                    ImmLeaf<XLenVT, [{return isShiftedUInt<6, 3>(Imm);}]> {
151   let ParserMatchClass = UImmAsmOperand<9, "Lsb000">;
152   let EncoderMethod = "getImmOpValue";
153   let DecoderMethod = "decodeUImmOperand<9>";
154   let MCOperandPredicate = [{
155     int64_t Imm;
156     if (!MCOp.evaluateAsConstantImm(Imm))
157       return false;
158     return isShiftedUInt<6, 3>(Imm);
159   }];
160 }
161
162 // A 10-bit unsigned immediate where the least significant two bits are zero
163 // and the immediate can't be zero.
164 def uimm10_lsb00nonzero : Operand<XLenVT>,
165                           ImmLeaf<XLenVT,
166                           [{return isShiftedUInt<8, 2>(Imm) && (Imm != 0);}]> {
167   let ParserMatchClass = UImmAsmOperand<10, "Lsb00NonZero">;
168   let EncoderMethod = "getImmOpValue";
169   let DecoderMethod = "decodeUImmNonZeroOperand<10>";
170   let MCOperandPredicate = [{
171     int64_t Imm;
172     if (!MCOp.evaluateAsConstantImm(Imm))
173       return false;
174     return isShiftedUInt<8, 2>(Imm) && (Imm != 0);
175   }];
176 }
177
178 // A 10-bit signed immediate where the least significant four bits are zero.
179 def simm10_lsb0000nonzero : Operand<XLenVT>,
180                             ImmLeaf<XLenVT,
181                             [{return (Imm != 0) && isShiftedInt<6, 4>(Imm);}]> {
182   let ParserMatchClass = SImmAsmOperand<10, "Lsb0000NonZero">;
183   let EncoderMethod = "getImmOpValue";
184   let DecoderMethod = "decodeSImmNonZeroOperand<10>";
185   let MCOperandPredicate = [{
186     int64_t Imm;
187     if (!MCOp.evaluateAsConstantImm(Imm))
188       return false;
189     return isShiftedInt<6, 4>(Imm) && (Imm != 0);
190   }];
191 }
192
193 // A 12-bit signed immediate where the least significant bit is zero.
194 def simm12_lsb0 : Operand<XLenVT> {
195   let ParserMatchClass = SImmAsmOperand<12, "Lsb0">;
196   let EncoderMethod = "getImmOpValueAsr1";
197   let DecoderMethod = "decodeSImmOperandAndLsl1<12>";
198   let MCOperandPredicate = [{
199     int64_t Imm;
200     if (MCOp.evaluateAsConstantImm(Imm))
201       return isShiftedInt<11, 1>(Imm);
202     return MCOp.isBareSymbolRef();
203   }];
204 }
205
206 //===----------------------------------------------------------------------===//
207 // Instruction Class Templates
208 //===----------------------------------------------------------------------===//
209
210 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
211 class CStackLoad<bits<3> funct3, string OpcodeStr,
212                  RegisterClass cls, DAGOperand opnd>
213     : RVInst16CI<funct3, 0b10, (outs cls:$rd), (ins SP:$rs1, opnd:$imm),
214                  OpcodeStr, "$rd, ${imm}(${rs1})">;
215
216 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
217 class CStackStore<bits<3> funct3, string OpcodeStr,
218                   RegisterClass cls, DAGOperand opnd>
219     : RVInst16CSS<funct3, 0b10, (outs), (ins cls:$rs2, SP:$rs1, opnd:$imm),
220                   OpcodeStr, "$rs2, ${imm}(${rs1})">;
221
222 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
223 class CLoad_ri<bits<3> funct3, string OpcodeStr,
224                RegisterClass cls, DAGOperand opnd>
225     : RVInst16CL<funct3, 0b00, (outs cls:$rd), (ins GPRC:$rs1, opnd:$imm),
226                  OpcodeStr, "$rd, ${imm}(${rs1})">;
227
228 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
229 class CStore_rri<bits<3> funct3, string OpcodeStr,
230                  RegisterClass cls, DAGOperand opnd>
231     : RVInst16CS<funct3, 0b00, (outs), (ins cls:$rs2, GPRC:$rs1, opnd:$imm),
232                  OpcodeStr, "$rs2, ${imm}(${rs1})">;
233
234 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
235 class Bcz<bits<3> funct3, string OpcodeStr, PatFrag CondOp,
236           RegisterClass cls>
237     : RVInst16CB<funct3, 0b01, (outs), (ins cls:$rs1, simm9_lsb0:$imm),
238                  OpcodeStr, "$rs1, $imm"> {
239   let isBranch = 1;
240   let isTerminator = 1;
241   let Inst{12} = imm{7};
242   let Inst{11-10} = imm{3-2};
243   let Inst{6-5} = imm{6-5};
244   let Inst{4-3} = imm{1-0};
245   let Inst{2} = imm{4};
246 }
247
248 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
249 class Shift_right<bits<2> funct2, string OpcodeStr, RegisterClass cls,
250                   Operand ImmOpnd>
251     : RVInst16CB<0b100, 0b01, (outs cls:$rs1_wb), (ins cls:$rs1, ImmOpnd:$imm),
252                  OpcodeStr, "$rs1, $imm"> {
253   let Constraints = "$rs1 = $rs1_wb";
254   let Inst{12} = imm{5};
255   let Inst{11-10} = funct2;
256   let Inst{6-2} = imm{4-0};
257 }
258
259 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
260 class CS_ALU<bits<6> funct6, bits<2> funct2, string OpcodeStr,
261              RegisterClass cls>
262     : RVInst16CA<funct6, funct2, 0b01, (outs cls:$rd_wb), (ins cls:$rd, cls:$rs2),
263                  OpcodeStr, "$rd, $rs2"> {
264   bits<3> rd;
265   let Constraints = "$rd = $rd_wb";
266   let Inst{9-7} = rd;
267 }
268
269 //===----------------------------------------------------------------------===//
270 // Instructions
271 //===----------------------------------------------------------------------===//
272
273 let Predicates = [HasStdExtC] in {
274
275 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
276 def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd),
277                              (ins SP:$rs1, uimm10_lsb00nonzero:$imm),
278                              "c.addi4spn", "$rd, $rs1, $imm"> {
279   bits<5> rs1;
280   let Inst{12-11} = imm{5-4};
281   let Inst{10-7} = imm{9-6};
282   let Inst{6} = imm{2};
283   let Inst{5} = imm{3};
284 }
285
286 let Predicates = [HasStdExtC, HasStdExtD] in
287 def C_FLD  : CLoad_ri<0b001, "c.fld", FPR64C, uimm8_lsb000> {
288   bits<8> imm;
289   let Inst{12-10} = imm{5-3};
290   let Inst{6-5} = imm{7-6};
291 }
292
293 def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00> {
294   bits<7> imm;
295   let Inst{12-10} = imm{5-3};
296   let Inst{6} = imm{2};
297   let Inst{5} = imm{6};
298 }
299
300 let DecoderNamespace = "RISCV32Only_",
301     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
302 def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00> {
303   bits<7> imm;
304   let Inst{12-10} = imm{5-3};
305   let Inst{6} = imm{2};
306   let Inst{5} = imm{6};
307 }
308
309 let Predicates = [HasStdExtC, IsRV64] in
310 def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000> {
311   bits<8> imm;
312   let Inst{12-10} = imm{5-3};
313   let Inst{6-5} = imm{7-6};
314 }
315
316 let Predicates = [HasStdExtC, HasStdExtD] in
317 def C_FSD  : CStore_rri<0b101, "c.fsd", FPR64C, 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 def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00> {
324   bits<7> imm;
325   let Inst{12-10} = imm{5-3};
326   let Inst{6} = imm{2};
327   let Inst{5} = imm{6};
328 }
329
330 let DecoderNamespace = "RISCV32Only_",
331     Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
332 def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00> {
333   bits<7> imm;
334   let Inst{12-10} = imm{5-3};
335   let Inst{6} = imm{2};
336   let Inst{5} = imm{6};
337 }
338
339 let Predicates = [HasStdExtC, IsRV64] in
340 def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000> {
341   bits<8> imm;
342   let Inst{12-10} = imm{5-3};
343   let Inst{6-5} = imm{7-6};
344 }
345
346 let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
347 def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
348
349 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
350 def C_ADDI : RVInst16CI<0b000, 0b01, (outs GPRNoX0:$rd_wb),
351                         (ins GPRNoX0:$rd, simm6nonzero:$imm),
352                         "c.addi", "$rd, $imm"> {
353   let Constraints = "$rd = $rd_wb";
354   let Inst{6-2} = imm{4-0};
355 }
356
357 let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
358     DecoderNamespace = "RISCV32Only_", Defs = [X1],
359     Predicates = [HasStdExtC, IsRV32]  in
360 def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
361                        "c.jal", "$offset">;
362
363 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
364     Predicates = [HasStdExtC, IsRV64] in
365 def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb),
366                          (ins GPRNoX0:$rd, simm6:$imm),
367                          "c.addiw", "$rd, $imm"> {
368   let Constraints = "$rd = $rd_wb";
369   let Inst{6-2} = imm{4-0};
370 }
371
372 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
373 def C_LI : RVInst16CI<0b010, 0b01, (outs GPRNoX0:$rd), (ins simm6:$imm),
374                       "c.li", "$rd, $imm"> {
375   let Inst{6-2} = imm{4-0};
376 }
377
378 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
379 def C_ADDI16SP : RVInst16CI<0b011, 0b01, (outs SP:$rd_wb),
380                             (ins SP:$rd, simm10_lsb0000nonzero:$imm),
381                             "c.addi16sp", "$rd, $imm"> {
382   let Constraints = "$rd = $rd_wb";
383   let Inst{12} = imm{9};
384   let Inst{11-7} = 2;
385   let Inst{6} = imm{4};
386   let Inst{5} = imm{6};
387   let Inst{4-3} = imm{8-7};
388   let Inst{2} = imm{5};
389 }
390
391 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
392 def C_LUI : RVInst16CI<0b011, 0b01, (outs GPRNoX0X2:$rd),
393                        (ins c_lui_imm:$imm),
394                        "c.lui", "$rd, $imm"> {
395   let Inst{6-2} = imm{4-0};
396 }
397
398 def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
399 def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
400
401 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
402 def C_ANDI : RVInst16CB<0b100, 0b01, (outs GPRC:$rs1_wb), (ins GPRC:$rs1, simm6:$imm),
403                         "c.andi", "$rs1, $imm"> {
404   let Constraints = "$rs1 = $rs1_wb";
405   let Inst{12} = imm{5};
406   let Inst{11-10} = 0b10;
407   let Inst{6-2} = imm{4-0};
408 }
409
410 def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
411 def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
412 def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
413 def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
414
415 let Predicates = [HasStdExtC, IsRV64] in {
416 def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
417 def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
418 }
419
420 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
421 def C_J : RVInst16CJ<0b101, 0b01, (outs), (ins simm12_lsb0:$offset),
422                      "c.j", "$offset"> {
423   let isBranch = 1;
424   let isTerminator=1;
425   let isBarrier=1;
426 }
427
428 def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
429 def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
430
431 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
432 def C_SLLI : RVInst16CI<0b000, 0b10, (outs GPRNoX0:$rd_wb),
433                         (ins GPRNoX0:$rd, uimmlog2xlennonzero:$imm),
434                         "c.slli" ,"$rd, $imm"> {
435   let Constraints = "$rd = $rd_wb";
436   let Inst{6-2} = imm{4-0};
437 }
438
439 let Predicates = [HasStdExtC, HasStdExtD] in
440 def C_FLDSP  : CStackLoad<0b001, "c.fldsp", FPR64, uimm9_lsb000> {
441   let Inst{6-5} = imm{4-3};
442   let Inst{4-2} = imm{8-6};
443 }
444
445 def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00> {
446   let Inst{6-4} = imm{4-2};
447   let Inst{3-2} = imm{7-6};
448 }
449
450 let DecoderNamespace = "RISCV32Only_",
451     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
452 def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00> {
453   let Inst{6-4} = imm{4-2};
454   let Inst{3-2} = imm{7-6};
455 }
456
457 let Predicates = [HasStdExtC, IsRV64] in
458 def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000> {
459   let Inst{6-5} = imm{4-3};
460   let Inst{4-2} = imm{8-6};
461 }
462
463 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
464 def C_JR : RVInst16CR<0b1000, 0b10, (outs), (ins GPRNoX0:$rs1),
465                       "c.jr", "$rs1"> {
466   let isBranch = 1;
467   let isBarrier = 1;
468   let isTerminator = 1;
469   let isIndirectBranch = 1;
470   let rs2 = 0;
471 }
472
473 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
474 def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
475                       "c.mv", "$rs1, $rs2">;
476
477 let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
478 def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
479
480 let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
481     isCall=1, Defs=[X1], rs2 = 0 in
482 def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
483                         "c.jalr", "$rs1">;
484
485 let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
486 def C_ADD : RVInst16CR<0b1001, 0b10, (outs GPRNoX0:$rs1_wb),
487                        (ins GPRNoX0:$rs1, GPRNoX0:$rs2),
488                        "c.add", "$rs1, $rs2"> {
489   let Constraints = "$rs1 = $rs1_wb";
490 }
491
492 let Predicates = [HasStdExtC, HasStdExtD] in
493 def C_FSDSP  : CStackStore<0b101, "c.fsdsp", FPR64, uimm9_lsb000> {
494   let Inst{12-10} = imm{5-3};
495   let Inst{9-7}   = imm{8-6};
496 }
497
498 def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00> {
499   let Inst{12-9} = imm{5-2};
500   let Inst{8-7}  = imm{7-6};
501 }
502
503 let DecoderNamespace = "RISCV32Only_",
504     Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
505 def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00> {
506   let Inst{12-9} = imm{5-2};
507   let Inst{8-7}  = imm{7-6};
508 }
509
510 let Predicates = [HasStdExtC, IsRV64] in
511 def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000> {
512   let Inst{12-10} = imm{5-3};
513   let Inst{9-7}   = imm{8-6};
514 }
515
516 // The all zeros pattern isn't a valid RISC-V instruction. It's used by GNU
517 // binutils as 16-bit instruction known to be unimplemented (i.e., trapping).
518 let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
519 def C_UNIMP : RVInst16<(outs), (ins), "c.unimp", "", [], InstFormatOther> {
520   let Inst{15-0} = 0;
521 }
522
523 } // Predicates = [HasStdExtC]
524
525 //===----------------------------------------------------------------------===//
526 // Assembler Pseudo Instructions
527 //===----------------------------------------------------------------------===//
528
529 let EmitPriority = 0 in {
530 let Predicates = [HasStdExtC, HasStdExtD] in
531 def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
532
533 def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
534
535 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
536 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
537
538 let Predicates = [HasStdExtC, IsRV64] in
539 def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
540
541 let Predicates = [HasStdExtC, HasStdExtD] in
542 def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
543
544 def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
545
546 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
547 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
548
549 let Predicates = [HasStdExtC, IsRV64] in
550 def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
551
552 let Predicates = [HasStdExtC, HasStdExtD] in
553 def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
554
555 def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
556
557 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
558 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
559
560 let Predicates = [HasStdExtC, IsRV64] in
561 def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
562
563 let Predicates = [HasStdExtC, HasStdExtD] in
564 def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
565
566 def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
567
568 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
569 def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
570
571 let Predicates = [HasStdExtC, IsRV64] in
572 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
573 }
574
575 //===----------------------------------------------------------------------===//
576 // Compress Instruction tablegen backend.
577 //===----------------------------------------------------------------------===//
578
579 class CompressPat<dag input, dag output> {
580   dag Input  = input;
581   dag Output    = output;
582   list<Predicate> Predicates = [];
583 }
584
585 // Patterns are defined in the same order the compressed instructions appear
586 // on page 82 of the ISA manual.
587
588 // Quadrant 0
589 let Predicates = [HasStdExtC] in {
590 def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
591                   (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
592 } // Predicates = [HasStdExtC]
593
594 let Predicates = [HasStdExtC, HasStdExtD] in {
595 def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
596                   (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
597 } // Predicates = [HasStdExtC, HasStdExtD]
598
599 let Predicates = [HasStdExtC] in {
600 def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
601                   (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
602 } // Predicates = [HasStdExtC]
603
604 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
605 def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
606                   (C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
607 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
608
609 let Predicates = [HasStdExtC, IsRV64] in {
610 def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
611                   (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
612 } // Predicates = [HasStdExtC, IsRV64]
613
614 let Predicates = [HasStdExtC, HasStdExtD] in {
615 def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
616                   (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
617 } // Predicates = [HasStdExtC, HasStdExtD]
618
619 let Predicates = [HasStdExtC] in {
620 def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
621                   (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
622 } // Predicates = [HasStdExtC]
623
624 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
625 def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1,uimm7_lsb00:$imm),
626                   (C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
627 } // Predicate = [HasStdExtC, HasStdExtF, IsRV32]
628
629 let Predicates = [HasStdExtC, IsRV64] in {
630 def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
631                   (C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
632 } // Predicates = [HasStdExtC, IsRV64]
633
634 // Quadrant 1
635 let Predicates = [HasStdExtC] in {
636 def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
637 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
638                   (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
639 } // Predicates = [HasStdExtC]
640
641 let Predicates = [HasStdExtC, IsRV32] in {
642 def : CompressPat<(JAL X1, simm12_lsb0:$offset),
643                   (C_JAL simm12_lsb0:$offset)>;
644 } // Predicates = [HasStdExtC, IsRV32]
645
646 let Predicates = [HasStdExtC, IsRV64] in {
647 def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
648                   (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
649 } // Predicates = [HasStdExtC, IsRV64]
650
651 let Predicates = [HasStdExtC] in {
652 def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
653                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
654 def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
655                   (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
656 def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
657                   (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
658 def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
659                   (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
660 def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
661                   (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
662 def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
663                   (C_ANDI GPRC:$rs1, simm6:$imm)>;
664 def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
665                   (C_SUB GPRC:$rs1, GPRC:$rs2)>;
666 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
667                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
668 def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
669                   (C_XOR GPRC:$rs1, GPRC:$rs2)>;
670 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
671                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
672 def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
673                   (C_OR GPRC:$rs1, GPRC:$rs2)>;
674 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
675                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
676 def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
677                   (C_AND GPRC:$rs1, GPRC:$rs2)>;
678 } //  Predicates = [HasStdExtC]
679
680 let Predicates = [HasStdExtC, IsRV64] in {
681 def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
682                   (C_LI GPRNoX0:$rd, simm6:$imm)>;
683 def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
684                   (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
685 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
686                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
687 def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
688                    (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
689 } // Predicates = [HasStdExtC, IsRV64]
690
691 let Predicates = [HasStdExtC] in {
692 def : CompressPat<(JAL X0, simm12_lsb0:$offset),
693                   (C_J simm12_lsb0:$offset)>;
694 def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
695                   (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
696 def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
697                   (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
698 } //  Predicates = [HasStdExtC]
699
700 // Quadrant 2
701 let Predicates = [HasStdExtC] in {
702 def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
703                   (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
704 } //  Predicates = [HasStdExtC]
705
706 let Predicates = [HasStdExtC, HasStdExtD] in {
707 def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
708                   (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
709 } // Predicates = [HasStdExtC, HasStdExtD]
710
711 let Predicates = [HasStdExtC] in {
712 def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
713                   (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
714 } // Predicates = [HasStdExtC]
715
716 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
717 def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
718                   (C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
719 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
720
721 let Predicates = [HasStdExtC, IsRV64] in {
722 def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
723                   (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
724 } // Predicates = [HasStdExtC, IsRV64]
725
726 let Predicates = [HasStdExtC] in {
727 def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
728                   (C_JR GPRNoX0:$rs1)>;
729 def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
730                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
731 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
732                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
733 def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
734                   (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
735 def : CompressPat<(EBREAK), (C_EBREAK)>;
736 def : CompressPat<(UNIMP), (C_UNIMP)>;
737 def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
738                   (C_JALR GPRNoX0:$rs1)>;
739 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
740                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
741 def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
742                   (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
743 } // Predicates = [HasStdExtC]
744
745 let Predicates = [HasStdExtC, HasStdExtD] in {
746 def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
747                   (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
748 } // Predicates = [HasStdExtC, HasStdExtD]
749
750 let Predicates = [HasStdExtC] in {
751 def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
752                   (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
753 } // Predicates = [HasStdExtC]
754
755 let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
756 def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
757                   (C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
758 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
759
760 let Predicates = [HasStdExtC, IsRV64] in {
761 def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
762                   (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
763 } //  Predicates = [HasStdExtC, IsRV64]