22 Win64EH::ARMUnwindEmitter EHStreamer;
25 ARMWinCOFFStreamer(MCContext &
C, std::unique_ptr<MCAsmBackend> AB,
26 std::unique_ptr<MCCodeEmitter> CE,
27 std::unique_ptr<MCObjectWriter> OW)
30 void emitWinEHHandlerData(SMLoc Loc)
override;
31 void emitWindowsUnwindTables()
override;
32 void emitWindowsUnwindTables(WinEH::FrameInfo *Frame)
override;
34 void finishImpl()
override;
37void ARMWinCOFFStreamer::emitWinEHHandlerData(
SMLoc Loc) {
46void ARMWinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
50void ARMWinCOFFStreamer::emitWindowsUnwindTables() {
51 if (!getNumWinFrameInfos())
53 EHStreamer.
Emit(*
this);
56void ARMWinCOFFStreamer::finishImpl() {
58 emitWindowsUnwindTables();
66 std::unique_ptr<MCAsmBackend> &&MAB,
67 std::unique_ptr<MCObjectWriter> &&OW,
68 std::unique_ptr<MCCodeEmitter> &&
Emitter) {
69 return new ARMWinCOFFStreamer(Context, std::move(MAB), std::move(
Emitter),
78 ARMWinCOFFStreamer &getStreamer() {
79 return static_cast<ARMWinCOFFStreamer &
>(Streamer);
81 void emitThumbFunc(MCSymbol *Symbol)
override;
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;
97 void emitARMWinUnwindCode(
unsigned UnwindCode,
int Reg,
int Offset);
100void ARMTargetWinCOFFStreamer::emitThumbFunc(MCSymbol *Symbol) {
101 getStreamer().getAssembler().setIsThumbFunc(Symbol);
106void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(
unsigned UnwindCode,
108 auto &S = getStreamer();
109 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
113 auto Inst = WinEH::Instruction(UnwindCode, Label,
Reg,
Offset);
114 if (S.isInEpilogCFI())
115 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
120void ARMTargetWinCOFFStreamer::emitARMWinCFIAllocStack(
unsigned Size,
124 if (
Size / 4 > 0xffff)
126 else if (
Size / 4 > 0x7f)
130 if (
Size / 4 > 0xffff)
132 else if (
Size / 4 > 0x3ff)
135 emitARMWinUnwindCode(
Op, -1,
Size);
138void ARMTargetWinCOFFStreamer::emitARMWinCFISaveRegMask(
unsigned Mask,
141 int Lr = (
Mask & 0x4000) ? 1 : 0;
144 assert((Mask & ~0x1fff) == 0);
146 assert((Mask & ~0x00ff) == 0);
147 if (Mask && ((Mask + (1 << 4)) & Mask) == 0) {
148 if (Wide && (Mask & 0x1000) == 0 && (Mask & 0xff) == 0xf0) {
150 for (
int I = 11;
I >= 8;
I--) {
151 if (Mask & (1 <<
I)) {
159 for (
int I = 7;
I >= 4;
I--) {
160 if (Mask & (1 <<
I)) {
175void ARMTargetWinCOFFStreamer::emitARMWinCFISaveSP(
unsigned Reg) {
179void ARMTargetWinCOFFStreamer::emitARMWinCFISaveFRegs(
unsigned First,
186 else if (
First <= 15)
192void ARMTargetWinCOFFStreamer::emitARMWinCFISaveLR(
unsigned Offset) {
196void ARMTargetWinCOFFStreamer::emitARMWinCFINop(
bool Wide) {
203void ARMTargetWinCOFFStreamer::emitARMWinCFIPrologEnd(
bool Fragment) {
204 auto &S = getStreamer();
205 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
211 WinEH::Instruction Inst =
218void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogStart(
unsigned Condition) {
219 auto &S = getStreamer();
220 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
224 S.emitWinCFIBeginEpilogue();
225 if (S.isInEpilogCFI()) {
226 S.getCurrentWinEpilog()->Condition = Condition;
230void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
231 auto &S = getStreamer();
232 WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
236 if (S.isInEpilogCFI()) {
237 std::vector<WinEH::Instruction> &
Epilog =
238 S.getCurrentWinEpilog()->Instructions;
242 WinEH::Instruction EndInstr =
Epilog.back();
252 WinEH::Instruction Inst = WinEH::Instruction(UnwindCode,
nullptr, -1, 0);
253 S.getCurrentWinEpilog()->Instructions.push_back(Inst);
255 S.emitWinCFIEndEpilogue();
258void ARMTargetWinCOFFStreamer::emitARMWinCFICustom(
unsigned Opcode) {
265 return new ARMTargetWinCOFFStreamer(S);
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)
MCStreamer * createARMWinCOFFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
std::vector< Instruction > Instructions
const MCSymbol * PrologEnd