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 "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 39 PPCELFStreamer::PPCELFStreamer(MCContext &Context, 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, 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. 65 MCELFStreamer::emitInstruction(Inst, STI); 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 87 void PPCELFStreamer::emitInstruction(const MCInst &Inst, 88 const MCSubtargetInfo &STI) { 89 PPCMCCodeEmitter *Emitter = 90 static_cast<PPCMCCodeEmitter*>(getAssembler().getEmitterPtr()); 91 92 // Special handling is only for prefixed instructions. 93 if (!Emitter->isPrefixedInstruction(Inst)) { 94 MCELFStreamer::emitInstruction(Inst, STI); 95 return; 96 } 97 emitPrefixedInstruction(Inst, STI); 98 } 99 100 void PPCELFStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) { 101 LastLabel = Symbol; 102 LastLabelLoc = Loc; 103 MCELFStreamer::emitLabel(Symbol); 104 } 105 106 MCELFStreamer *llvm::createPPCELFStreamer( 107 MCContext &Context, std::unique_ptr<MCAsmBackend> MAB, 108 std::unique_ptr<MCObjectWriter> OW, 109 std::unique_ptr<MCCodeEmitter> Emitter) { 110 return new PPCELFStreamer(Context, std::move(MAB), std::move(OW), 111 std::move(Emitter)); 112 } 113