//===-- SystemZXPLINKAsmPrinter.cpp - SystemZ XPLINK asm printer ----------===//
//
// 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 implements the SystemZXPLINKAsmPrinter class.
//
//===----------------------------------------------------------------------===//

#include "SystemZXPLINKAsmPrinter.h"
#include "MCTargetDesc/SystemZMCTargetDesc.h"
#include "MCTargetDesc/SystemZTargetStreamer.h"
#include "SystemZFrameLowering.h"
#include "SystemZInstrInfo.h"
#include "SystemZMCInstLower.h"
#include "SystemZMachineFunctionInfo.h"
#include "SystemZSubtarget.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSymbolGOFF.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ConvertEBCDIC.h"
#include "llvm/Support/FormatVariadic.h"

using namespace llvm;

SystemZXPLINKAsmPrinter::SystemZXPLINKAsmPrinter(
    TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
    : SystemZAsmPrinter(TM, std::move(Streamer)), ADATable(8) {}

bool SystemZXPLINKAsmPrinter::doInitialization(Module &M) {
  SM.reset();

  // In HLASM, the only way to represent aliases is to use the
  // extra-label-at-definition strategy. This is similar to the AIX
  // implementation with the additional caveat that all symbol attributes must
  // be emitted before the label is emitted.
  // Construct an aliasing list for each GlobalObject.
  for (const auto &Alias : M.aliases()) {
    const GlobalObject *Aliasee = Alias.getAliaseeObject();
    if (!Aliasee)
      OutContext.reportError(
          {}, "Alias without a base object is not yet supported on z/OS.");

    bool IsFunc = isa<Function>(Aliasee->stripPointerCasts());
    if (IsFunc) {
      if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
        OutContext.reportError({},
                               "Weak alias/reference not supported on z/OS");

      GOAliasMap[Aliasee].push_back(&Alias);
    } else
      OutContext.reportError({},
                             "Only aliases to functions is supported in GOFF.");
  }
  return AsmPrinter::doInitialization(M);
}

// The XPLINK ABI requires that a no-op encoding the call type is emitted after
// each call to a subroutine. This information can be used by the called
// function to determine its entry point, e.g. for generating a backtrace. The
// call type is encoded as a register number in the bcr instruction. See
// enumeration CallType for the possible values.
void SystemZXPLINKAsmPrinter::emitCallInformation(CallType CT) {
  EmitToStreamer(*OutStreamer,
                 MCInstBuilder(SystemZ::BCRAsm)
                     .addImm(0)
                     .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
}

uint32_t
SystemZXPLINKAsmPrinter::AssociatedDataAreaTable::insert(const MCSymbol *Sym,
                                                         unsigned SlotKind) {
  auto Key = std::make_pair(Sym, SlotKind);
  auto It = Displacements.find(Key);

  if (It != Displacements.end())
    return (*It).second;

  // Determine length of descriptor.
  uint32_t Length;
  switch (SlotKind) {
  case SystemZII::MO_ADA_DIRECT_FUNC_DESC:
    Length = 2 * PointerSize;
    break;
  default:
    Length = PointerSize;
    break;
  }

  uint32_t Displacement = NextDisplacement;
  Displacements[std::make_pair(Sym, SlotKind)] = NextDisplacement;
  NextDisplacement += Length;

  return Displacement;
}

uint32_t SystemZXPLINKAsmPrinter::AssociatedDataAreaTable::insert(
    const MachineFunction &MF, const MachineOperand &MO) {
  MCSymbol *Sym;
  if (MO.getType() == MachineOperand::MO_GlobalAddress) {
    const GlobalValue *GV = MO.getGlobal();
    Sym = MF.getTarget().getSymbol(GV);
    assert(Sym && "No symbol");
  } else if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
    const char *SymName = MO.getSymbolName();
    Sym = MF.getContext().getOrCreateSymbol(SymName);
    assert(Sym && "No symbol");
  } else
    llvm_unreachable("Unexpected operand type");

  unsigned ADAslotType = MO.getTargetFlags();
  return insert(Sym, ADAslotType);
}

void SystemZXPLINKAsmPrinter::emitInstruction(const MachineInstr *MI) {
  SystemZMCInstLower Lower(MF->getContext(), *this);
  MCInst LoweredMI;

  switch (MI->getOpcode()) {
  case SystemZ::CallBRASL_XPLINK64:
    EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BRASL)
                                     .addReg(SystemZ::R7D)
                                     .addExpr(Lower.getExpr(MI->getOperand(0),
                                                            SystemZ::S_None)));
    emitCallInformation(CallType::BRASL7);
    return;

  case SystemZ::CallBASR_XPLINK64:
    EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
                                     .addReg(SystemZ::R7D)
                                     .addReg(MI->getOperand(0).getReg()));
    emitCallInformation(CallType::BASR76);
    return;

  case SystemZ::Return_XPLINK:
    LoweredMI =
        MCInstBuilder(SystemZ::B).addReg(SystemZ::R7D).addImm(2).addReg(0);
    break;

  case SystemZ::CondReturn_XPLINK:
    LoweredMI = MCInstBuilder(SystemZ::BC)
                    .addImm(MI->getOperand(0).getImm())
                    .addImm(MI->getOperand(1).getImm())
                    .addReg(SystemZ::R7D)
                    .addImm(2)
                    .addReg(0);
    break;

  case SystemZ::CallBASR_STACKEXT:
    EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
                                     .addReg(SystemZ::R3D)
                                     .addReg(MI->getOperand(0).getReg()));
    emitCallInformation(CallType::BASR33);
    return;

  case SystemZ::ADA_ENTRY_VALUE:
  case SystemZ::ADA_ENTRY: {
    const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
    const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
    uint32_t Disp = ADATable.insert(*MF, MI->getOperand(1));
    Register TargetReg = MI->getOperand(0).getReg();

    Register ADAReg = MI->getOperand(2).getReg();
    Disp += MI->getOperand(3).getImm();
    bool LoadAddr = MI->getOpcode() == SystemZ::ADA_ENTRY;

    unsigned Op0 = LoadAddr ? SystemZ::LA : SystemZ::LG;
    unsigned Op = TII->getOpcodeForOffset(Op0, Disp);

    Register IndexReg = 0;
    if (!Op) {
      if (TargetReg != ADAReg) {
        IndexReg = TargetReg;
        // Use TargetReg to store displacement.
        EmitToStreamer(
            *OutStreamer,
            MCInstBuilder(SystemZ::LLILF).addReg(TargetReg).addImm(Disp));
      } else
        EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::ALGFI)
                                         .addReg(TargetReg)
                                         .addReg(TargetReg)
                                         .addImm(Disp));
      Disp = 0;
      Op = Op0;
    }
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(Op).addReg(TargetReg).addReg(ADAReg).addImm(Disp).addReg(
            IndexReg));
    return;
  }

  default:
    SystemZAsmPrinter::emitInstruction(MI);
    return;
  }
  EmitToStreamer(*OutStreamer, LoweredMI);
}

void SystemZXPLINKAsmPrinter::emitXXStructorList(const DataLayout &DL,
                                                 const Constant *List,
                                                 bool IsCtor) {
  assert(TM.getTargetTriple().isOSBinFormatGOFF() && "Only GOFF supported");

  SmallVector<Structor, 8> Structors;
  preprocessXXStructorList(DL, List, Structors);
  if (Structors.empty())
    return;

  const Align Align = llvm::Align(4);
  const TargetLoweringObjectFileGOFF &Obj =
      static_cast<const TargetLoweringObjectFileGOFF &>(getObjFileLowering());
  for (Structor &S : Structors) {
    MCSectionGOFF *Section =
        static_cast<MCSectionGOFF *>(Obj.getStaticXtorSection(S.Priority));
    OutStreamer->switchSection(Section);
    if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
      emitAlignment(Align);

    // The priority is provided as an input to getStaticXtorSection(), and is
    // recalculated within that function as `Prio` going to going into the
    // PR section.
    // This priority retrieved via the `SortKey` below is the recalculated
    // Priority.
    uint32_t XtorPriority = Section->getPRAttributes().SortKey;

    const GlobalValue *GV = dyn_cast<GlobalValue>(S.Func->stripPointerCasts());
    assert(GV && "C++ xxtor pointer was not a GlobalValue!");
    MCSymbolGOFF *Symbol = static_cast<MCSymbolGOFF *>(getSymbol(GV));

    // @@SQINIT entry: { unsigned prio; void (*ctor)();  void (*dtor)(); }

    unsigned PointerSizeInBytes = DL.getPointerSize();

    auto &Ctx = OutStreamer->getContext();
    const MCExpr *ADAFuncRefExpr;
    unsigned SlotKind = SystemZII::MO_ADA_DIRECT_FUNC_DESC;

    MCSectionGOFF *ADASection =
        static_cast<MCSectionGOFF *>(Obj.getADASection());
    assert(ADASection && "ADA section must exist for GOFF targets!");
    const MCSymbol *ADASym = ADASection->getBeginSymbol();
    assert(ADASym && "ADA symbol should already be set!");

    ADAFuncRefExpr = MCBinaryExpr::createAdd(
        MCSpecifierExpr::create(MCSymbolRefExpr::create(ADASym, OutContext),
                                SystemZ::S_QCon, OutContext),
        MCConstantExpr::create(ADATable.insert(Symbol, SlotKind), Ctx), Ctx);

    emitInt32(XtorPriority);
    if (IsCtor) {
      OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes);
      OutStreamer->emitIntValue(0, PointerSizeInBytes);
    } else {
      OutStreamer->emitIntValue(0, PointerSizeInBytes);
      OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes);
    }
  }
}

void SystemZXPLINKAsmPrinter::emitEndOfAsmFile(Module &M) {
  auto *ZOS = getTargetStreamer();
  emitADASection();
  emitIDRLSection(M);
  // On z/OS, we need to associate an external data reference with an ED
  // symbol, for which we use the the ED of the ADA. We also need to mark the
  // reference as being to data, otherwise we cannot bind with code generated
  // by XL.
  for (auto &GO : M.global_objects()) {
    if (auto *GV = dyn_cast<GlobalVariable>(&GO)) {
      if (!GV->hasInitializer()) {
        MCSymbol *Sym = getSymbol(GV);
        ZOS->emitADA(Sym, OutContext.getObjectFileInfo()->getADASection());
        OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
      }
    }
  }
}

// Emit CELQMAIN in RENT format (see z/OS Language Environment Vendor
// Interfaces, "Program initialization and termination for AMODE 64
// applications"):
//   +0   X'04000001'
//   +8   AD(main entry point)
//   +10  AD(CELQINPL)
//   +18  A(0) / Q(environment); emitted as 8 byte R-con to main, which the
//        binder resolves to the offset of the ADA of main (fits into 4 bytes)
// followed by a reference to the bootstrap routine CELQBST. CELQSTRT only has
// a weak reference to CELQBST, so without it autocall would not include it.
void SystemZXPLINKAsmPrinter::emitCELQMAIN(const Function &MainFn) {
  MCSymbol *MainSym = getSymbol(&MainFn);
  auto ExternalOSSymbol = [&](StringRef Name) {
    MCSymbol *Sym = OutContext.getOrCreateSymbol(Name);
    OutStreamer->emitSymbolAttribute(Sym, MCSA_OSLinkage);
    OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);
    return Sym;
  };
  MCSymbol *CELQINPL = ExternalOSSymbol("CELQINPL");
  MCSymbol *CELQBST = ExternalOSSymbol("CELQBST");

  OutStreamer->pushSection();
  OutStreamer->switchSection(getObjFileLowering().getTextSection());
  OutStreamer->emitValueToAlignment(Align(8));
  MCSymbol *CELQMAIN = OutContext.getOrCreateSymbol("CELQMAIN");
  // Referenced by CELQSTRT, CELQINPL and CELQBST with OS linkage.
  OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_OSLinkage);
  OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_Global);
  OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_Hidden);
  OutStreamer->emitLabel(CELQMAIN);
  OutStreamer->AddComment("CELQMAIN, RENT format");
  OutStreamer->emitInt32(0x04000001);
  OutStreamer->emitInt32(0);
  OutStreamer->AddComment("Address of main");
  OutStreamer->emitValue(MCSymbolRefExpr::create(MainSym, OutContext), 8);
  OutStreamer->AddComment("Address of CELQINPL");
  OutStreamer->emitValue(MCSymbolRefExpr::create(CELQINPL, OutContext), 8);
  OutStreamer->AddComment("Q(environment) of main");
  OutStreamer->emitValue(
      MCSpecifierExpr::create(MCSymbolRefExpr::create(MainSym, OutContext),
                              SystemZ::S_RCon, OutContext),
      8);
  OutStreamer->AddComment("Reference to CELQBST");
  OutStreamer->emitValue(MCSymbolRefExpr::create(CELQBST, OutContext), 8);
  OutStreamer->popSection();
}

void SystemZXPLINKAsmPrinter::emitADASection() {
  OutStreamer->pushSection();

  const unsigned PointerSize = getDataLayout().getPointerSize();
  OutStreamer->switchSection(getObjFileLowering().getADASection());

  auto *ZOS = getTargetStreamer();
  unsigned EmittedBytes = 0;
  for (auto &Entry : ADATable.getTable()) {
    const MCSymbol *Sym;
    unsigned SlotKind;
    std::tie(Sym, SlotKind) = Entry.first;
    unsigned Offset = Entry.second;
    assert(Offset == EmittedBytes && "Offset not as expected");
    (void)EmittedBytes;
#define EMIT_COMMENT(Str)                                                      \
  OutStreamer->AddComment(Twine("Offset ")                                     \
                              .concat(utostr(Offset))                          \
                              .concat(" " Str " ")                             \
                              .concat(Sym->getName()));
    switch (SlotKind) {
    case SystemZII::MO_ADA_DIRECT_FUNC_DESC:
      // Language Environment DLL logic requires function descriptors, for
      // imported functions, that are placed in the ADA to be 8 byte aligned.
      EMIT_COMMENT("function descriptor of");
      OutStreamer->emitValue(
          MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext),
                                  SystemZ::S_RCon, OutContext),
          PointerSize);
      OutStreamer->emitValue(
          MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext),
                                  SystemZ::S_VCon, OutContext),
          PointerSize);
      EmittedBytes += PointerSize * 2;
      break;
    case SystemZII::MO_ADA_DATA_SYMBOL_ADDR:
      EMIT_COMMENT("pointer to data symbol");
      OutStreamer->emitValue(
          MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext),
                                  SystemZ::S_None, OutContext),
          PointerSize);
      EmittedBytes += PointerSize;
      break;
    case SystemZII::MO_ADA_INDIRECT_FUNC_DESC: {
      MCSymbol *Alias = OutContext.getOrCreateSymbol(
          Twine(Sym->getName()).concat("@indirect"));
      OutStreamer->emitSymbolAttribute(Alias, MCSA_IndirectSymbol);
      OutStreamer->emitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
      OutStreamer->emitSymbolAttribute(Alias, MCSA_Global);
      OutStreamer->emitSymbolAttribute(Alias, MCSA_Extern);
      MCSymbolGOFF *GOFFSym =
          static_cast<llvm::MCSymbolGOFF *>(const_cast<llvm::MCSymbol *>(Sym));
      // A weak reference (extern_weak) stays weak through the indirect
      // symbol, otherwise the binder fails on the unresolved reference.
      if (GOFFSym->isWeak())
        OutStreamer->emitSymbolAttribute(Alias, MCSA_WeakReference);
      ZOS->emitExternalName(Alias, GOFFSym->getExternalName());
      EMIT_COMMENT("pointer to function descriptor");
      OutStreamer->emitValue(
          MCSpecifierExpr::create(MCSymbolRefExpr::create(Alias, OutContext),
                                  SystemZ::S_VCon, OutContext),
          PointerSize);
      EmittedBytes += PointerSize;
      break;
    }
    default:
      llvm_unreachable("Unexpected slot kind");
    }
#undef EMIT_COMMENT
  }
  OutStreamer->popSection();
}

static std::string getProductID(Module &M) {
  std::string ProductID;
  if (auto *MD = M.getModuleFlag("zos_product_id"))
    ProductID = cast<MDString>(MD)->getString().str();
  if (ProductID.empty())
    ProductID = "LLVM";
  return ProductID;
}

static uint32_t getProductVersion(Module &M) {
  if (auto *VersionVal = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("zos_product_major_version")))
    return VersionVal->getZExtValue();
  return LLVM_VERSION_MAJOR;
}

static uint32_t getProductRelease(Module &M) {
  if (auto *ReleaseVal = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("zos_product_minor_version")))
    return ReleaseVal->getZExtValue();
  return LLVM_VERSION_MINOR;
}

static uint32_t getProductPatch(Module &M) {
  if (auto *PatchVal = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("zos_product_patchlevel")))
    return PatchVal->getZExtValue();
  return LLVM_VERSION_PATCH;
}

static time_t getTranslationTime(Module &M) {
  std::time_t Time = 0;
  if (auto *Val = mdconst::extract_or_null<ConstantInt>(
          M.getModuleFlag("zos_translation_time"))) {
    long SecondsSinceEpoch = Val->getSExtValue();
    Time = static_cast<time_t>(SecondsSinceEpoch);
  }
  return Time;
}

void SystemZXPLINKAsmPrinter::emitIDRLSection(Module &M) {
  OutStreamer->pushSection();
  OutStreamer->switchSection(getObjFileLowering().getIDRLSection());
  constexpr unsigned IDRLDataLength = 30;
  std::time_t Time = getTranslationTime(M);

  uint32_t ProductVersion = getProductVersion(M);
  uint32_t ProductRelease = getProductRelease(M);

  std::string ProductID = getProductID(M);

  SmallString<IDRLDataLength + 1> TempStr;
  raw_svector_ostream O(TempStr);
  O << formatv("{0,-10}{1,0-2:d}{2,0-2:d}{3:%Y%m%d%H%M%S}{4,0-2}",
               ProductID.substr(0, 10).c_str(), ProductVersion, ProductRelease,
               llvm::sys::toUtcTime(Time), "0");
  SmallString<IDRLDataLength> Data;
  ConverterEBCDIC::convertToEBCDIC(TempStr, Data);

  OutStreamer->emitInt8(0);               // Reserved.
  OutStreamer->emitInt8(3);               // Format.
  OutStreamer->emitInt16(IDRLDataLength); // Length.
  OutStreamer->emitBytes(Data.str());
  OutStreamer->popSection();
}

void SystemZXPLINKAsmPrinter::emitFunctionBodyEnd() {
  // Emit symbol for the end of function if the z/OS target streamer
  // is used. This is needed to calculate the size of the function.
  auto *ZOS = getTargetStreamer();
  OutStreamer->emitLabel(ZOS->DeferredPPA1.back().FnEnd);
}

// Determine the end of the prolog and the instructions which updates the stack
// register, and attach symbols to those instructions.
static void determinePrologueStackUpdateSym(MachineFunction *MF,
                                            MCSymbol *&EndOfPrologSym,
                                            MCSymbol *&StackUpdateSym) {
  EndOfPrologSym = nullptr;
  StackUpdateSym = nullptr;

  // Scan the basic block for the FENCE instruction which marks the end
  // of the prologue. We know
  // the prologue is spread at most across the first 3 basic blocks. Also record
  // the first instruction updating the stack pointer.
  const SystemZSubtarget &STI = MF->getSubtarget<SystemZSubtarget>();
  auto &Regs = STI.getSpecialRegisters<SystemZXPLINK64Registers>();
  MachineInstr *EndOfPrologMI = nullptr;
  MachineInstr *StackUpdateMI = nullptr;
  unsigned BBCount = 1;

  for (auto &MBB : *MF) {
    for (auto &I : MBB) {
      if (I.getOpcode() == SystemZ::FENCE)
        EndOfPrologMI = &I;
      else if (!StackUpdateMI) {
        unsigned Opcode = I.getOpcode();
        // TODO: We can instead emit a pseudo instruction in
        // SystemZFrameLowering to represent a stack adjustment instruction, and
        // check for that here, instead of having to check for multiple
        // instructions.
        if ((Opcode == SystemZ::AGHI || Opcode == SystemZ::AGFI) &&
            I.getOperand(0).getReg() == Regs.getStackPointerRegister())
          StackUpdateMI = &I;
      }
    }

    // Prologue can be a max of 3 BBs if we need to call stack extension code
    if (EndOfPrologMI || BBCount == 3)
      break;

    ++BBCount;
  }

  // Leaf functions do not have a prologue.
  if (EndOfPrologMI == nullptr)
    return;

#ifdef EXPENSIVE_CHECKS
  // Check that the prolog length is valid.
  auto *TII = STI.getInstrInfo();
  size_t Size = 0;

  for (auto &MBB : *MF) {
    bool TerminateLoop = false;
    for (auto &I : MBB) {
      Size += TII->getInstSizeInBytes(I);
      if (&I == EndOfPrologMI) {
        TerminateLoop = true;
        break;
      }
    }
    if (TerminateLoop)
      break;
  }
  if (Size > 128)
    report_fatal_error(
        Twine(MF->getName()).concat(": Prolog exceeds 128 bytes"));
#endif

  // Attach a temporary symbol to mark the end of the prolog.
  EndOfPrologSym = MF->getContext().createTempSymbol("end_of_prologue");
  EndOfPrologMI->setPostInstrSymbol(*MF, EndOfPrologSym);

  if (StackUpdateMI) {
    StackUpdateSym = MF->getContext().createTempSymbol("stack_update");
    StackUpdateMI->setPreInstrSymbol(*MF, StackUpdateSym);
  }
}

void SystemZXPLINKAsmPrinter::calculatePPA1() {
  auto *ZOS = getTargetStreamer();
  assert(ZOS->PPA2Sym != nullptr && "PPA2 Symbol not defined");

  SystemZTargetzOSStreamer::PPA1Info Info;

  const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
  const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();

  const SystemZMachineFunctionInfo *ZFI =
      MF->getInfo<SystemZMachineFunctionInfo>();
  const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
      Subtarget.getFrameLowering());
  const MachineFrameInfo &MFFrame = MF->getFrameInfo();

  // Get saved GPR/FPR/VPR masks.
  const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
  uint16_t SavedGPRMask = 0;
  uint16_t SavedFPRMask = 0;
  uint8_t SavedVRMask = 0;
  int64_t OffsetFPR = 0;
  int64_t OffsetVR = 0;
  const int64_t TopOfStack =
      MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();

  // Loop over the spilled registers. The CalleeSavedInfo can't be used because
  // it does not contain all spilled registers.
  for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
                E = ZFI->getSpillGPRRegs().HighGPR;
       I && E && I <= E; ++I) {
    unsigned V = TRI->getEncodingValue((Register)I);
    assert(V < 16 && "GPR index out of range");
    SavedGPRMask |= 1 << (15 - V);
  }

  for (auto &CS : CSI) {
    unsigned Reg = CS.getReg();
    unsigned I = TRI->getEncodingValue(Reg);

    if (SystemZ::FP64BitRegClass.contains(Reg)) {
      assert(I < 16 && "FPR index out of range");
      SavedFPRMask |= 1 << (15 - I);
      int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
      if (Temp < OffsetFPR)
        OffsetFPR = Temp;
    } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
      assert(I >= 16 && I <= 23 && "VPR index out of range");
      unsigned BitNum = I - 16;
      SavedVRMask |= 1 << (7 - BitNum);
      int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
      if (Temp < OffsetVR)
        OffsetVR = Temp;
    }
  }

  // Adjust the offset.
  OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
  OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;

  // Get alloca register.
  uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
  uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
  assert(AllocaReg < 16 && "Can't have alloca register larger than 15");

  MCSymbol *PersonalityRoutine = nullptr;
  MCSymbol *GCCEH = nullptr;
  uint64_t PersonalityADADisp = 0;
  uint64_t GCCEHADADisp = 0;
  if (!MF->getLandingPads().empty()) {
    const Function *Per = dyn_cast<Function>(
        MF->getFunction().getPersonalityFn()->stripPointerCasts());
    PersonalityRoutine = Per ? MF->getTarget().getSymbol(Per) : nullptr;
    if (PersonalityRoutine) {
      GCCEH = MF->getContext().getOrCreateSymbol(
          Twine("GCC_except_table") + Twine(MF->getFunctionNumber()));
      PersonalityADADisp = ADATable.insert(
          PersonalityRoutine, SystemZII::MO_ADA_INDIRECT_FUNC_DESC);
      GCCEHADADisp = ADATable.insert(GCCEH, SystemZII::MO_ADA_DATA_SYMBOL_ADDR);
    }
  }

  // Get the name of the function, with suffix _.
  std::string N(MF->getFunction().hasName()
                    ? Twine(MF->getFunction().getName()).concat("_").str()
                    : "");

  // Calculate the lables for the prolog size and the stack update symbol.
  MCSymbol *EndOfPrologSym;
  MCSymbol *StackUpdateSym;
  determinePrologueStackUpdateSym(MF, EndOfPrologSym, StackUpdateSym);

  // Save the calculated values.
  if (MF->getFunction().hasFnAttribute("zos-ppa1-name"))
    Info.Name =
        MF->getFunction().getFnAttribute("zos-ppa1-name").getValueAsString();
  else if (MF->getFunction().hasName())
    Info.Name = MF->getFunction().getName();

  Info.PPA1 = OutContext.createTempSymbol(Twine("PPA1_").concat(N), true);
  Info.EPMarker = OutContext.createTempSymbol(Twine("EPM_").concat(N), true);
  Info.FnEnd = OutContext.createTempSymbol(Twine(N).concat("end_"));
  Info.Fn = CurrentFnSym;
  Info.EndOfProlog = EndOfPrologSym;
  Info.StackUpdate = StackUpdateSym;
  Info.PersonalityADADisp = PersonalityADADisp;
  Info.GCCEHADADisp = GCCEHADADisp;
  Info.OffsetFPR = OffsetFPR;
  Info.OffsetVR = OffsetVR;
  Info.CallFrameSize = MFFrame.getMaxCallFrameSize();
  Info.SizeOfFnParams = ZFI->getSizeOfFnParams();
  Info.SavedGPRMask = SavedGPRMask;
  Info.SavedFPRMask = SavedFPRMask;
  Info.SavedVRMask = SavedVRMask;
  Info.FrameReg = FrameReg;
  Info.AllocaReg = AllocaReg;
  Info.IsVarArg = MF->getFunction().isVarArg();
  Info.HasStackProtector = MFFrame.hasStackProtectorIndex();

  ZOS->DeferredPPA1.push_back(Info);
}

void SystemZXPLINKAsmPrinter::emitStartOfAsmFile(Module &M) {
  emitPPA2(M);
  // A main program needs CELQMAIN, through which the Language Environment
  // startup (CELQSTRT) finds the main routine and its environment. It is
  // emitted here and not at the end of the file, because the text section
  // may already be closed then (e.g. after emitting the DWARF aranges).
  if (const Function *MainFn = M.getFunction("main");
      MainFn && !MainFn->isDeclaration())
    emitCELQMAIN(*MainFn);
  AsmPrinter::emitStartOfAsmFile(M);
}

void SystemZXPLINKAsmPrinter::emitPPA2(Module &M) {
  auto *ZOS = getTargetStreamer();
  OutStreamer->pushSection();
  OutStreamer->switchSection(getObjFileLowering().getTextSection());
  MCContext &OutContext = OutStreamer->getContext();
  // Make CELQSTRT symbol.
  const char *StartSymbolName = "CELQSTRT";
  MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
  OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
  OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);

  // Create symbol and assign to streamer field for use in PPA1.
  ZOS->PPA2Sym = OutContext.createTempSymbol("PPA2", false);
  MCSymbol *PPA2Sym = ZOS->PPA2Sym;
  MCSymbol *DateVersionSym = OutContext.createTempSymbol("DVS", false);

  std::time_t Time = getTranslationTime(M);
  SmallString<14> CompilationTimeEBCDIC, CompilationTime;
  CompilationTime = formatv("{0:%Y%m%d%H%M%S}", llvm::sys::toUtcTime(Time));

  uint32_t ProductVersion = getProductVersion(M),
           ProductRelease = getProductRelease(M),
           ProductPatch = getProductPatch(M);

  SmallString<6> VersionEBCDIC, Version;
  Version = formatv("{0,0+2:d}{1,0+2:d}{2,0+2:d}", ProductVersion,
                    ProductRelease, ProductPatch);

  ConverterEBCDIC::convertToEBCDIC(CompilationTime, CompilationTimeEBCDIC);
  ConverterEBCDIC::convertToEBCDIC(Version, VersionEBCDIC);

  enum class PPA2MemberId : uint8_t {
    // See z/OS Language Environment Vendor Interfaces v2r5, p.23, for
    // complete list. Only the C runtime is supported by this backend.
    LE_C_Runtime = 3,
  };
  enum class PPA2MemberSubId : uint8_t {
    // List of languages using the LE C runtime implementation.
    C = 0x00,
    CXX = 0x01,
    Swift = 0x03,
    Go = 0x60,
    LLVMBasedLang = 0xe7,
  };
  // PPA2 Flags
  enum class PPA2Flags : uint8_t {
    CompileForBinaryFloatingPoint = 0x80,
    CompiledWithXPLink = 0x01,
    CompiledUnitASCII = 0x04,
    HasServiceInfo = 0x20,
  };

  PPA2MemberSubId MemberSubId = PPA2MemberSubId::LLVMBasedLang;
  if (auto *MD = M.getModuleFlag("zos_cu_language")) {
    StringRef Language = cast<MDString>(MD)->getString();
    MemberSubId = StringSwitch<PPA2MemberSubId>(Language)
                      .Case("C", PPA2MemberSubId::C)
                      .Case("C++", PPA2MemberSubId::CXX)
                      .Case("Swift", PPA2MemberSubId::Swift)
                      .Case("Go", PPA2MemberSubId::Go)
                      .Default(PPA2MemberSubId::LLVMBasedLang);
  }

  // Emit PPA2 section.
  OutStreamer->emitLabel(PPA2Sym);
  OutStreamer->emitInt8(static_cast<uint8_t>(PPA2MemberId::LE_C_Runtime));
  OutStreamer->emitInt8(static_cast<uint8_t>(MemberSubId));
  OutStreamer->emitInt8(0x22); // Member defined, c370_plist+c370_env
  OutStreamer->emitInt8(0x04); // Control level 4 (XPLink)
  OutStreamer->emitAbsoluteSymbolDiff(CELQSTRT, PPA2Sym, 4);
  OutStreamer->emitInt32(0x00000000);
  OutStreamer->emitAbsoluteSymbolDiff(DateVersionSym, PPA2Sym, 4);
  OutStreamer->emitInt32(
      0x00000000); // Offset to main entry point, always 0 (so says TR).
  uint8_t Flgs = static_cast<uint8_t>(PPA2Flags::CompileForBinaryFloatingPoint);
  Flgs |= static_cast<uint8_t>(PPA2Flags::CompiledWithXPLink);

  bool IsASCII = true;
  if (auto *MD = M.getModuleFlag("zos_le_char_mode")) {
    const StringRef &CharMode = cast<MDString>(MD)->getString();
    if (CharMode == "ebcdic")
      IsASCII = false;
    else if (CharMode != "ascii")
      OutContext.reportError(
          {}, "Only ascii or ebcdic are allowed for zos_le_char_mode");
  }
  if (IsASCII)
    Flgs |= static_cast<uint8_t>(
        PPA2Flags::CompiledUnitASCII); // Setting bit for ASCII char. mode.

  OutStreamer->emitInt8(Flgs);
  OutStreamer->emitInt8(0x00);    // Reserved.
                                  // No MD5 signature before timestamp.
                                  // No FLOAT(AFP(VOLATILE)).
                                  // Remaining 5 flag bits reserved.
  OutStreamer->emitInt16(0x0000); // 16 Reserved flag bits.

  // Emit date and version section.
  OutStreamer->emitLabel(DateVersionSym);
  OutStreamer->emitBytes(CompilationTimeEBCDIC.str());
  OutStreamer->emitBytes(VersionEBCDIC.str());

  OutStreamer->emitInt16(0x0000); // Service level string length.

  // The binder requires that the offset to the PPA2 be emitted in a different,
  // specially-named section.
  OutStreamer->switchSection(getObjFileLowering().getPPA2ListSection());
  // Emit 8 byte alignment.
  // Emit pointer to PPA2 label.
  OutStreamer->AddComment("A(PPA2-CELQSTRT)");
  OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CELQSTRT, 8);
  OutStreamer->popSection();
}

void SystemZXPLINKAsmPrinter::emitGlobalAlias(const Module &M,
                                              const GlobalAlias &GA) {
  if (!TM.getTargetTriple().isOSzOS())
    return AsmPrinter::emitGlobalAlias(M, GA);

  // Aliased function labels have already been emitted for z/OS
}

const MCExpr *SystemZXPLINKAsmPrinter::lowerConstant(const Constant *CV,
                                                     const Constant *BaseCV,
                                                     uint64_t Offset) {
  const GlobalAlias *GA = dyn_cast<GlobalAlias>(CV);
  const GlobalVariable *GV = dyn_cast<GlobalVariable>(CV);
  const Function *FV = dyn_cast<Function>(CV);
  bool IsFunc = !GV && (FV || (GA && isa<Function>(GA->getAliaseeObject())));

  MCSymbol *Sym = NULL;

  if (GA)
    Sym = getSymbol(GA);
  else if (IsFunc)
    Sym = getSymbol(FV);
  else if (GV)
    Sym = getSymbol(GV);

  if (IsFunc) {
    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
    // A function pointer must point to a function descriptor (a V-con would
    // yield the entry point instead), and it must compare equal to the address
    // of the same function taken in code. For a function that is not internal,
    // code loads the address of the descriptor from an ADA slot that refers to
    // the indirect symbol; the binder resolves that reference to the function
    // descriptor. Use the same reference here. The slot is shared with code
    // taking the address and defines the indirect symbol.
    const GlobalValue *FGV = GA ? static_cast<const GlobalValue *>(GA)
                                : static_cast<const GlobalValue *>(FV);
    if (!FGV->hasLocalLinkage()) {
      ADATable.insert(Sym, SystemZII::MO_ADA_INDIRECT_FUNC_DESC);
      MCSymbol *Alias = OutContext.getOrCreateSymbol(
          Twine(Sym->getName()).concat("@indirect"));
      return MCSpecifierExpr::create(MCSymbolRefExpr::create(Alias, OutContext),
                                     SystemZ::S_VCon, OutContext);
    }
    // Internal functions: function descriptor in the ADA.
    unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
    return MCBinaryExpr::createAdd(
        MCSpecifierExpr::create(
            MCSymbolRefExpr::create(
                getObjFileLowering().getADASection()->getBeginSymbol(),
                OutContext),
            SystemZ::S_None, OutContext),
        MCConstantExpr::create(Disp, OutContext), OutContext);
  }
  if (Sym) {
    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
    return MCSymbolRefExpr::create(Sym, OutContext);
  }
  return AsmPrinter::lowerConstant(CV);
}

void SystemZXPLINKAsmPrinter::emitFunctionEntryLabel() {
  auto *ZOS = getTargetStreamer();
  calculatePPA1();

  // EntryPoint Marker
  const MachineFrameInfo &MFFrame = MF->getFrameInfo();
  bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
  uint32_t DSASize = MFFrame.getStackSize();
  bool IsLeaf = DSASize == 0 && MFFrame.getCalleeSavedInfo().empty();

  // Set Flags.
  uint8_t Flags = 0;
  if (IsLeaf)
    Flags |= 0x08;
  if (IsUsingAlloca)
    Flags |= 0x04;

  // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
  uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
  DSAAndFlags |= Flags;

  // Emit entry point marker section.
  OutStreamer->AddComment("XPLINK Routine Layout Entry");
  OutStreamer->emitLabel(ZOS->DeferredPPA1.back().EPMarker);
  OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
  OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
  OutStreamer->AddComment("Mark Type C'1'");
  OutStreamer->emitInt8(0xF1); // Mark Type.
  OutStreamer->AddComment("Offset to PPA1");
  OutStreamer->emitAbsoluteSymbolDiff(ZOS->DeferredPPA1.back().PPA1,
                                      ZOS->DeferredPPA1.back().EPMarker, 4);
  if (OutStreamer->isVerboseAsm()) {
    OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
    OutStreamer->AddComment("Entry Flags");
    if (Flags & 0x08)
      OutStreamer->AddComment("  Bit 1: 1 = Leaf function");
    else
      OutStreamer->AddComment("  Bit 1: 0 = Non-leaf function");
    if (Flags & 0x04)
      OutStreamer->AddComment("  Bit 2: 1 = Uses alloca");
    else
      OutStreamer->AddComment("  Bit 2: 0 = Does not use alloca");
  }
  OutStreamer->emitInt32(DSAAndFlags);

  ZOS->emitADA(CurrentFnSym, getObjFileLowering().getADASection());

  AsmPrinter::emitFunctionEntryLabel();

  const Function *F = &MF->getFunction();
  // Emit aliasing label for function entry point label.
  for (const GlobalAlias *Alias : GOAliasMap[F]) {
    MCSymbol *Sym = getSymbol(Alias);
    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
    emitVisibility(Sym, Alias->getVisibility());
    emitLinkage(Alias, Sym);
    OutStreamer->emitLabel(Sym);
  }
}
