1 //===-------- PPCXCOFFStreamer.cpp - XCOFF 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 MCXCOFFStreamer for PowerPC.
11 //
12 // The purpose of the custom XCOFF 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 aligning 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 #include "PPCXCOFFStreamer.h"
22 #include "PPCMCCodeEmitter.h"
23 #include "llvm/BinaryFormat/XCOFF.h"
24 #include "llvm/MC/MCAsmBackend.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/Support/TargetRegistry.h"
31
32 using namespace llvm;
33
PPCXCOFFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)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
emitPrefixedInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)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(64, 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
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)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 *
createPPCXCOFFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> MAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter)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