//===- subzero/src/IceInstX8664.cpp - X86-64 instruction implementation ---===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file defines X8664 specific data related to X8664 Instructions
/// and Instruction traits.
///
/// These are declared in the IceTargetLoweringX8664Traits.h header file.
///
/// This file also defines X8664 operand specific methods (dump and emit.)
///
//===----------------------------------------------------------------------===//
#include "IceInstX8664.h"

#include "IceAssemblerX8664.h"
#include "IceCfg.h"
#include "IceCfgNode.h"
#include "IceConditionCodesX86.h"
#include "IceInst.h"
#include "IceOperand.h"
#include "IceRegistersX8664.h"
#include "IceTargetLoweringX8664.h"

namespace Ice {

namespace X8664 {

const TargetX8664Traits::InstBrAttributesType
    TargetX8664Traits::InstBrAttributes[] = {
#define X(val, encode, opp, dump, emit) {CondX86::opp, dump, emit},
        ICEINSTX86BR_TABLE
#undef X
};

const TargetX8664Traits::InstCmppsAttributesType
    TargetX8664Traits::InstCmppsAttributes[] = {
#define X(val, emit) {emit},
        ICEINSTX86CMPPS_TABLE
#undef X
};

const TargetX8664Traits::TypeAttributesType
    TargetX8664Traits::TypeAttributes[] = {
#define X(tag, elty, cvt, sdss, pdps, spsd, int_, unpack, pack, width, fld)    \
  {cvt, sdss, pdps, spsd, int_, unpack, pack, width, fld},
        ICETYPEX86_TABLE
#undef X
};

void TargetX8664Traits::X86Operand::dump(const Cfg *, Ostream &Str) const {
  if (BuildDefs::dump())
    Str << "<OperandX8664>";
}

TargetX8664Traits::X86OperandMem::X86OperandMem(Cfg *Func, Type Ty,
                                                Variable *Base,
                                                Constant *Offset,
                                                Variable *Index, uint16_t Shift,
                                                bool IsRebased)
    : X86Operand(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
      Shift(Shift), IsRebased(IsRebased) {
  assert(Shift <= 3);
  Vars = nullptr;
  NumVars = 0;
  if (Base)
    ++NumVars;
  if (Index)
    ++NumVars;
  if (NumVars) {
    Vars = Func->allocateArrayOf<Variable *>(NumVars);
    SizeT I = 0;
    if (Base)
      Vars[I++] = Base;
    if (Index)
      Vars[I++] = Index;
    assert(I == NumVars);
  }
}

namespace {
int32_t getRematerializableOffset(Variable *Var,
                                  const ::Ice::X8664::TargetX8664 *Target) {
  int32_t Disp = Var->getStackOffset();
  const auto RegNum = Var->getRegNum();
  if (RegNum == Target->getFrameReg()) {
    Disp += Target->getFrameFixedAllocaOffset();
  } else if (RegNum != Target->getStackReg()) {
    llvm::report_fatal_error("Unexpected rematerializable register type");
  }
  return Disp;
}
} // end of anonymous namespace

void TargetX8664Traits::X86OperandMem::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  const auto *Target =
      static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget());
  // If the base is rematerializable, we need to replace it with the correct
  // physical register (stack or base pointer), and update the Offset.
  int32_t Disp = 0;
  if (getBase() && getBase()->isRematerializable()) {
    Disp += getRematerializableOffset(getBase(), Target);
  }
  // The index should never be rematerializable.  But if we ever allow it, then
  // we should make sure the rematerialization offset is shifted by the Shift
  // value.
  if (getIndex())
    assert(!getIndex()->isRematerializable());
  Ostream &Str = Func->getContext()->getStrEmit();
  // Emit as Offset(Base,Index,1<<Shift). Offset is emitted without the leading
  // '$'. Omit the (Base,Index,1<<Shift) part if Base==nullptr.
  if (getOffset() == nullptr && Disp == 0) {
    // No offset, emit nothing.
  } else if (getOffset() == nullptr && Disp != 0) {
    Str << Disp;
  } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
    if (Base == nullptr || CI->getValue() || Disp != 0)
      // Emit a non-zero offset without a leading '$'.
      Str << CI->getValue() + Disp;
  } else if (const auto *CR = llvm::dyn_cast<ConstantRelocatable>(Offset)) {
    // TODO(sehr): ConstantRelocatable still needs updating for
    // rematerializable base/index and Disp.
    assert(Disp == 0);
    CR->emitWithoutPrefix(Target);
    if (Base == nullptr && Index == nullptr) {
      // rip-relative addressing.
      Str << "(%rip)";
    }
  } else {
    llvm_unreachable("Invalid offset type for x86 mem operand");
  }

  if (Base == nullptr && Index == nullptr) {
    return;
  }

  Str << "(";
  if (Base != nullptr) {
    Base->emit(Func);
  }

  if (Index != nullptr) {
    Variable *I = Index;
    Str << ",";
    I->emit(Func);
    if (Shift)
      Str << "," << (1u << Shift);
  }

  Str << ")";
}

void TargetX8664Traits::X86OperandMem::dump(const Cfg *Func,
                                            Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  bool Dumped = false;
  Str << "[";
  int32_t Disp = 0;
  const auto *Target =
      static_cast<const ::Ice::X8664::TargetX8664 *>(Func->getTarget());
  if (getBase() && getBase()->isRematerializable()) {
    Disp += getRematerializableOffset(getBase(), Target);
  }
  if (Base) {
    if (Func)
      Base->dump(Func);
    else
      Base->dump(Str);
    Dumped = true;
  }
  if (Index) {
    if (Base)
      Str << "+";
    if (Shift > 0)
      Str << (1u << Shift) << "*";
    if (Func)
      Index->dump(Func);
    else
      Index->dump(Str);
    Dumped = true;
  }
  if (Disp) {
    if (Disp > 0)
      Str << "+";
    Str << Disp;
    Dumped = true;
  }
  // Pretty-print the Offset.
  bool OffsetIsZero = false;
  bool OffsetIsNegative = false;
  if (!Offset) {
    OffsetIsZero = true;
  } else if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(Offset)) {
    OffsetIsZero = (CI->getValue() == 0);
    OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
  } else {
    assert(llvm::isa<ConstantRelocatable>(Offset));
  }
  if (Dumped) {
    if (!OffsetIsZero) {     // Suppress if Offset is known to be 0
      if (!OffsetIsNegative) // Suppress if Offset is known to be negative
        Str << "+";
      Offset->dump(Func, Str);
    }
  } else {
    // There is only the offset.
    Offset->dump(Func, Str);
  }
  Str << "]";
}

TargetX8664Traits::Address TargetX8664Traits::X86OperandMem::toAsmAddress(
    TargetX8664Traits::Assembler *Asm,
    const Ice::TargetLowering *TargetLowering, bool IsLeaAddr) const {
  (void)IsLeaAddr;
  const auto *Target =
      static_cast<const ::Ice::X8664::TargetX8664 *>(TargetLowering);
  int32_t Disp = 0;
  if (getBase() && getBase()->isRematerializable()) {
    Disp += getRematerializableOffset(getBase(), Target);
  }
  if (getIndex() != nullptr) {
    assert(!getIndex()->isRematerializable());
  }

  AssemblerFixup *Fixup = nullptr;
  // Determine the offset (is it relocatable?)
  if (getOffset() != nullptr) {
    if (const auto *CI = llvm::dyn_cast<ConstantInteger32>(getOffset())) {
      Disp += static_cast<int32_t>(CI->getValue());
    } else if (const auto *CR =
                   llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
      const auto FixupKind =
          (getBase() != nullptr || getIndex() != nullptr) ? FK_Abs : FK_PcRel;
      const RelocOffsetT DispAdjustment = FixupKind == FK_PcRel ? 4 : 0;
      Fixup = Asm->createFixup(FixupKind, CR);
      Fixup->set_addend(-DispAdjustment);
      Disp = CR->getOffset();
    } else {
      llvm_unreachable("Unexpected offset type");
    }
  }

  // Now convert to the various possible forms.
  if (getBase() && getIndex()) {
    return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()),
                                  getEncodedGPR(getIndex()->getRegNum()),
                                  X8664::Traits::ScaleFactor(getShift()), Disp,
                                  Fixup);
  }

  if (getBase()) {
    return X8664::Traits::Address(getEncodedGPR(getBase()->getRegNum()), Disp,
                                  Fixup);
  }

  if (getIndex()) {
    return X8664::Traits::Address(getEncodedGPR(getIndex()->getRegNum()),
                                  X8664::Traits::ScaleFactor(getShift()), Disp,
                                  Fixup);
  }

  if (Fixup == nullptr) {
    return X8664::Traits::Address::Absolute(Disp);
  }

  return X8664::Traits::Address::RipRelative(Disp, Fixup);
}

TargetX8664Traits::Address
TargetX8664Traits::VariableSplit::toAsmAddress(const Cfg *Func) const {
  assert(!Var->hasReg());
  const ::Ice::TargetLowering *Target = Func->getTarget();
  int32_t Offset = Var->getStackOffset() + getOffset();
  return X8664::Traits::Address(getEncodedGPR(Target->getFrameOrStackReg()),
                                Offset, AssemblerFixup::NoFixup);
}

void TargetX8664Traits::VariableSplit::emit(const Cfg *Func) const {
  if (!BuildDefs::dump())
    return;
  Ostream &Str = Func->getContext()->getStrEmit();
  assert(!Var->hasReg());
  // The following is copied/adapted from TargetX8664::emitVariable().
  const ::Ice::TargetLowering *Target = Func->getTarget();
  constexpr Type Ty = IceType_i32;
  int32_t Offset = Var->getStackOffset() + getOffset();
  if (Offset)
    Str << Offset;
  Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
}

void TargetX8664Traits::VariableSplit::dump(const Cfg *Func,
                                            Ostream &Str) const {
  if (!BuildDefs::dump())
    return;
  switch (Part) {
  case Low:
    Str << "low";
    break;
  case High:
    Str << "high";
    break;
  }
  Str << "(";
  if (Func)
    Var->dump(Func);
  else
    Var->dump(Str);
  Str << ")";
}

} // namespace X8664
} // end of namespace Ice
