LLVM 24.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::PseudoTAILReg) {
180 Func = MI.getOperand(0);
181 Ra = MI.getOperand(1).getReg();
182 } else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
183 Func = MI.getOperand(1);
184 Ra = MI.getOperand(0).getReg();
185 } else if (MI.getOpcode() == RISCV::PseudoCALL) {
186 Func = MI.getOperand(0);
187 Ra = RISCV::X1;
188 } else if (MI.getOpcode() == RISCV::PseudoJump) {
189 Func = MI.getOperand(1);
190 Ra = MI.getOperand(0).getReg();
191 }
192 uint32_t Binary;
193
194 assert(Func.isExpr() && "Expected expression");
195
196 const MCExpr *CallExpr = Func.getExpr();
197
199 MCOperand FuncOp = MCOperand::createExpr(CallExpr);
200 if (MI.getOpcode() == RISCV::PseudoTAIL ||
201 MI.getOpcode() == RISCV::PseudoTAILReg ||
202 MI.getOpcode() == RISCV::PseudoJump)
203 // Emit JAL X0, Func
204 TmpInst = MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(FuncOp);
205 else
206 // Emit JAL Ra, Func
207 TmpInst = MCInstBuilder(RISCV::JAL).addReg(Ra).addOperand(FuncOp);
208 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
210 return;
211 }
212 // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
213 TmpInst = MCInstBuilder(RISCV::AUIPC).addReg(Ra).addExpr(CallExpr);
214 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
216
217 if (MI.getOpcode() == RISCV::PseudoTAIL ||
218 MI.getOpcode() == RISCV::PseudoTAILReg ||
219 MI.getOpcode() == RISCV::PseudoJump)
220 // Emit JALR X0, Ra, 0
221 TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
222 else
223 // Emit JALR Ra, Ra, 0
224 TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
225 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
227}
228
229// Expand to AUIPC+JALR+LPAD (direct) or JALR+LPAD (indirect).
230// R_RISCV_RELAX is not emitted for the call because linker relaxation could
231// convert it to c.jal/cm.jalt, which would misalign the following LPAD.
232void RISCVMCCodeEmitter::expandFunctionCallLpad(
233 const MCInst &MI, SmallVectorImpl<char> &CB,
234 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
235 bool IsIndirect = MI.getOpcode() == RISCV::PseudoCALLIndirectLpadAlign;
236 MCInst TmpInst;
237 uint32_t Binary;
238
239 if (!IsIndirect) {
240 const MCOperand &Func = MI.getOperand(0);
241 assert(Func.isExpr() && "Expected expression for call target");
242
243 // Use a STI without FeatureRelax so getImmOpValue does not mark the
244 // R_RISCV_CALL_PLT fixup as LinkerRelaxable (which would emit
245 // R_RISCV_RELAX).
246 MCSubtargetInfo NoRelaxSTI(STI);
247 if (STI.hasFeature(RISCV::FeatureRelax))
248 NoRelaxSTI.ToggleFeature(RISCV::FeatureRelax);
249
250 TmpInst =
251 MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X1).addExpr(Func.getExpr());
252 Binary = getBinaryCodeForInstr(TmpInst, Fixups, NoRelaxSTI);
254
255 TmpInst = MCInstBuilder(RISCV::JALR)
256 .addReg(RISCV::X1)
257 .addReg(RISCV::X1)
258 .addImm(0);
259 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
261 } else {
262 TmpInst = MCInstBuilder(RISCV::JALR)
263 .addReg(RISCV::X1)
264 .addReg(MI.getOperand(0).getReg())
265 .addImm(0);
266 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
268 }
269
270 // LPAD is encoded as AUIPC X0, label.
271 TmpInst = MCInstBuilder(RISCV::AUIPC)
272 .addReg(RISCV::X0)
273 .addImm(MI.getOperand(1).getImm());
274 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
276}
277
278void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI,
279 SmallVectorImpl<char> &CB,
280 SmallVectorImpl<MCFixup> &Fixups,
281 const MCSubtargetInfo &STI) const {
282 MCOperand SrcSymbol = MI.getOperand(3);
283 assert(SrcSymbol.isExpr() &&
284 "Expected expression as first input to TLSDESCCALL");
285 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr());
286 MCRegister Link = MI.getOperand(0).getReg();
287 MCRegister Dest = MI.getOperand(1).getReg();
288 int64_t Imm = MI.getOperand(2).getImm();
289 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TLSDESC_CALL);
290 MCInst Call =
291 MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm);
292
293 uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI);
295}
296
297// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
298void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
299 SmallVectorImpl<char> &CB,
300 SmallVectorImpl<MCFixup> &Fixups,
301 const MCSubtargetInfo &STI) const {
302 MCOperand DestReg = MI.getOperand(0);
303 MCOperand SrcReg = MI.getOperand(1);
304 MCOperand TPReg = MI.getOperand(2);
305 assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
306 "Expected thread pointer as second input to TP-relative add");
307
308 MCOperand SrcSymbol = MI.getOperand(3);
309 assert(SrcSymbol.isExpr() &&
310 "Expected expression as third input to TP-relative add");
311
312 const auto *Expr = dyn_cast<MCSpecifierExpr>(SrcSymbol.getExpr());
313 assert(Expr && Expr->getSpecifier() == ELF::R_RISCV_TPREL_ADD &&
314 "Expected tprel_add relocation on TP-relative symbol");
315
316 addFixup(Fixups, 0, Expr, ELF::R_RISCV_TPREL_ADD);
317 if (STI.hasFeature(RISCV::FeatureRelax))
318 Fixups.back().setLinkerRelaxable();
319
320 // Emit a normal ADD instruction with the given operands.
321 MCInst TmpInst = MCInstBuilder(RISCV::ADD)
322 .addOperand(DestReg)
323 .addOperand(SrcReg)
324 .addOperand(TPReg);
325 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
327}
328
329static unsigned getInvertedBranchOp(unsigned BrOp) {
330 switch (BrOp) {
331 default:
332 llvm_unreachable("Unexpected branch opcode!");
333 case RISCV::PseudoLongBEQ:
334 return RISCV::BNE;
335 case RISCV::PseudoLongBNE:
336 return RISCV::BEQ;
337 case RISCV::PseudoLongBEQI:
338 return RISCV::BNEI;
339 case RISCV::PseudoLongBNEI:
340 return RISCV::BEQI;
341 case RISCV::PseudoLongBLT:
342 return RISCV::BGE;
343 case RISCV::PseudoLongBGE:
344 return RISCV::BLT;
345 case RISCV::PseudoLongBLTU:
346 return RISCV::BGEU;
347 case RISCV::PseudoLongBGEU:
348 return RISCV::BLTU;
349 case RISCV::PseudoLongQC_BEQI:
350 return RISCV::QC_BNEI;
351 case RISCV::PseudoLongQC_BNEI:
352 return RISCV::QC_BEQI;
353 case RISCV::PseudoLongQC_BLTI:
354 return RISCV::QC_BGEI;
355 case RISCV::PseudoLongQC_BGEI:
356 return RISCV::QC_BLTI;
357 case RISCV::PseudoLongQC_BLTUI:
358 return RISCV::QC_BGEUI;
359 case RISCV::PseudoLongQC_BGEUI:
360 return RISCV::QC_BLTUI;
361 case RISCV::PseudoLongQC_E_BEQI:
362 return RISCV::QC_E_BNEI;
363 case RISCV::PseudoLongQC_E_BNEI:
364 return RISCV::QC_E_BEQI;
365 case RISCV::PseudoLongQC_E_BLTI:
366 return RISCV::QC_E_BGEI;
367 case RISCV::PseudoLongQC_E_BGEI:
368 return RISCV::QC_E_BLTI;
369 case RISCV::PseudoLongQC_E_BLTUI:
370 return RISCV::QC_E_BGEUI;
371 case RISCV::PseudoLongQC_E_BGEUI:
372 return RISCV::QC_E_BLTUI;
373 case RISCV::PseudoLongCV_BEQIMM:
374 return RISCV::CV_BNEIMM;
375 case RISCV::PseudoLongCV_BNEIMM:
376 return RISCV::CV_BEQIMM;
377 }
378}
379
380// Expand PseudoLongBxx to an inverted conditional branch and an unconditional
381// jump.
382void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
383 SmallVectorImpl<char> &CB,
384 SmallVectorImpl<MCFixup> &Fixups,
385 const MCSubtargetInfo &STI) const {
386 MCRegister SrcReg1 = MI.getOperand(0).getReg();
387 const MCOperand &Src2 = MI.getOperand(1);
388 const MCOperand &SrcSymbol = MI.getOperand(2);
389 unsigned Opcode = MI.getOpcode();
390 bool IsEqTest =
391 Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
392
393 bool UseCompressedBr = false;
394 if (IsEqTest && STI.hasFeature(RISCV::FeatureStdExtZca)) {
395 MCRegister SrcReg2 = Src2.getReg();
396 if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 &&
397 SrcReg2.id() == RISCV::X0) {
398 UseCompressedBr = true;
399 } else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 &&
400 SrcReg1.id() == RISCV::X0) {
401 std::swap(SrcReg1, SrcReg2);
402 UseCompressedBr = true;
403 }
404 }
405
406 uint32_t Offset;
407 if (UseCompressedBr) {
408 unsigned InvOpc =
409 Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
410 MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6);
411 uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
413 Offset = 2;
414 } else {
415 unsigned InvOpc = getInvertedBranchOp(Opcode);
416 MCInst TmpInst =
417 MCInstBuilder(InvOpc).addReg(SrcReg1).addOperand(Src2).addImm(8);
418 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
420 Offset = 4;
421 }
422
423 // Save the number fixups.
424 size_t FixupStartIndex = Fixups.size();
425
426 // Emit an unconditional jump to the destination.
427 MCInst TmpInst =
428 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
429 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
431
432 // Drop any fixup added so we can add the correct one.
433 Fixups.resize(FixupStartIndex);
434
435 if (SrcSymbol.isExpr()) {
436 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
437 if (STI.hasFeature(RISCV::FeatureRelax))
438 Fixups.back().setLinkerRelaxable();
439 }
440}
441
442// Expand PseudoLongQC_(E_)Bxxx to an inverted conditional branch and an
443// unconditional jump.
444void RISCVMCCodeEmitter::expandQCLongCondBrImm(const MCInst &MI,
445 SmallVectorImpl<char> &CB,
446 SmallVectorImpl<MCFixup> &Fixups,
447 const MCSubtargetInfo &STI,
448 unsigned Size) const {
449 MCRegister SrcReg1 = MI.getOperand(0).getReg();
450 auto BrImm = MI.getOperand(1).getImm();
451 MCOperand SrcSymbol = MI.getOperand(2);
452 unsigned Opcode = MI.getOpcode();
453 uint32_t Offset;
454 unsigned InvOpc = getInvertedBranchOp(Opcode);
455 // Emit inverted conditional branch with offset:
456 // 8 (QC.BXXX(4) + JAL(4))
457 // or
458 // 10 (QC.E.BXXX(6) + JAL(4)).
459 if (Size == 4) {
460 MCInst TmpBr =
461 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(8);
462 uint32_t BrBinary = getBinaryCodeForInstr(TmpBr, Fixups, STI);
464 } else {
465 MCInst TmpBr =
466 MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(BrImm).addImm(10);
467 uint64_t BrBinary =
468 getBinaryCodeForInstr(TmpBr, Fixups, STI) & 0xffff'ffff'ffffu;
469 SmallVector<char, 8> Encoding;
471 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
472 "Unexpected encoding for 48-bit instruction");
473 Encoding.truncate(6);
474 CB.append(Encoding);
475 }
476 Offset = Size;
477 // Save the number fixups.
478 size_t FixupStartIndex = Fixups.size();
479 // Emit an unconditional jump to the destination.
480 MCInst TmpJ =
481 MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
482 uint32_t JBinary = getBinaryCodeForInstr(TmpJ, Fixups, STI);
484 // Drop any fixup added so we can add the correct one.
485 Fixups.resize(FixupStartIndex);
486 if (SrcSymbol.isExpr()) {
487 addFixup(Fixups, Offset, SrcSymbol.getExpr(), RISCV::fixup_riscv_jal);
488 if (STI.hasFeature(RISCV::FeatureRelax))
489 Fixups.back().setLinkerRelaxable();
490 }
491}
492
493void RISCVMCCodeEmitter::expandPseudoQCAccess(
494 const MCInst &MI, SmallVectorImpl<char> &CB,
495 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
496 unsigned AccessOpc;
497
498 switch (MI.getOpcode()) {
499#define QC_ACCESS_CASE(_Suffix) \
500 case RISCV::PseudoQCAccess##_Suffix: \
501 AccessOpc = RISCV::_Suffix; \
502 break;
503 // clang-format off
505 QC_ACCESS_CASE(LBU)
507 QC_ACCESS_CASE(LHU)
512 QC_ACCESS_CASE(C_LBU)
513 QC_ACCESS_CASE(C_LH)
514 QC_ACCESS_CASE(C_LHU)
515 QC_ACCESS_CASE(C_LW)
516 QC_ACCESS_CASE(C_SB)
517 QC_ACCESS_CASE(C_SH)
518 QC_ACCESS_CASE(C_SW)
519 // clang-format on
520 default:
521 llvm_unreachable("Unhandled QC Access Opcode");
522 };
523
524 MCInst TmpAccess = MCInstBuilder(AccessOpc)
525 .addOperand(MI.getOperand(0))
526 .addOperand(MI.getOperand(1))
527 .addOperand(MI.getOperand(2));
528 unsigned Size = MCII.get(AccessOpc).getSize();
529 uint16_t FixupKind;
530 switch (Size) {
531 default:
532 llvm_unreachable("Unhandled QC Access Instruction Size");
533 case 2: {
534 uint16_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
537 break;
538 }
539 case 4: {
540 uint32_t AccessBinary = getBinaryCodeForInstr(TmpAccess, Fixups, STI);
543 break;
544 }
545 }
546 // Only emit the qc.access fixup if linker relaxation is enabled. The pass has
547 // already checked for this before using the Pseudos, but the user may have
548 // written the instructions directly in assembly.
549 if (!STI.hasFeature(RISCV::FeatureRelax))
550 return;
551
552 const MCOperand &AccessSymbol = MI.getOperand(3);
553 assert(AccessSymbol.isExpr() && "Expected expression in PseudoQCAccess");
554
555 const auto *AccessExpr = cast<MCSpecifierExpr>(AccessSymbol.getExpr());
556 assert(AccessExpr->getSpecifier() == RISCV::S_QC_ACCESS &&
557 "Expected qc.access specifier on symbol");
558
559 addFixup(Fixups, /*Offset=*/0, AccessExpr, FixupKind);
560 // The added fixup is always linker relaxable.
561 Fixups.back().setLinkerRelaxable();
562}
563
564void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
565 SmallVectorImpl<char> &CB,
566 SmallVectorImpl<MCFixup> &Fixups,
567 const MCSubtargetInfo &STI) const {
568 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
569 // Get byte count of instruction.
570 unsigned Size = Desc.getSize();
571
572 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
573 // expanded instructions for each pseudo is correct in the Size field of the
574 // tablegen definition for the pseudo.
575 switch (MI.getOpcode()) {
576 default:
577 break;
578 case RISCV::PseudoCALLReg:
579 case RISCV::PseudoCALL:
580 case RISCV::PseudoTAIL:
581 case RISCV::PseudoTAILReg:
582 case RISCV::PseudoJump:
583 expandFunctionCall(MI, CB, Fixups, STI);
584 MCNumEmitted += 2;
585 return;
586 case RISCV::PseudoCALLLpadAlign:
587 expandFunctionCallLpad(MI, CB, Fixups, STI);
588 MCNumEmitted += 3; // AUIPC + JALR + LPAD
589 return;
590 case RISCV::PseudoCALLIndirectLpadAlign:
591 expandFunctionCallLpad(MI, CB, Fixups, STI);
592 MCNumEmitted += 2; // JALR + LPAD
593 return;
594 case RISCV::PseudoAddTPRel:
595 expandAddTPRel(MI, CB, Fixups, STI);
596 MCNumEmitted += 1;
597 return;
598 case RISCV::PseudoLongBEQ:
599 case RISCV::PseudoLongBNE:
600 case RISCV::PseudoLongBEQI:
601 case RISCV::PseudoLongBNEI:
602 case RISCV::PseudoLongBLT:
603 case RISCV::PseudoLongBGE:
604 case RISCV::PseudoLongBLTU:
605 case RISCV::PseudoLongBGEU:
606 expandLongCondBr(MI, CB, Fixups, STI);
607 MCNumEmitted += 2;
608 return;
609 case RISCV::PseudoLongQC_BEQI:
610 case RISCV::PseudoLongQC_BNEI:
611 case RISCV::PseudoLongQC_BLTI:
612 case RISCV::PseudoLongQC_BGEI:
613 case RISCV::PseudoLongQC_BLTUI:
614 case RISCV::PseudoLongQC_BGEUI:
615 case RISCV::PseudoLongCV_BEQIMM:
616 case RISCV::PseudoLongCV_BNEIMM:
617 expandQCLongCondBrImm(MI, CB, Fixups, STI, 4);
618 MCNumEmitted += 2;
619 return;
620 case RISCV::PseudoLongQC_E_BEQI:
621 case RISCV::PseudoLongQC_E_BNEI:
622 case RISCV::PseudoLongQC_E_BLTI:
623 case RISCV::PseudoLongQC_E_BGEI:
624 case RISCV::PseudoLongQC_E_BLTUI:
625 case RISCV::PseudoLongQC_E_BGEUI:
626 expandQCLongCondBrImm(MI, CB, Fixups, STI, 6);
627 MCNumEmitted += 2;
628 return;
629 case RISCV::PseudoTLSDESCCall:
630 expandTLSDESCCall(MI, CB, Fixups, STI);
631 MCNumEmitted += 1;
632 return;
633 case RISCV::PseudoQCAccessLB:
634 case RISCV::PseudoQCAccessLBU:
635 case RISCV::PseudoQCAccessLH:
636 case RISCV::PseudoQCAccessLHU:
637 case RISCV::PseudoQCAccessLW:
638 case RISCV::PseudoQCAccessSB:
639 case RISCV::PseudoQCAccessSH:
640 case RISCV::PseudoQCAccessSW:
641 case RISCV::PseudoQCAccessC_LBU:
642 case RISCV::PseudoQCAccessC_LH:
643 case RISCV::PseudoQCAccessC_LHU:
644 case RISCV::PseudoQCAccessC_LW:
645 case RISCV::PseudoQCAccessC_SB:
646 case RISCV::PseudoQCAccessC_SH:
647 case RISCV::PseudoQCAccessC_SW:
648 expandPseudoQCAccess(MI, CB, Fixups, STI);
649 MCNumEmitted += 1;
650 return;
651 }
652
653 switch (Size) {
654 default:
655 llvm_unreachable("Unhandled encodeInstruction length!");
656 case 2: {
657 uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
659 break;
660 }
661 case 4: {
662 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
664 break;
665 }
666 case 6: {
667 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI) & 0xffff'ffff'ffffu;
668 SmallVector<char, 8> Encoding;
670 assert(Encoding[6] == 0 && Encoding[7] == 0 &&
671 "Unexpected encoding for 48-bit instruction");
672 Encoding.truncate(6);
673 CB.append(Encoding);
674 break;
675 }
676 case 8: {
677 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
679 break;
680 }
681 }
682
683 ++MCNumEmitted; // Keep track of the # of mi's emitted.
684}
685
687RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
688 SmallVectorImpl<MCFixup> &Fixups,
689 const MCSubtargetInfo &STI) const {
690
691 if (MO.isReg())
692 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
693
694 if (MO.isImm())
695 return MO.getImm();
696
697 llvm_unreachable("Unhandled expression!");
698 return 0;
699}
700
702RISCVMCCodeEmitter::getImmOpValueMinus1(const MCInst &MI, unsigned OpNo,
703 SmallVectorImpl<MCFixup> &Fixups,
704 const MCSubtargetInfo &STI) const {
705 const MCOperand &MO = MI.getOperand(OpNo);
706
707 if (MO.isImm()) {
708 uint64_t Res = MO.getImm();
709 return (Res - 1);
710 }
711
712 llvm_unreachable("Unhandled expression!");
713 return 0;
714}
715
717RISCVMCCodeEmitter::getImmOpValueSlist(const MCInst &MI, unsigned OpNo,
718 SmallVectorImpl<MCFixup> &Fixups,
719 const MCSubtargetInfo &STI) const {
720 const MCOperand &MO = MI.getOperand(OpNo);
721 assert(MO.isImm() && "Slist operand must be immediate");
722
723 uint64_t Res = MO.getImm();
724 switch (Res) {
725 case 0:
726 return 0;
727 case 1:
728 return 1;
729 case 2:
730 return 2;
731 case 4:
732 return 3;
733 case 8:
734 return 4;
735 case 16:
736 return 5;
737 case 15:
738 return 6;
739 case 31:
740 return 7;
741 default:
742 llvm_unreachable("Unhandled Slist value!");
743 }
744}
745
746template <unsigned N>
747unsigned
748RISCVMCCodeEmitter::getImmOpValueAsrN(const MCInst &MI, unsigned OpNo,
749 SmallVectorImpl<MCFixup> &Fixups,
750 const MCSubtargetInfo &STI) const {
751 const MCOperand &MO = MI.getOperand(OpNo);
752
753 if (MO.isImm()) {
754 uint64_t Res = MO.getImm();
755 assert((Res & ((1 << N) - 1)) == 0 && "LSB is non-zero");
756 return Res >> N;
757 }
758
759 return getImmOpValue(MI, OpNo, Fixups, STI);
760}
761
763RISCVMCCodeEmitter::getImmOpValueZibi(const MCInst &MI, unsigned OpNo,
764 SmallVectorImpl<MCFixup> &Fixups,
765 const MCSubtargetInfo &STI) const {
766 const MCOperand &MO = MI.getOperand(OpNo);
767 assert(MO.isImm() && "Zibi operand must be an immediate");
768 int64_t Res = MO.getImm();
769 if (Res == -1)
770 return 0;
771
772 return Res;
773}
774
775uint64_t RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
776 SmallVectorImpl<MCFixup> &Fixups,
777 const MCSubtargetInfo &STI) const {
778 bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax);
779 const MCOperand &MO = MI.getOperand(OpNo);
780
781 MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
782 unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags);
783
784 // If the destination is an immediate, there is nothing to do.
785 if (MO.isImm())
786 return MO.getImm();
787
788 assert(MO.isExpr() &&
789 "getImmOpValue expects only expressions or immediates");
790 const MCExpr *Expr = MO.getExpr();
791 MCExpr::ExprKind Kind = Expr->getKind();
792
793 // `RelaxCandidate` must be set to `true` in two cases:
794 // - The fixup's relocation gets a R_RISCV_RELAX relocation
795 // - The underlying instruction may be relaxed to an instruction that gets a
796 // `R_RISCV_RELAX` relocation.
797 //
798 // The actual emission of `R_RISCV_RELAX` will be handled in
799 // `RISCVAsmBackend::applyFixup`.
800 bool RelaxCandidate = false;
801 auto AsmRelaxToLinkerRelaxable = [&]() -> void {
802 if (!STI.hasFeature(RISCV::FeatureExactAssembly))
803 RelaxCandidate = true;
804 };
805
807 if (Kind == MCExpr::Specifier) {
808 const auto *RVExpr = cast<MCSpecifierExpr>(Expr);
809 FixupKind = RVExpr->getSpecifier();
810 switch (RVExpr->getSpecifier()) {
811 default:
813 "invalid specifier");
814 break;
815 case ELF::R_RISCV_TPREL_ADD:
816 // tprel_add is only used to indicate that a relocation should be emitted
817 // for an add instruction used in TP-relative addressing. It should not be
818 // expanded as if representing an actual instruction operand and so to
819 // encounter it here is an error.
821 "ELF::R_RISCV_TPREL_ADD should not represent an instruction operand");
823 // The same logic for tprel_add applies to S_QC_ACCESS, for similar
824 // reasons, but we use a specifier becuase %qc.access() gets expanded
825 // differently depending on the underlying instruction.
827 "S_QC_ACCESS should not represent an instruction operand");
828 case RISCV::S_LO:
829 if (MIFrm == RISCVII::InstFormatI)
831 else if (MIFrm == RISCVII::InstFormatS)
833 else
834 llvm_unreachable("VK_LO used with unexpected instruction format");
835 RelaxCandidate = true;
836 break;
837 case ELF::R_RISCV_HI20:
839 RelaxCandidate = true;
840 break;
842 if (MIFrm == RISCVII::InstFormatI)
844 else if (MIFrm == RISCVII::InstFormatS)
846 else
847 llvm_unreachable("VK_PCREL_LO used with unexpected instruction format");
848 RelaxCandidate = true;
849 break;
852 RelaxCandidate = true;
853 break;
854 case RISCV::S_GOT_HI:
855 FixupKind = ELF::R_RISCV_GOT_HI20;
856 RelaxCandidate = true;
857 break;
859 if (MIFrm == RISCVII::InstFormatI)
860 FixupKind = ELF::R_RISCV_TPREL_LO12_I;
861 else if (MIFrm == RISCVII::InstFormatS)
862 FixupKind = ELF::R_RISCV_TPREL_LO12_S;
863 else
864 llvm_unreachable("VK_TPREL_LO used with unexpected instruction format");
865 RelaxCandidate = true;
866 break;
870 break;
871 }
873 RelaxCandidate = true;
874 break;
877 RelaxCandidate = true;
878 break;
879 case ELF::R_RISCV_GOT_HI20:
880 case ELF::R_RISCV_TPREL_HI20:
881 case ELF::R_RISCV_TLSDESC_HI20:
882 RelaxCandidate = true;
883 break;
884 }
885 } else if (Kind == MCExpr::SymbolRef || Kind == MCExpr::Binary) {
886 // FIXME: Sub kind binary exprs have chance of underflow.
887 if (MIFrm == RISCVII::InstFormatJ) {
889 RelaxCandidate = true;
890 } else if (MIFrm == RISCVII::InstFormatB) {
892 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
893 AsmRelaxToLinkerRelaxable();
894 } else if (MIFrm == RISCVII::InstFormatCJ) {
896 // Relaxes to JAL with fixup_riscv_jal
897 AsmRelaxToLinkerRelaxable();
898 } else if (MIFrm == RISCVII::InstFormatCB) {
900 // Relaxes to B<cc>; JAL, with fixup_riscv_jal
901 AsmRelaxToLinkerRelaxable();
902 } else if (MIFrm == RISCVII::InstFormatCI) {
904 // Relaxes to `QC.E.LI` with fixup_riscv_qc_e_32
905 if (STI.hasFeature(RISCV::FeatureVendorXqcili))
906 AsmRelaxToLinkerRelaxable();
907 } else if (MIFrm == RISCVII::InstFormatI) {
909 } else if (MIFrm == RISCVII::InstFormatQC_EB) {
911 // Relaxes to QC.E.B<cc>I; JAL, with fixup_riscv_jal
912 AsmRelaxToLinkerRelaxable();
913 } else if (MIFrm == RISCVII::InstFormatQC_EAI) {
915 RelaxCandidate = true;
916 } else if (MIFrm == RISCVII::InstFormatQC_EJ) {
918 RelaxCandidate = true;
919 } else if (MIFrm == RISCVII::InstFormatNDS_BRANCH_10) {
921 }
922 }
923
924 assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
925
926 addFixup(Fixups, 0, Expr, FixupKind);
927 // If linker relaxation is enabled and supported by this relocation, set a bit
928 // so that the assembler knows the size of the instruction is not fixed/known,
929 // and the relocation will need a R_RISCV_RELAX relocation.
930 if (EnableRelax && RelaxCandidate)
931 Fixups.back().setLinkerRelaxable();
932 ++MCNumFixups;
933
934 return 0;
935}
936
937unsigned
938RISCVMCCodeEmitter::getYBNDSWImmOpValue(const MCInst &MI, unsigned OpNo,
939 SmallVectorImpl<MCFixup> &Fixups,
940 const MCSubtargetInfo &STI) const {
941 unsigned Imm = getImmOpValue(MI, OpNo, Fixups, STI);
942 assert(RISCV::isValidYBNDSWImm(Imm) && "Should have been checked before");
943 // YBNDSWI decodes to the requested length result as follows:
944 // If imm[8:0] == 0, result is 4096.
945 if (Imm == 4096)
946 return 0;
947 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0] (1, 2, ..., 255).
948 if (Imm > 0 && Imm <= 255)
949 return Imm;
950 // If imm[8] == 1 and imm[7:5] == 0, result is
951 // `256 | (imm[3:0] << 4) | (imm[4] << 3)` (256, 264, ..., 504).
952 if (Imm >= 256 && Imm <= 504 && (Imm % 8) == 0) {
953 // Encode the multiples of 8 in this range in odd-even buckets, setting bit
954 // 4 of the immediate to 1 for odd multiples of 8.
955 unsigned MultipleOf8 = (Imm - 256) >> 3;
956 unsigned OddMultiple = MultipleOf8 & 1;
957 unsigned Bits3To0 = MultipleOf8 >> 1;
958 return 256 | (OddMultiple << 4) | Bits3To0;
959 }
960 // Otherwise, result is imm[7:0] << 4 (512, 528, ... 4080).
961 if (Imm >= 512 && Imm <= 4080 && (Imm % 16) == 0)
962 return 256 | (Imm >> 4);
963 llvm_unreachable("Invalid immediate for YBNDSWI");
964}
965
966unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
967 SmallVectorImpl<MCFixup> &Fixups,
968 const MCSubtargetInfo &STI) const {
969 MCOperand MO = MI.getOperand(OpNo);
970 assert(MO.isReg() && "Expected a register.");
971
972 switch (MO.getReg().id()) {
973 default:
974 llvm_unreachable("Invalid mask register.");
975 case RISCV::V0:
976 return 0;
977 case RISCV::NoRegister:
978 return 1;
979 }
980}
981
982unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
983 SmallVectorImpl<MCFixup> &Fixups,
984 const MCSubtargetInfo &STI) const {
985 const MCOperand &MO = MI.getOperand(OpNo);
986 assert(MO.isImm() && "Rlist operand must be immediate");
987 auto Imm = MO.getImm();
988 assert(Imm >= 4 && "EABI is currently not implemented");
989 return Imm;
990}
991unsigned
992RISCVMCCodeEmitter::getRlistS0OpValue(const MCInst &MI, unsigned OpNo,
993 SmallVectorImpl<MCFixup> &Fixups,
994 const MCSubtargetInfo &STI) const {
995 const MCOperand &MO = MI.getOperand(OpNo);
996 assert(MO.isImm() && "Rlist operand must be immediate");
997 auto Imm = MO.getImm();
998 assert(Imm >= 4 && "EABI is currently not implemented");
999 assert(Imm != RISCVZC::RA && "Rlist operand must include s0");
1000 return Imm;
1001}
1002
1003#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!")
unsigned Imm
unsigned uint64_t
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:89
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:875
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:82
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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:880
#define N