15ffd83dbSDimitry Andric //===-------- PPCELFStreamer.cpp - ELF Object Output ---------------------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // The LLVM Compiler Infrastructure 45ffd83dbSDimitry Andric // 55ffd83dbSDimitry Andric // This file is distributed under the University of Illinois Open Source 65ffd83dbSDimitry Andric // License. See LICENSE.TXT for details. 75ffd83dbSDimitry Andric // 85ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 95ffd83dbSDimitry Andric // 105ffd83dbSDimitry Andric // This is a custom MCELFStreamer for PowerPC. 115ffd83dbSDimitry Andric // 125ffd83dbSDimitry Andric // The purpose of the custom ELF streamer is to allow us to intercept 135ffd83dbSDimitry Andric // instructions as they are being emitted and align all 8 byte instructions 145ffd83dbSDimitry Andric // to a 64 byte boundary if required (by adding a 4 byte nop). This is important 155ffd83dbSDimitry Andric // because 8 byte instructions are not allowed to cross 64 byte boundaries 165ffd83dbSDimitry Andric // and by aliging anything that is within 4 bytes of the boundary we can 175ffd83dbSDimitry Andric // guarantee that the 8 byte instructions do not cross that boundary. 185ffd83dbSDimitry Andric // 195ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 205ffd83dbSDimitry Andric 215ffd83dbSDimitry Andric 225ffd83dbSDimitry Andric #include "PPCELFStreamer.h" 23*e8d8bef9SDimitry Andric #include "PPCFixupKinds.h" 245ffd83dbSDimitry Andric #include "PPCInstrInfo.h" 255ffd83dbSDimitry Andric #include "PPCMCCodeEmitter.h" 265ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELF.h" 275ffd83dbSDimitry Andric #include "llvm/MC/MCAsmBackend.h" 285ffd83dbSDimitry Andric #include "llvm/MC/MCAssembler.h" 295ffd83dbSDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 305ffd83dbSDimitry Andric #include "llvm/MC/MCContext.h" 315ffd83dbSDimitry Andric #include "llvm/MC/MCInst.h" 325ffd83dbSDimitry Andric #include "llvm/MC/MCInstrDesc.h" 335ffd83dbSDimitry Andric #include "llvm/MC/MCObjectWriter.h" 345ffd83dbSDimitry Andric #include "llvm/MC/MCSymbolELF.h" 355ffd83dbSDimitry Andric #include "llvm/Support/Casting.h" 365ffd83dbSDimitry Andric #include "llvm/Support/SourceMgr.h" 375ffd83dbSDimitry Andric 385ffd83dbSDimitry Andric using namespace llvm; 395ffd83dbSDimitry Andric 405ffd83dbSDimitry Andric PPCELFStreamer::PPCELFStreamer(MCContext &Context, 415ffd83dbSDimitry Andric std::unique_ptr<MCAsmBackend> MAB, 425ffd83dbSDimitry Andric std::unique_ptr<MCObjectWriter> OW, 435ffd83dbSDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter) 445ffd83dbSDimitry Andric : MCELFStreamer(Context, std::move(MAB), std::move(OW), 455ffd83dbSDimitry Andric std::move(Emitter)), LastLabel(NULL) { 465ffd83dbSDimitry Andric } 475ffd83dbSDimitry Andric 485ffd83dbSDimitry Andric void PPCELFStreamer::emitPrefixedInstruction(const MCInst &Inst, 495ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 505ffd83dbSDimitry Andric // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is 515ffd83dbSDimitry Andric // before the boundary and the remaining 4-bytes are after the boundary). In 525ffd83dbSDimitry Andric // order to achieve this, a nop is added prior to any such boundary-crossing 535ffd83dbSDimitry Andric // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4 545ffd83dbSDimitry Andric // bytes when trying to do that. If alignment requires adding more than 4 555ffd83dbSDimitry Andric // bytes then the instruction won't be aligned. When emitting a code alignment 565ffd83dbSDimitry Andric // a new fragment is created for this alignment. This fragment will contain 575ffd83dbSDimitry Andric // all of the nops required as part of the alignment operation. In the cases 585ffd83dbSDimitry Andric // when no nops are added then The fragment is still created but it remains 595ffd83dbSDimitry Andric // empty. 605ffd83dbSDimitry Andric emitCodeAlignment(64, 4); 615ffd83dbSDimitry Andric 625ffd83dbSDimitry Andric // Emit the instruction. 635ffd83dbSDimitry Andric // Since the previous emit created a new fragment then adding this instruction 645ffd83dbSDimitry Andric // also forces the addition of a new fragment. Inst is now the first 655ffd83dbSDimitry Andric // instruction in that new fragment. 665ffd83dbSDimitry Andric MCELFStreamer::emitInstruction(Inst, STI); 675ffd83dbSDimitry Andric 685ffd83dbSDimitry Andric // The above instruction is forced to start a new fragment because it 695ffd83dbSDimitry Andric // comes after a code alignment fragment. Get that new fragment. 705ffd83dbSDimitry Andric MCFragment *InstructionFragment = getCurrentFragment(); 715ffd83dbSDimitry Andric SMLoc InstLoc = Inst.getLoc(); 725ffd83dbSDimitry Andric // Check if there was a last label emitted. 735ffd83dbSDimitry Andric if (LastLabel && !LastLabel->isUnset() && LastLabelLoc.isValid() && 745ffd83dbSDimitry Andric InstLoc.isValid()) { 755ffd83dbSDimitry Andric const SourceMgr *SourceManager = getContext().getSourceManager(); 765ffd83dbSDimitry Andric unsigned InstLine = SourceManager->FindLineNumber(InstLoc); 775ffd83dbSDimitry Andric unsigned LabelLine = SourceManager->FindLineNumber(LastLabelLoc); 785ffd83dbSDimitry Andric // If the Label and the Instruction are on the same line then move the 795ffd83dbSDimitry Andric // label to the top of the fragment containing the aligned instruction that 805ffd83dbSDimitry Andric // was just added. 815ffd83dbSDimitry Andric if (InstLine == LabelLine) { 825ffd83dbSDimitry Andric AssignFragment(LastLabel, InstructionFragment); 835ffd83dbSDimitry Andric LastLabel->setOffset(0); 845ffd83dbSDimitry Andric } 855ffd83dbSDimitry Andric } 865ffd83dbSDimitry Andric } 875ffd83dbSDimitry Andric 885ffd83dbSDimitry Andric void PPCELFStreamer::emitInstruction(const MCInst &Inst, 895ffd83dbSDimitry Andric const MCSubtargetInfo &STI) { 905ffd83dbSDimitry Andric PPCMCCodeEmitter *Emitter = 915ffd83dbSDimitry Andric static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr()); 925ffd83dbSDimitry Andric 93*e8d8bef9SDimitry Andric // If the instruction is a part of the GOT to PC-Rel link time optimization 94*e8d8bef9SDimitry Andric // instruction pair, return a value, otherwise return None. A true returned 95*e8d8bef9SDimitry Andric // value means the instruction is the PLDpc and a false value means it is 96*e8d8bef9SDimitry Andric // the user instruction. 97*e8d8bef9SDimitry Andric Optional<bool> IsPartOfGOTToPCRelPair = isPartOfGOTToPCRelPair(Inst, STI); 98*e8d8bef9SDimitry Andric 99*e8d8bef9SDimitry Andric // User of the GOT-indirect address. 100*e8d8bef9SDimitry Andric // For example, the load that will get the relocation as follows: 101*e8d8bef9SDimitry Andric // .reloc .Lpcrel1-8,R_PPC64_PCREL_OPT,.-(.Lpcrel1-8) 102*e8d8bef9SDimitry Andric // lwa 3, 4(3) 103*e8d8bef9SDimitry Andric if (IsPartOfGOTToPCRelPair.hasValue() && !IsPartOfGOTToPCRelPair.getValue()) 104*e8d8bef9SDimitry Andric emitGOTToPCRelReloc(Inst); 105*e8d8bef9SDimitry Andric 1065ffd83dbSDimitry Andric // Special handling is only for prefixed instructions. 1075ffd83dbSDimitry Andric if (!Emitter->isPrefixedInstruction(Inst)) { 1085ffd83dbSDimitry Andric MCELFStreamer::emitInstruction(Inst, STI); 1095ffd83dbSDimitry Andric return; 1105ffd83dbSDimitry Andric } 1115ffd83dbSDimitry Andric emitPrefixedInstruction(Inst, STI); 112*e8d8bef9SDimitry Andric 113*e8d8bef9SDimitry Andric // Producer of the GOT-indirect address. 114*e8d8bef9SDimitry Andric // For example, the prefixed load from the got that will get the label as 115*e8d8bef9SDimitry Andric // follows: 116*e8d8bef9SDimitry Andric // pld 3, vec@got@pcrel(0), 1 117*e8d8bef9SDimitry Andric // .Lpcrel1: 118*e8d8bef9SDimitry Andric if (IsPartOfGOTToPCRelPair.hasValue() && IsPartOfGOTToPCRelPair.getValue()) 119*e8d8bef9SDimitry Andric emitGOTToPCRelLabel(Inst); 1205ffd83dbSDimitry Andric } 1215ffd83dbSDimitry Andric 1225ffd83dbSDimitry Andric void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { 1235ffd83dbSDimitry Andric LastLabel = Symbol; 1245ffd83dbSDimitry Andric LastLabelLoc = Loc; 1255ffd83dbSDimitry Andric MCELFStreamer::emitLabel(Symbol); 1265ffd83dbSDimitry Andric } 1275ffd83dbSDimitry Andric 128*e8d8bef9SDimitry Andric // This linker time GOT PC Relative optimization relocation will look like this: 129*e8d8bef9SDimitry Andric // pld <reg> symbol@got@pcrel 130*e8d8bef9SDimitry Andric // <Label###>: 131*e8d8bef9SDimitry Andric // .reloc Label###-8,R_PPC64_PCREL_OPT,.-(Label###-8) 132*e8d8bef9SDimitry Andric // load <loadedreg>, 0(<reg>) 133*e8d8bef9SDimitry Andric // The reason we place the label after the PLDpc instruction is that there 134*e8d8bef9SDimitry Andric // may be an alignment nop before it since prefixed instructions must not 135*e8d8bef9SDimitry Andric // cross a 64-byte boundary (please see 136*e8d8bef9SDimitry Andric // PPCELFStreamer::emitPrefixedInstruction()). When referring to the 137*e8d8bef9SDimitry Andric // label, we subtract the width of a prefixed instruction (8 bytes) to ensure 138*e8d8bef9SDimitry Andric // we refer to the PLDpc. 139*e8d8bef9SDimitry Andric void PPCELFStreamer::emitGOTToPCRelReloc(const MCInst &Inst) { 140*e8d8bef9SDimitry Andric // Get the last operand which contains the symbol. 141*e8d8bef9SDimitry Andric const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1); 142*e8d8bef9SDimitry Andric assert(Operand.isExpr() && "Expecting an MCExpr."); 143*e8d8bef9SDimitry Andric // Cast the last operand to MCSymbolRefExpr to get the symbol. 144*e8d8bef9SDimitry Andric const MCExpr *Expr = Operand.getExpr(); 145*e8d8bef9SDimitry Andric const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr); 146*e8d8bef9SDimitry Andric assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT && 147*e8d8bef9SDimitry Andric "Expecting a symbol of type VK_PPC_PCREL_OPT"); 148*e8d8bef9SDimitry Andric MCSymbol *LabelSym = 149*e8d8bef9SDimitry Andric getContext().getOrCreateSymbol(SymExpr->getSymbol().getName()); 150*e8d8bef9SDimitry Andric const MCExpr *LabelExpr = MCSymbolRefExpr::create(LabelSym, getContext()); 151*e8d8bef9SDimitry Andric const MCExpr *Eight = MCConstantExpr::create(8, getContext()); 152*e8d8bef9SDimitry Andric // SubExpr is just Label###-8 153*e8d8bef9SDimitry Andric const MCExpr *SubExpr = 154*e8d8bef9SDimitry Andric MCBinaryExpr::createSub(LabelExpr, Eight, getContext()); 155*e8d8bef9SDimitry Andric MCSymbol *CurrentLocation = getContext().createTempSymbol(); 156*e8d8bef9SDimitry Andric const MCExpr *CurrentLocationExpr = 157*e8d8bef9SDimitry Andric MCSymbolRefExpr::create(CurrentLocation, getContext()); 158*e8d8bef9SDimitry Andric // SubExpr2 is .-(Label###-8) 159*e8d8bef9SDimitry Andric const MCExpr *SubExpr2 = 160*e8d8bef9SDimitry Andric MCBinaryExpr::createSub(CurrentLocationExpr, SubExpr, getContext()); 161*e8d8bef9SDimitry Andric 162*e8d8bef9SDimitry Andric MCDataFragment *DF = static_cast<MCDataFragment *>(LabelSym->getFragment()); 163*e8d8bef9SDimitry Andric assert(DF && "Expecting a valid data fragment."); 164*e8d8bef9SDimitry Andric MCFixupKind FixupKind = static_cast<MCFixupKind>(FirstLiteralRelocationKind + 165*e8d8bef9SDimitry Andric ELF::R_PPC64_PCREL_OPT); 166*e8d8bef9SDimitry Andric DF->getFixups().push_back( 167*e8d8bef9SDimitry Andric MCFixup::create(LabelSym->getOffset() - 8, SubExpr2, 168*e8d8bef9SDimitry Andric FixupKind, Inst.getLoc())); 169*e8d8bef9SDimitry Andric emitLabel(CurrentLocation, Inst.getLoc()); 170*e8d8bef9SDimitry Andric } 171*e8d8bef9SDimitry Andric 172*e8d8bef9SDimitry Andric // Emit the label that immediately follows the PLDpc for a link time GOT PC Rel 173*e8d8bef9SDimitry Andric // optimization. 174*e8d8bef9SDimitry Andric void PPCELFStreamer::emitGOTToPCRelLabel(const MCInst &Inst) { 175*e8d8bef9SDimitry Andric // Get the last operand which contains the symbol. 176*e8d8bef9SDimitry Andric const MCOperand &Operand = Inst.getOperand(Inst.getNumOperands() - 1); 177*e8d8bef9SDimitry Andric assert(Operand.isExpr() && "Expecting an MCExpr."); 178*e8d8bef9SDimitry Andric // Cast the last operand to MCSymbolRefExpr to get the symbol. 179*e8d8bef9SDimitry Andric const MCExpr *Expr = Operand.getExpr(); 180*e8d8bef9SDimitry Andric const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr); 181*e8d8bef9SDimitry Andric assert(SymExpr->getKind() == MCSymbolRefExpr::VK_PPC_PCREL_OPT && 182*e8d8bef9SDimitry Andric "Expecting a symbol of type VK_PPC_PCREL_OPT"); 183*e8d8bef9SDimitry Andric MCSymbol *LabelSym = 184*e8d8bef9SDimitry Andric getContext().getOrCreateSymbol(SymExpr->getSymbol().getName()); 185*e8d8bef9SDimitry Andric emitLabel(LabelSym, Inst.getLoc()); 186*e8d8bef9SDimitry Andric } 187*e8d8bef9SDimitry Andric 188*e8d8bef9SDimitry Andric // This funciton checks if the parameter Inst is part of the setup for a link 189*e8d8bef9SDimitry Andric // time GOT PC Relative optimization. For example in this situation: 190*e8d8bef9SDimitry Andric // <MCInst PLDpc <MCOperand Reg:282> <MCOperand Expr:(glob_double@got@pcrel)> 191*e8d8bef9SDimitry Andric // <MCOperand Imm:0> <MCOperand Expr:(.Lpcrel@<<invalid>>)>> 192*e8d8bef9SDimitry Andric // <MCInst SOME_LOAD <MCOperand Reg:22> <MCOperand Imm:0> <MCOperand Reg:282> 193*e8d8bef9SDimitry Andric // <MCOperand Expr:(.Lpcrel@<<invalid>>)>> 194*e8d8bef9SDimitry Andric // The above is a pair of such instructions and this function will not return 195*e8d8bef9SDimitry Andric // None for either one of them. In both cases we are looking for the last 196*e8d8bef9SDimitry Andric // operand <MCOperand Expr:(.Lpcrel@<<invalid>>)> which needs to be an MCExpr 197*e8d8bef9SDimitry Andric // and has the flag MCSymbolRefExpr::VK_PPC_PCREL_OPT. After that we just look 198*e8d8bef9SDimitry Andric // at the opcode and in the case of PLDpc we will return true. For the load 199*e8d8bef9SDimitry Andric // (or store) this function will return false indicating it has found the second 200*e8d8bef9SDimitry Andric // instruciton in the pair. 201*e8d8bef9SDimitry Andric Optional<bool> llvm::isPartOfGOTToPCRelPair(const MCInst &Inst, 202*e8d8bef9SDimitry Andric const MCSubtargetInfo &STI) { 203*e8d8bef9SDimitry Andric // Need at least two operands. 204*e8d8bef9SDimitry Andric if (Inst.getNumOperands() < 2) 205*e8d8bef9SDimitry Andric return None; 206*e8d8bef9SDimitry Andric 207*e8d8bef9SDimitry Andric unsigned LastOp = Inst.getNumOperands() - 1; 208*e8d8bef9SDimitry Andric // The last operand needs to be an MCExpr and it needs to have a variant kind 209*e8d8bef9SDimitry Andric // of VK_PPC_PCREL_OPT. If it does not satisfy these conditions it is not a 210*e8d8bef9SDimitry Andric // link time GOT PC Rel opt instruction and we can ignore it and return None. 211*e8d8bef9SDimitry Andric const MCOperand &Operand = Inst.getOperand(LastOp); 212*e8d8bef9SDimitry Andric if (!Operand.isExpr()) 213*e8d8bef9SDimitry Andric return None; 214*e8d8bef9SDimitry Andric 215*e8d8bef9SDimitry Andric // Check for the variant kind VK_PPC_PCREL_OPT in this expression. 216*e8d8bef9SDimitry Andric const MCExpr *Expr = Operand.getExpr(); 217*e8d8bef9SDimitry Andric const MCSymbolRefExpr *SymExpr = static_cast<const MCSymbolRefExpr *>(Expr); 218*e8d8bef9SDimitry Andric if (!SymExpr || SymExpr->getKind() != MCSymbolRefExpr::VK_PPC_PCREL_OPT) 219*e8d8bef9SDimitry Andric return None; 220*e8d8bef9SDimitry Andric 221*e8d8bef9SDimitry Andric return (Inst.getOpcode() == PPC::PLDpc); 222*e8d8bef9SDimitry Andric } 223*e8d8bef9SDimitry Andric 2245ffd83dbSDimitry Andric MCELFStreamer *llvm::createPPCELFStreamer( 2255ffd83dbSDimitry Andric MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, 2265ffd83dbSDimitry Andric std::unique_ptr<MCObjectWriter> OW, 2275ffd83dbSDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter) { 2285ffd83dbSDimitry Andric return new PPCELFStreamer(Context, std::move(MAB), std::move(OW), 2295ffd83dbSDimitry Andric std::move(Emitter)); 2305ffd83dbSDimitry Andric } 231