//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
//
// 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 a printer that converts from our internal representation
// of machine-dependent LLVM code to PowerPC assembly language. This printer is
// the output mechanism used by `llc'.
//
// Documentation at http://developer.apple.com/documentation/DeveloperTools/
// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/PPCInstPrinter.h"
#include "MCTargetDesc/PPCMCAsmInfo.h"
#include "MCTargetDesc/PPCMCTargetDesc.h"
#include "MCTargetDesc/PPCPredicates.h"
#include "MCTargetDesc/PPCTargetStreamer.h"
#include "PPC.h"
#include "PPCInstrInfo.h"
#include "PPCMachineFunctionInfo.h"
#include "PPCSubtarget.h"
#include "PPCTargetMachine.h"
#include "TargetInfo/PowerPCTargetInfo.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/StackMaps.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCSymbolXCOFF.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/PPCTargetParser.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <cassert>
#include <cstdint>
#include <memory>
#include <new>

using namespace llvm;
using namespace llvm::XCOFF;
using namespace PatternMatch;

#define DEBUG_TYPE "asmprinter"

STATISTIC(NumTOCEntries, "Number of Total TOC Entries Emitted.");
STATISTIC(NumTOCConstPool, "Number of Constant Pool TOC Entries.");
STATISTIC(NumTOCGlobalInternal,
          "Number of Internal Linkage Global TOC Entries.");
STATISTIC(NumTOCGlobalExternal,
          "Number of External Linkage Global TOC Entries.");
STATISTIC(NumTOCJumpTable, "Number of Jump Table TOC Entries.");
STATISTIC(NumTOCThreadLocal, "Number of Thread Local TOC Entries.");
STATISTIC(NumTOCBlockAddress, "Number of Block Address TOC Entries.");
STATISTIC(NumTOCEHBlock, "Number of EH Block TOC Entries.");

static cl::opt<bool> EnableSSPCanaryBitInTB(
    "aix-ssp-tb-bit", cl::init(false),
    cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden);

static cl::opt<bool> IFuncLocalIfProven(
    "ifunc-local-if-proven", cl::init(false),
    cl::desc("During ifunc lowering, the compiler assumes the resolver returns "
             "dso-local functions and bails out if non-local functions are "
             "detected; this flag flips the assumption: resolver returns "
             "preemptible functions unless the compiler can prove all paths "
             "return local functions."),
    cl::Hidden);

// this flag is used for testing only as it might generate bad code.
static cl::opt<bool> IFuncWarnInsteadOfError("test-ifunc-warn-noerror",
                                             cl::init(false), cl::ReallyHidden);

// Specialize DenseMapInfo to allow
// std::pair<const MCSymbol *, PPCMCExpr::Specifier> in DenseMap.
// This specialization is needed here because that type is used as keys in the
// map representing TOC entries.
namespace llvm {
template <>
struct DenseMapInfo<std::pair<const MCSymbol *, PPCMCExpr::Specifier>> {
  using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;

  static unsigned getHashValue(const TOCKey &PairVal) {
    return detail::combineHashValue(
        DenseMapInfo<const MCSymbol *>::getHashValue(PairVal.first),
        DenseMapInfo<int>::getHashValue(PairVal.second));
  }
  static bool isEqual(const TOCKey &A, const TOCKey &B) { return A == B; }
};
} // end namespace llvm

namespace {

enum {
  // GNU attribute tags for PowerPC ABI
  Tag_GNU_Power_ABI_FP = 4,
  Tag_GNU_Power_ABI_Vector = 8,
  Tag_GNU_Power_ABI_Struct_Return = 12,

  // GNU attribute values for PowerPC float ABI, as combination of two parts
  Val_GNU_Power_ABI_NoFloat = 0b00,
  Val_GNU_Power_ABI_HardFloat_DP = 0b01,
  Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
  Val_GNU_Power_ABI_HardFloat_SP = 0b11,

  Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
  Val_GNU_Power_ABI_LDBL_64 = 0b1000,
  Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
};

class PPCAsmPrinter : public AsmPrinter {
protected:
  // For TLS on AIX, we need to be able to identify TOC entries of specific
  // specifier so we can add the right relocations when we generate the
  // entries. So each entry is represented by a pair of MCSymbol and
  // VariantKind. For example, we need to be able to identify the following
  // entry as a TLSGD entry so we can add the @m relocation:
  //   .tc .i[TC],i[TL]@m
  // By default, 0 is used for the specifier.
  MapVector<std::pair<const MCSymbol *, PPCMCExpr::Specifier>, MCSymbol *> TOC;
  const PPCSubtarget *Subtarget = nullptr;

  // Keep track of the number of TLS variables and their corresponding
  // addresses, which is then used for the assembly printing of
  // non-TOC-based local-exec variables.
  MapVector<const GlobalValue *, uint64_t> TLSVarsToAddressMapping;

public:
  explicit PPCAsmPrinter(TargetMachine &TM,
                         std::unique_ptr<MCStreamer> Streamer, char &ID)
      : AsmPrinter(TM, std::move(Streamer), ID) {}

  StringRef getPassName() const override { return "PowerPC Assembly Printer"; }

  enum TOCEntryType {
    TOCType_ConstantPool,
    TOCType_GlobalExternal,
    TOCType_GlobalInternal,
    TOCType_JumpTable,
    TOCType_ThreadLocal,
    TOCType_BlockAddress,
    TOCType_EHBlock
  };

  MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym, TOCEntryType Type,
                                   PPCMCExpr::Specifier Kind = PPC::S_None);

  bool doInitialization(Module &M) override {
    if (!TOC.empty())
      TOC.clear();
    return AsmPrinter::doInitialization(M);
  }

  const MCExpr *symbolWithSpecifier(const MCSymbol *S,
                                    PPCMCExpr::Specifier Kind);
  void emitInstruction(const MachineInstr *MI) override;

  /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
  /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
  /// The \p MI would be INLINEASM ONLY.
  void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);

  void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                       const char *ExtraCode, raw_ostream &O) override;
  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                             const char *ExtraCode, raw_ostream &O) override;

  void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
  void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
  void emitTlsCall(const MachineInstr *MI, PPCMCExpr::Specifier VK);
  void EmitAIXTlsCallHelper(const MachineInstr *MI);
  const MCExpr *getAdjustedFasterLocalExpr(const MachineOperand &MO,
                                           int64_t Offset);
  bool runOnMachineFunction(MachineFunction &MF) override {
    Subtarget = &MF.getSubtarget<PPCSubtarget>();
    bool Changed = AsmPrinter::runOnMachineFunction(MF);
    emitXRayTable();
    return Changed;
  }
};

/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
class PPCLinuxAsmPrinter : public PPCAsmPrinter {
public:
  static char ID;

  explicit PPCLinuxAsmPrinter(TargetMachine &TM,
                              std::unique_ptr<MCStreamer> Streamer)
      : PPCAsmPrinter(TM, std::move(Streamer), ID) {}

  StringRef getPassName() const override {
    return "Linux PPC Assembly Printer";
  }

  void emitGNUAttributes(Module &M);

  void emitStartOfAsmFile(Module &M) override;
  void emitEndOfAsmFile(Module &) override;

  void emitFunctionEntryLabel() override;

  void emitFunctionBodyStart() override;
  void emitFunctionBodyEnd() override;
  void emitInstruction(const MachineInstr *MI) override;
};

class PPCAIXAsmPrinter : public PPCAsmPrinter {
private:
  /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
  /// linkage for them in AIX.
  SmallSetVector<MCSymbol *, 8> ExtSymSDNodeSymbols;

  /// A format indicator and unique trailing identifier to form part of the
  /// sinit/sterm function names.
  std::string FormatIndicatorAndUniqueModId;

  // Record a list of GlobalAlias associated with a GlobalObject.
  // This is used for AIX's extra-label-at-definition aliasing strategy.
  DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
      GOAliasMap;

  uint16_t getNumberOfVRSaved();
  void emitTracebackTable();

  SmallVector<const GlobalVariable *, 8> TOCDataGlobalVars;

  void emitGlobalVariableHelper(const GlobalVariable *);

  // Get the offset of an alias based on its AliaseeObject.
  uint64_t getAliasOffset(const Constant *C);

public:
  static char ID;

  PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
      : PPCAsmPrinter(TM, std::move(Streamer), ID) {
    if (MAI.isLittleEndian())
      report_fatal_error(
          "cannot create AIX PPC Assembly Printer for a little-endian target");
  }

  StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }

  bool doInitialization(Module &M) override;

  void emitXXStructorList(const DataLayout &DL, const Constant *List,
                          bool IsCtor) override;

  void SetupMachineFunction(MachineFunction &MF) override;

  void emitGlobalVariable(const GlobalVariable *GV) override;

  void emitFunctionDescriptor() override;

  void emitFunctionEntryLabel() override;

  void emitFunctionBodyEnd() override;

  void emitPGORefs(Module &M);

  void emitGCOVRefs();

  void emitEndOfAsmFile(Module &) override;

  void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override;

  void emitInstruction(const MachineInstr *MI) override;

  bool doFinalization(Module &M) override;

  void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;

  void emitModuleCommandLines(Module &M) override;

  void emitRefMetadata(const GlobalObject *);

  void emitGlobalIFunc(Module &M, const GlobalIFunc &GI) override;
};

} // end anonymous namespace

void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
                                       raw_ostream &O) {
  // Computing the address of a global symbol, not calling it.
  const GlobalValue *GV = MO.getGlobal();
  getSymbol(GV)->print(O, MAI);
  printOffset(MO.getOffset(), O);
}

void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
                                 raw_ostream &O) {
  const DataLayout &DL = getDataLayout();
  const MachineOperand &MO = MI->getOperand(OpNo);

  switch (MO.getType()) {
  case MachineOperand::MO_Register: {
    // The MI is INLINEASM ONLY and UseVSXReg is always false.
    const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());

    // Linux assembler (Others?) does not take register mnemonics.
    // FIXME - What about special registers used in mfspr/mtspr?
    O << PPC::stripRegisterPrefix(RegName);
    return;
  }
  case MachineOperand::MO_Immediate:
    O << MO.getImm();
    return;

  case MachineOperand::MO_MachineBasicBlock:
    MO.getMBB()->getSymbol()->print(O, MAI);
    return;
  case MachineOperand::MO_ConstantPoolIndex:
    O << DL.getInternalSymbolPrefix() << "CPI" << getFunctionNumber() << '_'
      << MO.getIndex();
    return;
  case MachineOperand::MO_BlockAddress:
    GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
    return;
  case MachineOperand::MO_GlobalAddress: {
    PrintSymbolOperand(MO, O);
    return;
  }

  default:
    O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
    return;
  }
}

/// PrintAsmOperand - Print out an operand for an inline asm expression.
///
bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                                    const char *ExtraCode, raw_ostream &O) {
  // Does this asm operand have a single letter operand modifier?
  if (ExtraCode && ExtraCode[0]) {
    if (ExtraCode[1] != 0) return true; // Unknown modifier.

    switch (ExtraCode[0]) {
    default:
      // See if this is a generic print operand
      return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
    case 'L': // Write second word of DImode reference.
      // Verify that this operand has two consecutive registers.
      if (!MI->getOperand(OpNo).isReg() ||
          OpNo+1 == MI->getNumOperands() ||
          !MI->getOperand(OpNo+1).isReg())
        return true;
      ++OpNo;   // Return the high-part.
      break;
    case 'I':
      // Write 'i' if an integer constant, otherwise nothing.  Used to print
      // addi vs add, etc.
      if (MI->getOperand(OpNo).isImm())
        O << "i";
      return false;
    case 'x':
      if(!MI->getOperand(OpNo).isReg())
        return true;
      // This operand uses VSX numbering.
      // If the operand is a VMX register, convert it to a VSX register.
      Register Reg = MI->getOperand(OpNo).getReg();
      if (PPC::isVRRegister(Reg))
        Reg = PPC::VSX32 + (Reg - PPC::V0);
      else if (PPC::isVFRegister(Reg))
        Reg = PPC::VSX32 + (Reg - PPC::VF0);
      const char *RegName;
      RegName = PPCInstPrinter::getRegisterName(Reg);
      RegName = PPC::stripRegisterPrefix(RegName);
      O << RegName;
      return false;
    }
  }

  printOperand(MI, OpNo, O);
  return false;
}

// At the moment, all inline asm memory operands are a single register.
// In any case, the output of this routine should always be just one
// assembler operand.
bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                                          const char *ExtraCode,
                                          raw_ostream &O) {
  if (ExtraCode && ExtraCode[0]) {
    if (ExtraCode[1] != 0) return true; // Unknown modifier.

    switch (ExtraCode[0]) {
    default: return true;  // Unknown modifier.
    case 'L': // A memory reference to the upper word of a double word op.
      O << getDataLayout().getPointerSize() << "(";
      printOperand(MI, OpNo, O);
      O << ")";
      return false;
    case 'y': // A memory reference for an X-form instruction
      O << "0, ";
      printOperand(MI, OpNo, O);
      return false;
    case 'I':
      // Write 'i' if an integer constant, otherwise nothing.  Used to print
      // addi vs add, etc.
      if (MI->getOperand(OpNo).isImm())
        O << "i";
      return false;
    case 'U': // Print 'u' for update form.
    case 'X': // Print 'x' for indexed form.
      // FIXME: Currently for PowerPC memory operands are always loaded
      // into a register, so we never get an update or indexed form.
      // This is bad even for offset forms, since even if we know we
      // have a value in -16(r1), we will generate a load into r<n>
      // and then load from 0(r<n>).  Until that issue is fixed,
      // tolerate 'U' and 'X' but don't output anything.
      assert(MI->getOperand(OpNo).isReg());
      return false;
    }
  }

  assert(MI->getOperand(OpNo).isReg());
  O << "0(";
  printOperand(MI, OpNo, O);
  O << ")";
  return false;
}

static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type) {
  ++NumTOCEntries;
  switch (Type) {
  case PPCAsmPrinter::TOCType_ConstantPool:
    ++NumTOCConstPool;
    break;
  case PPCAsmPrinter::TOCType_GlobalInternal:
    ++NumTOCGlobalInternal;
    break;
  case PPCAsmPrinter::TOCType_GlobalExternal:
    ++NumTOCGlobalExternal;
    break;
  case PPCAsmPrinter::TOCType_JumpTable:
    ++NumTOCJumpTable;
    break;
  case PPCAsmPrinter::TOCType_ThreadLocal:
    ++NumTOCThreadLocal;
    break;
  case PPCAsmPrinter::TOCType_BlockAddress:
    ++NumTOCBlockAddress;
    break;
  case PPCAsmPrinter::TOCType_EHBlock:
    ++NumTOCEHBlock;
    break;
  }
}

static CodeModel::Model getCodeModel(const PPCSubtarget &S,
                                     const TargetMachine &TM,
                                     const MachineOperand &MO) {
  CodeModel::Model ModuleModel = TM.getCodeModel();

  // If the operand is not a global address then there is no
  // global variable to carry an attribute.
  if (!(MO.getType() == MachineOperand::MO_GlobalAddress))
    return ModuleModel;

  const GlobalValue *GV = MO.getGlobal();
  assert(GV && "expected global for MO_GlobalAddress");

  return S.getCodeModel(TM, GV);
}

static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM) {
  switch (CM) {
  case CodeModel::Large:
    XSym->setPerSymbolCodeModel(MCSymbolXCOFF::CM_Large);
    return;
  case CodeModel::Small:
    XSym->setPerSymbolCodeModel(MCSymbolXCOFF::CM_Small);
    return;
  default:
    report_fatal_error("Invalid code model for AIX");
  }
}

/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
/// exists for it.  If not, create one.  Then return a symbol that references
/// the TOC entry.
MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym,
                                                TOCEntryType Type,
                                                PPCMCExpr::Specifier Spec) {
  // If this is a new TOC entry add statistics about it.
  auto [It, Inserted] = TOC.try_emplace({Sym, Spec});
  if (Inserted)
    collectTOCStats(Type);

  MCSymbol *&TOCEntry = It->second;
  if (!TOCEntry)
    TOCEntry = createTempSymbol("C");
  return TOCEntry;
}

void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
  unsigned NumNOPBytes = MI.getOperand(1).getImm();
  
  auto &Ctx = OutStreamer->getContext();
  MCSymbol *MILabel = Ctx.createTempSymbol();
  OutStreamer->emitLabel(MILabel);

  SM.recordStackMap(*MILabel, MI);
  assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");

  // Scan ahead to trim the shadow.
  const MachineBasicBlock &MBB = *MI.getParent();
  MachineBasicBlock::const_iterator MII(MI);
  ++MII;
  while (NumNOPBytes > 0) {
    if (MII == MBB.end() || MII->isCall() ||
        MII->getOpcode() == PPC::DBG_VALUE ||
        MII->getOpcode() == TargetOpcode::PATCHPOINT ||
        MII->getOpcode() == TargetOpcode::STACKMAP)
      break;
    ++MII;
    NumNOPBytes -= 4;
  }

  // Emit nops.
  for (unsigned i = 0; i < NumNOPBytes; i += 4)
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
}

// Lower a patchpoint of the form:
// [<def>], <id>, <numBytes>, <target>, <numArgs>
void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
  auto &Ctx = OutStreamer->getContext();
  MCSymbol *MILabel = Ctx.createTempSymbol();
  OutStreamer->emitLabel(MILabel);

  SM.recordPatchPoint(*MILabel, MI);
  PatchPointOpers Opers(&MI);

  unsigned EncodedBytes = 0;
  const MachineOperand &CalleeMO = Opers.getCallTarget();

  if (CalleeMO.isImm()) {
    int64_t CallTarget = CalleeMO.getImm();
    if (CallTarget) {
      assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
             "High 16 bits of call target should be zero.");
      Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
      EncodedBytes = 0;
      // Materialize the jump address:
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
                                      .addReg(ScratchReg)
                                      .addImm((CallTarget >> 32) & 0xFFFF));
      ++EncodedBytes;

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
                                      .addReg(ScratchReg)
                                      .addReg(ScratchReg)
                                      .addImm(32).addImm(16));
      ++EncodedBytes;

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
                                      .addReg(ScratchReg)
                                      .addReg(ScratchReg)
                                      .addImm((CallTarget >> 16) & 0xFFFF));
      ++EncodedBytes;

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
                                      .addReg(ScratchReg)
                                      .addReg(ScratchReg)
                                      .addImm(CallTarget & 0xFFFF));
      ++EncodedBytes;

      // Save the current TOC pointer before the remote call.
      int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
                                      .addReg(PPC::X2)
                                      .addImm(TOCSaveOffset)
                                      .addReg(PPC::X1));
      ++EncodedBytes;

      // If we're on ELFv1, then we need to load the actual function pointer
      // from the function descriptor.
      if (!Subtarget->isELFv2ABI()) {
        // Load the new TOC pointer and the function address, but not r11
        // (needing this is rare, and loading it here would prevent passing it
        // via a 'nest' parameter.
        EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
                                        .addReg(PPC::X2)
                                        .addImm(8)
                                        .addReg(ScratchReg));
        ++EncodedBytes;

        EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
                                        .addReg(ScratchReg)
                                        .addImm(0)
                                        .addReg(ScratchReg));
        ++EncodedBytes;
      }

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
                                      .addReg(ScratchReg));
      ++EncodedBytes;

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
      ++EncodedBytes;

      // Restore the TOC pointer after the call.
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
                                      .addReg(PPC::X2)
                                      .addImm(TOCSaveOffset)
                                      .addReg(PPC::X1));
      ++EncodedBytes;
    }
  } else if (CalleeMO.isGlobal()) {
    const GlobalValue *GValue = CalleeMO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);

    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
                                    .addExpr(SymVar));
    EncodedBytes += 2;
  }

  // Each instruction is 4 bytes.
  EncodedBytes *= 4;

  // Emit padding.
  unsigned NumBytes = Opers.getNumPatchBytes();
  if (NumBytes < EncodedBytes)
    reportFatalUsageError(
        "Patchpoint can't request size less than the length of a call.");

  assert((NumBytes - EncodedBytes) % 4 == 0 &&
         "Invalid number of NOP bytes requested!");
  for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
}

/// This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX. We
/// will create the csect and use the qual-name symbol instead of creating just
/// the external symbol.
static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc) {
  StringRef SymName;
  switch (MIOpc) {
  default:
    SymName = ".__tls_get_addr";
    break;
  case PPC::GETtlsTpointer32AIX:
    SymName = ".__get_tpointer";
    break;
  case PPC::GETtlsMOD32AIX:
  case PPC::GETtlsMOD64AIX:
    SymName = ".__tls_get_mod";
    break;
  }
  return Ctx
      .getXCOFFSection(SymName, SectionKind::getText(),
                       XCOFF::CsectProperties(XCOFF::XMC_PR, XCOFF::XTY_ER))
      ->getQualNameSymbol();
}

void PPCAsmPrinter::EmitAIXTlsCallHelper(const MachineInstr *MI) {
  assert(Subtarget->isAIXABI() &&
         "Only expecting to emit calls to get the thread pointer on AIX!");

  MCSymbol *TlsCall = createMCSymbolForTlsGetAddr(OutContext, MI->getOpcode());
  const MCExpr *TlsRef = MCSymbolRefExpr::create(TlsCall, OutContext);
  EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
}

/// Given a GETtls[ld]ADDR[32] instruction, print a call to __tls_get_addr to
/// the current output stream.
void PPCAsmPrinter::emitTlsCall(const MachineInstr *MI,
                                PPCMCExpr::Specifier VK) {
  PPCMCExpr::Specifier Kind = PPC::S_None;
  unsigned Opcode = PPC::BL8_NOP_TLS;

  assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
  if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
      MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) {
    Kind = PPC::S_NOTOC;
    Opcode = PPC::BL8_NOTOC_TLS;
  }
  const Module *M = MF->getFunction().getParent();

  assert(MI->getOperand(0).isReg() &&
         ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
          (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
         "GETtls[ld]ADDR[32] must define GPR3");
  assert(MI->getOperand(1).isReg() &&
         ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
          (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
         "GETtls[ld]ADDR[32] must read GPR3");

  if (Subtarget->isAIXABI()) {
    // For TLSGD, the variable offset should already be in R4 and the region
    // handle should already be in R3. We generate an absolute branch to
    // .__tls_get_addr. For TLSLD, the module handle should already be in R3.
    // We generate an absolute branch to .__tls_get_mod.
    Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
    (void)VarOffsetReg;
    assert((MI->getOpcode() == PPC::GETtlsMOD32AIX ||
            MI->getOpcode() == PPC::GETtlsMOD64AIX ||
            (MI->getOperand(2).isReg() &&
             MI->getOperand(2).getReg() == VarOffsetReg)) &&
           "GETtls[ld]ADDR[32] must read GPR4");
    EmitAIXTlsCallHelper(MI);
    return;
  }

  MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr");

  if (Subtarget->is32BitELFABI() && isPositionIndependent())
    Kind = PPC::S_PLT;

  const MCExpr *TlsRef = MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);

  // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
  if (Kind == PPC::S_PLT && Subtarget->isSecurePlt() &&
      M->getPICLevel() == PICLevel::BigPIC)
    TlsRef = MCBinaryExpr::createAdd(
        TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
  const MachineOperand &MO = MI->getOperand(2);
  const GlobalValue *GValue = MO.getGlobal();
  MCSymbol *MOSymbol = getSymbol(GValue);
  const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
  EmitToStreamer(*OutStreamer,
                 MCInstBuilder(Subtarget->isPPC64() ? Opcode
                                                    : (unsigned)PPC::BL_TLS)
                     .addExpr(TlsRef)
                     .addExpr(SymVar));
}

/// Map a machine operand for a TOC pseudo-machine instruction to its
/// corresponding MCSymbol.
static MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO,
                                           AsmPrinter &AP) {
  switch (MO.getType()) {
  case MachineOperand::MO_GlobalAddress:
    return AP.getSymbol(MO.getGlobal());
  case MachineOperand::MO_ConstantPoolIndex:
    return AP.GetCPISymbol(MO.getIndex());
  case MachineOperand::MO_JumpTableIndex:
    return AP.GetJTISymbol(MO.getIndex());
  case MachineOperand::MO_BlockAddress:
    return AP.GetBlockAddressSymbol(MO.getBlockAddress());
  default:
    llvm_unreachable("Unexpected operand type to get symbol.");
  }
}

static PPCAsmPrinter::TOCEntryType
getTOCEntryTypeForLinkage(GlobalValue::LinkageTypes Linkage) {
  if (Linkage == GlobalValue::ExternalLinkage ||
      Linkage == GlobalValue::AvailableExternallyLinkage ||
      Linkage == GlobalValue::ExternalWeakLinkage)
    return PPCAsmPrinter::TOCType_GlobalExternal;

  return PPCAsmPrinter::TOCType_GlobalInternal;
}

static PPCAsmPrinter::TOCEntryType
getTOCEntryTypeForMO(const MachineOperand &MO) {
  // Use the target flags to determine if this MO is Thread Local.
  // If we don't do this it comes out as Global.
  if (PPCInstrInfo::hasTLSFlag(MO.getTargetFlags()))
    return PPCAsmPrinter::TOCType_ThreadLocal;

  switch (MO.getType()) {
  case MachineOperand::MO_GlobalAddress: {
    const GlobalValue *GlobalV = MO.getGlobal();
    return getTOCEntryTypeForLinkage(GlobalV->getLinkage());
  }
  case MachineOperand::MO_ConstantPoolIndex:
    return PPCAsmPrinter::TOCType_ConstantPool;
  case MachineOperand::MO_JumpTableIndex:
    return PPCAsmPrinter::TOCType_JumpTable;
  case MachineOperand::MO_BlockAddress:
    return PPCAsmPrinter::TOCType_BlockAddress;
  default:
    llvm_unreachable("Unexpected operand type to get TOC type.");
  }
}

const MCExpr *PPCAsmPrinter::symbolWithSpecifier(const MCSymbol *S,
                                                 PPCMCExpr::Specifier Spec) {
  return MCSymbolRefExpr::create(S, Spec, OutContext);
}

/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
/// the current output stream.
///
void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
  PPC_MC::verifyInstructionPredicates(MI->getOpcode(),
                                      getSubtargetInfo().getFeatureBits());

  MCInst TmpInst;
  const bool IsPPC64 = Subtarget->isPPC64();
  const bool IsAIX = Subtarget->isAIXABI();
  const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
                                   Subtarget->hasAIXSmallLocalDynamicTLS();
  const Module *M = MF->getFunction().getParent();
  PICLevel::Level PL = M->getPICLevel();

#ifndef NDEBUG
  // Validate that SPE and FPU are mutually exclusive in codegen
  if (!MI->isInlineAsm()) {
    for (const MachineOperand &MO: MI->operands()) {
      if (MO.isReg()) {
        Register Reg = MO.getReg();
        if (Subtarget->hasSPE()) {
          if (PPC::F4RCRegClass.contains(Reg) ||
              PPC::F8RCRegClass.contains(Reg) ||
              PPC::VFRCRegClass.contains(Reg) ||
              PPC::VRRCRegClass.contains(Reg) ||
              PPC::VSFRCRegClass.contains(Reg) ||
              PPC::VSSRCRegClass.contains(Reg)
              )
            llvm_unreachable("SPE targets cannot have FPRegs!");
        } else {
          if (PPC::SPERCRegClass.contains(Reg))
            llvm_unreachable("SPE register found in FPU-targeted code!");
        }
      }
    }
  }
#endif

  auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,
                                                ptrdiff_t OriginalOffset) {
    // Apply an offset to the TOC-based expression such that the adjusted
    // notional offset from the TOC base (to be encoded into the instruction's D
    // or DS field) is the signed 16-bit truncation of the original notional
    // offset from the TOC base.
    // This is consistent with the treatment used both by XL C/C++ and
    // by AIX ld -r.
    ptrdiff_t Adjustment =
        OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
    return MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext);
  };

  auto getTOCEntryLoadingExprForXCOFF =
      [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
       this](const MCSymbol *MOSymbol, const MCExpr *Expr,
             PPCMCExpr::Specifier VK = PPC::S_None) -> const MCExpr * {
    const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
    const auto TOCEntryIter = TOC.find({MOSymbol, VK});
    assert(TOCEntryIter != TOC.end() &&
           "Could not find the TOC entry for this symbol.");
    const ptrdiff_t EntryDistanceFromTOCBase =
        (TOCEntryIter - TOC.begin()) * EntryByteSize;
    constexpr int16_t PositiveTOCRange = INT16_MAX;

    if (EntryDistanceFromTOCBase > PositiveTOCRange)
      return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);

    return Expr;
  };
  auto getSpecifier = [&](const MachineOperand &MO) {
    // For TLS initial-exec and local-exec accesses on AIX, we have one TOC
    // entry for the symbol (with the variable offset), which is differentiated
    // by MO_TPREL_FLAG.
    unsigned Flag = MO.getTargetFlags();
    if (Flag == PPCII::MO_TPREL_FLAG ||
        Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
        Flag == PPCII::MO_TPREL_PCREL_FLAG) {
      assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n");
      TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());
      if (Model == TLSModel::LocalExec)
        return PPC::S_AIX_TLSLE;
      if (Model == TLSModel::InitialExec)
        return PPC::S_AIX_TLSIE;
      // On AIX, TLS model opt may have turned local-dynamic accesses into
      // initial-exec accesses.
      PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
      if (Model == TLSModel::LocalDynamic &&
          FuncInfo->isAIXFuncUseTLSIEForLD()) {
        LLVM_DEBUG(
            dbgs() << "Current function uses IE access for default LD vars.\n");
        return PPC::S_AIX_TLSIE;
      }
      llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
    }
    // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
    // the variable offset and the other for the region handle). They are
    // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
    if (Flag == PPCII::MO_TLSGDM_FLAG)
      return PPC::S_AIX_TLSGDM;
    if (Flag == PPCII::MO_TLSGD_FLAG || Flag == PPCII::MO_GOT_TLSGD_PCREL_FLAG)
      return PPC::S_AIX_TLSGD;
    // For local-dynamic TLS access on AIX, we have one TOC entry for the symbol
    // (the variable offset) and one shared TOC entry for the module handle.
    // They are differentiated by MO_TLSLD_FLAG and MO_TLSLDM_FLAG.
    if (Flag == PPCII::MO_TLSLD_FLAG && IsAIX)
      return PPC::S_AIX_TLSLD;
    if (Flag == PPCII::MO_TLSLDM_FLAG && IsAIX)
      return PPC::S_AIX_TLSML;
    return PPC::S_None;
  };

  // Lower multi-instruction pseudo operations.
  switch (MI->getOpcode()) {
  default: break;
  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
    assert(!Subtarget->isAIXABI() &&
           "AIX does not support patchable function entry!");
    const Function &F = MF->getFunction();
    unsigned Num = F.getFnAttributeAsParsedInteger("patchable-function-entry");
    if (!Num)
      return;
    emitNops(Num);
    return;
  }
  case TargetOpcode::DBG_VALUE:
    llvm_unreachable("Should be handled target independently");
  case TargetOpcode::STACKMAP:
    return LowerSTACKMAP(SM, *MI);
  case TargetOpcode::PATCHPOINT:
    return LowerPATCHPOINT(SM, *MI);

  case PPC::MoveGOTtoLR: {
    // Transform %lr = MoveGOTtoLR
    // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
    // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
    // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
    //      blrl
    // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
    MCSymbol *GOTSymbol =
      OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
    const MCExpr *OffsExpr = MCBinaryExpr::createSub(
        MCSymbolRefExpr::create(GOTSymbol, PPC::S_LOCAL, OutContext),
        MCConstantExpr::create(4, OutContext), OutContext);

    // Emit the 'bl'.
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
    return;
  }
  case PPC::MovePCtoLR:
  case PPC::MovePCtoLR8: {
    // Transform %lr = MovePCtoLR
    // Into this, where the label is the PIC base:
    //     bl L1$pb
    // L1$pb:
    MCSymbol *PICBase = MF->getPICBaseSymbol();

    // Emit 'bcl 20,31,.+4' so the link stack is not corrupted.
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(PPC::BCLalways)
                       // FIXME: We would like an efficient form for this, so we
                       // don't have to do a lot of extra uniquing.
                       .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));

    // Emit the label.
    OutStreamer->emitLabel(PICBase);
    return;
  }
  case PPC::UpdateGBR: {
    // Transform %rd = UpdateGBR(%rt, %ri)
    // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
    //       add %rd, %rt, %ri
    // or into (if secure plt mode is on):
    //       addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
    //       addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
    // Get the offset from the GOT Base Register to the GOT
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
    if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
      MCRegister PICR = TmpInst.getOperand(0).getReg();
      MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
          M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
                                                 : ".LTOC");
      const MCExpr *PB =
          MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);

      const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
          MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);

      const MCExpr *DeltaHi =
          MCSpecifierExpr::create(DeltaExpr, PPC::S_HA, OutContext);
      EmitToStreamer(
          *OutStreamer,
          MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));

      const MCExpr *DeltaLo =
          MCSpecifierExpr::create(DeltaExpr, PPC::S_LO, OutContext);
      EmitToStreamer(
          *OutStreamer,
          MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
      return;
    } else {
      MCSymbol *PICOffset =
        MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
      TmpInst.setOpcode(PPC::LWZ);
      const MCExpr *Exp = MCSymbolRefExpr::create(PICOffset, OutContext);
      const MCExpr *PB =
        MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
                                OutContext);
      const MCOperand TR = TmpInst.getOperand(1);
      const MCOperand PICR = TmpInst.getOperand(0);

      // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
      TmpInst.getOperand(1) =
          MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
      TmpInst.getOperand(0) = TR;
      TmpInst.getOperand(2) = PICR;
      EmitToStreamer(*OutStreamer, TmpInst);

      TmpInst.setOpcode(PPC::ADD4);
      TmpInst.getOperand(0) = PICR;
      TmpInst.getOperand(1) = TR;
      TmpInst.getOperand(2) = PICR;
      EmitToStreamer(*OutStreamer, TmpInst);
      return;
    }
  }
  case PPC::LWZtoc: {
    // Transform %rN = LWZtoc @op1, %r2
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to LWZ.
    TmpInst.setOpcode(PPC::LWZ);

    const MachineOperand &MO = MI->getOperand(1);
    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
           "Invalid operand for LWZtoc.");

    // Map the operand to its corresponding MCSymbol.
    const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    // Create a reference to the GOT entry for the symbol. The GOT entry will be
    // synthesized later.
    if (PL == PICLevel::SmallPIC && !IsAIX) {
      const MCExpr *Exp = symbolWithSpecifier(MOSymbol, PPC::S_GOT);
      TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
      EmitToStreamer(*OutStreamer, TmpInst);
      return;
    }

    PPCMCExpr::Specifier VK = getSpecifier(MO);

    // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
    // storage allocated in the TOC which contains the address of
    // 'MOSymbol'. Said TOC entry will be synthesized later.
    MCSymbol *TOCEntry =
        lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
    const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, OutContext);

    // AIX uses the label directly as the lwz displacement operand for
    // references into the toc section. The displacement value will be generated
    // relative to the toc-base.
    if (IsAIX) {
      assert(
          getCodeModel(*Subtarget, TM, MO) == CodeModel::Small &&
          "This pseudo should only be selected for 32-bit small code model.");
      Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
      TmpInst.getOperand(1) = MCOperand::createExpr(Exp);

      // Print MO for better readability
      if (isVerbose())
        OutStreamer->getCommentOS() << MO << '\n';
      EmitToStreamer(*OutStreamer, TmpInst);
      return;
    }

    // Create an explicit subtract expression between the local symbol and
    // '.LTOC' to manifest the toc-relative offset.
    const MCExpr *PB = MCSymbolRefExpr::create(
        OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
    Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
    TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::ADDItoc:
  case PPC::ADDItoc8: {
    assert(IsAIX && TM.getCodeModel() == CodeModel::Small &&
           "PseudoOp only valid for small code model AIX");

    // Transform %rN = ADDItoc/8 %r2, @op1.
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to load address.
    TmpInst.setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));

    const MachineOperand &MO = MI->getOperand(2);
    assert(MO.isGlobal() && "Invalid operand for ADDItoc[8].");

    // Map the operand to its corresponding MCSymbol.
    const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    const MCExpr *Exp = MCSymbolRefExpr::create(MOSymbol, OutContext);

    TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::LDtocJTI:
  case PPC::LDtocCPT:
  case PPC::LDtocBA:
  case PPC::LDtoc: {
    // Transform %x3 = LDtoc @min1, %x2
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to LD.
    TmpInst.setOpcode(PPC::LD);

    const MachineOperand &MO = MI->getOperand(1);
    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
           "Invalid operand!");

    // Map the operand to its corresponding MCSymbol.
    const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    PPCMCExpr::Specifier VK = getSpecifier(MO);

    // Map the machine operand to its corresponding MCSymbol, then map the
    // global address operand to be a reference to the TOC entry we will
    // synthesize later.
    MCSymbol *TOCEntry =
        lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);

    PPCMCExpr::Specifier VKExpr = IsAIX ? PPC::S_None : PPC::S_TOC;
    const MCExpr *Exp = symbolWithSpecifier(TOCEntry, VKExpr);
    TmpInst.getOperand(1) = MCOperand::createExpr(
        IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);

    // Print MO for better readability
    if (isVerbose() && IsAIX)
      OutStreamer->getCommentOS() << MO << '\n';
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::ADDIStocHA: {
    const MachineOperand &MO = MI->getOperand(2);

    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
           "Invalid operand for ADDIStocHA.");
    assert((IsAIX && !IsPPC64 &&
            getCodeModel(*Subtarget, TM, MO) == CodeModel::Large) &&
           "This pseudo should only be selected for 32-bit large code model on"
           " AIX.");

    // Transform %rd = ADDIStocHA %rA, @sym(%r2)
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to ADDIS.
    TmpInst.setOpcode(PPC::ADDIS);

    // Map the machine operand to its corresponding MCSymbol.
    MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    PPCMCExpr::Specifier VK = getSpecifier(MO);

    // Map the global address operand to be a reference to the TOC entry we
    // will synthesize later. 'TOCEntry' is a label used to reference the
    // storage allocated in the TOC which contains the address of 'MOSymbol'.
    // If the symbol does not have the toc-data attribute, then we create the
    // TOC entry on AIX. If the toc-data attribute is used, the TOC entry
    // contains the data rather than the address of the MOSymbol.
    if (![](const MachineOperand &MO) {
          if (!MO.isGlobal())
            return false;

          const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal());
          if (!GV)
            return false;
          return GV->hasAttribute("toc-data");
        }(MO)) {
      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
    }

    const MCExpr *Exp = symbolWithSpecifier(MOSymbol, PPC::S_U);
    TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::LWZtocL: {
    const MachineOperand &MO = MI->getOperand(1);

    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
           "Invalid operand for LWZtocL.");
    assert(IsAIX && !IsPPC64 &&
           getCodeModel(*Subtarget, TM, MO) == CodeModel::Large &&
           "This pseudo should only be selected for 32-bit large code model on"
           " AIX.");

    // Transform %rd = LWZtocL @sym, %rs.
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to lwz.
    TmpInst.setOpcode(PPC::LWZ);

    // Map the machine operand to its corresponding MCSymbol.
    MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    PPCMCExpr::Specifier VK = getSpecifier(MO);

    // Always use TOC on AIX. Map the global address operand to be a reference
    // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
    // reference the storage allocated in the TOC which contains the address of
    // 'MOSymbol'.
    MCSymbol *TOCEntry =
        lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
    const MCExpr *Exp = symbolWithSpecifier(TOCEntry, PPC::S_L);
    TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::ADDIStocHA8: {
    // Transform %xd = ADDIStocHA8 %x2, @sym
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to ADDIS8. If the global address is the address of
    // an external symbol, is a jump table address, is a block address, or is a
    // constant pool index with large code model enabled, then generate a TOC
    // entry and reference that. Otherwise, reference the symbol directly.
    TmpInst.setOpcode(PPC::ADDIS8);

    const MachineOperand &MO = MI->getOperand(2);
    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
           "Invalid operand for ADDIStocHA8!");

    const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    PPCMCExpr::Specifier VK = getSpecifier(MO);

    const bool GlobalToc =
        MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());

    const CodeModel::Model CM =
        IsAIX ? getCodeModel(*Subtarget, TM, MO) : TM.getCodeModel();

    if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
        (MO.isCPI() && CM == CodeModel::Large))
      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);

    VK = IsAIX ? PPC::S_U : PPC::S_TOC_HA;

    const MCExpr *Exp = symbolWithSpecifier(MOSymbol, VK);

    if (!MO.isJTI() && MO.getOffset())
      Exp = MCBinaryExpr::createAdd(Exp,
                                    MCConstantExpr::create(MO.getOffset(),
                                                           OutContext),
                                    OutContext);

    TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::LDtocL: {
    // Transform %xd = LDtocL @sym, %xs
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to LD. If the global address is the address of
    // an external symbol, is a jump table address, is a block address, or is
    // a constant pool index with large code model enabled, then generate a
    // TOC entry and reference that. Otherwise, reference the symbol directly.
    TmpInst.setOpcode(PPC::LD);

    const MachineOperand &MO = MI->getOperand(1);
    assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
            MO.isBlockAddress()) &&
           "Invalid operand for LDtocL!");

    LLVM_DEBUG(assert(
        (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
        "LDtocL used on symbol that could be accessed directly is "
        "invalid. Must match ADDIStocHA8."));

    const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    PPCMCExpr::Specifier VK = getSpecifier(MO);
    CodeModel::Model CM =
        IsAIX ? getCodeModel(*Subtarget, TM, MO) : TM.getCodeModel();
    if (!MO.isCPI() || CM == CodeModel::Large)
      MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);

    VK = IsAIX ? PPC::S_L : PPC::S_TOC_LO;
    const MCExpr *Exp = symbolWithSpecifier(MOSymbol, VK);
    TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::ADDItocL:
  case PPC::ADDItocL8: {
    // Transform %xd = ADDItocL %xs, @sym
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    unsigned Op = MI->getOpcode();

    // Change the opcode to load address for toc-data.
    // ADDItocL is only used for 32-bit toc-data on AIX and will always use LA.
    TmpInst.setOpcode(Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
                                           : PPC::LA);

    const MachineOperand &MO = MI->getOperand(2);
    assert((Op == PPC::ADDItocL8)
               ? (MO.isGlobal() || MO.isCPI())
               : MO.isGlobal() && "Invalid operand for ADDItocL8.");
    assert(!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
           "Interposable definitions must use indirect accesses.");

    // Map the operand to its corresponding MCSymbol.
    const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);

    const MCExpr *Exp = MCSymbolRefExpr::create(
        MOSymbol, IsAIX ? PPC::S_L : PPC::S_TOC_LO, OutContext);

    TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }
  case PPC::ADDISgotTprelHA: {
    // Transform: %xd = ADDISgotTprelHA %x2, @sym
    // Into:      %xd = ADDIS8 %x2, sym@got@tlsgd@ha
    assert(IsPPC64 && "Not supported for 32-bit PowerPC");
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymGotTprel =
        symbolWithSpecifier(MOSymbol, PPC::S_GOT_TPREL_HA);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addReg(MI->getOperand(1).getReg())
                                 .addExpr(SymGotTprel));
    return;
  }
  case PPC::LDgotTprelL:
  case PPC::LDgotTprelL32: {
    // Transform %xd = LDgotTprelL @sym, %xs
    LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

    // Change the opcode to LD.
    TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
    const MachineOperand &MO = MI->getOperand(1);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *Exp = symbolWithSpecifier(
        MOSymbol, IsPPC64 ? PPC::S_GOT_TPREL_LO : PPC::S_GOT_TPREL);
    TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
    EmitToStreamer(*OutStreamer, TmpInst);
    return;
  }

  case PPC::PPC32PICGOT: {
    MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
    MCSymbol *GOTRef = OutContext.createTempSymbol();
    MCSymbol *NextInstr = OutContext.createTempSymbol();

    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
      // FIXME: We would like an efficient form for this, so we don't have to do
      // a lot of extra uniquing.
      .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
    const MCExpr *OffsExpr =
      MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
                                MCSymbolRefExpr::create(GOTRef, OutContext),
        OutContext);
    OutStreamer->emitLabel(GOTRef);
    OutStreamer->emitValue(OffsExpr, 4);
    OutStreamer->emitLabel(NextInstr);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
                                 .addReg(MI->getOperand(0).getReg()));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
                                 .addReg(MI->getOperand(1).getReg())
                                 .addImm(0)
                                 .addReg(MI->getOperand(0).getReg()));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addReg(MI->getOperand(1).getReg())
                                 .addReg(MI->getOperand(0).getReg()));
    return;
  }
  case PPC::PPC32GOT: {
    MCSymbol *GOTSymbol =
        OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
    const MCExpr *SymGotTlsL =
        MCSpecifierExpr::create(GOTSymbol, PPC::S_LO, OutContext);
    const MCExpr *SymGotTlsHA =
        MCSpecifierExpr::create(GOTSymbol, PPC::S_HA, OutContext);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addExpr(SymGotTlsL));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addReg(MI->getOperand(0).getReg())
                                 .addExpr(SymGotTlsHA));
    return;
  }
  case PPC::ADDIStlsgdHA: {
    // Transform: %xd = ADDIStlsgdHA %x2, @sym
    // Into:      %xd = ADDIS8 %x2, sym@got@tlsgd@ha
    assert(IsPPC64 && "Not supported for 32-bit PowerPC");
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymGotTlsGD =
        symbolWithSpecifier(MOSymbol, PPC::S_GOT_TLSGD_HA);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addReg(MI->getOperand(1).getReg())
                                 .addExpr(SymGotTlsGD));
    return;
  }
  case PPC::ADDItlsgdL:
    // Transform: %xd = ADDItlsgdL %xs, @sym
    // Into:      %xd = ADDI8 %xs, sym@got@tlsgd@l
  case PPC::ADDItlsgdL32: {
    // Transform: %rd = ADDItlsgdL32 %rs, @sym
    // Into:      %rd = ADDI %rs, sym@got@tlsgd
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymGotTlsGD = symbolWithSpecifier(
        MOSymbol, IsPPC64 ? PPC::S_GOT_TLSGD_LO : PPC::S_GOT_TLSGD);
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
                   .addReg(MI->getOperand(0).getReg())
                   .addReg(MI->getOperand(1).getReg())
                   .addExpr(SymGotTlsGD));
    return;
  }
  case PPC::GETtlsMOD32AIX:
  case PPC::GETtlsMOD64AIX:
    // Transform: %r3 = GETtlsMODNNAIX %r3 (for NN == 32/64).
    // Into: BLA .__tls_get_mod()
    // Input parameter is a module handle (_$TLSML[TC]@ml) for all variables.
  case PPC::GETtlsADDR:
    // Transform: %x3 = GETtlsADDR %x3, @sym
    // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
  case PPC::GETtlsADDRPCREL:
  case PPC::GETtlsADDR32AIX:
  case PPC::GETtlsADDR64AIX:
    // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
    // Into: BLA .__tls_get_addr()
    // Unlike on Linux, there is no symbol or relocation needed for this call.
  case PPC::GETtlsADDR32: {
    // Transform: %r3 = GETtlsADDR32 %r3, @sym
    // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
    emitTlsCall(MI, PPC::S_TLSGD);
    return;
  }
  case PPC::GETtlsTpointer32AIX: {
    // Transform: %r3 = GETtlsTpointer32AIX
    // Into: BLA .__get_tpointer()
    EmitAIXTlsCallHelper(MI);
    return;
  }
  case PPC::ADDIStlsldHA: {
    // Transform: %xd = ADDIStlsldHA %x2, @sym
    // Into:      %xd = ADDIS8 %x2, sym@got@tlsld@ha
    assert(IsPPC64 && "Not supported for 32-bit PowerPC");
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymGotTlsLD =
        symbolWithSpecifier(MOSymbol, PPC::S_GOT_TLSLD_HA);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
                                 .addReg(MI->getOperand(0).getReg())
                                 .addReg(MI->getOperand(1).getReg())
                                 .addExpr(SymGotTlsLD));
    return;
  }
  case PPC::ADDItlsldL:
    // Transform: %xd = ADDItlsldL %xs, @sym
    // Into:      %xd = ADDI8 %xs, sym@got@tlsld@l
  case PPC::ADDItlsldL32: {
    // Transform: %rd = ADDItlsldL32 %rs, @sym
    // Into:      %rd = ADDI %rs, sym@got@tlsld
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymGotTlsLD = symbolWithSpecifier(
        MOSymbol, IsPPC64 ? PPC::S_GOT_TLSLD_LO : PPC::S_GOT_TLSLD);
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
                       .addReg(MI->getOperand(0).getReg())
                       .addReg(MI->getOperand(1).getReg())
                       .addExpr(SymGotTlsLD));
    return;
  }
  case PPC::GETtlsldADDR:
    // Transform: %x3 = GETtlsldADDR %x3, @sym
    // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
  case PPC::GETtlsldADDRPCREL:
  case PPC::GETtlsldADDR32: {
    // Transform: %r3 = GETtlsldADDR32 %r3, @sym
    // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
    emitTlsCall(MI, PPC::S_TLSLD);
    return;
  }
  case PPC::ADDISdtprelHA:
    // Transform: %xd = ADDISdtprelHA %xs, @sym
    // Into:      %xd = ADDIS8 %xs, sym@dtprel@ha
  case PPC::ADDISdtprelHA32: {
    // Transform: %rd = ADDISdtprelHA32 %rs, @sym
    // Into:      %rd = ADDIS %rs, sym@dtprel@ha
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL_HA);
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
            .addReg(MI->getOperand(0).getReg())
            .addReg(MI->getOperand(1).getReg())
            .addExpr(SymDtprel));
    return;
  }
  case PPC::PADDIdtprel: {
    // Transform: %rd = PADDIdtprel %rs, @sym
    // Into:      %rd = PADDI8 %rs, sym@dtprel
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
                                     .addReg(MI->getOperand(0).getReg())
                                     .addReg(MI->getOperand(1).getReg())
                                     .addExpr(SymDtprel));
    return;
  }

  case PPC::ADDIdtprelL:
    // Transform: %xd = ADDIdtprelL %xs, @sym
    // Into:      %xd = ADDI8 %xs, sym@dtprel@l
  case PPC::ADDIdtprelL32: {
    // Transform: %rd = ADDIdtprelL32 %rs, @sym
    // Into:      %rd = ADDI %rs, sym@dtprel@l
    const MachineOperand &MO = MI->getOperand(2);
    const GlobalValue *GValue = MO.getGlobal();
    MCSymbol *MOSymbol = getSymbol(GValue);
    const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL_LO);
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
                       .addReg(MI->getOperand(0).getReg())
                       .addReg(MI->getOperand(1).getReg())
                       .addExpr(SymDtprel));
    return;
  }
  case PPC::MFOCRF:
  case PPC::MFOCRF8:
    if (!Subtarget->hasMFOCRF()) {
      // Transform: %r3 = MFOCRF %cr7
      // Into:      %r3 = MFCR   ;; cr7
      unsigned NewOpcode =
        MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
      OutStreamer->AddComment(PPCInstPrinter::
                              getRegisterName(MI->getOperand(1).getReg()));
      EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
                                  .addReg(MI->getOperand(0).getReg()));
      return;
    }
    break;
  case PPC::MTOCRF:
  case PPC::MTOCRF8:
    if (!Subtarget->hasMFOCRF()) {
      // Transform: %cr7 = MTOCRF %r3
      // Into:      MTCRF mask, %r3 ;; cr7
      unsigned NewOpcode =
        MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
      unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
                              ->getEncodingValue(MI->getOperand(0).getReg());
      OutStreamer->AddComment(PPCInstPrinter::
                              getRegisterName(MI->getOperand(0).getReg()));
      EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
                                     .addImm(Mask)
                                     .addReg(MI->getOperand(1).getReg()));
      return;
    }
    break;
  case PPC::LD:
  case PPC::STD:
  case PPC::LWA_32:
  case PPC::LWA: {
    // Verify alignment is legal, so we don't create relocations
    // that can't be supported.
    unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
    // For non-TOC-based local-exec TLS accesses with non-zero offsets, the
    // machine operand (which is a TargetGlobalTLSAddress) is expected to be
    // the same operand for both loads and stores.
    for (const MachineOperand &TempMO : MI->operands()) {
      if (((TempMO.getTargetFlags() == PPCII::MO_TPREL_FLAG ||
            TempMO.getTargetFlags() == PPCII::MO_TLSLD_FLAG)) &&
          TempMO.getOperandNo() == 1)
        OpNum = 1;
    }
    const MachineOperand &MO = MI->getOperand(OpNum);
    if (MO.isGlobal()) {
      const DataLayout &DL = MO.getGlobal()->getDataLayout();
      if (MO.getGlobal()->getPointerAlignment(DL) < 4)
        llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
    }
    // As these load/stores share common code with the following load/stores,
    // fall through to the subsequent cases in order to either process the
    // non-TOC-based local-exec sequence or to process the instruction normally.
    [[fallthrough]];
  }
  case PPC::LBZ:
  case PPC::LBZ8:
  case PPC::LHA:
  case PPC::LHA8:
  case PPC::LHZ:
  case PPC::LHZ8:
  case PPC::LWZ:
  case PPC::LWZ8:
  case PPC::STB:
  case PPC::STB8:
  case PPC::STH:
  case PPC::STH8:
  case PPC::STW:
  case PPC::STW8:
  case PPC::LFS:
  case PPC::STFS:
  case PPC::LFD:
  case PPC::STFD:
  case PPC::ADDI8: {
    // A faster non-TOC-based local-[exec|dynamic] sequence is represented by
    // `addi` or a load/store instruction (that directly loads or stores off of
    // the thread pointer) with an immediate operand having the
    // [MO_TPREL_FLAG|MO_TLSLD_FLAG]. Such instructions do not otherwise arise.
    if (!HasAIXSmallLocalTLS)
      break;
    bool IsMIADDI8 = MI->getOpcode() == PPC::ADDI8;
    unsigned OpNum = IsMIADDI8 ? 2 : 1;
    const MachineOperand &MO = MI->getOperand(OpNum);
    unsigned Flag = MO.getTargetFlags();
    if (Flag == PPCII::MO_TPREL_FLAG ||
        Flag == PPCII::MO_GOT_TPREL_PCREL_FLAG ||
        Flag == PPCII::MO_TPREL_PCREL_FLAG || Flag == PPCII::MO_TLSLD_FLAG) {
      LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);

      const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.getOffset());
      if (Expr)
        TmpInst.getOperand(OpNum) = MCOperand::createExpr(Expr);

      // Change the opcode to load address if the original opcode is an `addi`.
      if (IsMIADDI8)
        TmpInst.setOpcode(PPC::LA8);

      EmitToStreamer(*OutStreamer, TmpInst);
      return;
    }
    // Now process the instruction normally.
    break;
  }
  case PPC::PseudoEIEIO: {
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
    return;
  }
  }

  LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
  EmitToStreamer(*OutStreamer, TmpInst);
}

// For non-TOC-based local-[exec|dynamic] variables that have a non-zero offset,
// we need to create a new MCExpr that adds the non-zero offset to the address
// of the local-[exec|dynamic] variable that will be used in either an addi,
// load or store. However, the final displacement for these instructions must be
// between [-32768, 32768), so if the TLS address + its non-zero offset is
// greater than 32KB, a new MCExpr is produced to accommodate this situation.
const MCExpr *
PPCAsmPrinter::getAdjustedFasterLocalExpr(const MachineOperand &MO,
                                          int64_t Offset) {
  // Non-zero offsets (for loads, stores or `addi`) require additional handling.
  // When the offset is zero, there is no need to create an adjusted MCExpr.
  if (!Offset)
    return nullptr;

  assert(MO.isGlobal() && "Only expecting a global MachineOperand here!");
  const GlobalValue *GValue = MO.getGlobal();
  TLSModel::Model Model = TM.getTLSModel(GValue);
  assert((Model == TLSModel::LocalExec || Model == TLSModel::LocalDynamic) &&
         "Only local-[exec|dynamic] accesses are handled!");

  bool IsGlobalADeclaration = GValue->isDeclarationForLinker();
  // Find the GlobalVariable that corresponds to the particular TLS variable
  // in the TLS variable-to-address mapping. All TLS variables should exist
  // within this map, with the exception of TLS variables marked as extern.
  const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.find(GValue);
  if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.end())
    assert(IsGlobalADeclaration &&
           "Only expecting to find extern TLS variables not present in the TLS "
           "variable-to-address map!");

  unsigned TLSVarAddress =
      IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
  ptrdiff_t FinalAddress = (TLSVarAddress + Offset);
  // If the address of the TLS variable + the offset is less than 32KB,
  // or if the TLS variable is extern, we simply produce an MCExpr to add the
  // non-zero offset to the TLS variable address.
  // For when TLS variables are extern, this is safe to do because we can
  // assume that the address of extern TLS variables are zero.
  const MCExpr *Expr = MCSymbolRefExpr::create(
      getSymbol(GValue),
      (Model == TLSModel::LocalExec ? PPC::S_AIX_TLSLE : PPC::S_AIX_TLSLD),
      OutContext);
  Expr = MCBinaryExpr::createAdd(
      Expr, MCConstantExpr::create(Offset, OutContext), OutContext);
  if (FinalAddress >= 32768) {
    // Handle the written offset for cases where:
    //   TLS variable address + Offset > 32KB.

    // The assembly that is printed will look like:
    //  TLSVar@le + Offset - Delta
    // where Delta is a multiple of 64KB: ((FinalAddress + 32768) & ~0xFFFF).
    ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
    // Check that the total instruction displacement fits within [-32768,32768).
    [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress + Offset - Delta;
    assert(
        ((InstDisp < 32768) && (InstDisp >= -32768)) &&
        "Expecting the instruction displacement for local-[exec|dynamic] TLS "
        "variables to be between [-32768, 32768)!");
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(-Delta, OutContext), OutContext);
  }

  return Expr;
}

void PPCLinuxAsmPrinter::emitGNUAttributes(Module &M) {
  // Emit float ABI into GNU attribute
  Metadata *MD = M.getModuleFlag("float-abi");
  MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
  if (!FloatABI)
    return;
  StringRef flt = FloatABI->getString();
  // TODO: Support emitting soft-fp and hard double/single attributes.
  if (flt == "doubledouble")
    OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                  Val_GNU_Power_ABI_HardFloat_DP |
                                      Val_GNU_Power_ABI_LDBL_IBM128);
  else if (flt == "ieeequad")
    OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                  Val_GNU_Power_ABI_HardFloat_DP |
                                      Val_GNU_Power_ABI_LDBL_IEEE128);
  else if (flt == "ieeedouble")
    OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
                                  Val_GNU_Power_ABI_HardFloat_DP |
                                      Val_GNU_Power_ABI_LDBL_64);
}

void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
  if (!Subtarget->isPPC64())
    return PPCAsmPrinter::emitInstruction(MI);

  switch (MI->getOpcode()) {
  default:
    break;
  case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
    // .begin:
    //   b .end # lis 0, FuncId[16..32]
    //   nop    # li  0, FuncId[0..15]
    //   std 0, -8(1)
    //   mflr 0
    //   bl __xray_FunctionEntry
    //   mtlr 0
    // .end:
    //
    // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
    // of instructions change.
    // XRAY is only supported on PPC Linux little endian.
    const Function &F = MF->getFunction();
    unsigned Num = F.getFnAttributeAsParsedInteger("patchable-function-entry");

    if (!MAI.isLittleEndian() || Num)
      break;
    MCSymbol *BeginOfSled = OutContext.createTempSymbol();
    MCSymbol *EndOfSled = OutContext.createTempSymbol();
    OutStreamer->emitLabel(BeginOfSled);
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(PPC::B).addExpr(
                       MCSymbolRefExpr::create(EndOfSled, OutContext)));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(PPC::BL8_NOP)
                       .addExpr(MCSymbolRefExpr::create(
                           OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
                           OutContext)));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
    OutStreamer->emitLabel(EndOfSled);
    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2);
    break;
  }
  case TargetOpcode::PATCHABLE_RET: {
    unsigned RetOpcode = MI->getOperand(0).getImm();
    MCInst RetInst;
    RetInst.setOpcode(RetOpcode);
    for (const auto &MO : llvm::drop_begin(MI->operands())) {
      MCOperand MCOp;
      if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this))
        RetInst.addOperand(MCOp);
    }

    bool IsConditional;
    if (RetOpcode == PPC::BCCLR) {
      IsConditional = true;
    } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
               RetOpcode == PPC::TCRETURNai8) {
      break;
    } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
      IsConditional = false;
    } else {
      EmitToStreamer(*OutStreamer, RetInst);
      return;
    }

    MCSymbol *FallthroughLabel;
    if (IsConditional) {
      // Before:
      //   bgtlr cr0
      //
      // After:
      //   ble cr0, .end
      // .p2align 3
      // .begin:
      //   blr    # lis 0, FuncId[16..32]
      //   nop    # li  0, FuncId[0..15]
      //   std 0, -8(1)
      //   mflr 0
      //   bl __xray_FunctionExit
      //   mtlr 0
      //   blr
      // .end:
      //
      // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
      // of instructions change.
      FallthroughLabel = OutContext.createTempSymbol();
      EmitToStreamer(
          *OutStreamer,
          MCInstBuilder(PPC::BCC)
              .addImm(PPC::InvertPredicate(
                  static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
              .addReg(MI->getOperand(2).getReg())
              .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
      RetInst = MCInst();
      RetInst.setOpcode(PPC::BLR8);
    }
    // .p2align 3
    // .begin:
    //   b(lr)? # lis 0, FuncId[16..32]
    //   nop    # li  0, FuncId[0..15]
    //   std 0, -8(1)
    //   mflr 0
    //   bl __xray_FunctionExit
    //   mtlr 0
    //   b(lr)?
    //
    // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
    // of instructions change.
    OutStreamer->emitCodeAlignment(Align(8), getSubtargetInfo());
    MCSymbol *BeginOfSled = OutContext.createTempSymbol();
    OutStreamer->emitLabel(BeginOfSled);
    EmitToStreamer(*OutStreamer, RetInst);
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
    EmitToStreamer(*OutStreamer,
                   MCInstBuilder(PPC::BL8_NOP)
                       .addExpr(MCSymbolRefExpr::create(
                           OutContext.getOrCreateSymbol("__xray_FunctionExit"),
                           OutContext)));
    EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
    EmitToStreamer(*OutStreamer, RetInst);
    if (IsConditional)
      OutStreamer->emitLabel(FallthroughLabel);
    recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2);
    return;
  }
  case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
    llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
  case TargetOpcode::PATCHABLE_TAIL_CALL:
    // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
    // normal function exit from a tail exit.
    llvm_unreachable("Tail call is handled in the normal case. See comments "
                     "around this assert.");
  }
  return PPCAsmPrinter::emitInstruction(MI);
}

void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
  if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
    PPCTargetStreamer *TS =
      static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
    TS->emitAbiVersion(2);
  }

  if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
      !isPositionIndependent())
    return AsmPrinter::emitStartOfAsmFile(M);

  if (M.getPICLevel() == PICLevel::SmallPIC)
    return AsmPrinter::emitStartOfAsmFile(M);

  OutStreamer->switchSection(OutContext.getELFSection(
      ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));

  MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
  MCSymbol *CurrentPos = OutContext.createTempSymbol();

  OutStreamer->emitLabel(CurrentPos);

  // The GOT pointer points to the middle of the GOT, in order to reference the
  // entire 64kB range.  0x8000 is the midpoint.
  const MCExpr *tocExpr =
    MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
                            MCConstantExpr::create(0x8000, OutContext),
                            OutContext);

  OutStreamer->emitAssignment(TOCSym, tocExpr);

  OutStreamer->switchSection(getObjFileLowering().getTextSection());
}

void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
  // linux/ppc32 - Normal entry label.
  if (!Subtarget->isPPC64() &&
      (!isPositionIndependent() ||
       MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
    return AsmPrinter::emitFunctionEntryLabel();

  if (!Subtarget->isPPC64()) {
    const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
    if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
      MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(*MF);
      MCSymbol *PICBase = MF->getPICBaseSymbol();
      OutStreamer->emitLabel(RelocSymbol);

      const MCExpr *OffsExpr =
        MCBinaryExpr::createSub(
          MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
                                                               OutContext),
                                  MCSymbolRefExpr::create(PICBase, OutContext),
          OutContext);
      OutStreamer->emitValue(OffsExpr, 4);
      OutStreamer->emitLabel(CurrentFnSym);
      return;
    } else
      return AsmPrinter::emitFunctionEntryLabel();
  }

  // ELFv2 ABI - Normal entry label.
  if (Subtarget->isELFv2ABI()) {
    // In the Large code model, we allow arbitrary displacements between
    // the text section and its associated TOC section.  We place the
    // full 8-byte offset to the TOC in memory immediately preceding
    // the function global entry point.
    if (TM.getCodeModel() == CodeModel::Large
        && !MF->getRegInfo().use_empty(PPC::X2)) {
      const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();

      MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
      MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol(*MF);
      const MCExpr *TOCDeltaExpr =
        MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
                                MCSymbolRefExpr::create(GlobalEPSymbol,
                                                        OutContext),
                                OutContext);

      OutStreamer->emitLabel(PPCFI->getTOCOffsetSymbol(*MF));
      OutStreamer->emitValue(TOCDeltaExpr, 8);
    }
    return AsmPrinter::emitFunctionEntryLabel();
  }

  // Emit an official procedure descriptor.
  MCSectionSubPair Current = OutStreamer->getCurrentSection();
  MCSectionELF *Section = OutStreamer->getContext().getELFSection(
      ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
  OutStreamer->switchSection(Section);
  OutStreamer->emitLabel(CurrentFnSym);
  OutStreamer->emitValueToAlignment(Align(8));
  MCSymbol *Symbol1 = CurrentFnSymForSize;
  // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
  // entry point.
  OutStreamer->emitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
                         8 /*size*/);
  MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
  // Generates a R_PPC64_TOC relocation for TOC base insertion.
  OutStreamer->emitValue(
      MCSymbolRefExpr::create(Symbol2, PPC::S_TOCBASE, OutContext), 8 /*size*/);
  // Emit a null environment pointer.
  OutStreamer->emitIntValue(0, 8 /* size */);
  OutStreamer->switchSection(Current.first, Current.second);
}

void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {
  const DataLayout &DL = getDataLayout();

  bool isPPC64 = DL.getPointerSizeInBits() == 64;

  PPCTargetStreamer *TS =
      static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

  // If we are using any values provided by Glibc at fixed addresses,
  // we need to ensure that the Glibc used at link time actually provides
  // those values. All versions of Glibc that do will define the symbol
  // named "__parse_hwcap_and_convert_at_platform".
  if (static_cast<const PPCTargetMachine &>(TM).hasGlibcHWCAPAccess())
    OutStreamer->emitSymbolValue(
        GetExternalSymbolSymbol("__parse_hwcap_and_convert_at_platform"),
        MAI.getCodePointerSize());
  emitGNUAttributes(M);

  if (!TOC.empty()) {
    const char *Name = isPPC64 ? ".toc" : ".got2";
    MCSectionELF *Section = OutContext.getELFSection(
        Name, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
    OutStreamer->switchSection(Section);
    if (!isPPC64)
      OutStreamer->emitValueToAlignment(Align(4));

    for (const auto &TOCMapPair : TOC) {
      const MCSymbol *const TOCEntryTarget = TOCMapPair.first.first;
      MCSymbol *const TOCEntryLabel = TOCMapPair.second;

      OutStreamer->emitLabel(TOCEntryLabel);
      if (isPPC64)
        TS->emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
      else
        OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
    }
  }

  PPCAsmPrinter::emitEndOfAsmFile(M);
}

/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
  // In the ELFv2 ABI, in functions that use the TOC register, we need to
  // provide two entry points.  The ABI guarantees that when calling the
  // local entry point, r2 is set up by the caller to contain the TOC base
  // for this function, and when calling the global entry point, r12 is set
  // up by the caller to hold the address of the global entry point.  We
  // thus emit a prefix sequence along the following lines:
  //
  // func:
  // .Lfunc_gepNN:
  //         # global entry point
  //         addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
  //         addi  r2,r2,(.TOC.-.Lfunc_gepNN)@l
  // .Lfunc_lepNN:
  //         .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
  //         # local entry point, followed by function body
  //
  // For the Large code model, we create
  //
  // .Lfunc_tocNN:
  //         .quad .TOC.-.Lfunc_gepNN      # done by EmitFunctionEntryLabel
  // func:
  // .Lfunc_gepNN:
  //         # global entry point
  //         ld    r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
  //         add   r2,r2,r12
  // .Lfunc_lepNN:
  //         .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
  //         # local entry point, followed by function body
  //
  // This ensures we have r2 set up correctly while executing the function
  // body, no matter which entry point is called.
  const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
  const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
                          !MF->getRegInfo().use_empty(PPC::R2);
  const bool PCrelGEPRequired = Subtarget->isUsingPCRelativeCalls() &&
                                UsesX2OrR2 && PPCFI->usesTOCBasePtr();
  const bool NonPCrelGEPRequired = !Subtarget->isUsingPCRelativeCalls() &&
                                   Subtarget->isELFv2ABI() && UsesX2OrR2;

  // Only do all that if the function uses R2 as the TOC pointer
  // in the first place. We don't need the global entry point if the
  // function uses R2 as an allocatable register.
  if (NonPCrelGEPRequired || PCrelGEPRequired) {
    // Note: The logic here must be synchronized with the code in the
    // branch-selection pass which sets the offset of the first block in the
    // function. This matters because it affects the alignment.
    MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol(*MF);
    OutStreamer->emitLabel(GlobalEntryLabel);
    const MCSymbolRefExpr *GlobalEntryLabelExp =
      MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);

    if (TM.getCodeModel() != CodeModel::Large) {
      MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
      const MCExpr *TOCDeltaExpr =
        MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
                                GlobalEntryLabelExp, OutContext);

      const MCExpr *TOCDeltaHi =
          MCSpecifierExpr::create(TOCDeltaExpr, PPC::S_HA, OutContext);
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
                                   .addReg(PPC::X2)
                                   .addReg(PPC::X12)
                                   .addExpr(TOCDeltaHi));

      const MCExpr *TOCDeltaLo =
          MCSpecifierExpr::create(TOCDeltaExpr, PPC::S_LO, OutContext);
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
                                   .addReg(PPC::X2)
                                   .addReg(PPC::X2)
                                   .addExpr(TOCDeltaLo));
    } else {
      MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol(*MF);
      const MCExpr *TOCOffsetDeltaExpr =
        MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
                                GlobalEntryLabelExp, OutContext);

      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
                                   .addReg(PPC::X2)
                                   .addExpr(TOCOffsetDeltaExpr)
                                   .addReg(PPC::X12));
      EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
                                   .addReg(PPC::X2)
                                   .addReg(PPC::X2)
                                   .addReg(PPC::X12));
    }

    MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol(*MF);
    OutStreamer->emitLabel(LocalEntryLabel);
    const MCSymbolRefExpr *LocalEntryLabelExp =
       MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
    const MCExpr *LocalOffsetExp =
      MCBinaryExpr::createSub(LocalEntryLabelExp,
                              GlobalEntryLabelExp, OutContext);

    PPCTargetStreamer *TS =
      static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
    TS->emitLocalEntry(static_cast<MCSymbolELF *>(CurrentFnSym),
                       LocalOffsetExp);
  } else if (Subtarget->isUsingPCRelativeCalls()) {
    // When generating the entry point for a function we have a few scenarios
    // based on whether or not that function uses R2 and whether or not that
    // function makes calls (or is a leaf function).
    // 1) A leaf function that does not use R2 (or treats it as callee-saved
    //    and preserves it). In this case st_other=0 and both
    //    the local and global entry points for the function are the same.
    //    No special entry point code is required.
    // 2) A function uses the TOC pointer R2. This function may or may not have
    //    calls. In this case st_other=[2,6] and the global and local entry
    //    points are different. Code to correctly setup the TOC pointer in R2
    //    is put between the global and local entry points. This case is
    //    covered by the if statatement above.
    // 3) A function does not use the TOC pointer R2 but does have calls.
    //    In this case st_other=1 since we do not know whether or not any
    //    of the callees clobber R2. This case is dealt with in this else if
    //    block. Tail calls are considered calls and the st_other should also
    //    be set to 1 in that case as well.
    // 4) The function does not use the TOC pointer but R2 is used inside
    //    the function. In this case st_other=1 once again.
    // 5) This function uses inline asm. We mark R2 as reserved if the function
    //    has inline asm as we have to assume that it may be used.
    if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
        MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {
      PPCTargetStreamer *TS =
          static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
      TS->emitLocalEntry(static_cast<MCSymbolELF *>(CurrentFnSym),
                         MCConstantExpr::create(1, OutContext));
    }
  }
}

/// EmitFunctionBodyEnd - Print the traceback table before the .size
/// directive.
///
void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
  // Only the 64-bit target requires a traceback table.  For now,
  // we only emit the word of zeroes that GDB requires to find
  // the end of the function, and zeroes for the eight-byte
  // mandatory fields.
  // FIXME: We should fill in the eight-byte mandatory fields as described in
  // the PPC64 ELF ABI (this is a low-priority item because GDB does not
  // currently make use of these fields).
  if (Subtarget->isPPC64()) {
    OutStreamer->emitIntValue(0, 4/*size*/);
    OutStreamer->emitIntValue(0, 8/*size*/);
  }
}

char PPCLinuxAsmPrinter::ID = 0;

INITIALIZE_PASS(PPCLinuxAsmPrinter, "ppc-linux-asm-printer",
                "Linux PPC Assembly Printer", false, false)

void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
                                   MCSymbol *GVSym) const {
  MCSymbolAttr LinkageAttr = MCSA_Invalid;
  switch (GV->getLinkage()) {
  case GlobalValue::ExternalLinkage:
    LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
    break;
  case GlobalValue::LinkOnceAnyLinkage:
  case GlobalValue::LinkOnceODRLinkage:
  case GlobalValue::WeakAnyLinkage:
  case GlobalValue::WeakODRLinkage:
  case GlobalValue::ExternalWeakLinkage:
    LinkageAttr = MCSA_Weak;
    break;
  case GlobalValue::AvailableExternallyLinkage:
    LinkageAttr = MCSA_Extern;
    break;
  case GlobalValue::PrivateLinkage:
    return;
  case GlobalValue::InternalLinkage:
    assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
           "InternalLinkage should not have other visibility setting.");
    LinkageAttr = MCSA_LGlobal;
    break;
  case GlobalValue::AppendingLinkage:
    llvm_unreachable("Should never emit this");
  case GlobalValue::CommonLinkage:
    llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
  }

  assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");

  MCSymbolAttr VisibilityAttr = MCSA_Invalid;
  if (!TM.getIgnoreXCOFFVisibility()) {
    if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
      report_fatal_error(
          "Cannot not be both dllexport and non-default visibility");
    switch (GV->getVisibility()) {

    // TODO: "internal" Visibility needs to go here.
    case GlobalValue::DefaultVisibility:
      if (GV->hasDLLExportStorageClass())
        VisibilityAttr = MAI.getExportedVisibilityAttr();
      break;
    case GlobalValue::HiddenVisibility:
      VisibilityAttr = MAI.getHiddenVisibilityAttr();
      break;
    case GlobalValue::ProtectedVisibility:
      VisibilityAttr = MAI.getProtectedVisibilityAttr();
      break;
    }
  }

  // Do not emit the _$TLSML symbol.
  if (GV->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel &&
      GV->hasName() && GV->getName() == "_$TLSML")
    return;

  OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
                                                    VisibilityAttr);
}

void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
  // Setup CurrentFnDescSym and its containing csect.
  auto *FnDescSec = static_cast<MCSectionXCOFF *>(
      getObjFileLowering().getSectionForFunctionDescriptor(&MF.getFunction(),
                                                           TM));
  FnDescSec->setAlignment(Align(Subtarget->isPPC64() ? 8 : 4));

  CurrentFnDescSym = FnDescSec->getQualNameSymbol();

  return AsmPrinter::SetupMachineFunction(MF);
}

uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
  // Calculate the number of VRs be saved.
  // Vector registers 20 through 31 are marked as reserved and cannot be used
  // in the default ABI.
  const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
  if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
      TM.getAIXExtendedAltivecABI()) {
    const MachineRegisterInfo &MRI = MF->getRegInfo();
    for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
      if (MRI.isPhysRegModified(Reg))
        // Number of VRs saved.
        return PPC::V31 - Reg + 1;
  }
  return 0;
}

void PPCAIXAsmPrinter::emitFunctionBodyEnd() {

  if (!TM.getXCOFFTracebackTable())
    return;

  emitTracebackTable();

  // If ShouldEmitEHBlock returns true, then the eh info table
  // will be emitted via `AIXException::endFunction`. Otherwise, we
  // need to emit a dumy eh info table when VRs are saved. We could not
  // consolidate these two places into one because there is no easy way
  // to access register information in `AIXException` class.
  if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF) &&
      (getNumberOfVRSaved() > 0)) {
    // Emit dummy EH Info Table.
    OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
    MCSymbol *EHInfoLabel =
        TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF);
    OutStreamer->emitLabel(EHInfoLabel);

    // Version number.
    OutStreamer->emitInt32(0);

    const DataLayout &DL = MMI->getModule()->getDataLayout();
    const unsigned PointerSize = DL.getPointerSize();
    // Add necessary paddings in 64 bit mode.
    OutStreamer->emitValueToAlignment(Align(PointerSize));

    OutStreamer->emitIntValue(0, PointerSize);
    OutStreamer->emitIntValue(0, PointerSize);
    OutStreamer->switchSection(MF->getSection());
  }
}

void PPCAIXAsmPrinter::emitTracebackTable() {

  // Create a symbol for the end of function.
  MCSymbol *FuncEnd = createTempSymbol(MF->getName());
  OutStreamer->emitLabel(FuncEnd);

  OutStreamer->AddComment("Traceback table begin");
  // Begin with a fullword of zero.
  OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/);

  SmallString<128> CommentString;
  raw_svector_ostream CommentOS(CommentString);

  auto EmitComment = [&]() {
    OutStreamer->AddComment(CommentOS.str());
    CommentString.clear();
  };

  auto EmitCommentAndValue = [&](uint64_t Value, int Size) {
    EmitComment();
    OutStreamer->emitIntValueInHexWithPadding(Value, Size);
  };

  unsigned int Version = 0;
  CommentOS << "Version = " << Version;
  EmitCommentAndValue(Version, 1);

  // There is a lack of information in the IR to assist with determining the
  // source language. AIX exception handling mechanism would only search for
  // personality routine and LSDA area when such language supports exception
  // handling. So to be conservatively correct and allow runtime to do its job,
  // we need to set it to C++ for now.
  TracebackTable::LanguageID LanguageIdentifier =
      TracebackTable::CPlusPlus; // C++

  CommentOS << "Language = "
            << getNameForTracebackTableLanguageId(LanguageIdentifier);
  EmitCommentAndValue(LanguageIdentifier, 1);

  //  This is only populated for the third and fourth bytes.
  uint32_t FirstHalfOfMandatoryField = 0;

  // Emit the 3rd byte of the mandatory field.

  // We always set traceback offset bit to true.
  FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask;

  const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
  const MachineRegisterInfo &MRI = MF->getRegInfo();

  // Check the function uses floating-point processor instructions or not
  for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
    if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
      FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
      break;
    }
  }

#define GENBOOLCOMMENT(Prefix, V, Field)                                       \
  CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-")   \
            << #Field

#define GENVALUECOMMENT(PrefixAndName, V, Field)                               \
  CommentOS << (PrefixAndName) << " = "                                        \
            << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >>  \
                                     (TracebackTable::Field##Shift))

  GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobalLinkage);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
  EmitComment();

  GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);
  EmitComment();

  GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);
  EmitComment();

  GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);
  EmitComment();
  GENBOOLCOMMENT("", FirstHalfOfMandatoryField,
                 IsFloatingPointOperationLogOrAbortEnabled);
  EmitComment();

  OutStreamer->emitIntValueInHexWithPadding(
      (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);

  // Set the 4th byte of the mandatory field.
  FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;

  const PPCRegisterInfo *RegInfo = Subtarget->getRegisterInfo();
  Register FrameReg = RegInfo->getFrameRegister(*MF);
  if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
    FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;

  const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
  if (!MustSaveCRs.empty())
    FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;

  if (FI->mustSaveLR())
    FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask;

  GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);
  EmitComment();
  GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,
                  OnConditionDirective);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);
  GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);
  EmitComment();
  OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
                                            1);

  // Set the 5th byte of mandatory field.
  uint32_t SecondHalfOfMandatoryField = 0;

  SecondHalfOfMandatoryField |= MF->getFrameInfo().getStackSize()
                                    ? TracebackTable::IsBackChainStoredMask
                                    : 0;

  uint32_t FPRSaved = 0;
  for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {
    if (MRI.isPhysRegModified(Reg)) {
      FPRSaved = PPC::F31 - Reg + 1;
      break;
    }
  }
  SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) &
                                TracebackTable::FPRSavedMask;
  GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);
  GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);
  GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
  EmitComment();
  OutStreamer->emitIntValueInHexWithPadding(
      (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);

  // Set the 6th byte of mandatory field.

  // Check whether has Vector Instruction,We only treat instructions uses vector
  // register as vector instructions.
  bool HasVectorInst = false;
  for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
    if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
      // Has VMX instruction.
      HasVectorInst = true;
      break;
    }

  if (FI->hasVectorParms() || HasVectorInst)
    SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;

  uint16_t NumOfVRSaved = getNumberOfVRSaved();
  bool ShouldEmitEHBlock =
      TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF) || NumOfVRSaved > 0;

  if (ShouldEmitEHBlock)
    SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;

  uint32_t GPRSaved = 0;

  // X13 is reserved under 64-bit environment.
  unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
  unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;

  for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
    if (MRI.isPhysRegModified(Reg)) {
      GPRSaved = GPREnd - Reg + 1;
      break;
    }
  }

  SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &
                                TracebackTable::GPRSavedMask;

  GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasExtensionTable);
  GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasVectorInfo);
  GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
  EmitComment();
  OutStreamer->emitIntValueInHexWithPadding(
      (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);

  // Set the 7th byte of mandatory field.
  uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
  SecondHalfOfMandatoryField |=
      (NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
      TracebackTable::NumberOfFixedParmsMask;
  GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
                  NumberOfFixedParms);
  EmitComment();
  OutStreamer->emitIntValueInHexWithPadding(
      (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);

  // Set the 8th byte of mandatory field.

  // Always set parameter on stack.
  SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;

  uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
  SecondHalfOfMandatoryField |=
      (NumberOfFPParms << TracebackTable::NumberOfFloatingPointParmsShift) &
      TracebackTable::NumberOfFloatingPointParmsMask;

  GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
                  NumberOfFloatingPointParms);
  GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);
  EmitComment();
  OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
                                            1);

  // Generate the optional fields of traceback table.

  // Parameter type.
  if (NumberOfFixedParms || NumberOfFPParms) {
    uint32_t ParmsTypeValue = FI->getParmsType();

    Expected<SmallString<32>> ParmsType =
        FI->hasVectorParms()
            ? XCOFF::parseParmsTypeWithVecInfo(
                  ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
                  FI->getVectorParmsNum())
            : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
                                    NumberOfFPParms);

    assert(ParmsType && toString(ParmsType.takeError()).c_str());
    if (ParmsType) {
      CommentOS << "Parameter type = " << ParmsType.get();
      EmitComment();
    }
    OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
                                              sizeof(ParmsTypeValue));
  }
  // Traceback table offset.
  OutStreamer->AddComment("Function size");
  if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
    MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
        &(MF->getFunction()), TM);
    OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
  }

  // Since we unset the Int_Handler.
  if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask)
    report_fatal_error("Hand_Mask not implement yet");

  if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask)
    report_fatal_error("Ctl_Info not implement yet");

  if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) {
    StringRef Name = MF->getName().substr(0, INT16_MAX);
    int16_t NameLength = Name.size();
    CommentOS << "Function name len = "
              << static_cast<unsigned int>(NameLength);
    EmitCommentAndValue(NameLength, 2);
    OutStreamer->AddComment("Function Name");
    OutStreamer->emitBytes(Name);
  }

  if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) {
    uint8_t AllocReg = XCOFF::AllocRegNo;
    OutStreamer->AddComment("AllocaUsed");
    OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
  }

  if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
    uint16_t VRData = 0;
    if (NumOfVRSaved) {
      // Number of VRs saved.
      VRData |= (NumOfVRSaved << TracebackTable::NumberOfVRSavedShift) &
                TracebackTable::NumberOfVRSavedMask;
      // This bit is supposed to set only when the special register
      // VRSAVE is saved on stack.
      // However, IBM XL compiler sets the bit when any vector registers
      // are saved on the stack. We will follow XL's behavior on AIX
      // so that we don't get surprise behavior change for C code.
      VRData |= TracebackTable::IsVRSavedOnStackMask;
    }

    // Set has_varargs.
    if (FI->getVarArgsFrameIndex())
      VRData |= TracebackTable::HasVarArgsMask;

    // Vector parameters number.
    unsigned VectorParmsNum = FI->getVectorParmsNum();
    VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
              TracebackTable::NumberOfVectorParmsMask;

    if (HasVectorInst)
      VRData |= TracebackTable::HasVMXInstructionMask;

    GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
    GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
    GENBOOLCOMMENT(", ", VRData, HasVarArgs);
    EmitComment();
    OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);

    GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
    GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
    EmitComment();
    OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);

    uint32_t VecParmTypeValue = FI->getVecExtParmsType();

    Expected<SmallString<32>> VecParmsType =
        XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
    assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
    if (VecParmsType) {
      CommentOS << "Vector Parameter type = " << VecParmsType.get();
      EmitComment();
    }
    OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
                                              sizeof(VecParmTypeValue));
    // Padding 2 bytes.
    CommentOS << "Padding";
    EmitCommentAndValue(0, 2);
  }

  uint8_t ExtensionTableFlag = 0;
  if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
    if (ShouldEmitEHBlock)
      ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
    if (EnableSSPCanaryBitInTB &&
        TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(MF))
      ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;

    CommentOS << "ExtensionTableFlag = "
              << getExtendedTBTableFlagString(ExtensionTableFlag);
    EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));
  }

  if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
    auto &Ctx = OutStreamer->getContext();
    MCSymbol *EHInfoSym =
        TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF);
    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
    const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
                                     getObjFileLowering().getTOCBaseSection())
                                     ->getQualNameSymbol();
    const MCExpr *Exp =
        MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
                                MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);

    const DataLayout &DL = getDataLayout();
    OutStreamer->emitValueToAlignment(Align(4));
    OutStreamer->AddComment("EHInfo Table");
    OutStreamer->emitValue(Exp, DL.getPointerSize());
  }
#undef GENBOOLCOMMENT
#undef GENVALUECOMMENT
}

static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV) {
  return GV->hasAppendingLinkage() &&
         StringSwitch<bool>(GV->getName())
             // TODO: Linker could still eliminate the GV if we just skip
             // handling llvm.used array. Skipping them for now until we or the
             // AIX OS team come up with a good solution.
             .Case("llvm.used", true)
             // It's correct to just skip llvm.compiler.used array here.
             .Case("llvm.compiler.used", true)
             .Default(false);
}

static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
  return StringSwitch<bool>(GV->getName())
      .Cases({"llvm.global_ctors", "llvm.global_dtors"}, true)
      .Default(false);
}

uint64_t PPCAIXAsmPrinter::getAliasOffset(const Constant *C) {
  if (auto *GA = dyn_cast<GlobalAlias>(C))
    return getAliasOffset(GA->getAliasee());
  if (auto *CE = dyn_cast<ConstantExpr>(C)) {
    const MCExpr *LowC = lowerConstant(CE);
    const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
    if (!CBE)
      return 0;
    if (CBE->getOpcode() != MCBinaryExpr::Add)
      report_fatal_error("Only adding an offset is supported now.");
    auto *RHS = dyn_cast<MCConstantExpr>(CBE->getRHS());
    if (!RHS)
      report_fatal_error("Unable to get the offset of alias.");
    return RHS->getValue();
  }
  return 0;
}

static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV) {
  // TODO: These asserts should be updated as more support for the toc data
  // transformation is added (struct support, etc.).
  assert(
      PointerSize >= GV->getAlign().valueOrOne().value() &&
      "GlobalVariables with an alignment requirement stricter than TOC entry "
      "size not supported by the toc data transformation.");

  Type *GVType = GV->getValueType();
  assert(GVType->isSized() && "A GlobalVariable's size must be known to be "
                              "supported by the toc data transformation.");
  if (GV->getDataLayout().getTypeSizeInBits(GVType) >
      PointerSize * 8)
    report_fatal_error(
        "A GlobalVariable with size larger than a TOC entry is not currently "
        "supported by the toc data transformation.");
  if (GV->hasPrivateLinkage())
    report_fatal_error("A GlobalVariable with private linkage is not "
                       "currently supported by the toc data transformation.");
}

void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
  // Special LLVM global arrays have been handled at the initialization.
  if (isSpecialLLVMGlobalArrayToSkip(GV) || isSpecialLLVMGlobalArrayForStaticInit(GV))
    return;

  // Ignore non-emitted data.
  if (GV->getSection() == "llvm.metadata")
    return;

  // If the Global Variable has the toc-data attribute, it needs to be emitted
  // when we emit the .toc section.
  if (GV->hasAttribute("toc-data")) {
    unsigned PointerSize = GV->getDataLayout().getPointerSize();
    tocDataChecks(PointerSize, GV);
    TOCDataGlobalVars.push_back(GV);
    return;
  }

  emitGlobalVariableHelper(GV);
}

void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
  assert(!GV->getName().starts_with("llvm.") &&
         "Unhandled intrinsic global variable.");

  if (GV->hasComdat())
    report_fatal_error("COMDAT not yet supported by AIX.");

  auto *GVSym = static_cast<MCSymbolXCOFF *>(getSymbol(GV));

  if (GV->isDeclarationForLinker()) {
    emitLinkage(GV, GVSym);
    return;
  }

  SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
  if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly() &&
      !GVKind.isThreadLocal()) // Checks for both ThreadData and ThreadBSS.
    report_fatal_error("Encountered a global variable kind that is "
                       "not supported yet.");

  // Print GV in verbose mode
  if (isVerbose()) {
    if (GV->hasInitializer()) {
      GV->printAsOperand(OutStreamer->getCommentOS(),
                         /*PrintType=*/false, GV->getParent());
      OutStreamer->getCommentOS() << '\n';
    }
  }

  auto *Csect = static_cast<MCSectionXCOFF *>(
      getObjFileLowering().SectionForGlobal(GV, GVKind, TM));

  // Switch to the containing csect.
  OutStreamer->switchSection(Csect);

  if (GV->hasMetadata(LLVMContext::MD_implicit_ref)) {
    emitRefMetadata(GV);
  }

  const DataLayout &DL = GV->getDataLayout();

  // Handle common and zero-initialized local symbols.
  if (GV->hasCommonLinkage() || GVKind.isBSSLocal() ||
      GVKind.isThreadBSSLocal()) {
    Align Alignment = GV->getAlign().value_or(DL.getPreferredAlign(GV));
    uint64_t Size = GV->getGlobalSize(DL);
    GVSym->setStorageClass(
        TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));

    if (GVKind.isBSSLocal() && Csect->getMappingClass() == XCOFF::XMC_TD) {
      OutStreamer->emitZeros(Size);
    } else if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) {
      assert(Csect->getMappingClass() != XCOFF::XMC_TD &&
             "BSS local toc-data already handled and TLS variables "
             "incompatible with XMC_TD");
      OutStreamer->emitXCOFFLocalCommonSymbol(
          OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
          GVSym, Alignment);
    } else {
      OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
    }
    return;
  }

  MCSymbol *EmittedInitSym = GVSym;

  // Emit linkage for the global variable and its aliases.
  emitLinkage(GV, EmittedInitSym);
  for (const GlobalAlias *GA : GOAliasMap[GV])
    emitLinkage(GA, getSymbol(GA));

  emitAlignment(getGVAlignment(GV, DL), GV);

  // When -fdata-sections is enabled, every GlobalVariable will
  // be put into its own csect; therefore, label is not necessary here.
  if (!TM.getDataSections() || GV->hasSection()) {
    if (Csect->getMappingClass() != XCOFF::XMC_TD)
      OutStreamer->emitLabel(EmittedInitSym);
  }

  // No alias to emit.
  if (!GOAliasMap[GV].size()) {
    emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
    return;
  }

  // Aliases with the same offset should be aligned. Record the list of aliases
  // associated with the offset.
  AliasMapTy AliasList;
  for (const GlobalAlias *GA : GOAliasMap[GV])
    AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);

  // Emit alias label and element value for global variable.
  emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
                     &AliasList);
}

void PPCAIXAsmPrinter::emitFunctionDescriptor() {
  const DataLayout &DL = getDataLayout();
  const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;

  MCSectionSubPair Current = OutStreamer->getCurrentSection();
  // Emit function descriptor.
  OutStreamer->switchSection(
      static_cast<MCSymbolXCOFF *>(CurrentFnDescSym)->getRepresentedCsect());

  // Emit aliasing label for function descriptor csect.
  // An Ifunc doesn't have a corresponding machine function.
  if (MF)
    for (const GlobalAlias *Alias : GOAliasMap[&MF->getFunction()])
      OutStreamer->emitLabel(getSymbol(Alias));

  // Emit function entry point address.
  OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
                         PointerSize);
  // Emit TOC base address.
  const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
                                   getObjFileLowering().getTOCBaseSection())
                                   ->getQualNameSymbol();
  OutStreamer->emitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
                         PointerSize);
  // Emit a null environment pointer.
  OutStreamer->emitIntValue(0, PointerSize);

  OutStreamer->switchSection(Current.first, Current.second);
}

void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
  // For functions without user defined section, it's not necessary to emit the
  // label when we have individual function in its own csect.
  if (!TM.getFunctionSections() || (MF && MF->getFunction().hasSection()))
    PPCAsmPrinter::emitFunctionEntryLabel();

  // an ifunc does not have an associated MachineFunction
  if (!MF)
    return;

  const Function *F = &MF->getFunction();
  // Emit aliasing label for function entry point label.
  for (const GlobalAlias *Alias : GOAliasMap[F])
    OutStreamer->emitLabel(
        getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));

  if (F->hasMetadata(LLVMContext::MD_implicit_ref)) {
    emitRefMetadata(F);
  }
}

void PPCAIXAsmPrinter::emitPGORefs(Module &M) {
  if (!OutContext.hasXCOFFSection(
          "__llvm_prf_cnts",
          XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)))
    return;

  // When inside a csect `foo`, a .ref directive referring to a csect `bar`
  // translates into a relocation entry from `foo` to` bar`. The referring
  // csect, `foo`, is identified by its address.  If multiple csects have the
  // same address (because one or more of them are zero-length), the referring
  // csect cannot be determined. Hence, we don't generate the .ref directives
  // if `__llvm_prf_cnts` is an empty section.
  bool HasNonZeroLengthPrfCntsSection = false;
  const DataLayout &DL = M.getDataLayout();
  for (GlobalVariable &GV : M.globals())
    if (GV.hasSection() && GV.getSection() == "__llvm_prf_cnts" &&
        GV.getGlobalSize(DL) > 0) {
      HasNonZeroLengthPrfCntsSection = true;
      break;
    }

  if (HasNonZeroLengthPrfCntsSection) {
    MCSection *CntsSection = OutContext.getXCOFFSection(
        "__llvm_prf_cnts", SectionKind::getData(),
        XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD),
        /*MultiSymbolsAllowed*/ true);

    OutStreamer->switchSection(CntsSection);
    if (OutContext.hasXCOFFSection(
            "__llvm_prf_data",
            XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD))) {
      MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_data[RW]");
      OutStreamer->emitXCOFFRefDirective(S);
    }
    if (OutContext.hasXCOFFSection(
            "__llvm_prf_names",
            XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD))) {
      MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_names[RO]");
      OutStreamer->emitXCOFFRefDirective(S);
    }
    if (OutContext.hasXCOFFSection(
            "__llvm_prf_vnds",
            XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD))) {
      MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_vnds[RW]");
      OutStreamer->emitXCOFFRefDirective(S);
    }
  }
}

void PPCAIXAsmPrinter::emitGCOVRefs() {
  if (!OutContext.hasXCOFFSection(
          "__llvm_gcov_ctr_section",
          XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)))
    return;

  MCSection *CtrSection = OutContext.getXCOFFSection(
      "__llvm_gcov_ctr_section", SectionKind::getData(),
      XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD),
      /*MultiSymbolsAllowed*/ true);

  OutStreamer->switchSection(CtrSection);
  const XCOFF::StorageMappingClass MappingClass =
      TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;
  if (OutContext.hasXCOFFSection(
          "__llvm_covinit",
          XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD))) {
    const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
                                ? "__llvm_covinit[RO]"
                                : "__llvm_covinit[RW]";
    MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
    OutStreamer->emitXCOFFRefDirective(S);
  }
}

void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
  // If there are no functions and there are no toc-data definitions in this
  // module, we will never need to reference the TOC base.
  if (M.empty() && TOCDataGlobalVars.empty())
    return;

  emitPGORefs(M);
  emitGCOVRefs();

  // Switch to section to emit TOC base.
  OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());

  PPCTargetStreamer *TS =
      static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());

  for (auto &I : TOC) {
    MCSectionXCOFF *TCEntry;
    // Setup the csect for the current TC entry. If the variant kind is
    // VK_AIX_TLSGDM the entry represents the region handle, we create a
    // new symbol to prefix the name with a dot.
    // If TLS model opt is turned on, create a new symbol to prefix the name
    // with a dot.
    if (I.first.second == PPC::S_AIX_TLSGDM ||
        (Subtarget->hasAIXShLibTLSModelOpt() &&
         I.first.second == PPC::S_AIX_TLSLD)) {
      SmallString<128> Name;
      StringRef Prefix = ".";
      Name += Prefix;
      Name += static_cast<const MCSymbolXCOFF *>(I.first.first)
                  ->getSymbolTableName();
      MCSymbol *S = OutContext.getOrCreateSymbol(Name);
      TCEntry = static_cast<MCSectionXCOFF *>(
          getObjFileLowering().getSectionForTOCEntry(S, TM));
    } else {
      TCEntry = static_cast<MCSectionXCOFF *>(
          getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
    }
    OutStreamer->switchSection(TCEntry);

    OutStreamer->emitLabel(I.second);
    TS->emitTCEntry(*I.first.first, I.first.second);
  }

  // Traverse the list of global variables twice, emitting all of the
  // non-common global variables before the common ones, as emitting a
  // .comm directive changes the scope from .toc to the common symbol.
  for (const auto *GV : TOCDataGlobalVars) {
    if (!GV->hasCommonLinkage())
      emitGlobalVariableHelper(GV);
  }
  for (const auto *GV : TOCDataGlobalVars) {
    if (GV->hasCommonLinkage())
      emitGlobalVariableHelper(GV);
  }
}

bool PPCAIXAsmPrinter::doInitialization(Module &M) {
  const bool Result = PPCAsmPrinter::doInitialization(M);

  // Emit the .machine directive on AIX.
  const Triple &Target = TM.getTargetTriple();
  XCOFF::CFileCpuId TargetCpuId = XCOFF::TCPU_INVALID;
  // Walk through the "target-cpu" attribute of functions and use the newest
  // level as the CPU of the module.
  for (auto &F : M) {
    XCOFF::CFileCpuId FunCpuId =
        XCOFF::getCpuID(TM.getSubtargetImpl(F)->getCPU());
    if (FunCpuId > TargetCpuId)
      TargetCpuId = FunCpuId;
  }
  // If there is no "target-cpu" attribute within the functions, take the
  // "-mcpu" value. If both are omitted, use getNormalizedPPCTargetCPU() to
  // determine the default CPU.
  if (!TargetCpuId) {
    StringRef TargetCPU = TM.getTargetCPU();
    TargetCpuId = XCOFF::getCpuID(
        TargetCPU.empty() ? PPC::getNormalizedPPCTargetCPU(Target) : TargetCPU);
  }

  PPCTargetStreamer *TS =
      static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
  TS->emitMachine(XCOFF::getTCPUString(TargetCpuId));

  auto setCsectAlignment = [this](const GlobalObject *GO) {
    // Declarations have 0 alignment which is set by default.
    if (GO->isDeclarationForLinker())
      return;

    SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
    auto *Csect = static_cast<MCSectionXCOFF *>(
        getObjFileLowering().SectionForGlobal(GO, GOKind, TM));

    Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
    Csect->ensureMinAlignment(GOAlign);
  };

  // For all TLS variables, calculate their corresponding addresses and store
  // them into TLSVarsToAddressMapping, which will be used to determine whether
  // or not local-exec TLS variables require special assembly printing.
  uint64_t TLSVarAddress = 0;
  auto DL = M.getDataLayout();
  for (const auto &G : M.globals()) {
    if (G.isThreadLocal() && !G.isDeclaration()) {
      TLSVarAddress = alignTo(TLSVarAddress, getGVAlignment(&G, DL));
      TLSVarsToAddressMapping[&G] = TLSVarAddress;
      TLSVarAddress += G.getGlobalSize(DL);
    }
  }

  // We need to know, up front, the alignment of csects for the assembly path,
  // because once a .csect directive gets emitted, we could not change the
  // alignment value on it.
  for (const auto &G : M.globals()) {
    if (isSpecialLLVMGlobalArrayToSkip(&G))
      continue;

    if (isSpecialLLVMGlobalArrayForStaticInit(&G)) {
      // Generate a format indicator and a unique module id to be a part of
      // the sinit and sterm function names.
      if (FormatIndicatorAndUniqueModId.empty()) {
        std::string UniqueModuleId = getUniqueModuleId(&M);
        if (UniqueModuleId != "")
          // TODO: Use source file full path to generate the unique module id
          // and add a format indicator as a part of function name in case we
          // will support more than one format.
          FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);
        else {
          // Use threadId, Pid, and current time as the unique module id when we
          // cannot generate one based on a module's strong external symbols.
          auto CurTime =
              std::chrono::duration_cast<std::chrono::nanoseconds>(
                  std::chrono::steady_clock::now().time_since_epoch())
                  .count();
          FormatIndicatorAndUniqueModId =
              "clangPidTidTime_" + llvm::itostr(sys::Process::getProcessId()) +
              "_" + llvm::itostr(llvm::get_threadid()) + "_" +
              llvm::itostr(CurTime);
        }
      }

      emitSpecialLLVMGlobal(&G);
      continue;
    }

    setCsectAlignment(&G);
    std::optional<CodeModel::Model> OptionalCodeModel = G.getCodeModel();
    if (OptionalCodeModel)
      setOptionalCodeModel(static_cast<MCSymbolXCOFF *>(getSymbol(&G)),
                           *OptionalCodeModel);
  }

  for (const auto &F : M)
    setCsectAlignment(&F);

  // Construct an aliasing list for each GlobalObject.
  for (const auto &Alias : M.aliases()) {
    const GlobalObject *Aliasee = Alias.getAliaseeObject();
    if (!Aliasee)
      report_fatal_error(
          "alias without a base object is not yet supported on AIX");

    if (Aliasee->hasCommonLinkage()) {
      report_fatal_error("Aliases to common variables are not allowed on AIX:"
                         "\n\tAlias attribute for " +
                             Alias.getName() + " is invalid because " +
                             Aliasee->getName() + " is common.",
                         false);
    }

    const GlobalVariable *GVar =
        dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
    if (GVar) {
      std::optional<CodeModel::Model> OptionalCodeModel = GVar->getCodeModel();
      if (OptionalCodeModel)
        setOptionalCodeModel(static_cast<MCSymbolXCOFF *>(getSymbol(&Alias)),
                             *OptionalCodeModel);
    }

    GOAliasMap[Aliasee].push_back(&Alias);
  }

  return Result;
}

void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
  switch (MI->getOpcode()) {
  default:
    break;
  case PPC::TW:
  case PPC::TWI:
  case PPC::TD:
  case PPC::TDI: {
    if (MI->getNumOperands() < 5)
      break; 
    const MachineOperand &LangMO = MI->getOperand(3);
    const MachineOperand &ReasonMO = MI->getOperand(4);
    if (!LangMO.isImm() || !ReasonMO.isImm())
      break;
    MCSymbol *TempSym = OutContext.createNamedTempSymbol();
    OutStreamer->emitLabel(TempSym);
    OutStreamer->emitXCOFFExceptDirective(
        CurrentFnSym, TempSym, LangMO.getImm(), ReasonMO.getImm(),
        Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8
                             : MI->getMF()->getInstructionCount() * 4,
        hasDebugInfo());
    break;
  }
  case PPC::GETtlsMOD32AIX:
  case PPC::GETtlsMOD64AIX:
  case PPC::GETtlsTpointer32AIX:
  case PPC::GETtlsADDR64AIX:
  case PPC::GETtlsADDR32AIX: {
    // A reference to .__tls_get_mod/.__tls_get_addr/.__get_tpointer is unknown
    // to the assembler so we need to emit an external symbol reference.
    MCSymbol *TlsGetAddr =
        createMCSymbolForTlsGetAddr(OutContext, MI->getOpcode());
    ExtSymSDNodeSymbols.insert(TlsGetAddr);
    break;
  }
  case PPC::BL8:
  case PPC::BL:
  case PPC::BL8_NOP:
  case PPC::BL_NOP:
  case PPC::BL_LWZinto_toc:
  case PPC::BL_LWZinto_toc_RM:
  case PPC::BL8_LDinto_toc:
  case PPC::BL8_LDinto_toc_RM: {
    const MachineOperand &MO = MI->getOperand(0);
    if (MO.isSymbol()) {
      auto *S = static_cast<MCSymbolXCOFF *>(
          OutContext.getOrCreateSymbol(MO.getSymbolName()));
      ExtSymSDNodeSymbols.insert(S);
    }
  } break;
  case PPC::BL_TLS:
  case PPC::BL8_TLS:
  case PPC::BL8_TLS_:
  case PPC::BL8_NOP_TLS:
    report_fatal_error("TLS call not yet implemented");
  case PPC::TAILB:
  case PPC::TAILB8:
  case PPC::TAILBA:
  case PPC::TAILBA8:
  case PPC::TAILBCTR:
  case PPC::TAILBCTR8:
    if (MI->getOperand(0).isSymbol())
      report_fatal_error("Tail call for extern symbol not yet supported.");
    break;
  case PPC::DST:
  case PPC::DST64:
  case PPC::DSTT:
  case PPC::DSTT64:
  case PPC::DSTST:
  case PPC::DSTST64:
  case PPC::DSTSTT:
  case PPC::DSTSTT64:
    EmitToStreamer(
        *OutStreamer,
        MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
    return;
  }
  return PPCAsmPrinter::emitInstruction(MI);
}

bool PPCAIXAsmPrinter::doFinalization(Module &M) {
  for (MCSymbol *Sym : ExtSymSDNodeSymbols)
    OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
  return PPCAsmPrinter::doFinalization(M);
}

static unsigned mapToSinitPriority(int P) {
  if (P < 0 || P > 65535)
    report_fatal_error("invalid init priority");

  if (P <= 20)
    return P;

  if (P < 81)
    return 20 + (P - 20) * 16;

  if (P <= 1124)
    return 1004 + (P - 81);

  if (P < 64512)
    return 2047 + (P - 1124) * 33878;

  return 2147482625u + (P - 64512);
}

static std::string convertToSinitPriority(int Priority) {
  // This helper function converts clang init priority to values used in sinit
  // and sterm functions.
  //
  // The conversion strategies are:
  // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
  // reserved priority range [0, 1023] by
  // - directly mapping the first 21 and the last 20 elements of the ranges
  // - linear interpolating the intermediate values with a step size of 16.
  //
  // We map the non reserved clang/gnu priority range of [101, 65535] into the
  // sinit/sterm priority range [1024, 2147483648] by:
  // - directly mapping the first and the last 1024 elements of the ranges
  // - linear interpolating the intermediate values with a step size of 33878.
  unsigned int P = mapToSinitPriority(Priority);

  std::string PrioritySuffix;
  llvm::raw_string_ostream os(PrioritySuffix);
  os << llvm::format_hex_no_prefix(P, 8);
  return PrioritySuffix;
}

void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
                                          const Constant *List, bool IsCtor) {
  SmallVector<Structor, 8> Structors;
  preprocessXXStructorList(DL, List, Structors);
  if (Structors.empty())
    return;

  unsigned Index = 0;
  for (Structor &S : Structors) {
    if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
      S.Func = CE->getOperand(0);

    llvm::GlobalAlias::create(
        GlobalValue::ExternalLinkage,
        (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
            llvm::Twine(convertToSinitPriority(S.Priority)) +
            llvm::Twine("_", FormatIndicatorAndUniqueModId) +
            llvm::Twine("_", llvm::utostr(Index++)),
        cast<Function>(S.Func));
  }
}

void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
                                          unsigned Encoding) {
  if (GV) {
    TOCEntryType GlobalType = TOCType_GlobalInternal;
    GlobalValue::LinkageTypes Linkage = GV->getLinkage();
    if (Linkage == GlobalValue::ExternalLinkage ||
        Linkage == GlobalValue::AvailableExternallyLinkage ||
        Linkage == GlobalValue::ExternalWeakLinkage)
      GlobalType = TOCType_GlobalExternal;
    MCSymbol *TypeInfoSym = TM.getSymbol(GV);
    MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
    const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
                                     getObjFileLowering().getTOCBaseSection())
                                     ->getQualNameSymbol();
    auto &Ctx = OutStreamer->getContext();
    const MCExpr *Exp =
        MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry, Ctx),
                                MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
    OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
  } else
    OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
}

void PPCAIXAsmPrinter::emitRefMetadata(const GlobalObject *GO) {
  SmallVector<MDNode *> MDs;
  GO->getMetadata(LLVMContext::MD_implicit_ref, MDs);
  assert(MDs.size() && "Expected !implicit.ref metadata nodes");

  for (const MDNode *MD : MDs) {
    const ValueAsMetadata *VAM = cast<ValueAsMetadata>(MD->getOperand(0).get());
    const GlobalValue *GV = cast<GlobalValue>(VAM->getValue());
    MCSymbol *Referenced =
        isa<Function>(GV)
            ? getObjFileLowering().getFunctionEntryPointSymbol(GV, TM)
            : TM.getSymbol(GV);
    OutStreamer->emitXCOFFRefDirective(Referenced);
  }
}

// Return a pass that prints the PPC assembly code for a MachineFunction to the
// given output stream.
static AsmPrinter *
createPPCAsmPrinterPass(TargetMachine &tm,
                        std::unique_ptr<MCStreamer> &&Streamer) {
  if (tm.getTargetTriple().isOSAIX())
    return new PPCAIXAsmPrinter(tm, std::move(Streamer));

  return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
}

void PPCAIXAsmPrinter::emitModuleCommandLines(Module &M) {
  const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
  if (!NMD || !NMD->getNumOperands())
    return;

  std::string S;
  raw_string_ostream RSOS(S);
  for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
    const MDNode *N = NMD->getOperand(i);
    assert(N->getNumOperands() == 1 &&
           "llvm.commandline metadata entry can have only one operand");
    const MDString *MDS = cast<MDString>(N->getOperand(0));
    // Add "@(#)" to support retrieving the command line information with the
    // AIX "what" command
    RSOS << "@(#)opt " << MDS->getString() << "\n";
    RSOS.write('\0');
  }
  OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
}

static bool TOCRestoreNeededForCallToImplementation(const GlobalIFunc &GI) {
  enum class IsLocal {
    Unknown, // Structure of the llvm::Value is not one of the recognizable
             // structures, and so it's unknown if the llvm::Value is the
             // address of a local function at runtime.
    True,    // We can statically prove that all runtime values of the
             // llvm::Value is an address of a local function.
    False    // We can statically prove that one of the runtime values of the
             // llvm::Value is the address of a non-local function; it could be
             // the case that at runtime the non-local function is never
             // selected but we don't care.
  };
  auto Combine = [](IsLocal LHS, IsLocal RHS) -> IsLocal {
    if (LHS == IsLocal::False || RHS == IsLocal::False)
      return IsLocal::False;
    if (LHS == IsLocal::True && RHS == IsLocal::True)
      return IsLocal::True;
    return IsLocal::Unknown;
  };

  // Query if the given function is local to the load module.
  auto IsLocalFunc = [](const Function *F) -> IsLocal {
    bool Result = F->isDSOLocal();
    LLVM_DEBUG(dbgs() << F->getName() << " is "
                      << (Result ? "dso_local\n" : "not dso_local\n"));
    return Result ? IsLocal::True : IsLocal::False;
  };

  // Recursive walker that visits certain patterns that make up the given Value,
  // and returns
  //  - false if at least one non-local function was seen,
  //  - otherwise, return unknown if some unrecognizable pattern was seen,
  //  - otherwise, return true (which means only recognizable patterns were seen
  //    and all possible values are local functions).
  std::function<IsLocal(const Value *)> ValueIsALocalFunc =
      [&IsLocalFunc, &Combine, &ValueIsALocalFunc](const Value *V) -> IsLocal {
    if (auto *F = dyn_cast<Function>(V))
      return IsLocalFunc(F);
    if (!isa<Instruction>(V))
      return IsLocal::Unknown;

    auto *I = cast<Instruction>(V);
    // return isP9 ? foo_p9 : foo_default;
    if (auto *SI = dyn_cast<SelectInst>(I))
      return Combine(ValueIsALocalFunc(SI->getTrueValue()),
                     ValueIsALocalFunc(SI->getFalseValue()));
    else if (auto *PN = dyn_cast<PHINode>(I)) {
      IsLocal Res = IsLocal::True;
      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
        Res = Combine(Res, ValueIsALocalFunc(PN->getIncomingValue(i)));
        if (Res == IsLocal::False)
          return Res;
      }
      return Res;
    }
    // clang-format off
    // @switch.table.resolve_foo = private unnamed_addr constant [3 x ptr] [ptr @foo_static, ptr @foo_hidden, ptr @foo_protected]
    // %switch.gep = getelementptr inbounds nuw ptr, ptr @switch.table, i64 %2
    // V = load ptr, ptr %switch.gep,
    // clang-format on
    else if (auto *Op = getPointerOperand(I)) {
      while (isa<GEPOperator>(Op))
        Op = cast<GEPOperator>(Op)->getPointerOperand();

      if (!isa<GlobalVariable>(Op))
        return IsLocal::Unknown;
      auto *GV = dyn_cast<GlobalVariable>(Op);
      if (!GV->hasInitializer() || !isa<ConstantArray>(GV->getInitializer()))
        return IsLocal::Unknown;
      auto *Init = cast<ConstantArray>(GV->getInitializer());
      IsLocal Res = IsLocal::True;
      for (unsigned Idx = 0, End = Init->getNumOperands(); Idx != End; ++Idx) {
        Res = Combine(Res, ValueIsALocalFunc(Init->getOperand(Idx)));
        if (Res == IsLocal::False)
          return Res;
      }
      return Res;
    }
    return IsLocal::Unknown;
  };

  auto *Resolver = GI.getResolverFunction();
  // If the resolver is preemptible then we cannot rely on its implementation.
  if (IsLocalFunc(Resolver) == IsLocal::False && IFuncLocalIfProven)
    return true;

  // If one of the return values of the resolver function is not a
  // local function, then we have to conservatively do a TOC save/restore.
  IsLocal Res = IsLocal::True;
  for (auto &BB : *Resolver) {
    if (!isa<ReturnInst>(BB.getTerminator()))
      continue;
    auto *Ret = cast<ReturnInst>(BB.getTerminator());
    Value *RV = Ret->getReturnValue();
    assert(RV);
    Res = Combine(Res, ValueIsALocalFunc(RV));
    if (Res == IsLocal::False)
      break;
  }
  // no TOC save/restore needed if either all functions were local or we're
  // being optimistic and no preemptible functions were seen.
  if (Res == IsLocal::True || (Res == IsLocal::Unknown && !IFuncLocalIfProven))
    return false;
  return true;
}
/*
 *   .csect .foo[PR],5
 *   .globl  foo[DS]
 *   .globl  .foo[PR]
 *   .lglobl ifunc_sec.foo[RW]
 *   .align  4
 *   .csect foo[DS],2
 *   .vbyte  4, .foo[PR]
 *   .vbyte  4, TOC[TC0]
 *   .vbyte  4, 0
 *   .csect .foo[PR],5
 *   .ref ifunc_sec.foo[RW]
 *   lwz 12, L..foo_desc(2) # load foo's descriptor address
 *   lwz 11, 8(12)          # load the env pointer (for non-C/C++ functions)
 *   lwz 12, 0(12)          # load foo.addr
 *   mtctr 12
 *   bctr                   # branch to CR without setting LR so that callee
 *                          # returns to the caller of .foo
 *                          # -- End function
 */
void PPCAIXAsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
  // Set the Subtarget to that of the resolver.
  const TargetSubtargetInfo *STI =
      TM.getSubtargetImpl(*GI.getResolverFunction());
  bool IsPPC64 = static_cast<const PPCSubtarget *>(STI)->isPPC64();

  // Create syms and sections that are part of the ifunc implementation:
  //  - Function descriptor symbol foo[RW]
  //  - Function entry symbol .foo[PR]
  MCSectionXCOFF *FnDescSec = static_cast<MCSectionXCOFF *>(
      getObjFileLowering().getSectionForFunctionDescriptor(&GI, TM));
  FnDescSec->setAlignment(Align(IsPPC64 ? 8 : 4));

  CurrentFnDescSym = FnDescSec->getQualNameSymbol();

  CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&GI, TM);

  // Start codegen:
  if (TM.getFunctionSections())
    OutStreamer->switchSection(
        static_cast<MCSymbolXCOFF *>(CurrentFnSym)->getRepresentedCsect());
  else
    OutStreamer->switchSection(getObjFileLowering().getTextSection());

  if (GI.hasMetadata(LLVMContext::MD_implicit_ref))
    emitRefMetadata(&GI);

  // generate linkage for foo and .foo
  emitLinkage(&GI, CurrentFnDescSym);
  emitLinkage(&GI, CurrentFnSym);

  // .align 4
  Align Alignment(STI->getTargetLowering()->getMinFunctionAlignment());
  emitAlignment(Alignment, nullptr);

  // generate foo's function descriptor
  emitFunctionDescriptor();

  emitFunctionEntryLabel();

  // generate the code for .foo now:
  if (TOCRestoreNeededForCallToImplementation(GI)) {
    SmallString<128> Msg;
    Msg.append("unimplemented: TOC register save/restore needed for ifunc \"");
    getNameWithPrefix(Msg, &GI);
    Msg.append("\", because couldn't prove all candidates are static or "
               "hidden/protected visibility definitions");
    if (!IFuncWarnInsteadOfError)
      reportFatalUsageError(Msg.str());
    else
      dbgs() << Msg << "\n";
  }

  auto FnDescTOCEntryType = getTOCEntryTypeForLinkage(GI.getLinkage());
  auto *FnDescTOCEntrySym =
      lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);

  if (TM.getCodeModel() == CodeModel::Large) {
    //  addis 12, L..foo_desc@u(2)
    //  lwz 12, L..foo_desc@l(12)
    auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym, PPC::S_U);
    OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
                                     .addReg(PPC::X12)
                                     .addReg(PPC::X2)
                                     .addExpr(Exp_U),
                                 *Subtarget);
    auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym, PPC::S_L);
    OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
                                     .addReg(PPC::X12)
                                     .addExpr(Exp_L)
                                     .addReg(PPC::X12),
                                 *Subtarget);
  } else {
    //  lwz 12, L..foo_desc(2)
    auto *Exp = MCSymbolRefExpr::create(FnDescTOCEntrySym, OutContext);
    // Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
    // TODO: do we need to uncomment this?
    OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
                                     .addReg(PPC::X12)
                                     .addExpr(Exp)
                                     .addReg(PPC::X2),
                                 *Subtarget);
  }
  //  lwz 11, 8(12)
  OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
                                   .addReg(PPC::X11)
                                   .addImm(IsPPC64 ? 16 : 8)
                                   .addReg(PPC::X12),
                               *Subtarget);
  //  lwz 12, 0(12)
  OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
                                   .addReg(PPC::X12)
                                   .addImm(0)
                                   .addReg(PPC::X12),
                               *Subtarget);
  //  mtctr 12
  OutStreamer->emitInstruction(
      MCInstBuilder(IsPPC64 ? PPC::MTCTR8 : PPC::MTCTR).addReg(PPC::X12),
      *Subtarget);
  //  bctr
  OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::BCTR8 : PPC::BCTR),
                               *Subtarget);
}

char PPCAIXAsmPrinter::ID = 0;

INITIALIZE_PASS(PPCAIXAsmPrinter, "ppc-aix-asm-printer",
                "AIX PPC Assembly Printer", false, false)

// Force static initialization.
extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializePowerPCAsmPrinter() {
  TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
                                     createPPCAsmPrinterPass);
  TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
                                     createPPCAsmPrinterPass);
  TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
                                     createPPCAsmPrinterPass);
  TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
                                     createPPCAsmPrinterPass);
}
