LLVM: lib/Target/ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17
18using namespace llvm;
19
20namespace {
22 Win64EH::ARMUnwindEmitter EHStreamer;
23
24public:
25 ARMWinCOFFStreamer(MCContext &C, std::unique_ptr AB,
26 std::unique_ptr CE,
27 std::unique_ptr 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
34 void finishImpl() override;
35};
36
37void ARMWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
39
40
41
42 EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo(),
43 true);
44}
45
46void ARMWinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
47 EHStreamer.EmitUnwindInfo(*this, Frame, false);
48}
49
50void ARMWinCOFFStreamer::emitWindowsUnwindTables() {
51 if (!getNumWinFrameInfos())
52 return;
53 EHStreamer.Emit(*this);
54}
55
56void ARMWinCOFFStreamer::finishImpl() {
57 emitFrames();
58 emitWindowsUnwindTables();
59
61}
62}
63
64MCStreamer *
66 std::unique_ptr &&MAB,
67 std::unique_ptr &&OW,
68 std::unique_ptr &&Emitter) {
69 return new ARMWinCOFFStreamer(Context, std::move(MAB), std::move(Emitter),
70 std::move(OW));
71}
72
73namespace {
75public:
77
78 ARMWinCOFFStreamer &getStreamer() {
79 return static_cast<ARMWinCOFFStreamer &>(Streamer);
80 }
81 void emitThumbFunc(MCSymbol *Symbol) override;
82
83
84
85 void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override;
86 void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) override;
87 void emitARMWinCFISaveSP(unsigned Reg) override;
88 void emitARMWinCFISaveFRegs(unsigned First, unsigned Last) override;
89 void emitARMWinCFISaveLR(unsigned Offset) override;
90 void emitARMWinCFIPrologEnd(bool Fragment) override;
91 void emitARMWinCFINop(bool Wide) override;
92 void emitARMWinCFIEpilogStart(unsigned Condition) override;
93 void emitARMWinCFIEpilogEnd() override;
94 void emitARMWinCFICustom(unsigned Opcode) override;
95
96private:
97 void emitARMWinUnwindCode(unsigned UnwindCode, int Reg, int Offset);
98};
99
100void ARMTargetWinCOFFStreamer::emitThumbFunc(MCSymbol *Symbol) {
101 getStreamer().getAssembler().setIsThumbFunc(Symbol);
102}
103
104
105
106void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(unsigned UnwindCode,
108 auto &S = getStreamer();
109 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
110 if (!CurFrame)
111 return;
113 auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
114 if (S.isInEpilogCFI())
115 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
116 else
118}
119
120void ARMTargetWinCOFFStreamer::emitARMWinCFIAllocStack(unsigned Size,
121 bool Wide) {
123 if (!Wide) {
124 if (Size / 4 > 0xffff)
126 else if (Size / 4 > 0x7f)
128 } else {
130 if (Size / 4 > 0xffff)
132 else if (Size / 4 > 0x3ff)
134 }
135 emitARMWinUnwindCode(Op, -1, Size);
136}
137
138void ARMTargetWinCOFFStreamer::emitARMWinCFISaveRegMask(unsigned Mask,
139 bool Wide) {
141 int Lr = (Mask & 0x4000) ? 1 : 0;
142 Mask &= ~0x4000;
143 if (Wide)
144 assert((Mask & ~0x1fff) == 0);
145 else
146 assert((Mask & ~0x00ff) == 0);
147 if (Mask && ((Mask + (1 << 4)) & Mask) == 0) {
148 if (Wide && (Mask & 0x1000) == 0 && (Mask & 0xff) == 0xf0) {
149
150 for (int I = 11; I >= 8; I--) {
151 if (Mask & (1 << I)) {
153 return;
154 }
155 }
156
157 } else if (!Wide) {
158
159 for (int I = 7; I >= 4; I--) {
160 if (Mask & (1 << I)) {
162 return;
163 }
164 }
166 }
167 }
168 Mask |= Lr << 14;
169 if (Wide)
171 else
173}
174
175void ARMTargetWinCOFFStreamer::emitARMWinCFISaveSP(unsigned Reg) {
177}
178
179void ARMTargetWinCOFFStreamer::emitARMWinCFISaveFRegs(unsigned First,
180 unsigned Last) {
186 else if (First <= 15)
188 else
190}
191
192void ARMTargetWinCOFFStreamer::emitARMWinCFISaveLR(unsigned Offset) {
194}
195
196void ARMTargetWinCOFFStreamer::emitARMWinCFINop(bool Wide) {
197 if (Wide)
199 else
201}
202
203void ARMTargetWinCOFFStreamer::emitARMWinCFIPrologEnd(bool Fragment) {
204 auto &S = getStreamer();
205 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
206 if (!CurFrame)
207 return;
208
211 WinEH::Instruction Inst =
212 WinEH::Instruction(Win64EH::UOP_End, nullptr, -1, 0);
215 CurFrame->Fragment = Fragment;
216}
217
218void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {
219 auto &S = getStreamer();
220 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
221 if (!CurFrame)
222 return;
223
224 S.emitWinCFIBeginEpilogue();
225 if (S.isInEpilogCFI()) {
226 S.getCurrentWinEpilog()->Condition = Condition;
227 }
228}
229
230void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
231 auto &S = getStreamer();
232 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
233 if (!CurFrame)
234 return;
235
236 if (S.isInEpilogCFI()) {
237 std::vectorWinEH::Instruction &Epilog =
238 S.getCurrentWinEpilog()->Instructions;
239
241 if (.empty()) {
242 WinEH::Instruction EndInstr = Epilog.back();
249 }
250 }
251
252 WinEH::Instruction Inst = WinEH::Instruction(UnwindCode, nullptr, -1, 0);
253 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
254 }
255 S.emitWinCFIEndEpilogue();
256}
257
258void ARMTargetWinCOFFStreamer::emitARMWinCFICustom(unsigned Opcode) {
260}
261
262}
263
265 return new ARMTargetWinCOFFStreamer(S);
266}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
Context object for machine code objects.
Streaming machine code generation interface.
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Target specific streamer interface.
void finishImpl() override
Streamer specific finalization.
Represents a location in source code.
void Emit(MCStreamer &Streamer) const override
This emits the unwind info sections (.pdata and .xdata in PE/COFF).
void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI, bool HandlerData) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
@ UOP_WideSaveRegsR4R11LR
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
MCTargetStreamer * createARMObjectTargetWinCOFFStreamer(MCStreamer &S)
Definition ARMWinCOFFStreamer.cpp:264
MCStreamer * createARMWinCOFFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
Definition ARMWinCOFFStreamer.cpp:65
std::vector< Instruction > Instructions
const MCSymbol * PrologEnd