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
9include "RISCVInstrFormatsC.td"
10
11//===----------------------------------------------------------------------===//
12// Operand definitions.
13//===----------------------------------------------------------------------===//
14
15def UImmLog2XLenNonZeroAsmOperand : AsmOperandClass {
16  let Name = "UImmLog2XLenNonZero";
17  let RenderMethod = "addImmOperands";
18  let DiagnosticType = "InvalidUImmLog2XLenNonZero";
19}
20
21def 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
39def 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
51def 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
64def 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].
76def 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.
93def 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.
107def 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.
121def 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.
135def 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.
149def 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.
164def 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.
179def 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.
194def 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
210let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
211class 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
216let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
217class 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
222let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
223class 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
228let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
229class 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
234let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
235class 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
248let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
249class 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
259let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
260class 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
273let Predicates = [HasStdExtC] in {
274
275let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in
276def 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
286let Predicates = [HasStdExtC, HasStdExtD] in
287def 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
293def 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
300let DecoderNamespace = "RISCV32Only_",
301    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
302def 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
309let Predicates = [HasStdExtC, IsRV64] in
310def 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
316let Predicates = [HasStdExtC, HasStdExtD] in
317def 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
323def 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
330let DecoderNamespace = "RISCV32Only_",
331    Predicates = [HasStdExtC, HasStdExtF, IsRV32]  in
332def 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
339let Predicates = [HasStdExtC, IsRV64] in
340def 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
346let rd = 0, imm = 0, hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
347def C_NOP : RVInst16CI<0b000, 0b01, (outs), (ins), "c.nop", "">;
348
349let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
350def 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
357let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1,
358    DecoderNamespace = "RISCV32Only_", Defs = [X1],
359    Predicates = [HasStdExtC, IsRV32]  in
360def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset),
361                       "c.jal", "$offset">;
362
363let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
364    Predicates = [HasStdExtC, IsRV64] in
365def 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
372let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
373def 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
378let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
379def 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
391let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
392def 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
398def C_SRLI : Shift_right<0b00, "c.srli", GPRC, uimmlog2xlennonzero>;
399def C_SRAI : Shift_right<0b01, "c.srai", GPRC, uimmlog2xlennonzero>;
400
401let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
402def 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
410def C_SUB  : CS_ALU<0b100011, 0b00, "c.sub", GPRC>;
411def C_XOR  : CS_ALU<0b100011, 0b01, "c.xor", GPRC>;
412def C_OR   : CS_ALU<0b100011, 0b10, "c.or" , GPRC>;
413def C_AND  : CS_ALU<0b100011, 0b11, "c.and", GPRC>;
414
415let Predicates = [HasStdExtC, IsRV64] in {
416def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>;
417def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>;
418}
419
420let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
421def 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
428def C_BEQZ : Bcz<0b110, "c.beqz",  seteq, GPRC>;
429def C_BNEZ : Bcz<0b111, "c.bnez",  setne, GPRC>;
430
431let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
432def 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
439let Predicates = [HasStdExtC, HasStdExtD] in
440def 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
445def 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
450let DecoderNamespace = "RISCV32Only_",
451    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
452def 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
457let Predicates = [HasStdExtC, IsRV64] in
458def 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
463let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
464def 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
473let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
474def C_MV : RVInst16CR<0b1000, 0b10, (outs GPRNoX0:$rs1), (ins GPRNoX0:$rs2),
475                      "c.mv", "$rs1, $rs2">;
476
477let rs1 = 0, rs2 = 0, hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
478def C_EBREAK : RVInst16CR<0b1001, 0b10, (outs), (ins), "c.ebreak", "">;
479
480let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
481    isCall=1, Defs=[X1], rs2 = 0 in
482def C_JALR : RVInst16CR<0b1001, 0b10, (outs), (ins GPRNoX0:$rs1),
483                        "c.jalr", "$rs1">;
484
485let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
486def 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
492let Predicates = [HasStdExtC, HasStdExtD] in
493def 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
498def 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
503let DecoderNamespace = "RISCV32Only_",
504    Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
505def 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
510let Predicates = [HasStdExtC, IsRV64] in
511def 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).
518let hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
519def 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
529let EmitPriority = 0 in {
530let Predicates = [HasStdExtC, HasStdExtD] in
531def : InstAlias<"c.fld $rd, (${rs1})", (C_FLD FPR64C:$rd, GPRC:$rs1, 0)>;
532
533def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>;
534
535let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
536def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRC:$rs1, 0)>;
537
538let Predicates = [HasStdExtC, IsRV64] in
539def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>;
540
541let Predicates = [HasStdExtC, HasStdExtD] in
542def : InstAlias<"c.fsd $rs2, (${rs1})", (C_FSD FPR64C:$rs2, GPRC:$rs1, 0)>;
543
544def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>;
545
546let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
547def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRC:$rs1, 0)>;
548
549let Predicates = [HasStdExtC, IsRV64] in
550def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>;
551
552let Predicates = [HasStdExtC, HasStdExtD] in
553def : InstAlias<"c.fldsp $rd, (${rs1})", (C_FLDSP FPR64C:$rd, SP:$rs1, 0)>;
554
555def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>;
556
557let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
558def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SP:$rs1, 0)>;
559
560let Predicates = [HasStdExtC, IsRV64] in
561def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>;
562
563let Predicates = [HasStdExtC, HasStdExtD] in
564def : InstAlias<"c.fsdsp $rs2, (${rs1})", (C_FSDSP FPR64C:$rs2, SP:$rs1, 0)>;
565
566def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>;
567
568let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in
569def : InstAlias<"c.fswsp $rs2, (${rs1})", (C_FSWSP FPR32C:$rs2, SP:$rs1, 0)>;
570
571let Predicates = [HasStdExtC, IsRV64] in
572def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SP:$rs1, 0)>;
573}
574
575//===----------------------------------------------------------------------===//
576// Compress Instruction tablegen backend.
577//===----------------------------------------------------------------------===//
578
579class 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
589let Predicates = [HasStdExtC] in {
590def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
591                  (C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
592} // Predicates = [HasStdExtC]
593
594let Predicates = [HasStdExtC, HasStdExtD] in {
595def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
596                  (C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
597} // Predicates = [HasStdExtC, HasStdExtD]
598
599let Predicates = [HasStdExtC] in {
600def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
601                  (C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
602} // Predicates = [HasStdExtC]
603
604let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
605def : 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
609let Predicates = [HasStdExtC, IsRV64] in {
610def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
611                  (C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
612} // Predicates = [HasStdExtC, IsRV64]
613
614let Predicates = [HasStdExtC, HasStdExtD] in {
615def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
616                  (C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
617} // Predicates = [HasStdExtC, HasStdExtD]
618
619let Predicates = [HasStdExtC] in {
620def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
621                  (C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
622} // Predicates = [HasStdExtC]
623
624let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
625def : 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
629let Predicates = [HasStdExtC, IsRV64] in {
630def : 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
635let Predicates = [HasStdExtC] in {
636def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
637def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
638                  (C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
639} // Predicates = [HasStdExtC]
640
641let Predicates = [HasStdExtC, IsRV32] in {
642def : CompressPat<(JAL X1, simm12_lsb0:$offset),
643                  (C_JAL simm12_lsb0:$offset)>;
644} // Predicates = [HasStdExtC, IsRV32]
645
646let Predicates = [HasStdExtC, IsRV64] in {
647def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
648                  (C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
649} // Predicates = [HasStdExtC, IsRV64]
650
651let Predicates = [HasStdExtC] in {
652def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
653                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
654def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
655                  (C_ADDI16SP X2, simm10_lsb0000nonzero:$imm)>;
656def : CompressPat<(LUI GPRNoX0X2:$rd, c_lui_imm:$imm),
657                  (C_LUI GPRNoX0X2:$rd, c_lui_imm:$imm)>;
658def : CompressPat<(SRLI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
659                  (C_SRLI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
660def : CompressPat<(SRAI GPRC:$rs1, GPRC:$rs1, uimmlog2xlennonzero:$imm),
661                  (C_SRAI GPRC:$rs1, uimmlog2xlennonzero:$imm)>;
662def : CompressPat<(ANDI GPRC:$rs1, GPRC:$rs1, simm6:$imm),
663                  (C_ANDI GPRC:$rs1, simm6:$imm)>;
664def : CompressPat<(SUB GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
665                  (C_SUB GPRC:$rs1, GPRC:$rs2)>;
666def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
667                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
668def : CompressPat<(XOR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
669                  (C_XOR GPRC:$rs1, GPRC:$rs2)>;
670def : CompressPat<(OR GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
671                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
672def : CompressPat<(OR GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
673                  (C_OR GPRC:$rs1, GPRC:$rs2)>;
674def : CompressPat<(AND GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
675                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
676def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
677                  (C_AND GPRC:$rs1, GPRC:$rs2)>;
678} //  Predicates = [HasStdExtC]
679
680let Predicates = [HasStdExtC, IsRV64] in {
681def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
682                  (C_LI GPRNoX0:$rd, simm6:$imm)>;
683def : CompressPat<(SUBW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
684                  (C_SUBW GPRC:$rs1, GPRC:$rs2)>;
685def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs1, GPRC:$rs2),
686                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
687def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
688                   (C_ADDW GPRC:$rs1, GPRC:$rs2)>;
689} // Predicates = [HasStdExtC, IsRV64]
690
691let Predicates = [HasStdExtC] in {
692def : CompressPat<(JAL X0, simm12_lsb0:$offset),
693                  (C_J simm12_lsb0:$offset)>;
694def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
695                  (C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
696def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
697                  (C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
698} //  Predicates = [HasStdExtC]
699
700// Quadrant 2
701let Predicates = [HasStdExtC] in {
702def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
703                  (C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
704} //  Predicates = [HasStdExtC]
705
706let Predicates = [HasStdExtC, HasStdExtD] in {
707def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
708                  (C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
709} // Predicates = [HasStdExtC, HasStdExtD]
710
711let Predicates = [HasStdExtC] in {
712def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1,  uimm8_lsb00:$imm),
713                  (C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
714} // Predicates = [HasStdExtC]
715
716let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
717def : 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
721let Predicates = [HasStdExtC, IsRV64] in {
722def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
723                  (C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
724} // Predicates = [HasStdExtC, IsRV64]
725
726let Predicates = [HasStdExtC] in {
727def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
728                  (C_JR GPRNoX0:$rs1)>;
729def : CompressPat<(ADD GPRNoX0:$rs1, X0, GPRNoX0:$rs2),
730                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
731def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, X0),
732                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
733def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs2, 0),
734                  (C_MV GPRNoX0:$rs1, GPRNoX0:$rs2)>;
735def : CompressPat<(EBREAK), (C_EBREAK)>;
736def : CompressPat<(UNIMP), (C_UNIMP)>;
737def : CompressPat<(JALR X1, GPRNoX0:$rs1, 0),
738                  (C_JALR GPRNoX0:$rs1)>;
739def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs1, GPRNoX0:$rs2),
740                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
741def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
742                  (C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
743} // Predicates = [HasStdExtC]
744
745let Predicates = [HasStdExtC, HasStdExtD] in {
746def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
747                  (C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
748} // Predicates = [HasStdExtC, HasStdExtD]
749
750let Predicates = [HasStdExtC] in {
751def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
752                  (C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
753} // Predicates = [HasStdExtC]
754
755let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
756def : 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
760let Predicates = [HasStdExtC, IsRV64] in {
761def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
762                  (C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
763} //  Predicates = [HasStdExtC, IsRV64]
764