LLVM 24.0.0git
SystemZTargetStreamer.cpp
Go to the documentation of this file.
1//==-- SystemZTargetStreamer.cpp - SystemZ Target Streamer Methods ----------=//
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/// \file
10/// This file defines SystemZ-specific target streamer classes.
11/// These are for implementing support for target-specific assembly directives.
12///
13//===----------------------------------------------------------------------===//
14
19#include "llvm/ADT/Twine.h"
20#include "llvm/MC/MCAsmInfo.h"
23
24using namespace llvm;
25
27 // Emit EXRL target instructions.
28 if (EXRLTargets2Sym.empty())
29 return;
30 // Switch to the .text section.
31 const MCObjectFileInfo &OFI = *Streamer.getContext().getObjectFileInfo();
32 Streamer.switchSection(OFI.getTextSection());
33 for (auto &I : EXRLTargets2Sym) {
34 Streamer.emitLabel(I.second);
35 const MCInstSTIPair &MCI_STI = I.first;
36 Streamer.emitInstruction(MCI_STI.first, *MCI_STI.second);
37 }
38 EXRLTargets2Sym.clear();
39}
40
41static void emitPPA1Flags(MCStreamer &OutStreamer, bool VarArg,
42 bool StackProtector, bool FPRMask, bool VRMask,
43 bool EHBlock, bool HasArgAreaLength, bool HasName) {
44 enum class PPA1Flag1 : uint8_t {
45 DSA64Bit = (0x80 >> 0),
46 VarArg = (0x80 >> 7),
48 };
49 enum class PPA1Flag2 : uint8_t {
50 ExternalProcedure = (0x80 >> 0),
51 STACKPROTECTOR = (0x80 >> 3),
52 LLVM_MARK_AS_BITMASK_ENUM(ExternalProcedure)
53 };
54 enum class PPA1Flag3 : uint8_t {
55 HasArgAreaLength = (0x80 >> 1),
56 FPRMask = (0x80 >> 2),
57 LLVM_MARK_AS_BITMASK_ENUM(HasArgAreaLength)
58 };
59 enum class PPA1Flag4 : uint8_t {
60 EPMOffsetPresent = (0x80 >> 0),
61 VRMask = (0x80 >> 2),
62 EHBlock = (0x80 >> 3),
63 ProcedureNamePresent = (0x80 >> 7),
64 LLVM_MARK_AS_BITMASK_ENUM(EPMOffsetPresent)
65 };
66
67 // Declare optional section flags that can be modified.
68 auto Flags1 = PPA1Flag1(0);
69 auto Flags2 = PPA1Flag2::ExternalProcedure;
70 auto Flags3 = PPA1Flag3(0);
71 auto Flags4 = PPA1Flag4::EPMOffsetPresent;
72
73 Flags1 |= PPA1Flag1::DSA64Bit;
74
75 if (VarArg)
76 Flags1 |= PPA1Flag1::VarArg;
77
79 Flags2 |= PPA1Flag2::STACKPROTECTOR;
80
81 if (HasArgAreaLength)
82 Flags3 |= PPA1Flag3::HasArgAreaLength; // Add emit ArgAreaLength flag.
83
84 // SavedGPRMask, SavedFPRMask, and SavedVRMask are precomputed in.
85 if (FPRMask)
86 Flags3 |= PPA1Flag3::FPRMask; // Add emit FPR mask flag.
87
88 if (VRMask)
89 Flags4 |= PPA1Flag4::VRMask; // Add emit VR mask flag.
90
91 if (EHBlock)
92 Flags4 |= PPA1Flag4::EHBlock; // Add optional EH block.
93
94 if (HasName)
95 Flags4 |= PPA1Flag4::ProcedureNamePresent; // Add optional name block.
96
97 OutStreamer.AddComment("PPA1 Flags 1");
98 OutStreamer.AddComment(" Bit 0: 1 = 64-bit DSA");
99 if ((Flags1 & PPA1Flag1::VarArg) == PPA1Flag1::VarArg)
100 OutStreamer.AddComment(" Bit 7: 1 = Vararg function");
101 OutStreamer.emitInt8(static_cast<uint8_t>(Flags1)); // Flags 1.
102
103 OutStreamer.AddComment("PPA1 Flags 2");
104 if ((Flags2 & PPA1Flag2::ExternalProcedure) == PPA1Flag2::ExternalProcedure)
105 OutStreamer.AddComment(" Bit 0: 1 = External procedure");
106 if ((Flags2 & PPA1Flag2::STACKPROTECTOR) == PPA1Flag2::STACKPROTECTOR)
107 OutStreamer.AddComment(" Bit 3: 1 = STACKPROTECT is enabled");
108 else
109 OutStreamer.AddComment(" Bit 3: 0 = STACKPROTECT is not enabled");
110 OutStreamer.emitInt8(static_cast<uint8_t>(Flags2)); // Flags 2.
111
112 OutStreamer.AddComment("PPA1 Flags 3");
113 if ((Flags3 & PPA1Flag3::HasArgAreaLength) == PPA1Flag3::HasArgAreaLength)
114 OutStreamer.AddComment(
115 " Bit 1: 1 = Argument Area Length is in optional area");
116 if ((Flags3 & PPA1Flag3::FPRMask) == PPA1Flag3::FPRMask)
117 OutStreamer.AddComment(" Bit 2: 1 = FP Reg Mask is in optional area");
118 OutStreamer.emitInt8(
119 static_cast<uint8_t>(Flags3)); // Flags 3 (optional sections).
120
121 OutStreamer.AddComment("PPA1 Flags 4");
122 if ((Flags4 & PPA1Flag4::VRMask) == PPA1Flag4::VRMask)
123 OutStreamer.AddComment(" Bit 2: 1 = Vector Reg Mask is in optional area");
124 if ((Flags4 & PPA1Flag4::EHBlock) == PPA1Flag4::EHBlock)
125 OutStreamer.AddComment(" Bit 3: 1 = C++ EH block");
126 if ((Flags4 & PPA1Flag4::ProcedureNamePresent) ==
127 PPA1Flag4::ProcedureNamePresent)
128 OutStreamer.AddComment(" Bit 7: 1 = Name Length and Name");
129 OutStreamer.emitInt8(static_cast<uint8_t>(
130 Flags4)); // Flags 4 (optional sections, always emit these).
131}
132
133static void emitPPA1Name(MCStreamer &OutStreamer, StringRef OutName) {
134 size_t NameSize = OutName.size();
135 uint16_t OutSize;
136 if (NameSize < UINT16_MAX) {
137 OutSize = static_cast<uint16_t>(NameSize);
138 } else {
139 OutName = OutName.substr(0, UINT16_MAX);
140 OutSize = UINT16_MAX;
141 }
142 // Emit padding to ensure that the next optional field word-aligned.
143 uint8_t ExtraZeros = 4 - ((2 + OutSize) % 4);
144
145 SmallString<512> OutnameConv;
146 ConverterEBCDIC::convertToEBCDIC(OutName, OutnameConv);
147 OutName = OutnameConv.str();
148
149 OutStreamer.AddComment("Length of Name");
150 OutStreamer.emitInt16(OutSize);
151 OutStreamer.AddComment("Name of Function");
152 OutStreamer.emitBytes(OutName);
153 OutStreamer.emitZeros(ExtraZeros);
154}
155
157 assert(PPA2Sym != nullptr && "PPA2 Symbol not defined");
158 MCStreamer &OutStreamer = getStreamer();
159 MCContext &OutContext = OutStreamer.getContext();
161
162 // Optional Argument Area Length.
163 // Note: This represents the length of the argument area that we reserve
164 // in our stack for setting up arguments for calls to other
165 // routines. If this optional field is not set, LE will reserve
166 // 128 bytes for the argument area. This optional field is
167 // created if greater than 128 bytes is required - to guarantee
168 // the required space is reserved on stack extension in the new
169 // extension. This optional field is also created if the
170 // routine has alloca(). This may reduce stack space
171 // if alloca() call causes a stack extension.
172 bool HasArgAreaLength = (Info.AllocaReg != 0) || (Info.CallFrameSize > 128);
173
174 // The personality function is present if at least one of the displacements is
175 // larger than zero.
176 bool HasPersonalityFn = Info.PersonalityADADisp > 0 || Info.GCCEHADADisp > 0;
177
178 // Emit PPA1 section.
179 OutStreamer.AddComment("PPA1");
180 OutStreamer.emitLabel(Info.PPA1);
181 OutStreamer.AddComment("Version");
182 OutStreamer.emitInt8(0x02); // Version.
183 OutStreamer.AddComment("LE Signature X'CE'");
184 OutStreamer.emitInt8(0xCE); // CEL signature.
185 OutStreamer.AddComment("Saved GPR Mask");
186 OutStreamer.emitInt16(Info.SavedGPRMask);
187 OutStreamer.AddComment("Offset to PPA2");
188 OutStreamer.emitAbsoluteSymbolDiff(PPA2Sym, Info.PPA1, 4);
189
190 emitPPA1Flags(OutStreamer, Info.IsVarArg, Info.HasStackProtector,
191 Info.SavedFPRMask != 0, Info.SavedVRMask != 0, HasPersonalityFn,
192 HasArgAreaLength, Info.Name.size() > 0);
193
194 OutStreamer.AddComment("Length/4 of Parms");
195 OutStreamer.emitInt16(
196 static_cast<uint16_t>(Info.SizeOfFnParams / 4)); // Parms/4.
197
198 OutStreamer.AddComment("Length/2 of Prolog ");
199 if (Info.EndOfProlog)
200 OutStreamer.emitValue(
201 createWordDiffExpr(OutContext, Info.EndOfProlog, Info.Fn), 1);
202 else
203 OutStreamer.emitInt8(0);
204
205 OutStreamer.AddComment("Alloca Reg + Offset/2 to SP Update");
206 OutStreamer.AddComment(
207 Twine(" Bit 0-3: Register R").concat(utostr(Info.AllocaReg)).str());
208 OutStreamer.AddComment(" Bit 4-8: Offset ");
209 const MCExpr *AllocaRegExpr =
210 MCConstantExpr::create(Info.AllocaReg << 4, OutContext);
211 if (Info.StackUpdate)
212 OutStreamer.emitValue(
214 createWordDiffExpr(OutContext, Info.StackUpdate, Info.Fn),
215 AllocaRegExpr, OutContext),
216 1);
217 else
218 OutStreamer.emitValue(AllocaRegExpr, 1);
219
220 OutStreamer.AddComment("Length of Code");
221 OutStreamer.emitAbsoluteSymbolDiff(Info.FnEnd, Info.EPMarker, 4);
222
223 if (HasArgAreaLength) {
224 OutStreamer.AddComment("Argument Area Length");
225 OutStreamer.emitInt32(Info.CallFrameSize);
226 }
227
228 // Emit saved FPR mask and offset to FPR save area (0x20 of flags 3).
229 if (Info.SavedFPRMask) {
230 OutStreamer.AddComment("FPR mask");
231 OutStreamer.emitInt16(Info.SavedFPRMask);
232 OutStreamer.AddComment("AR mask");
233 OutStreamer.emitInt16(0); // AR Mask, unused currently.
234 OutStreamer.AddComment("FPR Save Area Locator");
235 uint64_t FPRSaveAreaOffset = Info.OffsetFPR;
236 assert(FPRSaveAreaOffset < 0x10000000 && "Offset out of range");
237 FPRSaveAreaOffset &= 0x0FFFFFFF; // Lose top 4 bits.
238 OutStreamer.AddComment(
239 Twine(" Bit 0-3: Register R").concat(utostr(Info.FrameReg)));
240 OutStreamer.AddComment(
241 Twine(" Bit 4-31: Offset ").concat(utostr(FPRSaveAreaOffset)));
242 OutStreamer.emitInt32(FPRSaveAreaOffset |
243 (Info.FrameReg << 28)); // Offset to FPR save area
244 // with register to add
245 // value to (alloca reg).
246 }
247
248 // Emit saved VR mask to VR save area.
249 if (Info.SavedVRMask) {
250 OutStreamer.AddComment("VR mask");
251 OutStreamer.emitInt8(Info.SavedVRMask);
252 OutStreamer.emitInt8(0); // Reserved.
253 OutStreamer.emitInt16(0); // Also reserved.
254 uint64_t VRSaveAreaOffset = Info.OffsetVR;
255 assert(VRSaveAreaOffset < 0x10000000 && "Offset out of range");
256 VRSaveAreaOffset &= 0x0FFFFFFF; // Lose top 4 bits.
257 OutStreamer.AddComment("VR Save Area Locator");
258 OutStreamer.AddComment(
259 Twine(" Bit 0-3: Register R").concat(utostr(Info.FrameReg)));
260 OutStreamer.AddComment(
261 Twine(" Bit 4-31: Offset ").concat(utostr(VRSaveAreaOffset)));
262 OutStreamer.emitInt32(VRSaveAreaOffset | (Info.FrameReg << 28));
263 }
264
265 // Emit C++ EH information block.
266 if (HasPersonalityFn) {
267 OutStreamer.AddComment("Version");
268 OutStreamer.emitInt32(1);
269 OutStreamer.AddComment("Flags");
270 OutStreamer.emitInt32(0); // LSDA field is a WAS offset
271 OutStreamer.AddComment("Personality routine");
272 OutStreamer.emitInt64(Info.PersonalityADADisp);
273 OutStreamer.AddComment("LSDA location");
274 OutStreamer.emitInt64(Info.GCCEHADADisp);
275 }
276
277 // Emit name length and name optional section (0x01 of flags 4)
278 if (Info.Name.size() > 0)
279 emitPPA1Name(OutStreamer, Info.Name);
280
281 // Emit offset to entry point optional section (0x80 of flags 4).
282 OutStreamer.emitAbsoluteSymbolDiff(Info.EPMarker, Info.PPA1, 4);
283}
284
286 // Emit EXRL target instructions (base class prolog).
289
290 // Emit deferred PPA1 blocks into the text section.
291 if (DeferredPPA1.empty())
292 return;
295 for (auto &Info : DeferredPPA1)
296 emitPPA1(Info);
297}
298
302
303// HLASM statements can only perform a single operation at a time
305 MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
306 assert(Hi && Lo && "Symbols required to calculate expression");
307 MCSymbol *Temp = Ctx.createTempSymbol();
308 OS << Temp->getName() << " EQU ";
309 const MCBinaryExpr *TempExpr = MCBinaryExpr::createSub(
311 Ctx.getAsmInfo().printExpr(OS, *TempExpr);
312 OS << "\n";
314 MCConstantExpr::create(1, Ctx), Ctx);
315}
316
318 MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) {
319 assert(Hi && Lo && "Symbols required to calculate expression");
322 MCSymbolRefExpr::create(Lo, Ctx), Ctx),
323 MCConstantExpr::create(1, Ctx), Ctx);
324}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file provides utility functions for converting between EBCDIC-1047 and UTF-8.
#define I(x, y, z)
Definition MD5.cpp:57
This file contains some functions that are useful when dealing with strings.
static void emitPPA1Flags(MCStreamer &OutStreamer, bool VarArg, bool StackProtector, bool FPRMask, bool VRMask, bool EHBlock, bool HasArgAreaLength, bool HasName)
static void emitPPA1Name(MCStreamer &OutStreamer, StringRef OutName)
Binary assembler expressions.
Definition MCExpr.h:298
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:422
static const MCBinaryExpr * createOr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:407
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:427
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition MCContext.h:413
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
MCSection * getTextSection() const
Streaming machine code generation interface.
Definition MCStreamer.h:222
MCContext & getContext() const
Definition MCStreamer.h:326
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition MCStreamer.h:404
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
virtual void emitValueToAlignment(Align Alignment, int64_t Fill=0, uint8_t FillLen=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void emitInt16(uint64_t Value)
Definition MCStreamer.h:768
void emitInt64(uint64_t Value)
Definition MCStreamer.h:770
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
Definition MCStreamer.h:769
void emitZeros(uint64_t NumBytes)
Emit NumBytes worth of zeros.
void emitInt8(uint64_t Value)
Definition MCStreamer.h:767
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MCStreamer & getStreamer()
Definition MCStreamer.h:103
MCStreamer & Streamer
Definition MCStreamer.h:97
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
StringRef str() const
Explicit conversion to StringRef.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
const MCExpr * createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) override
SystemZHLASMAsmStreamer & getHLASMStreamer()
const MCExpr * createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo) override
std::pair< MCInst, const MCSubtargetInfo * > MCInstSTIPair
virtual const MCExpr * createWordDiffExpr(MCContext &Ctx, const MCSymbol *Hi, const MCSymbol *Lo)=0
SmallVector< PPA1Info, 0 > DeferredPPA1
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
LLVM_ABI std::error_code convertToEBCDIC(StringRef Source, SmallVectorImpl< char > &Result)
constexpr size_t NameSize
Definition XCOFF.h:30
This is an optimization pass for GlobalISel generic memory operations.
std::string utostr(uint64_t X, bool isNeg=false)
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1151
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Information about a single function needed to emit a PPA1 block.