LLVM 19.0.0git
AMDGPUAsmBackend.cpp
Go to the documentation of this file.
1//===-- AMDGPUAsmBackend.cpp - AMDGPU 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/// \file
8//===----------------------------------------------------------------------===//
9
15#include "llvm/MC/MCAssembler.h"
16#include "llvm/MC/MCContext.h"
23
24using namespace llvm;
25using namespace llvm::AMDGPU;
26
27namespace {
28
29class AMDGPUAsmBackend : public MCAsmBackend {
30public:
31 AMDGPUAsmBackend(const Target &T) : MCAsmBackend(llvm::endianness::little) {}
32
33 unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; };
34
35 void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
37 uint64_t Value, bool IsResolved,
38 const MCSubtargetInfo *STI) const override;
40 uint64_t Value) const override;
41
42 void relaxInstruction(MCInst &Inst,
43 const MCSubtargetInfo &STI) const override;
44
45 bool mayNeedRelaxation(const MCInst &Inst,
46 const MCSubtargetInfo &STI) const override;
47
48 unsigned getMinimumNopSize() const override;
50 const MCSubtargetInfo *STI) const override;
51
52 std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
53 const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
54 bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
55 const MCValue &Target,
56 const MCSubtargetInfo *STI) override;
57};
58
59} //End anonymous namespace
60
61void AMDGPUAsmBackend::relaxInstruction(MCInst &Inst,
62 const MCSubtargetInfo &STI) const {
63 MCInst Res;
64 unsigned RelaxedOpcode = AMDGPU::getSOPPWithRelaxation(Inst.getOpcode());
65 Res.setOpcode(RelaxedOpcode);
66 Res.addOperand(Inst.getOperand(0));
67 Inst = std::move(Res);
68}
69
70bool AMDGPUAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
71 uint64_t Value) const {
72 // if the branch target has an offset of x3f this needs to be relaxed to
73 // add a s_nop 0 immediately after branch to effectively increment offset
74 // for hardware workaround in gfx1010
75 return (((int64_t(Value)/4)-1) == 0x3f);
76}
77
78bool AMDGPUAsmBackend::mayNeedRelaxation(const MCInst &Inst,
79 const MCSubtargetInfo &STI) const {
80 if (!STI.hasFeature(AMDGPU::FeatureOffset3fBug))
81 return false;
82
84 return true;
85
86 return false;
87}
88
89static unsigned getFixupKindNumBytes(unsigned Kind) {
90 switch (Kind) {
92 return 2;
93 case FK_SecRel_1:
94 case FK_Data_1:
95 return 1;
96 case FK_SecRel_2:
97 case FK_Data_2:
98 return 2;
99 case FK_SecRel_4:
100 case FK_Data_4:
101 case FK_PCRel_4:
102 return 4;
103 case FK_SecRel_8:
104 case FK_Data_8:
105 return 8;
106 default:
107 llvm_unreachable("Unknown fixup kind!");
108 }
109}
110
112 MCContext *Ctx) {
113 int64_t SignedValue = static_cast<int64_t>(Value);
114
115 switch (Fixup.getTargetKind()) {
117 int64_t BrImm = (SignedValue - 4) / 4;
118
119 if (Ctx && !isInt<16>(BrImm))
120 Ctx->reportError(Fixup.getLoc(), "branch size exceeds simm16");
121
122 return BrImm;
123 }
124 case FK_Data_1:
125 case FK_Data_2:
126 case FK_Data_4:
127 case FK_Data_8:
128 case FK_PCRel_4:
129 case FK_SecRel_4:
130 return Value;
131 default:
132 llvm_unreachable("unhandled fixup kind");
133 }
134}
135
136void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
137 const MCValue &Target,
139 bool IsResolved,
140 const MCSubtargetInfo *STI) const {
141 if (Fixup.getKind() >= FirstLiteralRelocationKind)
142 return;
143
144 Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
145 if (!Value)
146 return; // Doesn't change encoding.
147
148 MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
149
150 // Shift the value into position.
151 Value <<= Info.TargetOffset;
152
153 unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
154 uint32_t Offset = Fixup.getOffset();
155 assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
156
157 // For each byte of the fragment that the fixup touches, mask in the bits from
158 // the fixup value.
159 for (unsigned i = 0; i != NumBytes; ++i)
160 Data[Offset + i] |= static_cast<uint8_t>((Value >> (i * 8)) & 0xff);
161}
162
163std::optional<MCFixupKind>
164AMDGPUAsmBackend::getFixupKind(StringRef Name) const {
166#define ELF_RELOC(Name, Value) \
168#include "llvm/BinaryFormat/ELFRelocs/AMDGPU.def"
169#undef ELF_RELOC
170 .Default(std::nullopt);
171}
172
173const MCFixupKindInfo &AMDGPUAsmBackend::getFixupKindInfo(
174 MCFixupKind Kind) const {
175 const static MCFixupKindInfo Infos[AMDGPU::NumTargetFixupKinds] = {
176 // name offset bits flags
177 { "fixup_si_sopp_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
178 };
179
180 if (Kind >= FirstLiteralRelocationKind)
182
183 if (Kind < FirstTargetFixupKind)
185
186 assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
187 "Invalid kind!");
188 return Infos[Kind - FirstTargetFixupKind];
189}
190
191bool AMDGPUAsmBackend::shouldForceRelocation(const MCAssembler &,
192 const MCFixup &Fixup,
193 const MCValue &,
194 const MCSubtargetInfo *STI) {
195 return Fixup.getKind() >= FirstLiteralRelocationKind;
196}
197
198unsigned AMDGPUAsmBackend::getMinimumNopSize() const {
199 return 4;
200}
201
202bool AMDGPUAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
203 const MCSubtargetInfo *STI) const {
204 // If the count is not 4-byte aligned, we must be writing data into the text
205 // section (otherwise we have unaligned instructions, and thus have far
206 // bigger problems), so just write zeros instead.
207 OS.write_zeros(Count % 4);
208
209 // We are properly aligned, so write NOPs as requested.
210 Count /= 4;
211
212 // FIXME: R600 support.
213 // s_nop 0
214 const uint32_t Encoded_S_NOP_0 = 0xbf800000;
215
216 for (uint64_t I = 0; I != Count; ++I)
217 support::endian::write<uint32_t>(OS, Encoded_S_NOP_0, Endian);
218
219 return true;
220}
221
222//===----------------------------------------------------------------------===//
223// ELFAMDGPUAsmBackend class
224//===----------------------------------------------------------------------===//
225
226namespace {
227
228class ELFAMDGPUAsmBackend : public AMDGPUAsmBackend {
229 bool Is64Bit;
230 bool HasRelocationAddend;
231 uint8_t OSABI = ELF::ELFOSABI_NONE;
232
233public:
234 ELFAMDGPUAsmBackend(const Target &T, const Triple &TT)
235 : AMDGPUAsmBackend(T), Is64Bit(TT.getArch() == Triple::amdgcn),
236 HasRelocationAddend(TT.getOS() == Triple::AMDHSA) {
237 switch (TT.getOS()) {
238 case Triple::AMDHSA:
240 break;
241 case Triple::AMDPAL:
243 break;
244 case Triple::Mesa3D:
246 break;
247 default:
248 break;
249 }
250 }
251
252 std::unique_ptr<MCObjectTargetWriter>
253 createObjectTargetWriter() const override {
254 return createAMDGPUELFObjectWriter(Is64Bit, OSABI, HasRelocationAddend);
255 }
256};
257
258} // end anonymous namespace
259
261 const MCSubtargetInfo &STI,
262 const MCRegisterInfo &MRI,
263 const MCTargetOptions &Options) {
264 return new ELFAMDGPUAsmBackend(T, STI.getTargetTriple());
265}
unsigned const MachineRegisterInfo * MRI
#define ELF_RELOC(Name, Value)
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext *Ctx)
static unsigned getFixupKindNumBytes(unsigned Kind)
Provides AMDGPU specific target descriptions.
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
@ Default
Definition: DwarfDebug.cpp:87
std::string Name
static LVOptions Options
Definition: LVOptions.cpp:25
#define I(x, y, z)
Definition: MD5.cpp:58
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:42
virtual unsigned getMinimumNopSize() const
Returns the minimum size of a nop in bytes on this target.
Definition: MCAsmBackend.h:205
virtual bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const =0
Write an (optimal) nop sequence of Count bytes to the given output.
virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const
Relax the instruction in the given fragment to the next wider instruction.
Definition: MCAsmBackend.h:177
virtual bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const
Check whether the given instruction may need relaxation.
Definition: MCAsmBackend.h:153
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value) const
Simple predicate for targets where !Resolved implies requiring relaxation.
Definition: MCAsmBackend.h:167
virtual bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, const MCSubtargetInfo *STI)
Hook to check if a relocation is needed for some target specific reason.
Definition: MCAsmBackend.h:94
virtual unsigned getNumFixupKinds() const =0
Get the number of target specific fixup kinds.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
virtual std::optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const =0
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
Context object for machine code objects.
Definition: MCContext.h:83
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1069
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
unsigned getOpcode() const
Definition: MCInst.h:198
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
This represents an "assembler immediate".
Definition: MCValue.h:36
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_si_sopp_br
16-bit PC relative fixup for SOPP branch instructions.
LLVM_READONLY int getSOPPWithRelaxation(uint16_t Opcode)
@ ELFOSABI_AMDGPU_HSA
Definition: ELF.h:362
@ ELFOSABI_AMDGPU_MESA3D
Definition: ELF.h:364
@ ELFOSABI_NONE
Definition: ELF.h:342
@ ELFOSABI_AMDGPU_PAL
Definition: ELF.h:363
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MCAsmBackend * createAMDGPUAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
std::unique_ptr< MCObjectTargetWriter > createAMDGPUELFObjectWriter(bool Is64Bit, uint8_t OSABI, bool HasRelocationAddend)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
@ FirstTargetFixupKind
Definition: MCFixup.h:45
@ FK_PCRel_4
A four-byte pc relative fixup.
Definition: MCFixup.h:30
@ FK_SecRel_2
A two-byte section relative fixup.
Definition: MCFixup.h:41
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:26
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
@ FK_SecRel_8
A eight-byte section relative fixup.
Definition: MCFixup.h:43
@ FK_NONE
A no-op fixup.
Definition: MCFixup.h:22
@ FK_SecRel_4
A four-byte section relative fixup.
Definition: MCFixup.h:42
@ FK_SecRel_1
A one-byte section relative fixup.
Definition: MCFixup.h:40
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24
endianness
Definition: bit.h:70
Target independent information on a fixup kind.
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...