1 //===-------- PPCXCOFFStreamer.cpp - XCOFF 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 MCXCOFFStreamer for PowerPC. 10 // 11 // The purpose of the custom XCOFF 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 aligning 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 #include "PPCXCOFFStreamer.h" 21 #include "PPCMCCodeEmitter.h" 22 #include "llvm/BinaryFormat/XCOFF.h" 23 #include "llvm/MC/MCAsmBackend.h" 24 #include "llvm/MC/MCCodeEmitter.h" 25 #include "llvm/MC/MCDirectives.h" 26 #include "llvm/MC/MCObjectWriter.h" 27 #include "llvm/MC/MCSectionXCOFF.h" 28 #include "llvm/MC/MCSymbolXCOFF.h" 29 #include "llvm/MC/TargetRegistry.h" 30 31 using namespace llvm; 32 33 PPCXCOFFStreamer::PPCXCOFFStreamer(MCContext &Context, 34 std::unique_ptr<MCAsmBackend> MAB, 35 std::unique_ptr<MCObjectWriter> OW, 36 std::unique_ptr<MCCodeEmitter> Emitter) 37 : MCXCOFFStreamer(Context, std::move(MAB), std::move(OW), 38 std::move(Emitter)) {} 39 40 void PPCXCOFFStreamer::emitPrefixedInstruction(const MCInst &Inst, 41 const MCSubtargetInfo &STI) { 42 // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is 43 // before the boundary and the remaining 4-bytes are after the boundary). In 44 // order to achieve this, a nop is added prior to any such boundary-crossing 45 // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4 46 // bytes when trying to do that. If alignment requires adding more than 4 47 // bytes then the instruction won't be aligned. 48 emitCodeAlignment(64, &STI, 4); 49 50 // Emit the instruction. 51 // Since the previous emit created a new fragment then adding this instruction 52 // also forces the addition of a new fragment. Inst is now the first 53 // instruction in that new fragment. 54 MCXCOFFStreamer::emitInstruction(Inst, STI); 55 } 56 57 void PPCXCOFFStreamer::emitInstruction(const MCInst &Inst, 58 const MCSubtargetInfo &STI) { 59 PPCMCCodeEmitter *Emitter = 60 static_cast<PPCMCCodeEmitter *>(getAssembler().getEmitterPtr()); 61 62 // Special handling is only for prefixed instructions. 63 if (!Emitter->isPrefixedInstruction(Inst)) { 64 MCXCOFFStreamer::emitInstruction(Inst, STI); 65 return; 66 } 67 emitPrefixedInstruction(Inst, STI); 68 } 69 70 MCXCOFFStreamer * 71 llvm::createPPCXCOFFStreamer(MCContext &Context, 72 std::unique_ptr<MCAsmBackend> MAB, 73 std::unique_ptr<MCObjectWriter> OW, 74 std::unique_ptr<MCCodeEmitter> Emitter) { 75 return new PPCXCOFFStreamer(Context, std::move(MAB), std::move(OW), 76 std::move(Emitter)); 77 } 78