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 (Epilog.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