//===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the Hexagon implementation of the TargetRegisterInfo
// class.
//
//===----------------------------------------------------------------------===//

#include "HexagonRegisterInfo.h"
#include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"

#define GET_REGINFO_TARGET_DESC
#include "HexagonGenRegisterInfo.inc"

using namespace llvm;

HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode)
    : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/,
                             0/*PC*/, HwMode) {}


bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
  return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
         R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
}

const MCPhysReg *
HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
      const TargetRegisterClass *RC) const {
  using namespace Hexagon;

  static const MCPhysReg Int32[] = {
    R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
  };
  static const MCPhysReg Int64[] = {
    D0, D1, D2, D3, D4, D5, D6, D7, 0
  };
  static const MCPhysReg Pred[] = {
    P0, P1, P2, P3, 0
  };
  static const MCPhysReg VecSgl[] = {
     V0,  V1,  V2,  V3,  V4,  V5,  V6,  V7,  V8,  V9, V10, V11, V12, V13,
    V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
    V28, V29, V30, V31,   0
  };
  static const MCPhysReg VecDbl[] = {
    W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
  };

  switch (RC->getID()) {
    case IntRegsRegClassID:
      return Int32;
    case DoubleRegsRegClassID:
      return Int64;
    case PredRegsRegClassID:
      return Pred;
    case HvxVRRegClassID:
      return VecSgl;
    case HvxWRRegClassID:
      return VecDbl;
    default:
      break;
  }

  static const MCPhysReg Empty[] = { 0 };
#ifndef NDEBUG
  dbgs() << "Register class: " << getRegClassName(RC) << "\n";
#endif
  llvm_unreachable("Unexpected register class");
  return Empty;
}


const MCPhysReg *
HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
  static const MCPhysReg CalleeSavedRegsV3[] = {
    Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
    Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
    Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
  };

  // Functions that contain a call to __builtin_eh_return also save the first 4
  // parameter registers.
  static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
    Hexagon::R0,    Hexagon::R1,    Hexagon::R2,    Hexagon::R3,
    Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
    Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
    Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
  };

  bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn();

  switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
  case Hexagon::ArchEnum::V4:
  case Hexagon::ArchEnum::V5:
  case Hexagon::ArchEnum::V55:
  case Hexagon::ArchEnum::V60:
  case Hexagon::ArchEnum::V62:
    return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
  }

  llvm_unreachable("Callee saved registers requested for unknown architecture "
                   "version");
}


const uint32_t *HexagonRegisterInfo::getCallPreservedMask(
      const MachineFunction &MF, CallingConv::ID) const {
  return HexagonCSR_RegMask;
}


BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
  const {
  BitVector Reserved(getNumRegs());
  Reserved.set(Hexagon::R29);
  Reserved.set(Hexagon::R30);
  Reserved.set(Hexagon::R31);
  // Control registers.
  Reserved.set(Hexagon::SA0);         // C0
  Reserved.set(Hexagon::LC0);         // C1
  Reserved.set(Hexagon::SA1);         // C2
  Reserved.set(Hexagon::LC1);         // C3
  Reserved.set(Hexagon::P3_0);        // C4
  Reserved.set(Hexagon::USR);         // C8
  Reserved.set(Hexagon::PC);          // C9
  Reserved.set(Hexagon::UGP);         // C10
  Reserved.set(Hexagon::GP);          // C11
  Reserved.set(Hexagon::CS0);         // C12
  Reserved.set(Hexagon::CS1);         // C13
  Reserved.set(Hexagon::UPCYCLELO);   // C14
  Reserved.set(Hexagon::UPCYCLEHI);   // C15
  Reserved.set(Hexagon::FRAMELIMIT);  // C16
  Reserved.set(Hexagon::FRAMEKEY);    // C17
  Reserved.set(Hexagon::PKTCOUNTLO);  // C18
  Reserved.set(Hexagon::PKTCOUNTHI);  // C19
  Reserved.set(Hexagon::UTIMERLO);    // C30
  Reserved.set(Hexagon::UTIMERHI);    // C31
  // Out of the control registers, only C8 is explicitly defined in
  // HexagonRegisterInfo.td. If others are defined, make sure to add
  // them here as well.
  Reserved.set(Hexagon::C8);
  Reserved.set(Hexagon::USR_OVF);

  for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x))
    markSuperRegs(Reserved, x);

  return Reserved;
}


void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
                                              int SPAdj, unsigned FIOp,
                                              RegScavenger *RS) const {
  //
  // Hexagon_TODO: Do we need to enforce this for Hexagon?
  assert(SPAdj == 0 && "Unexpected");

  MachineInstr &MI = *II;
  MachineBasicBlock &MB = *MI.getParent();
  MachineFunction &MF = *MB.getParent();
  auto &HST = MF.getSubtarget<HexagonSubtarget>();
  auto &HII = *HST.getInstrInfo();
  auto &HFI = *HST.getFrameLowering();

  unsigned BP = 0;
  int FI = MI.getOperand(FIOp).getIndex();
  // Select the base pointer (BP) and calculate the actual offset from BP
  // to the beginning of the object at index FI.
  int Offset = HFI.getFrameIndexReference(MF, FI, BP);
  // Add the offset from the instruction.
  int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
  bool IsKill = false;

  unsigned Opc = MI.getOpcode();
  switch (Opc) {
    case Hexagon::PS_fia:
      MI.setDesc(HII.get(Hexagon::A2_addi));
      MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
      MI.RemoveOperand(FIOp+1);
      return;
    case Hexagon::PS_fi:
      // Set up the instruction for updating below.
      MI.setDesc(HII.get(Hexagon::A2_addi));
      break;
  }

  if (!HII.isValidOffset(Opc, RealOffset, this)) {
    // If the offset is not valid, calculate the address in a temporary
    // register and use it with offset 0.
    auto &MRI = MF.getRegInfo();
    unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
    const DebugLoc &DL = MI.getDebugLoc();
    BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR)
      .addReg(BP)
      .addImm(RealOffset);
    BP = TmpR;
    RealOffset = 0;
    IsKill = true;
  }

  MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill);
  MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
}


unsigned HexagonRegisterInfo::getRARegister() const {
  return Hexagon::R31;
}


unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
                                               &MF) const {
  const HexagonFrameLowering *TFI = getFrameLowering(MF);
  if (TFI->hasFP(MF))
    return getFrameRegister();
  return getStackRegister();
}


unsigned HexagonRegisterInfo::getFrameRegister() const {
  return Hexagon::R30;
}


unsigned HexagonRegisterInfo::getStackRegister() const {
  return Hexagon::R29;
}


unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
      const TargetRegisterClass &RC, unsigned GenIdx) const {
  assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi);

  static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
  static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };

  switch (RC.getID()) {
    case Hexagon::CtrRegs64RegClassID:
    case Hexagon::DoubleRegsRegClassID:
      return ISub[GenIdx];
    case Hexagon::HvxWRRegClassID:
      return VSub[GenIdx];
  }

  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
    return getHexagonSubRegIndex(*SuperRC, GenIdx);

  llvm_unreachable("Invalid register class");
}

bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
      const {
  return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
}


unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
  return Hexagon::R6;
}

