Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
35294 views
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
13
#include "MCTargetDesc/RISCVBaseInfo.h"
14
#include "MCTargetDesc/RISCVFixupKinds.h"
15
#include "MCTargetDesc/RISCVMCExpr.h"
16
#include "MCTargetDesc/RISCVMCTargetDesc.h"
17
#include "llvm/ADT/Statistic.h"
18
#include "llvm/MC/MCAsmInfo.h"
19
#include "llvm/MC/MCCodeEmitter.h"
20
#include "llvm/MC/MCContext.h"
21
#include "llvm/MC/MCExpr.h"
22
#include "llvm/MC/MCInst.h"
23
#include "llvm/MC/MCInstBuilder.h"
24
#include "llvm/MC/MCInstrInfo.h"
25
#include "llvm/MC/MCRegisterInfo.h"
26
#include "llvm/MC/MCSubtargetInfo.h"
27
#include "llvm/MC/MCSymbol.h"
28
#include "llvm/Support/Casting.h"
29
#include "llvm/Support/EndianStream.h"
30
#include "llvm/Support/raw_ostream.h"
31
32
using namespace llvm;
33
34
#define DEBUG_TYPE "mccodeemitter"
35
36
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
37
STATISTIC(MCNumFixups, "Number of MC fixups created");
38
39
namespace {
40
class RISCVMCCodeEmitter : public MCCodeEmitter {
41
RISCVMCCodeEmitter(const RISCVMCCodeEmitter &) = delete;
42
void operator=(const RISCVMCCodeEmitter &) = delete;
43
MCContext &Ctx;
44
MCInstrInfo const &MCII;
45
46
public:
47
RISCVMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
48
: Ctx(ctx), MCII(MCII) {}
49
50
~RISCVMCCodeEmitter() override = default;
51
52
void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
53
SmallVectorImpl<MCFixup> &Fixups,
54
const MCSubtargetInfo &STI) const override;
55
56
void expandFunctionCall(const MCInst &MI, SmallVectorImpl<char> &CB,
57
SmallVectorImpl<MCFixup> &Fixups,
58
const MCSubtargetInfo &STI) const;
59
60
void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB,
61
SmallVectorImpl<MCFixup> &Fixups,
62
const MCSubtargetInfo &STI) const;
63
64
void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB,
65
SmallVectorImpl<MCFixup> &Fixups,
66
const MCSubtargetInfo &STI) const;
67
68
void expandLongCondBr(const MCInst &MI, SmallVectorImpl<char> &CB,
69
SmallVectorImpl<MCFixup> &Fixups,
70
const MCSubtargetInfo &STI) const;
71
72
/// TableGen'erated function for getting the binary encoding for an
73
/// instruction.
74
uint64_t getBinaryCodeForInstr(const MCInst &MI,
75
SmallVectorImpl<MCFixup> &Fixups,
76
const MCSubtargetInfo &STI) const;
77
78
/// Return binary encoding of operand. If the machine operand requires
79
/// relocation, record the relocation and return zero.
80
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
81
SmallVectorImpl<MCFixup> &Fixups,
82
const MCSubtargetInfo &STI) const;
83
84
unsigned getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
85
SmallVectorImpl<MCFixup> &Fixups,
86
const MCSubtargetInfo &STI) const;
87
88
unsigned getImmOpValue(const MCInst &MI, unsigned OpNo,
89
SmallVectorImpl<MCFixup> &Fixups,
90
const MCSubtargetInfo &STI) const;
91
92
unsigned getVMaskReg(const MCInst &MI, unsigned OpNo,
93
SmallVectorImpl<MCFixup> &Fixups,
94
const MCSubtargetInfo &STI) const;
95
96
unsigned getRlistOpValue(const MCInst &MI, unsigned OpNo,
97
SmallVectorImpl<MCFixup> &Fixups,
98
const MCSubtargetInfo &STI) const;
99
100
unsigned getRegReg(const MCInst &MI, unsigned OpNo,
101
SmallVectorImpl<MCFixup> &Fixups,
102
const MCSubtargetInfo &STI) const;
103
};
104
} // end anonymous namespace
105
106
MCCodeEmitter *llvm::createRISCVMCCodeEmitter(const MCInstrInfo &MCII,
107
MCContext &Ctx) {
108
return new RISCVMCCodeEmitter(Ctx, MCII);
109
}
110
111
// Expand PseudoCALL(Reg), PseudoTAIL and PseudoJump to AUIPC and JALR with
112
// relocation types. We expand those pseudo-instructions while encoding them,
113
// meaning AUIPC and JALR won't go through RISC-V MC to MC compressed
114
// instruction transformation. This is acceptable because AUIPC has no 16-bit
115
// form and C_JALR has no immediate operand field. We let linker relaxation
116
// deal with it. When linker relaxation is enabled, AUIPC and JALR have a
117
// chance to relax to JAL.
118
// If the C extension is enabled, JAL has a chance relax to C_JAL.
119
void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI,
120
SmallVectorImpl<char> &CB,
121
SmallVectorImpl<MCFixup> &Fixups,
122
const MCSubtargetInfo &STI) const {
123
MCInst TmpInst;
124
MCOperand Func;
125
MCRegister Ra;
126
if (MI.getOpcode() == RISCV::PseudoTAIL) {
127
Func = MI.getOperand(0);
128
Ra = RISCV::X6;
129
// For Zicfilp, PseudoTAIL should be expanded to a software guarded branch.
130
// It means to use t2(x7) as rs1 of JALR to expand PseudoTAIL.
131
if (STI.hasFeature(RISCV::FeatureStdExtZicfilp))
132
Ra = RISCV::X7;
133
} else if (MI.getOpcode() == RISCV::PseudoCALLReg) {
134
Func = MI.getOperand(1);
135
Ra = MI.getOperand(0).getReg();
136
} else if (MI.getOpcode() == RISCV::PseudoCALL) {
137
Func = MI.getOperand(0);
138
Ra = RISCV::X1;
139
} else if (MI.getOpcode() == RISCV::PseudoJump) {
140
Func = MI.getOperand(1);
141
Ra = MI.getOperand(0).getReg();
142
}
143
uint32_t Binary;
144
145
assert(Func.isExpr() && "Expected expression");
146
147
const MCExpr *CallExpr = Func.getExpr();
148
149
// Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
150
TmpInst = MCInstBuilder(RISCV::AUIPC).addReg(Ra).addExpr(CallExpr);
151
Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
152
support::endian::write(CB, Binary, llvm::endianness::little);
153
154
if (MI.getOpcode() == RISCV::PseudoTAIL ||
155
MI.getOpcode() == RISCV::PseudoJump)
156
// Emit JALR X0, Ra, 0
157
TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
158
else
159
// Emit JALR Ra, Ra, 0
160
TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
161
Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
162
support::endian::write(CB, Binary, llvm::endianness::little);
163
}
164
165
void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI,
166
SmallVectorImpl<char> &CB,
167
SmallVectorImpl<MCFixup> &Fixups,
168
const MCSubtargetInfo &STI) const {
169
MCOperand SrcSymbol = MI.getOperand(3);
170
assert(SrcSymbol.isExpr() &&
171
"Expected expression as first input to TLSDESCCALL");
172
const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
173
MCRegister Link = MI.getOperand(0).getReg();
174
MCRegister Dest = MI.getOperand(1).getReg();
175
MCRegister Imm = MI.getOperand(2).getImm();
176
Fixups.push_back(MCFixup::create(
177
0, Expr, MCFixupKind(RISCV::fixup_riscv_tlsdesc_call), MI.getLoc()));
178
MCInst Call =
179
MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm);
180
181
uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI);
182
support::endian::write(CB, Binary, llvm::endianness::little);
183
}
184
185
// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
186
void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
187
SmallVectorImpl<char> &CB,
188
SmallVectorImpl<MCFixup> &Fixups,
189
const MCSubtargetInfo &STI) const {
190
MCOperand DestReg = MI.getOperand(0);
191
MCOperand SrcReg = MI.getOperand(1);
192
MCOperand TPReg = MI.getOperand(2);
193
assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
194
"Expected thread pointer as second input to TP-relative add");
195
196
MCOperand SrcSymbol = MI.getOperand(3);
197
assert(SrcSymbol.isExpr() &&
198
"Expected expression as third input to TP-relative add");
199
200
const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
201
assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD &&
202
"Expected tprel_add relocation on TP-relative symbol");
203
204
// Emit the correct tprel_add relocation for the symbol.
205
Fixups.push_back(MCFixup::create(
206
0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc()));
207
208
// Emit fixup_riscv_relax for tprel_add where the relax feature is enabled.
209
if (STI.hasFeature(RISCV::FeatureRelax)) {
210
const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
211
Fixups.push_back(MCFixup::create(
212
0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc()));
213
}
214
215
// Emit a normal ADD instruction with the given operands.
216
MCInst TmpInst = MCInstBuilder(RISCV::ADD)
217
.addOperand(DestReg)
218
.addOperand(SrcReg)
219
.addOperand(TPReg);
220
uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
221
support::endian::write(CB, Binary, llvm::endianness::little);
222
}
223
224
static unsigned getInvertedBranchOp(unsigned BrOp) {
225
switch (BrOp) {
226
default:
227
llvm_unreachable("Unexpected branch opcode!");
228
case RISCV::PseudoLongBEQ:
229
return RISCV::BNE;
230
case RISCV::PseudoLongBNE:
231
return RISCV::BEQ;
232
case RISCV::PseudoLongBLT:
233
return RISCV::BGE;
234
case RISCV::PseudoLongBGE:
235
return RISCV::BLT;
236
case RISCV::PseudoLongBLTU:
237
return RISCV::BGEU;
238
case RISCV::PseudoLongBGEU:
239
return RISCV::BLTU;
240
}
241
}
242
243
// Expand PseudoLongBxx to an inverted conditional branch and an unconditional
244
// jump.
245
void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
246
SmallVectorImpl<char> &CB,
247
SmallVectorImpl<MCFixup> &Fixups,
248
const MCSubtargetInfo &STI) const {
249
MCRegister SrcReg1 = MI.getOperand(0).getReg();
250
MCRegister SrcReg2 = MI.getOperand(1).getReg();
251
MCOperand SrcSymbol = MI.getOperand(2);
252
unsigned Opcode = MI.getOpcode();
253
bool IsEqTest =
254
Opcode == RISCV::PseudoLongBNE || Opcode == RISCV::PseudoLongBEQ;
255
256
bool UseCompressedBr = false;
257
if (IsEqTest && (STI.hasFeature(RISCV::FeatureStdExtC) ||
258
STI.hasFeature(RISCV::FeatureStdExtZca))) {
259
if (RISCV::X8 <= SrcReg1.id() && SrcReg1.id() <= RISCV::X15 &&
260
SrcReg2.id() == RISCV::X0) {
261
UseCompressedBr = true;
262
} else if (RISCV::X8 <= SrcReg2.id() && SrcReg2.id() <= RISCV::X15 &&
263
SrcReg1.id() == RISCV::X0) {
264
std::swap(SrcReg1, SrcReg2);
265
UseCompressedBr = true;
266
}
267
}
268
269
uint32_t Offset;
270
if (UseCompressedBr) {
271
unsigned InvOpc =
272
Opcode == RISCV::PseudoLongBNE ? RISCV::C_BEQZ : RISCV::C_BNEZ;
273
MCInst TmpInst = MCInstBuilder(InvOpc).addReg(SrcReg1).addImm(6);
274
uint16_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
275
support::endian::write<uint16_t>(CB, Binary, llvm::endianness::little);
276
Offset = 2;
277
} else {
278
unsigned InvOpc = getInvertedBranchOp(Opcode);
279
MCInst TmpInst =
280
MCInstBuilder(InvOpc).addReg(SrcReg1).addReg(SrcReg2).addImm(8);
281
uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
282
support::endian::write(CB, Binary, llvm::endianness::little);
283
Offset = 4;
284
}
285
286
// Save the number fixups.
287
size_t FixupStartIndex = Fixups.size();
288
289
// Emit an unconditional jump to the destination.
290
MCInst TmpInst =
291
MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
292
uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
293
support::endian::write(CB, Binary, llvm::endianness::little);
294
295
// Drop any fixup added so we can add the correct one.
296
Fixups.resize(FixupStartIndex);
297
298
if (SrcSymbol.isExpr()) {
299
Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
300
MCFixupKind(RISCV::fixup_riscv_jal),
301
MI.getLoc()));
302
}
303
}
304
305
void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
306
SmallVectorImpl<char> &CB,
307
SmallVectorImpl<MCFixup> &Fixups,
308
const MCSubtargetInfo &STI) const {
309
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
310
// Get byte count of instruction.
311
unsigned Size = Desc.getSize();
312
313
// RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
314
// expanded instructions for each pseudo is correct in the Size field of the
315
// tablegen definition for the pseudo.
316
switch (MI.getOpcode()) {
317
default:
318
break;
319
case RISCV::PseudoCALLReg:
320
case RISCV::PseudoCALL:
321
case RISCV::PseudoTAIL:
322
case RISCV::PseudoJump:
323
expandFunctionCall(MI, CB, Fixups, STI);
324
MCNumEmitted += 2;
325
return;
326
case RISCV::PseudoAddTPRel:
327
expandAddTPRel(MI, CB, Fixups, STI);
328
MCNumEmitted += 1;
329
return;
330
case RISCV::PseudoLongBEQ:
331
case RISCV::PseudoLongBNE:
332
case RISCV::PseudoLongBLT:
333
case RISCV::PseudoLongBGE:
334
case RISCV::PseudoLongBLTU:
335
case RISCV::PseudoLongBGEU:
336
expandLongCondBr(MI, CB, Fixups, STI);
337
MCNumEmitted += 2;
338
return;
339
case RISCV::PseudoTLSDESCCall:
340
expandTLSDESCCall(MI, CB, Fixups, STI);
341
MCNumEmitted += 1;
342
return;
343
}
344
345
switch (Size) {
346
default:
347
llvm_unreachable("Unhandled encodeInstruction length!");
348
case 2: {
349
uint16_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
350
support::endian::write<uint16_t>(CB, Bits, llvm::endianness::little);
351
break;
352
}
353
case 4: {
354
uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
355
support::endian::write(CB, Bits, llvm::endianness::little);
356
break;
357
}
358
}
359
360
++MCNumEmitted; // Keep track of the # of mi's emitted.
361
}
362
363
unsigned
364
RISCVMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
365
SmallVectorImpl<MCFixup> &Fixups,
366
const MCSubtargetInfo &STI) const {
367
368
if (MO.isReg())
369
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
370
371
if (MO.isImm())
372
return static_cast<unsigned>(MO.getImm());
373
374
llvm_unreachable("Unhandled expression!");
375
return 0;
376
}
377
378
unsigned
379
RISCVMCCodeEmitter::getImmOpValueAsr1(const MCInst &MI, unsigned OpNo,
380
SmallVectorImpl<MCFixup> &Fixups,
381
const MCSubtargetInfo &STI) const {
382
const MCOperand &MO = MI.getOperand(OpNo);
383
384
if (MO.isImm()) {
385
unsigned Res = MO.getImm();
386
assert((Res & 1) == 0 && "LSB is non-zero");
387
return Res >> 1;
388
}
389
390
return getImmOpValue(MI, OpNo, Fixups, STI);
391
}
392
393
unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
394
SmallVectorImpl<MCFixup> &Fixups,
395
const MCSubtargetInfo &STI) const {
396
bool EnableRelax = STI.hasFeature(RISCV::FeatureRelax);
397
const MCOperand &MO = MI.getOperand(OpNo);
398
399
MCInstrDesc const &Desc = MCII.get(MI.getOpcode());
400
unsigned MIFrm = RISCVII::getFormat(Desc.TSFlags);
401
402
// If the destination is an immediate, there is nothing to do.
403
if (MO.isImm())
404
return MO.getImm();
405
406
assert(MO.isExpr() &&
407
"getImmOpValue expects only expressions or immediates");
408
const MCExpr *Expr = MO.getExpr();
409
MCExpr::ExprKind Kind = Expr->getKind();
410
RISCV::Fixups FixupKind = RISCV::fixup_riscv_invalid;
411
bool RelaxCandidate = false;
412
if (Kind == MCExpr::Target) {
413
const RISCVMCExpr *RVExpr = cast<RISCVMCExpr>(Expr);
414
415
switch (RVExpr->getKind()) {
416
case RISCVMCExpr::VK_RISCV_None:
417
case RISCVMCExpr::VK_RISCV_Invalid:
418
case RISCVMCExpr::VK_RISCV_32_PCREL:
419
llvm_unreachable("Unhandled fixup kind!");
420
case RISCVMCExpr::VK_RISCV_TPREL_ADD:
421
// tprel_add is only used to indicate that a relocation should be emitted
422
// for an add instruction used in TP-relative addressing. It should not be
423
// expanded as if representing an actual instruction operand and so to
424
// encounter it here is an error.
425
llvm_unreachable(
426
"VK_RISCV_TPREL_ADD should not represent an instruction operand");
427
case RISCVMCExpr::VK_RISCV_LO:
428
if (MIFrm == RISCVII::InstFormatI)
429
FixupKind = RISCV::fixup_riscv_lo12_i;
430
else if (MIFrm == RISCVII::InstFormatS)
431
FixupKind = RISCV::fixup_riscv_lo12_s;
432
else
433
llvm_unreachable("VK_RISCV_LO used with unexpected instruction format");
434
RelaxCandidate = true;
435
break;
436
case RISCVMCExpr::VK_RISCV_HI:
437
FixupKind = RISCV::fixup_riscv_hi20;
438
RelaxCandidate = true;
439
break;
440
case RISCVMCExpr::VK_RISCV_PCREL_LO:
441
if (MIFrm == RISCVII::InstFormatI)
442
FixupKind = RISCV::fixup_riscv_pcrel_lo12_i;
443
else if (MIFrm == RISCVII::InstFormatS)
444
FixupKind = RISCV::fixup_riscv_pcrel_lo12_s;
445
else
446
llvm_unreachable(
447
"VK_RISCV_PCREL_LO used with unexpected instruction format");
448
RelaxCandidate = true;
449
break;
450
case RISCVMCExpr::VK_RISCV_PCREL_HI:
451
FixupKind = RISCV::fixup_riscv_pcrel_hi20;
452
RelaxCandidate = true;
453
break;
454
case RISCVMCExpr::VK_RISCV_GOT_HI:
455
FixupKind = RISCV::fixup_riscv_got_hi20;
456
break;
457
case RISCVMCExpr::VK_RISCV_TPREL_LO:
458
if (MIFrm == RISCVII::InstFormatI)
459
FixupKind = RISCV::fixup_riscv_tprel_lo12_i;
460
else if (MIFrm == RISCVII::InstFormatS)
461
FixupKind = RISCV::fixup_riscv_tprel_lo12_s;
462
else
463
llvm_unreachable(
464
"VK_RISCV_TPREL_LO used with unexpected instruction format");
465
RelaxCandidate = true;
466
break;
467
case RISCVMCExpr::VK_RISCV_TPREL_HI:
468
FixupKind = RISCV::fixup_riscv_tprel_hi20;
469
RelaxCandidate = true;
470
break;
471
case RISCVMCExpr::VK_RISCV_TLS_GOT_HI:
472
FixupKind = RISCV::fixup_riscv_tls_got_hi20;
473
break;
474
case RISCVMCExpr::VK_RISCV_TLS_GD_HI:
475
FixupKind = RISCV::fixup_riscv_tls_gd_hi20;
476
break;
477
case RISCVMCExpr::VK_RISCV_CALL:
478
FixupKind = RISCV::fixup_riscv_call;
479
RelaxCandidate = true;
480
break;
481
case RISCVMCExpr::VK_RISCV_CALL_PLT:
482
FixupKind = RISCV::fixup_riscv_call_plt;
483
RelaxCandidate = true;
484
break;
485
case RISCVMCExpr::VK_RISCV_TLSDESC_HI:
486
FixupKind = RISCV::fixup_riscv_tlsdesc_hi20;
487
break;
488
case RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO:
489
FixupKind = RISCV::fixup_riscv_tlsdesc_load_lo12;
490
break;
491
case RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO:
492
FixupKind = RISCV::fixup_riscv_tlsdesc_add_lo12;
493
break;
494
case RISCVMCExpr::VK_RISCV_TLSDESC_CALL:
495
FixupKind = RISCV::fixup_riscv_tlsdesc_call;
496
break;
497
}
498
} else if ((Kind == MCExpr::SymbolRef &&
499
cast<MCSymbolRefExpr>(Expr)->getKind() ==
500
MCSymbolRefExpr::VK_None) ||
501
Kind == MCExpr::Binary) {
502
// FIXME: Sub kind binary exprs have chance of underflow.
503
if (MIFrm == RISCVII::InstFormatJ) {
504
FixupKind = RISCV::fixup_riscv_jal;
505
} else if (MIFrm == RISCVII::InstFormatB) {
506
FixupKind = RISCV::fixup_riscv_branch;
507
} else if (MIFrm == RISCVII::InstFormatCJ) {
508
FixupKind = RISCV::fixup_riscv_rvc_jump;
509
} else if (MIFrm == RISCVII::InstFormatCB) {
510
FixupKind = RISCV::fixup_riscv_rvc_branch;
511
} else if (MIFrm == RISCVII::InstFormatI) {
512
FixupKind = RISCV::fixup_riscv_12_i;
513
}
514
}
515
516
assert(FixupKind != RISCV::fixup_riscv_invalid && "Unhandled expression!");
517
518
Fixups.push_back(
519
MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
520
++MCNumFixups;
521
522
// Ensure an R_RISCV_RELAX relocation will be emitted if linker relaxation is
523
// enabled and the current fixup will result in a relocation that may be
524
// relaxed.
525
if (EnableRelax && RelaxCandidate) {
526
const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
527
Fixups.push_back(
528
MCFixup::create(0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax),
529
MI.getLoc()));
530
++MCNumFixups;
531
}
532
533
return 0;
534
}
535
536
unsigned RISCVMCCodeEmitter::getVMaskReg(const MCInst &MI, unsigned OpNo,
537
SmallVectorImpl<MCFixup> &Fixups,
538
const MCSubtargetInfo &STI) const {
539
MCOperand MO = MI.getOperand(OpNo);
540
assert(MO.isReg() && "Expected a register.");
541
542
switch (MO.getReg()) {
543
default:
544
llvm_unreachable("Invalid mask register.");
545
case RISCV::V0:
546
return 0;
547
case RISCV::NoRegister:
548
return 1;
549
}
550
}
551
552
unsigned RISCVMCCodeEmitter::getRlistOpValue(const MCInst &MI, unsigned OpNo,
553
SmallVectorImpl<MCFixup> &Fixups,
554
const MCSubtargetInfo &STI) const {
555
const MCOperand &MO = MI.getOperand(OpNo);
556
assert(MO.isImm() && "Rlist operand must be immediate");
557
auto Imm = MO.getImm();
558
assert(Imm >= 4 && "EABI is currently not implemented");
559
return Imm;
560
}
561
562
unsigned RISCVMCCodeEmitter::getRegReg(const MCInst &MI, unsigned OpNo,
563
SmallVectorImpl<MCFixup> &Fixups,
564
const MCSubtargetInfo &STI) const {
565
const MCOperand &MO = MI.getOperand(OpNo);
566
const MCOperand &MO1 = MI.getOperand(OpNo + 1);
567
assert(MO.isReg() && MO1.isReg() && "Expected registers.");
568
569
unsigned Op = Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
570
unsigned Op1 = Ctx.getRegisterInfo()->getEncodingValue(MO1.getReg());
571
572
return Op | Op1 << 5;
573
}
574
575
#include "RISCVGenMCCodeEmitter.inc"
576
577