//===-- CSKYAsmPrinter.cpp - CSKY LLVM assembly writer --------------------===//
//
// 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 the CSKY assembly language.
//
//===----------------------------------------------------------------------===//
#include "CSKYAsmPrinter.h"
#include "CSKY.h"
#include "CSKYConstantPoolValue.h"
#include "CSKYTargetMachine.h"
#include "MCTargetDesc/CSKYInstPrinter.h"
#include "MCTargetDesc/CSKYMCAsmInfo.h"
#include "MCTargetDesc/CSKYTargetStreamer.h"
#include "TargetInfo/CSKYTargetInfo.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/TargetRegistry.h"

using namespace llvm;

#define DEBUG_TYPE "csky-asm-printer"

STATISTIC(CSKYNumInstrsCompressed,
          "Number of C-SKY Compressed instructions emitted");

CSKYAsmPrinter::CSKYAsmPrinter(llvm::TargetMachine &TM,
                               std::unique_ptr<llvm::MCStreamer> Streamer)
    : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this) {}

bool CSKYAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
  MCP = MF.getConstantPool();
  TII = MF.getSubtarget().getInstrInfo();

  // Set the current MCSubtargetInfo to a copy which has the correct
  // feature bits for the current MachineFunction
  MCSubtargetInfo &NewSTI =
      OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo());
  NewSTI.setFeatureBits(MF.getSubtarget().getFeatureBits());
  Subtarget = &NewSTI;

  return AsmPrinter::runOnMachineFunction(MF);
}

#define GEN_COMPRESS_INSTR
#include "CSKYGenCompressInstEmitter.inc"
void CSKYAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
  MCInst CInst;
  bool Res = compressInst(CInst, Inst, *Subtarget);
  if (Res)
    ++CSKYNumInstrsCompressed;
  AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
}

// Simple pseudo-instructions have their lowering (with expansion to real
// instructions) auto-generated.
#include "CSKYGenMCPseudoLowering.inc"

void CSKYAsmPrinter::expandTLSLA(const MachineInstr *MI) {
  DebugLoc DL = MI->getDebugLoc();

  MCSymbol *PCLabel = OutContext.getOrCreateSymbol(
      Twine(MAI->getPrivateGlobalPrefix()) + "PC" + Twine(getFunctionNumber()) +
      "_" + Twine(MI->getOperand(3).getImm()));

  OutStreamer->emitLabel(PCLabel);

  auto Instr = BuildMI(*MF, DL, TII->get(CSKY::LRW32))
                   .add(MI->getOperand(0))
                   .add(MI->getOperand(2));
  MCInst LRWInst;
  MCInstLowering.Lower(Instr, LRWInst);
  EmitToStreamer(*OutStreamer, LRWInst);

  Instr = BuildMI(*MF, DL, TII->get(CSKY::GRS32))
              .add(MI->getOperand(1))
              .addSym(PCLabel);
  MCInst GRSInst;
  MCInstLowering.Lower(Instr, GRSInst);
  EmitToStreamer(*OutStreamer, GRSInst);
  return;
}

void CSKYAsmPrinter::emitCustomConstantPool(const MachineInstr *MI) {

  // This instruction represents a floating constant pool in the function.
  // The first operand is the ID# for this instruction, the second is the
  // index into the MachineConstantPool that this is, the third is the size
  // in bytes of this constant pool entry.
  // The required alignment is specified on the basic block holding this MI.
  unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
  unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();

  // If this is the first entry of the pool, mark it.
  if (!InConstantPool) {
    OutStreamer->emitValueToAlignment(Align(4));
    InConstantPool = true;
  }

  OutStreamer->emitLabel(GetCPISymbol(LabelId));

  const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
  if (MCPE.isMachineConstantPoolEntry())
    emitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
  else
    emitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal);
  return;
}

void CSKYAsmPrinter::emitFunctionBodyEnd() {
  // Make sure to terminate any constant pools that were at the end
  // of the function.
  if (!InConstantPool)
    return;
  InConstantPool = false;
}

void CSKYAsmPrinter::emitStartOfAsmFile(Module &M) {
  if (TM.getTargetTriple().isOSBinFormatELF())
    emitAttributes();
}

void CSKYAsmPrinter::emitEndOfAsmFile(Module &M) {
  CSKYTargetStreamer &CTS =
      static_cast<CSKYTargetStreamer &>(*OutStreamer->getTargetStreamer());

  if (TM.getTargetTriple().isOSBinFormatELF())
    CTS.finishAttributeSection();
}

void CSKYAsmPrinter::emitInstruction(const MachineInstr *MI) {
  CSKY_MC::verifyInstructionPredicates(MI->getOpcode(),
                                       getSubtargetInfo().getFeatureBits());

  // Do any auto-generated pseudo lowerings.
  if (MCInst OutInst; lowerPseudoInstExpansion(MI, OutInst)) {
    EmitToStreamer(*OutStreamer, OutInst);
    return;
  }

  // If we just ended a constant pool, mark it as such.
  if (InConstantPool && MI->getOpcode() != CSKY::CONSTPOOL_ENTRY) {
    InConstantPool = false;
  }

  if (MI->getOpcode() == CSKY::PseudoTLSLA32)
    return expandTLSLA(MI);

  if (MI->getOpcode() == CSKY::CONSTPOOL_ENTRY)
    return emitCustomConstantPool(MI);

  MCInst TmpInst;
  MCInstLowering.Lower(MI, TmpInst);
  EmitToStreamer(*OutStreamer, TmpInst);
}

// Convert a CSKY-specific constant pool modifier into the associated
// MCSymbolRefExpr variant kind.
static CSKY::Specifier getModifierVariantKind(CSKYCP::CSKYCPModifier Modifier) {
  switch (Modifier) {
  case CSKYCP::NO_MOD:
    return CSKY::S_None;
  case CSKYCP::ADDR:
    return CSKY::S_ADDR;
  case CSKYCP::GOT:
    return CSKY::S_GOT;
  case CSKYCP::GOTOFF:
    return CSKY::S_GOTOFF;
  case CSKYCP::PLT:
    return CSKY::S_PLT;
  case CSKYCP::TLSGD:
    return CSKY::S_TLSGD;
  case CSKYCP::TLSLE:
    return CSKY::S_TLSLE;
  case CSKYCP::TLSIE:
    return CSKY::S_TLSIE;
  }
  llvm_unreachable("Invalid CSKYCPModifier!");
}

void CSKYAsmPrinter::emitMachineConstantPoolValue(
    MachineConstantPoolValue *MCPV) {
  int Size = getDataLayout().getTypeAllocSize(MCPV->getType());
  CSKYConstantPoolValue *CCPV = static_cast<CSKYConstantPoolValue *>(MCPV);
  MCSymbol *MCSym;

  if (CCPV->isBlockAddress()) {
    const BlockAddress *BA =
        cast<CSKYConstantPoolConstant>(CCPV)->getBlockAddress();
    MCSym = GetBlockAddressSymbol(BA);
  } else if (CCPV->isGlobalValue()) {
    const GlobalValue *GV = cast<CSKYConstantPoolConstant>(CCPV)->getGV();
    MCSym = getSymbol(GV);
  } else if (CCPV->isMachineBasicBlock()) {
    const MachineBasicBlock *MBB = cast<CSKYConstantPoolMBB>(CCPV)->getMBB();
    MCSym = MBB->getSymbol();
  } else if (CCPV->isJT()) {
    signed JTI = cast<CSKYConstantPoolJT>(CCPV)->getJTI();
    MCSym = GetJTISymbol(JTI);
  } else if (CCPV->isConstPool()) {
    const Constant *C = cast<CSKYConstantPoolConstant>(CCPV)->getConstantPool();
    MCSym = GetCPISymbol(MCP->getConstantPoolIndex(C, Align(4)));
  } else {
    assert(CCPV->isExtSymbol() && "unrecognized constant pool value");
    StringRef Sym = cast<CSKYConstantPoolSymbol>(CCPV)->getSymbol();
    MCSym = GetExternalSymbolSymbol(Sym);
  }
  // Create an MCSymbol for the reference.
  const MCExpr *Expr = MCSymbolRefExpr::create(MCSym, OutContext);

  if (CCPV->getPCAdjustment()) {

    MCSymbol *PCLabel = OutContext.getOrCreateSymbol(
        Twine(MAI->getPrivateGlobalPrefix()) + "PC" +
        Twine(getFunctionNumber()) + "_" + Twine(CCPV->getLabelID()));

    const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
    if (CCPV->mustAddCurrentAddress()) {
      // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
      // label, so just emit a local label end reference that instead.
      MCSymbol *DotSym = OutContext.createTempSymbol();
      OutStreamer->emitLabel(DotSym);
      const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
      PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
    }
    Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
  }

  // Create an MCSymbol for the reference.
  Expr = MCSpecifierExpr::create(
      Expr, getModifierVariantKind(CCPV->getModifier()), OutContext);

  OutStreamer->emitValue(Expr, Size);
}

void CSKYAsmPrinter::emitAttributes() {
  CSKYTargetStreamer &CTS =
      static_cast<CSKYTargetStreamer &>(*OutStreamer->getTargetStreamer());

  const Triple &TT = TM.getTargetTriple();
  StringRef CPU = TM.getTargetCPU();
  StringRef FS = TM.getTargetFeatureString();
  const CSKYTargetMachine &CTM = static_cast<const CSKYTargetMachine &>(TM);
  /* TuneCPU doesn't impact emission of ELF attributes, ELF attributes only
     care about arch related features, so we can set TuneCPU as CPU.  */
  const CSKYSubtarget STI(TT, CPU, /*TuneCPU=*/CPU, FS, CTM);

  CTS.emitTargetAttributes(STI);
}

bool CSKYAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                                     const char *ExtraCode, raw_ostream &OS) {
  // First try the generic code, which knows about modifiers like 'c' and 'n'.
  if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
    return false;

  const MachineOperand &MO = MI->getOperand(OpNo);
  if (ExtraCode && ExtraCode[0]) {
    if (ExtraCode[1] != 0)
      return true; // Unknown modifier.

    switch (ExtraCode[0]) {
    default:
      return true; // Unknown modifier.
    case 'R':
      if (MO.getType() == MachineOperand::MO_Register) {
        OS << CSKYInstPrinter::getRegisterName(MO.getReg() + 1);
        return false;
      }
    }
  }

  switch (MO.getType()) {
  case MachineOperand::MO_Immediate:
    OS << MO.getImm();
    return false;
  case MachineOperand::MO_Register:
    if (MO.getReg() == CSKY::C)
      return false;
    OS << CSKYInstPrinter::getRegisterName(MO.getReg());
    return false;
  case MachineOperand::MO_GlobalAddress:
    PrintSymbolOperand(MO, OS);
    return false;
  case MachineOperand::MO_BlockAddress: {
    MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
    Sym->print(OS, MAI);
    return false;
  }
  default:
    break;
  }

  return true;
}

bool CSKYAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
                                           unsigned OpNo, const char *ExtraCode,
                                           raw_ostream &OS) {
  if (!ExtraCode) {
    const MachineOperand &MO = MI->getOperand(OpNo);
    // For now, we only support register memory operands in registers and
    // assume there is no addend
    if (!MO.isReg())
      return true;

    OS << "(" << CSKYInstPrinter::getRegisterName(MO.getReg()) << ", 0)";
    return false;
  }

  return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
}

extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmPrinter() {
  RegisterAsmPrinter<CSKYAsmPrinter> X(getTheCSKYTarget());
}
