LLVM  10.0.0svn
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 
10 #include "llvm/MC/MCAsmBackend.h"
11 #include "llvm/MC/MCCodeEmitter.h"
12 #include "llvm/MC/MCObjectWriter.h"
13 #include "llvm/MC/MCWin64EH.h"
15 
16 using namespace llvm;
17 
18 namespace {
19 
20 class AArch64WinCOFFStreamer : public MCWinCOFFStreamer {
22 
23 public:
24  AArch64WinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
25  std::unique_ptr<MCCodeEmitter> CE,
26  std::unique_ptr<MCObjectWriter> OW)
27  : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}
28 
29  void EmitWinEHHandlerData(SMLoc Loc) override;
30  void EmitWindowsUnwindTables() override;
31  void FinishImpl() override;
32 };
33 
34 void AArch64WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
36 
37  // We have to emit the unwind info now, because this directive
38  // actually switches to the .xdata section!
39  EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo());
40 }
41 
42 void AArch64WinCOFFStreamer::EmitWindowsUnwindTables() {
43  if (!getNumWinFrameInfos())
44  return;
45  EHStreamer.Emit(*this);
46 }
47 
48 void AArch64WinCOFFStreamer::FinishImpl() {
49  EmitFrames(nullptr);
50  EmitWindowsUnwindTables();
51 
53 }
54 } // end anonymous namespace
55 
56 namespace llvm {
57 
58 // Helper function to common out unwind code setup for those codes that can
59 // belong to both prolog and epilog.
60 // There are three types of Windows ARM64 SEH codes. They can
61 // 1) take no operands: SEH_Nop, SEH_PrologEnd, SEH_EpilogStart, SEH_EpilogEnd
62 // 2) take an offset: SEH_StackAlloc, SEH_SaveFPLR, SEH_SaveFPLR_X
63 // 3) take a register and an offset/size: all others
64 void AArch64TargetWinCOFFStreamer::EmitARM64WinUnwindCode(unsigned UnwindCode,
65  int Reg,
66  int Offset) {
67  auto &S = getStreamer();
68  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
69  if (!CurFrame)
70  return;
71  MCSymbol *Label = S.EmitCFILabel();
72  auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
73  if (InEpilogCFI)
74  CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
75  else
76  CurFrame->Instructions.push_back(Inst);
77 }
78 
80  unsigned Op = Win64EH::UOP_AllocSmall;
81  if (Size >= 16384)
83  else if (Size >= 512)
85  EmitARM64WinUnwindCode(Op, -1, Size);
86 }
87 
89  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFPLR, -1, Offset);
90 }
91 
93  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFPLRX, -1, Offset);
94 }
95 
97  int Offset) {
98  assert(Offset >= 0 && Offset <= 504 &&
99  "Offset for save reg should be >= 0 && <= 504");
100  EmitARM64WinUnwindCode(Win64EH::UOP_SaveReg, Reg, Offset);
101 }
102 
104  int Offset) {
105  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegX, Reg, Offset);
106 }
107 
109  int Offset) {
110  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegP, Reg, Offset);
111 }
112 
114  int Offset) {
115  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegPX, Reg, Offset);
116 }
117 
119  int Offset) {
120  assert(Offset >= 0 && Offset <= 504 &&
121  "Offset for save reg should be >= 0 && <= 504");
122  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFReg, Reg, Offset);
123 }
124 
126  int Offset) {
127  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegX, Reg, Offset);
128 }
129 
131  int Offset) {
132  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegP, Reg, Offset);
133 }
134 
136  int Offset) {
137  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegPX, Reg, Offset);
138 }
139 
141  EmitARM64WinUnwindCode(Win64EH::UOP_SetFP, -1, 0);
142 }
143 
145  assert(Offset <= 2040 && "UOP_AddFP must have offset <= 2040");
146  EmitARM64WinUnwindCode(Win64EH::UOP_AddFP, -1, Offset);
147 }
148 
150  EmitARM64WinUnwindCode(Win64EH::UOP_Nop, -1, 0);
151 }
152 
153 // The functions below handle opcodes that can end up in either a prolog or
154 // an epilog, but not both.
156  auto &S = getStreamer();
157  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
158  if (!CurFrame)
159  return;
160 
161  MCSymbol *Label = S.EmitCFILabel();
162  CurFrame->PrologEnd = Label;
164  auto it = CurFrame->Instructions.begin();
165  CurFrame->Instructions.insert(it, Inst);
166 }
167 
169  auto &S = getStreamer();
170  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
171  if (!CurFrame)
172  return;
173 
174  InEpilogCFI = true;
175  CurrentEpilog = S.EmitCFILabel();
176 }
177 
179  auto &S = getStreamer();
180  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
181  if (!CurFrame)
182  return;
183 
184  InEpilogCFI = false;
185  MCSymbol *Label = S.EmitCFILabel();
187  CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
188  CurrentEpilog = nullptr;
189 }
190 
192  MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
193  std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
194  bool RelaxAll, bool IncrementalLinkerCompatible) {
195  auto *S = new AArch64WinCOFFStreamer(Context, std::move(MAB),
196  std::move(Emitter), std::move(OW));
197  S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
198  return S;
199 }
200 
201 } // end llvm namespace
uint64_t CallInst * C
void FinishImpl() override
Streamer specific finalization.
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:23
void EmitARM64WinCFISaveRegP(unsigned Reg, int Offset) override
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
unsigned Reg
MCWinCOFFStreamer * createAArch64WinCOFFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > MAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter, bool RelaxAll, bool IncrementalLinkerCompatible)
std::vector< Instruction > Instructions
Definition: MCWinEH.h:46
void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) override
Definition: BitVector.h:937
Emits exception handling directives.
Definition: EHStreamer.h:30
void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override
Context object for machine code objects.
Definition: MCContext.h:64
void EmitARM64WinCFISaveFPLR(int Offset) override
void EmitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override
virtual void EmitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:705
void EmitARM64WinCFISaveReg(unsigned Reg, int Offset) override
void EmitARM64WinCFISaveRegX(unsigned Reg, int Offset) override
void EmitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override
const MCSymbol * PrologEnd
Definition: MCWinEH.h:37
MapVector< MCSymbol *, std::vector< Instruction > > EpilogMap
Definition: MCWinEH.h:47
void EmitARM64WinCFIAddFP(unsigned Size) override
void EmitARM64WinCFIAllocStack(unsigned Size) override
void EmitARM64WinCFISaveFPLRX(int Offset) override
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override
Represents a location in source code.
Definition: SMLoc.h:23