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