LLVM  14.0.0git
PPCELFStreamer.cpp
Go to the documentation of this file.
1 //===-------- PPCELFStreamer.cpp - ELF Object Output ---------------------===//
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 //
9 // This is a custom MCELFStreamer for PowerPC.
10 //
11 // The purpose of the custom ELF streamer is to allow us to intercept
12 // instructions as they are being emitted and align all 8 byte instructions
13 // to a 64 byte boundary if required (by adding a 4 byte nop). This is important
14 // because 8 byte instructions are not allowed to cross 64 byte boundaries
15 // and by aliging anything that is within 4 bytes of the boundary we can
16 // guarantee that the 8 byte instructions do not cross that boundary.
17 //
18 //===----------------------------------------------------------------------===//
19 
20 
21 #include "PPCELFStreamer.h"
22 #include "PPCFixupKinds.h"
23 #include "PPCInstrInfo.h"
24 #include "PPCMCCodeEmitter.h"
25 #include "llvm/BinaryFormat/ELF.h"
26 #include "llvm/MC/MCAsmBackend.h"
27 #include "llvm/MC/MCAssembler.h"
28 #include "llvm/MC/MCCodeEmitter.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCInst.h"
31 #include "llvm/MC/MCInstrDesc.h"
32 #include "llvm/MC/MCObjectWriter.h"
33 #include "llvm/MC/MCSymbolELF.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/SourceMgr.h"
36 
37 using namespace llvm;
38 
40  std::unique_ptr<MCAsmBackend> MAB,
41  std::unique_ptr<MCObjectWriter> OW,
42  std::unique_ptr<MCCodeEmitter> Emitter)
43  : MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter)),
44  LastLabel(nullptr) {}
45 
46 void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst,
47  const MCSubtargetInfo &STI) {
48  // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is
49  // before the boundary and the remaining 4-bytes are after the boundary). In
50  // order to achieve this, a nop is added prior to any such boundary-crossing
51  // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4
52  // bytes when trying to do that. If alignment requires adding more than 4
53  // bytes then the instruction won't be aligned. When emitting a code alignment
54  // a new fragment is created for this alignment. This fragment will contain
55  // all of the nops required as part of the alignment operation. In the cases
56  // when no nops are added then The fragment is still created but it remains
57  // empty.
58  emitCodeAlignment(64, &STI, 4);
59 
60  // Emit the instruction.
61  // Since the previous emit created a new fragment then adding this instruction
62  // also forces the addition of a new fragment. Inst is now the first
63  // instruction in that new fragment.
65 
66  // The above instruction is forced to start a new fragment because it
67  // comes after a code alignment fragment. Get that new fragment.
68  MCFragment *InstructionFragment = getCurrentFragment();
69  SMLoc InstLoc = Inst.getLoc();
70  // Check if there was a last label emitted.
71  if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() &&
72  InstLoc.isValid()) {
73  const SourceMgr *SourceManager = getContext().getSourceManager();
74  unsigned InstLine = SourceManager->FindLineNumber(InstLoc);
75  unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc);
76  // If the Label and the Instruction are on the same line then move the
77  // label to the top of the fragment containing the aligned instruction that
78  // was just added.
79  if (InstLine == LabelLine) {
80  AssignFragment(LastLabel, InstructionFragment);
81  LastLabel->setOffset(0);
82  }
83  }
84 }
85 
87  const MCSubtargetInfo &STI) {
88  PPCMCCodeEmitter *Emitter =
89  static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr());
90 
91  // If the instruction is a part of the GOT to PC-Rel link time optimization
92  // instruction pair, return a value, otherwise return None. A true returned
93  // value means the instruction is the PLDpc and a false value means it is
94  // the user instruction.
95  Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI);
96 
97  // User of the GOT-indirect address.
98  // For example, the load that will get the relocation as follows:
99  // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
100  // lwa 3, 4(3)
101  if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue())
102  emitGOTToPCRelReloc(Inst);
103 
104  // Special handling is only for prefixed instructions.
105  if (!Emitter->isPrefixedInstruction(Inst)) {
107  return;
108  }
109  emitPrefixedInstruction(Inst, STI);
110 
111  // Producer of the GOT-indirect address.
112  // For example, the prefixed load from the got that will get the label as
113  // follows:
114  // pld 3, vec@got@pcrel(0), 1
115  // .Lpcrel1:
116  if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue())
117  emitGOTToPCRelLabel(Inst);
118 }
119 
121  LastLabel = Symbol;
122  LastLabelLoc = Loc;
124 }
125 
126 // This linker time GOT PC Relative optimization relocation will look like this:
127 // pld <reg> symbol@got@pcrel
128 // <Label###>:
129 // .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8)
130 // load <loadedreg>, 0(<reg>)
131 // The reason we place the label after the PLDpc instruction is that there
132 // may be an alignment nop before it since prefixed instructions must not
133 // cross a 64-byte boundary (please see
134 // PPCELFStreamer::emitPrefixedInstruction()). When referring to the
135 // label, we subtract the width of a prefixed instruction (8 bytes) to ensure
136 // we refer to the PLDpc.
137 void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
138  // Get the last operand which contains the symbol.
139  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
140  assert(Operand.isExpr() && "Expecting an MCExpr.");
141  // Cast the last operand to MCSymbolRefExpr to get the symbol.
142  const MCExpr *Expr = Operand.getExpr();
143  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
145  "Expecting a symbol of type VK_PPC_PCREL_OPT");
146  MCSymbol *LabelSym =
148  const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext());
149  const MCExpr *Eight = MCConstantExpr::create(8, getContext());
150  // SubExpr is just Label###-8
151  const MCExpr *SubExpr =
152  MCBinaryExpr::createSub(LabelExpr, Eight, getContext());
153  MCSymbol *CurrentLocation = getContext().createTempSymbol();
154  const MCExpr *CurrentLocationExpr =
155  MCSymbolRefExpr::create(CurrentLocation, getContext());
156  // SubExpr2 is .-(Label###-8)
157  const MCExpr *SubExpr2 =
158  MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext());
159 
160  MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment());
161  assert(DF && "Expecting a valid data fragment.");
163  ELF::R_PPC64_PCREL_OPT);
164  DF->getFixups().push_back(
165  MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
166  FixupKind, Inst.getLoc()));
167  emitLabel(CurrentLocation, Inst.getLoc());
168 }
169 
170 // Emit the label that immediately follows the PLDpc for a link time GOT PC Rel
171 // optimization.
172 void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) {
173  // Get the last operand which contains the symbol.
174  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
175  assert(Operand.isExpr() && "Expecting an MCExpr.");
176  // Cast the last operand to MCSymbolRefExpr to get the symbol.
177  const MCExpr *Expr = Operand.getExpr();
178  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
180  "Expecting a symbol of type VK_PPC_PCREL_OPT");
181  MCSymbol *LabelSym =
183  emitLabel(LabelSym, Inst.getLoc());
184 }
185 
186 // This funciton checks if the parameter Inst is part of the setup for a link
187 // time GOT PC Relative optimization. For example in this situation:
188 // <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)>
189 // <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
190 // <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282>
191 // <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
192 // The above is a pair of such instructions and this function will not return
193 // None for either one of them. In both cases we are looking for the last
194 // operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr
195 // and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look
196 // at the opcode and in the case of PLDpc we will return true. For the load
197 // (or store) this function will return false indicating it has found the second
198 // instruciton in the pair.
200  const MCSubtargetInfo &STI) {
201  // Need at least two operands.
202  if (Inst.getNumOperands() < 2)
203  return None;
204 
205  unsigned LastOp = Inst.getNumOperands() - 1;
206  // The last operand needs to be an MCExpr and it needs to have a variant kind
207  // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a
208  // link time GOT PC Rel opt instruction and we can ignore it and return None.
209  const MCOperand &Operand = Inst.getOperand(LastOp);
210  if (!Operand.isExpr())
211  return None;
212 
213  // Check for the variant kind VK_PPC_PCREL_OPT in this expression.
214  const MCExpr *Expr = Operand.getExpr();
215  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
216  if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT)
217  return None;
218 
219  return (Inst.getOpcode() == PPC::PLDpc);
220 }
221 
223  MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
224  std::unique_ptr<MCObjectWriter> OW,
225  std::unique_ptr<MCCodeEmitter> Emitter) {
226  return new PPCELFStreamer(Context, std::move(MAB), std::move(OW),
227  std::move(Emitter));
228 }
llvm::MCSymbolRefExpr::getKind
VariantKind getKind() const
Definition: MCExpr.h:401
llvm::PPCMCCodeEmitter::isPrefixedInstruction
bool isPrefixedInstruction(const MCInst &MI) const
Definition: PPCMCCodeEmitter.cpp:488
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:22
llvm::MCSymbol::setOffset
void setOffset(uint64_t Value)
Definition: MCSymbol.h:326
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::FixupKind
static Lanai::Fixups FixupKind(const MCExpr *Expr)
Definition: LanaiMCCodeEmitter.cpp:90
llvm::MCELFStreamer::emitLabel
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
Definition: MCELFStreamer.cpp:100
PPCELFStreamer.h
MCInstrDesc.h
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::MCSymbol::getOffset
uint64_t getOffset() const
Definition: MCSymbol.h:320
MCCodeEmitter.h
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
llvm::MCFixup::create
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
MCAssembler.h
llvm::MCSymbolRefExpr::VK_PPC_PCREL_OPT
@ VK_PPC_PCREL_OPT
Definition: MCExpr.h:314
llvm::MCSymbol::getFragment
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:392
llvm::Optional< bool >
llvm::PPCMCCodeEmitter
Definition: PPCMCCodeEmitter.h:25
llvm::PPCELFStreamer::emitInstruction
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
Definition: PPCELFStreamer.cpp:86
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::MCInst::getNumOperands
unsigned getNumOperands() const
Definition: MCInst.h:208
llvm::PPCELFStreamer
Definition: PPCELFStreamer.h:27
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:288
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
llvm::MCFragment
Definition: MCFragment.h:31
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:191
ELF.h
llvm::MCELFStreamer
Definition: MCELFStreamer.h:24
MCAsmBackend.h
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
MCSymbolELF.h
MCContext.h
llvm::MCObjectStreamer::emitInstruction
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
Definition: MCObjectStreamer.cpp:410
llvm::MCSymbol::isUnset
bool isUnset() const
Definition: MCSymbol.h:318
MCInst.h
llvm::MCSymbolRefExpr::getSymbol
const MCSymbol & getSymbol() const
Definition: MCExpr.h:399
llvm::MCAssembler::getEmitterPtr
MCCodeEmitter * getEmitterPtr() const
Definition: MCAssembler.h:312
llvm::PPCELFStreamer::PPCELFStreamer
PPCELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
Definition: PPCELFStreamer.cpp:39
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
llvm::MCObjectStreamer::getCurrentFragment
MCFragment * getCurrentFragment() const
Definition: MCObjectStreamer.cpp:202
llvm::None
const NoneType None
Definition: None.h:23
SourceMgr.h
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::SMLoc::isValid
bool isValid() const
Definition: SMLoc.h:29
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
PPCFixupKinds.h
PPCInstrInfo.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1650
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:610
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
llvm::PPCELFStreamer::emitLabel
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
Definition: PPCELFStreamer.cpp:120
llvm::MCObjectStreamer::getAssembler
MCAssembler & getAssembler()
Definition: MCObjectStreamer.h:122
llvm::createPPCELFStreamer
MCELFStreamer * createPPCELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
Definition: PPCELFStreamer.cpp:222
llvm::SourceMgr
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
Definition: SourceMgr.h:31
llvm::MCContext::createTempSymbol
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:303
MCObjectWriter.h
PPCMCCodeEmitter.h
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
std
Definition: BitVector.h:850
llvm::MCStreamer::AssignFragment
void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment)
Sets the symbol's section.
Definition: MCStreamer.cpp:406
Casting.h
llvm::MCOperand::getExpr
const MCExpr * getExpr() const
Definition: MCInst.h:114
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::isPartOfGOTToPCRelPair
Optional< bool > isPartOfGOTToPCRelPair(const MCInst &Inst, const MCSubtargetInfo &STI)
Definition: PPCELFStreamer.cpp:199
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:83
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::MCStreamer::getContext
MCContext & getContext() const
Definition: MCStreamer.h:280
llvm::MCContext::getSourceManager
const SourceMgr * getSourceManager() const
Definition: MCContext.h:410
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::MCObjectStreamer::emitCodeAlignment
void emitCodeAlignment(unsigned ByteAlignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
Definition: MCObjectStreamer.cpp:659
llvm::MCDataFragment
Fragment for data and encoded instructions.
Definition: MCFragment.h:242
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::Optional::getValue
constexpr const T & getValue() const LLVM_LVALUE_FUNCTION
Definition: Optional.h:282
llvm::SourceMgr::FindLineNumber
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
Definition: SourceMgr.h:166