//===-- XtensaMCCodeEmitter.cpp - Convert Xtensa Code to Machine Code -----===//
//
//                     The LLVM Compiler Infrastructure
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the XtensaMCCodeEmitter class.
//
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/XtensaFixupKinds.h"
#include "MCTargetDesc/XtensaMCExpr.h"
#include "MCTargetDesc/XtensaMCTargetDesc.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"

#define GET_INSTRMAP_INFO
#include "XtensaGenInstrInfo.inc"
#undef GET_INSTRMAP_INFO

using namespace llvm;

#define DEBUG_TYPE "mccodeemitter"

namespace {
class XtensaMCCodeEmitter : public MCCodeEmitter {
  const MCInstrInfo &MCII;
  MCContext &Ctx;
  bool IsLittleEndian;

public:
  XtensaMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool isLE)
      : MCII(mcii), Ctx(ctx), IsLittleEndian(isLE) {}

  ~XtensaMCCodeEmitter() {}

  // OVerride MCCodeEmitter.
  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
                         SmallVectorImpl<MCFixup> &Fixups,
                         const MCSubtargetInfo &STI) const override;

private:
  // Automatically generated by TableGen.
  uint64_t getBinaryCodeForInstr(const MCInst &MI,
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;

  // Called by the TableGen code to get the binary encoding of operand
  // MO in MI.  Fixups is the list of fixups against MI.
  uint32_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;

  uint32_t getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;

  uint32_t getBranchTargetEncoding(const MCInst &MI, unsigned int OpNum,
                                   SmallVectorImpl<MCFixup> &Fixups,
                                   const MCSubtargetInfo &STI) const;

  uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,
                           SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;

  uint32_t getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;

  uint32_t getMemRegEncoding(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;

  uint32_t getImm8OpValue(const MCInst &MI, unsigned OpNo,
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const;

  uint32_t getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;

  uint32_t getImm12OpValue(const MCInst &MI, unsigned OpNo,
                           SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;

  uint32_t getUimm4OpValue(const MCInst &MI, unsigned OpNo,
                           SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;

  uint32_t getUimm5OpValue(const MCInst &MI, unsigned OpNo,
                           SmallVectorImpl<MCFixup> &Fixups,
                           const MCSubtargetInfo &STI) const;

  uint32_t getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;

  uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
                               SmallVectorImpl<MCFixup> &Fixups,
                               const MCSubtargetInfo &STI) const;

  uint32_t getB4constOpValue(const MCInst &MI, unsigned OpNo,
                             SmallVectorImpl<MCFixup> &Fixups,
                             const MCSubtargetInfo &STI) const;

  uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
};
} // namespace

MCCodeEmitter *llvm::createXtensaMCCodeEmitter(const MCInstrInfo &MCII,
                                               MCContext &Ctx) {
  return new XtensaMCCodeEmitter(MCII, Ctx, true);
}

void XtensaMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
  unsigned Size = MCII.get(MI.getOpcode()).getSize();

  if (IsLittleEndian) {
    // Little-endian insertion of Size bytes.
    unsigned ShiftValue = 0;
    for (unsigned I = 0; I != Size; ++I) {
      OS << uint8_t(Bits >> ShiftValue);
      ShiftValue += 8;
    }
  } else {
    // TODO Big-endian insertion of Size bytes.
    report_fatal_error("Big-endian mode currently is not supported!");
  }
}

uint32_t
XtensaMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const {
  if (MO.isReg())
    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
  if (MO.isImm()) {
    uint32_t Res = static_cast<uint32_t>(MO.getImm());
    return Res;
  }

  report_fatal_error("Unhandled expression!");
  return 0;
}

uint32_t
XtensaMCCodeEmitter::getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,
                                           SmallVectorImpl<MCFixup> &Fixups,
                                           const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNum);

  if (MO.isImm())
    return MO.getImm();

  const MCExpr *Expr = MO.getExpr();
  Fixups.push_back(MCFixup::create(
      0, Expr, MCFixupKind(Xtensa::fixup_xtensa_jump_18), MI.getLoc()));
  return 0;
}

uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(
    const MCInst &MI, unsigned int OpNum, SmallVectorImpl<MCFixup> &Fixups,
    const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNum);
  if (MO.isImm())
    return static_cast<uint32_t>(MO.getImm());

  const MCExpr *Expr = MO.getExpr();
  switch (MI.getOpcode()) {
  case Xtensa::BEQZ:
  case Xtensa::BGEZ:
  case Xtensa::BLTZ:
  case Xtensa::BNEZ:
    Fixups.push_back(MCFixup::create(
        0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_12), MI.getLoc()));
    return 0;
  default:
    Fixups.push_back(MCFixup::create(
        0, Expr, MCFixupKind(Xtensa::fixup_xtensa_branch_8), MI.getLoc()));
    return 0;
  }
}

uint32_t
XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNum);
  if (MO.isImm()) {
    int32_t Res = MO.getImm();
    if (Res & 0x3) {
      llvm_unreachable("Unexpected operand value!");
    }
    Res >>= 2;
    return Res;
  }

  assert((MO.isExpr()) && "Unexpected operand value!");
  const MCExpr *Expr = MO.getExpr();
  Fixups.push_back(MCFixup::create(
      0, Expr, MCFixupKind(Xtensa::fixup_xtensa_call_18), MI.getLoc()));
  return 0;
}

uint32_t
XtensaMCCodeEmitter::getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,
                                           SmallVectorImpl<MCFixup> &Fixups,
                                           const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNum);
  if (MO.isImm()) {
    int32_t Res = MO.getImm();
    // We don't check first 2 bits, because in these bits we could store first 2
    // bits of instruction address
    Res >>= 2;
    return Res;
  }

  assert((MO.isExpr()) && "Unexpected operand value!");

  Fixups.push_back(MCFixup::create(
      0, MO.getExpr(), MCFixupKind(Xtensa::fixup_xtensa_l32r_16), MI.getLoc()));
  return 0;
}

uint32_t
XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const {
  assert(MI.getOperand(OpNo + 1).isImm());

  uint32_t Res = static_cast<uint32_t>(MI.getOperand(OpNo + 1).getImm());

  switch (MI.getOpcode()) {
  case Xtensa::S16I:
  case Xtensa::L16SI:
  case Xtensa::L16UI:
    if (Res & 0x1) {
      report_fatal_error("Unexpected operand value!");
    }
    Res >>= 1;
    break;
  case Xtensa::S32I:
  case Xtensa::L32I:
    if (Res & 0x3) {
      report_fatal_error("Unexpected operand value!");
    }
    Res >>= 2;
    break;
  }
  
  assert((isUInt<8>(Res)) && "Unexpected operand value!");

  uint32_t OffBits = Res << 4;
  uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);

  return ((OffBits & 0xFF0) | RegBits);
}

uint32_t XtensaMCCodeEmitter::getImm8OpValue(const MCInst &MI, unsigned OpNo,
                                             SmallVectorImpl<MCFixup> &Fixups,
                                             const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  int32_t Res = MO.getImm();

  assert(((Res >= -128) && (Res <= 127)) && "Unexpected operand value!");

  return (Res & 0xff);
}

uint32_t
XtensaMCCodeEmitter::getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  int32_t Res = MO.getImm();

  assert(((Res >= -32768) && (Res <= 32512) && ((Res & 0xff) == 0)) &&
         "Unexpected operand value!");

  return (Res & 0xffff);
}

uint32_t
XtensaMCCodeEmitter::getImm12OpValue(const MCInst &MI, unsigned OpNo,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  int32_t Res = MO.getImm();

  assert(((Res >= -2048) && (Res <= 2047)) && "Unexpected operand value!");

  return (Res & 0xfff);
}

uint32_t
XtensaMCCodeEmitter::getUimm4OpValue(const MCInst &MI, unsigned OpNo,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  assert((Res <= 15) && "Unexpected operand value!");

  return Res & 0xf;
}

uint32_t
XtensaMCCodeEmitter::getUimm5OpValue(const MCInst &MI, unsigned OpNo,
                                     SmallVectorImpl<MCFixup> &Fixups,
                                     const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  assert((Res <= 31) && "Unexpected operand value!");

  return (Res & 0x1f);
}

uint32_t
XtensaMCCodeEmitter::getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,
                                         SmallVectorImpl<MCFixup> &Fixups,
                                         const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  assert(((Res >= 1) && (Res <= 31)) && "Unexpected operand value!");

  return ((32 - Res) & 0x1f);
}

uint32_t
XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  assert(((Res >= 1) && (Res <= 16)) && "Unexpected operand value!");

  return (Res - 1);
}

uint32_t
XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,
                                       SmallVectorImpl<MCFixup> &Fixups,
                                       const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  switch (Res) {
  case 0xffffffff:
    Res = 0;
    break;
  case 1:
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
    break;
  case 10:
    Res = 9;
    break;
  case 12:
    Res = 10;
    break;
  case 16:
    Res = 11;
    break;
  case 32:
    Res = 12;
    break;
  case 64:
    Res = 13;
    break;
  case 128:
    Res = 14;
    break;
  case 256:
    Res = 15;
    break;
  default:
    llvm_unreachable("Unexpected operand value!");
  }

  return Res;
}

uint32_t
XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  const MCOperand &MO = MI.getOperand(OpNo);
  uint32_t Res = static_cast<uint32_t>(MO.getImm());

  switch (Res) {
  case 32768:
    Res = 0;
    break;
  case 65536:
    Res = 1;
    break;
  case 2:
  case 3:
  case 4:
  case 5:
  case 6:
  case 7:
  case 8:
    break;
  case 10:
    Res = 9;
    break;
  case 12:
    Res = 10;
    break;
  case 16:
    Res = 11;
    break;
  case 32:
    Res = 12;
    break;
  case 64:
    Res = 13;
    break;
  case 128:
    Res = 14;
    break;
  case 256:
    Res = 15;
    break;
  default:
    llvm_unreachable("Unexpected operand value!");
  }

  return Res;
}
#include "XtensaGenMCCodeEmitter.inc"
