LLVM 22.0.0git
AArch64WinCOFFStreamer.cpp
Go to the documentation of this file.
1//===-- AArch64WinCOFFStreamer.cpp - ARM Target WinCOFF 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
11#include "llvm/MC/MCAssembler.h"
14#include "llvm/MC/MCWin64EH.h"
16
17using namespace llvm;
18
19namespace {
20
21class AArch64WinCOFFStreamer : public MCWinCOFFStreamer {
23
24public:
25 AArch64WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
26 std::unique_ptr<MCCodeEmitter> CE,
27 std::unique_ptr<MCObjectWriter> OW)
28 : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
29
30 void emitWinEHHandlerData(SMLoc Loc) override;
31 void emitWindowsUnwindTables() override;
32 void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;
33 void finishImpl() override;
34};
35
36void AArch64WinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
38
39 // We have to emit the unwind info now, because this directive
40 // actually switches to the .xdata section!
41 EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo(),
42 /* HandlerData = */ true);
43}
44
45void AArch64WinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
46 EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
47}
48
49void AArch64WinCOFFStreamer::emitWindowsUnwindTables() {
50 if (!getNumWinFrameInfos())
51 return;
52 EHStreamer.Emit(*this);
53}
54
55void AArch64WinCOFFStreamer::finishImpl() {
56 emitFrames(nullptr);
57 emitWindowsUnwindTables();
58
60}
61} // end anonymous namespace
62
63// Helper function to common out unwind code setup for those codes that can
64// belong to both prolog and epilog.
65// There are three types of Windows ARM64 SEH codes. They can
66// 1) take no operands: SEH_Nop, SEH_PrologEnd, SEH_EpilogStart, SEH_EpilogEnd
67// 2) take an offset: SEH_StackAlloc, SEH_SaveFPLR, SEH_SaveFPLR_X
68// 3) take a register and an offset/size: all others
69void AArch64TargetWinCOFFStreamer::emitARM64WinUnwindCode(unsigned UnwindCode,
70 int Reg, int Offset) {
71 auto &S = getStreamer();
72 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
73 if (!CurFrame)
74 return;
75 auto Inst = WinEH::Instruction(UnwindCode, /*Label=*/nullptr, Reg, Offset);
76 if (S.isInEpilogCFI())
77 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
78 else
79 CurFrame->Instructions.push_back(Inst);
80}
81
83 unsigned Op = Win64EH::UOP_AllocSmall;
84 if (Size >= 16384)
86 else if (Size >= 512)
88 emitARM64WinUnwindCode(Op, -1, Size);
89}
90
92 emitARM64WinUnwindCode(Win64EH::UOP_SaveR19R20X, -1, Offset);
93}
94
96 emitARM64WinUnwindCode(Win64EH::UOP_SaveFPLR, -1, Offset);
97}
98
100 emitARM64WinUnwindCode(Win64EH::UOP_SaveFPLRX, -1, Offset);
101}
102
104 int Offset) {
105 assert(Offset >= 0 && Offset <= 504 &&
106 "Offset for save reg should be >= 0 && <= 504");
107 emitARM64WinUnwindCode(Win64EH::UOP_SaveReg, Reg, Offset);
108}
109
111 int Offset) {
112 emitARM64WinUnwindCode(Win64EH::UOP_SaveRegX, Reg, Offset);
113}
114
116 int Offset) {
117 emitARM64WinUnwindCode(Win64EH::UOP_SaveRegP, Reg, Offset);
118}
119
121 int Offset) {
122 emitARM64WinUnwindCode(Win64EH::UOP_SaveRegPX, Reg, Offset);
123}
124
126 int Offset) {
127 emitARM64WinUnwindCode(Win64EH::UOP_SaveLRPair, Reg, Offset);
128}
129
131 int Offset) {
132 assert(Offset >= 0 && Offset <= 504 &&
133 "Offset for save reg should be >= 0 && <= 504");
134 emitARM64WinUnwindCode(Win64EH::UOP_SaveFReg, Reg, Offset);
135}
136
138 int Offset) {
139 emitARM64WinUnwindCode(Win64EH::UOP_SaveFRegX, Reg, Offset);
140}
141
143 int Offset) {
144 emitARM64WinUnwindCode(Win64EH::UOP_SaveFRegP, Reg, Offset);
145}
146
148 int Offset) {
149 emitARM64WinUnwindCode(Win64EH::UOP_SaveFRegPX, Reg, Offset);
150}
151
153 emitARM64WinUnwindCode(Win64EH::UOP_SetFP, -1, 0);
154}
155
157 assert(Offset <= 2040 && "UOP_AddFP must have offset <= 2040");
158 emitARM64WinUnwindCode(Win64EH::UOP_AddFP, -1, Offset);
159}
160
162 emitARM64WinUnwindCode(Win64EH::UOP_Nop, -1, 0);
163}
164
166 emitARM64WinUnwindCode(Win64EH::UOP_SaveNext, -1, 0);
167}
168
169// The functions below handle opcodes that can end up in either a prolog or
170// an epilog, but not both.
172 auto &S = getStreamer();
173 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
174 if (!CurFrame)
175 return;
176
177 MCSymbol *Label = S.emitCFILabel();
178 CurFrame->PrologEnd = Label;
179 WinEH::Instruction Inst =
180 WinEH::Instruction(Win64EH::UOP_End, /*Label=*/nullptr, -1, 0);
181 auto it = CurFrame->Instructions.begin();
182 CurFrame->Instructions.insert(it, Inst);
183}
184
187}
188
190 auto &S = getStreamer();
191 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
192 if (!CurFrame)
193 return;
194
195 if (S.isInEpilogCFI()) {
196 WinEH::Instruction Inst =
197 WinEH::Instruction(Win64EH::UOP_End, /*Label=*/nullptr, -1, 0);
198 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
199 }
200 S.emitWinCFIEndEpilogue();
201}
202
204 emitARM64WinUnwindCode(Win64EH::UOP_TrapFrame, -1, 0);
205}
206
208 emitARM64WinUnwindCode(Win64EH::UOP_PushMachFrame, -1, 0);
209}
210
212 emitARM64WinUnwindCode(Win64EH::UOP_Context, -1, 0);
213}
214
216 emitARM64WinUnwindCode(Win64EH::UOP_ECContext, -1, 0);
217}
218
220 emitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
221}
222
224 emitARM64WinUnwindCode(Win64EH::UOP_PACSignLR, -1, 0);
225}
226
228 int Offset) {
229 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegI, Reg, Offset);
230}
231
233 int Offset) {
234 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIP, Reg, Offset);
235}
236
238 int Offset) {
239 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegD, Reg, Offset);
240}
241
243 int Offset) {
244 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDP, Reg, Offset);
245}
246
248 int Offset) {
249 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQ, Reg, Offset);
250}
251
253 int Offset) {
254 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQP, Reg, Offset);
255}
256
258 int Offset) {
259 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIX, Reg, Offset);
260}
261
263 int Offset) {
264 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIPX, Reg, Offset);
265}
266
268 int Offset) {
269 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDX, Reg, Offset);
270}
271
273 int Offset) {
274 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDPX, Reg, Offset);
275}
276
278 int Offset) {
279 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQX, Reg, Offset);
280}
281
283 int Offset) {
284 emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQPX, Reg, Offset);
285}
286
288 emitARM64WinUnwindCode(Win64EH::UOP_AllocZ, 0, Offset);
289}
290
292 int Offset) {
293 emitARM64WinUnwindCode(Win64EH::UOP_SaveZReg, Reg, Offset);
294}
295
297 int Offset) {
298 emitARM64WinUnwindCode(Win64EH::UOP_SavePReg, Reg, Offset);
299}
300
303 std::unique_ptr<MCAsmBackend> &&MAB,
304 std::unique_ptr<MCObjectWriter> &&OW,
305 std::unique_ptr<MCCodeEmitter> &&Emitter) {
306 return new AArch64WinCOFFStreamer(Context, std::move(MAB), std::move(Emitter),
307 std::move(OW));
308}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
uint64_t Size
void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override
void emitARM64WinCFIAllocZ(int Offset) override
void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override
void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) override
void emitARM64WinCFISaveR19R20X(int Offset) override
void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) override
void emitARM64WinCFISavePReg(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveFPLR(int Offset) override
void emitARM64WinCFISaveZReg(unsigned Reg, int Offset) override
void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override
void emitARM64WinCFIAllocStack(unsigned Size) override
void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override
void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override
void emitARM64WinCFISaveFPLRX(int Offset) override
void emitARM64WinCFISaveReg(unsigned Reg, int Offset) override
void emitARM64WinCFIAddFP(unsigned Size) override
void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override
void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override
void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override
This class represents an Operation in the Expression.
Emits exception handling directives.
Definition: EHStreamer.h:30
Context object for machine code objects.
Definition: MCContext.h:83
Streaming machine code generation interface.
Definition: MCStreamer.h:220
virtual void emitWindowsUnwindTables()
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:821
virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:992
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
MCStreamer & getStreamer()
Definition: MCStreamer.h:101
void finishImpl() override
Streamer specific finalization.
void emitWinEHHandlerData(SMLoc Loc) override
Represents a location in source code.
Definition: SMLoc.h:23
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ UOP_SaveFRegP
Definition: Win64EH.h:54
@ UOP_SaveFReg
Definition: Win64EH.h:52
@ UOP_SaveAnyRegDPX
Definition: Win64EH.h:75
@ UOP_SaveFRegPX
Definition: Win64EH.h:55
@ UOP_SaveFPLRX
Definition: Win64EH.h:45
@ UOP_ClearUnwoundToCall
Definition: Win64EH.h:64
@ UOP_SaveAnyRegDX
Definition: Win64EH.h:74
@ UOP_SaveAnyRegQP
Definition: Win64EH.h:71
@ UOP_SaveAnyRegD
Definition: Win64EH.h:68
@ UOP_SaveFPLR
Definition: Win64EH.h:46
@ UOP_SaveAnyRegIPX
Definition: Win64EH.h:73
@ UOP_SavePReg
Definition: Win64EH.h:80
@ UOP_SaveRegX
Definition: Win64EH.h:48
@ UOP_SaveAnyRegQX
Definition: Win64EH.h:76
@ UOP_AllocLarge
Definition: Win64EH.h:31
@ UOP_SaveLRPair
Definition: Win64EH.h:51
@ UOP_SaveAnyRegIX
Definition: Win64EH.h:72
@ UOP_SaveZReg
Definition: Win64EH.h:79
@ UOP_AllocSmall
Definition: Win64EH.h:32
@ UOP_SaveRegP
Definition: Win64EH.h:49
@ UOP_SaveRegPX
Definition: Win64EH.h:50
@ UOP_SaveAnyRegQ
Definition: Win64EH.h:70
@ UOP_SaveNext
Definition: Win64EH.h:60
@ UOP_SaveAnyRegDP
Definition: Win64EH.h:69
@ UOP_PushMachFrame
Definition: Win64EH.h:40
@ UOP_SaveR19R20X
Definition: Win64EH.h:44
@ UOP_SaveAnyRegQPX
Definition: Win64EH.h:77
@ UOP_PACSignLR
Definition: Win64EH.h:65
@ UOP_ECContext
Definition: Win64EH.h:63
@ UOP_AllocMedium
Definition: Win64EH.h:43
@ UOP_SaveAnyRegIP
Definition: Win64EH.h:67
@ UOP_TrapFrame
Definition: Win64EH.h:61
@ UOP_SaveFRegX
Definition: Win64EH.h:53
@ UOP_SaveAnyRegI
Definition: Win64EH.h:66
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
MCStreamer * createAArch64WinCOFFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
std::vector< Instruction > Instructions
Definition: MCWinEH.h:63
const MCSymbol * PrologEnd
Definition: MCWinEH.h:48