//===-- 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(TM.getPointerSize(0)) {}

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);
      }
    }
  }
}

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));
      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);
  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);
    if (FV->hasExternalLinkage())
      return MCSpecifierExpr::create(MCSymbolRefExpr::create(Sym, OutContext),
                                     SystemZ::S_VCon, OutContext);
    // Trigger creation of function descriptor in ADA for internal
    // functions.
    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);
  }
}
