//===-- ARMWinCOFFStreamer.cpp - ARM Target WinCOFF Streamer ----*- C++ -*-===//
//
// 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 "ARMMCTargetDesc.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/MC/MCWinCOFFStreamer.h"

using namespace llvm;

namespace {
class ARMWinCOFFStreamer : public MCWinCOFFStreamer {
  Win64EH::ARMUnwindEmitter EHStreamer;

public:
  ARMWinCOFFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> AB,
                     std::unique_ptr<MCCodeEmitter> CE,
                     std::unique_ptr<MCObjectWriter> OW)
      : MCWinCOFFStreamer(C, std::move(AB), std::move(CE), std::move(OW)) {}

  void emitWinEHHandlerData(SMLoc Loc) override;
  void emitWindowsUnwindTables() override;
  void emitWindowsUnwindTables(WinEH::FrameInfo *Frame) override;

  void emitThumbFunc(MCSymbol *Symbol) override;
  void finishImpl() override;
};

void ARMWinCOFFStreamer::emitWinEHHandlerData(SMLoc Loc) {
  MCStreamer::emitWinEHHandlerData(Loc);

  // We have to emit the unwind info now, because this directive
  // actually switches to the .xdata section!
  EHStreamer.EmitUnwindInfo(*this, getCurrentWinFrameInfo(),
                            /* HandlerData = */ true);
}

void ARMWinCOFFStreamer::emitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
  EHStreamer.EmitUnwindInfo(*this, Frame, /* HandlerData = */ false);
}

void ARMWinCOFFStreamer::emitWindowsUnwindTables() {
  if (!getNumWinFrameInfos())
    return;
  EHStreamer.Emit(*this);
}

void ARMWinCOFFStreamer::emitThumbFunc(MCSymbol *Symbol) {
  getAssembler().setIsThumbFunc(Symbol);
}

void ARMWinCOFFStreamer::finishImpl() {
  emitFrames(nullptr);
  emitWindowsUnwindTables();

  MCWinCOFFStreamer::finishImpl();
}
}

MCStreamer *llvm::createARMWinCOFFStreamer(
    MCContext &Context, std::unique_ptr<MCAsmBackend> &&MAB,
    std::unique_ptr<MCObjectWriter> &&OW,
    std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll,
    bool IncrementalLinkerCompatible) {
  auto *S = new ARMWinCOFFStreamer(Context, std::move(MAB), std::move(Emitter),
                                   std::move(OW));
  S->getAssembler().setIncrementalLinkerCompatible(IncrementalLinkerCompatible);
  return S;
}

namespace {
class ARMTargetWinCOFFStreamer : public llvm::ARMTargetStreamer {
private:
  // True if we are processing SEH directives in an epilogue.
  bool InEpilogCFI = false;

  // Symbol of the current epilog for which we are processing SEH directives.
  MCSymbol *CurrentEpilog = nullptr;

public:
  ARMTargetWinCOFFStreamer(llvm::MCStreamer &S) : ARMTargetStreamer(S) {}

  // The unwind codes on ARM Windows are documented at
  // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
  void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override;
  void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) override;
  void emitARMWinCFISaveSP(unsigned Reg) override;
  void emitARMWinCFISaveFRegs(unsigned First, unsigned Last) override;
  void emitARMWinCFISaveLR(unsigned Offset) override;
  void emitARMWinCFIPrologEnd(bool Fragment) override;
  void emitARMWinCFINop(bool Wide) override;
  void emitARMWinCFIEpilogStart(unsigned Condition) override;
  void emitARMWinCFIEpilogEnd() override;
  void emitARMWinCFICustom(unsigned Opcode) override;

private:
  void emitARMWinUnwindCode(unsigned UnwindCode, int Reg, int Offset);
};

// Helper function to common out unwind code setup for those codes that can
// belong to both prolog and epilog.
void ARMTargetWinCOFFStreamer::emitARMWinUnwindCode(unsigned UnwindCode,
                                                    int Reg, int Offset) {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;
  MCSymbol *Label = S.emitCFILabel();
  auto Inst = WinEH::Instruction(UnwindCode, Label, Reg, Offset);
  if (InEpilogCFI)
    CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
  else
    CurFrame->Instructions.push_back(Inst);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFIAllocStack(unsigned Size,
                                                       bool Wide) {
  unsigned Op = Win64EH::UOP_AllocSmall;
  if (!Wide) {
    if (Size / 4 > 0xffff)
      Op = Win64EH::UOP_AllocHuge;
    else if (Size / 4 > 0x7f)
      Op = Win64EH::UOP_AllocLarge;
  } else {
    Op = Win64EH::UOP_WideAllocMedium;
    if (Size / 4 > 0xffff)
      Op = Win64EH::UOP_WideAllocHuge;
    else if (Size / 4 > 0x3ff)
      Op = Win64EH::UOP_WideAllocLarge;
  }
  emitARMWinUnwindCode(Op, -1, Size);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFISaveRegMask(unsigned Mask,
                                                        bool Wide) {
  assert(Mask != 0);
  int Lr = (Mask & 0x4000) ? 1 : 0;
  Mask &= ~0x4000;
  if (Wide)
    assert((Mask & ~0x1fff) == 0);
  else
    assert((Mask & ~0x00ff) == 0);
  if (Mask && ((Mask + (1 << 4)) & Mask) == 0) {
    if (Wide && (Mask & 0x1000) == 0 && (Mask & 0xff) == 0xf0) {
      // One continuous range from r4 to r8-r11
      for (int I = 11; I >= 8; I--) {
        if (Mask & (1 << I)) {
          emitARMWinUnwindCode(Win64EH::UOP_WideSaveRegsR4R11LR, I, Lr);
          return;
        }
      }
      // If it actually was from r4 to r4-r7, continue below.
    } else if (!Wide) {
      // One continuous range from r4 to r4-r7
      for (int I = 7; I >= 4; I--) {
        if (Mask & (1 << I)) {
          emitARMWinUnwindCode(Win64EH::UOP_SaveRegsR4R7LR, I, Lr);
          return;
        }
      }
      llvm_unreachable("logic error");
    }
  }
  Mask |= Lr << 14;
  if (Wide)
    emitARMWinUnwindCode(Win64EH::UOP_WideSaveRegMask, Mask, 0);
  else
    emitARMWinUnwindCode(Win64EH::UOP_SaveRegMask, Mask, 0);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFISaveSP(unsigned Reg) {
  emitARMWinUnwindCode(Win64EH::UOP_SaveSP, Reg, 0);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFISaveFRegs(unsigned First,
                                                      unsigned Last) {
  assert(First <= Last);
  assert(First >= 16 || Last < 16);
  assert(First <= 31 && Last <= 31);
  if (First == 8)
    emitARMWinUnwindCode(Win64EH::UOP_SaveFRegD8D15, Last, 0);
  else if (First <= 15)
    emitARMWinUnwindCode(Win64EH::UOP_SaveFRegD0D15, First, Last);
  else
    emitARMWinUnwindCode(Win64EH::UOP_SaveFRegD16D31, First, Last);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFISaveLR(unsigned Offset) {
  emitARMWinUnwindCode(Win64EH::UOP_SaveLR, 0, Offset);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFINop(bool Wide) {
  if (Wide)
    emitARMWinUnwindCode(Win64EH::UOP_WideNop, -1, 0);
  else
    emitARMWinUnwindCode(Win64EH::UOP_Nop, -1, 0);
}

void ARMTargetWinCOFFStreamer::emitARMWinCFIPrologEnd(bool Fragment) {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  MCSymbol *Label = S.emitCFILabel();
  CurFrame->PrologEnd = Label;
  WinEH::Instruction Inst =
      WinEH::Instruction(Win64EH::UOP_End, /*Label=*/nullptr, -1, 0);
  auto it = CurFrame->Instructions.begin();
  CurFrame->Instructions.insert(it, Inst);
  CurFrame->Fragment = Fragment;
}

void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  InEpilogCFI = true;
  CurrentEpilog = S.emitCFILabel();
  CurFrame->EpilogMap[CurrentEpilog].Condition = Condition;
}

void ARMTargetWinCOFFStreamer::emitARMWinCFIEpilogEnd() {
  auto &S = getStreamer();
  WinEH::FrameInfo *CurFrame = S.EnsureValidWinFrameInfo(SMLoc());
  if (!CurFrame)
    return;

  if (!CurrentEpilog) {
    S.getContext().reportError(SMLoc(), "Stray .seh_endepilogue in " +
                                            CurFrame->Function->getName());
    return;
  }

  std::vector<WinEH::Instruction> &Epilog =
      CurFrame->EpilogMap[CurrentEpilog].Instructions;

  unsigned UnwindCode = Win64EH::UOP_End;
  if (!Epilog.empty()) {
    WinEH::Instruction EndInstr = Epilog.back();
    if (EndInstr.Operation == Win64EH::UOP_Nop) {
      UnwindCode = Win64EH::UOP_EndNop;
      Epilog.pop_back();
    } else if (EndInstr.Operation == Win64EH::UOP_WideNop) {
      UnwindCode = Win64EH::UOP_WideEndNop;
      Epilog.pop_back();
    }
  }

  InEpilogCFI = false;
  WinEH::Instruction Inst = WinEH::Instruction(UnwindCode, nullptr, -1, 0);
  CurFrame->EpilogMap[CurrentEpilog].Instructions.push_back(Inst);
  MCSymbol *Label = S.emitCFILabel();
  CurFrame->EpilogMap[CurrentEpilog].End = Label;
  CurrentEpilog = nullptr;
}

void ARMTargetWinCOFFStreamer::emitARMWinCFICustom(unsigned Opcode) {
  emitARMWinUnwindCode(Win64EH::UOP_Custom, 0, Opcode);
}

} // end anonymous namespace

MCTargetStreamer *llvm::createARMObjectTargetWinCOFFStreamer(MCStreamer &S) {
  return new ARMTargetWinCOFFStreamer(S);
}
