Home | History | Annotate | Download | only in Hexagon
      1 //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the Hexagon implementation of the TargetRegisterInfo
     11 // class.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "HexagonRegisterInfo.h"
     16 #include "Hexagon.h"
     17 #include "HexagonMachineFunctionInfo.h"
     18 #include "HexagonSubtarget.h"
     19 #include "HexagonTargetMachine.h"
     20 #include "llvm/ADT/BitVector.h"
     21 #include "llvm/ADT/STLExtras.h"
     22 #include "llvm/CodeGen/MachineFrameInfo.h"
     23 #include "llvm/CodeGen/MachineFunction.h"
     24 #include "llvm/CodeGen/MachineFunctionPass.h"
     25 #include "llvm/CodeGen/MachineInstrBuilder.h"
     26 #include "llvm/CodeGen/MachineRegisterInfo.h"
     27 #include "llvm/CodeGen/PseudoSourceValue.h"
     28 #include "llvm/CodeGen/RegisterScavenging.h"
     29 #include "llvm/IR/Function.h"
     30 #include "llvm/IR/Type.h"
     31 #include "llvm/MC/MachineLocation.h"
     32 #include "llvm/Support/CommandLine.h"
     33 #include "llvm/Support/Debug.h"
     34 #include "llvm/Support/ErrorHandling.h"
     35 #include "llvm/Support/raw_ostream.h"
     36 #include "llvm/Target/TargetInstrInfo.h"
     37 #include "llvm/Target/TargetMachine.h"
     38 #include "llvm/Target/TargetOptions.h"
     39 
     40 using namespace llvm;
     41 
     42 HexagonRegisterInfo::HexagonRegisterInfo()
     43     : HexagonGenRegisterInfo(Hexagon::R31) {}
     44 
     45 
     46 bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
     47   return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
     48          R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
     49 }
     50 
     51 bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const {
     52   return Hexagon::R16 <= Reg && Reg <= Hexagon::R27;
     53 }
     54 
     55 
     56 const MCPhysReg *
     57 HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF) const {
     58   static const MCPhysReg CallerSavedRegsV4[] = {
     59     Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
     60     Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
     61     Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
     62     Hexagon::R15, 0
     63   };
     64 
     65   auto &HST = static_cast<const HexagonSubtarget&>(MF->getSubtarget());
     66   switch (HST.getHexagonArchVersion()) {
     67   case HexagonSubtarget::V4:
     68   case HexagonSubtarget::V5:
     69   case HexagonSubtarget::V55:
     70   case HexagonSubtarget::V60:
     71     return CallerSavedRegsV4;
     72   }
     73   llvm_unreachable(
     74     "Callee saved registers requested for unknown archtecture version");
     75 }
     76 
     77 
     78 const MCPhysReg *
     79 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
     80   static const MCPhysReg CalleeSavedRegsV3[] = {
     81     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
     82     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
     83     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
     84   };
     85 
     86   switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
     87   case HexagonSubtarget::V4:
     88   case HexagonSubtarget::V5:
     89   case HexagonSubtarget::V55:
     90   case HexagonSubtarget::V60:
     91     return CalleeSavedRegsV3;
     92   }
     93   llvm_unreachable("Callee saved registers requested for unknown architecture "
     94                    "version");
     95 }
     96 
     97 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
     98   const {
     99   BitVector Reserved(getNumRegs());
    100   Reserved.set(HEXAGON_RESERVED_REG_1);
    101   Reserved.set(HEXAGON_RESERVED_REG_2);
    102   Reserved.set(Hexagon::R29);
    103   Reserved.set(Hexagon::R30);
    104   Reserved.set(Hexagon::R31);
    105   Reserved.set(Hexagon::PC);
    106   Reserved.set(Hexagon::D15);
    107   Reserved.set(Hexagon::LC0);
    108   Reserved.set(Hexagon::LC1);
    109   Reserved.set(Hexagon::SA0);
    110   Reserved.set(Hexagon::SA1);
    111   return Reserved;
    112 }
    113 
    114 
    115 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
    116                                               int SPAdj, unsigned FIOp,
    117                                               RegScavenger *RS) const {
    118   //
    119   // Hexagon_TODO: Do we need to enforce this for Hexagon?
    120   assert(SPAdj == 0 && "Unexpected");
    121 
    122   MachineInstr &MI = *II;
    123   MachineBasicBlock &MB = *MI.getParent();
    124   MachineFunction &MF = *MB.getParent();
    125   auto &HST = MF.getSubtarget<HexagonSubtarget>();
    126   auto &HII = *HST.getInstrInfo();
    127   auto &HFI = *HST.getFrameLowering();
    128 
    129   unsigned BP = 0;
    130   int FI = MI.getOperand(FIOp).getIndex();
    131   // Select the base pointer (BP) and calculate the actual offset from BP
    132   // to the beginning of the object at index FI.
    133   int Offset = HFI.getFrameIndexReference(MF, FI, BP);
    134   // Add the offset from the instruction.
    135   int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
    136 
    137   unsigned Opc = MI.getOpcode();
    138   switch (Opc) {
    139     case Hexagon::TFR_FIA:
    140       MI.setDesc(HII.get(Hexagon::A2_addi));
    141       MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
    142       MI.RemoveOperand(FIOp+1);
    143       return;
    144     case Hexagon::TFR_FI:
    145       // Set up the instruction for updating below.
    146       MI.setDesc(HII.get(Hexagon::A2_addi));
    147       break;
    148   }
    149 
    150   if (HII.isValidOffset(Opc, RealOffset)) {
    151     MI.getOperand(FIOp).ChangeToRegister(BP, false);
    152     MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
    153     return;
    154   }
    155 
    156 #ifndef NDEBUG
    157   const Function *F = MF.getFunction();
    158   dbgs() << "In function ";
    159   if (F) dbgs() << F->getName();
    160   else   dbgs() << "<?>";
    161   dbgs() << ", BB#" << MB.getNumber() << "\n" << MI;
    162 #endif
    163   llvm_unreachable("Unhandled instruction");
    164 }
    165 
    166 
    167 unsigned HexagonRegisterInfo::getRARegister() const {
    168   return Hexagon::R31;
    169 }
    170 
    171 
    172 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
    173                                                &MF) const {
    174   const HexagonFrameLowering *TFI = getFrameLowering(MF);
    175   if (TFI->hasFP(MF))
    176     return getFrameRegister();
    177   return getStackRegister();
    178 }
    179 
    180 
    181 unsigned HexagonRegisterInfo::getFrameRegister() const {
    182   return Hexagon::R30;
    183 }
    184 
    185 
    186 unsigned HexagonRegisterInfo::getStackRegister() const {
    187   return Hexagon::R29;
    188 }
    189 
    190 
    191 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
    192       const {
    193   return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
    194 }
    195 
    196 
    197 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
    198   return Hexagon::R6;
    199 }
    200 
    201 
    202 #define GET_REGINFO_TARGET_DESC
    203 #include "HexagonGenRegisterInfo.inc"
    204