blob: c7e59981ec1a8e635ed2813a726717a80012c351 [file] [log] [blame]
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001//===-- RISCVAsmBackend.h - RISCV Assembler Backend -----------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
10#define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
11
12#include "MCTargetDesc/RISCVFixupKinds.h"
13#include "MCTargetDesc/RISCVMCTargetDesc.h"
14#include "llvm/MC/MCAsmBackend.h"
15#include "llvm/MC/MCFixupKindInfo.h"
16#include "llvm/MC/MCSubtargetInfo.h"
17
18namespace llvm {
19class MCAssembler;
20class MCObjectTargetWriter;
21class raw_ostream;
22
23class RISCVAsmBackend : public MCAsmBackend {
24 const MCSubtargetInfo &STI;
25 uint8_t OSABI;
26 bool Is64Bit;
27 bool ForceRelocs = false;
28
29public:
30 RISCVAsmBackend(const MCSubtargetInfo &STI, uint8_t OSABI, bool Is64Bit)
31 : MCAsmBackend(support::little), STI(STI), OSABI(OSABI),
32 Is64Bit(Is64Bit) {}
33 ~RISCVAsmBackend() override {}
34
35 void setForceRelocs() { ForceRelocs = true; }
36
37 // Generate diff expression relocations if the relax feature is enabled or had
38 // previously been enabled, otherwise it is safe for the assembler to
39 // calculate these internally.
40 bool requiresDiffExpressionRelocations() const override {
41 return STI.getFeatureBits()[RISCV::FeatureRelax] || ForceRelocs;
42 }
43 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
44 const MCValue &Target, MutableArrayRef<char> Data,
45 uint64_t Value, bool IsResolved,
46 const MCSubtargetInfo *STI) const override;
47
48 std::unique_ptr<MCObjectTargetWriter>
49 createObjectTargetWriter() const override;
50
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000051 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
Alex Bradburyeb3a64a2018-12-20 14:52:15 +000052 const MCValue &Target) override;
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000053
54 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
55 const MCRelaxableFragment *DF,
56 const MCAsmLayout &Layout) const override {
57 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
58 }
59
60 bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
61 uint64_t Value,
62 const MCRelaxableFragment *DF,
63 const MCAsmLayout &Layout,
64 const bool WasForced) const override;
65
66 unsigned getNumFixupKinds() const override {
67 return RISCV::NumTargetFixupKinds;
68 }
69
70 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
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 { "fixup_riscv_hi20", 12, 20, 0 },
77 { "fixup_riscv_lo12_i", 20, 12, 0 },
78 { "fixup_riscv_lo12_s", 0, 32, 0 },
79 { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
80 { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel },
81 { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
82 { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
83 { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
84 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
85 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
86 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
87 { "fixup_riscv_relax", 0, 0, 0 }
88 };
89 static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
90 "Not all fixup kinds added to Infos array");
91
92 if (Kind < FirstTargetFixupKind)
93 return MCAsmBackend::getFixupKindInfo(Kind);
94
95 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
96 "Invalid kind!");
97 return Infos[Kind - FirstTargetFixupKind];
98 }
99
100 bool mayNeedRelaxation(const MCInst &Inst,
101 const MCSubtargetInfo &STI) const override;
102 unsigned getRelaxedOpcode(unsigned Op) const;
103
104 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
105 MCInst &Res) const override;
106
107
108 bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
109};
110}
111
112#endif