Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/PowerPC/MCTargetDesc/PPCXCOFFStreamer.cpp
35294 views
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
80