xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCELFStreamer.cpp (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
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