LLVM  16.0.0git
PPCAsmBackend.cpp
Go to the documentation of this file.
1 //===-- PPCAsmBackend.cpp - PPC 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 
11 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/MC/MCAsmBackend.h"
14 #include "llvm/MC/MCAssembler.h"
18 #include "llvm/MC/MCObjectWriter.h"
19 #include "llvm/MC/MCSectionMachO.h"
21 #include "llvm/MC/MCSymbolELF.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/MC/TargetRegistry.h"
25 using namespace llvm;
26 
27 static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
28  switch (Kind) {
29  default:
30  llvm_unreachable("Unknown fixup kind!");
31  case FK_Data_1:
32  case FK_Data_2:
33  case FK_Data_4:
34  case FK_Data_8:
36  return Value;
39  return Value & 0xfffc;
43  return Value & 0x3fffffc;
45  return Value & 0xffff;
48  return Value & 0xfffc;
51  return Value & 0x3ffffffff;
52  }
53 }
54 
55 static unsigned getFixupKindNumBytes(unsigned Kind) {
56  switch (Kind) {
57  default:
58  llvm_unreachable("Unknown fixup kind!");
59  case FK_Data_1:
60  return 1;
61  case FK_Data_2:
65  return 2;
66  case FK_Data_4:
72  return 4;
75  case FK_Data_8:
76  return 8;
78  return 0;
79  }
80 }
81 
82 namespace {
83 
84 class PPCAsmBackend : public MCAsmBackend {
85 protected:
86  Triple TT;
87 public:
88  PPCAsmBackend(const Target &T, const Triple &TT)
89  : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big),
90  TT(TT) {}
91 
92  unsigned getNumFixupKinds() const override {
94  }
95 
96  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
97  const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = {
98  // name offset bits flags
99  { "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
100  { "fixup_ppc_br24_notoc", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
101  { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
102  { "fixup_ppc_br24abs", 6, 24, 0 },
103  { "fixup_ppc_brcond14abs", 16, 14, 0 },
104  { "fixup_ppc_half16", 0, 16, 0 },
105  { "fixup_ppc_half16ds", 0, 14, 0 },
106  { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
107  { "fixup_ppc_imm34", 0, 34, 0 },
108  { "fixup_ppc_nofixup", 0, 0, 0 }
109  };
110  const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
111  // name offset bits flags
112  { "fixup_ppc_br24", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
113  { "fixup_ppc_br24_notoc", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
114  { "fixup_ppc_brcond14", 2, 14, MCFixupKindInfo::FKF_IsPCRel },
115  { "fixup_ppc_br24abs", 2, 24, 0 },
116  { "fixup_ppc_brcond14abs", 2, 14, 0 },
117  { "fixup_ppc_half16", 0, 16, 0 },
118  { "fixup_ppc_half16ds", 2, 14, 0 },
119  { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
120  { "fixup_ppc_imm34", 0, 34, 0 },
121  { "fixup_ppc_nofixup", 0, 0, 0 }
122  };
123 
124  // Fixup kinds from .reloc directive are like R_PPC_NONE/R_PPC64_NONE. They
125  // do not require any extra processing.
126  if (Kind >= FirstLiteralRelocationKind)
128 
129  if (Kind < FirstTargetFixupKind)
130  return MCAsmBackend::getFixupKindInfo(Kind);
131 
132  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
133  "Invalid kind!");
134  return (Endian == support::little
135  ? InfosLE
136  : InfosBE)[Kind - FirstTargetFixupKind];
137  }
138 
139  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
141  uint64_t Value, bool IsResolved,
142  const MCSubtargetInfo *STI) const override {
143  MCFixupKind Kind = Fixup.getKind();
144  if (Kind >= FirstLiteralRelocationKind)
145  return;
146  Value = adjustFixupValue(Kind, Value);
147  if (!Value) return; // Doesn't change encoding.
148 
149  unsigned Offset = Fixup.getOffset();
150  unsigned NumBytes = getFixupKindNumBytes(Kind);
151 
152  // For each byte of the fragment that the fixup touches, mask in the bits
153  // from the fixup value. The Value has been "split up" into the appropriate
154  // bitfields above.
155  for (unsigned i = 0; i != NumBytes; ++i) {
156  unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i);
157  Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff);
158  }
159  }
160 
161  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
162  const MCValue &Target) override {
163  MCFixupKind Kind = Fixup.getKind();
164  switch ((unsigned)Kind) {
165  default:
167  case PPC::fixup_ppc_br24:
170  // If the target symbol has a local entry point we must not attempt
171  // to resolve the fixup directly. Emit a relocation and leave
172  // resolution of the final target address to the linker.
173  if (const MCSymbolRefExpr *A = Target.getSymA()) {
174  if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) {
175  // The "other" values are stored in the last 6 bits of the second
176  // byte. The traditional defines for STO values assume the full byte
177  // and thus the shift to pack it.
178  unsigned Other = S->getOther() << 2;
179  if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0)
180  return true;
181  }
182  }
183  return false;
184  }
185  }
186 
187  bool fixupNeedsRelaxation(const MCFixup &Fixup,
188  uint64_t Value,
189  const MCRelaxableFragment *DF,
190  const MCAsmLayout &Layout) const override {
191  // FIXME.
192  llvm_unreachable("relaxInstruction() unimplemented");
193  }
194 
195  void relaxInstruction(MCInst &Inst,
196  const MCSubtargetInfo &STI) const override {
197  // FIXME.
198  llvm_unreachable("relaxInstruction() unimplemented");
199  }
200 
201  bool writeNopData(raw_ostream &OS, uint64_t Count,
202  const MCSubtargetInfo *STI) const override {
203  uint64_t NumNops = Count / 4;
204  for (uint64_t i = 0; i != NumNops; ++i)
205  support::endian::write<uint32_t>(OS, 0x60000000, Endian);
206 
207  OS.write_zeros(Count % 4);
208 
209  return true;
210  }
211 };
212 } // end anonymous namespace
213 
214 
215 // FIXME: This should be in a separate file.
216 namespace {
217 
218 class ELFPPCAsmBackend : public PPCAsmBackend {
219 public:
220  ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {}
221 
222  std::unique_ptr<MCObjectTargetWriter>
223  createObjectTargetWriter() const override {
224  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
225  bool Is64 = TT.isPPC64();
226  return createPPCELFObjectWriter(Is64, OSABI);
227  }
228 
229  Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
230 };
231 
232 class XCOFFPPCAsmBackend : public PPCAsmBackend {
233 public:
234  XCOFFPPCAsmBackend(const Target &T, const Triple &TT)
235  : PPCAsmBackend(T, TT) {}
236 
237  std::unique_ptr<MCObjectTargetWriter>
238  createObjectTargetWriter() const override {
239  return createPPCXCOFFObjectWriter(TT.isArch64Bit());
240  }
241 };
242 
243 } // end anonymous namespace
244 
245 Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
246  if (TT.isOSBinFormatELF()) {
247  unsigned Type;
248  if (TT.isPPC64()) {
250 #define ELF_RELOC(X, Y) .Case(#X, Y)
251 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
252 #undef ELF_RELOC
253  .Case("BFD_RELOC_NONE", ELF::R_PPC64_NONE)
254  .Case("BFD_RELOC_16", ELF::R_PPC64_ADDR16)
255  .Case("BFD_RELOC_32", ELF::R_PPC64_ADDR32)
256  .Case("BFD_RELOC_64", ELF::R_PPC64_ADDR64)
257  .Default(-1u);
258  } else {
260 #define ELF_RELOC(X, Y) .Case(#X, Y)
261 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
262 #undef ELF_RELOC
263  .Case("BFD_RELOC_NONE", ELF::R_PPC_NONE)
264  .Case("BFD_RELOC_16", ELF::R_PPC_ADDR16)
265  .Case("BFD_RELOC_32", ELF::R_PPC_ADDR32)
266  .Default(-1u);
267  }
268  if (Type != -1u)
269  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
270  }
271  return None;
272 }
273 
275  const MCSubtargetInfo &STI,
276  const MCRegisterInfo &MRI,
277  const MCTargetOptions &Options) {
278  const Triple &TT = STI.getTargetTriple();
279  if (TT.isOSBinFormatXCOFF())
280  return new XCOFFPPCAsmBackend(T, TT);
281 
282  return new ELFPPCAsmBackend(T, TT);
283 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
i
i
Definition: README.txt:29
llvm::PPC::fixup_ppc_brcond14
@ fixup_ppc_brcond14
14-bit PC relative relocation for conditional branches.
Definition: PPCFixupKinds.h:27
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::MCRelaxableFragment
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:270
llvm::ARM::PredBlockMask::TT
@ TT
llvm::MCAsmBackend::getFixupKindInfo
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Definition: MCAsmBackend.cpp:81
llvm::PPC::fixup_ppc_br24_notoc
@ fixup_ppc_br24_notoc
Definition: PPCFixupKinds.h:24
llvm::PPC::fixup_ppc_nofixup
@ fixup_ppc_nofixup
Not a true fixup, but ties a symbol to a call to __tls_get_addr for the TLS general and local dynamic...
Definition: PPCFixupKinds.h:52
llvm::raw_ostream::write_zeros
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
Definition: raw_ostream.cpp:499
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::FirstTargetFixupKind
@ FirstTargetFixupKind
Definition: MCFixup.h:45
ErrorHandling.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
MCAssembler.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::Optional
Definition: APInt.h:33
MCFixupKindInfo.h
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
PPCMCTargetDesc.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
llvm::FK_Data_4
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
llvm::MCAsmBackend
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:42
ELF.h
MCAsmBackend.h
llvm::MutableArrayRef< char >
llvm::support::little
@ little
Definition: Endian.h:27
llvm::ARM_PROC::A
@ A
Definition: ARMBaseInfo.h:34
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:108
MCSymbolELF.h
MCSectionMachO.h
llvm::PPC::fixup_ppc_half16dq
@ fixup_ppc_half16dq
A 16-bit fixup corresponding to lo16(_foo) with implied 3 zero bits for instrs like 'lxv'.
Definition: PPCFixupKinds.h:56
MCSubtargetInfo.h
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::PPC::NumTargetFixupKinds
@ NumTargetFixupKinds
Definition: PPCFixupKinds.h:60
MCMachObjectWriter.h
llvm::createPPCXCOFFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createPPCXCOFFObjectWriter(bool Is64Bit)
Construct a PPC XCOFF object writer.
Definition: PPCXCOFFObjectWriter.cpp:37
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::PPC::fixup_ppc_half16
@ fixup_ppc_half16
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like 'li' or 'addis'.
Definition: PPCFixupKinds.h:37
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::PPC::fixup_ppc_brcond14abs
@ fixup_ppc_brcond14abs
14-bit absolute relocation for conditional branches.
Definition: PPCFixupKinds.h:33
llvm::MCAssembler
Definition: MCAssembler.h:73
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:416
uint64_t
MCELFObjectWriter.h
llvm::MCFixupKindInfo::FKF_IsPCRel
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
Definition: MCFixupKindInfo.h:19
PPCFixupKinds.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCFixupKindInfo
Target independent information on a fixup kind.
Definition: MCFixupKindInfo.h:15
llvm::createPPCELFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
Construct an PPC ELF object writer.
Definition: PPCELFObjectWriter.cpp:488
llvm::FK_Data_1
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
llvm::MCTargetOptions
Definition: MCTargetOptions.h:37
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
adjustFixupValue
static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value)
Definition: PPCAsmBackend.cpp:27
llvm::FK_NONE
@ FK_NONE
A no-op fixup.
Definition: MCFixup.h:22
llvm::MCELFObjectTargetWriter::getOSABI
uint8_t getOSABI() const
Definition: MCELFObjectWriter.h:101
llvm::PPC::fixup_ppc_half16ds
@ fixup_ppc_half16ds
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like 'std'.
Definition: PPCFixupKinds.h:41
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:215
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::PPC::fixup_ppc_imm34
@ fixup_ppc_imm34
Definition: PPCFixupKinds.h:47
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
getFixupKindNumBytes
static unsigned getFixupKindNumBytes(unsigned Kind)
Definition: PPCAsmBackend.cpp:55
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::ELF::STO_PPC64_LOCAL_MASK
@ STO_PPC64_LOCAL_MASK
Definition: ELF.h:409
MCObjectWriter.h
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
llvm::MCAsmLayout
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
llvm::PPC::fixup_ppc_pcrel34
@ fixup_ppc_pcrel34
Definition: PPCFixupKinds.h:44
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::PPC::fixup_ppc_br24abs
@ fixup_ppc_br24abs
24-bit absolute relocation for direct branches like 'ba' and 'bla'.
Definition: PPCFixupKinds.h:30
MCValue.h
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::FK_Data_8
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:26
llvm::createPPCAsmBackend
MCAsmBackend * createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition: PPCAsmBackend.cpp:274
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::StringSwitch::Default
R Default(T Value)
Definition: StringSwitch.h:183
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:45
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:36
MachO.h
llvm::FK_Data_2
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24
TargetRegistry.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::PPC::fixup_ppc_br24
@ fixup_ppc_br24
Definition: PPCFixupKinds.h:20
llvm::support::big
@ big
Definition: Endian.h:27
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1251