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 
40 PPCELFStreamer::PPCELFStreamer(MCContext &Context,
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.
66   MCELFStreamer::emitInstruction(Inst, STI);
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 
88 void PPCELFStreamer::emitInstruction(const MCInst &Inst,
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)) {
108     MCELFStreamer::emitInstruction(Inst, STI);
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 
122 void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
123   LastLabel = Symbol;
124   LastLabelLoc = Loc;
125   MCELFStreamer::emitLabel(Symbol);
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);
146   assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
147          "Expecting a symbol of type VK_PPC_PCREL_OPT");
148   MCSymbol *LabelSym =
149       getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
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.");
164   MCFixupKind FixupKind = static_cast<MCFixupKind>(FirstLiteralRelocationKind +
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);
181   assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT &&
182          "Expecting a symbol of type VK_PPC_PCREL_OPT");
183   MCSymbol *LabelSym =
184       getContext().getOrCreateSymbol(SymExpr->getSymbol().getName());
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.
201 Optional<bool> llvm::isPartOfGOTToPCRelPair(const MCInst &Inst,
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 
224 MCELFStreamer *llvm::createPPCELFStreamer(
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 }
231