LLVM 23.0.0git
RISCVMCCodeEmitter.cpp
Go to the documentation of this file.
1//===-- RISCVMCCodeEmitter.cpp - Convert RISC-V 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
17#include "llvm/ADT/Statistic.h"
18#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
24#include "llvm/MC/MCInstrInfo.h"
27#include "llvm/MC/MCSymbol.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "mccodeemitter"
34
35STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
36STATISTIC(MCNumFixups, "Number of MC fixups created");
37
38namespace {
39class RISCVMCCodeEmitter : public MCCodeEmitter {
40 RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
41 void operator=(const RISCVMCCodeEmitter &) = delete;
42 MCContext &Ctx;
43 MCInstrInfo const &MCII;
44
45public:
46 RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
47 : Ctx(ctx), MCII(MCII) {}
48
49 ~RISCVMCCodeEmitter() override = default;
50
51 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
52 SmallVectorImpl<MCFixup> &Fixups,
53 const MCSubtargetInfo &STI) const override;
54
55 void expandFunctionCall(const MCInst &MI, SmallVectorImpl<char> &CB,
56 SmallVectorImpl<MCFixup> &Fixups,
57 const MCSubtargetInfo &STI) const;
58
59 void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB,
60 SmallVectorImpl<MCFixup> &Fixups,
61 const MCSubtargetInfo &STI) const;
62
63 void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB,
64 SmallVectorImpl<MCFixup> &Fixups,
65 const MCSubtargetInfo &STI) const;
66
67 void expandLongCondBr(const MCInst &MI, SmallVectorImpl<char> &CB,
68 SmallVectorImpl<MCFixup> &Fixups,
69 const MCSubtargetInfo &STI) const;
70
71 void expandFunctionCallLpad(const MCInst &MI, SmallVectorImpl<char> &CB,
72 SmallVectorImpl<MCFixup> &Fixups,
73 const MCSubtargetInfo &STI) const;
74
75 void expandQCLongCondBrImm(const MCInst &MI, SmallVectorImpl<char> &CB,
76 SmallVectorImpl<MCFixup> &Fixups,
77 const MCSubtargetInfo &STI, unsigned Size) const;
78
79 void expandPseudoQCAccess(const MCInst &MI, SmallVectorImpl<char> &CB,
80 SmallVectorImpl<MCFixup> &Fixups,
81 const MCSubtargetInfo &STI) const;
82
83 /// TableGen'erated function for getting the binary encoding for an
84 /// instruction.
85 uint64_t getBinaryCodeForInstr(const MCInst &MI,
86 SmallVectorImpl<MCFixup> &Fixups,
87 const MCSubtargetInfo &STI) const;
88
89 /// Return binary encoding of operand. If the machine operand requires
90 /// relocation, record the relocation and return zero.
91 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
92 SmallVectorImpl<MCFixup> &Fixups,
93 const MCSubtargetInfo &STI) const;
94
95 uint64_t getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
96 SmallVectorImpl<MCFixup> &Fixups,
97 const MCSubtargetInfo &STI) const;
98
99 uint64_t getImmOpValueSlist(const MCInst &MI, unsigned OpNo,
100 SmallVectorImpl<MCFixup> &Fixups,
101 const MCSubtargetInfo &STI) const;
102
103 template <unsigned N>
104 unsigned getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
105 SmallVectorImpl<MCFixup> &Fixups,
106 const MCSubtargetInfo &STI) const;
107
108 uint64_t getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
109 SmallVectorImpl<MCFixup> &Fixups,
110 const MCSubtargetInfo &STI) const;
111
112 uint64_t getImmOpValue(const MCInst &MI, unsigned OpNo,
113 SmallVectorImpl<MCFixup> &Fixups,
114 const MCSubtargetInfo &STI) const;
115
116 unsigned getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo,
117 SmallVectorImpl<MCFixup> &Fixups,
118 const MCSubtargetInfo &STI) const;
119
120 unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
121 SmallVectorImpl<MCFixup> &Fixups,
122 const MCSubtargetInfo &STI) const;
123
124 unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
125 SmallVectorImpl<MCFixup> &Fixups,
126 const MCSubtargetInfo &STI) const;
127
128 unsigned getRlistS0OpValue(const MCInst &MI, unsigned OpNo,
129 SmallVectorImpl<MCFixup> &Fixups,
130 const MCSubtargetInfo &STI) const;
131};
132} // end anonymous namespace
133
135 MCContext &Ctx) {
136 return new RISCVMCCodeEmitter(Ctx, MCII);
137}
138
140 const MCExpr *Value, uint16_t Kind) {
141 bool PCRel = false;
142 switch (Kind) {
143 case ELF::R_RISCV_CALL_PLT:
156 PCRel = true;
157 }
158 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
159}
160
161// Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with
162// relocation types. We expand those pseudo-instructions while encoding them,
163// meaning AUIPC and JALR won't go through RISC-V MC to MC compressed
164// instruction transformation. This is acceptable because AUIPC has no 16-bit
165// form and C_JALR has no immediate operand field. We let linker relaxation
166// deal with it. When linker relaxation is enabled, AUIPC and JALR have a
167// chance to relax to JAL.
168// If the C extension is enabled, JAL has a chance relax to C_JAL.
169void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI,
172 const MCSubtargetInfo &STI) const {
173 MCInst TmpInst;
174 MCOperand Func;
175 MCRegister Ra;
176 if (MI.getOpcode() == RISCV::PseudoTAIL) {
177 Func = MI.getOperand(0);
179 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
180 Func = MI.getOperand(1);
181 Ra = MI.getOperand(0).getReg();
182 } else if (MI.getOpcode() == RISCV::PseudoCALL) {
183 Func = MI.getOperand(0);
184 Ra = RISCV::X1;
185 } else if (MI.getOpcode() == RISCV::PseudoJump) {
186 Func = MI.getOperand(1);
187 Ra = MI.getOperand(0).getReg();
188 }
189 uint32_t Binary;
190
191 assert(Func.isExpr() && "Expected expression");
192
193 const MCExpr *CallExpr = Func.getExpr();
194
196 MCOperand FuncOp = MCOperand::createExpr(CallExpr);
197 if (MI.getOpcode() == RISCV::PseudoTAIL ||
198 MI.getOpcode() == RISCV::PseudoJump)
199 // Emit JAL X0, Func
200 TmpInst = MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(FuncOp);
201 else
202 // Emit JAL Ra, Func
203 TmpInst = MCInstBuilder(RISCV::JAL).addReg(Ra).addOperand(FuncOp);
204 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
206 return;
207 }
208 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
209 TmpInst = MCInstBuilder(RISCV::AUIPC).addReg(Ra).addExpr(CallExpr);
210 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
212
213 if (MI.getOpcode() == RISCV::PseudoTAIL ||
214 MI.getOpcode() == RISCV::PseudoJump)
215 // Emit JALR X0, Ra, 0
216 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
217 else
218 // Emit JALR Ra, Ra, 0
219 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
220 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
222}
223
224// Expand to AUIPC+JALR+LPAD (direct) or JALR+LPAD (indirect).
225// R_RISCV_RELAX is not emitted for the call because linker relaxation could
226// convert it to c.jal/cm.jalt, which would misalign the following LPAD.
227void RISCVMCCodeEmitter::expandFunctionCallLpad(
228 const MCInst &MI, SmallVectorImpl<char> &CB,
229 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
230 bool IsIndirect = MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign;
231 MCInst TmpInst;
232 uint32_t Binary;
233
234 if (!IsIndirect) {
235 const MCOperand &Func = MI.getOperand(0);
236 assert(Func.isExpr() && "Expected expression for call target");
237
238 // Use a STI without FeatureRelax so getImmOpValue does not mark the
239 // R_RISCV_CALL_PLT fixup as LinkerRelaxable (which would emit
240 // R_RISCV_RELAX).
241 MCSubtargetInfo NoRelaxSTI(STI);
242 if (STI.hasFeature(RISCV::FeatureRelax))
243 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
244
245 TmpInst =
246 MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X1).addExpr(Func.getExpr());
247 Binary = getBinaryCodeForInstr(TmpInst, Fixups, NoRelaxSTI);
249
250 TmpInst = MCInstBuilder(RISCV::JALR)
251 .addReg(RISCV::X1)
252 .addReg(RISCV::X1)
253 .addImm(0);
254 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
256 } else {
257 TmpInst = MCInstBuilder(RISCV::JALR)
258 .addReg(RISCV::X1)
259 .addReg(MI.getOperand(0).getReg())
260 .addImm(0);
261 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
263 }
264
265 // LPAD is encoded as AUIPC X0, label.
266 TmpInst = MCInstBuilder(RISCV::AUIPC)
267 .addReg(RISCV::X0)
268 .addImm(MI.getOperand(1).getImm());
269 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
271}
272
273void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI,
274 SmallVectorImpl<char> &CB,
275 SmallVectorImpl<MCFixup> &Fixups,
276 const MCSubtargetInfo &STI) const {
277 MCOperand SrcSymbol = MI.getOperand(3);
278 assert(SrcSymbol.isExpr() &&
279 "Expected expression as first input to TLSDESCCALL");
280 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr());
281 MCRegister Link = MI.getOperand(0).getReg();
282 MCRegister Dest = MI.getOperand(1).getReg();
283 int64_t Imm = MI.getOperand(2).getImm();
284 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TLSDESC_CALL);
285 MCInst Call =
286 MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm);
287
288 uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI);
290}
291
292// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
293void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
294 SmallVectorImpl<char> &CB,
295 SmallVectorImpl<MCFixup> &Fixups,
296 const MCSubtargetInfo &STI) const {
297 MCOperand DestReg = MI.getOperand(0);
298 MCOperand SrcReg = MI.getOperand(1);
299 MCOperand TPReg = MI.getOperand(2);
300 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
301 "Expected thread pointer as second input to TP-relative add");
302
303 MCOperand SrcSymbol = MI.getOperand(3);
304 assert(SrcSymbol.isExpr() &&
305 "Expected expression as third input to TP-relative add");
306
307 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr());
308 assert(Expr && Expr->getSpecifier() == ELF::R_RISCV_TPREL_ADD &&
309 "Expected tprel_add relocation on TP-relative symbol");
310
311 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TPREL_ADD);
312 if (STI.hasFeature(RISCV::FeatureRelax))
313 Fixups.back().setLinkerRelaxable();
314
315 // Emit a normal ADD instruction with the given operands.
316 MCInst TmpInst = MCInstBuilder(RISCV::ADD)
317 .addOperand(DestReg)
318 .addOperand(SrcReg)
319 .addOperand(TPReg);
320 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
322}
323
324static unsigned getInvertedBranchOp(unsigned BrOp) {
325 switch (BrOp) {
326 default:
327 llvm_unreachable("Unexpected branch opcode!");
328 case RISCV::PseudoLongBEQ:
329 return RISCV::BNE;
330 case RISCV::PseudoLongBNE:
331 return RISCV::BEQ;
332 case RISCV::PseudoLongBEQI:
333 return RISCV::BNEI;
334 case RISCV::PseudoLongBNEI:
335 return RISCV::BEQI;
336 case RISCV::PseudoLongBLT:
337 return RISCV::BGE;
338 case RISCV::PseudoLongBGE:
339 return RISCV::BLT;
340 case RISCV::PseudoLongBLTU:
341 return RISCV::BGEU;
342 case RISCV::PseudoLongBGEU:
343 return RISCV::BLTU;
344 case RISCV::PseudoLongQC_BEQI:
345 return RISCV::QC_BNEI;
346 case RISCV::PseudoLongQC_BNEI:
347 return RISCV::QC_BEQI;
348 case RISCV::PseudoLongQC_BLTI:
349 return RISCV::QC_BGEI;
350 case RISCV::PseudoLongQC_BGEI:
351 return RISCV::QC_BLTI;
352 case RISCV::PseudoLongQC_BLTUI:
353 return RISCV::QC_BGEUI;
354 case RISCV::PseudoLongQC_BGEUI:
355 return RISCV::QC_BLTUI;
356 case RISCV::PseudoLongQC_E_BEQI:
357 return RISCV::QC_E_BNEI;
358 case RISCV::PseudoLongQC_E_BNEI:
359 return RISCV::QC_E_BEQI;
360 case RISCV::PseudoLongQC_E_BLTI:
361 return RISCV::QC_E_BGEI;
362 case RISCV::PseudoLongQC_E_BGEI:
363 return RISCV::QC_E_BLTI;
364 case RISCV::PseudoLongQC_E_BLTUI:
365 return RISCV::QC_E_BGEUI;
366 case RISCV::PseudoLongQC_E_BGEUI:
367 return RISCV::QC_E_BLTUI;
368 case RISCV::PseudoLongCV_BEQIMM:
369 return RISCV::CV_BNEIMM;
370 case RISCV::PseudoLongCV_BNEIMM:
371 return RISCV::CV_BEQIMM;
372 }
373}
374
375// Expand PseudoLongBxx to an inverted conditional branch and an unconditional
376// jump.
377void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
378 SmallVectorImpl<char> &CB,
379 SmallVectorImpl<MCFixup> &Fixups,
380 const MCSubtargetInfo &STI) const {
381 MCRegister SrcReg1 = MI.getOperand(0).getReg();
382 const MCOperand &Src2 = MI.getOperand(1);
383 const MCOperand &SrcSymbol = MI.getOperand(2);
384 unsigned Opcode = MI.getOpcode();
385 bool IsEqTest =
386 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
387
388 bool UseCompressedBr = false;
389 if (IsEqTest && STI.hasFeature(RISCV::FeatureStdExtZca)) {
390 MCRegister SrcReg2 = Src2.getReg();
391 if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 &&
392 SrcReg2.id() == RISCV::X0) {
393 UseCompressedBr = true;
394 } else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 &&
395 SrcReg1.id() == RISCV::X0) {
396 std::swap(SrcReg1, SrcReg2);
397 UseCompressedBr = true;
398 }
399 }
400
401 uint32_t Offset;
402 if (UseCompressedBr) {
403 unsigned InvOpc =
404 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
405 MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6);
406 uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
408 Offset = 2;
409 } else {
410 unsigned InvOpc = getInvertedBranchOp(Opcode);
411 MCInst TmpInst =
412 MCInstBuilder(InvOpc).addReg(SrcReg1).addOperand(Src2).addImm(8);
413 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
415 Offset = 4;
416 }
417
418 // Save the number fixups.
419 size_t FixupStartIndex = Fixups.size();
420
421 // Emit an unconditional jump to the destination.
422 MCInst TmpInst =
423 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
424 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
426
427 // Drop any fixup added so we can add the correct one.
428 Fixups.resize(FixupStartIndex);
429
430 if (SrcSymbol.isExpr()) {
431 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
432 if (STI.hasFeature(RISCV::FeatureRelax))
433 Fixups.back().setLinkerRelaxable();
434 }
435}
436
437// Expand PseudoLongQC_(E_)Bxxx to an inverted conditional branch and an
438// unconditional jump.
439void RISCVMCCodeEmitter::expandQCLongCondBrImm(const MCInst &MI,
440 SmallVectorImpl<char> &CB,
441 SmallVectorImpl<MCFixup> &Fixups,
442 const MCSubtargetInfo &STI,
443 unsigned Size) const {
444 MCRegister SrcReg1 = MI.getOperand(0).getReg();
445 auto BrImm = MI.getOperand(1).getImm();
446 MCOperand SrcSymbol = MI.getOperand(2);
447 unsigned Opcode = MI.getOpcode();
448 uint32_t Offset;
449 unsigned InvOpc = getInvertedBranchOp(Opcode);
450 // Emit inverted conditional branch with offset:
451 // 8 (QC.BXXX(4) + JAL(4))
452 // or
453 // 10 (QC.E.BXXX(6) + JAL(4)).
454 if (Size == 4) {
455 MCInst TmpBr =
456 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(8);
457 uint32_t BrBinary = getBinaryCodeForInstr(TmpBr, Fixups, STI);
459 } else {
460 MCInst TmpBr =
461 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(10);
462 uint64_t BrBinary =
463 getBinaryCodeForInstr(TmpBr, Fixups, STI) & 0xffff'ffff'ffffu;
464 SmallVector<char, 8> Encoding;
466 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
467 "Unexpected encoding for 48-bit instruction");
468 Encoding.truncate(6);
469 CB.append(Encoding);
470 }
471 Offset = Size;
472 // Save the number fixups.
473 size_t FixupStartIndex = Fixups.size();
474 // Emit an unconditional jump to the destination.
475 MCInst TmpJ =
476 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
477 uint32_t JBinary = getBinaryCodeForInstr(TmpJ, Fixups, STI);
479 // Drop any fixup added so we can add the correct one.
480 Fixups.resize(FixupStartIndex);
481 if (SrcSymbol.isExpr()) {
482 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
483 if (STI.hasFeature(RISCV::FeatureRelax))
484 Fixups.back().setLinkerRelaxable();
485 }
486}
487
488void RISCVMCCodeEmitter::expandPseudoQCAccess(
489 const MCInst &MI, SmallVectorImpl<char> &CB,
490 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
491 unsigned AccessOpc;
492
493 switch (MI.getOpcode()) {
494#define QC_ACCESS_CASE(_Suffix) \
495 case RISCV::PseudoQCAccess##_Suffix: \
496 AccessOpc = RISCV::_Suffix; \
497 break;
498 // clang-format off
500 QC_ACCESS_CASE(LBU)
502 QC_ACCESS_CASE(LHU)
507 QC_ACCESS_CASE(C_LBU)
508 QC_ACCESS_CASE(C_LH)
509 QC_ACCESS_CASE(C_LHU)
510 QC_ACCESS_CASE(C_LW)
511 QC_ACCESS_CASE(C_SB)
512 QC_ACCESS_CASE(C_SH)
513 QC_ACCESS_CASE(C_SW)
514 // clang-format on
515 default:
516 llvm_unreachable("Unhandled QC Access Opcode");
517 };
518
519 MCInst TmpAccess = MCInstBuilder(AccessOpc)
520 .addOperand(MI.getOperand(0))
521 .addOperand(MI.getOperand(1))
522 .addOperand(MI.getOperand(2));
523 unsigned Size = MCII.get(AccessOpc).getSize();
524 uint16_t FixupKind;
525 switch (Size) {
526 default:
527 llvm_unreachable("Unhandled QC Access Instruction Size");
528 case 2: {
529 uint16_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
532 break;
533 }
534 case 4: {
535 uint32_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
538 break;
539 }
540 }
541 // Only emit the qc.access fixup if linker relaxation is enabled. The pass has
542 // already checked for this before using the Pseudos, but the user may have
543 // written the instructions directly in assembly.
544 if (!STI.hasFeature(RISCV::FeatureRelax))
545 return;
546
547 const MCOperand &AccessSymbol = MI.getOperand(3);
548 assert(AccessSymbol.isExpr() && "Expected expression in PseudoQCAccess");
549
550 const auto *AccessExpr = cast<MCSpecifierExpr>(AccessSymbol.getExpr());
551 assert(AccessExpr->getSpecifier() == RISCV::S_QC_ACCESS &&
552 "Expected qc.access specifier on symbol");
553
554 addFixup(Fixups, /*Offset=*/0, AccessExpr, FixupKind);
555 // The added fixup is always linker relaxable.
556 Fixups.back().setLinkerRelaxable();
557}
558
559void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
560 SmallVectorImpl<char> &CB,
561 SmallVectorImpl<MCFixup> &Fixups,
562 const MCSubtargetInfo &STI) const {
563 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
564 // Get byte count of instruction.
565 unsigned Size = Desc.getSize();
566
567 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
568 // expanded instructions for each pseudo is correct in the Size field of the
569 // tablegen definition for the pseudo.
570 switch (MI.getOpcode()) {
571 default:
572 break;
573 case RISCV::PseudoCALLReg:
574 case RISCV::PseudoCALL:
575 case RISCV::PseudoTAIL:
576 case RISCV::PseudoJump:
577 expandFunctionCall(MI, CB, Fixups, STI);
578 MCNumEmitted += 2;
579 return;
580 case RISCV::PseudoCALLLpadAlign:
581 expandFunctionCallLpad(MI, CB, Fixups, STI);
582 MCNumEmitted += 3; // AUIPC + JALR + LPAD
583 return;
584 case RISCV::PseudoCALLIndirectLpadAlign:
585 expandFunctionCallLpad(MI, CB, Fixups, STI);
586 MCNumEmitted += 2; // JALR + LPAD
587 return;
588 case RISCV::PseudoAddTPRel:
589 expandAddTPRel(MI, CB, Fixups, STI);
590 MCNumEmitted += 1;
591 return;
592 case RISCV::PseudoLongBEQ:
593 case RISCV::PseudoLongBNE:
594 case RISCV::PseudoLongBEQI:
595 case RISCV::PseudoLongBNEI:
596 case RISCV::PseudoLongBLT:
597 case RISCV::PseudoLongBGE:
598 case RISCV::PseudoLongBLTU:
599 case RISCV::PseudoLongBGEU:
600 expandLongCondBr(MI, CB, Fixups, STI);
601 MCNumEmitted += 2;
602 return;
603 case RISCV::PseudoLongQC_BEQI:
604 case RISCV::PseudoLongQC_BNEI:
605 case RISCV::PseudoLongQC_BLTI:
606 case RISCV::PseudoLongQC_BGEI:
607 case RISCV::PseudoLongQC_BLTUI:
608 case RISCV::PseudoLongQC_BGEUI:
609 case RISCV::PseudoLongCV_BEQIMM:
610 case RISCV::PseudoLongCV_BNEIMM:
611 expandQCLongCondBrImm(MI, CB, Fixups, STI, 4);
612 MCNumEmitted += 2;
613 return;
614 case RISCV::PseudoLongQC_E_BEQI:
615 case RISCV::PseudoLongQC_E_BNEI:
616 case RISCV::PseudoLongQC_E_BLTI:
617 case RISCV::PseudoLongQC_E_BGEI:
618 case RISCV::PseudoLongQC_E_BLTUI:
619 case RISCV::PseudoLongQC_E_BGEUI:
620 expandQCLongCondBrImm(MI, CB, Fixups, STI, 6);
621 MCNumEmitted += 2;
622 return;
623 case RISCV::PseudoTLSDESCCall:
624 expandTLSDESCCall(MI, CB, Fixups, STI);
625 MCNumEmitted += 1;
626 return;
627 case RISCV::PseudoQCAccessLB:
628 case RISCV::PseudoQCAccessLBU:
629 case RISCV::PseudoQCAccessLH:
630 case RISCV::PseudoQCAccessLHU:
631 case RISCV::PseudoQCAccessLW:
632 case RISCV::PseudoQCAccessSB:
633 case RISCV::PseudoQCAccessSH:
634 case RISCV::PseudoQCAccessSW:
635 case RISCV::PseudoQCAccessC_LBU:
636 case RISCV::PseudoQCAccessC_LH:
637 case RISCV::PseudoQCAccessC_LHU:
638 case RISCV::PseudoQCAccessC_LW:
639 case RISCV::PseudoQCAccessC_SB:
640 case RISCV::PseudoQCAccessC_SH:
641 case RISCV::PseudoQCAccessC_SW:
642 expandPseudoQCAccess(MI, CB, Fixups, STI);
643 MCNumEmitted += 1;
644 return;
645 }
646
647 switch (Size) {
648 default:
649 llvm_unreachable("Unhandled encodeInstruction length!");
650 case 2: {
651 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
653 break;
654 }
655 case 4: {
656 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
658 break;
659 }
660 case 6: {
661 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI) & 0xffff'ffff'ffffu;
662 SmallVector<char, 8> Encoding;
664 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
665 "Unexpected encoding for 48-bit instruction");
666 Encoding.truncate(6);
667 CB.append(Encoding);
668 break;
669 }
670 case 8: {
671 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
673 break;
674 }
675 }
676
677 ++MCNumEmitted; // Keep track of the # of mi's emitted.
678}
679
680uint64_t
681RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
682 SmallVectorImpl<MCFixup> &Fixups,
683 const MCSubtargetInfo &STI) const {
684
685 if (MO.isReg())
686 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
687
688 if (MO.isImm())
689 return MO.getImm();
690
691 llvm_unreachable("Unhandled expression!");
692 return 0;
693}
694
695uint64_t
696RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
697 SmallVectorImpl<MCFixup> &Fixups,
698 const MCSubtargetInfo &STI) const {
699 const MCOperand &MO = MI.getOperand(OpNo);
700
701 if (MO.isImm()) {
702 uint64_t Res = MO.getImm();
703 return (Res - 1);
704 }
705
706 llvm_unreachable("Unhandled expression!");
707 return 0;
708}
709
710uint64_t
711RISCVMCCodeEmitter::getImmOpValueSlist(const MCInst &MI, unsigned OpNo,
712 SmallVectorImpl<MCFixup> &Fixups,
713 const MCSubtargetInfo &STI) const {
714 const MCOperand &MO = MI.getOperand(OpNo);
715 assert(MO.isImm() && "Slist operand must be immediate");
716
717 uint64_t Res = MO.getImm();
718 switch (Res) {
719 case 0:
720 return 0;
721 case 1:
722 return 1;
723 case 2:
724 return 2;
725 case 4:
726 return 3;
727 case 8:
728 return 4;
729 case 16:
730 return 5;
731 case 15:
732 return 6;
733 case 31:
734 return 7;
735 default:
736 llvm_unreachable("Unhandled Slist value!");
737 }
738}
739
740template <unsigned N>
741unsigned
742RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
743 SmallVectorImpl<MCFixup> &Fixups,
744 const MCSubtargetInfo &STI) const {
745 const MCOperand &MO = MI.getOperand(OpNo);
746
747 if (MO.isImm()) {
748 uint64_t Res = MO.getImm();
749 assert((Res & ((1 << N) - 1)) == 0 && "LSB is non-zero");
750 return Res >> N;
751 }
752
753 return getImmOpValue(MI, OpNo, Fixups, STI);
754}
755
756uint64_t
757RISCVMCCodeEmitter::getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
758 SmallVectorImpl<MCFixup> &Fixups,
759 const MCSubtargetInfo &STI) const {
760 const MCOperand &MO = MI.getOperand(OpNo);
761 assert(MO.isImm() && "Zibi operand must be an immediate");
762 int64_t Res = MO.getImm();
763 if (Res == -1)
764 return 0;
765
766 return Res;
767}
768
769uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
770 SmallVectorImpl<MCFixup> &Fixups,
771 const MCSubtargetInfo &STI) const {
772 bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax);
773 const MCOperand &MO = MI.getOperand(OpNo);
774
775 MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
776 unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags);
777
778 // If the destination is an immediate, there is nothing to do.
779 if (MO.isImm())
780 return MO.getImm();
781
782 assert(MO.isExpr() &&
783 "getImmOpValue expects only expressions or immediates");
784 const MCExpr *Expr = MO.getExpr();
785 MCExpr::ExprKind Kind = Expr->getKind();
786
787 // `RelaxCandidate` must be set to `true` in two cases:
788 // - The fixup's relocation gets a R_RISCV_RELAX relocation
789 // - The underlying instruction may be relaxed to an instruction that gets a
790 // `R_RISCV_RELAX` relocation.
791 //
792 // The actual emission of `R_RISCV_RELAX` will be handled in
793 // `RISCVAsmBackend::applyFixup`.
794 bool RelaxCandidate = false;
795 auto AsmRelaxToLinkerRelaxable = [&]() -> void {
796 if (!STI.hasFeature(RISCV::FeatureExactAssembly))
797 RelaxCandidate = true;
798 };
799
801 if (Kind == MCExpr::Specifier) {
802 const auto *RVExpr = cast<MCSpecifierExpr>(Expr);
803 FixupKind = RVExpr->getSpecifier();
804 switch (RVExpr->getSpecifier()) {
805 default:
807 "invalid specifier");
808 break;
809 case ELF::R_RISCV_TPREL_ADD:
810 // tprel_add is only used to indicate that a relocation should be emitted
811 // for an add instruction used in TP-relative addressing. It should not be
812 // expanded as if representing an actual instruction operand and so to
813 // encounter it here is an error.
815 "ELF::R_RISCV_TPREL_ADD should not represent an instruction operand");
817 // The same logic for tprel_add applies to S_QC_ACCESS, for similar
818 // reasons, but we use a specifier becuase %qc.access() gets expanded
819 // differently depending on the underlying instruction.
821 "S_QC_ACCESS should not represent an instruction operand");
822 case RISCV::S_LO:
823 if (MIFrm == RISCVII::InstFormatI)
825 else if (MIFrm == RISCVII::InstFormatS)
827 else
828 llvm_unreachable("VK_LO used with unexpected instruction format");
829 RelaxCandidate = true;
830 break;
831 case ELF::R_RISCV_HI20:
833 RelaxCandidate = true;
834 break;
836 if (MIFrm == RISCVII::InstFormatI)
838 else if (MIFrm == RISCVII::InstFormatS)
840 else
841 llvm_unreachable("VK_PCREL_LO used with unexpected instruction format");
842 RelaxCandidate = true;
843 break;
846 RelaxCandidate = true;
847 break;
848 case RISCV::S_GOT_HI:
849 FixupKind = ELF::R_RISCV_GOT_HI20;
850 RelaxCandidate = true;
851 break;
853 if (MIFrm == RISCVII::InstFormatI)
854 FixupKind = ELF::R_RISCV_TPREL_LO12_I;
855 else if (MIFrm == RISCVII::InstFormatS)
856 FixupKind = ELF::R_RISCV_TPREL_LO12_S;
857 else
858 llvm_unreachable("VK_TPREL_LO used with unexpected instruction format");
859 RelaxCandidate = true;
860 break;
864 break;
865 }
867 RelaxCandidate = true;
868 break;
871 RelaxCandidate = true;
872 break;
873 case ELF::R_RISCV_GOT_HI20:
874 case ELF::R_RISCV_TPREL_HI20:
875 case ELF::R_RISCV_TLSDESC_HI20:
876 RelaxCandidate = true;
877 break;
878 }
879 } else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) {
880 // FIXME: Sub kind binary exprs have chance of underflow.
881 if (MIFrm == RISCVII::InstFormatJ) {
883 RelaxCandidate = true;
884 } else if (MIFrm == RISCVII::InstFormatB) {
886 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
887 AsmRelaxToLinkerRelaxable();
888 } else if (MIFrm == RISCVII::InstFormatCJ) {
890 // Relaxes to JAL with fixup_riscv_jal
891 AsmRelaxToLinkerRelaxable();
892 } else if (MIFrm == RISCVII::InstFormatCB) {
894 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
895 AsmRelaxToLinkerRelaxable();
896 } else if (MIFrm == RISCVII::InstFormatCI) {
898 // Relaxes to `QC.E.LI` with fixup_riscv_qc_e_32
899 if (STI.hasFeature(RISCV::FeatureVendorXqcili))
900 AsmRelaxToLinkerRelaxable();
901 } else if (MIFrm == RISCVII::InstFormatI) {
903 } else if (MIFrm == RISCVII::InstFormatQC_EB) {
905 // Relaxes to QC.E.B<cc>I; JAL, with fixup_riscv_jal
906 AsmRelaxToLinkerRelaxable();
907 } else if (MIFrm == RISCVII::InstFormatQC_EAI) {
909 RelaxCandidate = true;
910 } else if (MIFrm == RISCVII::InstFormatQC_EJ) {
912 RelaxCandidate = true;
913 } else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
915 }
916 }
917
918 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
919
920 addFixup(Fixups, 0, Expr, FixupKind);
921 // If linker relaxation is enabled and supported by this relocation, set a bit
922 // so that the assembler knows the size of the instruction is not fixed/known,
923 // and the relocation will need a R_RISCV_RELAX relocation.
924 if (EnableRelax && RelaxCandidate)
925 Fixups.back().setLinkerRelaxable();
926 ++MCNumFixups;
927
928 return 0;
929}
930
931unsigned
932RISCVMCCodeEmitter::getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo,
933 SmallVectorImpl<MCFixup> &Fixups,
934 const MCSubtargetInfo &STI) const {
935 unsigned Imm = getImmOpValue(MI, OpNo, Fixups, STI);
936 assert(RISCV::isValidYBNDSWImm(Imm) && "Should have been checked before");
937 // YBNDSWI decodes to the requested length result as follows:
938 // If imm[8:0] == 0, result is 4096.
939 if (Imm == 4096)
940 return 0;
941 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0] (1, 2, ..., 255).
942 if (Imm > 0 && Imm <= 255)
943 return Imm;
944 // If imm[8] == 1 and imm[7:5] == 0, result is
945 // `256 | (imm[3:0] << 4) | (imm[4] << 3)` (256, 264, ..., 504).
946 if (Imm >= 256 && Imm <= 504 && (Imm % 8) == 0) {
947 // Encode the multiples of 8 in this range in odd-even buckets, setting bit
948 // 4 of the immediate to 1 for odd multiples of 8.
949 unsigned MultipleOf8 = (Imm - 256) >> 3;
950 unsigned OddMultiple = MultipleOf8 & 1;
951 unsigned Bits3To0 = MultipleOf8 >> 1;
952 return 256 | (OddMultiple << 4) | Bits3To0;
953 }
954 // Otherwise, result is imm[7:0] << 4 (512, 528, ... 4080).
955 if (Imm >= 512 && Imm <= 4080 && (Imm % 16) == 0)
956 return 256 | (Imm >> 4);
957 llvm_unreachable("Invalid immediate for YBNDSWI");
958}
959
960unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
961 SmallVectorImpl<MCFixup> &Fixups,
962 const MCSubtargetInfo &STI) const {
963 MCOperand MO = MI.getOperand(OpNo);
964 assert(MO.isReg() && "Expected a register.");
965
966 switch (MO.getReg().id()) {
967 default:
968 llvm_unreachable("Invalid mask register.");
969 case RISCV::V0:
970 return 0;
971 case RISCV::NoRegister:
972 return 1;
973 }
974}
975
976unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
977 SmallVectorImpl<MCFixup> &Fixups,
978 const MCSubtargetInfo &STI) const {
979 const MCOperand &MO = MI.getOperand(OpNo);
980 assert(MO.isImm() && "Rlist operand must be immediate");
981 auto Imm = MO.getImm();
982 assert(Imm >= 4 && "EABI is currently not implemented");
983 return Imm;
984}
985unsigned
986RISCVMCCodeEmitter::getRlistS0OpValue(const MCInst &MI, unsigned OpNo,
987 SmallVectorImpl<MCFixup> &Fixups,
988 const MCSubtargetInfo &STI) const {
989 const MCOperand &MO = MI.getOperand(OpNo);
990 assert(MO.isImm() && "Rlist operand must be immediate");
991 auto Imm = MO.getImm();
992 assert(Imm >= 4 && "EABI is currently not implemented");
993 assert(Imm != RISCVZC::RA && "Rlist operand must include s0");
994 return Imm;
995}
996
997#include "RISCVGenMCCodeEmitter.inc"
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
IRTranslator LLVM IR MI
#define QC_ACCESS_CASE(_Suffix)
static unsigned getInvertedBranchOp(unsigned BrOp)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
Definition MCContext.h:83
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:411
const Triple & getTargetTriple() const
Definition MCContext.h:397
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
@ SymbolRef
References to labels and assigned expressions.
Definition MCExpr.h:43
@ Specifier
Expression with a relocation specifier.
Definition MCExpr.h:45
@ Binary
Binary expressions.
Definition MCExpr.h:41
ExprKind getKind() const
Definition MCExpr.h:85
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Definition MCFixup.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition MCInstrInfo.h:90
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
constexpr unsigned id() const
Definition MCRegister.h:82
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void truncate(size_type N)
Like resize, but requires that N is less than size().
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition Triple.h:786
LLVM Value Representation.
Definition Value.h:75
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned getFormat(uint64_t TSFlags)
static MCRegister getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
bool isValidYBNDSWImm(int64_t Imm)
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:96
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
MCCodeEmitter * createRISCVMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
Op::Description Desc
static Lanai::Fixups FixupKind(const MCExpr *Expr)
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
@ FirstTargetFixupKind
Definition MCFixup.h:44
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#define N