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