//=- AArch64/AArch64MCCodeEmitter.cpp - Convert AArch64 code to machine code =//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AArch64MCCodeEmitter class.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mccodeemitter"
#include "MCTargetDesc/AArch64FixupKinds.h"
#include "MCTargetDesc/AArch64MCExpr.h"
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "Utils/AArch64BaseInfo.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
class AArch64MCCodeEmitter : public MCCodeEmitter {
  AArch64MCCodeEmitter(const AArch64MCCodeEmitter &) LLVM_DELETED_FUNCTION;
  void operator=(const AArch64MCCodeEmitter &) LLVM_DELETED_FUNCTION;
  MCContext &Ctx;

public:
  AArch64MCCodeEmitter(MCContext &ctx) : Ctx(ctx) {}

  ~AArch64MCCodeEmitter() {}

  unsigned getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
                               SmallVectorImpl<MCFixup> &Fixups) const;

  unsigned getAdrpLabelOpValue(const MCInst &MI, unsigned OpIdx,
                               SmallVectorImpl<MCFixup> &Fixups) const;

  template<int MemSize>
  unsigned getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
                                    SmallVectorImpl<MCFixup> &Fixups) const {
    return getOffsetUImm12OpValue(MI, OpIdx, Fixups, MemSize);
  }

  unsigned getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
                                    SmallVectorImpl<MCFixup> &Fixups,
                                    int MemSize) const;

  unsigned getBitfield32LSLOpValue(const MCInst &MI, unsigned OpIdx,
                                   SmallVectorImpl<MCFixup> &Fixups) const;
  unsigned getBitfield64LSLOpValue(const MCInst &MI, unsigned OpIdx,
                                   SmallVectorImpl<MCFixup> &Fixups) const;


  // Labels are handled mostly the same way: a symbol is needed, and
  // just gets some fixup attached.
  template<AArch64::Fixups fixupDesired>
  unsigned getLabelOpValue(const MCInst &MI, unsigned OpIdx,
                           SmallVectorImpl<MCFixup> &Fixups) const;

  unsigned  getLoadLitLabelOpValue(const MCInst &MI, unsigned OpIdx,
                                   SmallVectorImpl<MCFixup> &Fixups) const;


  unsigned getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
                                 SmallVectorImpl<MCFixup> &Fixups) const;


  unsigned getAddressWithFixup(const MCOperand &MO,
                               unsigned FixupKind,
                               SmallVectorImpl<MCFixup> &Fixups) const;


  // getBinaryCodeForInstr - TableGen'erated function for getting the
  // binary encoding for an instruction.
  uint64_t getBinaryCodeForInstr(const MCInst &MI,
                                 SmallVectorImpl<MCFixup> &Fixups) const;

  /// getMachineOpValue - Return binary encoding of operand. If the machine
  /// operand requires relocation, record the relocation and return zero.
  unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
                             SmallVectorImpl<MCFixup> &Fixups) const;


  void EmitByte(unsigned char C, raw_ostream &OS) const {
    OS << (char)C;
  }

  void EmitInstruction(uint32_t Val, raw_ostream &OS) const {
    // Output the constant in little endian byte order.
    for (unsigned i = 0; i != 4; ++i) {
      EmitByte(Val & 0xff, OS);
      Val >>= 8;
    }
  }


  void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
                         SmallVectorImpl<MCFixup> &Fixups) const;

  template<int hasRs, int hasRt2> unsigned
  fixLoadStoreExclusive(const MCInst &MI, unsigned EncodedValue) const;

  unsigned fixMOVZ(const MCInst &MI, unsigned EncodedValue) const;

  unsigned fixMulHigh(const MCInst &MI, unsigned EncodedValue) const;


};

} // end anonymous namespace

unsigned AArch64MCCodeEmitter::getAddressWithFixup(const MCOperand &MO,
                                       unsigned FixupKind,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
  if (!MO.isExpr()) {
    // This can occur for manually decoded or constructed MCInsts, but neither
    // the assembly-parser nor instruction selection will currently produce an
    // MCInst that's not a symbol reference.
    assert(MO.isImm() && "Unexpected address requested");
    return MO.getImm();
  }

  const MCExpr *Expr = MO.getExpr();
  MCFixupKind Kind = MCFixupKind(FixupKind);
  Fixups.push_back(MCFixup::Create(0, Expr, Kind));

  return 0;
}

unsigned AArch64MCCodeEmitter::
getOffsetUImm12OpValue(const MCInst &MI, unsigned OpIdx,
                       SmallVectorImpl<MCFixup> &Fixups,
                       int MemSize) const {
  const MCOperand &ImmOp = MI.getOperand(OpIdx);
  if (ImmOp.isImm())
    return ImmOp.getImm();

  assert(ImmOp.isExpr() && "Unexpected operand type");
  const AArch64MCExpr *Expr = cast<AArch64MCExpr>(ImmOp.getExpr());
  unsigned FixupKind;


  switch (Expr->getKind()) {
  default: llvm_unreachable("Unexpected operand modifier");
  case AArch64MCExpr::VK_AARCH64_LO12: {
    unsigned FixupsBySize[] = { AArch64::fixup_a64_ldst8_lo12,
                                AArch64::fixup_a64_ldst16_lo12,
                                AArch64::fixup_a64_ldst32_lo12,
                                AArch64::fixup_a64_ldst64_lo12,
                                AArch64::fixup_a64_ldst128_lo12 };
    assert(MemSize <= 16 && "Invalid fixup for operation");
    FixupKind = FixupsBySize[Log2_32(MemSize)];
    break;
  }
  case AArch64MCExpr::VK_AARCH64_GOT_LO12:
    assert(MemSize == 8 && "Invalid fixup for operation");
    FixupKind = AArch64::fixup_a64_ld64_got_lo12_nc;
    break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_LO12:  {
    unsigned FixupsBySize[] = { AArch64::fixup_a64_ldst8_dtprel_lo12,
                                AArch64::fixup_a64_ldst16_dtprel_lo12,
                                AArch64::fixup_a64_ldst32_dtprel_lo12,
                                AArch64::fixup_a64_ldst64_dtprel_lo12 };
    assert(MemSize <= 8 && "Invalid fixup for operation");
    FixupKind = FixupsBySize[Log2_32(MemSize)];
    break;
  }
  case AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC: {
    unsigned FixupsBySize[] = { AArch64::fixup_a64_ldst8_dtprel_lo12_nc,
                                AArch64::fixup_a64_ldst16_dtprel_lo12_nc,
                                AArch64::fixup_a64_ldst32_dtprel_lo12_nc,
                                AArch64::fixup_a64_ldst64_dtprel_lo12_nc };
    assert(MemSize <= 8 && "Invalid fixup for operation");
    FixupKind = FixupsBySize[Log2_32(MemSize)];
    break;
  }
  case AArch64MCExpr::VK_AARCH64_GOTTPREL_LO12:
    assert(MemSize == 8 && "Invalid fixup for operation");
    FixupKind = AArch64::fixup_a64_ld64_gottprel_lo12_nc;
    break;
  case AArch64MCExpr::VK_AARCH64_TPREL_LO12:{
    unsigned FixupsBySize[] = { AArch64::fixup_a64_ldst8_tprel_lo12,
                                AArch64::fixup_a64_ldst16_tprel_lo12,
                                AArch64::fixup_a64_ldst32_tprel_lo12,
                                AArch64::fixup_a64_ldst64_tprel_lo12 };
    assert(MemSize <= 8 && "Invalid fixup for operation");
    FixupKind = FixupsBySize[Log2_32(MemSize)];
    break;
  }
  case AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC: {
    unsigned FixupsBySize[] = { AArch64::fixup_a64_ldst8_tprel_lo12_nc,
                                AArch64::fixup_a64_ldst16_tprel_lo12_nc,
                                AArch64::fixup_a64_ldst32_tprel_lo12_nc,
                                AArch64::fixup_a64_ldst64_tprel_lo12_nc };
    assert(MemSize <= 8 && "Invalid fixup for operation");
    FixupKind = FixupsBySize[Log2_32(MemSize)];
    break;
  }
  case AArch64MCExpr::VK_AARCH64_TLSDESC_LO12:
    assert(MemSize == 8 && "Invalid fixup for operation");
    FixupKind = AArch64::fixup_a64_tlsdesc_ld64_lo12_nc;
    break;
  }

  return getAddressWithFixup(ImmOp, FixupKind, Fixups);
}

unsigned
AArch64MCCodeEmitter::getAddSubImmOpValue(const MCInst &MI, unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
  const MCOperand &MO = MI.getOperand(OpIdx);
  if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());

  assert(MO.isExpr());

  unsigned FixupKind = 0;
  switch(cast<AArch64MCExpr>(MO.getExpr())->getKind()) {
  default: llvm_unreachable("Invalid expression modifier");
  case AArch64MCExpr::VK_AARCH64_LO12:
    FixupKind = AArch64::fixup_a64_add_lo12; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_HI12:
    FixupKind = AArch64::fixup_a64_add_dtprel_hi12; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_LO12:
    FixupKind = AArch64::fixup_a64_add_dtprel_lo12; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_LO12_NC:
    FixupKind = AArch64::fixup_a64_add_dtprel_lo12_nc; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_HI12:
    FixupKind = AArch64::fixup_a64_add_tprel_hi12; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_LO12:
    FixupKind = AArch64::fixup_a64_add_tprel_lo12; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_LO12_NC:
    FixupKind = AArch64::fixup_a64_add_tprel_lo12_nc; break;
  case AArch64MCExpr::VK_AARCH64_TLSDESC_LO12:
    FixupKind = AArch64::fixup_a64_tlsdesc_add_lo12_nc; break;
  }

  return getAddressWithFixup(MO, FixupKind, Fixups);
}

unsigned
AArch64MCCodeEmitter::getAdrpLabelOpValue(const MCInst &MI, unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {

  const MCOperand &MO = MI.getOperand(OpIdx);
  if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());

  assert(MO.isExpr());

  unsigned Modifier = AArch64MCExpr::VK_AARCH64_None;
  if (const AArch64MCExpr *Expr = dyn_cast<AArch64MCExpr>(MO.getExpr()))
    Modifier = Expr->getKind();

  unsigned FixupKind = 0;
  switch(Modifier) {
  case AArch64MCExpr::VK_AARCH64_None:
    FixupKind = AArch64::fixup_a64_adr_prel_page;
    break;
  case AArch64MCExpr::VK_AARCH64_GOT:
    FixupKind = AArch64::fixup_a64_adr_prel_got_page;
    break;
  case AArch64MCExpr::VK_AARCH64_GOTTPREL:
    FixupKind = AArch64::fixup_a64_adr_gottprel_page;
    break;
  case AArch64MCExpr::VK_AARCH64_TLSDESC:
    FixupKind = AArch64::fixup_a64_tlsdesc_adr_page;
    break;
  default:
    llvm_unreachable("Unknown symbol reference kind for ADRP instruction");
  }

  return getAddressWithFixup(MO, FixupKind, Fixups);
}

unsigned
AArch64MCCodeEmitter::getBitfield32LSLOpValue(const MCInst &MI, unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {

  const MCOperand &MO = MI.getOperand(OpIdx);
  assert(MO.isImm() && "Only immediate expected for shift");

  return ((32 - MO.getImm()) & 0x1f) | (31 - MO.getImm()) << 6;
}

unsigned
AArch64MCCodeEmitter::getBitfield64LSLOpValue(const MCInst &MI, unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {

  const MCOperand &MO = MI.getOperand(OpIdx);
  assert(MO.isImm() && "Only immediate expected for shift");

  return ((64 - MO.getImm()) & 0x3f) | (63 - MO.getImm()) << 6;
}


template<AArch64::Fixups fixupDesired> unsigned
AArch64MCCodeEmitter::getLabelOpValue(const MCInst &MI,
                                      unsigned OpIdx,
                                      SmallVectorImpl<MCFixup> &Fixups) const {
  const MCOperand &MO = MI.getOperand(OpIdx);

  if (MO.isExpr())
    return getAddressWithFixup(MO, fixupDesired, Fixups);

  assert(MO.isImm());
  return MO.getImm();
}

unsigned
AArch64MCCodeEmitter::getLoadLitLabelOpValue(const MCInst &MI,
                                       unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
  const MCOperand &MO = MI.getOperand(OpIdx);

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

  assert(MO.isExpr());

  unsigned FixupKind;
  if (isa<AArch64MCExpr>(MO.getExpr())) {
    assert(dyn_cast<AArch64MCExpr>(MO.getExpr())->getKind()
           == AArch64MCExpr::VK_AARCH64_GOTTPREL
           && "Invalid symbol modifier for literal load");
    FixupKind = AArch64::fixup_a64_ld_gottprel_prel19;
  } else {
    FixupKind = AArch64::fixup_a64_ld_prel;
  }

  return getAddressWithFixup(MO, FixupKind, Fixups);
}


unsigned
AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                       const MCOperand &MO,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
  if (MO.isReg()) {
    return Ctx.getRegisterInfo().getEncodingValue(MO.getReg());
  } else if (MO.isImm()) {
    return static_cast<unsigned>(MO.getImm());
  }

  llvm_unreachable("Unable to encode MCOperand!");
  return 0;
}

unsigned
AArch64MCCodeEmitter::getMoveWideImmOpValue(const MCInst &MI, unsigned OpIdx,
                                       SmallVectorImpl<MCFixup> &Fixups) const {
  const MCOperand &UImm16MO = MI.getOperand(OpIdx);
  const MCOperand &ShiftMO = MI.getOperand(OpIdx + 1);

  unsigned Result = static_cast<unsigned>(ShiftMO.getImm()) << 16;

  if (UImm16MO.isImm()) {
    Result |= UImm16MO.getImm();
    return Result;
  }

  const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
  AArch64::Fixups requestedFixup;
  switch (A64E->getKind()) {
  default: llvm_unreachable("unexpected expression modifier");
  case AArch64MCExpr::VK_AARCH64_ABS_G0:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g0; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G0_NC:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g0_nc; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G1:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g1; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G1_NC:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g1_nc; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G2:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g2; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G2_NC:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g2_nc; break;
  case AArch64MCExpr::VK_AARCH64_ABS_G3:
    requestedFixup = AArch64::fixup_a64_movw_uabs_g3; break;
  case AArch64MCExpr::VK_AARCH64_SABS_G0:
    requestedFixup = AArch64::fixup_a64_movw_sabs_g0; break;
  case AArch64MCExpr::VK_AARCH64_SABS_G1:
    requestedFixup = AArch64::fixup_a64_movw_sabs_g1; break;
  case AArch64MCExpr::VK_AARCH64_SABS_G2:
    requestedFixup = AArch64::fixup_a64_movw_sabs_g2; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_G2:
    requestedFixup = AArch64::fixup_a64_movw_dtprel_g2; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_G1:
    requestedFixup = AArch64::fixup_a64_movw_dtprel_g1; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_G1_NC:
    requestedFixup = AArch64::fixup_a64_movw_dtprel_g1_nc; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_G0:
    requestedFixup = AArch64::fixup_a64_movw_dtprel_g0; break;
  case AArch64MCExpr::VK_AARCH64_DTPREL_G0_NC:
    requestedFixup = AArch64::fixup_a64_movw_dtprel_g0_nc; break;
  case AArch64MCExpr::VK_AARCH64_GOTTPREL_G1:
    requestedFixup = AArch64::fixup_a64_movw_gottprel_g1; break;
  case AArch64MCExpr::VK_AARCH64_GOTTPREL_G0_NC:
    requestedFixup = AArch64::fixup_a64_movw_gottprel_g0_nc; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_G2:
    requestedFixup = AArch64::fixup_a64_movw_tprel_g2; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_G1:
    requestedFixup = AArch64::fixup_a64_movw_tprel_g1; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_G1_NC:
    requestedFixup = AArch64::fixup_a64_movw_tprel_g1_nc; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_G0:
    requestedFixup = AArch64::fixup_a64_movw_tprel_g0; break;
  case AArch64MCExpr::VK_AARCH64_TPREL_G0_NC:
    requestedFixup = AArch64::fixup_a64_movw_tprel_g0_nc; break;
  }

  return Result | getAddressWithFixup(UImm16MO, requestedFixup, Fixups);
}

template<int hasRs, int hasRt2> unsigned
AArch64MCCodeEmitter::fixLoadStoreExclusive(const MCInst &MI,
                                            unsigned EncodedValue) const {
  if (!hasRs) EncodedValue |= 0x001F0000;
  if (!hasRt2) EncodedValue |= 0x00007C00;

  return EncodedValue;
}

unsigned
AArch64MCCodeEmitter::fixMOVZ(const MCInst &MI, unsigned EncodedValue) const {
  // If one of the signed fixup kinds is applied to a MOVZ instruction, the
  // eventual result could be either a MOVZ or a MOVN. It's the MCCodeEmitter's
  // job to ensure that any bits possibly affected by this are 0. This means we
  // must zero out bit 30 (essentially emitting a MOVN).
  MCOperand UImm16MO = MI.getOperand(1);

  // Nothing to do if there's no fixup.
  if (UImm16MO.isImm())
    return EncodedValue;

  const AArch64MCExpr *A64E = cast<AArch64MCExpr>(UImm16MO.getExpr());
  switch (A64E->getKind()) {
  case AArch64MCExpr::VK_AARCH64_SABS_G0:
  case AArch64MCExpr::VK_AARCH64_SABS_G1:
  case AArch64MCExpr::VK_AARCH64_SABS_G2:
  case AArch64MCExpr::VK_AARCH64_DTPREL_G2:
  case AArch64MCExpr::VK_AARCH64_DTPREL_G1:
  case AArch64MCExpr::VK_AARCH64_DTPREL_G0:
  case AArch64MCExpr::VK_AARCH64_GOTTPREL_G1:
  case AArch64MCExpr::VK_AARCH64_TPREL_G2:
  case AArch64MCExpr::VK_AARCH64_TPREL_G1:
  case AArch64MCExpr::VK_AARCH64_TPREL_G0:
    return EncodedValue & ~(1u << 30);
  default:
    // Nothing to do for an unsigned fixup.
    return EncodedValue;
  }

  llvm_unreachable("Should have returned by now");
}

unsigned
AArch64MCCodeEmitter::fixMulHigh(const MCInst &MI,
                                 unsigned EncodedValue) const {
  // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
  // (i.e. all bits 1) but is ignored by the processor.
  EncodedValue |= 0x1f << 10;
  return EncodedValue;
}

MCCodeEmitter *llvm::createAArch64MCCodeEmitter(const MCInstrInfo &MCII,
                                                const MCRegisterInfo &MRI,
                                                const MCSubtargetInfo &STI,
                                                MCContext &Ctx) {
  return new AArch64MCCodeEmitter(Ctx);
}

void AArch64MCCodeEmitter::
EncodeInstruction(const MCInst &MI, raw_ostream &OS,
                  SmallVectorImpl<MCFixup> &Fixups) const {
  if (MI.getOpcode() == AArch64::TLSDESCCALL) {
    // This is a directive which applies an R_AARCH64_TLSDESC_CALL to the
    // following (BLR) instruction. It doesn't emit any code itself so it
    // doesn't go through the normal TableGenerated channels.
    MCFixupKind Fixup = MCFixupKind(AArch64::fixup_a64_tlsdesc_call);
    const MCExpr *Expr;
    Expr = AArch64MCExpr::CreateTLSDesc(MI.getOperand(0).getExpr(), Ctx);
    Fixups.push_back(MCFixup::Create(0, Expr, Fixup));
    return;
  }

  uint32_t Binary = getBinaryCodeForInstr(MI, Fixups);

  EmitInstruction(Binary, OS);
}


#include "AArch64GenMCCodeEmitter.inc"
