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 }
369}
370
371// Expand PseudoLongBxx to an inverted conditional branch and an unconditional
372// jump.
373void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
374 SmallVectorImpl<char> &CB,
375 SmallVectorImpl<MCFixup> &Fixups,
376 const MCSubtargetInfo &STI) const {
377 MCRegister SrcReg1 = MI.getOperand(0).getReg();
378 const MCOperand &Src2 = MI.getOperand(1);
379 const MCOperand &SrcSymbol = MI.getOperand(2);
380 unsigned Opcode = MI.getOpcode();
381 bool IsEqTest =
382 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
383
384 bool UseCompressedBr = false;
385 if (IsEqTest && STI.hasFeature(RISCV::FeatureStdExtZca)) {
386 MCRegister SrcReg2 = Src2.getReg();
387 if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 &&
388 SrcReg2.id() == RISCV::X0) {
389 UseCompressedBr = true;
390 } else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 &&
391 SrcReg1.id() == RISCV::X0) {
392 std::swap(SrcReg1, SrcReg2);
393 UseCompressedBr = true;
394 }
395 }
396
397 uint32_t Offset;
398 if (UseCompressedBr) {
399 unsigned InvOpc =
400 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
401 MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6);
402 uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
404 Offset = 2;
405 } else {
406 unsigned InvOpc = getInvertedBranchOp(Opcode);
407 MCInst TmpInst =
408 MCInstBuilder(InvOpc).addReg(SrcReg1).addOperand(Src2).addImm(8);
409 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
411 Offset = 4;
412 }
413
414 // Save the number fixups.
415 size_t FixupStartIndex = Fixups.size();
416
417 // Emit an unconditional jump to the destination.
418 MCInst TmpInst =
419 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
420 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
422
423 // Drop any fixup added so we can add the correct one.
424 Fixups.resize(FixupStartIndex);
425
426 if (SrcSymbol.isExpr()) {
427 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
428 if (STI.hasFeature(RISCV::FeatureRelax))
429 Fixups.back().setLinkerRelaxable();
430 }
431}
432
433// Expand PseudoLongQC_(E_)Bxxx to an inverted conditional branch and an
434// unconditional jump.
435void RISCVMCCodeEmitter::expandQCLongCondBrImm(const MCInst &MI,
436 SmallVectorImpl<char> &CB,
437 SmallVectorImpl<MCFixup> &Fixups,
438 const MCSubtargetInfo &STI,
439 unsigned Size) const {
440 MCRegister SrcReg1 = MI.getOperand(0).getReg();
441 auto BrImm = MI.getOperand(1).getImm();
442 MCOperand SrcSymbol = MI.getOperand(2);
443 unsigned Opcode = MI.getOpcode();
444 uint32_t Offset;
445 unsigned InvOpc = getInvertedBranchOp(Opcode);
446 // Emit inverted conditional branch with offset:
447 // 8 (QC.BXXX(4) + JAL(4))
448 // or
449 // 10 (QC.E.BXXX(6) + JAL(4)).
450 if (Size == 4) {
451 MCInst TmpBr =
452 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(8);
453 uint32_t BrBinary = getBinaryCodeForInstr(TmpBr, Fixups, STI);
455 } else {
456 MCInst TmpBr =
457 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(10);
458 uint64_t BrBinary =
459 getBinaryCodeForInstr(TmpBr, Fixups, STI) & 0xffff'ffff'ffffu;
460 SmallVector<char, 8> Encoding;
462 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
463 "Unexpected encoding for 48-bit instruction");
464 Encoding.truncate(6);
465 CB.append(Encoding);
466 }
467 Offset = Size;
468 // Save the number fixups.
469 size_t FixupStartIndex = Fixups.size();
470 // Emit an unconditional jump to the destination.
471 MCInst TmpJ =
472 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
473 uint32_t JBinary = getBinaryCodeForInstr(TmpJ, Fixups, STI);
475 // Drop any fixup added so we can add the correct one.
476 Fixups.resize(FixupStartIndex);
477 if (SrcSymbol.isExpr()) {
478 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
479 if (STI.hasFeature(RISCV::FeatureRelax))
480 Fixups.back().setLinkerRelaxable();
481 }
482}
483
484void RISCVMCCodeEmitter::expandPseudoQCAccess(
485 const MCInst &MI, SmallVectorImpl<char> &CB,
486 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
487 unsigned AccessOpc;
488
489 switch (MI.getOpcode()) {
490#define QC_ACCESS_CASE(_Suffix) \
491 case RISCV::PseudoQCAccess##_Suffix: \
492 AccessOpc = RISCV::_Suffix; \
493 break;
494 // clang-format off
496 QC_ACCESS_CASE(LBU)
498 QC_ACCESS_CASE(LHU)
503 QC_ACCESS_CASE(C_LBU)
504 QC_ACCESS_CASE(C_LH)
505 QC_ACCESS_CASE(C_LHU)
506 QC_ACCESS_CASE(C_LW)
507 QC_ACCESS_CASE(C_SB)
508 QC_ACCESS_CASE(C_SH)
509 QC_ACCESS_CASE(C_SW)
510 // clang-format on
511 default:
512 llvm_unreachable("Unhandled QC Access Opcode");
513 };
514
515 MCInst TmpAccess = MCInstBuilder(AccessOpc)
516 .addOperand(MI.getOperand(0))
517 .addOperand(MI.getOperand(1))
518 .addOperand(MI.getOperand(2));
519 unsigned Size = MCII.get(AccessOpc).getSize();
520 uint16_t FixupKind;
521 switch (Size) {
522 default:
523 llvm_unreachable("Unhandled QC Access Instruction Size");
524 case 2: {
525 uint16_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
528 break;
529 }
530 case 4: {
531 uint32_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
534 break;
535 }
536 }
537 // Only emit the qc.access fixup if linker relaxation is enabled. The pass has
538 // already checked for this before using the Pseudos, but the user may have
539 // written the instructions directly in assembly.
540 if (!STI.hasFeature(RISCV::FeatureRelax))
541 return;
542
543 const MCOperand &AccessSymbol = MI.getOperand(3);
544 assert(AccessSymbol.isExpr() && "Expected expression in PseudoQCAccess");
545
546 const auto *AccessExpr = cast<MCSpecifierExpr>(AccessSymbol.getExpr());
547 assert(AccessExpr->getSpecifier() == RISCV::S_QC_ACCESS &&
548 "Expected qc.access specifier on symbol");
549
550 addFixup(Fixups, /*Offset=*/0, AccessExpr, FixupKind);
551 // The added fixup is always linker relaxable.
552 Fixups.back().setLinkerRelaxable();
553}
554
555void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
556 SmallVectorImpl<char> &CB,
557 SmallVectorImpl<MCFixup> &Fixups,
558 const MCSubtargetInfo &STI) const {
559 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
560 // Get byte count of instruction.
561 unsigned Size = Desc.getSize();
562
563 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
564 // expanded instructions for each pseudo is correct in the Size field of the
565 // tablegen definition for the pseudo.
566 switch (MI.getOpcode()) {
567 default:
568 break;
569 case RISCV::PseudoCALLReg:
570 case RISCV::PseudoCALL:
571 case RISCV::PseudoTAIL:
572 case RISCV::PseudoJump:
573 expandFunctionCall(MI, CB, Fixups, STI);
574 MCNumEmitted += 2;
575 return;
576 case RISCV::PseudoCALLLpadAlign:
577 expandFunctionCallLpad(MI, CB, Fixups, STI);
578 MCNumEmitted += 3; // AUIPC + JALR + LPAD
579 return;
580 case RISCV::PseudoCALLIndirectLpadAlign:
581 expandFunctionCallLpad(MI, CB, Fixups, STI);
582 MCNumEmitted += 2; // JALR + LPAD
583 return;
584 case RISCV::PseudoAddTPRel:
585 expandAddTPRel(MI, CB, Fixups, STI);
586 MCNumEmitted += 1;
587 return;
588 case RISCV::PseudoLongBEQ:
589 case RISCV::PseudoLongBNE:
590 case RISCV::PseudoLongBEQI:
591 case RISCV::PseudoLongBNEI:
592 case RISCV::PseudoLongBLT:
593 case RISCV::PseudoLongBGE:
594 case RISCV::PseudoLongBLTU:
595 case RISCV::PseudoLongBGEU:
596 expandLongCondBr(MI, CB, Fixups, STI);
597 MCNumEmitted += 2;
598 return;
599 case RISCV::PseudoLongQC_BEQI:
600 case RISCV::PseudoLongQC_BNEI:
601 case RISCV::PseudoLongQC_BLTI:
602 case RISCV::PseudoLongQC_BGEI:
603 case RISCV::PseudoLongQC_BLTUI:
604 case RISCV::PseudoLongQC_BGEUI:
605 expandQCLongCondBrImm(MI, CB, Fixups, STI, 4);
606 MCNumEmitted += 2;
607 return;
608 case RISCV::PseudoLongQC_E_BEQI:
609 case RISCV::PseudoLongQC_E_BNEI:
610 case RISCV::PseudoLongQC_E_BLTI:
611 case RISCV::PseudoLongQC_E_BGEI:
612 case RISCV::PseudoLongQC_E_BLTUI:
613 case RISCV::PseudoLongQC_E_BGEUI:
614 expandQCLongCondBrImm(MI, CB, Fixups, STI, 6);
615 MCNumEmitted += 2;
616 return;
617 case RISCV::PseudoTLSDESCCall:
618 expandTLSDESCCall(MI, CB, Fixups, STI);
619 MCNumEmitted += 1;
620 return;
621 case RISCV::PseudoQCAccessLB:
622 case RISCV::PseudoQCAccessLBU:
623 case RISCV::PseudoQCAccessLH:
624 case RISCV::PseudoQCAccessLHU:
625 case RISCV::PseudoQCAccessLW:
626 case RISCV::PseudoQCAccessSB:
627 case RISCV::PseudoQCAccessSH:
628 case RISCV::PseudoQCAccessSW:
629 case RISCV::PseudoQCAccessC_LBU:
630 case RISCV::PseudoQCAccessC_LH:
631 case RISCV::PseudoQCAccessC_LHU:
632 case RISCV::PseudoQCAccessC_LW:
633 case RISCV::PseudoQCAccessC_SB:
634 case RISCV::PseudoQCAccessC_SH:
635 case RISCV::PseudoQCAccessC_SW:
636 expandPseudoQCAccess(MI, CB, Fixups, STI);
637 MCNumEmitted += 1;
638 return;
639 }
640
641 switch (Size) {
642 default:
643 llvm_unreachable("Unhandled encodeInstruction length!");
644 case 2: {
645 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
647 break;
648 }
649 case 4: {
650 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
652 break;
653 }
654 case 6: {
655 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI) & 0xffff'ffff'ffffu;
656 SmallVector<char, 8> Encoding;
658 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
659 "Unexpected encoding for 48-bit instruction");
660 Encoding.truncate(6);
661 CB.append(Encoding);
662 break;
663 }
664 case 8: {
665 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
667 break;
668 }
669 }
670
671 ++MCNumEmitted; // Keep track of the # of mi's emitted.
672}
673
674uint64_t
675RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
676 SmallVectorImpl<MCFixup> &Fixups,
677 const MCSubtargetInfo &STI) const {
678
679 if (MO.isReg())
680 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
681
682 if (MO.isImm())
683 return MO.getImm();
684
685 llvm_unreachable("Unhandled expression!");
686 return 0;
687}
688
689uint64_t
690RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
691 SmallVectorImpl<MCFixup> &Fixups,
692 const MCSubtargetInfo &STI) const {
693 const MCOperand &MO = MI.getOperand(OpNo);
694
695 if (MO.isImm()) {
696 uint64_t Res = MO.getImm();
697 return (Res - 1);
698 }
699
700 llvm_unreachable("Unhandled expression!");
701 return 0;
702}
703
704uint64_t
705RISCVMCCodeEmitter::getImmOpValueSlist(const MCInst &MI, unsigned OpNo,
706 SmallVectorImpl<MCFixup> &Fixups,
707 const MCSubtargetInfo &STI) const {
708 const MCOperand &MO = MI.getOperand(OpNo);
709 assert(MO.isImm() && "Slist operand must be immediate");
710
711 uint64_t Res = MO.getImm();
712 switch (Res) {
713 case 0:
714 return 0;
715 case 1:
716 return 1;
717 case 2:
718 return 2;
719 case 4:
720 return 3;
721 case 8:
722 return 4;
723 case 16:
724 return 5;
725 case 15:
726 return 6;
727 case 31:
728 return 7;
729 default:
730 llvm_unreachable("Unhandled Slist value!");
731 }
732}
733
734template <unsigned N>
735unsigned
736RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
737 SmallVectorImpl<MCFixup> &Fixups,
738 const MCSubtargetInfo &STI) const {
739 const MCOperand &MO = MI.getOperand(OpNo);
740
741 if (MO.isImm()) {
742 uint64_t Res = MO.getImm();
743 assert((Res & ((1 << N) - 1)) == 0 && "LSB is non-zero");
744 return Res >> N;
745 }
746
747 return getImmOpValue(MI, OpNo, Fixups, STI);
748}
749
750uint64_t
751RISCVMCCodeEmitter::getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
752 SmallVectorImpl<MCFixup> &Fixups,
753 const MCSubtargetInfo &STI) const {
754 const MCOperand &MO = MI.getOperand(OpNo);
755 assert(MO.isImm() && "Zibi operand must be an immediate");
756 int64_t Res = MO.getImm();
757 if (Res == -1)
758 return 0;
759
760 return Res;
761}
762
763uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
764 SmallVectorImpl<MCFixup> &Fixups,
765 const MCSubtargetInfo &STI) const {
766 bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax);
767 const MCOperand &MO = MI.getOperand(OpNo);
768
769 MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
770 unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags);
771
772 // If the destination is an immediate, there is nothing to do.
773 if (MO.isImm())
774 return MO.getImm();
775
776 assert(MO.isExpr() &&
777 "getImmOpValue expects only expressions or immediates");
778 const MCExpr *Expr = MO.getExpr();
779 MCExpr::ExprKind Kind = Expr->getKind();
780
781 // `RelaxCandidate` must be set to `true` in two cases:
782 // - The fixup's relocation gets a R_RISCV_RELAX relocation
783 // - The underlying instruction may be relaxed to an instruction that gets a
784 // `R_RISCV_RELAX` relocation.
785 //
786 // The actual emission of `R_RISCV_RELAX` will be handled in
787 // `RISCVAsmBackend::applyFixup`.
788 bool RelaxCandidate = false;
789 auto AsmRelaxToLinkerRelaxable = [&]() -> void {
790 if (!STI.hasFeature(RISCV::FeatureExactAssembly))
791 RelaxCandidate = true;
792 };
793
795 if (Kind == MCExpr::Specifier) {
796 const auto *RVExpr = cast<MCSpecifierExpr>(Expr);
797 FixupKind = RVExpr->getSpecifier();
798 switch (RVExpr->getSpecifier()) {
799 default:
801 "invalid specifier");
802 break;
803 case ELF::R_RISCV_TPREL_ADD:
804 // tprel_add is only used to indicate that a relocation should be emitted
805 // for an add instruction used in TP-relative addressing. It should not be
806 // expanded as if representing an actual instruction operand and so to
807 // encounter it here is an error.
809 "ELF::R_RISCV_TPREL_ADD should not represent an instruction operand");
811 // The same logic for tprel_add applies to S_QC_ACCESS, for similar
812 // reasons, but we use a specifier becuase %qc.access() gets expanded
813 // differently depending on the underlying instruction.
815 "S_QC_ACCESS should not represent an instruction operand");
816 case RISCV::S_LO:
817 if (MIFrm == RISCVII::InstFormatI)
819 else if (MIFrm == RISCVII::InstFormatS)
821 else
822 llvm_unreachable("VK_LO used with unexpected instruction format");
823 RelaxCandidate = true;
824 break;
825 case ELF::R_RISCV_HI20:
827 RelaxCandidate = true;
828 break;
830 if (MIFrm == RISCVII::InstFormatI)
832 else if (MIFrm == RISCVII::InstFormatS)
834 else
835 llvm_unreachable("VK_PCREL_LO used with unexpected instruction format");
836 RelaxCandidate = true;
837 break;
840 RelaxCandidate = true;
841 break;
842 case RISCV::S_GOT_HI:
843 FixupKind = ELF::R_RISCV_GOT_HI20;
844 RelaxCandidate = true;
845 break;
847 if (MIFrm == RISCVII::InstFormatI)
848 FixupKind = ELF::R_RISCV_TPREL_LO12_I;
849 else if (MIFrm == RISCVII::InstFormatS)
850 FixupKind = ELF::R_RISCV_TPREL_LO12_S;
851 else
852 llvm_unreachable("VK_TPREL_LO used with unexpected instruction format");
853 RelaxCandidate = true;
854 break;
858 break;
859 }
861 RelaxCandidate = true;
862 break;
865 RelaxCandidate = true;
866 break;
867 case ELF::R_RISCV_GOT_HI20:
868 case ELF::R_RISCV_TPREL_HI20:
869 case ELF::R_RISCV_TLSDESC_HI20:
870 RelaxCandidate = true;
871 break;
872 }
873 } else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) {
874 // FIXME: Sub kind binary exprs have chance of underflow.
875 if (MIFrm == RISCVII::InstFormatJ) {
877 RelaxCandidate = true;
878 } else if (MIFrm == RISCVII::InstFormatB) {
880 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
881 AsmRelaxToLinkerRelaxable();
882 } else if (MIFrm == RISCVII::InstFormatCJ) {
884 // Relaxes to JAL with fixup_riscv_jal
885 AsmRelaxToLinkerRelaxable();
886 } else if (MIFrm == RISCVII::InstFormatCB) {
888 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
889 AsmRelaxToLinkerRelaxable();
890 } else if (MIFrm == RISCVII::InstFormatCI) {
892 // Relaxes to `QC.E.LI` with fixup_riscv_qc_e_32
893 if (STI.hasFeature(RISCV::FeatureVendorXqcili))
894 AsmRelaxToLinkerRelaxable();
895 } else if (MIFrm == RISCVII::InstFormatI) {
897 } else if (MIFrm == RISCVII::InstFormatQC_EB) {
899 // Relaxes to QC.E.B<cc>I; JAL, with fixup_riscv_jal
900 AsmRelaxToLinkerRelaxable();
901 } else if (MIFrm == RISCVII::InstFormatQC_EAI) {
903 RelaxCandidate = true;
904 } else if (MIFrm == RISCVII::InstFormatQC_EJ) {
906 RelaxCandidate = true;
907 } else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
909 }
910 }
911
912 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
913
914 addFixup(Fixups, 0, Expr, FixupKind);
915 // If linker relaxation is enabled and supported by this relocation, set a bit
916 // so that the assembler knows the size of the instruction is not fixed/known,
917 // and the relocation will need a R_RISCV_RELAX relocation.
918 if (EnableRelax && RelaxCandidate)
919 Fixups.back().setLinkerRelaxable();
920 ++MCNumFixups;
921
922 return 0;
923}
924
925unsigned
926RISCVMCCodeEmitter::getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo,
927 SmallVectorImpl<MCFixup> &Fixups,
928 const MCSubtargetInfo &STI) const {
929 unsigned Imm = getImmOpValue(MI, OpNo, Fixups, STI);
930 assert(RISCV::isValidYBNDSWImm(Imm) && "Should have been checked before");
931 // YBNDSWI decodes to the requested length result as follows:
932 // If imm[8:0] == 0, result is 4096.
933 if (Imm == 4096)
934 return 0;
935 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0] (1, 2, ..., 255).
936 if (Imm > 0 && Imm <= 255)
937 return Imm;
938 // If imm[8] == 1 and imm[7:5] == 0, result is
939 // `256 | (imm[3:0] << 4) | (imm[4] << 3)` (256, 264, ..., 504).
940 if (Imm >= 256 && Imm <= 504 && (Imm % 8) == 0) {
941 // Encode the multiples of 8 in this range in odd-even buckets, setting bit
942 // 4 of the immediate to 1 for odd multiples of 8.
943 unsigned MultipleOf8 = (Imm - 256) >> 3;
944 unsigned OddMultiple = MultipleOf8 & 1;
945 unsigned Bits3To0 = MultipleOf8 >> 1;
946 return 256 | (OddMultiple << 4) | Bits3To0;
947 }
948 // Otherwise, result is imm[7:0] << 4 (512, 528, ... 4080).
949 if (Imm >= 512 && Imm <= 4080 && (Imm % 16) == 0)
950 return 256 | (Imm >> 4);
951 llvm_unreachable("Invalid immediate for YBNDSWI");
952}
953
954unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
955 SmallVectorImpl<MCFixup> &Fixups,
956 const MCSubtargetInfo &STI) const {
957 MCOperand MO = MI.getOperand(OpNo);
958 assert(MO.isReg() && "Expected a register.");
959
960 switch (MO.getReg().id()) {
961 default:
962 llvm_unreachable("Invalid mask register.");
963 case RISCV::V0:
964 return 0;
965 case RISCV::NoRegister:
966 return 1;
967 }
968}
969
970unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
971 SmallVectorImpl<MCFixup> &Fixups,
972 const MCSubtargetInfo &STI) const {
973 const MCOperand &MO = MI.getOperand(OpNo);
974 assert(MO.isImm() && "Rlist operand must be immediate");
975 auto Imm = MO.getImm();
976 assert(Imm >= 4 && "EABI is currently not implemented");
977 return Imm;
978}
979unsigned
980RISCVMCCodeEmitter::getRlistS0OpValue(const MCInst &MI, unsigned OpNo,
981 SmallVectorImpl<MCFixup> &Fixups,
982 const MCSubtargetInfo &STI) const {
983 const MCOperand &MO = MI.getOperand(OpNo);
984 assert(MO.isImm() && "Rlist operand must be immediate");
985 auto Imm = MO.getImm();
986 assert(Imm >= 4 && "EABI is currently not implemented");
987 assert(Imm != RISCVZC::RA && "Rlist operand must include s0");
988 return Imm;
989}
990
991#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:791
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:558
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:863
#define N