1//=- SystemZTargetStreamer.h - SystemZ Target Streamer ----------*- C++ -*-===//
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#ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZTARGETSTREAMER_H
10#define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZTARGETSTREAMER_H
11
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/MC/MCInst.h"
17#include "llvm/MC/MCSectionGOFF.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/MC/MCSymbol.h"
20#include "llvm/MC/MCSymbolGOFF.h"
21#include "llvm/Support/FormattedStream.h"
22#include <map>
23#include <utility>
24
25namespace llvm {
26class MCGOFFStreamer;
27class SystemZHLASMAsmStreamer;
28
29class SystemZTargetStreamer : public MCTargetStreamer {
30public:
31 SystemZTargetStreamer(MCStreamer &S) : MCTargetStreamer(S) {}
32
33 typedef std::pair<MCInst, const MCSubtargetInfo *> MCInstSTIPair;
34 struct CmpMCInst {
35 bool operator()(const MCInstSTIPair &MCI_STI_A,
36 const MCInstSTIPair &MCI_STI_B) const {
37 if (MCI_STI_A.second != MCI_STI_B.second)
38 return uintptr_t(MCI_STI_A.second) < uintptr_t(MCI_STI_B.second);
39 const MCInst &A = MCI_STI_A.first;
40 const MCInst &B = MCI_STI_B.first;
41 assert(A.getNumOperands() == B.getNumOperands() &&
42 A.getNumOperands() == 5 && A.getOperand(2).getImm() == 1 &&
43 B.getOperand(2).getImm() == 1 && "Unexpected EXRL target MCInst");
44 if (A.getOpcode() != B.getOpcode())
45 return A.getOpcode() < B.getOpcode();
46 if (A.getOperand(i: 0).getReg() != B.getOperand(i: 0).getReg())
47 return A.getOperand(i: 0).getReg() < B.getOperand(i: 0).getReg();
48 if (A.getOperand(i: 1).getImm() != B.getOperand(i: 1).getImm())
49 return A.getOperand(i: 1).getImm() < B.getOperand(i: 1).getImm();
50 if (A.getOperand(i: 3).getReg() != B.getOperand(i: 3).getReg())
51 return A.getOperand(i: 3).getReg() < B.getOperand(i: 3).getReg();
52 if (A.getOperand(i: 4).getImm() != B.getOperand(i: 4).getImm())
53 return A.getOperand(i: 4).getImm() < B.getOperand(i: 4).getImm();
54 return false;
55 }
56 };
57 typedef std::map<MCInstSTIPair, MCSymbol *, CmpMCInst> EXRLT2SymMap;
58 EXRLT2SymMap EXRLTargets2Sym;
59
60 void emitConstantPools() override;
61
62 virtual void emitMachine(StringRef CPUOrCommand) {};
63};
64
65class SystemZTargetzOSStreamer : public SystemZTargetStreamer {
66public:
67 /// Information about a single function needed to emit a PPA1 block.
68 struct PPA1Info {
69 StringRef Name;
70 MCSymbol *Fn = nullptr; // Symbol marking function begin.
71 MCSymbol *FnEnd = nullptr; // Symbol marking function end.
72 MCSymbol *PPA1 = nullptr; // Symbol marking PPA1 begin.
73 MCSymbol *EPMarker = nullptr; // Symbol marking entry point.
74 MCSymbol *EndOfProlog = nullptr; // Symbol marking the end of the prolog.
75 MCSymbol *StackUpdate = nullptr; // Symbol marking the stack updating instr.
76 int64_t OffsetFPR = 0;
77 int64_t OffsetVR = 0;
78 uint64_t CallFrameSize = 0;
79 uint64_t PersonalityADADisp = 0; // ADA displacement for personality func.
80 uint64_t GCCEHADADisp = 0; // ADA displacement for GCCEH symbol.
81 unsigned SizeOfFnParams = 0;
82 uint32_t FrameAndFPROffset;
83 uint32_t FrameAndVROffset;
84 uint16_t SavedGPRMask = 0;
85 uint16_t SavedFPRMask = 0;
86 uint8_t SavedVRMask = 0;
87 uint8_t FrameReg = 0;
88 uint8_t AllocaReg = 0;
89 bool IsVarArg = false;
90 bool HasStackProtector = false;
91 };
92
93 SmallVector<PPA1Info, 0> DeferredPPA1;
94
95 MCSymbol *PPA2Sym = nullptr;
96
97 SystemZTargetzOSStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
98
99 void emitConstantPools() override;
100
101 void emitExternalName(MCSymbol *Sym, StringRef Name) {
102 static_cast<MCSymbolGOFF *>(Sym)->setExternalName(Name);
103 }
104 void emitExternalName(MCSection *Sec, StringRef Name) {
105 static_cast<MCSectionGOFF *>(Sec)->setExternalName(Name);
106 }
107 void emitADA(MCSymbol *Sym, MCSection *Section) {
108 static_cast<MCSymbolGOFF *>(Sym)->setADA(
109 static_cast<MCSectionGOFF *>(Section));
110 }
111
112 void emitPPA1(PPA1Info &Info);
113 virtual const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
114 const MCSymbol *Lo) = 0;
115};
116
117class SystemZTargetGOFFStreamer : public SystemZTargetzOSStreamer {
118public:
119 SystemZTargetGOFFStreamer(MCStreamer &S) : SystemZTargetzOSStreamer(S) {}
120 const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
121 const MCSymbol *Lo) override;
122};
123
124class SystemZTargetHLASMStreamer : public SystemZTargetzOSStreamer {
125 formatted_raw_ostream &OS;
126
127public:
128 SystemZTargetHLASMStreamer(MCStreamer &S, formatted_raw_ostream &OS)
129 : SystemZTargetzOSStreamer(S), OS(OS) {}
130 SystemZHLASMAsmStreamer &getHLASMStreamer();
131 const MCExpr *createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi,
132 const MCSymbol *Lo) override;
133};
134
135class SystemZTargetELFStreamer : public SystemZTargetStreamer {
136public:
137 SystemZTargetELFStreamer(MCStreamer &S) : SystemZTargetStreamer(S) {}
138 void emitMachine(StringRef CPUOrCommand) override {}
139};
140
141class SystemZTargetGNUStreamer : public SystemZTargetStreamer {
142 formatted_raw_ostream &OS;
143
144public:
145 SystemZTargetGNUStreamer(MCStreamer &S, formatted_raw_ostream &OS)
146 : SystemZTargetStreamer(S), OS(OS) {}
147 void emitMachine(StringRef CPUOrCommand) override {
148 OS << "\t.machine " << CPUOrCommand << "\n";
149 }
150};
151
152} // end namespace llvm
153
154#endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZTARGETSTREAMER_H
155