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/Debug.h"
     33 #include "llvm/Support/ErrorHandling.h"
     34 #include "llvm/Support/raw_ostream.h"
     35 #include "llvm/Target/TargetInstrInfo.h"
     36 #include "llvm/Target/TargetMachine.h"
     37 #include "llvm/Target/TargetOptions.h"
     38 
     39 using namespace llvm;
     40 
     41 HexagonRegisterInfo::HexagonRegisterInfo()
     42     : HexagonGenRegisterInfo(Hexagon::R31) {}
     43 
     44 
     45 bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const {
     46   return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
     47          R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
     48 }
     49 
     50 bool HexagonRegisterInfo::isCalleeSaveReg(unsigned Reg) const {
     51   return Hexagon::R16 <= Reg && Reg <= Hexagon::R27;
     52 }
     53 
     54 
     55 const MCPhysReg *
     56 HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF,
     57       const TargetRegisterClass *RC) const {
     58   using namespace Hexagon;
     59 
     60   static const MCPhysReg Int32[] = {
     61     R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
     62   };
     63   static const MCPhysReg Int64[] = {
     64     D0, D1, D2, D3, D4, D5, D6, D7, 0
     65   };
     66   static const MCPhysReg Pred[] = {
     67     P0, P1, P2, P3, 0
     68   };
     69   static const MCPhysReg VecSgl[] = {
     70      V0,  V1,  V2,  V3,  V4,  V5,  V6,  V7,  V8,  V9, V10, V11, V12, V13,
     71     V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
     72     V28, V29, V30, V31,   0
     73   };
     74   static const MCPhysReg VecDbl[] = {
     75     W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
     76   };
     77 
     78   switch (RC->getID()) {
     79     case IntRegsRegClassID:
     80       return Int32;
     81     case DoubleRegsRegClassID:
     82       return Int64;
     83     case PredRegsRegClassID:
     84       return Pred;
     85     case VectorRegsRegClassID:
     86     case VectorRegs128BRegClassID:
     87       return VecSgl;
     88     case VecDblRegsRegClassID:
     89     case VecDblRegs128BRegClassID:
     90       return VecDbl;
     91     default:
     92       break;
     93   }
     94 
     95   static const MCPhysReg Empty[] = { 0 };
     96 #ifndef NDEBUG
     97   dbgs() << "Register class: " << getRegClassName(RC) << "\n";
     98 #endif
     99   llvm_unreachable("Unexpected register class");
    100   return Empty;
    101 }
    102 
    103 
    104 const MCPhysReg *
    105 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
    106   static const MCPhysReg CalleeSavedRegsV3[] = {
    107     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
    108     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
    109     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
    110   };
    111 
    112   // Functions that contain a call to __builtin_eh_return also save the first 4
    113   // parameter registers.
    114   static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
    115     Hexagon::R0,    Hexagon::R1,    Hexagon::R2,    Hexagon::R3,
    116     Hexagon::R16,   Hexagon::R17,   Hexagon::R18,   Hexagon::R19,
    117     Hexagon::R20,   Hexagon::R21,   Hexagon::R22,   Hexagon::R23,
    118     Hexagon::R24,   Hexagon::R25,   Hexagon::R26,   Hexagon::R27, 0
    119   };
    120 
    121   bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn();
    122 
    123   switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) {
    124   case HexagonSubtarget::V4:
    125   case HexagonSubtarget::V5:
    126   case HexagonSubtarget::V55:
    127   case HexagonSubtarget::V60:
    128     return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
    129   }
    130 
    131   llvm_unreachable("Callee saved registers requested for unknown architecture "
    132                    "version");
    133 }
    134 
    135 
    136 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF)
    137   const {
    138   BitVector Reserved(getNumRegs());
    139   Reserved.set(Hexagon::R29);
    140   Reserved.set(Hexagon::R30);
    141   Reserved.set(Hexagon::R31);
    142   Reserved.set(Hexagon::PC);
    143   Reserved.set(Hexagon::D14);
    144   Reserved.set(Hexagon::D15);
    145   Reserved.set(Hexagon::LC0);
    146   Reserved.set(Hexagon::LC1);
    147   Reserved.set(Hexagon::SA0);
    148   Reserved.set(Hexagon::SA1);
    149   Reserved.set(Hexagon::UGP);
    150   Reserved.set(Hexagon::GP);
    151   Reserved.set(Hexagon::CS0);
    152   Reserved.set(Hexagon::CS1);
    153   Reserved.set(Hexagon::CS);
    154   return Reserved;
    155 }
    156 
    157 
    158 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
    159                                               int SPAdj, unsigned FIOp,
    160                                               RegScavenger *RS) const {
    161   //
    162   // Hexagon_TODO: Do we need to enforce this for Hexagon?
    163   assert(SPAdj == 0 && "Unexpected");
    164 
    165   MachineInstr &MI = *II;
    166   MachineBasicBlock &MB = *MI.getParent();
    167   MachineFunction &MF = *MB.getParent();
    168   auto &HST = MF.getSubtarget<HexagonSubtarget>();
    169   auto &HII = *HST.getInstrInfo();
    170   auto &HFI = *HST.getFrameLowering();
    171 
    172   unsigned BP = 0;
    173   int FI = MI.getOperand(FIOp).getIndex();
    174   // Select the base pointer (BP) and calculate the actual offset from BP
    175   // to the beginning of the object at index FI.
    176   int Offset = HFI.getFrameIndexReference(MF, FI, BP);
    177   // Add the offset from the instruction.
    178   int RealOffset = Offset + MI.getOperand(FIOp+1).getImm();
    179   bool IsKill = false;
    180 
    181   unsigned Opc = MI.getOpcode();
    182   switch (Opc) {
    183     case Hexagon::TFR_FIA:
    184       MI.setDesc(HII.get(Hexagon::A2_addi));
    185       MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
    186       MI.RemoveOperand(FIOp+1);
    187       return;
    188     case Hexagon::TFR_FI:
    189       // Set up the instruction for updating below.
    190       MI.setDesc(HII.get(Hexagon::A2_addi));
    191       break;
    192   }
    193 
    194   if (!HII.isValidOffset(Opc, RealOffset)) {
    195     // If the offset is not valid, calculate the address in a temporary
    196     // register and use it with offset 0.
    197     auto &MRI = MF.getRegInfo();
    198     unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
    199     const DebugLoc &DL = MI.getDebugLoc();
    200     BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR)
    201       .addReg(BP)
    202       .addImm(RealOffset);
    203     BP = TmpR;
    204     RealOffset = 0;
    205     IsKill = true;
    206   }
    207 
    208   MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill);
    209   MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
    210 }
    211 
    212 
    213 unsigned HexagonRegisterInfo::getRARegister() const {
    214   return Hexagon::R31;
    215 }
    216 
    217 
    218 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction
    219                                                &MF) const {
    220   const HexagonFrameLowering *TFI = getFrameLowering(MF);
    221   if (TFI->hasFP(MF))
    222     return getFrameRegister();
    223   return getStackRegister();
    224 }
    225 
    226 
    227 unsigned HexagonRegisterInfo::getFrameRegister() const {
    228   return Hexagon::R30;
    229 }
    230 
    231 
    232 unsigned HexagonRegisterInfo::getStackRegister() const {
    233   return Hexagon::R29;
    234 }
    235 
    236 
    237 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF)
    238       const {
    239   return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF);
    240 }
    241 
    242 
    243 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const {
    244   return Hexagon::R6;
    245 }
    246 
    247 
    248 #define GET_REGINFO_TARGET_DESC
    249 #include "HexagonGenRegisterInfo.inc"
    250