1 //===-- RISCVAsmBackend.h - RISCV Assembler Backend -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
10 #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVASMBACKEND_H
12 #include "MCTargetDesc/RISCVFixupKinds.h"
13 #include "MCTargetDesc/RISCVMCTargetDesc.h"
14 #include "Utils/RISCVBaseInfo.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCFixupKindInfo.h"
17 #include "llvm/MC/MCSubtargetInfo.h"
21 class MCObjectTargetWriter
;
24 class RISCVAsmBackend
: public MCAsmBackend
{
25 const MCSubtargetInfo
&STI
;
28 bool ForceRelocs
= false;
29 const MCTargetOptions
&TargetOptions
;
30 RISCVABI::ABI TargetABI
= RISCVABI::ABI_Unknown
;
33 RISCVAsmBackend(const MCSubtargetInfo
&STI
, uint8_t OSABI
, bool Is64Bit
,
34 const MCTargetOptions
&Options
)
35 : MCAsmBackend(support::little
), STI(STI
), OSABI(OSABI
), Is64Bit(Is64Bit
),
36 TargetOptions(Options
) {
37 TargetABI
= RISCVABI::computeTargetABI(
38 STI
.getTargetTriple(), STI
.getFeatureBits(), Options
.getABIName());
39 RISCVFeatures::validate(STI
.getTargetTriple(), STI
.getFeatureBits());
41 ~RISCVAsmBackend() override
{}
43 void setForceRelocs() { ForceRelocs
= true; }
45 // Returns true if relocations will be forced for shouldForceRelocation by
46 // default. This will be true if relaxation is enabled or had previously
48 bool willForceRelocations() const {
49 return ForceRelocs
|| STI
.getFeatureBits()[RISCV::FeatureRelax
];
52 // Generate diff expression relocations if the relax feature is enabled or had
53 // previously been enabled, otherwise it is safe for the assembler to
54 // calculate these internally.
55 bool requiresDiffExpressionRelocations() const override
{
56 return willForceRelocations();
59 // Return Size with extra Nop Bytes for alignment directive in code section.
60 bool shouldInsertExtraNopBytesForCodeAlign(const MCAlignFragment
&AF
,
61 unsigned &Size
) override
;
63 // Insert target specific fixup type for alignment directive in code section.
64 bool shouldInsertFixupForCodeAlign(MCAssembler
&Asm
,
65 const MCAsmLayout
&Layout
,
66 MCAlignFragment
&AF
) override
;
68 void applyFixup(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
69 const MCValue
&Target
, MutableArrayRef
<char> Data
,
70 uint64_t Value
, bool IsResolved
,
71 const MCSubtargetInfo
*STI
) const override
;
73 std::unique_ptr
<MCObjectTargetWriter
>
74 createObjectTargetWriter() const override
;
76 bool shouldForceRelocation(const MCAssembler
&Asm
, const MCFixup
&Fixup
,
77 const MCValue
&Target
) override
;
79 bool fixupNeedsRelaxation(const MCFixup
&Fixup
, uint64_t Value
,
80 const MCRelaxableFragment
*DF
,
81 const MCAsmLayout
&Layout
) const override
{
82 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
85 bool fixupNeedsRelaxationAdvanced(const MCFixup
&Fixup
, bool Resolved
,
87 const MCRelaxableFragment
*DF
,
88 const MCAsmLayout
&Layout
,
89 const bool WasForced
) const override
;
91 unsigned getNumFixupKinds() const override
{
92 return RISCV::NumTargetFixupKinds
;
95 const MCFixupKindInfo
&getFixupKindInfo(MCFixupKind Kind
) const override
{
96 const static MCFixupKindInfo Infos
[] = {
97 // This table *must* be in the order that the fixup_* kinds are defined in
100 // name offset bits flags
101 { "fixup_riscv_hi20", 12, 20, 0 },
102 { "fixup_riscv_lo12_i", 20, 12, 0 },
103 { "fixup_riscv_lo12_s", 0, 32, 0 },
104 { "fixup_riscv_pcrel_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel
},
105 { "fixup_riscv_pcrel_lo12_i", 20, 12, MCFixupKindInfo::FKF_IsPCRel
},
106 { "fixup_riscv_pcrel_lo12_s", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
107 { "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel
},
108 { "fixup_riscv_tprel_hi20", 12, 20, 0 },
109 { "fixup_riscv_tprel_lo12_i", 20, 12, 0 },
110 { "fixup_riscv_tprel_lo12_s", 0, 32, 0 },
111 { "fixup_riscv_tprel_add", 0, 0, 0 },
112 { "fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel
},
113 { "fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel
},
114 { "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel
},
115 { "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel
},
116 { "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel
},
117 { "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel
},
118 { "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel
},
119 { "fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel
},
120 { "fixup_riscv_relax", 0, 0, 0 },
121 { "fixup_riscv_align", 0, 0, 0 }
123 static_assert((array_lengthof(Infos
)) == RISCV::NumTargetFixupKinds
,
124 "Not all fixup kinds added to Infos array");
126 if (Kind
< FirstTargetFixupKind
)
127 return MCAsmBackend::getFixupKindInfo(Kind
);
129 assert(unsigned(Kind
- FirstTargetFixupKind
) < getNumFixupKinds() &&
131 return Infos
[Kind
- FirstTargetFixupKind
];
134 bool mayNeedRelaxation(const MCInst
&Inst
,
135 const MCSubtargetInfo
&STI
) const override
;
136 unsigned getRelaxedOpcode(unsigned Op
) const;
138 void relaxInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&STI
,
139 MCInst
&Res
) const override
;
142 bool writeNopData(raw_ostream
&OS
, uint64_t Count
) const override
;
144 const MCTargetOptions
&getTargetOptions() const { return TargetOptions
; }
145 RISCVABI::ABI
getTargetABI() const { return TargetABI
; }