LLVM  13.0.0git
PPCELFStreamer.cpp
Go to the documentation of this file.
1 //===-------- PPCELFStreamer.cpp - ELF Object Output ---------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is a custom MCELFStreamer for PowerPC.
11 //
12 // The purpose of the custom ELF streamer is to allow us to intercept
13 // instructions as they are being emitted and align all 8 byte instructions
14 // to a 64 byte boundary if required (by adding a 4 byte nop). This is important
15 // because 8 byte instructions are not allowed to cross 64 byte boundaries
16 // and by aliging anything that is within 4 bytes of the boundary we can
17 // guarantee that the 8 byte instructions do not cross that boundary.
18 //
19 //===----------------------------------------------------------------------===//
20 
21 
22 #include "PPCELFStreamer.h"
23 #include "PPCFixupKinds.h"
24 #include "PPCInstrInfo.h"
25 #include "PPCMCCodeEmitter.h"
26 #include "llvm/BinaryFormat/ELF.h"
27 #include "llvm/MC/MCAsmBackend.h"
28 #include "llvm/MC/MCAssembler.h"
29 #include "llvm/MC/MCCodeEmitter.h"
30 #include "llvm/MC/MCContext.h"
31 #include "llvm/MC/MCInst.h"
32 #include "llvm/MC/MCInstrDesc.h"
33 #include "llvm/MC/MCObjectWriter.h"
34 #include "llvm/MC/MCSymbolELF.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/SourceMgr.h"
37 
38 using namespace llvm;
39 
41  std::unique_ptr<MCAsmBackend> MAB,
42  std::unique_ptr<MCObjectWriter> OW,
43  std::unique_ptr<MCCodeEmitter> Emitter)
44  : MCELFStreamer(Context, std::move(MAB), std::move(OW),
45  std::move(Emitter)), LastLabel(NULL) {
46 }
47 
48 void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst,
49  const MCSubtargetInfo &STI) {
50  // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is
51  // before the boundary and the remaining 4-bytes are after the boundary). In
52  // order to achieve this, a nop is added prior to any such boundary-crossing
53  // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4
54  // bytes when trying to do that. If alignment requires adding more than 4
55  // bytes then the instruction won't be aligned. When emitting a code alignment
56  // a new fragment is created for this alignment. This fragment will contain
57  // all of the nops required as part of the alignment operation. In the cases
58  // when no nops are added then The fragment is still created but it remains
59  // empty.
60  emitCodeAlignment(64, 4);
61 
62  // Emit the instruction.
63  // Since the previous emit created a new fragment then adding this instruction
64  // also forces the addition of a new fragment. Inst is now the first
65  // instruction in that new fragment.
67 
68  // The above instruction is forced to start a new fragment because it
69  // comes after a code alignment fragment. Get that new fragment.
70  MCFragment *InstructionFragment = getCurrentFragment();
71  SMLoc InstLoc = Inst.getLoc();
72  // Check if there was a last label emitted.
73  if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() &&
74  InstLoc.isValid()) {
75  const SourceMgr *SourceManager = getContext().getSourceManager();
76  unsigned InstLine = SourceManager->FindLineNumber(InstLoc);
77  unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc);
78  // If the Label and the Instruction are on the same line then move the
79  // label to the top of the fragment containing the aligned instruction that
80  // was just added.
81  if (InstLine == LabelLine) {
82  AssignFragment(LastLabel, InstructionFragment);
83  LastLabel->setOffset(0);
84  }
85  }
86 }
87 
89  const MCSubtargetInfo &STI) {
90  PPCMCCodeEmitter *Emitter =
91  static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr());
92 
93  // If the instruction is a part of the GOT to PC-Rel link time optimization
94  // instruction pair, return a value, otherwise return None. A true returned
95  // value means the instruction is the PLDpc and a false value means it is
96  // the user instruction.
97  Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI);
98 
99  // User of the GOT-indirect address.
100  // For example, the load that will get the relocation as follows:
101  // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8)
102  // lwa 3, 4(3)
103  if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue())
104  emitGOTToPCRelReloc(Inst);
105 
106  // Special handling is only for prefixed instructions.
107  if (!Emitter->isPrefixedInstruction(Inst)) {
109  return;
110  }
111  emitPrefixedInstruction(Inst, STI);
112 
113  // Producer of the GOT-indirect address.
114  // For example, the prefixed load from the got that will get the label as
115  // follows:
116  // pld 3, vec@got@pcrel(0), 1
117  // .Lpcrel1:
118  if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue())
119  emitGOTToPCRelLabel(Inst);
120 }
121 
123  LastLabel = Symbol;
124  LastLabelLoc = Loc;
126 }
127 
128 // This linker time GOT PC Relative optimization relocation will look like this:
129 // pld <reg> symbol@got@pcrel
130 // <Label###>:
131 // .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8)
132 // load <loadedreg>, 0(<reg>)
133 // The reason we place the label after the PLDpc instruction is that there
134 // may be an alignment nop before it since prefixed instructions must not
135 // cross a 64-byte boundary (please see
136 // PPCELFStreamer::emitPrefixedInstruction()). When referring to the
137 // label, we subtract the width of a prefixed instruction (8 bytes) to ensure
138 // we refer to the PLDpc.
139 void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) {
140  // Get the last operand which contains the symbol.
141  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
142  assert(Operand.isExpr() && "Expecting an MCExpr.");
143  // Cast the last operand to MCSymbolRefExpr to get the symbol.
144  const MCExpr *Expr = Operand.getExpr();
145  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
147  "Expecting a symbol of type VK_PPC_PCREL_OPT");
148  MCSymbol *LabelSym =
150  const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext());
151  const MCExpr *Eight = MCConstantExpr::create(8, getContext());
152  // SubExpr is just Label###-8
153  const MCExpr *SubExpr =
154  MCBinaryExpr::createSub(LabelExpr, Eight, getContext());
155  MCSymbol *CurrentLocation = getContext().createTempSymbol();
156  const MCExpr *CurrentLocationExpr =
157  MCSymbolRefExpr::create(CurrentLocation, getContext());
158  // SubExpr2 is .-(Label###-8)
159  const MCExpr *SubExpr2 =
160  MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext());
161 
162  MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment());
163  assert(DF && "Expecting a valid data fragment.");
165  ELF::R_PPC64_PCREL_OPT);
166  DF->getFixups().push_back(
167  MCFixup::create(LabelSym->getOffset() - 8, SubExpr2,
168  FixupKind, Inst.getLoc()));
169  emitLabel(CurrentLocation, Inst.getLoc());
170 }
171 
172 // Emit the label that immediately follows the PLDpc for a link time GOT PC Rel
173 // optimization.
174 void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) {
175  // Get the last operand which contains the symbol.
176  const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1);
177  assert(Operand.isExpr() && "Expecting an MCExpr.");
178  // Cast the last operand to MCSymbolRefExpr to get the symbol.
179  const MCExpr *Expr = Operand.getExpr();
180  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
182  "Expecting a symbol of type VK_PPC_PCREL_OPT");
183  MCSymbol *LabelSym =
185  emitLabel(LabelSym, Inst.getLoc());
186 }
187 
188 // This funciton checks if the parameter Inst is part of the setup for a link
189 // time GOT PC Relative optimization. For example in this situation:
190 // <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)>
191 // <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
192 // <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282>
193 // <MCOperand Expr:(.Lpcrel@<<invalid>>)>>
194 // The above is a pair of such instructions and this function will not return
195 // None for either one of them. In both cases we are looking for the last
196 // operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr
197 // and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look
198 // at the opcode and in the case of PLDpc we will return true. For the load
199 // (or store) this function will return false indicating it has found the second
200 // instruciton in the pair.
202  const MCSubtargetInfo &STI) {
203  // Need at least two operands.
204  if (Inst.getNumOperands() < 2)
205  return None;
206 
207  unsigned LastOp = Inst.getNumOperands() - 1;
208  // The last operand needs to be an MCExpr and it needs to have a variant kind
209  // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a
210  // link time GOT PC Rel opt instruction and we can ignore it and return None.
211  const MCOperand &Operand = Inst.getOperand(LastOp);
212  if (!Operand.isExpr())
213  return None;
214 
215  // Check for the variant kind VK_PPC_PCREL_OPT in this expression.
216  const MCExpr *Expr = Operand.getExpr();
217  const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr);
218  if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT)
219  return None;
220 
221  return (Inst.getOpcode() == PPC::PLDpc);
222 }
223 
225  MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
226  std::unique_ptr<MCObjectWriter> OW,
227  std::unique_ptr<MCCodeEmitter> Emitter) {
228  return new PPCELFStreamer(Context, std::move(MAB), std::move(OW),
229  std::move(Emitter));
230 }
llvm::MCSymbolRefExpr::getKind
VariantKind getKind() const
Definition: MCExpr.h:399
llvm::PPCMCCodeEmitter::isPrefixedInstruction
bool isPrefixedInstruction(const MCInst &MI) const
Definition: PPCMCCodeEmitter.cpp:488
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbol::setOffset
void setOffset(uint64_t Value)
Definition: MCSymbol.h:323
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:71
llvm::MCSymbol::getOffset
uint64_t getOffset() const
Definition: MCSymbol.h:317
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:313
llvm::MCSymbol::getFragment
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:389
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:88
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:28
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:288
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
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:187
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:315
MCInst.h
llvm::MCSymbolRefExpr::getSymbol
const MCSymbol & getSymbol() const
Definition: MCExpr.h:397
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:40
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:197
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:1592
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:608
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:122
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:224
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:297
MCObjectWriter.h
PPCMCCodeEmitter.h
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition: MCInst.h:204
llvm::MCObjectStreamer::emitCodeAlignment
void emitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit=0) override
Emit nops until the byte alignment ByteAlignment is reached.
Definition: MCObjectStreamer.cpp:611
std
Definition: BitVector.h:838
llvm::MCStreamer::AssignFragment
void AssignFragment(MCSymbol *Symbol, MCFragment *Fragment)
Sets the symbol's section.
Definition: MCStreamer.cpp:404
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:384
llvm::isPartOfGOTToPCRelPair
Optional< bool > isPartOfGOTToPCRelPair(const MCInst &Inst, const MCSubtargetInfo &STI)
Definition: PPCELFStreamer.cpp:201
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:278
llvm::MCContext::getSourceManager
const SourceMgr * getSourceManager() const
Definition: MCContext.h:407
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::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