LLVM  14.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"
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;
47  return Value & 0xfffc;
50  return Value & 0x3ffffffff;
51  }
52 }
53 
54 static unsigned getFixupKindNumBytes(unsigned Kind) {
55  switch (Kind) {
56  default:
57  llvm_unreachable("Unknown fixup kind!");
58  case FK_Data_1:
59  return 1;
60  case FK_Data_2:
63  return 2;
64  case FK_Data_4:
70  return 4;
73  case FK_Data_8:
74  return 8;
76  return 0;
77  }
78 }
79 
80 namespace {
81 
82 class PPCAsmBackend : public MCAsmBackend {
83 protected:
84  Triple TT;
85 public:
86  PPCAsmBackend(const Target &T, const Triple &TT)
87  : MCAsmBackend(TT.isLittleEndian() ? support::little : support::big),
88  TT(TT) {}
89 
90  unsigned getNumFixupKinds() const override {
92  }
93 
94  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
95  const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = {
96  // name offset bits flags
97  { "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
98  { "fixup_ppc_br24_notoc", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
99  { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
100  { "fixup_ppc_br24abs", 6, 24, 0 },
101  { "fixup_ppc_brcond14abs", 16, 14, 0 },
102  { "fixup_ppc_half16", 0, 16, 0 },
103  { "fixup_ppc_half16ds", 0, 14, 0 },
104  { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
105  { "fixup_ppc_imm34", 0, 34, 0 },
106  { "fixup_ppc_nofixup", 0, 0, 0 }
107  };
108  const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
109  // name offset bits flags
110  { "fixup_ppc_br24", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
111  { "fixup_ppc_br24_notoc", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
112  { "fixup_ppc_brcond14", 2, 14, MCFixupKindInfo::FKF_IsPCRel },
113  { "fixup_ppc_br24abs", 2, 24, 0 },
114  { "fixup_ppc_brcond14abs", 2, 14, 0 },
115  { "fixup_ppc_half16", 0, 16, 0 },
116  { "fixup_ppc_half16ds", 2, 14, 0 },
117  { "fixup_ppc_pcrel34", 0, 34, MCFixupKindInfo::FKF_IsPCRel },
118  { "fixup_ppc_imm34", 0, 34, 0 },
119  { "fixup_ppc_nofixup", 0, 0, 0 }
120  };
121 
122  // Fixup kinds from .reloc directive are like R_PPC_NONE/R_PPC64_NONE. They
123  // do not require any extra processing.
126 
129 
130  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
131  "Invalid kind!");
132  return (Endian == support::little
133  ? InfosLE
134  : InfosBE)[Kind - FirstTargetFixupKind];
135  }
136 
137  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
139  uint64_t Value, bool IsResolved,
140  const MCSubtargetInfo *STI) const override {
141  MCFixupKind Kind = Fixup.getKind();
143  return;
145  if (!Value) return; // Doesn't change encoding.
146 
147  unsigned Offset = Fixup.getOffset();
148  unsigned NumBytes = getFixupKindNumBytes(Kind);
149 
150  // For each byte of the fragment that the fixup touches, mask in the bits
151  // from the fixup value. The Value has been "split up" into the appropriate
152  // bitfields above.
153  for (unsigned i = 0; i != NumBytes; ++i) {
154  unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i);
155  Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff);
156  }
157  }
158 
159  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
160  const MCValue &Target) override {
161  MCFixupKind Kind = Fixup.getKind();
162  switch ((unsigned)Kind) {
163  default:
165  case PPC::fixup_ppc_br24:
168  // If the target symbol has a local entry point we must not attempt
169  // to resolve the fixup directly. Emit a relocation and leave
170  // resolution of the final target address to the linker.
171  if (const MCSymbolRefExpr *A = Target.getSymA()) {
172  if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) {
173  // The "other" values are stored in the last 6 bits of the second
174  // byte. The traditional defines for STO values assume the full byte
175  // and thus the shift to pack it.
176  unsigned Other = S->getOther() << 2;
177  if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0)
178  return true;
179  }
180  }
181  return false;
182  }
183  }
184 
185  bool fixupNeedsRelaxation(const MCFixup &Fixup,
186  uint64_t Value,
187  const MCRelaxableFragment *DF,
188  const MCAsmLayout &Layout) const override {
189  // FIXME.
190  llvm_unreachable("relaxInstruction() unimplemented");
191  }
192 
193  void relaxInstruction(MCInst &Inst,
194  const MCSubtargetInfo &STI) const override {
195  // FIXME.
196  llvm_unreachable("relaxInstruction() unimplemented");
197  }
198 
199  bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
200  uint64_t NumNops = Count / 4;
201  for (uint64_t i = 0; i != NumNops; ++i)
202  support::endian::write<uint32_t>(OS, 0x60000000, Endian);
203 
204  OS.write_zeros(Count % 4);
205 
206  return true;
207  }
208 };
209 } // end anonymous namespace
210 
211 
212 // FIXME: This should be in a separate file.
213 namespace {
214 
215 class ELFPPCAsmBackend : public PPCAsmBackend {
216 public:
217  ELFPPCAsmBackend(const Target &T, const Triple &TT) : PPCAsmBackend(T, TT) {}
218 
219  std::unique_ptr<MCObjectTargetWriter>
220  createObjectTargetWriter() const override {
221  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
222  bool Is64 = TT.isPPC64();
223  return createPPCELFObjectWriter(Is64, OSABI);
224  }
225 
226  Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
227 };
228 
229 class XCOFFPPCAsmBackend : public PPCAsmBackend {
230 public:
231  XCOFFPPCAsmBackend(const Target &T, const Triple &TT)
232  : PPCAsmBackend(T, TT) {}
233 
234  std::unique_ptr<MCObjectTargetWriter>
235  createObjectTargetWriter() const override {
236  return createPPCXCOFFObjectWriter(TT.isArch64Bit());
237  }
238 };
239 
240 } // end anonymous namespace
241 
242 Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
243  if (TT.isOSBinFormatELF()) {
244  unsigned Type;
245  if (TT.isPPC64()) {
247 #define ELF_RELOC(X, Y) .Case(#X, Y)
248 #include "llvm/BinaryFormat/ELFRelocs/PowerPC64.def"
249 #undef ELF_RELOC
250  .Case("BFD_RELOC_NONE", ELF::R_PPC64_NONE)
251  .Case("BFD_RELOC_16", ELF::R_PPC64_ADDR16)
252  .Case("BFD_RELOC_32", ELF::R_PPC64_ADDR32)
253  .Case("BFD_RELOC_64", ELF::R_PPC64_ADDR64)
254  .Default(-1u);
255  } else {
257 #define ELF_RELOC(X, Y) .Case(#X, Y)
258 #include "llvm/BinaryFormat/ELFRelocs/PowerPC.def"
259 #undef ELF_RELOC
260  .Case("BFD_RELOC_NONE", ELF::R_PPC_NONE)
261  .Case("BFD_RELOC_16", ELF::R_PPC_ADDR16)
262  .Case("BFD_RELOC_32", ELF::R_PPC_ADDR32)
263  .Default(-1u);
264  }
265  if (Type != -1u)
266  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
267  }
268  return None;
269 }
270 
272  const MCSubtargetInfo &STI,
273  const MCRegisterInfo &MRI,
274  const MCTargetOptions &Options) {
275  const Triple &TT = STI.getTargetTriple();
276  if (TT.isOSBinFormatXCOFF())
277  return new XCOFFPPCAsmBackend(T, TT);
278 
279  return new ELFPPCAsmBackend(T, TT);
280 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
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
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCRelaxableFragment
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:271
llvm::ARM::PredBlockMask::TT
@ TT
llvm::MCAsmBackend::getFixupKindInfo
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Definition: MCAsmBackend.cpp:74
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:502
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::FirstTargetFixupKind
@ FirstTargetFixupKind
Definition: MCFixup.h:45
ErrorHandling.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
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
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
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:56
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:36
ELF.h
MCAsmBackend.h
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:307
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:107
MCSymbolELF.h
MCSectionMachO.h
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::ELF::STO_PPC64_LOCAL_MASK
@ STO_PPC64_LOCAL_MASK
Definition: ELF.h:408
llvm::PPC::NumTargetFixupKinds
@ NumTargetFixupKinds
Definition: PPCFixupKinds.h:56
MCMachObjectWriter.h
llvm::createPPCXCOFFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createPPCXCOFFObjectWriter(bool Is64Bit)
Construct a PPC XCOFF object writer.
Definition: PPCXCOFFObjectWriter.cpp:37
llvm::None
const NoneType None
Definition: None.h:23
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:60
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:486
llvm::FK_Data_1
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
llvm::MCTargetOptions
Definition: MCTargetOptions.h:36
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:99
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:235
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
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:54
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
MCObjectWriter.h
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
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:271
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
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:37
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:75
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:75
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:1172