1//===-- RISCVAsmBackend.cpp - RISC-V Assembler Backend --------------------===//
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#include "RISCVAsmBackend.h"
10#include "RISCVFixupKinds.h"
11#include "llvm/ADT/APInt.h"
12#include "llvm/MC/MCAsmInfo.h"
13#include "llvm/MC/MCAssembler.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCELFObjectWriter.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCMachObjectWriter.h"
18#include "llvm/MC/MCObjectWriter.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/MC/MCValue.h"
21#include "llvm/Support/CommandLine.h"
22#include "llvm/Support/EndianStream.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/LEB128.h"
25#include "llvm/Support/raw_ostream.h"
26
27using namespace llvm;
28
29// Temporary workaround for old linkers that do not support ULEB128 relocations,
30// which are abused by DWARF v5 DW_LLE_offset_pair/DW_RLE_offset_pair
31// implemented in Clang/LLVM.
32static cl::opt<bool> ULEB128Reloc(
33 "riscv-uleb128-reloc", cl::init(Val: true), cl::Hidden,
34 cl::desc("Emit R_RISCV_SET_ULEB128/E_RISCV_SUB_ULEB128 if appropriate"));
35
36static cl::opt<bool>
37 AlignRvc("riscv-align-rvc", cl::init(Val: true), cl::Hidden,
38 cl::desc("When generating R_RISCV_ALIGN, insert $alignment-2 "
39 "bytes of NOPs even in norvc code"));
40
41RISCVAsmBackend::RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI,
42 bool Is64Bit, bool IsLittleEndian,
43 const MCTargetOptions &Options)
44 : MCAsmBackend(IsLittleEndian ? llvm::endianness::little
45 : llvm::endianness::big),
46 STI(STI), OSABI(OSABI), Is64Bit(Is64Bit), TargetOptions(Options) {
47 RISCVFeatures::validate(TT: STI.getTargetTriple(), FeatureBits: STI.getFeatureBits());
48}
49
50std::optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {
51 if (STI.getTargetTriple().isOSBinFormatELF()) {
52 unsigned Type;
53 Type = llvm::StringSwitch<unsigned>(Name)
54#define ELF_RELOC(NAME, ID) .Case(#NAME, ID)
55#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
56#undef ELF_RELOC
57#define ELF_RISCV_NONSTANDARD_RELOC(_VENDOR, NAME, ID) .Case(#NAME, ID)
58#include "llvm/BinaryFormat/ELFRelocs/RISCV_nonstandard.def"
59#undef ELF_RISCV_NONSTANDARD_RELOC
60 .Case(S: "BFD_RELOC_NONE", Value: ELF::R_RISCV_NONE)
61 .Case(S: "BFD_RELOC_32", Value: ELF::R_RISCV_32)
62 .Case(S: "BFD_RELOC_64", Value: ELF::R_RISCV_64)
63 .Default(Value: -1u);
64 if (Type != -1u)
65 return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
66 }
67 return std::nullopt;
68}
69
70MCFixupKindInfo RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
71 const static MCFixupKindInfo Infos[] = {
72 // This table *must* be in the order that the fixup_* kinds are defined in
73 // RISCVFixupKinds.h.
74 //
75 // name offset bits flags
76 {.Name: "fixup_riscv_hi20", .TargetOffset: 12, .TargetSize: 20, .Flags: 0},
77 {.Name: "fixup_riscv_lo12_i", .TargetOffset: 20, .TargetSize: 12, .Flags: 0},
78 {.Name: "fixup_riscv_12_i", .TargetOffset: 20, .TargetSize: 12, .Flags: 0},
79 {.Name: "fixup_riscv_lo12_s", .TargetOffset: 0, .TargetSize: 32, .Flags: 0},
80 {.Name: "fixup_riscv_pcrel_hi20", .TargetOffset: 12, .TargetSize: 20, .Flags: 0},
81 {.Name: "fixup_riscv_pcrel_lo12_i", .TargetOffset: 20, .TargetSize: 12, .Flags: 0},
82 {.Name: "fixup_riscv_pcrel_lo12_s", .TargetOffset: 0, .TargetSize: 32, .Flags: 0},
83 {.Name: "fixup_riscv_jal", .TargetOffset: 12, .TargetSize: 20, .Flags: 0},
84 {.Name: "fixup_riscv_branch", .TargetOffset: 0, .TargetSize: 32, .Flags: 0},
85 {.Name: "fixup_riscv_rvc_jump", .TargetOffset: 2, .TargetSize: 11, .Flags: 0},
86 {.Name: "fixup_riscv_rvc_branch", .TargetOffset: 0, .TargetSize: 16, .Flags: 0},
87 {.Name: "fixup_riscv_rvc_imm", .TargetOffset: 0, .TargetSize: 16, .Flags: 0},
88 {.Name: "fixup_riscv_call", .TargetOffset: 0, .TargetSize: 64, .Flags: 0},
89 {.Name: "fixup_riscv_call_plt", .TargetOffset: 0, .TargetSize: 64, .Flags: 0},
90
91 // Qualcomm fixups
92 {.Name: "fixup_riscv_qc_e_branch", .TargetOffset: 0, .TargetSize: 48, .Flags: 0},
93 {.Name: "fixup_riscv_qc_e_32", .TargetOffset: 16, .TargetSize: 32, .Flags: 0},
94 {.Name: "fixup_riscv_qc_abs20_u", .TargetOffset: 0, .TargetSize: 32, .Flags: 0},
95 {.Name: "fixup_riscv_qc_e_call_plt", .TargetOffset: 0, .TargetSize: 48, .Flags: 0},
96 {.Name: "fixup_qc_access_16", .TargetOffset: 0, .TargetSize: 0, .Flags: 0},
97 {.Name: "fixup_qc_access_32", .TargetOffset: 0, .TargetSize: 0, .Flags: 0},
98
99 // Andes fixups
100 {.Name: "fixup_riscv_nds_branch_10", .TargetOffset: 0, .TargetSize: 32, .Flags: 0},
101 };
102 static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
103 "Not all fixup kinds added to Infos array");
104
105 // Fixup kinds from raw relocation types and .reloc directives force
106 // relocations and do not use these fields.
107 if (mc::isRelocation(FixupKind: Kind))
108 return {};
109
110 if (Kind < FirstTargetFixupKind)
111 return MCAsmBackend::getFixupKindInfo(Kind);
112
113 assert(unsigned(Kind - FirstTargetFixupKind) < RISCV::NumTargetFixupKinds &&
114 "Invalid kind!");
115 return Infos[Kind - FirstTargetFixupKind];
116}
117
118bool RISCVAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,
119 const MCFixup &Fixup,
120 const MCValue &,
121 uint64_t Value,
122 bool Resolved) const {
123 int64_t Offset = int64_t(Value);
124 auto Kind = Fixup.getKind();
125
126 // Return true if the symbol is unresolved.
127 if (!Resolved)
128 return true;
129
130 switch (Kind) {
131 default:
132 return false;
133 case RISCV::fixup_riscv_rvc_branch:
134 // For compressed branch instructions the immediate must be
135 // in the range [-256, 254].
136 return Offset > 254 || Offset < -256;
137 case RISCV::fixup_riscv_rvc_jump:
138 // For compressed jump instructions the immediate must be
139 // in the range [-2048, 2046].
140 return Offset > 2046 || Offset < -2048;
141 case RISCV::fixup_riscv_branch:
142 case RISCV::fixup_riscv_qc_e_branch:
143 // For conditional branch instructions the immediate must be
144 // in the range [-4096, 4094].
145 return Offset > 4094 || Offset < -4096;
146 case RISCV::fixup_riscv_jal:
147 // For jump instructions the immediate must be in the range
148 // [-1048576, 1048574]
149 return Offset > 1048574 || Offset < -1048576;
150 case RISCV::fixup_riscv_rvc_imm:
151 // This fixup can never be emitted as a relocation, so always needs to be
152 // relaxed.
153 return true;
154 }
155}
156
157// Given a compressed control flow instruction this function returns
158// the expanded instruction, or the original instruction code if no
159// expansion is available.
160static unsigned getRelaxedOpcode(unsigned Opcode, ArrayRef<MCOperand> Operands,
161 const MCSubtargetInfo &STI) {
162 switch (Opcode) {
163 case RISCV::C_BEQZ:
164 return RISCV::BEQ;
165 case RISCV::C_BNEZ:
166 return RISCV::BNE;
167 case RISCV::C_J:
168 case RISCV::C_JAL: // fall through.
169 // This only relaxes one "step" - i.e. from C.J to JAL, not from C.J to
170 // QC.E.J, because we can always relax again if needed.
171 return RISCV::JAL;
172 case RISCV::C_LI:
173 if (!STI.hasFeature(Feature: RISCV::FeatureVendorXqcili))
174 break;
175 // We only need this because `QC.E.LI` can be compressed into a `C.LI`. This
176 // happens because the `simm6` MCOperandPredicate accepts bare symbols, and
177 // `QC.E.LI` is the only instruction that accepts bare symbols at parse-time
178 // and compresses to `C.LI`. `C.LI` does not itself accept bare symbols at
179 // parse time.
180 //
181 // If we have a bare symbol, we need to turn this back to a `QC.E.LI`, as we
182 // have no way to emit a relocation on a `C.LI` instruction.
183 return RISCV::QC_E_LI;
184 case RISCV::JAL: {
185 // We can only relax JAL if we have Xqcilb
186 if (!STI.hasFeature(Feature: RISCV::FeatureVendorXqcilb))
187 break;
188
189 // And only if it is using X0 or X1 for rd.
190 MCRegister Reg = Operands[0].getReg();
191 if (Reg == RISCV::X0)
192 return RISCV::QC_E_J;
193 if (Reg == RISCV::X1)
194 return RISCV::QC_E_JAL;
195
196 break;
197 }
198 case RISCV::BEQ:
199 return RISCV::PseudoLongBEQ;
200 case RISCV::BNE:
201 return RISCV::PseudoLongBNE;
202 case RISCV::BEQI:
203 return RISCV::PseudoLongBEQI;
204 case RISCV::BNEI:
205 return RISCV::PseudoLongBNEI;
206 case RISCV::BLT:
207 return RISCV::PseudoLongBLT;
208 case RISCV::BGE:
209 return RISCV::PseudoLongBGE;
210 case RISCV::BLTU:
211 return RISCV::PseudoLongBLTU;
212 case RISCV::BGEU:
213 return RISCV::PseudoLongBGEU;
214 case RISCV::QC_BEQI:
215 return RISCV::PseudoLongQC_BEQI;
216 case RISCV::QC_BNEI:
217 return RISCV::PseudoLongQC_BNEI;
218 case RISCV::QC_BLTI:
219 return RISCV::PseudoLongQC_BLTI;
220 case RISCV::QC_BGEI:
221 return RISCV::PseudoLongQC_BGEI;
222 case RISCV::QC_BLTUI:
223 return RISCV::PseudoLongQC_BLTUI;
224 case RISCV::QC_BGEUI:
225 return RISCV::PseudoLongQC_BGEUI;
226 case RISCV::QC_E_BEQI:
227 return RISCV::PseudoLongQC_E_BEQI;
228 case RISCV::QC_E_BNEI:
229 return RISCV::PseudoLongQC_E_BNEI;
230 case RISCV::QC_E_BLTI:
231 return RISCV::PseudoLongQC_E_BLTI;
232 case RISCV::QC_E_BGEI:
233 return RISCV::PseudoLongQC_E_BGEI;
234 case RISCV::QC_E_BLTUI:
235 return RISCV::PseudoLongQC_E_BLTUI;
236 case RISCV::QC_E_BGEUI:
237 return RISCV::PseudoLongQC_E_BGEUI;
238 case RISCV::CV_BEQIMM:
239 return RISCV::PseudoLongCV_BEQIMM;
240 case RISCV::CV_BNEIMM:
241 return RISCV::PseudoLongCV_BNEIMM;
242 }
243
244 // Returning the original opcode means we cannot relax the instruction.
245 return Opcode;
246}
247
248void RISCVAsmBackend::relaxInstruction(MCInst &Inst,
249 const MCSubtargetInfo &STI) const {
250 if (STI.hasFeature(Feature: RISCV::FeatureExactAssembly))
251 return;
252
253 MCInst Res;
254 switch (Inst.getOpcode()) {
255 default:
256 llvm_unreachable("Opcode not expected!");
257 case RISCV::C_BEQZ:
258 case RISCV::C_BNEZ:
259 case RISCV::C_J:
260 case RISCV::C_JAL: {
261 [[maybe_unused]] bool Success = RISCVRVC::uncompress(OutInst&: Res, MI: Inst, STI);
262 assert(Success && "Can't uncompress instruction");
263 assert(Res.getOpcode() ==
264 getRelaxedOpcode(Inst.getOpcode(), Inst.getOperands(), STI) &&
265 "Branch Relaxation Error");
266 break;
267 }
268 case RISCV::JAL: {
269 // This has to be written manually because the QC.E.J -> JAL is
270 // compression-only, so that it is not used when printing disassembly.
271 assert(STI.hasFeature(RISCV::FeatureVendorXqcilb) &&
272 "JAL is only relaxable with Xqcilb");
273 assert((Inst.getOperand(0).getReg() == RISCV::X0 ||
274 Inst.getOperand(0).getReg() == RISCV::X1) &&
275 "JAL only relaxable with rd=x0 or rd=x1");
276 Res.setOpcode(getRelaxedOpcode(Opcode: Inst.getOpcode(), Operands: Inst.getOperands(), STI));
277 Res.addOperand(Op: Inst.getOperand(i: 1));
278 break;
279 }
280 case RISCV::C_LI: {
281 // This should only be hit when trying to relax a `C.LI` into a `QC.E.LI`
282 // because the `C.LI` has a bare symbol. We cannot use
283 // `RISCVRVC::uncompress` because it will use decompression patterns. The
284 // `QC.E.LI` compression pattern to `C.LI` is compression-only (because we
285 // don't want `c.li` ever printed as `qc.e.li`, which might be done if the
286 // pattern applied to decompression), but that doesn't help much becuase
287 // `C.LI` with a bare symbol will decompress to an `ADDI` anyway (because
288 // `simm12`'s MCOperandPredicate accepts a bare symbol and that pattern
289 // comes first), and we still cannot emit an `ADDI` with a bare symbol.
290 assert(STI.hasFeature(RISCV::FeatureVendorXqcili) &&
291 "C.LI is only relaxable with Xqcili");
292 Res.setOpcode(getRelaxedOpcode(Opcode: Inst.getOpcode(), Operands: Inst.getOperands(), STI));
293 Res.addOperand(Op: Inst.getOperand(i: 0));
294 Res.addOperand(Op: Inst.getOperand(i: 1));
295 break;
296 }
297 case RISCV::BEQ:
298 case RISCV::BNE:
299 case RISCV::BEQI:
300 case RISCV::BNEI:
301 case RISCV::BLT:
302 case RISCV::BGE:
303 case RISCV::BLTU:
304 case RISCV::BGEU:
305 case RISCV::QC_BEQI:
306 case RISCV::QC_BNEI:
307 case RISCV::QC_BLTI:
308 case RISCV::QC_BGEI:
309 case RISCV::QC_BLTUI:
310 case RISCV::QC_BGEUI:
311 case RISCV::QC_E_BEQI:
312 case RISCV::QC_E_BNEI:
313 case RISCV::QC_E_BLTI:
314 case RISCV::QC_E_BGEI:
315 case RISCV::QC_E_BLTUI:
316 case RISCV::QC_E_BGEUI:
317 case RISCV::CV_BEQIMM:
318 case RISCV::CV_BNEIMM:
319 Res.setOpcode(getRelaxedOpcode(Opcode: Inst.getOpcode(), Operands: Inst.getOperands(), STI));
320 Res.addOperand(Op: Inst.getOperand(i: 0));
321 Res.addOperand(Op: Inst.getOperand(i: 1));
322 Res.addOperand(Op: Inst.getOperand(i: 2));
323 break;
324 }
325 Inst = std::move(Res);
326}
327
328// Check if an R_RISCV_ALIGN relocation is needed for an alignment directive.
329// If conditions are met, compute the padding size and create a fixup encoding
330// the padding size in the addend.
331bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
332 // Alignments before the first linker-relaxable instruction have fixed sizes
333 // and do not require relocations. Alignments after a linker-relaxable
334 // instruction require a relocation, even if the STI specifies norelax.
335 //
336 // firstLinkerRelaxable is the layout order within the subsection, which may
337 // be smaller than the section's order. Therefore, alignments in a
338 // lower-numbered subsection may be unnecessarily treated as linker-relaxable.
339 auto *Sec = F.getParent();
340 if (F.getLayoutOrder() <= Sec->firstLinkerRelaxable())
341 return false;
342
343 // Use default handling unless the alignment is larger than the nop size.
344 const MCSubtargetInfo *STI = F.getSubtargetInfo();
345 unsigned MinNopLen =
346 AlignRvc || STI->hasFeature(Feature: RISCV::FeatureStdExtZca) ? 2 : 4;
347 if (F.getAlignment() <= MinNopLen)
348 return false;
349
350 Size = F.getAlignment().value() - MinNopLen;
351 auto *Expr = MCConstantExpr::create(Value: Size, Ctx&: getContext());
352 MCFixup Fixup =
353 MCFixup::create(Offset: 0, Value: Expr, Kind: FirstLiteralRelocationKind + ELF::R_RISCV_ALIGN);
354 F.setVarFixups({Fixup});
355 F.setLinkerRelaxable();
356 return true;
357}
358
359bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F) const {
360 int64_t LineDelta = F.getDwarfLineDelta();
361 const MCExpr &AddrDelta = F.getDwarfAddrDelta();
362 int64_t Value;
363 // If the label difference can be resolved, use the default handling, which
364 // utilizes a shorter special opcode.
365 if (AddrDelta.evaluateAsAbsolute(Res&: Value, Asm: *Asm))
366 return false;
367 [[maybe_unused]] bool IsAbsolute =
368 AddrDelta.evaluateKnownAbsolute(Res&: Value, Asm: *Asm);
369 assert(IsAbsolute && "CFA with invalid expression");
370
371 SmallVector<char> Data;
372 raw_svector_ostream OS(Data);
373
374 // INT64_MAX is a signal that this is actually a DW_LNE_end_sequence.
375 if (LineDelta != INT64_MAX) {
376 OS << uint8_t(dwarf::DW_LNS_advance_line);
377 encodeSLEB128(Value: LineDelta, OS);
378 }
379
380 // According to the DWARF specification, the `DW_LNS_fixed_advance_pc` opcode
381 // takes a single unsigned half (unencoded) operand. The maximum encodable
382 // value is therefore 65535. Set a conservative upper bound for relaxation.
383 unsigned PCBytes;
384 if (Value > 60000) {
385 PCBytes = getContext().getAsmInfo().getCodePointerSize();
386 OS << uint8_t(dwarf::DW_LNS_extended_op) << uint8_t(PCBytes + 1)
387 << uint8_t(dwarf::DW_LNE_set_address);
388 OS.write_zeros(NumZeros: PCBytes);
389 } else {
390 PCBytes = 2;
391 OS << uint8_t(dwarf::DW_LNS_fixed_advance_pc);
392 support::endian::write<uint16_t>(os&: OS, value: 0, endian: Endian);
393 }
394 auto Offset = OS.tell() - PCBytes;
395
396 if (LineDelta == INT64_MAX) {
397 OS << uint8_t(dwarf::DW_LNS_extended_op);
398 OS << uint8_t(1);
399 OS << uint8_t(dwarf::DW_LNE_end_sequence);
400 } else {
401 OS << uint8_t(dwarf::DW_LNS_copy);
402 }
403
404 F.setVarContents(Data);
405 F.setVarFixups({MCFixup::create(Offset, Value: &AddrDelta,
406 Kind: MCFixup::getDataKindForSize(Size: PCBytes))});
407 return true;
408}
409
410bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F) const {
411 const MCExpr &AddrDelta = F.getDwarfAddrDelta();
412 SmallVector<MCFixup, 2> Fixups;
413 int64_t Value;
414 if (AddrDelta.evaluateAsAbsolute(Res&: Value, Asm: *Asm))
415 return false;
416 [[maybe_unused]] bool IsAbsolute =
417 AddrDelta.evaluateKnownAbsolute(Res&: Value, Asm: *Asm);
418 assert(IsAbsolute && "CFA with invalid expression");
419
420 assert(getContext().getAsmInfo().getMinInstAlignment() == 1 &&
421 "expected 1-byte alignment");
422 if (Value == 0) {
423 F.clearVarContents();
424 F.clearVarFixups();
425 return true;
426 }
427
428 auto AddFixups = [&Fixups, &AddrDelta](unsigned Offset,
429 std::pair<unsigned, unsigned> Fixup) {
430 const MCBinaryExpr &MBE = cast<MCBinaryExpr>(Val: AddrDelta);
431 Fixups.push_back(Elt: MCFixup::create(Offset, Value: MBE.getLHS(), Kind: std::get<0>(in&: Fixup)));
432 Fixups.push_back(Elt: MCFixup::create(Offset, Value: MBE.getRHS(), Kind: std::get<1>(in&: Fixup)));
433 };
434
435 SmallVector<char, 8> Data;
436 raw_svector_ostream OS(Data);
437 if (isUIntN(N: 6, x: Value)) {
438 OS << uint8_t(dwarf::DW_CFA_advance_loc);
439 AddFixups(0, {ELF::R_RISCV_SET6, ELF::R_RISCV_SUB6});
440 } else if (isUInt<8>(x: Value)) {
441 OS << uint8_t(dwarf::DW_CFA_advance_loc1);
442 support::endian::write<uint8_t>(os&: OS, value: 0, endian: Endian);
443 AddFixups(1, {ELF::R_RISCV_SET8, ELF::R_RISCV_SUB8});
444 } else if (isUInt<16>(x: Value)) {
445 OS << uint8_t(dwarf::DW_CFA_advance_loc2);
446 support::endian::write<uint16_t>(os&: OS, value: 0, endian: Endian);
447 AddFixups(1, {ELF::R_RISCV_SET16, ELF::R_RISCV_SUB16});
448 } else if (isUInt<32>(x: Value)) {
449 OS << uint8_t(dwarf::DW_CFA_advance_loc4);
450 support::endian::write<uint32_t>(os&: OS, value: 0, endian: Endian);
451 AddFixups(1, {ELF::R_RISCV_SET32, ELF::R_RISCV_SUB32});
452 } else {
453 llvm_unreachable("unsupported CFA encoding");
454 }
455 F.setVarContents(Data);
456 F.setVarFixups(Fixups);
457 return true;
458}
459
460std::pair<bool, bool> RISCVAsmBackend::relaxLEB128(MCFragment &LF,
461 int64_t &Value) const {
462 if (LF.isLEBSigned())
463 return std::make_pair(x: false, y: false);
464 const MCExpr &Expr = LF.getLEBValue();
465 if (ULEB128Reloc) {
466 LF.setVarFixups({MCFixup::create(Offset: 0, Value: &Expr, Kind: FK_Data_leb128)});
467 }
468 return std::make_pair(x: Expr.evaluateKnownAbsolute(Res&: Value, Asm: *Asm), y: false);
469}
470
471bool RISCVAsmBackend::mayNeedRelaxation(unsigned Opcode,
472 ArrayRef<MCOperand> Operands,
473 const MCSubtargetInfo &STI) const {
474 // This function has access to two STIs, the member of the AsmBackend, and the
475 // one passed as an argument. The latter is more specific, so we query it for
476 // specific features.
477 if (STI.hasFeature(Feature: RISCV::FeatureExactAssembly))
478 return false;
479
480 return getRelaxedOpcode(Opcode, Operands, STI) != Opcode;
481}
482
483bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
484 const MCSubtargetInfo *STI) const {
485 // We mostly follow binutils' convention here: align to even boundary with a
486 // 0-fill padding. We emit up to 1 2-byte nop, though we use c.nop if RVC is
487 // enabled or 0-fill otherwise. The remainder is now padded with 4-byte nops.
488
489 // Instructions always are at even addresses. We must be in a data area or
490 // be unaligned due to some other reason.
491 if (Count % 2) {
492 OS.write(Ptr: "\0", Size: 1);
493 Count -= 1;
494 }
495
496 // TODO: emit a mapping symbol right here
497
498 if (Count % 4 == 2) {
499 // The canonical nop with Zca is c.nop. For .balign 4, we generate a 2-byte
500 // c.nop even in a norvc region.
501 OS.write(Ptr: "\x01\0", Size: 2);
502 Count -= 2;
503 }
504
505 // The canonical nop on RISC-V is addi x0, x0, 0.
506 for (; Count >= 4; Count -= 4)
507 OS.write(Ptr: "\x13\0\0\0", Size: 4);
508
509 return true;
510}
511
512static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
513 MCContext &Ctx) {
514 switch (Fixup.getKind()) {
515 default:
516 llvm_unreachable("Unknown fixup kind!");
517 case FK_Data_1:
518 case FK_Data_2:
519 case FK_Data_4:
520 case FK_Data_8:
521 case FK_Data_leb128:
522 return Value;
523 case RISCV::fixup_riscv_lo12_i:
524 case RISCV::fixup_riscv_pcrel_lo12_i:
525 return Value & 0xfff;
526 case RISCV::fixup_riscv_12_i:
527 if (!isInt<12>(x: Value)) {
528 Ctx.reportError(L: Fixup.getLoc(),
529 Msg: "operand must be a constant 12-bit integer");
530 }
531 return Value & 0xfff;
532 case RISCV::fixup_riscv_lo12_s:
533 case RISCV::fixup_riscv_pcrel_lo12_s:
534 return (((Value >> 5) & 0x7f) << 25) | ((Value & 0x1f) << 7);
535 case RISCV::fixup_riscv_hi20:
536 case RISCV::fixup_riscv_pcrel_hi20:
537 // Add 1 if bit 11 is 1, to compensate for low 12 bits being negative.
538 return ((Value + 0x800) >> 12) & 0xfffff;
539 case RISCV::fixup_riscv_jal: {
540 if (!isInt<21>(x: Value))
541 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
542 if (Value & 0x1)
543 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value must be 2-byte aligned");
544 // Need to produce imm[19|10:1|11|19:12] from the 21-bit Value.
545 unsigned Sbit = (Value >> 20) & 0x1;
546 unsigned Hi8 = (Value >> 12) & 0xff;
547 unsigned Mid1 = (Value >> 11) & 0x1;
548 unsigned Lo10 = (Value >> 1) & 0x3ff;
549 // Inst{31} = Sbit;
550 // Inst{30-21} = Lo10;
551 // Inst{20} = Mid1;
552 // Inst{19-12} = Hi8;
553 Value = (Sbit << 19) | (Lo10 << 9) | (Mid1 << 8) | Hi8;
554 return Value;
555 }
556 case RISCV::fixup_riscv_qc_e_branch:
557 case RISCV::fixup_riscv_branch: {
558 if (!isInt<13>(x: Value))
559 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
560 if (Value & 0x1)
561 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value must be 2-byte aligned");
562 // Need to extract imm[12], imm[10:5], imm[4:1], imm[11] from the 13-bit
563 // Value.
564 unsigned Sbit = (Value >> 12) & 0x1;
565 unsigned Hi1 = (Value >> 11) & 0x1;
566 unsigned Mid6 = (Value >> 5) & 0x3f;
567 unsigned Lo4 = (Value >> 1) & 0xf;
568 // Inst{31} = Sbit;
569 // Inst{30-25} = Mid6;
570 // Inst{11-8} = Lo4;
571 // Inst{7} = Hi1;
572 Value = (Sbit << 31) | (Mid6 << 25) | (Lo4 << 8) | (Hi1 << 7);
573 return Value;
574 }
575 case RISCV::fixup_riscv_call:
576 case RISCV::fixup_riscv_call_plt: {
577 // Jalr will add UpperImm with the sign-extended 12-bit LowerImm,
578 // we need to add 0x800ULL before extract upper bits to reflect the
579 // effect of the sign extension.
580 uint64_t UpperImm = (Value + 0x800ULL) & 0xfffff000ULL;
581 uint64_t LowerImm = Value & 0xfffULL;
582 return UpperImm | ((LowerImm << 20) << 32);
583 }
584 case RISCV::fixup_riscv_rvc_jump: {
585 if (!isInt<12>(x: Value))
586 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
587 // Need to produce offset[11|4|9:8|10|6|7|3:1|5] from the 11-bit Value.
588 unsigned Bit11 = (Value >> 11) & 0x1;
589 unsigned Bit4 = (Value >> 4) & 0x1;
590 unsigned Bit9_8 = (Value >> 8) & 0x3;
591 unsigned Bit10 = (Value >> 10) & 0x1;
592 unsigned Bit6 = (Value >> 6) & 0x1;
593 unsigned Bit7 = (Value >> 7) & 0x1;
594 unsigned Bit3_1 = (Value >> 1) & 0x7;
595 unsigned Bit5 = (Value >> 5) & 0x1;
596 Value = (Bit11 << 10) | (Bit4 << 9) | (Bit9_8 << 7) | (Bit10 << 6) |
597 (Bit6 << 5) | (Bit7 << 4) | (Bit3_1 << 1) | Bit5;
598 return Value;
599 }
600 case RISCV::fixup_riscv_rvc_branch: {
601 if (!isInt<9>(x: Value))
602 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
603 // Need to produce offset[8|4:3], [reg 3 bit], offset[7:6|2:1|5]
604 unsigned Bit8 = (Value >> 8) & 0x1;
605 unsigned Bit7_6 = (Value >> 6) & 0x3;
606 unsigned Bit5 = (Value >> 5) & 0x1;
607 unsigned Bit4_3 = (Value >> 3) & 0x3;
608 unsigned Bit2_1 = (Value >> 1) & 0x3;
609 Value = (Bit8 << 12) | (Bit4_3 << 10) | (Bit7_6 << 5) | (Bit2_1 << 3) |
610 (Bit5 << 2);
611 return Value;
612 }
613 case RISCV::fixup_riscv_rvc_imm: {
614 if (!isInt<6>(x: Value))
615 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
616 unsigned Bit5 = (Value >> 5) & 0x1;
617 unsigned Bit4_0 = Value & 0x1f;
618 Value = (Bit5 << 12) | (Bit4_0 << 2);
619 return Value;
620 }
621 case RISCV::fixup_riscv_qc_e_32: {
622 if (!isInt<32>(x: Value))
623 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
624 return Value & 0xffffffffu;
625 }
626 case RISCV::fixup_riscv_qc_abs20_u: {
627 if (!isInt<20>(x: Value))
628 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
629 unsigned Bit19 = (Value >> 19) & 0x1;
630 unsigned Bit14_0 = Value & 0x7fff;
631 unsigned Bit18_15 = (Value >> 15) & 0xf;
632 Value = (Bit19 << 31) | (Bit14_0 << 16) | (Bit18_15 << 12);
633 return Value;
634 }
635 case RISCV::fixup_riscv_qc_e_call_plt: {
636 if (!isInt<32>(x: Value))
637 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
638 if (Value & 0x1)
639 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value must be 2-byte aligned");
640 uint64_t Bit31_16 = (Value >> 16) & 0xffff;
641 uint64_t Bit12 = (Value >> 12) & 0x1;
642 uint64_t Bit10_5 = (Value >> 5) & 0x3f;
643 uint64_t Bit15_13 = (Value >> 13) & 0x7;
644 uint64_t Bit4_1 = (Value >> 1) & 0xf;
645 uint64_t Bit11 = (Value >> 11) & 0x1;
646 Value = (Bit31_16 << 32ull) | (Bit12 << 31) | (Bit10_5 << 25) |
647 (Bit15_13 << 17) | (Bit4_1 << 8) | (Bit11 << 7);
648 return Value;
649 }
650 case RISCV::fixup_qc_access_16:
651 case RISCV::fixup_qc_access_32:
652 return 0;
653 case RISCV::fixup_riscv_nds_branch_10: {
654 if (!isInt<11>(x: Value))
655 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value out of range");
656 if (Value & 0x1)
657 Ctx.reportError(L: Fixup.getLoc(), Msg: "fixup value must be 2-byte aligned");
658 // Need to extract imm[10], imm[9:5], imm[4:1] from the 11-bit Value.
659 unsigned Sbit = (Value >> 10) & 0x1;
660 unsigned Hi5 = (Value >> 5) & 0x1f;
661 unsigned Lo4 = (Value >> 1) & 0xf;
662 // Inst{31} = Sbit;
663 // Inst{29-25} = Hi5;
664 // Inst{11-8} = Lo4;
665 Value = (Sbit << 31) | (Hi5 << 25) | (Lo4 << 8);
666 return Value;
667 }
668 }
669}
670
671bool RISCVAsmBackend::isPCRelFixupResolved(const MCSymbol *SymA,
672 const MCFragment &F) {
673 // If the section does not contain linker-relaxable fragments, PC-relative
674 // fixups can be resolved.
675 if (!F.getParent()->isLinkerRelaxable())
676 return true;
677
678 // Otherwise, check if the offset between the symbol and fragment is fully
679 // resolved, unaffected by linker-relaxable fragments (e.g. instructions or
680 // offset-affected FT_Align fragments). Complements the generic
681 // isSymbolRefDifferenceFullyResolvedImpl.
682 if (!PCRelTemp)
683 PCRelTemp = getContext().createTempSymbol();
684 PCRelTemp->setFragment(const_cast<MCFragment *>(&F));
685 MCValue Res;
686 MCExpr::evaluateSymbolicAdd(Asm, false, MCValue::get(SymA),
687 MCValue::get(SymA: nullptr, SymB: PCRelTemp), Res);
688 return !Res.getSubSym();
689}
690
691// Get the corresponding PC-relative HI fixup that a S_PCREL_LO points to, and
692// optionally the fragment containing it.
693//
694// \returns nullptr if this isn't a S_PCREL_LO pointing to a known PC-relative
695// HI fixup.
696const MCFixup *getPCRelHiFixup(const MCSpecifierExpr &Expr,
697 const MCFragment **DFOut) {
698 MCValue AUIPCLoc;
699 if (!Expr.getSubExpr()->evaluateAsRelocatable(Res&: AUIPCLoc, Asm: nullptr))
700 return nullptr;
701
702 const MCSymbol *AUIPCSymbol = AUIPCLoc.getAddSym();
703 if (!AUIPCSymbol)
704 return nullptr;
705 const auto *DF = AUIPCSymbol->getFragment();
706 if (!DF)
707 return nullptr;
708
709 uint64_t Offset = AUIPCSymbol->getOffset();
710 if (DF->getContents().size() == Offset) {
711 DF = DF->getNext();
712 if (!DF)
713 return nullptr;
714 Offset = 0;
715 }
716
717 for (const MCFixup &F : DF->getFixups()) {
718 if (F.getOffset() != Offset)
719 continue;
720 auto Kind = F.getKind();
721 if (!mc::isRelocation(FixupKind: F.getKind())) {
722 if (Kind == RISCV::fixup_riscv_pcrel_hi20) {
723 *DFOut = DF;
724 return &F;
725 }
726 break;
727 }
728 switch (Kind) {
729 case ELF::R_RISCV_GOT_HI20:
730 case ELF::R_RISCV_TLS_GOT_HI20:
731 case ELF::R_RISCV_TLS_GD_HI20:
732 case ELF::R_RISCV_TLSDESC_HI20:
733 *DFOut = DF;
734 return &F;
735 }
736 }
737
738 return nullptr;
739}
740
741std::optional<bool> RISCVAsmBackend::evaluateFixup(const MCFragment &,
742 MCFixup &Fixup,
743 MCValue &Target,
744 uint64_t &Value) {
745 const MCFixup *AUIPCFixup;
746 const MCFragment *AUIPCDF;
747 MCValue AUIPCTarget;
748 switch (Fixup.getKind()) {
749 default:
750 // Use default handling for `Value` and `IsResolved`.
751 return {};
752 case RISCV::fixup_qc_access_16:
753 case RISCV::fixup_qc_access_32:
754 // Never resolved in the assembler
755 return false;
756 case RISCV::fixup_riscv_pcrel_lo12_i:
757 case RISCV::fixup_riscv_pcrel_lo12_s: {
758 AUIPCFixup =
759 getPCRelHiFixup(Expr: cast<MCSpecifierExpr>(Val: *Fixup.getValue()), DFOut: &AUIPCDF);
760 if (!AUIPCFixup) {
761 getContext().reportError(L: Fixup.getLoc(),
762 Msg: "could not find corresponding %pcrel_hi");
763 return true;
764 }
765
766 // MCAssembler::evaluateFixup will emit an error for this case when it sees
767 // the %pcrel_hi, so don't duplicate it when also seeing the %pcrel_lo.
768 const MCExpr *AUIPCExpr = AUIPCFixup->getValue();
769 if (!AUIPCExpr->evaluateAsRelocatable(Res&: AUIPCTarget, Asm))
770 return true;
771 break;
772 }
773 }
774
775 if (!AUIPCTarget.getAddSym())
776 return false;
777
778 auto &SA = static_cast<const MCSymbolELF &>(*AUIPCTarget.getAddSym());
779 if (SA.isUndefined())
780 return false;
781
782 bool IsResolved = &SA.getSection() == AUIPCDF->getParent() &&
783 SA.getBinding() == ELF::STB_LOCAL &&
784 SA.getType() != ELF::STT_GNU_IFUNC;
785 if (!IsResolved)
786 return false;
787
788 Value = Asm->getSymbolOffset(S: SA) + AUIPCTarget.getConstant();
789 Value -= Asm->getFragmentOffset(F: *AUIPCDF) + AUIPCFixup->getOffset();
790
791 return AUIPCFixup->getKind() == RISCV::fixup_riscv_pcrel_hi20 &&
792 isPCRelFixupResolved(SymA: AUIPCTarget.getAddSym(), F: *AUIPCDF);
793}
794
795void RISCVAsmBackend::maybeAddVendorReloc(const MCFragment &F,
796 const MCFixup &Fixup) {
797 StringRef VendorIdentifier;
798 switch (Fixup.getKind()) {
799 default:
800 // No Vendor Relocation Required.
801 return;
802 case RISCV::fixup_riscv_qc_e_branch:
803 case RISCV::fixup_riscv_qc_abs20_u:
804 case RISCV::fixup_riscv_qc_e_32:
805 case RISCV::fixup_riscv_qc_e_call_plt:
806 case RISCV::fixup_qc_access_16:
807 case RISCV::fixup_qc_access_32:
808 VendorIdentifier = "QUALCOMM";
809 break;
810 case RISCV::fixup_riscv_nds_branch_10:
811 VendorIdentifier = "ANDES";
812 break;
813 }
814
815 // Create a local symbol for the vendor relocation to reference. It's fine if
816 // the symbol has the same name as an existing symbol.
817 MCContext &Ctx = Asm->getContext();
818 MCSymbol *VendorSymbol = Ctx.createLocalSymbol(Name: VendorIdentifier);
819 auto [It, Inserted] =
820 VendorSymbols.try_emplace(Key: VendorIdentifier, Args&: VendorSymbol);
821
822 if (Inserted) {
823 // Setup the just-created symbol
824 VendorSymbol->setVariableValue(MCConstantExpr::create(Value: 0, Ctx));
825 Asm->registerSymbol(Symbol: *VendorSymbol);
826 } else {
827 // Fetch the existing symbol
828 VendorSymbol = It->getValue();
829 }
830
831 MCFixup VendorFixup =
832 MCFixup::create(Offset: Fixup.getOffset(), Value: nullptr, Kind: ELF::R_RISCV_VENDOR);
833 // Explicitly create MCValue rather than using an MCExpr and evaluating it so
834 // that the absolute vendor symbol is not evaluated to constant 0.
835 MCValue VendorTarget = MCValue::get(SymA: VendorSymbol);
836 uint64_t VendorValue;
837 Asm->getWriter().recordRelocation(F, Fixup: VendorFixup, Target: VendorTarget, FixedValue&: VendorValue);
838}
839
840static bool relaxableFixupNeedsRelocation(const MCFixupKind Kind) {
841 // Some Fixups are marked as LinkerRelaxable by
842 // `RISCVMCCodeEmitter::getImmOpValue` only because they may be
843 // (assembly-)relaxed into a linker-relaxable instruction. This function
844 // should return `false` for those fixups so they do not get a `R_RISCV_RELAX`
845 // relocation emitted in addition to the relocation.
846 switch (Kind) {
847 default:
848 break;
849 case RISCV::fixup_riscv_rvc_jump:
850 case RISCV::fixup_riscv_branch:
851 case RISCV::fixup_riscv_rvc_branch:
852 case RISCV::fixup_riscv_qc_e_branch:
853 case RISCV::fixup_riscv_rvc_imm:
854 return false;
855 }
856 return true;
857}
858
859bool RISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
860 const MCValue &Target, uint64_t &FixedValue,
861 bool IsResolved) {
862 uint64_t FixedValueA, FixedValueB;
863 if (Target.getSubSym()) {
864 assert(Target.getSpecifier() == 0 &&
865 "relocatable SymA-SymB cannot have relocation specifier");
866 unsigned TA = 0, TB = 0;
867 switch (Fixup.getKind()) {
868 case llvm::FK_Data_1:
869 TA = ELF::R_RISCV_ADD8;
870 TB = ELF::R_RISCV_SUB8;
871 break;
872 case llvm::FK_Data_2:
873 TA = ELF::R_RISCV_ADD16;
874 TB = ELF::R_RISCV_SUB16;
875 break;
876 case llvm::FK_Data_4:
877 TA = ELF::R_RISCV_ADD32;
878 TB = ELF::R_RISCV_SUB32;
879 break;
880 case llvm::FK_Data_8:
881 TA = ELF::R_RISCV_ADD64;
882 TB = ELF::R_RISCV_SUB64;
883 break;
884 case llvm::FK_Data_leb128:
885 TA = ELF::R_RISCV_SET_ULEB128;
886 TB = ELF::R_RISCV_SUB_ULEB128;
887 break;
888 default:
889 llvm_unreachable("unsupported fixup size");
890 }
891 MCValue A = MCValue::get(SymA: Target.getAddSym(), SymB: nullptr, Val: Target.getConstant());
892 MCValue B = MCValue::get(SymA: Target.getSubSym());
893 auto FA = MCFixup::create(Offset: Fixup.getOffset(), Value: nullptr, Kind: TA);
894 auto FB = MCFixup::create(Offset: Fixup.getOffset(), Value: nullptr, Kind: TB);
895 Asm->getWriter().recordRelocation(F, Fixup: FA, Target: A, FixedValue&: FixedValueA);
896 Asm->getWriter().recordRelocation(F, Fixup: FB, Target: B, FixedValue&: FixedValueB);
897 FixedValue = FixedValueA - FixedValueB;
898 return false;
899 }
900
901 // If linker relaxation is enabled and supported by the current fixup, then we
902 // always want to generate a relocation.
903 bool NeedsRelax = Fixup.isLinkerRelaxable() &&
904 relaxableFixupNeedsRelocation(Kind: Fixup.getKind());
905 if (NeedsRelax)
906 IsResolved = false;
907
908 if (IsResolved && Fixup.isPCRel())
909 IsResolved = isPCRelFixupResolved(SymA: Target.getAddSym(), F);
910
911 if (!IsResolved) {
912 // Some Fixups require a VENDOR relocation, record it (directly) before we
913 // add the relocation.
914 maybeAddVendorReloc(F, Fixup);
915
916 Asm->getWriter().recordRelocation(F, Fixup, Target, FixedValue);
917
918 if (NeedsRelax) {
919 // Some Fixups get a RELAX relocation, record it (directly) after we add
920 // the relocation.
921 MCFixup RelaxFixup =
922 MCFixup::create(Offset: Fixup.getOffset(), Value: nullptr, Kind: ELF::R_RISCV_RELAX);
923 MCValue RelaxTarget = MCValue::get(SymA: nullptr);
924 uint64_t RelaxValue;
925 Asm->getWriter().recordRelocation(F, Fixup: RelaxFixup, Target: RelaxTarget, FixedValue&: RelaxValue);
926 }
927 }
928
929 return false;
930}
931
932// Data fixups should be swapped for big endian cores.
933// Instruction fixups should not be swapped as RISC-V instructions
934// are always little-endian.
935static bool isDataFixup(unsigned Kind) {
936 switch (Kind) {
937 default:
938 return false;
939
940 case FK_Data_1:
941 case FK_Data_2:
942 case FK_Data_4:
943 case FK_Data_8:
944 return true;
945 }
946}
947
948void RISCVAsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
949 const MCValue &Target, uint8_t *Data,
950 uint64_t Value, bool IsResolved) {
951 IsResolved = addReloc(F, Fixup, Target, FixedValue&: Value, IsResolved);
952 MCFixupKind Kind = Fixup.getKind();
953 if (mc::isRelocation(FixupKind: Kind))
954 return;
955 MCContext &Ctx = getContext();
956 MCFixupKindInfo Info = getFixupKindInfo(Kind);
957 if (!Value)
958 return; // Doesn't change encoding.
959 // Apply any target-specific value adjustments.
960 Value = adjustFixupValue(Fixup, Value, Ctx);
961
962 // Shift the value into position.
963 Value <<= Info.TargetOffset;
964
965 unsigned NumBytes = alignTo(Value: Info.TargetSize + Info.TargetOffset, Align: 8) / 8;
966 assert(Fixup.getOffset() + NumBytes <= F.getSize() &&
967 "Invalid fixup offset!");
968
969 // For each byte of the fragment that the fixup touches, mask in the
970 // bits from the fixup value.
971 // For big endian cores, data fixup should be swapped.
972 bool SwapValue = Endian == llvm::endianness::big && isDataFixup(Kind);
973 for (unsigned i = 0; i != NumBytes; ++i) {
974 unsigned Idx = SwapValue ? (NumBytes - 1 - i) : i;
975 Data[Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
976 }
977}
978
979std::unique_ptr<MCObjectTargetWriter>
980RISCVAsmBackend::createObjectTargetWriter() const {
981 return createRISCVELFObjectWriter(OSABI, Is64Bit);
982}
983
984class DarwinRISCVAsmBackend : public RISCVAsmBackend {
985public:
986 DarwinRISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit,
987 bool IsLittleEndian, const MCTargetOptions &Options)
988 : RISCVAsmBackend(STI, OSABI, Is64Bit, IsLittleEndian, Options) {}
989
990 std::unique_ptr<MCObjectTargetWriter>
991 createObjectTargetWriter() const override {
992 const Triple &TT = STI.getTargetTriple();
993 uint32_t CPUType = cantFail(ValOrErr: MachO::getCPUType(T: TT));
994 uint32_t CPUSubType = cantFail(ValOrErr: MachO::getCPUSubType(T: TT));
995 return createRISCVMachObjectWriter(CPUType, CPUSubtype: CPUSubType);
996 }
997
998 bool addReloc(const MCFragment &, const MCFixup &, const MCValue &,
999 uint64_t &FixedValue, bool IsResolved) override;
1000
1001 std::optional<bool> evaluateFixup(const MCFragment &F, MCFixup &Fixup,
1002 MCValue &Target, uint64_t &Value) override {
1003 const MCFixup *AUIPCFixup;
1004 const MCFragment *AUIPCDF;
1005 const MCFixupKind FKind = Fixup.getKind();
1006 if ((FKind == RISCV::fixup_riscv_pcrel_lo12_i) ||
1007 (FKind == RISCV::fixup_riscv_pcrel_lo12_s)) {
1008 AUIPCFixup =
1009 getPCRelHiFixup(Expr: cast<MCSpecifierExpr>(Val: *Fixup.getValue()), DFOut: &AUIPCDF);
1010 if (!AUIPCFixup) {
1011 getContext().reportError(L: Fixup.getLoc(),
1012 Msg: "could not find corresponding %pcrel_hi");
1013 return true;
1014 }
1015
1016 return false;
1017 }
1018
1019 // Use default handling for all other cases.
1020 return {};
1021 }
1022};
1023
1024MCAsmBackend *llvm::createRISCVAsmBackend(const Target &T,
1025 const MCSubtargetInfo &STI,
1026 const MCRegisterInfo &MRI,
1027 const MCTargetOptions &Options) {
1028 const Triple &TT = STI.getTargetTriple();
1029 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType: TT.getOS());
1030 if (TT.isOSBinFormatMachO())
1031 return new DarwinRISCVAsmBackend(STI, OSABI, TT.isArch64Bit(),
1032 TT.isLittleEndian(), Options);
1033
1034 return new RISCVAsmBackend(STI, OSABI, TT.isArch64Bit(), TT.isLittleEndian(),
1035 Options);
1036}
1037
1038bool DarwinRISCVAsmBackend::addReloc(const MCFragment &F, const MCFixup &Fixup,
1039 const MCValue &Target,
1040 uint64_t &FixedValue, bool IsResolved) {
1041 if (!IsResolved)
1042 Asm->getWriter().recordRelocation(F, Fixup, Target, FixedValue);
1043 return IsResolved;
1044}
1045