27 for (
const auto &
I : Insns) {
28 switch (static_cast<Win64EH::UnwindOpcodes>(
I.Operation)) {
46 Count += (
I.Offset > 512 * 1024 - 8) ? 3 : 2;
67 switch (static_cast<Win64EH::UnwindOpcodes>(inst.
Operation)) {
77 if (inst.
Offset > 512 * 1024 - 8) {
90 b2 |= (((inst.
Offset - 8) >> 3) & 0x0F) << 4;
168 uint8_t flags = 0x01;
197 for (uint8_t c = 0; c < numInst; ++c) {
218 else if (numCodes == 0) {
267 for (
const auto &
I : Insns) {
268 switch (static_cast<Win64EH::UnwindOpcodes>(
I.Operation)) {
332 switch (static_cast<Win64EH::UnwindOpcodes>(inst.
Operation)) {
336 b = (inst.
Offset >> 4) & 0x1F;
340 uint16_t hw = (inst.
Offset >> 4) & 0x7FF;
353 b = (w & 0x00FF0000) >> 16;
355 b = (w & 0x0000FF00) >> 8;
377 b |= ((inst.
Offset - 1) >> 3) & 0x3F;
382 b |= (inst.
Offset >> 3) & 0x3F;
388 b = 0xD0 | ((reg & 0xC) >> 2);
390 b = ((reg & 0x3) << 6) | (inst.
Offset >> 3);
396 b = 0xD4 | ((reg & 0x8) >> 3);
398 b = ((reg & 0x7) << 5) | ((inst.
Offset >> 3) - 1);
404 b = 0xC8 | ((reg & 0xC) >> 2);
406 b = ((reg & 0x3) << 6) | (inst.
Offset >> 3);
412 b = 0xCC | ((reg & 0xC) >> 2);
414 b = ((reg & 0x3) << 6) | ((inst.
Offset >> 3) - 1);
420 b = 0xDC | ((reg & 0x4) >> 2);
422 b = ((reg & 0x3) << 6) | (inst.
Offset >> 3);
430 b = ((reg & 0x7) << 5) | ((inst.
Offset >> 3) - 1);
436 b = 0xD8 | ((reg & 0x4) >> 2);
438 b = ((reg & 0x3) << 6) | (inst.
Offset >> 3);
444 b = 0xDA | ((reg & 0x4) >> 2);
446 b = ((reg & 0x3) << 6) | ((inst.
Offset >> 3) - 1);
462 const std::vector<MCSymbol *>& Epilogs,
464 for (
auto *EpilogStart : Epilogs) {
465 auto InstrsIter = info->
EpilogMap.find(EpilogStart);
467 "Epilog not found in EpilogMap");
468 const auto &Instrs = InstrsIter->second;
470 if (Instrs.size() != EpilogInstrs.size())
474 for (
unsigned i = 0; i < Instrs.size(); ++i)
508 uint32_t TotalCodeBytes = PrologCodeBytes;
513 std::vector<MCSymbol *> AddedEpilogs;
517 auto &EpilogInstrs =
I.second;
522 if (MatchingEpilog) {
523 assert(EpilogInfo.
find(MatchingEpilog) != EpilogInfo.
end() &&
524 "Duplicate epilog not found");
525 EpilogInfo[EpilogStart] = EpilogInfo.
lookup(MatchingEpilog);
528 EpilogInstrs.clear();
530 EpilogInfo[EpilogStart] = TotalCodeBytes;
531 TotalCodeBytes += CodeBytes;
532 AddedEpilogs.push_back(EpilogStart);
538 uint32_t CodeWords = TotalCodeBytes / 4;
539 uint32_t CodeWordsMod = TotalCodeBytes % 4;
543 bool ExtensionWord = EpilogCount > 31 || TotalCodeBytes > 124;
544 if (!ExtensionWord) {
545 row1 |= (EpilogCount & 0x1F) << 22;
546 row1 |= (CodeWords & 0x1F) << 27;
551 row1 |= FuncLength & 0x3FFFF;
559 if (CodeWords > 0xFF || EpilogCount > 0xFFFF)
562 row2 |= (CodeWords & 0xFF) << 16;
563 row2 |= (EpilogCount & 0xFFFF);
568 for (
auto &
I : EpilogInfo) {
576 row3 |= (EpilogIndex & 0x3FF) << 22;
582 for (uint8_t c = 0; c < numInst; ++c) {
590 auto &EpilogInstrs =
I.second;
591 for (
uint32_t i = 0; i < EpilogInstrs.size(); i++) {
597 int32_t BytesMod = CodeWords * 4 - TotalCodeBytes;
599 for (
int i = 0; i < BytesMod; i++)
Instances of this class represent a uniqued identifier for a section in the current translation unit...
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static void ARM64EmitRuntimeFunction(MCStreamer &streamer, const WinEH::FrameInfo *info)
static void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, WinEH::Instruction &inst)
This class implements a map that also provides access to all stored values in a deterministic order...
std::vector< Instruction > Instructions
static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info)
MCContext & getContext() const
Base class for the full range of assembler expressions which are needed for parsing.
Represent a reference to a symbol from inside an expression.
static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, const MCSymbol *RHS)
ArrayRef< std::unique_ptr< WinEH::FrameInfo > > getWinFrameInfos() const
Context object for machine code objects.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Streaming object file generation interface.
UNW_ExceptionHandler - Specifies that this function has an exception handler.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
iterator find(const KeyT &Key)
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
static uint32_t ARM64CountOfUnwindCodes(const std::vector< WinEH::Instruction > &Insns)
static void EmitSymbolRefWithOfs(MCStreamer &streamer, const MCSymbol *Base, const MCSymbol *Other)
Streaming machine code generation interface.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
const FrameInfo * ChainedParent
static void EmitRuntimeFunction(MCStreamer &streamer, const WinEH::FrameInfo *info)
PowerPC Reduce CR logical Operation
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
MCAssembler & getAssembler()
MCSection * getAssociatedPDataSection(const MCSection *TextSec)
Get the .pdata section used for the given section.
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCSymbol * PrologEnd
const MCSection * TextSection
void Emit(MCStreamer &Streamer) const override
This emits the unwind info sections (.pdata and .xdata in PE/COFF).
Promote Memory to Register
MapVector< MCSymbol *, std::vector< Instruction > > EpilogMap
const MCSymbol * Function
ValueT lookup(const KeyT &Key) const
static MCSymbol * FindMatchingEpilog(const std::vector< WinEH::Instruction > &EpilogInstrs, const std::vector< MCSymbol *> &Epilogs, const WinEH::FrameInfo *info)
UNW_ChainInfo - Specifies that this UnwindInfo structure is chained to another one.
const MCSymbol * FuncletOrFuncEnd
static uint8_t CountOfUnwindCodes(std::vector< WinEH::Instruction > &Insns)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static int64_t GetAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS, const MCSymbol *RHS)
static void ARM64EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin, WinEH::Instruction &inst)
void EmitUnwindInfo(MCStreamer &Streamer, WinEH::FrameInfo *FI) const override
virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info)
const MCSymbol * ExceptionHandler
UNW_TerminateHandler - Specifies that this function has a termination handler.
void Emit(MCStreamer &Streamer) const override
This emits the unwind info sections (.pdata and .xdata in PE/COFF).
MCSection * getAssociatedXDataSection(const MCSection *TextSec)
Get the .xdata section used for the given section.