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;
34 void emitThumbFunc(
MCSymbol *Symbol)
override;
35 void finishImpl()
override;
38 void ARMWinCOFFStreamer::emitWinEHHandlerData(
SMLoc Loc) {
43 EHStreamer.EmitUnwindInfo(*
this, getCurrentWinFrameInfo(),
48 EHStreamer.EmitUnwindInfo(*
this, Frame,
false);
51 void ARMWinCOFFStreamer::emitWindowsUnwindTables() {
52 if (!getNumWinFrameInfos())
57 void ARMWinCOFFStreamer::emitThumbFunc(
MCSymbol *Symbol) {
58 getAssembler().setIsThumbFunc(Symbol);
61 void ARMWinCOFFStreamer::finishImpl() {
63 emitWindowsUnwindTables();
71 std::unique_ptr<MCObjectWriter> &&OW,
72 std::unique_ptr<MCCodeEmitter> &&
Emitter,
bool RelaxAll,
73 bool IncrementalLinkerCompatible) {
76 S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
84 bool InEpilogCFI =
false;
94 void emitARMWinCFIAllocStack(
unsigned Size,
bool Wide)
override;
95 void emitARMWinCFISaveRegMask(
unsigned Mask,
bool Wide)
override;
96 void emitARMWinCFISaveSP(
unsigned Reg)
override;
97 void emitARMWinCFISaveFRegs(
unsigned First,
unsigned Last)
override;
98 void emitARMWinCFISaveLR(
unsigned Offset)
override;
99 void emitARMWinCFIPrologEnd(
bool Fragment)
override;
100 void emitARMWinCFINop(
bool Wide)
override;
101 void emitARMWinCFIEpilogStart(
unsigned Condition)
override;
102 void emitARMWinCFIEpilogEnd()
override;
103 void emitARMWinCFICustom(
unsigned Opcode)
override;
106 void emitARMWinUnwindCode(
unsigned UnwindCode,
int Reg,
int Offset);
111 void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(
unsigned UnwindCode,
113 auto &
S = getStreamer();
120 CurFrame->
EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
125 void ARMTargetWinCOFFStreamer::emitARMWinCFIAllocStack(
unsigned Size,
129 if (Size / 4 > 0xffff)
131 else if (Size / 4 > 0x7f)
135 if (Size / 4 > 0xffff)
137 else if (Size / 4 > 0x3ff)
140 emitARMWinUnwindCode(
Op, -1, Size);
143 void ARMTargetWinCOFFStreamer::emitARMWinCFISaveRegMask(
unsigned Mask,
146 int Lr = (
Mask & 0x4000) ? 1 : 0;
153 if (Wide && (
Mask & 0x1000) == 0 && (
Mask & 0xff) == 0xf0) {
155 for (
int I = 11;
I >= 8;
I--) {
156 if (
Mask & (1 <<
I)) {
164 for (
int I = 7;
I >= 4;
I--) {
165 if (
Mask & (1 <<
I)) {
180 void ARMTargetWinCOFFStreamer::emitARMWinCFISaveSP(
unsigned Reg) {
184 void ARMTargetWinCOFFStreamer::emitARMWinCFISaveFRegs(
unsigned First,
187 assert(First >= 16 || Last < 16);
188 assert(First <= 31 && Last <= 31);
191 else if (First <= 15)
197 void ARMTargetWinCOFFStreamer::emitARMWinCFISaveLR(
unsigned Offset) {
201 void ARMTargetWinCOFFStreamer::emitARMWinCFINop(
bool Wide) {
208 void ARMTargetWinCOFFStreamer::emitARMWinCFIPrologEnd(
bool Fragment) {
209 auto &
S = getStreamer();
223 void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogStart(
unsigned Condition) {
224 auto &
S = getStreamer();
230 CurrentEpilog =
S.emitCFILabel();
231 CurFrame->
EpilogMap[CurrentEpilog].Condition = Condition;
234 void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
235 auto &
S = getStreamer();
240 if (!CurrentEpilog) {
241 S.getContext().reportError(
SMLoc(),
"Stray .seh_endepilogue in " +
246 std::vector<WinEH::Instruction> &
Epilog =
247 CurFrame->
EpilogMap[CurrentEpilog].Instructions;
263 CurFrame->
EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
266 CurrentEpilog =
nullptr;
269 void ARMTargetWinCOFFStreamer::emitARMWinCFICustom(
unsigned Opcode) {
276 return new ARMTargetWinCOFFStreamer(
S);