//===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===//
//
// 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 class prints an ARC MCInst to a .s file.
//
//===----------------------------------------------------------------------===//

#include "ARCInstPrinter.h"
#include "MCTargetDesc/ARCInfo.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "asm-printer"

#include "ARCGenAsmWriter.inc"

template <class T>
static const char *BadConditionCode(T cc) {
  LLVM_DEBUG(dbgs() << "Unknown condition code passed: " << cc << "\n");
  return "{unknown-cc}";
}

static const char *ARCBRCondCodeToString(ARCCC::BRCondCode BRCC) {
  switch (BRCC) {
  case ARCCC::BREQ:
    return "eq";
  case ARCCC::BRNE:
    return "ne";
  case ARCCC::BRLT:
    return "lt";
  case ARCCC::BRGE:
    return "ge";
  case ARCCC::BRLO:
    return "lo";
  case ARCCC::BRHS:
    return "hs";
  }
  return BadConditionCode(BRCC);
}

static const char *ARCCondCodeToString(ARCCC::CondCode CC) {
  switch (CC) {
  case ARCCC::EQ:
    return "eq";
  case ARCCC::NE:
    return "ne";
  case ARCCC::P:
    return "p";
  case ARCCC::N:
    return "n";
  case ARCCC::HS:
    return "hs";
  case ARCCC::LO:
    return "lo";
  case ARCCC::GT:
    return "gt";
  case ARCCC::GE:
    return "ge";
  case ARCCC::VS:
    return "vs";
  case ARCCC::VC:
    return "vc";
  case ARCCC::LT:
    return "lt";
  case ARCCC::LE:
    return "le";
  case ARCCC::HI:
    return "hi";
  case ARCCC::LS:
    return "ls";
  case ARCCC::PNZ:
    return "pnz";
  case ARCCC::AL:
    return "al";
  case ARCCC::NZ:
    return "nz";
  case ARCCC::Z:
    return "z";
  }
  return BadConditionCode(CC);
}

void ARCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
  OS << StringRef(getRegisterName(RegNo)).lower();
}

void ARCInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                               StringRef Annot, const MCSubtargetInfo &STI,
                               raw_ostream &O) {
  printInstruction(MI, Address, O);
  printAnnotation(O, Annot);
}

static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,
                      raw_ostream &OS) {
  int Offset = 0;
  const MCSymbolRefExpr *SRE;

  if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
    OS << "0x";
    OS.write_hex(CE->getValue());
    return;
  }

  if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) {
    SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
    const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
    assert(SRE && CE && "Binary expression must be sym+const.");
    Offset = CE->getValue();
  } else {
    SRE = dyn_cast<MCSymbolRefExpr>(Expr);
    assert(SRE && "Unexpected MCExpr type.");
  }
  assert(SRE->getKind() == MCSymbolRefExpr::VK_None);

  // Symbols are prefixed with '@'
  OS << '@';
  SRE->getSymbol().print(OS, MAI);

  if (Offset) {
    if (Offset > 0)
      OS << '+';
    OS << Offset;
  }
}

void ARCInstPrinter::printOperand(const MCInst *MI, unsigned OpNum,
                                  raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  if (Op.isReg()) {
    printRegName(O, Op.getReg());
    return;
  }

  if (Op.isImm()) {
    O << Op.getImm();
    return;
  }

  assert(Op.isExpr() && "unknown operand kind in printOperand");
  printExpr(Op.getExpr(), &MAI, O);
}

void ARCInstPrinter::printMemOperandRI(const MCInst *MI, unsigned OpNum,
                                       raw_ostream &O) {
  const MCOperand &base = MI->getOperand(OpNum);
  const MCOperand &offset = MI->getOperand(OpNum + 1);
  assert(base.isReg() && "Base should be register.");
  assert(offset.isImm() && "Offset should be immediate.");
  printRegName(O, base.getReg());
  O << "," << offset.getImm();
}

void ARCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
                                           raw_ostream &O) {

  const MCOperand &Op = MI->getOperand(OpNum);
  assert(Op.isImm() && "Predicate operand is immediate.");
  O << ARCCondCodeToString((ARCCC::CondCode)Op.getImm());
}

void ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,
                                               raw_ostream &O) {
  const MCOperand &Op = MI->getOperand(OpNum);
  assert(Op.isImm() && "Predicate operand is immediate.");
  O << ARCBRCondCodeToString((ARCCC::BRCondCode)Op.getImm());
}
