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) const { 57 static const MCPhysReg CallerSavedRegsV4[] = { 58 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, 59 Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, 60 Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, 61 Hexagon::R15, 0 62 }; 63 64 switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) { 65 case HexagonSubtarget::V4: 66 case HexagonSubtarget::V5: 67 case HexagonSubtarget::V55: 68 case HexagonSubtarget::V60: 69 return CallerSavedRegsV4; 70 } 71 llvm_unreachable( 72 "Callee saved registers requested for unknown archtecture version"); 73 } 74 75 76 const MCPhysReg * 77 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 78 static const MCPhysReg CalleeSavedRegsV3[] = { 79 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 80 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 81 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 82 }; 83 84 // Functions that contain a call to __builtin_eh_return also save the first 4 85 // parameter registers. 86 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = { 87 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, 88 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 89 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 90 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 91 }; 92 93 bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn(); 94 95 switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) { 96 case HexagonSubtarget::V4: 97 case HexagonSubtarget::V5: 98 case HexagonSubtarget::V55: 99 case HexagonSubtarget::V60: 100 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3; 101 } 102 103 llvm_unreachable("Callee saved registers requested for unknown architecture " 104 "version"); 105 } 106 107 108 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 109 const { 110 BitVector Reserved(getNumRegs()); 111 Reserved.set(Hexagon::R29); 112 Reserved.set(Hexagon::R30); 113 Reserved.set(Hexagon::R31); 114 Reserved.set(Hexagon::PC); 115 Reserved.set(Hexagon::D14); 116 Reserved.set(Hexagon::D15); 117 Reserved.set(Hexagon::LC0); 118 Reserved.set(Hexagon::LC1); 119 Reserved.set(Hexagon::SA0); 120 Reserved.set(Hexagon::SA1); 121 Reserved.set(Hexagon::UGP); 122 Reserved.set(Hexagon::GP); 123 Reserved.set(Hexagon::CS0); 124 Reserved.set(Hexagon::CS1); 125 Reserved.set(Hexagon::CS); 126 return Reserved; 127 } 128 129 130 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 131 int SPAdj, unsigned FIOp, 132 RegScavenger *RS) const { 133 // 134 // Hexagon_TODO: Do we need to enforce this for Hexagon? 135 assert(SPAdj == 0 && "Unexpected"); 136 137 MachineInstr &MI = *II; 138 MachineBasicBlock &MB = *MI.getParent(); 139 MachineFunction &MF = *MB.getParent(); 140 auto &HST = MF.getSubtarget<HexagonSubtarget>(); 141 auto &HII = *HST.getInstrInfo(); 142 auto &HFI = *HST.getFrameLowering(); 143 144 unsigned BP = 0; 145 int FI = MI.getOperand(FIOp).getIndex(); 146 // Select the base pointer (BP) and calculate the actual offset from BP 147 // to the beginning of the object at index FI. 148 int Offset = HFI.getFrameIndexReference(MF, FI, BP); 149 // Add the offset from the instruction. 150 int RealOffset = Offset + MI.getOperand(FIOp+1).getImm(); 151 bool IsKill = false; 152 153 unsigned Opc = MI.getOpcode(); 154 switch (Opc) { 155 case Hexagon::TFR_FIA: 156 MI.setDesc(HII.get(Hexagon::A2_addi)); 157 MI.getOperand(FIOp).ChangeToImmediate(RealOffset); 158 MI.RemoveOperand(FIOp+1); 159 return; 160 case Hexagon::TFR_FI: 161 // Set up the instruction for updating below. 162 MI.setDesc(HII.get(Hexagon::A2_addi)); 163 break; 164 } 165 166 if (!HII.isValidOffset(Opc, RealOffset)) { 167 // If the offset is not valid, calculate the address in a temporary 168 // register and use it with offset 0. 169 auto &MRI = MF.getRegInfo(); 170 unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 171 DebugLoc DL = MI.getDebugLoc(); 172 BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR) 173 .addReg(BP) 174 .addImm(RealOffset); 175 BP = TmpR; 176 RealOffset = 0; 177 IsKill = true; 178 } 179 180 MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill); 181 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset); 182 } 183 184 185 unsigned HexagonRegisterInfo::getRARegister() const { 186 return Hexagon::R31; 187 } 188 189 190 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 191 &MF) const { 192 const HexagonFrameLowering *TFI = getFrameLowering(MF); 193 if (TFI->hasFP(MF)) 194 return getFrameRegister(); 195 return getStackRegister(); 196 } 197 198 199 unsigned HexagonRegisterInfo::getFrameRegister() const { 200 return Hexagon::R30; 201 } 202 203 204 unsigned HexagonRegisterInfo::getStackRegister() const { 205 return Hexagon::R29; 206 } 207 208 209 bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) 210 const { 211 return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF); 212 } 213 214 215 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { 216 return Hexagon::R6; 217 } 218 219 220 #define GET_REGINFO_TARGET_DESC 221 #include "HexagonGenRegisterInfo.inc" 222