//==-- AArch64MCInstLower.cpp - Convert AArch64 MachineInstr to an MCInst --==//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file contains code to lower AArch64 MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//

#include "AArch64MCInstLower.h"
#include "AArch64MachineFunctionInfo.h"
#include "MCTargetDesc/AArch64MCAsmInfo.h"
#include "Utils/AArch64BaseInfo.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Object/COFF.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
using namespace llvm;
using namespace llvm::object;

extern cl::opt<bool> EnableAArch64ELFLocalDynamicTLSGeneration;

AArch64MCInstLower::AArch64MCInstLower(MCContext &ctx, AsmPrinter &printer)
    : Ctx(ctx), Printer(printer) {}

MCSymbol *
AArch64MCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
  return GetGlobalValueSymbol(MO.getGlobal(), MO.getTargetFlags());
}

MCSymbol *AArch64MCInstLower::GetGlobalValueSymbol(const GlobalValue *GV,
                                                   unsigned TargetFlags) const {
  const Triple &TheTriple = Printer.TM.getTargetTriple();
  if (!TheTriple.isOSBinFormatCOFF())
    return Printer.getSymbolPreferLocal(*GV);

  assert(TheTriple.isOSWindows() &&
         "Windows is the only supported COFF target");

  bool IsIndirect =
      (TargetFlags & (AArch64II::MO_DLLIMPORT | AArch64II::MO_COFFSTUB));
  if (!IsIndirect) {
    // For ARM64EC, symbol lookup in the MSVC linker has limited awareness
    // of ARM64EC mangling ("#"/"$$h"). So object files need to refer to both
    // the mangled and unmangled names of ARM64EC symbols, even if they aren't
    // actually used by any relocations. Emit the necessary references here.
    if (!TheTriple.isWindowsArm64EC() || !isa<Function>(GV) ||
        !GV->hasExternalLinkage())
      return Printer.getSymbol(GV);

    StringRef Name = Printer.getSymbol(GV)->getName();
    // Don't mangle ARM64EC runtime functions.
    static constexpr StringLiteral ExcludedFns[] = {
        "__os_arm64x_check_icall_cfg", "__os_arm64x_dispatch_call_no_redirect",
        "__os_arm64x_check_icall"};
    if (is_contained(ExcludedFns, Name))
      return Printer.getSymbol(GV);

    if (std::optional<std::string> MangledName =
            getArm64ECMangledFunctionName(Name.str())) {
      MCSymbol *MangledSym = Ctx.getOrCreateSymbol(MangledName.value());
      if (!cast<Function>(GV)->hasMetadata("arm64ec_hasguestexit")) {
        Printer.OutStreamer->emitSymbolAttribute(Printer.getSymbol(GV),
                                                 MCSA_WeakAntiDep);
        Printer.OutStreamer->emitAssignment(
            Printer.getSymbol(GV), MCSymbolRefExpr::create(MangledSym, Ctx));
        Printer.OutStreamer->emitSymbolAttribute(MangledSym, MCSA_WeakAntiDep);
        Printer.OutStreamer->emitAssignment(
            MangledSym, MCSymbolRefExpr::create(Printer.getSymbol(GV), Ctx));
      }

      if (TargetFlags & AArch64II::MO_ARM64EC_CALLMANGLE)
        return MangledSym;
    }

    return Printer.getSymbol(GV);
  }

  SmallString<128> Name;

  if ((TargetFlags & AArch64II::MO_DLLIMPORT) &&
      TheTriple.isWindowsArm64EC() &&
      !(TargetFlags & AArch64II::MO_ARM64EC_CALLMANGLE) &&
      isa<Function>(GV)) {
    // __imp_aux is specific to arm64EC; it represents the actual address of
    // an imported function without any thunks.
    //
    // If we see a reference to an "aux" symbol, also emit a reference to the
    // corresponding non-aux symbol.  Otherwise, the Microsoft linker behaves
    // strangely when linking against x64 import libraries.
    //
    // emitSymbolAttribute() doesn't have any real effect here; it just
    // ensures the symbol name appears in the assembly without any
    // side-effects. It might make sense to design a cleaner way to express
    // this.
    Name = "__imp_";
    Printer.TM.getNameWithPrefix(Name, GV,
                                 Printer.getObjFileLowering().getMangler());
    MCSymbol *ExtraSym = Ctx.getOrCreateSymbol(Name);
    Printer.OutStreamer->emitSymbolAttribute(ExtraSym, MCSA_Global);

    Name = "__imp_aux_";
  } else if (TargetFlags & AArch64II::MO_DLLIMPORT) {
    Name = "__imp_";
  } else if (TargetFlags & AArch64II::MO_COFFSTUB) {
    Name = ".refptr.";
  }
  Printer.TM.getNameWithPrefix(Name, GV,
                               Printer.getObjFileLowering().getMangler());

  MCSymbol *MCSym = Ctx.getOrCreateSymbol(Name);

  if (TargetFlags & AArch64II::MO_COFFSTUB) {
    MachineModuleInfoCOFF &MMICOFF =
        Printer.MMI->getObjFileInfo<MachineModuleInfoCOFF>();
    MachineModuleInfoImpl::StubValueTy &StubSym =
        MMICOFF.getGVStubEntry(MCSym);

    if (!StubSym.getPointer())
      StubSym = MachineModuleInfoImpl::StubValueTy(Printer.getSymbol(GV), true);
  }

  return MCSym;
}

MCSymbol *
AArch64MCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
}

MCOperand AArch64MCInstLower::lowerSymbolOperandMachO(const MachineOperand &MO,
                                                      MCSymbol *Sym) const {
  // FIXME: We would like an efficient form for this, so we don't have to do a
  // lot of extra uniquing.
  auto Spec = AArch64::S_None;
  if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      Spec = AArch64::S_MACHO_GOTPAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      Spec = AArch64::S_MACHO_GOTPAGEOFF;
    else
      llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
  } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      Spec = AArch64::S_MACHO_TLVPPAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      Spec = AArch64::S_MACHO_TLVPPAGEOFF;
    else
      llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
  } else {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      Spec = AArch64::S_MACHO_PAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      Spec = AArch64::S_MACHO_PAGEOFF;
  }
  // TODO: Migrate to MCSpecifierExpr::create like ELF.
  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Spec, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
  return MCOperand::createExpr(Expr);
}

MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
                                                    MCSymbol *Sym) const {
  uint32_t RefFlags = 0;

  if (MO.getTargetFlags() & AArch64II::MO_GOT) {
    const MachineFunction *MF = MO.getParent()->getParent()->getParent();
    RefFlags |= (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
                     ? AArch64::S_GOT_AUTH
                     : AArch64::S_GOT);
  } else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
    TLSModel::Model Model;
    if (MO.isGlobal()) {
      const MachineFunction *MF = MO.getParent()->getParent()->getParent();
      if (MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()) {
        Model = TLSModel::GeneralDynamic;
      } else {
        const GlobalValue *GV = MO.getGlobal();
        Model = Printer.TM.getTLSModel(GV);
        if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
            Model == TLSModel::LocalDynamic)
          Model = TLSModel::GeneralDynamic;
      }
    } else {
      assert(MO.isSymbol() &&
             StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
             "unexpected external TLS symbol");
      // The general dynamic access sequence is used to get the
      // address of _TLS_MODULE_BASE_.
      Model = TLSModel::GeneralDynamic;
    }
    switch (Model) {
    case TLSModel::InitialExec:
      RefFlags |= AArch64::S_GOTTPREL;
      break;
    case TLSModel::LocalExec:
      RefFlags |= AArch64::S_TPREL;
      break;
    case TLSModel::LocalDynamic:
      RefFlags |= AArch64::S_DTPREL;
      break;
    case TLSModel::GeneralDynamic: {
      // TODO: it's probably better to introduce MO_TLS_AUTH or smth and avoid
      // running hasELFSignedGOT() every time, but existing flags already
      // cover all 12 bits of SubReg_TargetFlags field in MachineOperand, and
      // making the field wider breaks static assertions.
      const MachineFunction *MF = MO.getParent()->getParent()->getParent();
      RefFlags |= MF->getInfo<AArch64FunctionInfo>()->hasELFSignedGOT()
                      ? AArch64::S_TLSDESC_AUTH
                      : AArch64::S_TLSDESC;
      break;
    }
    }
  } else if (MO.getTargetFlags() & AArch64II::MO_PREL) {
    RefFlags |= AArch64::S_PREL;
  } else {
    // No modifier means this is a generic reference, classified as absolute for
    // the cases where it matters (:abs_g0: etc).
    RefFlags |= AArch64::S_ABS;
  }

  if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
    RefFlags |= AArch64::S_PAGE;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
           AArch64II::MO_PAGEOFF)
    RefFlags |= AArch64::S_PAGEOFF;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
    RefFlags |= AArch64::S_G3;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
    RefFlags |= AArch64::S_G2;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
    RefFlags |= AArch64::S_G1;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
    RefFlags |= AArch64::S_G0;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12)
    RefFlags |= AArch64::S_HI12;

  if (MO.getTargetFlags() & AArch64II::MO_NC)
    RefFlags |= AArch64::S_NC;

  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

  Expr = MCSpecifierExpr::create(Expr, RefFlags, Ctx);
  return MCOperand::createExpr(Expr);
}

MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO,
                                                     MCSymbol *Sym) const {
  uint32_t RefFlags = 0;

  if (MO.getTargetFlags() & AArch64II::MO_TLS) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF)
      RefFlags |= AArch64::S_SECREL_LO12;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_HI12)
      RefFlags |= AArch64::S_SECREL_HI12;

  } else if (MO.getTargetFlags() & AArch64II::MO_S) {
    RefFlags |= AArch64::S_SABS;
  } else {
    RefFlags |= AArch64::S_ABS;

    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      RefFlags |= AArch64::S_PAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      RefFlags |= AArch64::S_PAGEOFF | AArch64::S_NC;
  }

  if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
    RefFlags |= AArch64::S_G3;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
    RefFlags |= AArch64::S_G2;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
    RefFlags |= AArch64::S_G1;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
    RefFlags |= AArch64::S_G0;

  // FIXME: Currently we only set VK_NC for MO_G3/MO_G2/MO_G1/MO_G0. This is
  // because setting VK_NC for others would mean setting their respective
  // RefFlags correctly.  We should do this in a separate patch.
  if (MO.getTargetFlags() & AArch64II::MO_NC) {
    auto MOFrag = (MO.getTargetFlags() & AArch64II::MO_FRAGMENT);
    if (MOFrag == AArch64II::MO_G3 || MOFrag == AArch64II::MO_G2 ||
        MOFrag == AArch64II::MO_G1 || MOFrag == AArch64II::MO_G0)
      RefFlags |= AArch64::S_NC;
  }

  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

  Expr = MCSpecifierExpr::create(Expr, RefFlags, Ctx);
  return MCOperand::createExpr(Expr);
}

MCOperand AArch64MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
                                                 MCSymbol *Sym) const {
  if (Printer.TM.getTargetTriple().isOSBinFormatMachO())
    return lowerSymbolOperandMachO(MO, Sym);
  if (Printer.TM.getTargetTriple().isOSBinFormatCOFF())
    return lowerSymbolOperandCOFF(MO, Sym);

  assert(Printer.TM.getTargetTriple().isOSBinFormatELF() && "Invalid target");
  return lowerSymbolOperandELF(MO, Sym);
}

bool AArch64MCInstLower::lowerOperand(const MachineOperand &MO,
                                      MCOperand &MCOp) const {
  switch (MO.getType()) {
  default:
    llvm_unreachable("unknown operand type");
  case MachineOperand::MO_Register:
    // Ignore all implicit register operands.
    if (MO.isImplicit())
      return false;
    MCOp = MCOperand::createReg(MO.getReg());
    break;
  case MachineOperand::MO_RegisterMask:
    // Regmasks are like implicit defs.
    return false;
  case MachineOperand::MO_Immediate:
    MCOp = MCOperand::createImm(MO.getImm());
    break;
  case MachineOperand::MO_MachineBasicBlock:
    MCOp = MCOperand::createExpr(
        MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
    break;
  case MachineOperand::MO_GlobalAddress:
    MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
    break;
  case MachineOperand::MO_ExternalSymbol:
    MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
    break;
  case MachineOperand::MO_MCSymbol:
    MCOp = LowerSymbolOperand(MO, MO.getMCSymbol());
    break;
  case MachineOperand::MO_JumpTableIndex:
    MCOp = LowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
    break;
  case MachineOperand::MO_ConstantPoolIndex:
    MCOp = LowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
    break;
  case MachineOperand::MO_BlockAddress:
    MCOp = LowerSymbolOperand(
        MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
    break;
  }
  return true;
}

void AArch64MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
  OutMI.setOpcode(MI->getOpcode());

  for (const MachineOperand &MO : MI->operands()) {
    MCOperand MCOp;
    if (lowerOperand(MO, MCOp))
      OutMI.addOperand(MCOp);
  }

  switch (OutMI.getOpcode()) {
  case AArch64::CATCHRET:
    OutMI = MCInst();
    OutMI.setOpcode(AArch64::RET);
    OutMI.addOperand(MCOperand::createReg(AArch64::LR));
    break;
  case AArch64::CLEANUPRET:
    OutMI = MCInst();
    OutMI.setOpcode(AArch64::RET);
    OutMI.addOperand(MCOperand::createReg(AArch64::LR));
    break;
  }
}
