LLVM  8.0.1
AArch64WinCOFFStreamer.cpp
Go to the documentation of this file.
1 //===-- AArch64WinCOFFStreamer.cpp - ARM Target WinCOFF Streamer ----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "AArch64WinCOFFStreamer.h"
11 #include "llvm/MC/MCAsmBackend.h"
12 #include "llvm/MC/MCCodeEmitter.h"
13 #include "llvm/MC/MCObjectWriter.h"
14 #include "llvm/MC/MCWin64EH.h"
16 
17 using namespace llvm;
18 
19 namespace {
20 
21 class AArch64WinCOFFStreamer : public MCWinCOFFStreamer {
23 
24 public:
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 FinishImpl() override;
33 };
34 
35 void AArch64WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
37 
38  // We have to emit the unwind info now, because this directive
39  // actually switches to the .xdata section!
40  EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo());
41 }
42 
43 void AArch64WinCOFFStreamer::EmitWindowsUnwindTables() {
44  if (!getNumWinFrameInfos())
45  return;
46  EHStreamer.Emit(*this);
47 }
48 
49 void AArch64WinCOFFStreamer::FinishImpl() {
50  EmitFrames(nullptr);
51  EmitWindowsUnwindTables();
52 
54 }
55 } // end anonymous namespace
56 
57 namespace llvm {
58 
59 // Helper function to common out unwind code setup for those codes that can
60 // belong to both prolog and epilog.
61 // There are three types of Windows ARM64 SEH codes. They can
62 // 1) take no operands: SEH_Nop, SEH_PrologEnd, SEH_EpilogStart, SEH_EpilogEnd
63 // 2) take an offset: SEH_StackAlloc, SEH_SaveFPLR, SEH_SaveFPLR_X
64 // 3) take a register and an offset/size: all others
65 void AArch64TargetWinCOFFStreamer::EmitARM64WinUnwindCode(unsigned UnwindCode,
66  int Reg,
67  int Offset) {
68  auto &S = getStreamer();
69  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
70  if (!CurFrame)
71  return;
72  MCSymbol *Label = S.EmitCFILabel();
73  auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
74  if (InEpilogCFI)
75  CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
76  else
77  CurFrame->Instructions.push_back(Inst);
78 }
79 
81  unsigned Op = Win64EH::UOP_AllocSmall;
82  if (Size >= 16384)
84  else if (Size >= 512)
86  EmitARM64WinUnwindCode(Op, -1, Size);
87 }
88 
90  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFPLR, -1, Offset);
91 }
92 
94  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFPLRX, -1, Offset);
95 }
96 
98  int Offset) {
99  assert(Offset >= 0 && Offset <= 504 &&
100  "Offset for save reg should be >= 0 && <= 504");
101  EmitARM64WinUnwindCode(Win64EH::UOP_SaveReg, Reg, Offset);
102 }
103 
105  int Offset) {
106  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegX, Reg, Offset);
107 }
108 
110  int Offset) {
111  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegP, Reg, Offset);
112 }
113 
115  int Offset) {
116  EmitARM64WinUnwindCode(Win64EH::UOP_SaveRegPX, Reg, Offset);
117 }
118 
120  int Offset) {
121  assert(Offset >= 0 && Offset <= 504 &&
122  "Offset for save reg should be >= 0 && <= 504");
123  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFReg, Reg, Offset);
124 }
125 
127  int Offset) {
128  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegX, Reg, Offset);
129 }
130 
132  int Offset) {
133  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegP, Reg, Offset);
134 }
135 
137  int Offset) {
138  EmitARM64WinUnwindCode(Win64EH::UOP_SaveFRegPX, Reg, Offset);
139 }
140 
142  EmitARM64WinUnwindCode(Win64EH::UOP_SetFP, -1, 0);
143 }
144 
146  assert(Offset <= 2040 && "UOP_AddFP must have offset <= 2040");
147  EmitARM64WinUnwindCode(Win64EH::UOP_AddFP, -1, Offset);
148 }
149 
151  EmitARM64WinUnwindCode(Win64EH::UOP_Nop, -1, 0);
152 }
153 
154 // The functions below handle opcodes that can end up in either a prolog or
155 // an epilog, but not both.
157  auto &S = getStreamer();
158  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
159  if (!CurFrame)
160  return;
161 
162  MCSymbol *Label = S.EmitCFILabel();
163  CurFrame->PrologEnd = Label;
165  auto it = CurFrame->Instructions.begin();
166  CurFrame->Instructions.insert(it, Inst);
167 }
168 
170  auto &S = getStreamer();
171  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
172  if (!CurFrame)
173  return;
174 
175  InEpilogCFI = true;
176  CurrentEpilog = S.EmitCFILabel();
177 }
178 
180  auto &S = getStreamer();
181  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
182  if (!CurFrame)
183  return;
184 
185  InEpilogCFI = false;
186  MCSymbol *Label = S.EmitCFILabel();
188  CurFrame->EpilogMap[CurrentEpilog].push_back(Inst);
189  CurrentEpilog = nullptr;
190 }
191 
193  MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
194  std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
195  bool RelaxAll, bool IncrementalLinkerCompatible) {
196  auto *S = new AArch64WinCOFFStreamer(Context, std::move(MAB),
197  std::move(Emitter), std::move(OW));
198  S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
199  return S;
200 }
201 
202 } // 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:24
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:42
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:47
void EmitARM64WinCFISaveFReg(unsigned Reg, int Offset) override
Definition: BitVector.h:938
Emits exception handling directives.
Definition: EHStreamer.h:31
void EmitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override
Context object for machine code objects.
Definition: MCContext.h:63
void EmitARM64WinCFISaveFPLR(int Offset) override
void EmitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override
virtual void EmitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:701
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:38
MapVector< MCSymbol *, std::vector< Instruction > > EpilogMap
Definition: MCWinEH.h:48
void EmitARM64WinCFIAddFP(unsigned Size) override
void EmitARM64WinCFIAllocStack(unsigned Size) override
void EmitARM64WinCFISaveFPLRX(int Offset) override
uint32_t Size
Definition: Profile.cpp:47
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void EmitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override
Represents a location in source code.
Definition: SMLoc.h:24