1 //===-- RISCVMCCodeEmitter.cpp - Convert RISCV code to machine code -------===//
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 // This file implements the RISCVMCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MCTargetDesc/RISCVFixupKinds.h"
14 #include "MCTargetDesc/RISCVMCExpr.h"
15 #include "MCTargetDesc/RISCVMCTargetDesc.h"
16 #include "Utils/RISCVBaseInfo.h"
17 #include "llvm/ADT/Statistic.h"
18 #include "llvm/CodeGen/Register.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCCodeEmitter.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCInst.h"
24 #include "llvm/MC/MCInstBuilder.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/EndianStream.h"
30 #include "llvm/Support/raw_ostream.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "mccodeemitter"
35 
36 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
37 STATISTIC(MCNumFixups, "Number of MC fixups created");
38 
39 namespace {
40 class RISCVMCCodeEmitter : public MCCodeEmitter {
41   RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
42   void operator=(const RISCVMCCodeEmitter &) = delete;
43   MCContext &Ctx;
44   MCInstrInfo const &MCII;
45 
46 public:
47   RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
48       : Ctx(ctx), MCII(MCII) {}
49 
50   ~RISCVMCCodeEmitter() override {}
51 
52   void encodeInstruction(const MCInst &MI, raw_ostream &OS,
53                          SmallVectorImpl<MCFixup> &Fixups,
54                          const MCSubtargetInfo &STI) const override;
55 
56   void expandFunctionCall(const MCInst &MI, raw_ostream &OS,
57                           SmallVectorImpl<MCFixup> &Fixups,
58                           const MCSubtargetInfo &STI) const;
59 
60   void expandAddTPRel(const MCInst &MI, raw_ostream &OS,
61                       SmallVectorImpl<MCFixup> &Fixups,
62                       const MCSubtargetInfo &STI) const;
63 
64   void expandVMSGE(const MCInst &MI, raw_ostream &OS,
65                    SmallVectorImpl<MCFixup> &Fixups,
66                    const MCSubtargetInfo &STI) const;
67 
68   /// TableGen'erated function for getting the binary encoding for an
69   /// instruction.
70   uint64_t getBinaryCodeForInstr(const MCInst &MI,
71                                  SmallVectorImpl<MCFixup> &Fixups,
72                                  const MCSubtargetInfo &STI) const;
73 
74   /// Return binary encoding of operand. If the machine operand requires
75   /// relocation, record the relocation and return zero.
76   unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
77                              SmallVectorImpl<MCFixup> &Fixups,
78                              const MCSubtargetInfo &STI) const;
79 
80   unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
81                              SmallVectorImpl<MCFixup> &Fixups,
82                              const MCSubtargetInfo &STI) const;
83 
84   unsigned getImmOpValue(const MCInst &MI, unsigned OpNo,
85                          SmallVectorImpl<MCFixup> &Fixups,
86                          const MCSubtargetInfo &STI) const;
87 
88   unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
89                        SmallVectorImpl<MCFixup> &Fixups,
90                        const MCSubtargetInfo &STI) const;
91 
92 private:
93   FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
94   void
95   verifyInstructionPredicates(const MCInst &MI,
96                               const FeatureBitset &AvailableFeatures) const;
97 };
98 } // end anonymous namespace
99 
100 MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII,
101                                               const MCRegisterInfo &MRI,
102                                               MCContext &Ctx) {
103   return new RISCVMCCodeEmitter(Ctx, MCII);
104 }
105 
106 // Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with
107 // relocation types. We expand those pseudo-instructions while encoding them,
108 // meaning AUIPC and JALR won't go through RISCV MC to MC compressed
109 // instruction transformation. This is acceptable because AUIPC has no 16-bit
110 // form and C_JALR has no immediate operand field.  We let linker relaxation
111 // deal with it. When linker relaxation is enabled, AUIPC and JALR have a
112 // chance to relax to JAL.
113 // If the C extension is enabled, JAL has a chance relax to C_JAL.
114 void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS,
115                                             SmallVectorImpl<MCFixup> &Fixups,
116                                             const MCSubtargetInfo &STI) const {
117   MCInst TmpInst;
118   MCOperand Func;
119   Register Ra;
120   if (MI.getOpcode() == RISCV::PseudoTAIL) {
121     Func = MI.getOperand(0);
122     Ra = RISCV::X6;
123   } else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
124     Func = MI.getOperand(1);
125     Ra = MI.getOperand(0).getReg();
126   } else if (MI.getOpcode() == RISCV::PseudoCALL) {
127     Func = MI.getOperand(0);
128     Ra = RISCV::X1;
129   } else if (MI.getOpcode() == RISCV::PseudoJump) {
130     Func = MI.getOperand(1);
131     Ra = MI.getOperand(0).getReg();
132   }
133   uint32_t Binary;
134 
135   assert(Func.isExpr() && "Expected expression");
136 
137   const MCExpr *CallExpr = Func.getExpr();
138 
139   // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
140   TmpInst = MCInstBuilder(RISCV::AUIPC)
141                 .addReg(Ra)
142                 .addOperand(MCOperand::createExpr(CallExpr));
143   Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
144   support::endian::write(OS, Binary, support::little);
145 
146   if (MI.getOpcode() == RISCV::PseudoTAIL ||
147       MI.getOpcode() == RISCV::PseudoJump)
148     // Emit JALR X0, Ra, 0
149     TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
150   else
151     // Emit JALR Ra, Ra, 0
152     TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
153   Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
154   support::endian::write(OS, Binary, support::little);
155 }
156 
157 // Expand PseudoAddTPRel to a simple ADD with the correct relocation.
158 void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS,
159                                         SmallVectorImpl<MCFixup> &Fixups,
160                                         const MCSubtargetInfo &STI) const {
161   MCOperand DestReg = MI.getOperand(0);
162   MCOperand SrcReg = MI.getOperand(1);
163   MCOperand TPReg = MI.getOperand(2);
164   assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
165          "Expected thread pointer as second input to TP-relative add");
166 
167   MCOperand SrcSymbol = MI.getOperand(3);
168   assert(SrcSymbol.isExpr() &&
169          "Expected expression as third input to TP-relative add");
170 
171   const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
172   assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD &&
173          "Expected tprel_add relocation on TP-relative symbol");
174 
175   // Emit the correct tprel_add relocation for the symbol.
176   Fixups.push_back(MCFixup::create(
177       0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc()));
178 
179   // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled.
180   if (STI.getFeatureBits()[RISCV::FeatureRelax]) {
181     const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
182     Fixups.push_back(MCFixup::create(
183         0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc()));
184   }
185 
186   // Emit a normal ADD instruction with the given operands.
187   MCInst TmpInst = MCInstBuilder(RISCV::ADD)
188                        .addOperand(DestReg)
189                        .addOperand(SrcReg)
190                        .addOperand(TPReg);
191   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
192   support::endian::write(OS, Binary, support::little);
193 }
194 
195 void RISCVMCCodeEmitter::expandVMSGE(const MCInst &MI, raw_ostream &OS,
196                                      SmallVectorImpl<MCFixup> &Fixups,
197                                      const MCSubtargetInfo &STI) const {
198   MCInst TmpInst;
199   uint32_t Binary;
200   unsigned Opcode;
201   switch (MI.getOpcode()) {
202   default:
203     llvm_unreachable("Unexpacted opcode. It should be vmsgeu.vx or vmsge.vx.");
204   case RISCV::PseudoVMSGEU_VX:
205   case RISCV::PseudoVMSGEU_VX_M:
206   case RISCV::PseudoVMSGEU_VX_M_T:
207     Opcode = RISCV::VMSLTU_VX;
208     break;
209   case RISCV::PseudoVMSGE_VX:
210   case RISCV::PseudoVMSGE_VX_M:
211   case RISCV::PseudoVMSGE_VX_M_T:
212     Opcode = RISCV::VMSLT_VX;
213     break;
214   }
215   if (MI.getNumOperands() == 3) {
216     // unmasked va >= x
217     //
218     //  pseudoinstruction: vmsge{u}.vx vd, va, x
219     //  expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
220     TmpInst = MCInstBuilder(Opcode)
221                   .addOperand(MI.getOperand(0))
222                   .addOperand(MI.getOperand(1))
223                   .addOperand(MI.getOperand(2))
224                   .addReg(RISCV::NoRegister);
225     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
226     support::endian::write(OS, Binary, support::little);
227 
228     TmpInst = MCInstBuilder(RISCV::VMNAND_MM)
229                   .addOperand(MI.getOperand(0))
230                   .addOperand(MI.getOperand(0))
231                   .addOperand(MI.getOperand(0));
232     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
233     support::endian::write(OS, Binary, support::little);
234   } else if (MI.getNumOperands() == 4) {
235     // masked va >= x, vd != v0
236     //
237     //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
238     //  expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
239     assert(MI.getOperand(0).getReg() != RISCV::V0 &&
240            "The destination register should not be V0.");
241     TmpInst = MCInstBuilder(Opcode)
242                   .addOperand(MI.getOperand(0))
243                   .addOperand(MI.getOperand(1))
244                   .addOperand(MI.getOperand(2))
245                   .addOperand(MI.getOperand(3));
246     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
247     support::endian::write(OS, Binary, support::little);
248 
249     TmpInst = MCInstBuilder(RISCV::VMXOR_MM)
250                   .addOperand(MI.getOperand(0))
251                   .addOperand(MI.getOperand(0))
252                   .addReg(RISCV::V0);
253     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
254     support::endian::write(OS, Binary, support::little);
255   } else if (MI.getNumOperands() == 5) {
256     // masked va >= x, vd == v0
257     //
258     //  pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
259     //  expansion: vmslt{u}.vx vt, va, x;  vmandnot.mm vd, vd, vt
260     assert(MI.getOperand(0).getReg() == RISCV::V0 &&
261            "The destination register should be V0.");
262     assert(MI.getOperand(1).getReg() != RISCV::V0 &&
263            "The temporary vector register should not be V0.");
264     TmpInst = MCInstBuilder(Opcode)
265                   .addOperand(MI.getOperand(1))
266                   .addOperand(MI.getOperand(2))
267                   .addOperand(MI.getOperand(3))
268                   .addOperand(MI.getOperand(4));
269     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
270     support::endian::write(OS, Binary, support::little);
271 
272     TmpInst = MCInstBuilder(RISCV::VMANDNOT_MM)
273                   .addOperand(MI.getOperand(0))
274                   .addOperand(MI.getOperand(0))
275                   .addOperand(MI.getOperand(1));
276     Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
277     support::endian::write(OS, Binary, support::little);
278   }
279 }
280 
281 void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
282                                            SmallVectorImpl<MCFixup> &Fixups,
283                                            const MCSubtargetInfo &STI) const {
284   verifyInstructionPredicates(MI,
285                               computeAvailableFeatures(STI.getFeatureBits()));
286 
287   const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
288   // Get byte count of instruction.
289   unsigned Size = Desc.getSize();
290 
291   // RISCVInstrInfo::getInstSizeInBytes hard-codes the number of expanded
292   // instructions for each pseudo, and must be updated when adding new pseudos
293   // or changing existing ones.
294   if (MI.getOpcode() == RISCV::PseudoCALLReg ||
295       MI.getOpcode() == RISCV::PseudoCALL ||
296       MI.getOpcode() == RISCV::PseudoTAIL ||
297       MI.getOpcode() == RISCV::PseudoJump) {
298     expandFunctionCall(MI, OS, Fixups, STI);
299     MCNumEmitted += 2;
300     return;
301   }
302 
303   if (MI.getOpcode() == RISCV::PseudoAddTPRel) {
304     expandAddTPRel(MI, OS, Fixups, STI);
305     MCNumEmitted += 1;
306     return;
307   }
308 
309   if (MI.getOpcode() == RISCV::PseudoVMSGEU_VX ||
310       MI.getOpcode() == RISCV::PseudoVMSGE_VX ||
311       MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M ||
312       MI.getOpcode() == RISCV::PseudoVMSGE_VX_M ||
313       MI.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T ||
314       MI.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) {
315     expandVMSGE(MI, OS, Fixups, STI);
316     return;
317   }
318 
319   switch (Size) {
320   default:
321     llvm_unreachable("Unhandled encodeInstruction length!");
322   case 2: {
323     uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
324     support::endian::write<uint16_t>(OS, Bits, support::little);
325     break;
326   }
327   case 4: {
328     uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
329     support::endian::write(OS, Bits, support::little);
330     break;
331   }
332   }
333 
334   ++MCNumEmitted; // Keep track of the # of mi's emitted.
335 }
336 
337 unsigned
338 RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
339                                       SmallVectorImpl<MCFixup> &Fixups,
340                                       const MCSubtargetInfo &STI) const {
341 
342   if (MO.isReg())
343     return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
344 
345   if (MO.isImm())
346     return static_cast<unsigned>(MO.getImm());
347 
348   llvm_unreachable("Unhandled expression!");
349   return 0;
350 }
351 
352 unsigned
353 RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
354                                       SmallVectorImpl<MCFixup> &Fixups,
355                                       const MCSubtargetInfo &STI) const {
356   const MCOperand &MO = MI.getOperand(OpNo);
357 
358   if (MO.isImm()) {
359     unsigned Res = MO.getImm();
360     assert((Res & 1) == 0 && "LSB is non-zero");
361     return Res >> 1;
362   }
363 
364   return getImmOpValue(MI, OpNo, Fixups, STI);
365 }
366 
367 unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
368                                            SmallVectorImpl<MCFixup> &Fixups,
369                                            const MCSubtargetInfo &STI) const {
370   bool EnableRelax = STI.getFeatureBits()[RISCV::FeatureRelax];
371   const MCOperand &MO = MI.getOperand(OpNo);
372 
373   MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
374   unsigned MIFrm = Desc.TSFlags & RISCVII::InstFormatMask;
375 
376   // If the destination is an immediate, there is nothing to do.
377   if (MO.isImm())
378     return MO.getImm();
379 
380   assert(MO.isExpr() &&
381          "getImmOpValue expects only expressions or immediates");
382   const MCExpr *Expr = MO.getExpr();
383   MCExpr::ExprKind Kind = Expr->getKind();
384   RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid;
385   bool RelaxCandidate = false;
386   if (Kind == MCExpr::Target) {
387     const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
388 
389     switch (RVExpr->getKind()) {
390     case RISCVMCExpr::VK_RISCV_None:
391     case RISCVMCExpr::VK_RISCV_Invalid:
392     case RISCVMCExpr::VK_RISCV_32_PCREL:
393       llvm_unreachable("Unhandled fixup kind!");
394     case RISCVMCExpr::VK_RISCV_TPREL_ADD:
395       // tprel_add is only used to indicate that a relocation should be emitted
396       // for an add instruction used in TP-relative addressing. It should not be
397       // expanded as if representing an actual instruction operand and so to
398       // encounter it here is an error.
399       llvm_unreachable(
400           "VK_RISCV_TPREL_ADD should not represent an instruction operand");
401     case RISCVMCExpr::VK_RISCV_LO:
402       if (MIFrm == RISCVII::InstFormatI)
403         FixupKind = RISCV::fixup_riscv_lo12_i;
404       else if (MIFrm == RISCVII::InstFormatS)
405         FixupKind = RISCV::fixup_riscv_lo12_s;
406       else
407         llvm_unreachable("VK_RISCV_LO used with unexpected instruction format");
408       RelaxCandidate = true;
409       break;
410     case RISCVMCExpr::VK_RISCV_HI:
411       FixupKind = RISCV::fixup_riscv_hi20;
412       RelaxCandidate = true;
413       break;
414     case RISCVMCExpr::VK_RISCV_PCREL_LO:
415       if (MIFrm == RISCVII::InstFormatI)
416         FixupKind = RISCV::fixup_riscv_pcrel_lo12_i;
417       else if (MIFrm == RISCVII::InstFormatS)
418         FixupKind = RISCV::fixup_riscv_pcrel_lo12_s;
419       else
420         llvm_unreachable(
421             "VK_RISCV_PCREL_LO used with unexpected instruction format");
422       RelaxCandidate = true;
423       break;
424     case RISCVMCExpr::VK_RISCV_PCREL_HI:
425       FixupKind = RISCV::fixup_riscv_pcrel_hi20;
426       RelaxCandidate = true;
427       break;
428     case RISCVMCExpr::VK_RISCV_GOT_HI:
429       FixupKind = RISCV::fixup_riscv_got_hi20;
430       break;
431     case RISCVMCExpr::VK_RISCV_TPREL_LO:
432       if (MIFrm == RISCVII::InstFormatI)
433         FixupKind = RISCV::fixup_riscv_tprel_lo12_i;
434       else if (MIFrm == RISCVII::InstFormatS)
435         FixupKind = RISCV::fixup_riscv_tprel_lo12_s;
436       else
437         llvm_unreachable(
438             "VK_RISCV_TPREL_LO used with unexpected instruction format");
439       RelaxCandidate = true;
440       break;
441     case RISCVMCExpr::VK_RISCV_TPREL_HI:
442       FixupKind = RISCV::fixup_riscv_tprel_hi20;
443       RelaxCandidate = true;
444       break;
445     case RISCVMCExpr::VK_RISCV_TLS_GOT_HI:
446       FixupKind = RISCV::fixup_riscv_tls_got_hi20;
447       break;
448     case RISCVMCExpr::VK_RISCV_TLS_GD_HI:
449       FixupKind = RISCV::fixup_riscv_tls_gd_hi20;
450       break;
451     case RISCVMCExpr::VK_RISCV_CALL:
452       FixupKind = RISCV::fixup_riscv_call;
453       RelaxCandidate = true;
454       break;
455     case RISCVMCExpr::VK_RISCV_CALL_PLT:
456       FixupKind = RISCV::fixup_riscv_call_plt;
457       RelaxCandidate = true;
458       break;
459     }
460   } else if (Kind == MCExpr::SymbolRef &&
461              cast<MCSymbolRefExpr>(Expr)->getKind() == MCSymbolRefExpr::VK_None) {
462     if (Desc.getOpcode() == RISCV::JAL) {
463       FixupKind = RISCV::fixup_riscv_jal;
464     } else if (MIFrm == RISCVII::InstFormatB) {
465       FixupKind = RISCV::fixup_riscv_branch;
466     } else if (MIFrm == RISCVII::InstFormatCJ) {
467       FixupKind = RISCV::fixup_riscv_rvc_jump;
468     } else if (MIFrm == RISCVII::InstFormatCB) {
469       FixupKind = RISCV::fixup_riscv_rvc_branch;
470     }
471   }
472 
473   assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
474 
475   Fixups.push_back(
476       MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
477   ++MCNumFixups;
478 
479   // Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is
480   // enabled and the current fixup will result in a relocation that may be
481   // relaxed.
482   if (EnableRelax && RelaxCandidate) {
483     const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
484     Fixups.push_back(
485     MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax),
486                     MI.getLoc()));
487     ++MCNumFixups;
488   }
489 
490   return 0;
491 }
492 
493 unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
494                                          SmallVectorImpl<MCFixup> &Fixups,
495                                          const MCSubtargetInfo &STI) const {
496   MCOperand MO = MI.getOperand(OpNo);
497   assert(MO.isReg() && "Expected a register.");
498 
499   switch (MO.getReg()) {
500   default:
501     llvm_unreachable("Invalid mask register.");
502   case RISCV::V0:
503     return 0;
504   case RISCV::NoRegister:
505     return 1;
506   }
507 }
508 
509 #define ENABLE_INSTR_PREDICATE_VERIFIER
510 #include "RISCVGenMCCodeEmitter.inc"
511