//===- lib/MC/MCWin64EH.cpp - MCWin64EH implementation --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCWin64EH.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Win64EH.h"
namespace llvm {
class MCSection;
}

using namespace llvm;

// NOTE: All relocations generated here are 4-byte image-relative.

static uint8_t CountOfUnwindCodes(std::vector<WinEH::Instruction> &Insns) {
  uint8_t Count = 0;
  for (const auto &I : Insns) {
    switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
    default:
      llvm_unreachable("Unsupported unwind code");
    case Win64EH::UOP_PushNonVol:
    case Win64EH::UOP_AllocSmall:
    case Win64EH::UOP_SetFPReg:
    case Win64EH::UOP_PushMachFrame:
      Count += 1;
      break;
    case Win64EH::UOP_SaveNonVol:
    case Win64EH::UOP_SaveXMM128:
      Count += 2;
      break;
    case Win64EH::UOP_SaveNonVolBig:
    case Win64EH::UOP_SaveXMM128Big:
      Count += 3;
      break;
    case Win64EH::UOP_AllocLarge:
      Count += (I.Offset > 512 * 1024 - 8) ? 3 : 2;
      break;
    }
  }
  return Count;
}

static void EmitAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
                              const MCSymbol *RHS) {
  MCContext &Context = Streamer.getContext();
  const MCExpr *Diff =
      MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context),
                              MCSymbolRefExpr::create(RHS, Context), Context);
  Streamer.emitValue(Diff, 1);
}

static void EmitUnwindCode(MCStreamer &streamer, const MCSymbol *begin,
                           WinEH::Instruction &inst) {
  uint8_t b2;
  uint16_t w;
  b2 = (inst.Operation & 0x0F);
  switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
  default:
    llvm_unreachable("Unsupported unwind code");
  case Win64EH::UOP_PushNonVol:
    EmitAbsDifference(streamer, inst.Label, begin);
    b2 |= (inst.Register & 0x0F) << 4;
    streamer.emitInt8(b2);
    break;
  case Win64EH::UOP_AllocLarge:
    EmitAbsDifference(streamer, inst.Label, begin);
    if (inst.Offset > 512 * 1024 - 8) {
      b2 |= 0x10;
      streamer.emitInt8(b2);
      w = inst.Offset & 0xFFF8;
      streamer.emitInt16(w);
      w = inst.Offset >> 16;
    } else {
      streamer.emitInt8(b2);
      w = inst.Offset >> 3;
    }
    streamer.emitInt16(w);
    break;
  case Win64EH::UOP_AllocSmall:
    b2 |= (((inst.Offset - 8) >> 3) & 0x0F) << 4;
    EmitAbsDifference(streamer, inst.Label, begin);
    streamer.emitInt8(b2);
    break;
  case Win64EH::UOP_SetFPReg:
    EmitAbsDifference(streamer, inst.Label, begin);
    streamer.emitInt8(b2);
    break;
  case Win64EH::UOP_SaveNonVol:
  case Win64EH::UOP_SaveXMM128:
    b2 |= (inst.Register & 0x0F) << 4;
    EmitAbsDifference(streamer, inst.Label, begin);
    streamer.emitInt8(b2);
    w = inst.Offset >> 3;
    if (inst.Operation == Win64EH::UOP_SaveXMM128)
      w >>= 1;
    streamer.emitInt16(w);
    break;
  case Win64EH::UOP_SaveNonVolBig:
  case Win64EH::UOP_SaveXMM128Big:
    b2 |= (inst.Register & 0x0F) << 4;
    EmitAbsDifference(streamer, inst.Label, begin);
    streamer.emitInt8(b2);
    if (inst.Operation == Win64EH::UOP_SaveXMM128Big)
      w = inst.Offset & 0xFFF0;
    else
      w = inst.Offset & 0xFFF8;
    streamer.emitInt16(w);
    w = inst.Offset >> 16;
    streamer.emitInt16(w);
    break;
  case Win64EH::UOP_PushMachFrame:
    if (inst.Offset == 1)
      b2 |= 0x10;
    EmitAbsDifference(streamer, inst.Label, begin);
    streamer.emitInt8(b2);
    break;
  }
}

static void EmitSymbolRefWithOfs(MCStreamer &streamer,
                                 const MCSymbol *Base,
                                 int64_t Offset) {
  MCContext &Context = streamer.getContext();
  const MCConstantExpr *OffExpr = MCConstantExpr::create(Offset, Context);
  const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::create(Base,
                                              MCSymbolRefExpr::VK_COFF_IMGREL32,
                                              Context);
  streamer.emitValue(MCBinaryExpr::createAdd(BaseRefRel, OffExpr, Context), 4);
}

static void EmitSymbolRefWithOfs(MCStreamer &streamer,
                                 const MCSymbol *Base,
                                 const MCSymbol *Other) {
  MCContext &Context = streamer.getContext();
  const MCSymbolRefExpr *BaseRef = MCSymbolRefExpr::create(Base, Context);
  const MCSymbolRefExpr *OtherRef = MCSymbolRefExpr::create(Other, Context);
  const MCExpr *Ofs = MCBinaryExpr::createSub(OtherRef, BaseRef, Context);
  const MCSymbolRefExpr *BaseRefRel = MCSymbolRefExpr::create(Base,
                                              MCSymbolRefExpr::VK_COFF_IMGREL32,
                                              Context);
  streamer.emitValue(MCBinaryExpr::createAdd(BaseRefRel, Ofs, Context), 4);
}

static void EmitRuntimeFunction(MCStreamer &streamer,
                                const WinEH::FrameInfo *info) {
  MCContext &context = streamer.getContext();

  streamer.emitValueToAlignment(Align(4));
  EmitSymbolRefWithOfs(streamer, info->Begin, info->Begin);
  EmitSymbolRefWithOfs(streamer, info->Begin, info->End);
  streamer.emitValue(MCSymbolRefExpr::create(info->Symbol,
                                             MCSymbolRefExpr::VK_COFF_IMGREL32,
                                             context), 4);
}

static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
  // If this UNWIND_INFO already has a symbol, it's already been emitted.
  if (info->Symbol)
    return;

  MCContext &context = streamer.getContext();
  MCSymbol *Label = context.createTempSymbol();

  streamer.emitValueToAlignment(Align(4));
  streamer.emitLabel(Label);
  info->Symbol = Label;

  // Upper 3 bits are the version number (currently 1).
  uint8_t flags = 0x01;
  if (info->ChainedParent)
    flags |= Win64EH::UNW_ChainInfo << 3;
  else {
    if (info->HandlesUnwind)
      flags |= Win64EH::UNW_TerminateHandler << 3;
    if (info->HandlesExceptions)
      flags |= Win64EH::UNW_ExceptionHandler << 3;
  }
  streamer.emitInt8(flags);

  if (info->PrologEnd)
    EmitAbsDifference(streamer, info->PrologEnd, info->Begin);
  else
    streamer.emitInt8(0);

  uint8_t numCodes = CountOfUnwindCodes(info->Instructions);
  streamer.emitInt8(numCodes);

  uint8_t frame = 0;
  if (info->LastFrameInst >= 0) {
    WinEH::Instruction &frameInst = info->Instructions[info->LastFrameInst];
    assert(frameInst.Operation == Win64EH::UOP_SetFPReg);
    frame = (frameInst.Register & 0x0F) | (frameInst.Offset & 0xF0);
  }
  streamer.emitInt8(frame);

  // Emit unwind instructions (in reverse order).
  uint8_t numInst = info->Instructions.size();
  for (uint8_t c = 0; c < numInst; ++c) {
    WinEH::Instruction inst = info->Instructions.back();
    info->Instructions.pop_back();
    EmitUnwindCode(streamer, info->Begin, inst);
  }

  // For alignment purposes, the instruction array will always have an even
  // number of entries, with the final entry potentially unused (in which case
  // the array will be one longer than indicated by the count of unwind codes
  // field).
  if (numCodes & 1) {
    streamer.emitInt16(0);
  }

  if (flags & (Win64EH::UNW_ChainInfo << 3))
    EmitRuntimeFunction(streamer, info->ChainedParent);
  else if (flags &
           ((Win64EH::UNW_TerminateHandler|Win64EH::UNW_ExceptionHandler) << 3))
    streamer.emitValue(MCSymbolRefExpr::create(info->ExceptionHandler,
                                              MCSymbolRefExpr::VK_COFF_IMGREL32,
                                              context), 4);
  else if (numCodes == 0) {
    // The minimum size of an UNWIND_INFO struct is 8 bytes. If we're not
    // a chained unwind info, if there is no handler, and if there are fewer
    // than 2 slots used in the unwind code array, we have to pad to 8 bytes.
    streamer.emitInt32(0);
  }
}

void llvm::Win64EH::UnwindEmitter::Emit(MCStreamer &Streamer) const {
  // Emit the unwind info structs first.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
    Streamer.switchSection(XData);
    ::EmitUnwindInfo(Streamer, CFI.get());
  }

  // Now emit RUNTIME_FUNCTION entries.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
    Streamer.switchSection(PData);
    EmitRuntimeFunction(Streamer, CFI.get());
  }
}

void llvm::Win64EH::UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
                                                  WinEH::FrameInfo *info,
                                                  bool HandlerData) const {
  // Switch sections (the static function above is meant to be called from
  // here and from Emit().
  MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
  Streamer.switchSection(XData);

  ::EmitUnwindInfo(Streamer, info);
}

static const MCExpr *GetSubDivExpr(MCStreamer &Streamer, const MCSymbol *LHS,
                                   const MCSymbol *RHS, int Div) {
  MCContext &Context = Streamer.getContext();
  const MCExpr *Expr =
      MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context),
                              MCSymbolRefExpr::create(RHS, Context), Context);
  if (Div != 1)
    Expr = MCBinaryExpr::createDiv(Expr, MCConstantExpr::create(Div, Context),
                                   Context);
  return Expr;
}

static std::optional<int64_t> GetOptionalAbsDifference(MCStreamer &Streamer,
                                                       const MCSymbol *LHS,
                                                       const MCSymbol *RHS) {
  MCContext &Context = Streamer.getContext();
  const MCExpr *Diff =
      MCBinaryExpr::createSub(MCSymbolRefExpr::create(LHS, Context),
                              MCSymbolRefExpr::create(RHS, Context), Context);
  MCObjectStreamer *OS = (MCObjectStreamer *)(&Streamer);
  // It should normally be possible to calculate the length of a function
  // at this point, but it might not be possible in the presence of certain
  // unusual constructs, like an inline asm with an alignment directive.
  int64_t value;
  if (!Diff->evaluateAsAbsolute(value, OS->getAssembler()))
    return std::nullopt;
  return value;
}

static int64_t GetAbsDifference(MCStreamer &Streamer, const MCSymbol *LHS,
                                const MCSymbol *RHS) {
  std::optional<int64_t> MaybeDiff =
      GetOptionalAbsDifference(Streamer, LHS, RHS);
  if (!MaybeDiff)
    report_fatal_error("Failed to evaluate function length in SEH unwind info");
  return *MaybeDiff;
}

static void checkARM64Instructions(MCStreamer &Streamer,
                                   ArrayRef<WinEH::Instruction> Insns,
                                   const MCSymbol *Begin, const MCSymbol *End,
                                   StringRef Name, StringRef Type) {
  if (!End)
    return;
  std::optional<int64_t> MaybeDistance =
      GetOptionalAbsDifference(Streamer, End, Begin);
  if (!MaybeDistance)
    return;
  uint32_t Distance = (uint32_t)*MaybeDistance;

  for (const auto &I : Insns) {
    switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
    default:
      break;
    case Win64EH::UOP_TrapFrame:
    case Win64EH::UOP_PushMachFrame:
    case Win64EH::UOP_Context:
    case Win64EH::UOP_ClearUnwoundToCall:
      // Can't reason about these opcodes and how they map to actual
      // instructions.
      return;
    }
  }
  // Exclude the end opcode which doesn't map to an instruction.
  uint32_t InstructionBytes = 4 * (Insns.size() - 1);
  if (Distance != InstructionBytes) {
    Streamer.getContext().reportError(
        SMLoc(), "Incorrect size for " + Name + " " + Type + ": " +
                     Twine(Distance) +
                     " bytes of instructions in range, but .seh directives "
                     "corresponding to " +
                     Twine(InstructionBytes) + " bytes\n");
  }
}

static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
  uint32_t Count = 0;
  for (const auto &I : Insns) {
    switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
    default:
      llvm_unreachable("Unsupported ARM64 unwind code");
    case Win64EH::UOP_AllocSmall:
      Count += 1;
      break;
    case Win64EH::UOP_AllocMedium:
      Count += 2;
      break;
    case Win64EH::UOP_AllocLarge:
      Count += 4;
      break;
    case Win64EH::UOP_SaveR19R20X:
      Count += 1;
      break;
    case Win64EH::UOP_SaveFPLRX:
      Count += 1;
      break;
    case Win64EH::UOP_SaveFPLR:
      Count += 1;
      break;
    case Win64EH::UOP_SaveReg:
      Count += 2;
      break;
    case Win64EH::UOP_SaveRegP:
      Count += 2;
      break;
    case Win64EH::UOP_SaveRegPX:
      Count += 2;
      break;
    case Win64EH::UOP_SaveRegX:
      Count += 2;
      break;
    case Win64EH::UOP_SaveLRPair:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFReg:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegP:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegX:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegPX:
      Count += 2;
      break;
    case Win64EH::UOP_SetFP:
      Count += 1;
      break;
    case Win64EH::UOP_AddFP:
      Count += 2;
      break;
    case Win64EH::UOP_Nop:
      Count += 1;
      break;
    case Win64EH::UOP_End:
      Count += 1;
      break;
    case Win64EH::UOP_SaveNext:
      Count += 1;
      break;
    case Win64EH::UOP_TrapFrame:
      Count += 1;
      break;
    case Win64EH::UOP_PushMachFrame:
      Count += 1;
      break;
    case Win64EH::UOP_Context:
      Count += 1;
      break;
    case Win64EH::UOP_ClearUnwoundToCall:
      Count += 1;
      break;
    case Win64EH::UOP_PACSignLR:
      Count += 1;
      break;
    case Win64EH::UOP_SaveAnyRegI:
    case Win64EH::UOP_SaveAnyRegIP:
    case Win64EH::UOP_SaveAnyRegD:
    case Win64EH::UOP_SaveAnyRegDP:
    case Win64EH::UOP_SaveAnyRegQ:
    case Win64EH::UOP_SaveAnyRegQP:
    case Win64EH::UOP_SaveAnyRegIX:
    case Win64EH::UOP_SaveAnyRegIPX:
    case Win64EH::UOP_SaveAnyRegDX:
    case Win64EH::UOP_SaveAnyRegDPX:
    case Win64EH::UOP_SaveAnyRegQX:
    case Win64EH::UOP_SaveAnyRegQPX:
      Count += 3;
      break;
    }
  }
  return Count;
}

// Unwind opcode encodings and restrictions are documented at
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
static void ARM64EmitUnwindCode(MCStreamer &streamer,
                                const WinEH::Instruction &inst) {
  uint8_t b, reg;
  switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
  default:
    llvm_unreachable("Unsupported ARM64 unwind code");
  case Win64EH::UOP_AllocSmall:
    b = (inst.Offset >> 4) & 0x1F;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_AllocMedium: {
    uint16_t hw = (inst.Offset >> 4) & 0x7FF;
    b = 0xC0;
    b |= (hw >> 8);
    streamer.emitInt8(b);
    b = hw & 0xFF;
    streamer.emitInt8(b);
    break;
  }
  case Win64EH::UOP_AllocLarge: {
    uint32_t w;
    b = 0xE0;
    streamer.emitInt8(b);
    w = inst.Offset >> 4;
    b = (w & 0x00FF0000) >> 16;
    streamer.emitInt8(b);
    b = (w & 0x0000FF00) >> 8;
    streamer.emitInt8(b);
    b = w & 0x000000FF;
    streamer.emitInt8(b);
    break;
  }
  case Win64EH::UOP_SetFP:
    b = 0xE1;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_AddFP:
    b = 0xE2;
    streamer.emitInt8(b);
    b = (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_Nop:
    b = 0xE3;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveR19R20X:
    b = 0x20;
    b |= (inst.Offset >> 3) & 0x1F;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFPLRX:
    b = 0x80;
    b |= ((inst.Offset - 1) >> 3) & 0x3F;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFPLR:
    b = 0x40;
    b |= (inst.Offset >> 3) & 0x3F;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveReg:
    assert(inst.Register >= 19 && "Saved reg must be >= 19");
    reg = inst.Register - 19;
    b = 0xD0 | ((reg & 0xC) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveRegX:
    assert(inst.Register >= 19 && "Saved reg must be >= 19");
    reg = inst.Register - 19;
    b = 0xD4 | ((reg & 0x8) >> 3);
    streamer.emitInt8(b);
    b = ((reg & 0x7) << 5) | ((inst.Offset >> 3) - 1);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveRegP:
    assert(inst.Register >= 19 && "Saved registers must be >= 19");
    reg = inst.Register - 19;
    b = 0xC8 | ((reg & 0xC) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveRegPX:
    assert(inst.Register >= 19 && "Saved registers must be >= 19");
    reg = inst.Register - 19;
    b = 0xCC | ((reg & 0xC) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | ((inst.Offset >> 3) - 1);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveLRPair:
    assert(inst.Register >= 19 && "Saved reg must be >= 19");
    reg = inst.Register - 19;
    assert((reg % 2) == 0 && "Saved reg must be 19+2*X");
    reg /= 2;
    b = 0xD6 | ((reg & 0x7) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFReg:
    assert(inst.Register >= 8 && "Saved dreg must be >= 8");
    reg = inst.Register - 8;
    b = 0xDC | ((reg & 0x4) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFRegX:
    assert(inst.Register >= 8 && "Saved dreg must be >= 8");
    reg = inst.Register - 8;
    b = 0xDE;
    streamer.emitInt8(b);
    b = ((reg & 0x7) << 5) | ((inst.Offset >> 3) - 1);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFRegP:
    assert(inst.Register >= 8 && "Saved dregs must be >= 8");
    reg = inst.Register - 8;
    b = 0xD8 | ((reg & 0x4) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | (inst.Offset >> 3);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveFRegPX:
    assert(inst.Register >= 8 && "Saved dregs must be >= 8");
    reg = inst.Register - 8;
    b = 0xDA | ((reg & 0x4) >> 2);
    streamer.emitInt8(b);
    b = ((reg & 0x3) << 6) | ((inst.Offset >> 3) - 1);
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_End:
    b = 0xE4;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveNext:
    b = 0xE6;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_TrapFrame:
    b = 0xE8;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_PushMachFrame:
    b = 0xE9;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_Context:
    b = 0xEA;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_ClearUnwoundToCall:
    b = 0xEC;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_PACSignLR:
    b = 0xFC;
    streamer.emitInt8(b);
    break;
  case Win64EH::UOP_SaveAnyRegI:
  case Win64EH::UOP_SaveAnyRegIP:
  case Win64EH::UOP_SaveAnyRegD:
  case Win64EH::UOP_SaveAnyRegDP:
  case Win64EH::UOP_SaveAnyRegQ:
  case Win64EH::UOP_SaveAnyRegQP:
  case Win64EH::UOP_SaveAnyRegIX:
  case Win64EH::UOP_SaveAnyRegIPX:
  case Win64EH::UOP_SaveAnyRegDX:
  case Win64EH::UOP_SaveAnyRegDPX:
  case Win64EH::UOP_SaveAnyRegQX:
  case Win64EH::UOP_SaveAnyRegQPX: {
    // This assumes the opcodes are listed in the enum in a particular order.
    int Op = inst.Operation - Win64EH::UOP_SaveAnyRegI;
    int Writeback = Op / 6;
    int Paired = Op % 2;
    int Mode = (Op / 2) % 3;
    int Offset = inst.Offset >> 3;
    if (Writeback || Paired || Mode == 2)
      Offset >>= 1;
    if (Writeback)
      --Offset;
    b = 0xE7;
    streamer.emitInt8(b);
    assert(inst.Register < 32);
    b = inst.Register | (Writeback << 5) | (Paired << 6);
    streamer.emitInt8(b);
    b = Offset | (Mode << 6);
    streamer.emitInt8(b);
    break;
  }
  }
}

// Returns the epilog symbol of an epilog with the exact same unwind code
// sequence, if it exists.  Otherwise, returns nullptr.
// EpilogInstrs - Unwind codes for the current epilog.
// Epilogs - Epilogs that potentialy match the current epilog.
static MCSymbol*
FindMatchingEpilog(const std::vector<WinEH::Instruction>& EpilogInstrs,
                   const std::vector<MCSymbol *>& Epilogs,
                   const WinEH::FrameInfo *info) {
  for (auto *EpilogStart : Epilogs) {
    auto InstrsIter = info->EpilogMap.find(EpilogStart);
    assert(InstrsIter != info->EpilogMap.end() &&
           "Epilog not found in EpilogMap");
    const auto &Instrs = InstrsIter->second.Instructions;

    if (Instrs.size() != EpilogInstrs.size())
      continue;

    bool Match = true;
    for (unsigned i = 0; i < Instrs.size(); ++i)
      if (Instrs[i] != EpilogInstrs[i]) {
        Match = false;
        break;
      }

    if (Match)
      return EpilogStart;
  }
  return nullptr;
}

static void simplifyARM64Opcodes(std::vector<WinEH::Instruction> &Instructions,
                                 bool Reverse) {
  unsigned PrevOffset = -1;
  unsigned PrevRegister = -1;

  auto VisitInstruction = [&](WinEH::Instruction &Inst) {
    // Convert 2-byte opcodes into equivalent 1-byte ones.
    if (Inst.Operation == Win64EH::UOP_SaveRegP && Inst.Register == 29) {
      Inst.Operation = Win64EH::UOP_SaveFPLR;
      Inst.Register = -1;
    } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
               Inst.Register == 29) {
      Inst.Operation = Win64EH::UOP_SaveFPLRX;
      Inst.Register = -1;
    } else if (Inst.Operation == Win64EH::UOP_SaveRegPX &&
               Inst.Register == 19 && Inst.Offset <= 248) {
      Inst.Operation = Win64EH::UOP_SaveR19R20X;
      Inst.Register = -1;
    } else if (Inst.Operation == Win64EH::UOP_AddFP && Inst.Offset == 0) {
      Inst.Operation = Win64EH::UOP_SetFP;
    } else if (Inst.Operation == Win64EH::UOP_SaveRegP &&
               Inst.Register == PrevRegister + 2 &&
               Inst.Offset == PrevOffset + 16) {
      Inst.Operation = Win64EH::UOP_SaveNext;
      Inst.Register = -1;
      Inst.Offset = 0;
      // Intentionally not creating UOP_SaveNext for float register pairs,
      // as current versions of Windows (up to at least 20.04) is buggy
      // regarding SaveNext for float pairs.
    }
    // Update info about the previous instruction, for detecting if
    // the next one can be made a UOP_SaveNext
    if (Inst.Operation == Win64EH::UOP_SaveR19R20X) {
      PrevOffset = 0;
      PrevRegister = 19;
    } else if (Inst.Operation == Win64EH::UOP_SaveRegPX) {
      PrevOffset = 0;
      PrevRegister = Inst.Register;
    } else if (Inst.Operation == Win64EH::UOP_SaveRegP) {
      PrevOffset = Inst.Offset;
      PrevRegister = Inst.Register;
    } else if (Inst.Operation == Win64EH::UOP_SaveNext) {
      PrevRegister += 2;
      PrevOffset += 16;
    } else {
      PrevRegister = -1;
      PrevOffset = -1;
    }
  };

  // Iterate over instructions in a forward order (for prologues),
  // backwards for epilogues (i.e. always reverse compared to how the
  // opcodes are stored).
  if (Reverse) {
    for (auto It = Instructions.rbegin(); It != Instructions.rend(); It++)
      VisitInstruction(*It);
  } else {
    for (WinEH::Instruction &Inst : Instructions)
      VisitInstruction(Inst);
  }
}

// Check if an epilog exists as a subset of the end of a prolog (backwards).
static int
getARM64OffsetInProlog(const std::vector<WinEH::Instruction> &Prolog,
                       const std::vector<WinEH::Instruction> &Epilog) {
  // Can't find an epilog as a subset if it is longer than the prolog.
  if (Epilog.size() > Prolog.size())
    return -1;

  // Check that the epilog actually is a perfect match for the end (backwrds)
  // of the prolog.
  for (int I = Epilog.size() - 1; I >= 0; I--) {
    if (Prolog[I] != Epilog[Epilog.size() - 1 - I])
      return -1;
  }

  if (Epilog.size() == Prolog.size())
    return 0;

  // If the epilog was a subset of the prolog, find its offset.
  return ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction>(
      &Prolog[Epilog.size()], Prolog.size() - Epilog.size()));
}

static int checkARM64PackedEpilog(MCStreamer &streamer, WinEH::FrameInfo *info,
                                  WinEH::FrameInfo::Segment *Seg,
                                  int PrologCodeBytes) {
  // Can only pack if there's one single epilog
  if (Seg->Epilogs.size() != 1)
    return -1;

  MCSymbol *Sym = Seg->Epilogs.begin()->first;
  const std::vector<WinEH::Instruction> &Epilog =
      info->EpilogMap[Sym].Instructions;

  // Check that the epilog actually is at the very end of the function,
  // otherwise it can't be packed.
  uint32_t DistanceFromEnd =
      (uint32_t)(Seg->Offset + Seg->Length - Seg->Epilogs.begin()->second);
  if (DistanceFromEnd / 4 != Epilog.size())
    return -1;

  int RetVal = -1;
  // Even if we don't end up sharing opcodes with the prolog, we can still
  // write the offset as a packed offset, if the single epilog is located at
  // the end of the function and the offset (pointing after the prolog) fits
  // as a packed offset.
  if (PrologCodeBytes <= 31 &&
      PrologCodeBytes + ARM64CountOfUnwindCodes(Epilog) <= 124)
    RetVal = PrologCodeBytes;

  int Offset = getARM64OffsetInProlog(info->Instructions, Epilog);
  if (Offset < 0)
    return RetVal;

  // Check that the offset and prolog size fits in the first word; it's
  // unclear whether the epilog count in the extension word can be taken
  // as packed epilog offset.
  if (Offset > 31 || PrologCodeBytes > 124)
    return RetVal;

  // As we choose to express the epilog as part of the prolog, remove the
  // epilog from the map, so we don't try to emit its opcodes.
  info->EpilogMap.erase(Sym);
  return Offset;
}

static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength,
                                 int PackedEpilogOffset) {
  if (PackedEpilogOffset == 0) {
    // Fully symmetric prolog and epilog, should be ok for packed format.
    // For CR=3, the corresponding synthesized epilog actually lacks the
    // SetFP opcode, but unwinding should work just fine despite that
    // (if at the SetFP opcode, the unwinder considers it as part of the
    // function body and just unwinds the full prolog instead).
  } else if (PackedEpilogOffset == 1) {
    // One single case of differences between prolog and epilog is allowed:
    // The epilog can lack a single SetFP that is the last opcode in the
    // prolog, for the CR=3 case.
    if (info->Instructions.back().Operation != Win64EH::UOP_SetFP)
      return false;
  } else {
    // Too much difference between prolog and epilog.
    return false;
  }
  unsigned RegI = 0, RegF = 0;
  int Predecrement = 0;
  enum {
    Start,
    Start2,
    Start3,
    IntRegs,
    FloatRegs,
    InputArgs,
    StackAdjust,
    FrameRecord,
    End
  } Location = Start;
  bool StandaloneLR = false, FPLRPair = false;
  bool PAC = false;
  int StackOffset = 0;
  int Nops = 0;
  // Iterate over the prolog and check that all opcodes exactly match
  // the canonical order and form. A more lax check could verify that
  // all saved registers are in the expected locations, but not enforce
  // the order - that would work fine when unwinding from within
  // functions, but not be exactly right if unwinding happens within
  // prologs/epilogs.
  for (const WinEH::Instruction &Inst : info->Instructions) {
    switch (Inst.Operation) {
    case Win64EH::UOP_End:
      if (Location != Start)
        return false;
      Location = Start2;
      break;
    case Win64EH::UOP_PACSignLR:
      if (Location != Start2)
        return false;
      PAC = true;
      Location = Start3;
      break;
    case Win64EH::UOP_SaveR19R20X:
      if (Location != Start2 && Location != Start3)
        return false;
      Predecrement = Inst.Offset;
      RegI = 2;
      Location = IntRegs;
      break;
    case Win64EH::UOP_SaveRegX:
      if (Location != Start2 && Location != Start3)
        return false;
      Predecrement = Inst.Offset;
      if (Inst.Register == 19)
        RegI += 1;
      else if (Inst.Register == 30)
        StandaloneLR = true;
      else
        return false;
      // Odd register; can't be any further int registers.
      Location = FloatRegs;
      break;
    case Win64EH::UOP_SaveRegPX:
      // Can't have this in a canonical prologue. Either this has been
      // canonicalized into SaveR19R20X or SaveFPLRX, or it's an unsupported
      // register pair.
      // It can't be canonicalized into SaveR19R20X if the offset is
      // larger than 248 bytes, but even with the maximum case with
      // RegI=10/RegF=8/CR=1/H=1, we end up with SavSZ = 216, which should
      // fit into SaveR19R20X.
      // The unwinding opcodes can't describe the otherwise seemingly valid
      // case for RegI=1 CR=1, that would start with a
      // "stp x19, lr, [sp, #-...]!" as that fits neither SaveRegPX nor
      // SaveLRPair.
      return false;
    case Win64EH::UOP_SaveRegP:
      if (Location != IntRegs || Inst.Offset != 8 * RegI ||
          Inst.Register != 19 + RegI)
        return false;
      RegI += 2;
      break;
    case Win64EH::UOP_SaveReg:
      if (Location != IntRegs || Inst.Offset != 8 * RegI)
        return false;
      if (Inst.Register == 19 + RegI)
        RegI += 1;
      else if (Inst.Register == 30)
        StandaloneLR = true;
      else
        return false;
      // Odd register; can't be any further int registers.
      Location = FloatRegs;
      break;
    case Win64EH::UOP_SaveLRPair:
      if (Location != IntRegs || Inst.Offset != 8 * RegI ||
          Inst.Register != 19 + RegI)
        return false;
      RegI += 1;
      StandaloneLR = true;
      Location = FloatRegs;
      break;
    case Win64EH::UOP_SaveFRegX:
      // Packed unwind can't handle prologs that only save one single
      // float register.
      return false;
    case Win64EH::UOP_SaveFReg:
      if (Location != FloatRegs || RegF == 0 || Inst.Register != 8 + RegF ||
          Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
        return false;
      RegF += 1;
      Location = InputArgs;
      break;
    case Win64EH::UOP_SaveFRegPX:
      if ((Location != Start2 && Location != Start3) || Inst.Register != 8)
        return false;
      Predecrement = Inst.Offset;
      RegF = 2;
      Location = FloatRegs;
      break;
    case Win64EH::UOP_SaveFRegP:
      if ((Location != IntRegs && Location != FloatRegs) ||
          Inst.Register != 8 + RegF ||
          Inst.Offset != 8 * (RegI + (StandaloneLR ? 1 : 0) + RegF))
        return false;
      RegF += 2;
      Location = FloatRegs;
      break;
    case Win64EH::UOP_SaveNext:
      if (Location == IntRegs)
        RegI += 2;
      else if (Location == FloatRegs)
        RegF += 2;
      else
        return false;
      break;
    case Win64EH::UOP_Nop:
      if (Location != IntRegs && Location != FloatRegs && Location != InputArgs)
        return false;
      Location = InputArgs;
      Nops++;
      break;
    case Win64EH::UOP_AllocSmall:
    case Win64EH::UOP_AllocMedium:
      if (Location != Start2 && Location != Start3 && Location != IntRegs &&
          Location != FloatRegs && Location != InputArgs &&
          Location != StackAdjust)
        return false;
      // Can have either a single decrement, or a pair of decrements with
      // 4080 and another decrement.
      if (StackOffset == 0)
        StackOffset = Inst.Offset;
      else if (StackOffset != 4080)
        return false;
      else
        StackOffset += Inst.Offset;
      Location = StackAdjust;
      break;
    case Win64EH::UOP_SaveFPLRX:
      // Not allowing FPLRX after StackAdjust; if a StackAdjust is used, it
      // should be followed by a FPLR instead.
      if (Location != Start2 && Location != Start3 && Location != IntRegs &&
          Location != FloatRegs && Location != InputArgs)
        return false;
      StackOffset = Inst.Offset;
      Location = FrameRecord;
      FPLRPair = true;
      break;
    case Win64EH::UOP_SaveFPLR:
      // This can only follow after a StackAdjust
      if (Location != StackAdjust || Inst.Offset != 0)
        return false;
      Location = FrameRecord;
      FPLRPair = true;
      break;
    case Win64EH::UOP_SetFP:
      if (Location != FrameRecord)
        return false;
      Location = End;
      break;
    case Win64EH::UOP_SaveAnyRegI:
    case Win64EH::UOP_SaveAnyRegIP:
    case Win64EH::UOP_SaveAnyRegD:
    case Win64EH::UOP_SaveAnyRegDP:
    case Win64EH::UOP_SaveAnyRegQ:
    case Win64EH::UOP_SaveAnyRegQP:
    case Win64EH::UOP_SaveAnyRegIX:
    case Win64EH::UOP_SaveAnyRegIPX:
    case Win64EH::UOP_SaveAnyRegDX:
    case Win64EH::UOP_SaveAnyRegDPX:
    case Win64EH::UOP_SaveAnyRegQX:
    case Win64EH::UOP_SaveAnyRegQPX:
      // These are never canonical; they don't show up with the usual Arm64
      // calling convention.
      return false;
    case Win64EH::UOP_AllocLarge:
      // Allocations this large can't be represented in packed unwind (and
      // usually don't fit the canonical form anyway because we need to use
      // __chkstk to allocate the stack space).
      return false;
    case Win64EH::UOP_AddFP:
      // "add x29, sp, #N" doesn't show up in the canonical pattern (except for
      // N=0, which is UOP_SetFP).
      return false;
    case Win64EH::UOP_TrapFrame:
    case Win64EH::UOP_Context:
    case Win64EH::UOP_ClearUnwoundToCall:
    case Win64EH::UOP_PushMachFrame:
      // These are special opcodes that aren't normally generated.
      return false;
    default:
      report_fatal_error("Unknown Arm64 unwind opcode");
    }
  }
  if (RegI > 10 || RegF > 8)
    return false;
  if (StandaloneLR && FPLRPair)
    return false;
  if (FPLRPair && Location != End)
    return false;
  if (Nops != 0 && Nops != 4)
    return false;
  if (PAC && !FPLRPair)
    return false;
  int H = Nops == 4;
  // There's an inconsistency regarding packed unwind info with homed
  // parameters; according to the documentation, the epilog shouldn't have
  // the same corresponding nops (and thus, to set the H bit, we should
  // require an epilog which isn't exactly symmetrical - we shouldn't accept
  // an exact mirrored epilog for those cases), but in practice,
  // RtlVirtualUnwind behaves as if it does expect the epilogue to contain
  // the same nops. See https://github.com/llvm/llvm-project/issues/54879.
  // To play it safe, don't produce packed unwind info with homed parameters.
  if (H)
    return false;
  int IntSZ = 8 * RegI;
  if (StandaloneLR)
    IntSZ += 8;
  int FpSZ = 8 * RegF; // RegF not yet decremented
  int SavSZ = (IntSZ + FpSZ + 8 * 8 * H + 0xF) & ~0xF;
  if (Predecrement != SavSZ)
    return false;
  if (FPLRPair && StackOffset < 16)
    return false;
  if (StackOffset % 16)
    return false;
  uint32_t FrameSize = (StackOffset + SavSZ) / 16;
  if (FrameSize > 0x1FF)
    return false;
  assert(RegF != 1 && "One single float reg not allowed");
  if (RegF > 0)
    RegF--; // Convert from actual number of registers, to value stored
  assert(FuncLength <= 0x7FF && "FuncLength should have been checked earlier");
  int Flag = 0x01; // Function segments not supported yet
  int CR = PAC ? 2 : FPLRPair ? 3 : StandaloneLR ? 1 : 0;
  info->PackedInfo |= Flag << 0;
  info->PackedInfo |= (FuncLength & 0x7FF) << 2;
  info->PackedInfo |= (RegF & 0x7) << 13;
  info->PackedInfo |= (RegI & 0xF) << 16;
  info->PackedInfo |= (H & 0x1) << 20;
  info->PackedInfo |= (CR & 0x3) << 21;
  info->PackedInfo |= (FrameSize & 0x1FF) << 23;
  return true;
}

static void ARM64ProcessEpilogs(WinEH::FrameInfo *info,
                                WinEH::FrameInfo::Segment *Seg,
                                uint32_t &TotalCodeBytes,
                                MapVector<MCSymbol *, uint32_t> &EpilogInfo) {

  std::vector<MCSymbol *> EpilogStarts;
  for (auto &I : Seg->Epilogs)
    EpilogStarts.push_back(I.first);

  // Epilogs processed so far.
  std::vector<MCSymbol *> AddedEpilogs;
  for (auto *S : EpilogStarts) {
    MCSymbol *EpilogStart = S;
    auto &EpilogInstrs = info->EpilogMap[S].Instructions;
    uint32_t CodeBytes = ARM64CountOfUnwindCodes(EpilogInstrs);

    MCSymbol* MatchingEpilog =
      FindMatchingEpilog(EpilogInstrs, AddedEpilogs, info);
    int PrologOffset;
    if (MatchingEpilog) {
      assert(EpilogInfo.contains(MatchingEpilog) &&
             "Duplicate epilog not found");
      EpilogInfo[EpilogStart] = EpilogInfo.lookup(MatchingEpilog);
      // Clear the unwind codes in the EpilogMap, so that they don't get output
      // in ARM64EmitUnwindInfoForSegment().
      EpilogInstrs.clear();
    } else if ((PrologOffset = getARM64OffsetInProlog(info->Instructions,
                                                      EpilogInstrs)) >= 0) {
      EpilogInfo[EpilogStart] = PrologOffset;
      // If the segment doesn't have a prolog, an end_c will be emitted before
      // prolog opcodes. So epilog start index in opcodes array is moved by 1.
      if (!Seg->HasProlog)
        EpilogInfo[EpilogStart] += 1;
      // Clear the unwind codes in the EpilogMap, so that they don't get output
      // in ARM64EmitUnwindInfoForSegment().
      EpilogInstrs.clear();
    } else {
      EpilogInfo[EpilogStart] = TotalCodeBytes;
      TotalCodeBytes += CodeBytes;
      AddedEpilogs.push_back(EpilogStart);
    }
  }
}

static void ARM64FindSegmentsInFunction(MCStreamer &streamer,
                                        WinEH::FrameInfo *info,
                                        int64_t RawFuncLength) {
  if (info->PrologEnd)
    checkARM64Instructions(streamer, info->Instructions, info->Begin,
                           info->PrologEnd, info->Function->getName(),
                           "prologue");
  struct EpilogStartEnd {
    MCSymbol *Start;
    int64_t Offset;
    int64_t End;
  };
  // Record Start and End of each epilog.
  SmallVector<struct EpilogStartEnd, 4> Epilogs;
  for (auto &I : info->EpilogMap) {
    MCSymbol *Start = I.first;
    auto &Instrs = I.second.Instructions;
    int64_t Offset = GetAbsDifference(streamer, Start, info->Begin);
    checkARM64Instructions(streamer, Instrs, Start, I.second.End,
                           info->Function->getName(), "epilogue");
    assert((Epilogs.size() == 0 || Offset >= Epilogs.back().End) &&
           "Epilogs should be monotonically ordered");
    // Exclue the end opcode from Instrs.size() when calculating the end of the
    // epilog.
    Epilogs.push_back({Start, Offset, Offset + (int64_t)(Instrs.size() - 1) * 4});
  }

  unsigned E = 0;
  int64_t SegLimit = 0xFFFFC;
  int64_t SegOffset = 0;

  if (RawFuncLength > SegLimit) {

    int64_t RemainingLength = RawFuncLength;

    while (RemainingLength > SegLimit) {
      // Try divide the function into segments, requirements:
      // 1. Segment length <= 0xFFFFC;
      // 2. Each Prologue or Epilogue must be fully within a segment.
      int64_t SegLength = SegLimit;
      int64_t SegEnd = SegOffset + SegLength;
      // Keep record on symbols and offsets of epilogs in this segment.
      MapVector<MCSymbol *, int64_t> EpilogsInSegment;

      while (E < Epilogs.size() && Epilogs[E].End < SegEnd) {
        // Epilogs within current segment.
        EpilogsInSegment[Epilogs[E].Start] = Epilogs[E].Offset;
        ++E;
      }

      // At this point, we have:
      // 1. Put all epilogs in segments already. No action needed here; or
      // 2. Found an epilog that will cross segments boundry. We need to
      //    move back current segment's end boundry, so the epilog is entirely
      //    in the next segment; or
      // 3. Left at least one epilog that is entirely after this segment.
      //    It'll be handled by the next iteration, or the last segment.
      if (E < Epilogs.size() && Epilogs[E].Offset <= SegEnd)
        // Move back current Segment's end boundry.
        SegLength = Epilogs[E].Offset - SegOffset;

      auto Seg = WinEH::FrameInfo::Segment(
          SegOffset, SegLength, /* HasProlog */!SegOffset);
      Seg.Epilogs = std::move(EpilogsInSegment);
      info->Segments.push_back(Seg);

      SegOffset += SegLength;
      RemainingLength -= SegLength;
    }
  }

  // Add the last segment when RawFuncLength > 0xFFFFC,
  // or the only segment otherwise.
  auto LastSeg =
      WinEH::FrameInfo::Segment(SegOffset, RawFuncLength - SegOffset,
                                /* HasProlog */!SegOffset);
  for (; E < Epilogs.size(); ++E)
    LastSeg.Epilogs[Epilogs[E].Start] = Epilogs[E].Offset;
  info->Segments.push_back(LastSeg);
}

static void ARM64EmitUnwindInfoForSegment(MCStreamer &streamer,
                                          WinEH::FrameInfo *info,
                                          WinEH::FrameInfo::Segment &Seg,
                                          bool TryPacked = true) {
  MCContext &context = streamer.getContext();
  MCSymbol *Label = context.createTempSymbol();

  streamer.emitValueToAlignment(Align(4));
  streamer.emitLabel(Label);
  Seg.Symbol = Label;
  // Use the 1st segemnt's label as function's.
  if (Seg.Offset == 0)
    info->Symbol = Label;

  bool HasProlog = Seg.HasProlog;
  bool HasEpilogs = (Seg.Epilogs.size() != 0);

  uint32_t SegLength = (uint32_t)Seg.Length / 4;
  uint32_t PrologCodeBytes = info->PrologCodeBytes;

  int PackedEpilogOffset = HasEpilogs ?
      checkARM64PackedEpilog(streamer, info, &Seg, PrologCodeBytes) : -1;

  // TODO:
  // 1. Enable packed unwind info (.pdata only) for multi-segment functions.
  // 2. Emit packed unwind info (.pdata only) for segments that have neithor
  //    prolog nor epilog.
  if (info->Segments.size() == 1 && PackedEpilogOffset >= 0 &&
      uint32_t(PackedEpilogOffset) < PrologCodeBytes &&
      !info->HandlesExceptions && SegLength <= 0x7ff && TryPacked) {
    // Matching prolog/epilog and no exception handlers; check if the
    // prolog matches the patterns that can be described by the packed
    // format.

    // info->Symbol was already set even if we didn't actually write any
    // unwind info there. Keep using that as indicator that this unwind
    // info has been generated already.
    if (tryARM64PackedUnwind(info, SegLength, PackedEpilogOffset))
      return;
  }

  // If the prolog is not in this segment, we need to emit an end_c, which takes
  // 1 byte, before prolog unwind ops.
  if (!HasProlog) {
    PrologCodeBytes += 1;
    if (PackedEpilogOffset >= 0)
      PackedEpilogOffset += 1;
    // If a segment has neither prolog nor epilog, "With full .xdata record,
    // Epilog Count = 1. Epilog Start Index points to end_c."
    // https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#function-fragments
    // TODO: We can remove this if testing shows zero epilog scope is ok with
    //       MS unwinder.
    if (!HasEpilogs)
      // Pack the fake epilog into phantom prolog.
      PackedEpilogOffset = 0;
  }

  uint32_t TotalCodeBytes = PrologCodeBytes;

  // Process epilogs.
  MapVector<MCSymbol *, uint32_t> EpilogInfo;
  ARM64ProcessEpilogs(info, &Seg, TotalCodeBytes, EpilogInfo);

  // Code Words, Epilog count, E, X, Vers, Function Length
  uint32_t row1 = 0x0;
  uint32_t CodeWords = TotalCodeBytes / 4;
  uint32_t CodeWordsMod = TotalCodeBytes % 4;
  if (CodeWordsMod)
    CodeWords++;
  uint32_t EpilogCount =
      PackedEpilogOffset >= 0 ? PackedEpilogOffset : Seg.Epilogs.size();
  bool ExtensionWord = EpilogCount > 31 || TotalCodeBytes > 124;
  if (!ExtensionWord) {
    row1 |= (EpilogCount & 0x1F) << 22;
    row1 |= (CodeWords & 0x1F) << 27;
  }
  if (info->HandlesExceptions) // X
    row1 |= 1 << 20;
  if (PackedEpilogOffset >= 0) // E
    row1 |= 1 << 21;
  row1 |= SegLength & 0x3FFFF;
  streamer.emitInt32(row1);

  // Extended Code Words, Extended Epilog Count
  if (ExtensionWord) {
    // FIXME: We should be able to split unwind info into multiple sections.
    if (CodeWords > 0xFF || EpilogCount > 0xFFFF)
      report_fatal_error(
          "SEH unwind data splitting is only implemented for large functions, "
          "cases of too many code words or too many epilogs will be done "
          "later");
    uint32_t row2 = 0x0;
    row2 |= (CodeWords & 0xFF) << 16;
    row2 |= (EpilogCount & 0xFFFF);
    streamer.emitInt32(row2);
  }

  if (PackedEpilogOffset < 0) {
    // Epilog Start Index, Epilog Start Offset
    for (auto &I : EpilogInfo) {
      MCSymbol *EpilogStart = I.first;
      uint32_t EpilogIndex = I.second;
      // Epilog offset within the Segment.
      uint32_t EpilogOffset = (uint32_t)(Seg.Epilogs[EpilogStart] - Seg.Offset);
      if (EpilogOffset)
        EpilogOffset /= 4;
      uint32_t row3 = EpilogOffset;
      row3 |= (EpilogIndex & 0x3FF) << 22;
      streamer.emitInt32(row3);
    }
  }

  // Note that even for segments that have no prolog, we still need to emit
  // prolog unwinding opcodes so that the unwinder knows how to unwind from
  // such a segment.
  // The end_c opcode at the start indicates to the unwinder that the actual
  // prolog is outside of the current segment, and the unwinder shouldn't try
  // to check for unwinding from a partial prolog.
  if (!HasProlog)
    // Emit an end_c.
    streamer.emitInt8((uint8_t)0xE5);

  // Emit prolog unwind instructions (in reverse order).
  for (auto Inst : llvm::reverse(info->Instructions))
    ARM64EmitUnwindCode(streamer, Inst);

  // Emit epilog unwind instructions
  for (auto &I : Seg.Epilogs) {
    auto &EpilogInstrs = info->EpilogMap[I.first].Instructions;
    for (const WinEH::Instruction &inst : EpilogInstrs)
      ARM64EmitUnwindCode(streamer, inst);
  }

  int32_t BytesMod = CodeWords * 4 - TotalCodeBytes;
  assert(BytesMod >= 0);
  for (int i = 0; i < BytesMod; i++)
    streamer.emitInt8(0xE3);

  if (info->HandlesExceptions)
    streamer.emitValue(
        MCSymbolRefExpr::create(info->ExceptionHandler,
                                MCSymbolRefExpr::VK_COFF_IMGREL32, context),
        4);
}

// Populate the .xdata section.  The format of .xdata on ARM64 is documented at
// https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling
static void ARM64EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
                                bool TryPacked = true) {
  // If this UNWIND_INFO already has a symbol, it's already been emitted.
  if (info->Symbol)
    return;
  // If there's no unwind info here (not even a terminating UOP_End), the
  // unwind info is considered bogus and skipped. If this was done in
  // response to an explicit .seh_handlerdata, the associated trailing
  // handler data is left orphaned in the xdata section.
  if (info->empty()) {
    info->EmitAttempted = true;
    return;
  }
  if (info->EmitAttempted) {
    // If we tried to emit unwind info before (due to an explicit
    // .seh_handlerdata directive), but skipped it (because there was no
    // valid information to emit at the time), and it later got valid unwind
    // opcodes, we can't emit it here, because the trailing handler data
    // was already emitted elsewhere in the xdata section.
    streamer.getContext().reportError(
        SMLoc(), "Earlier .seh_handlerdata for " + info->Function->getName() +
                     " skipped due to no unwind info at the time "
                     "(.seh_handlerdata too early?), but the function later "
                     "did get unwind info that can't be emitted");
    return;
  }

  simplifyARM64Opcodes(info->Instructions, false);
  for (auto &I : info->EpilogMap)
    simplifyARM64Opcodes(I.second.Instructions, true);

  int64_t RawFuncLength;
  if (!info->FuncletOrFuncEnd) {
    report_fatal_error("FuncletOrFuncEnd not set");
  } else {
    // FIXME: GetAbsDifference tries to compute the length of the function
    // immediately, before the whole file is emitted, but in general
    // that's impossible: the size in bytes of certain assembler directives
    // like .align and .fill is not known until the whole file is parsed and
    // relaxations are applied. Currently, GetAbsDifference fails with a fatal
    // error in that case. (We mostly don't hit this because inline assembly
    // specifying those directives is rare, and we don't normally try to
    // align loops on AArch64.)
    //
    // There are two potential approaches to delaying the computation. One,
    // we could emit something like ".word (endfunc-beginfunc)/4+0x10800000",
    // as long as we have some conservative estimate we could use to prove
    // that we don't need to split the unwind data. Emitting the constant
    // is straightforward, but there's no existing code for estimating the
    // size of the function.
    //
    // The other approach would be to use a dedicated, relaxable fragment,
    // which could grow to accommodate splitting the unwind data if
    // necessary. This is more straightforward, since it automatically works
    // without any new infrastructure, and it's consistent with how we handle
    // relaxation in other contexts.  But it would require some refactoring
    // to move parts of the pdata/xdata emission into the implementation of
    // a fragment. We could probably continue to encode the unwind codes
    // here, but we'd have to emit the pdata, the xdata header, and the
    // epilogue scopes later, since they depend on whether the we need to
    // split the unwind data.
    RawFuncLength = GetAbsDifference(streamer, info->FuncletOrFuncEnd,
                                     info->Begin);
  }

  ARM64FindSegmentsInFunction(streamer, info, RawFuncLength);

  info->PrologCodeBytes = ARM64CountOfUnwindCodes(info->Instructions);
  for (auto &S : info->Segments)
    ARM64EmitUnwindInfoForSegment(streamer, info, S, TryPacked);

  // Clear prolog instructions after unwind info is emitted for all segments.
  info->Instructions.clear();
}

static uint32_t ARMCountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
  uint32_t Count = 0;
  for (const auto &I : Insns) {
    switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
    default:
      llvm_unreachable("Unsupported ARM unwind code");
    case Win64EH::UOP_AllocSmall:
      Count += 1;
      break;
    case Win64EH::UOP_AllocLarge:
      Count += 3;
      break;
    case Win64EH::UOP_AllocHuge:
      Count += 4;
      break;
    case Win64EH::UOP_WideAllocMedium:
      Count += 2;
      break;
    case Win64EH::UOP_WideAllocLarge:
      Count += 3;
      break;
    case Win64EH::UOP_WideAllocHuge:
      Count += 4;
      break;
    case Win64EH::UOP_WideSaveRegMask:
      Count += 2;
      break;
    case Win64EH::UOP_SaveSP:
      Count += 1;
      break;
    case Win64EH::UOP_SaveRegsR4R7LR:
      Count += 1;
      break;
    case Win64EH::UOP_WideSaveRegsR4R11LR:
      Count += 1;
      break;
    case Win64EH::UOP_SaveFRegD8D15:
      Count += 1;
      break;
    case Win64EH::UOP_SaveRegMask:
      Count += 2;
      break;
    case Win64EH::UOP_SaveLR:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegD0D15:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegD16D31:
      Count += 2;
      break;
    case Win64EH::UOP_Nop:
    case Win64EH::UOP_WideNop:
    case Win64EH::UOP_End:
    case Win64EH::UOP_EndNop:
    case Win64EH::UOP_WideEndNop:
      Count += 1;
      break;
    case Win64EH::UOP_Custom: {
      int J;
      for (J = 3; J > 0; J--)
        if (I.Offset & (0xffu << (8 * J)))
          break;
      Count += J + 1;
      break;
    }
    }
  }
  return Count;
}

static uint32_t ARMCountOfInstructionBytes(ArrayRef<WinEH::Instruction> Insns,
                                           bool *HasCustom = nullptr) {
  uint32_t Count = 0;
  for (const auto &I : Insns) {
    switch (static_cast<Win64EH::UnwindOpcodes>(I.Operation)) {
    default:
      llvm_unreachable("Unsupported ARM unwind code");
    case Win64EH::UOP_AllocSmall:
    case Win64EH::UOP_AllocLarge:
    case Win64EH::UOP_AllocHuge:
      Count += 2;
      break;
    case Win64EH::UOP_WideAllocMedium:
    case Win64EH::UOP_WideAllocLarge:
    case Win64EH::UOP_WideAllocHuge:
      Count += 4;
      break;
    case Win64EH::UOP_WideSaveRegMask:
    case Win64EH::UOP_WideSaveRegsR4R11LR:
      Count += 4;
      break;
    case Win64EH::UOP_SaveSP:
      Count += 2;
      break;
    case Win64EH::UOP_SaveRegMask:
    case Win64EH::UOP_SaveRegsR4R7LR:
      Count += 2;
      break;
    case Win64EH::UOP_SaveFRegD8D15:
    case Win64EH::UOP_SaveFRegD0D15:
    case Win64EH::UOP_SaveFRegD16D31:
      Count += 4;
      break;
    case Win64EH::UOP_SaveLR:
      Count += 4;
      break;
    case Win64EH::UOP_Nop:
    case Win64EH::UOP_EndNop:
      Count += 2;
      break;
    case Win64EH::UOP_WideNop:
    case Win64EH::UOP_WideEndNop:
      Count += 4;
      break;
    case Win64EH::UOP_End:
      // This doesn't map to any instruction
      break;
    case Win64EH::UOP_Custom:
      // We can't reason about what instructions this maps to; return a
      // phony number to make sure we don't accidentally do epilog packing.
      Count += 1000;
      if (HasCustom)
        *HasCustom = true;
      break;
    }
  }
  return Count;
}

static void checkARMInstructions(MCStreamer &Streamer,
                                 ArrayRef<WinEH::Instruction> Insns,
                                 const MCSymbol *Begin, const MCSymbol *End,
                                 StringRef Name, StringRef Type) {
  if (!End)
    return;
  std::optional<int64_t> MaybeDistance =
      GetOptionalAbsDifference(Streamer, End, Begin);
  if (!MaybeDistance)
    return;
  uint32_t Distance = (uint32_t)*MaybeDistance;
  bool HasCustom = false;
  uint32_t InstructionBytes = ARMCountOfInstructionBytes(Insns, &HasCustom);
  if (HasCustom)
    return;
  if (Distance != InstructionBytes) {
    Streamer.getContext().reportError(
        SMLoc(), "Incorrect size for " + Name + " " + Type + ": " +
                     Twine(Distance) +
                     " bytes of instructions in range, but .seh directives "
                     "corresponding to " +
                     Twine(InstructionBytes) + " bytes\n");
  }
}

static bool isARMTerminator(const WinEH::Instruction &inst) {
  switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
  case Win64EH::UOP_End:
  case Win64EH::UOP_EndNop:
  case Win64EH::UOP_WideEndNop:
    return true;
  default:
    return false;
  }
}

// Unwind opcode encodings and restrictions are documented at
// https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
static void ARMEmitUnwindCode(MCStreamer &streamer,
                              const WinEH::Instruction &inst) {
  uint32_t w, lr;
  int i;
  switch (static_cast<Win64EH::UnwindOpcodes>(inst.Operation)) {
  default:
    llvm_unreachable("Unsupported ARM unwind code");
  case Win64EH::UOP_AllocSmall:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0x7f);
    streamer.emitInt8(inst.Offset / 4);
    break;
  case Win64EH::UOP_WideSaveRegMask:
    assert((inst.Register & ~0x5fff) == 0);
    lr = (inst.Register >> 14) & 1;
    w = 0x8000 | (inst.Register & 0x1fff) | (lr << 13);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_SaveSP:
    assert(inst.Register <= 0x0f);
    streamer.emitInt8(0xc0 | inst.Register);
    break;
  case Win64EH::UOP_SaveRegsR4R7LR:
    assert(inst.Register >= 4 && inst.Register <= 7);
    assert(inst.Offset <= 1);
    streamer.emitInt8(0xd0 | (inst.Register - 4) | (inst.Offset << 2));
    break;
  case Win64EH::UOP_WideSaveRegsR4R11LR:
    assert(inst.Register >= 8 && inst.Register <= 11);
    assert(inst.Offset <= 1);
    streamer.emitInt8(0xd8 | (inst.Register - 8) | (inst.Offset << 2));
    break;
  case Win64EH::UOP_SaveFRegD8D15:
    assert(inst.Register >= 8 && inst.Register <= 15);
    streamer.emitInt8(0xe0 | (inst.Register - 8));
    break;
  case Win64EH::UOP_WideAllocMedium:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0x3ff);
    w = 0xe800 | (inst.Offset / 4);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_SaveRegMask:
    assert((inst.Register & ~0x40ff) == 0);
    lr = (inst.Register >> 14) & 1;
    w = 0xec00 | (inst.Register & 0x0ff) | (lr << 8);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_SaveLR:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0x0f);
    streamer.emitInt8(0xef);
    streamer.emitInt8(inst.Offset / 4);
    break;
  case Win64EH::UOP_SaveFRegD0D15:
    assert(inst.Register <= 15);
    assert(inst.Offset <= 15);
    assert(inst.Register <= inst.Offset);
    streamer.emitInt8(0xf5);
    streamer.emitInt8((inst.Register << 4) | inst.Offset);
    break;
  case Win64EH::UOP_SaveFRegD16D31:
    assert(inst.Register >= 16 && inst.Register <= 31);
    assert(inst.Offset >= 16 && inst.Offset <= 31);
    assert(inst.Register <= inst.Offset);
    streamer.emitInt8(0xf6);
    streamer.emitInt8(((inst.Register - 16) << 4) | (inst.Offset - 16));
    break;
  case Win64EH::UOP_AllocLarge:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0xffff);
    w = inst.Offset / 4;
    streamer.emitInt8(0xf7);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_AllocHuge:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0xffffff);
    w = inst.Offset / 4;
    streamer.emitInt8(0xf8);
    streamer.emitInt8((w >> 16) & 0xff);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_WideAllocLarge:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0xffff);
    w = inst.Offset / 4;
    streamer.emitInt8(0xf9);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_WideAllocHuge:
    assert((inst.Offset & 3) == 0);
    assert(inst.Offset / 4 <= 0xffffff);
    w = inst.Offset / 4;
    streamer.emitInt8(0xfa);
    streamer.emitInt8((w >> 16) & 0xff);
    streamer.emitInt8((w >> 8) & 0xff);
    streamer.emitInt8((w >> 0) & 0xff);
    break;
  case Win64EH::UOP_Nop:
    streamer.emitInt8(0xfb);
    break;
  case Win64EH::UOP_WideNop:
    streamer.emitInt8(0xfc);
    break;
  case Win64EH::UOP_EndNop:
    streamer.emitInt8(0xfd);
    break;
  case Win64EH::UOP_WideEndNop:
    streamer.emitInt8(0xfe);
    break;
  case Win64EH::UOP_End:
    streamer.emitInt8(0xff);
    break;
  case Win64EH::UOP_Custom:
    for (i = 3; i > 0; i--)
      if (inst.Offset & (0xffu << (8 * i)))
        break;
    for (; i >= 0; i--)
      streamer.emitInt8((inst.Offset >> (8 * i)) & 0xff);
    break;
  }
}

// Check if an epilog exists as a subset of the end of a prolog (backwards).
// An epilog may end with one out of three different end opcodes; if this
// is the first epilog that shares opcodes with the prolog, we can tolerate
// that this opcode differs (and the caller will update the prolog to use
// the same end opcode as the epilog). If another epilog already shares
// opcodes with the prolog, the ending opcode must be a strict match.
static int getARMOffsetInProlog(const std::vector<WinEH::Instruction> &Prolog,
                                const std::vector<WinEH::Instruction> &Epilog,
                                bool CanTweakProlog) {
  // Can't find an epilog as a subset if it is longer than the prolog.
  if (Epilog.size() > Prolog.size())
    return -1;

  // Check that the epilog actually is a perfect match for the end (backwrds)
  // of the prolog.
  // If we can adjust the prolog afterwards, don't check that the end opcodes
  // match.
  int EndIdx = CanTweakProlog ? 1 : 0;
  for (int I = Epilog.size() - 1; I >= EndIdx; I--) {
    // TODO: Could also allow minor mismatches, e.g. "add sp, #16" vs
    // "push {r0-r3}".
    if (Prolog[I] != Epilog[Epilog.size() - 1 - I])
      return -1;
  }

  if (CanTweakProlog) {
    // Check that both prolog and epilog end with an expected end opcode.
    if (Prolog.front().Operation != Win64EH::UOP_End)
      return -1;
    if (Epilog.back().Operation != Win64EH::UOP_End &&
        Epilog.back().Operation != Win64EH::UOP_EndNop &&
        Epilog.back().Operation != Win64EH::UOP_WideEndNop)
      return -1;
  }

  // If the epilog was a subset of the prolog, find its offset.
  if (Epilog.size() == Prolog.size())
    return 0;
  return ARMCountOfUnwindCodes(ArrayRef<WinEH::Instruction>(
      &Prolog[Epilog.size()], Prolog.size() - Epilog.size()));
}

static int checkARMPackedEpilog(MCStreamer &streamer, WinEH::FrameInfo *info,
                                int PrologCodeBytes) {
  // Can only pack if there's one single epilog
  if (info->EpilogMap.size() != 1)
    return -1;

  const WinEH::FrameInfo::Epilog &EpilogInfo = info->EpilogMap.begin()->second;
  // Can only pack if the epilog is unconditional
  if (EpilogInfo.Condition != 0xe) // ARMCC::AL
    return -1;

  const std::vector<WinEH::Instruction> &Epilog = EpilogInfo.Instructions;
  // Make sure we have at least the trailing end opcode
  if (info->Instructions.empty() || Epilog.empty())
    return -1;

  // Check that the epilog actually is at the very end of the function,
  // otherwise it can't be packed.
  std::optional<int64_t> MaybeDistance = GetOptionalAbsDifference(
      streamer, info->FuncletOrFuncEnd, info->EpilogMap.begin()->first);
  if (!MaybeDistance)
    return -1;
  uint32_t DistanceFromEnd = (uint32_t)*MaybeDistance;
  uint32_t InstructionBytes = ARMCountOfInstructionBytes(Epilog);
  if (DistanceFromEnd != InstructionBytes)
    return -1;

  int RetVal = -1;
  // Even if we don't end up sharing opcodes with the prolog, we can still
  // write the offset as a packed offset, if the single epilog is located at
  // the end of the function and the offset (pointing after the prolog) fits
  // as a packed offset.
  if (PrologCodeBytes <= 31 &&
      PrologCodeBytes + ARMCountOfUnwindCodes(Epilog) <= 63)
    RetVal = PrologCodeBytes;

  int Offset =
      getARMOffsetInProlog(info->Instructions, Epilog, /*CanTweakProlog=*/true);
  if (Offset < 0)
    return RetVal;

  // Check that the offset and prolog size fits in the first word; it's
  // unclear whether the epilog count in the extension word can be taken
  // as packed epilog offset.
  if (Offset > 31 || PrologCodeBytes > 63)
    return RetVal;

  // Replace the regular end opcode of the prolog with the one from the
  // epilog.
  info->Instructions.front() = Epilog.back();

  // As we choose to express the epilog as part of the prolog, remove the
  // epilog from the map, so we don't try to emit its opcodes.
  info->EpilogMap.clear();
  return Offset;
}

static bool parseRegMask(unsigned Mask, bool &HasLR, bool &HasR11,
                         unsigned &Folded, int &IntRegs) {
  if (Mask & (1 << 14)) {
    HasLR = true;
    Mask &= ~(1 << 14);
  }
  if (Mask & (1 << 11)) {
    HasR11 = true;
    Mask &= ~(1 << 11);
  }
  Folded = 0;
  IntRegs = -1;
  if (!Mask)
    return true;
  int First = 0;
  // Shift right until we have the bits at the bottom
  while ((Mask & 1) == 0) {
    First++;
    Mask >>= 1;
  }
  if ((Mask & (Mask + 1)) != 0)
    return false; // Not a consecutive series of bits? Can't be packed.
  // Count the bits
  int N = 0;
  while (Mask & (1 << N))
    N++;
  if (First < 4) {
    if (First + N < 4)
      return false;
    Folded = 4 - First;
    N -= Folded;
    First = 4;
  }
  if (First > 4)
    return false; // Can't be packed
  if (N >= 1)
    IntRegs = N - 1;
  return true;
}

static bool tryARMPackedUnwind(MCStreamer &streamer, WinEH::FrameInfo *info,
                               uint32_t FuncLength) {
  int Step = 0;
  bool Homing = false;
  bool HasR11 = false;
  bool HasChain = false;
  bool HasLR = false;
  int IntRegs = -1;   // r4 - r(4+N)
  int FloatRegs = -1; // d8 - d(8+N)
  unsigned PF = 0;    // Number of extra pushed registers
  unsigned StackAdjust = 0;
  // Iterate over the prolog and check that all opcodes exactly match
  // the canonical order and form.
  for (const WinEH::Instruction &Inst : info->Instructions) {
    switch (Inst.Operation) {
    default:
      llvm_unreachable("Unsupported ARM unwind code");
    case Win64EH::UOP_Custom:
    case Win64EH::UOP_AllocLarge:
    case Win64EH::UOP_AllocHuge:
    case Win64EH::UOP_WideAllocLarge:
    case Win64EH::UOP_WideAllocHuge:
    case Win64EH::UOP_SaveFRegD0D15:
    case Win64EH::UOP_SaveFRegD16D31:
      // Can't be packed
      return false;
    case Win64EH::UOP_SaveSP:
      // Can't be packed; we can't rely on restoring sp from r11 when
      // unwinding a packed prologue.
      return false;
    case Win64EH::UOP_SaveLR:
      // Can't be present in a packed prologue
      return false;

    case Win64EH::UOP_End:
    case Win64EH::UOP_EndNop:
    case Win64EH::UOP_WideEndNop:
      if (Step != 0)
        return false;
      Step = 1;
      break;

    case Win64EH::UOP_SaveRegsR4R7LR:
    case Win64EH::UOP_WideSaveRegsR4R11LR:
      // push {r4-r11,lr}
      if (Step != 1 && Step != 2)
        return false;
      assert(Inst.Register >= 4 && Inst.Register <= 11); // r4-rX
      assert(Inst.Offset <= 1);                          // Lr
      IntRegs = Inst.Register - 4;
      if (Inst.Register == 11) {
        HasR11 = true;
        IntRegs--;
      }
      if (Inst.Offset)
        HasLR = true;
      Step = 3;
      break;

    case Win64EH::UOP_SaveRegMask:
      if (Step == 1 && Inst.Register == 0x0f) {
        // push {r0-r3}
        Homing = true;
        Step = 2;
        break;
      }
      [[fallthrough]];
    case Win64EH::UOP_WideSaveRegMask:
      if (Step != 1 && Step != 2)
        return false;
      // push {r4-r9,r11,lr}
      // push {r11,lr}
      // push {r1-r5}
      if (!parseRegMask(Inst.Register, HasLR, HasR11, PF, IntRegs))
        return false;
      Step = 3;
      break;

    case Win64EH::UOP_Nop:
      // mov r11, sp
      if (Step != 3 || !HasR11 || IntRegs >= 0 || PF > 0)
        return false;
      HasChain = true;
      Step = 4;
      break;
    case Win64EH::UOP_WideNop:
      // add.w r11, sp, #xx
      if (Step != 3 || !HasR11 || (IntRegs < 0 && PF == 0))
        return false;
      HasChain = true;
      Step = 4;
      break;

    case Win64EH::UOP_SaveFRegD8D15:
      if (Step != 1 && Step != 2 && Step != 3 && Step != 4)
        return false;
      assert(Inst.Register >= 8 && Inst.Register <= 15);
      if (Inst.Register == 15)
        return false; // Can't pack this case, R==7 means no IntRegs
      if (IntRegs >= 0)
        return false;
      FloatRegs = Inst.Register - 8;
      Step = 5;
      break;

    case Win64EH::UOP_AllocSmall:
    case Win64EH::UOP_WideAllocMedium:
      if (Step != 1 && Step != 2 && Step != 3 && Step != 4 && Step != 5)
        return false;
      if (PF > 0) // Can't have both folded and explicit stack allocation
        return false;
      if (Inst.Offset / 4 >= 0x3f4)
        return false;
      StackAdjust = Inst.Offset / 4;
      Step = 6;
      break;
    }
  }
  if (HasR11 && !HasChain) {
    if (IntRegs + 4 == 10) {
      // r11 stored, but not chaining; can be packed if already saving r4-r10
      // and we can fit r11 into this range.
      IntRegs++;
      HasR11 = false;
    } else
      return false;
  }
  if (HasChain && !HasLR)
    return false;

  // Packed uneind info can't express multiple epilogues.
  if (info->EpilogMap.size() > 1)
    return false;

  unsigned EF = 0;
  int Ret = 0;
  if (info->EpilogMap.size() == 0) {
    Ret = 3; // No epilogue
  } else {
    // As the prologue and epilogue aren't exact mirrors of each other,
    // we have to check the epilogue too and see if it matches what we've
    // concluded from the prologue.
    const WinEH::FrameInfo::Epilog &EpilogInfo =
        info->EpilogMap.begin()->second;
    if (EpilogInfo.Condition != 0xe) // ARMCC::AL
      return false;
    const std::vector<WinEH::Instruction> &Epilog = EpilogInfo.Instructions;
    std::optional<int64_t> MaybeDistance = GetOptionalAbsDifference(
        streamer, info->FuncletOrFuncEnd, info->EpilogMap.begin()->first);
    if (!MaybeDistance)
      return false;
    uint32_t DistanceFromEnd = (uint32_t)*MaybeDistance;
    uint32_t InstructionBytes = ARMCountOfInstructionBytes(Epilog);
    if (DistanceFromEnd != InstructionBytes)
      return false;

    bool GotStackAdjust = false;
    bool GotFloatRegs = false;
    bool GotIntRegs = false;
    bool GotHomingRestore = false;
    bool GotLRRestore = false;
    bool NeedsReturn = false;
    bool GotReturn = false;

    Step = 6;
    for (const WinEH::Instruction &Inst : Epilog) {
      switch (Inst.Operation) {
      default:
        llvm_unreachable("Unsupported ARM unwind code");
      case Win64EH::UOP_Custom:
      case Win64EH::UOP_AllocLarge:
      case Win64EH::UOP_AllocHuge:
      case Win64EH::UOP_WideAllocLarge:
      case Win64EH::UOP_WideAllocHuge:
      case Win64EH::UOP_SaveFRegD0D15:
      case Win64EH::UOP_SaveFRegD16D31:
      case Win64EH::UOP_SaveSP:
      case Win64EH::UOP_Nop:
      case Win64EH::UOP_WideNop:
        // Can't be packed in an epilogue
        return false;

      case Win64EH::UOP_AllocSmall:
      case Win64EH::UOP_WideAllocMedium:
        if (Inst.Offset / 4 >= 0x3f4)
          return false;
        if (Step == 6) {
          if (Homing && FloatRegs < 0 && IntRegs < 0 && StackAdjust == 0 &&
              PF == 0 && Inst.Offset == 16) {
            GotHomingRestore = true;
            Step = 10;
          } else {
            if (StackAdjust > 0) {
              // Got stack adjust in prologue too; must match.
              if (StackAdjust != Inst.Offset / 4)
                return false;
              GotStackAdjust = true;
            } else if (PF == Inst.Offset / 4) {
              // Folded prologue, non-folded epilogue
              StackAdjust = Inst.Offset / 4;
              GotStackAdjust = true;
            } else {
              // StackAdjust == 0 in prologue, mismatch
              return false;
            }
            Step = 7;
          }
        } else if (Step == 7 || Step == 8 || Step == 9) {
          if (!Homing || Inst.Offset != 16)
            return false;
          GotHomingRestore = true;
          Step = 10;
        } else
          return false;
        break;

      case Win64EH::UOP_SaveFRegD8D15:
        if (Step != 6 && Step != 7)
          return false;
        assert(Inst.Register >= 8 && Inst.Register <= 15);
        if (FloatRegs != (int)(Inst.Register - 8))
          return false;
        GotFloatRegs = true;
        Step = 8;
        break;

      case Win64EH::UOP_SaveRegsR4R7LR:
      case Win64EH::UOP_WideSaveRegsR4R11LR: {
        // push {r4-r11,lr}
        if (Step != 6 && Step != 7 && Step != 8)
          return false;
        assert(Inst.Register >= 4 && Inst.Register <= 11); // r4-rX
        assert(Inst.Offset <= 1);                          // Lr
        if (Homing && HasLR) {
          // If homing and LR is backed up, we can either restore LR here
          // and return with Ret == 1 or 2, or return with SaveLR below
          if (Inst.Offset) {
            GotLRRestore = true;
            NeedsReturn = true;
          } else {
            // Expecting a separate SaveLR below
          }
        } else {
          if (HasLR != (Inst.Offset == 1))
            return false;
        }
        GotLRRestore = Inst.Offset == 1;
        if (IntRegs < 0) // This opcode must include r4
          return false;
        int Expected = IntRegs;
        if (HasChain) {
          // Can't express r11 here unless IntRegs describe r4-r10
          if (IntRegs != 6)
            return false;
          Expected++;
        }
        if (Expected != (int)(Inst.Register - 4))
          return false;
        GotIntRegs = true;
        Step = 9;
        break;
      }

      case Win64EH::UOP_SaveRegMask:
      case Win64EH::UOP_WideSaveRegMask: {
        if (Step != 6 && Step != 7 && Step != 8)
          return false;
        // push {r4-r9,r11,lr}
        // push {r11,lr}
        // push {r1-r5}
        bool CurHasLR = false, CurHasR11 = false;
        int Regs;
        if (!parseRegMask(Inst.Register, CurHasLR, CurHasR11, EF, Regs))
          return false;
        if (EF > 0) {
          if (EF != PF && EF != StackAdjust)
            return false;
        }
        if (Homing && HasLR) {
          // If homing and LR is backed up, we can either restore LR here
          // and return with Ret == 1 or 2, or return with SaveLR below
          if (CurHasLR) {
            GotLRRestore = true;
            NeedsReturn = true;
          } else {
            // Expecting a separate SaveLR below
          }
        } else {
          if (CurHasLR != HasLR)
            return false;
          GotLRRestore = CurHasLR;
        }
        int Expected = IntRegs;
        if (HasChain) {
          // If we have chaining, the mask must have included r11.
          if (!CurHasR11)
            return false;
        } else if (Expected == 7) {
          // If we don't have chaining, the mask could still include r11,
          // expressed as part of IntRegs Instead.
          Expected--;
          if (!CurHasR11)
            return false;
        } else {
          // Neither HasChain nor r11 included in IntRegs, must not have r11
          // here either.
          if (CurHasR11)
            return false;
        }
        if (Expected != Regs)
          return false;
        GotIntRegs = true;
        Step = 9;
        break;
      }

      case Win64EH::UOP_SaveLR:
        if (Step != 6 && Step != 7 && Step != 8 && Step != 9)
          return false;
        if (!Homing || Inst.Offset != 20 || GotLRRestore)
          return false;
        GotLRRestore = true;
        GotHomingRestore = true;
        Step = 10;
        break;

      case Win64EH::UOP_EndNop:
      case Win64EH::UOP_WideEndNop:
        GotReturn = true;
        Ret = (Inst.Operation == Win64EH::UOP_EndNop) ? 1 : 2;
        [[fallthrough]];
      case Win64EH::UOP_End:
        if (Step != 6 && Step != 7 && Step != 8 && Step != 9 && Step != 10)
          return false;
        Step = 11;
        break;
      }
    }

    if (Step != 11)
      return false;
    if (StackAdjust > 0 && !GotStackAdjust && EF == 0)
      return false;
    if (FloatRegs >= 0 && !GotFloatRegs)
      return false;
    if (IntRegs >= 0 && !GotIntRegs)
      return false;
    if (Homing && !GotHomingRestore)
      return false;
    if (HasLR && !GotLRRestore)
      return false;
    if (NeedsReturn && !GotReturn)
      return false;
  }

  assert(PF == 0 || EF == 0 ||
         StackAdjust == 0); // Can't have adjust in all three
  if (PF > 0 || EF > 0) {
    StackAdjust = PF > 0 ? (PF - 1) : (EF - 1);
    assert(StackAdjust <= 3);
    StackAdjust |= 0x3f0;
    if (PF > 0)
      StackAdjust |= 1 << 2;
    if (EF > 0)
      StackAdjust |= 1 << 3;
  }

  assert(FuncLength <= 0x7FF && "FuncLength should have been checked earlier");
  int Flag = info->Fragment ? 0x02 : 0x01;
  int H = Homing ? 1 : 0;
  int L = HasLR ? 1 : 0;
  int C = HasChain ? 1 : 0;
  assert(IntRegs < 0 || FloatRegs < 0);
  unsigned Reg, R;
  if (IntRegs >= 0) {
    Reg = IntRegs;
    assert(Reg <= 7);
    R = 0;
  } else if (FloatRegs >= 0) {
    Reg = FloatRegs;
    assert(Reg < 7);
    R = 1;
  } else {
    // No int or float regs stored (except possibly R11,LR)
    Reg = 7;
    R = 1;
  }
  info->PackedInfo |= Flag << 0;
  info->PackedInfo |= (FuncLength & 0x7FF) << 2;
  info->PackedInfo |= (Ret & 0x3) << 13;
  info->PackedInfo |= H << 15;
  info->PackedInfo |= Reg << 16;
  info->PackedInfo |= R << 19;
  info->PackedInfo |= L << 20;
  info->PackedInfo |= C << 21;
  assert(StackAdjust <= 0x3ff);
  info->PackedInfo |= StackAdjust << 22;
  return true;
}

// Populate the .xdata section.  The format of .xdata on ARM is documented at
// https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
static void ARMEmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info,
                              bool TryPacked = true) {
  // If this UNWIND_INFO already has a symbol, it's already been emitted.
  if (info->Symbol)
    return;
  // If there's no unwind info here (not even a terminating UOP_End), the
  // unwind info is considered bogus and skipped. If this was done in
  // response to an explicit .seh_handlerdata, the associated trailing
  // handler data is left orphaned in the xdata section.
  if (info->empty()) {
    info->EmitAttempted = true;
    return;
  }
  if (info->EmitAttempted) {
    // If we tried to emit unwind info before (due to an explicit
    // .seh_handlerdata directive), but skipped it (because there was no
    // valid information to emit at the time), and it later got valid unwind
    // opcodes, we can't emit it here, because the trailing handler data
    // was already emitted elsewhere in the xdata section.
    streamer.getContext().reportError(
        SMLoc(), "Earlier .seh_handlerdata for " + info->Function->getName() +
                     " skipped due to no unwind info at the time "
                     "(.seh_handlerdata too early?), but the function later "
                     "did get unwind info that can't be emitted");
    return;
  }

  MCContext &context = streamer.getContext();
  MCSymbol *Label = context.createTempSymbol();

  streamer.emitValueToAlignment(Align(4));
  streamer.emitLabel(Label);
  info->Symbol = Label;

  if (!info->PrologEnd)
    streamer.getContext().reportError(SMLoc(), "Prologue in " +
                                                   info->Function->getName() +
                                                   " not correctly terminated");

  if (info->PrologEnd && !info->Fragment)
    checkARMInstructions(streamer, info->Instructions, info->Begin,
                         info->PrologEnd, info->Function->getName(),
                         "prologue");
  for (auto &I : info->EpilogMap) {
    MCSymbol *EpilogStart = I.first;
    auto &Epilog = I.second;
    checkARMInstructions(streamer, Epilog.Instructions, EpilogStart, Epilog.End,
                         info->Function->getName(), "epilogue");
    if (Epilog.Instructions.empty() ||
        !isARMTerminator(Epilog.Instructions.back()))
      streamer.getContext().reportError(
          SMLoc(), "Epilogue in " + info->Function->getName() +
                       " not correctly terminated");
  }

  std::optional<int64_t> RawFuncLength;
  const MCExpr *FuncLengthExpr = nullptr;
  if (!info->FuncletOrFuncEnd) {
    report_fatal_error("FuncletOrFuncEnd not set");
  } else {
    // As the size of many thumb2 instructions isn't known until later,
    // we can't always rely on being able to calculate the absolute
    // length of the function here. If we can't calculate it, defer it
    // to a relocation.
    //
    // In such a case, we won't know if the function is too long so that
    // the unwind info would need to be split (but this isn't implemented
    // anyway).
    RawFuncLength =
        GetOptionalAbsDifference(streamer, info->FuncletOrFuncEnd, info->Begin);
    if (!RawFuncLength)
      FuncLengthExpr =
          GetSubDivExpr(streamer, info->FuncletOrFuncEnd, info->Begin, 2);
  }
  uint32_t FuncLength = 0;
  if (RawFuncLength)
    FuncLength = (uint32_t)*RawFuncLength / 2;
  if (FuncLength > 0x3FFFF)
    report_fatal_error("SEH unwind data splitting not yet implemented");
  uint32_t PrologCodeBytes = ARMCountOfUnwindCodes(info->Instructions);
  uint32_t TotalCodeBytes = PrologCodeBytes;

  if (!info->HandlesExceptions && RawFuncLength && FuncLength <= 0x7ff &&
      TryPacked) {
    // No exception handlers; check if the prolog and epilog matches the
    // patterns that can be described by the packed format. If we don't
    // know the exact function length yet, we can't do this.

    // info->Symbol was already set even if we didn't actually write any
    // unwind info there. Keep using that as indicator that this unwind
    // info has been generated already.

    if (tryARMPackedUnwind(streamer, info, FuncLength))
      return;
  }

  int PackedEpilogOffset =
      checkARMPackedEpilog(streamer, info, PrologCodeBytes);

  // Process epilogs.
  MapVector<MCSymbol *, uint32_t> EpilogInfo;
  // Epilogs processed so far.
  std::vector<MCSymbol *> AddedEpilogs;

  bool CanTweakProlog = true;
  for (auto &I : info->EpilogMap) {
    MCSymbol *EpilogStart = I.first;
    auto &EpilogInstrs = I.second.Instructions;
    uint32_t CodeBytes = ARMCountOfUnwindCodes(EpilogInstrs);

    MCSymbol *MatchingEpilog =
        FindMatchingEpilog(EpilogInstrs, AddedEpilogs, info);
    int PrologOffset;
    if (MatchingEpilog) {
      assert(EpilogInfo.contains(MatchingEpilog) &&
             "Duplicate epilog not found");
      EpilogInfo[EpilogStart] = EpilogInfo.lookup(MatchingEpilog);
      // Clear the unwind codes in the EpilogMap, so that they don't get output
      // in the logic below.
      EpilogInstrs.clear();
    } else if ((PrologOffset = getARMOffsetInProlog(
                    info->Instructions, EpilogInstrs, CanTweakProlog)) >= 0) {
      if (CanTweakProlog) {
        // Replace the regular end opcode of the prolog with the one from the
        // epilog.
        info->Instructions.front() = EpilogInstrs.back();
        // Later epilogs need a strict match for the end opcode.
        CanTweakProlog = false;
      }
      EpilogInfo[EpilogStart] = PrologOffset;
      // Clear the unwind codes in the EpilogMap, so that they don't get output
      // in the logic below.
      EpilogInstrs.clear();
    } else {
      EpilogInfo[EpilogStart] = TotalCodeBytes;
      TotalCodeBytes += CodeBytes;
      AddedEpilogs.push_back(EpilogStart);
    }
  }

  // Code Words, Epilog count, F, E, X, Vers, Function Length
  uint32_t row1 = 0x0;
  uint32_t CodeWords = TotalCodeBytes / 4;
  uint32_t CodeWordsMod = TotalCodeBytes % 4;
  if (CodeWordsMod)
    CodeWords++;
  uint32_t EpilogCount =
      PackedEpilogOffset >= 0 ? PackedEpilogOffset : info->EpilogMap.size();
  bool ExtensionWord = EpilogCount > 31 || CodeWords > 15;
  if (!ExtensionWord) {
    row1 |= (EpilogCount & 0x1F) << 23;
    row1 |= (CodeWords & 0x0F) << 28;
  }
  if (info->HandlesExceptions) // X
    row1 |= 1 << 20;
  if (PackedEpilogOffset >= 0) // E
    row1 |= 1 << 21;
  if (info->Fragment) // F
    row1 |= 1 << 22;
  row1 |= FuncLength & 0x3FFFF;
  if (RawFuncLength)
    streamer.emitInt32(row1);
  else
    streamer.emitValue(
        MCBinaryExpr::createOr(FuncLengthExpr,
                               MCConstantExpr::create(row1, context), context),
        4);

  // Extended Code Words, Extended Epilog Count
  if (ExtensionWord) {
    // FIXME: We should be able to split unwind info into multiple sections.
    if (CodeWords > 0xFF || EpilogCount > 0xFFFF)
      report_fatal_error("SEH unwind data splitting not yet implemented");
    uint32_t row2 = 0x0;
    row2 |= (CodeWords & 0xFF) << 16;
    row2 |= (EpilogCount & 0xFFFF);
    streamer.emitInt32(row2);
  }

  if (PackedEpilogOffset < 0) {
    // Epilog Start Index, Epilog Start Offset
    for (auto &I : EpilogInfo) {
      MCSymbol *EpilogStart = I.first;
      uint32_t EpilogIndex = I.second;

      std::optional<int64_t> MaybeEpilogOffset =
          GetOptionalAbsDifference(streamer, EpilogStart, info->Begin);
      const MCExpr *OffsetExpr = nullptr;
      uint32_t EpilogOffset = 0;
      if (MaybeEpilogOffset)
        EpilogOffset = *MaybeEpilogOffset / 2;
      else
        OffsetExpr = GetSubDivExpr(streamer, EpilogStart, info->Begin, 2);

      assert(info->EpilogMap.contains(EpilogStart));
      unsigned Condition = info->EpilogMap[EpilogStart].Condition;
      assert(Condition <= 0xf);

      uint32_t row3 = EpilogOffset;
      row3 |= Condition << 20;
      row3 |= (EpilogIndex & 0x3FF) << 24;
      if (MaybeEpilogOffset)
        streamer.emitInt32(row3);
      else
        streamer.emitValue(
            MCBinaryExpr::createOr(
                OffsetExpr, MCConstantExpr::create(row3, context), context),
            4);
    }
  }

  // Emit prolog unwind instructions (in reverse order).
  uint8_t numInst = info->Instructions.size();
  for (uint8_t c = 0; c < numInst; ++c) {
    WinEH::Instruction inst = info->Instructions.back();
    info->Instructions.pop_back();
    ARMEmitUnwindCode(streamer, inst);
  }

  // Emit epilog unwind instructions
  for (auto &I : info->EpilogMap) {
    auto &EpilogInstrs = I.second.Instructions;
    for (const WinEH::Instruction &inst : EpilogInstrs)
      ARMEmitUnwindCode(streamer, inst);
  }

  int32_t BytesMod = CodeWords * 4 - TotalCodeBytes;
  assert(BytesMod >= 0);
  for (int i = 0; i < BytesMod; i++)
    streamer.emitInt8(0xFB);

  if (info->HandlesExceptions)
    streamer.emitValue(
        MCSymbolRefExpr::create(info->ExceptionHandler,
                                MCSymbolRefExpr::VK_COFF_IMGREL32, context),
        4);
}

static void ARM64EmitRuntimeFunction(MCStreamer &streamer,
                                     const WinEH::FrameInfo *info) {
  MCContext &context = streamer.getContext();

  streamer.emitValueToAlignment(Align(4));
  for (const auto &S : info->Segments) {
    EmitSymbolRefWithOfs(streamer, info->Begin, S.Offset);
    if (info->PackedInfo)
      streamer.emitInt32(info->PackedInfo);
    else
      streamer.emitValue(
          MCSymbolRefExpr::create(S.Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32,
                                  context),
          4);
  }
}


static void ARMEmitRuntimeFunction(MCStreamer &streamer,
                                   const WinEH::FrameInfo *info) {
  MCContext &context = streamer.getContext();

  streamer.emitValueToAlignment(Align(4));
  EmitSymbolRefWithOfs(streamer, info->Begin, info->Begin);
  if (info->PackedInfo)
    streamer.emitInt32(info->PackedInfo);
  else
    streamer.emitValue(
        MCSymbolRefExpr::create(info->Symbol, MCSymbolRefExpr::VK_COFF_IMGREL32,
                                context),
        4);
}

void llvm::Win64EH::ARM64UnwindEmitter::Emit(MCStreamer &Streamer) const {
  // Emit the unwind info structs first.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    WinEH::FrameInfo *Info = CFI.get();
    if (Info->empty())
      continue;
    MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
    Streamer.switchSection(XData);
    ARM64EmitUnwindInfo(Streamer, Info);
  }

  // Now emit RUNTIME_FUNCTION entries.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    WinEH::FrameInfo *Info = CFI.get();
    // ARM64EmitUnwindInfo above clears the info struct, so we can't check
    // empty here. But if a Symbol is set, we should create the corresponding
    // pdata entry.
    if (!Info->Symbol)
      continue;
    MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
    Streamer.switchSection(PData);
    ARM64EmitRuntimeFunction(Streamer, Info);
  }
}

void llvm::Win64EH::ARM64UnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
                                                       WinEH::FrameInfo *info,
                                                       bool HandlerData) const {
  // Called if there's an .seh_handlerdata directive before the end of the
  // function. This forces writing the xdata record already here - and
  // in this case, the function isn't actually ended already, but the xdata
  // record needs to know the function length. In these cases, if the funclet
  // end hasn't been marked yet, the xdata function length won't cover the
  // whole function, only up to this point.
  if (!info->FuncletOrFuncEnd) {
    Streamer.switchSection(info->TextSection);
    info->FuncletOrFuncEnd = Streamer.emitCFILabel();
  }
  // Switch sections (the static function above is meant to be called from
  // here and from Emit().
  MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
  Streamer.switchSection(XData);
  ARM64EmitUnwindInfo(Streamer, info, /* TryPacked = */ !HandlerData);
}

void llvm::Win64EH::ARMUnwindEmitter::Emit(MCStreamer &Streamer) const {
  // Emit the unwind info structs first.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    WinEH::FrameInfo *Info = CFI.get();
    if (Info->empty())
      continue;
    MCSection *XData = Streamer.getAssociatedXDataSection(CFI->TextSection);
    Streamer.switchSection(XData);
    ARMEmitUnwindInfo(Streamer, Info);
  }

  // Now emit RUNTIME_FUNCTION entries.
  for (const auto &CFI : Streamer.getWinFrameInfos()) {
    WinEH::FrameInfo *Info = CFI.get();
    // ARMEmitUnwindInfo above clears the info struct, so we can't check
    // empty here. But if a Symbol is set, we should create the corresponding
    // pdata entry.
    if (!Info->Symbol)
      continue;
    MCSection *PData = Streamer.getAssociatedPDataSection(CFI->TextSection);
    Streamer.switchSection(PData);
    ARMEmitRuntimeFunction(Streamer, Info);
  }
}

void llvm::Win64EH::ARMUnwindEmitter::EmitUnwindInfo(MCStreamer &Streamer,
                                                     WinEH::FrameInfo *info,
                                                     bool HandlerData) const {
  // Called if there's an .seh_handlerdata directive before the end of the
  // function. This forces writing the xdata record already here - and
  // in this case, the function isn't actually ended already, but the xdata
  // record needs to know the function length. In these cases, if the funclet
  // end hasn't been marked yet, the xdata function length won't cover the
  // whole function, only up to this point.
  if (!info->FuncletOrFuncEnd) {
    Streamer.switchSection(info->TextSection);
    info->FuncletOrFuncEnd = Streamer.emitCFILabel();
  }
  // Switch sections (the static function above is meant to be called from
  // here and from Emit().
  MCSection *XData = Streamer.getAssociatedXDataSection(info->TextSection);
  Streamer.switchSection(XData);
  ARMEmitUnwindInfo(Streamer, info, /* TryPacked = */ !HandlerData);
}
