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),
44  std::move(Emitter)), LastLabel(NULL) {
45 }
46 
47 void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst,
48  const MCSubtargetInfo &STI) {
49  // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is
50  // before the boundary and the remaining 4-bytes are after the boundary). In
51  // order to achieve this, a nop is added prior to any such boundary-crossing
52  // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4
53  // bytes when trying to do that. If alignment requires adding more than 4
54  // bytes then the instruction won't be aligned. When emitting a code alignment
55  // a new fragment is created for this alignment. This fragment will contain
56  // all of the nops required as part of the alignment operation. In the cases
57  // when no nops are added then The fragment is still created but it remains
58  // empty.
59  emitCodeAlignment(64, &STI, 4);
60 
61  // Emit the instruction.
62  // Since the previous emit created a new fragment then adding this instruction
63  // also forces the addition of a new fragment. Inst is now the first
64  // instruction in that new fragment.
66 
67  // The above instruction is forced to start a new fragment because it
68  // comes after a code alignment fragment. Get that new fragment.
69  MCFragment *InstructionFragment = getCurrentFragment();
70  SMLoc InstLoc = Inst.getLoc();
71  // Check if there was a last label emitted.
72  if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() &&
73  InstLoc.isValid()) {
74  const SourceMgr *SourceManager = getContext().getSourceManager();
75  unsigned InstLine = SourceManager->FindLineNumber(InstLoc);
76  unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc);
77  // If the Label and the Instruction are on the same line then move the
78  // label to the top of the fragment containing the aligned instruction that
79  // was just added.
80  if (InstLine == LabelLine) {
81  AssignFragment(LastLabel, InstructionFragment);
82  LastLabel->setOffset(0);
83  }
84  }
85 }
86 
88  const MCSubtargetInfo &STI) {
89  PPCMCCodeEmitter *Emitter =
90  static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr());
91 
92  // If the instruction is a part of the GOT to PC-Rel link time optimization
93  // instruction pair, return a value, otherwise return None. A true returned
94  // value means the instruction is the PLDpc and a false value means it is
95  // the user instruction.
96  Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI);
97 
98  // User of the GOT-indirect address.
99  // For example, the load that will get the relocation as follows:
100  // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
101  // lwa 3, 4(3)
102  if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue())
103  emitGOTToPCRelReloc(Inst);
104 
105  // Special handling is only for prefixed instructions.
106  if (!Emitter->isPrefixedInstruction(Inst)) {
108  return;
109  }
110  emitPrefixedInstruction(Inst, STI);
111 
112  // Producer of the GOT-indirect address.
113  // For example, the prefixed load from the got that will get the label as
114  // follows:
115  // pld 3, vec@got@pcrel(0), 1
116  // .Lpcrel1:
117  if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue())
118  emitGOTToPCRelLabel(Inst);
119 }
120 
122  LastLabel = Symbol;
123  LastLabelLoc = Loc;
125 }
126 
127 // This linker time GOT PC Relative optimization relocation will look like this:
128 // pld <reg> symbol@got@pcrel
129 // <Label###>:
130 // .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8)
131 // load <loadedreg>, 0(<reg>)
132 // The reason we place the label after the PLDpc instruction is that there
133 // may be an alignment nop before it since prefixed instructions must not
134 // cross a 64-byte boundary (please see
135 // PPCELFStreamer::emitPrefixedInstruction()). When referring to the
136 // label, we subtract the width of a prefixed instruction (8 bytes) to ensure
137 // we refer to the PLDpc.
138 void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
139  // Get the last operand which contains the symbol.
140  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
141  assert(Operand.isExpr() && "Expecting an MCExpr.");
142  // Cast the last operand to MCSymbolRefExpr to get the symbol.
143  const MCExpr *Expr = Operand.getExpr();
144  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
146  "Expecting a symbol of type VK_PPC_PCREL_OPT");
147  MCSymbol *LabelSym =
149  const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext());
150  const MCExpr *Eight = MCConstantExpr::create(8, getContext());
151  // SubExpr is just Label###-8
152  const MCExpr *SubExpr =
153  MCBinaryExpr::createSub(LabelExpr, Eight, getContext());
154  MCSymbol *CurrentLocation = getContext().createTempSymbol();
155  const MCExpr *CurrentLocationExpr =
156  MCSymbolRefExpr::create(CurrentLocation, getContext());
157  // SubExpr2 is .-(Label###-8)
158  const MCExpr *SubExpr2 =
159  MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext());
160 
161  MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment());
162  assert(DF && "Expecting a valid data fragment.");
164  ELF::R_PPC64_PCREL_OPT);
165  DF->getFixups().push_back(
166  MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
167  FixupKind, Inst.getLoc()));
168  emitLabel(CurrentLocation, Inst.getLoc());
169 }
170 
171 // Emit the label that immediately follows the PLDpc for a link time GOT PC Rel
172 // optimization.
173 void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) {
174  // Get the last operand which contains the symbol.
175  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
176  assert(Operand.isExpr() && "Expecting an MCExpr.");
177  // Cast the last operand to MCSymbolRefExpr to get the symbol.
178  const MCExpr *Expr = Operand.getExpr();
179  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
181  "Expecting a symbol of type VK_PPC_PCREL_OPT");
182  MCSymbol *LabelSym =
184  emitLabel(LabelSym, Inst.getLoc());
185 }
186 
187 // This funciton checks if the parameter Inst is part of the setup for a link
188 // time GOT PC Relative optimization. For example in this situation:
189 // <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)>
190 // <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
191 // <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282>
192 // <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
193 // The above is a pair of such instructions and this function will not return
194 // None for either one of them. In both cases we are looking for the last
195 // operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr
196 // and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look
197 // at the opcode and in the case of PLDpc we will return true. For the load
198 // (or store) this function will return false indicating it has found the second
199 // instruciton in the pair.
201  const MCSubtargetInfo &STI) {
202  // Need at least two operands.
203  if (Inst.getNumOperands() < 2)
204  return None;
205 
206  unsigned LastOp = Inst.getNumOperands() - 1;
207  // The last operand needs to be an MCExpr and it needs to have a variant kind
208  // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a
209  // link time GOT PC Rel opt instruction and we can ignore it and return None.
210  const MCOperand &Operand = Inst.getOperand(LastOp);
211  if (!Operand.isExpr())
212  return None;
213 
214  // Check for the variant kind VK_PPC_PCREL_OPT in this expression.
215  const MCExpr *Expr = Operand.getExpr();
216  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
217  if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT)
218  return None;
219 
220  return (Inst.getOpcode() == PPC::PLDpc);
221 }
222 
224  MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
225  std::unique_ptr<MCObjectWriter> OW,
226  std::unique_ptr<MCCodeEmitter> Emitter) {
227  return new PPCELFStreamer(Context, std::move(MAB), std::move(OW),
228  std::move(Emitter));
229 }
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:23
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:87
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:362
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:296
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:179
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:1639
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:121
llvm::MCObjectStreamer::getAssembler
MCAssembler & getAssembler()
Definition: MCObjectStreamer.h:112
llvm::createPPCELFStreamer
MCELFStreamer * createPPCELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)
Definition: PPCELFStreamer.cpp:223
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:838
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:200
llvm::MCOperand::isExpr
bool isExpr() const
Definition: MCInst.h:65
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:79
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:611
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