LLVM  10.0.0svn
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_NONE:
32  case FK_Data_1:
33  case FK_Data_2:
34  case FK_Data_4:
35  case FK_Data_8:
37  return Value;
40  return Value & 0xfffc;
43  return Value & 0x3fffffc;
45  return Value & 0xffff;
47  return Value & 0xfffc;
48  }
49 }
50 
51 static unsigned getFixupKindNumBytes(unsigned Kind) {
52  switch (Kind) {
53  default:
54  llvm_unreachable("Unknown fixup kind!");
55  case FK_NONE:
56  return 0;
57  case FK_Data_1:
58  return 1;
59  case FK_Data_2:
62  return 2;
63  case FK_Data_4:
68  return 4;
69  case FK_Data_8:
70  return 8;
72  return 0;
73  }
74 }
75 
76 namespace {
77 
78 class PPCAsmBackend : public MCAsmBackend {
79 protected:
80  Triple TT;
81 public:
82  PPCAsmBackend(const Target &T, const Triple &TT)
84  TT(TT) {}
85 
86  unsigned getNumFixupKinds() const override {
88  }
89 
90  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
91  const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = {
92  // name offset bits flags
93  { "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
94  { "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
95  { "fixup_ppc_br24abs", 6, 24, 0 },
96  { "fixup_ppc_brcond14abs", 16, 14, 0 },
97  { "fixup_ppc_half16", 0, 16, 0 },
98  { "fixup_ppc_half16ds", 0, 14, 0 },
99  { "fixup_ppc_nofixup", 0, 0, 0 }
100  };
101  const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
102  // name offset bits flags
103  { "fixup_ppc_br24", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
104  { "fixup_ppc_brcond14", 2, 14, MCFixupKindInfo::FKF_IsPCRel },
105  { "fixup_ppc_br24abs", 2, 24, 0 },
106  { "fixup_ppc_brcond14abs", 2, 14, 0 },
107  { "fixup_ppc_half16", 0, 16, 0 },
108  { "fixup_ppc_half16ds", 2, 14, 0 },
109  { "fixup_ppc_nofixup", 0, 0, 0 }
110  };
111 
112  if (Kind < FirstTargetFixupKind)
113  return MCAsmBackend::getFixupKindInfo(Kind);
114 
115  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
116  "Invalid kind!");
117  return (Endian == support::little
118  ? InfosLE
119  : InfosBE)[Kind - FirstTargetFixupKind];
120  }
121 
122  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
124  uint64_t Value, bool IsResolved,
125  const MCSubtargetInfo *STI) const override {
126  Value = adjustFixupValue(Fixup.getKind(), Value);
127  if (!Value) return; // Doesn't change encoding.
128 
129  unsigned Offset = Fixup.getOffset();
130  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
131 
132  // For each byte of the fragment that the fixup touches, mask in the bits
133  // from the fixup value. The Value has been "split up" into the appropriate
134  // bitfields above.
135  for (unsigned i = 0; i != NumBytes; ++i) {
136  unsigned Idx = Endian == support::little ? i : (NumBytes - 1 - i);
137  Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff);
138  }
139  }
140 
141  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
142  const MCValue &Target) override {
143  switch ((unsigned)Fixup.getKind()) {
144  default:
145  return false;
146  case FK_NONE:
147  return true;
148  case PPC::fixup_ppc_br24:
150  // If the target symbol has a local entry point we must not attempt
151  // to resolve the fixup directly. Emit a relocation and leave
152  // resolution of the final target address to the linker.
153  if (const MCSymbolRefExpr *A = Target.getSymA()) {
154  if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) {
155  // The "other" values are stored in the last 6 bits of the second
156  // byte. The traditional defines for STO values assume the full byte
157  // and thus the shift to pack it.
158  unsigned Other = S->getOther() << 2;
159  if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0)
160  return true;
161  }
162  }
163  return false;
164  }
165  }
166 
167  bool mayNeedRelaxation(const MCInst &Inst,
168  const MCSubtargetInfo &STI) const override {
169  // FIXME.
170  return false;
171  }
172 
173  bool fixupNeedsRelaxation(const MCFixup &Fixup,
174  uint64_t Value,
175  const MCRelaxableFragment *DF,
176  const MCAsmLayout &Layout) const override {
177  // FIXME.
178  llvm_unreachable("relaxInstruction() unimplemented");
179  }
180 
181  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
182  MCInst &Res) const override {
183  // FIXME.
184  llvm_unreachable("relaxInstruction() unimplemented");
185  }
186 
187  bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
188  uint64_t NumNops = Count / 4;
189  for (uint64_t i = 0; i != NumNops; ++i)
190  support::endian::write<uint32_t>(OS, 0x60000000, Endian);
191 
192  OS.write_zeros(Count % 4);
193 
194  return true;
195  }
196 };
197 } // end anonymous namespace
198 
199 
200 // FIXME: This should be in a separate file.
201 namespace {
202 
203 class DarwinPPCAsmBackend : public PPCAsmBackend {
204 public:
205  DarwinPPCAsmBackend(const Target &T, const Triple &TT)
206  : PPCAsmBackend(T, TT) {}
207 
208  std::unique_ptr<MCObjectTargetWriter>
209  createObjectTargetWriter() const override {
210  bool Is64 = TT.isPPC64();
212  /*Is64Bit=*/Is64,
215  }
216 };
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 {
240  }
241 };
242 
243 } // end anonymous namespace
244 
245 Optional<MCFixupKind> ELFPPCAsmBackend::getFixupKind(StringRef Name) const {
246  if (TT.isPPC64()) {
247  if (Name == "R_PPC64_NONE")
248  return FK_NONE;
249  } else {
250  if (Name == "R_PPC_NONE")
251  return FK_NONE;
252  }
253  return MCAsmBackend::getFixupKind(Name);
254 }
255 
257  const MCSubtargetInfo &STI,
258  const MCRegisterInfo &MRI,
259  const MCTargetOptions &Options) {
260  const Triple &TT = STI.getTargetTriple();
261  if (TT.isOSDarwin())
262  return new DarwinPPCAsmBackend(T, TT);
263 
264  if (TT.isOSBinFormatXCOFF())
265  return new XCOFFPPCAsmBackend(T, TT);
266 
267  return new ELFPPCAsmBackend(T, TT);
268 }
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
Definition: Triple.h:481
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:39
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:305
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert &#39;NumZeros&#39; nulls.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:952
14-bit absolute relocation for conditional branches.
Definition: PPCFixupKinds.h:29
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:77
const Triple & getTargetTriple() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like &#39;li&#39; or &#39;addis&#39;.
Definition: PPCFixupKinds.h:33
std::unique_ptr< MCObjectTargetWriter > createPPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct a PPC Mach-O object writer.
24-bit absolute relocation for direct branches like &#39;ba&#39; and &#39;bla&#39;.
Definition: PPCFixupKinds.h:26
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
std::unique_ptr< MCObjectTargetWriter > createPPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
Construct an PPC ELF object writer.
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:42
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
A four-byte fixup.
Definition: MCFixup.h:26
static unsigned getFixupKindNumBytes(unsigned Kind)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:272
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:290
bool isLittleEndian() const
Tests whether the target triple is little endian.
Definition: Triple.cpp:1518
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:47
MCAsmBackend * createPPCAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
uint32_t getOffset() const
Definition: MCFixup.h:130
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Definition: Triple.h:724
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A one-byte fixup.
Definition: MCFixup.h:24
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
PowerPC TLS Dynamic Call Fixup
A no-op fixup.
Definition: MCFixup.h:23
virtual Optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
Target - Wrapper for Target specific information.
bool isOSBinFormatXCOFF() const
Tests whether the OS uses the XCOFF binary format.
Definition: Triple.h:643
A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for instrs like &#39;std&#39;...
Definition: PPCFixupKinds.h:37
std::unique_ptr< MCObjectTargetWriter > createPPCXCOFFObjectWriter(bool Is64Bit)
Construct a PPC XCOFF object writer.
bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1292
Generic base class for all target subtargets.
A eight-byte fixup.
Definition: MCFixup.h:27
Target independent information on a fixup kind.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:41
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value)
14-bit PC relative relocation for conditional branches.
Definition: PPCFixupKinds.h:23
A two-byte fixup.
Definition: MCFixup.h:25
MCFixupKind getKind() const
Definition: MCFixup.h:126