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 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 switch (MF->getSubtarget<HexagonSubtarget>().getHexagonArchVersion()) { 85 case HexagonSubtarget::V4: 86 case HexagonSubtarget::V5: 87 return CalleeSavedRegsV3; 88 } 89 llvm_unreachable("Callee saved registers requested for unknown architecture " 90 "version"); 91 } 92 93 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 94 const { 95 BitVector Reserved(getNumRegs()); 96 Reserved.set(HEXAGON_RESERVED_REG_1); 97 Reserved.set(HEXAGON_RESERVED_REG_2); 98 Reserved.set(Hexagon::R29); 99 Reserved.set(Hexagon::R30); 100 Reserved.set(Hexagon::R31); 101 Reserved.set(Hexagon::D14); 102 Reserved.set(Hexagon::D15); 103 Reserved.set(Hexagon::LC0); 104 Reserved.set(Hexagon::LC1); 105 Reserved.set(Hexagon::SA0); 106 Reserved.set(Hexagon::SA1); 107 return Reserved; 108 } 109 110 111 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 112 int SPAdj, unsigned FIOp, 113 RegScavenger *RS) const { 114 // 115 // Hexagon_TODO: Do we need to enforce this for Hexagon? 116 assert(SPAdj == 0 && "Unexpected"); 117 118 MachineInstr &MI = *II; 119 120 MachineBasicBlock &MB = *MI.getParent(); 121 MachineFunction &MF = *MB.getParent(); 122 MachineFrameInfo &MFI = *MF.getFrameInfo(); 123 auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget()); 124 auto &HII = *HST.getInstrInfo(); 125 auto &HFI = *HST.getFrameLowering(); 126 127 int FI = MI.getOperand(FIOp).getIndex(); 128 int Offset = MFI.getObjectOffset(FI) + MI.getOperand(FIOp+1).getImm(); 129 bool HasAlloca = MFI.hasVarSizedObjects(); 130 bool HasAlign = needsStackRealignment(MF); 131 132 // XXX: Fixed objects cannot be accessed through SP if there are aligned 133 // objects in the local frame, or if there are dynamically allocated objects. 134 // In such cases, there has to be FP available. 135 if (!HFI.hasFP(MF)) { 136 assert(!HasAlloca && !HasAlign && "This function must have frame pointer"); 137 // We will not reserve space on the stack for the lr and fp registers. 138 Offset -= 8; 139 } 140 141 unsigned SP = getStackRegister(), FP = getFrameRegister(); 142 unsigned AP = 0; 143 if (MachineInstr *AI = HFI.getAlignaInstr(MF)) 144 AP = AI->getOperand(0).getReg(); 145 unsigned FrameSize = MFI.getStackSize(); 146 147 // Special handling of dbg_value instructions and INLINEASM. 148 if (MI.isDebugValue() || MI.isInlineAsm()) { 149 MI.getOperand(FIOp).ChangeToRegister(SP, false /*isDef*/); 150 MI.getOperand(FIOp+1).ChangeToImmediate(Offset+FrameSize); 151 return; 152 } 153 154 bool UseFP = false, UseAP = false; // Default: use SP. 155 if (MFI.isFixedObjectIndex(FI) || MFI.isObjectPreAllocated(FI)) { 156 UseFP = HasAlloca || HasAlign; 157 } else { 158 if (HasAlloca) { 159 if (HasAlign) 160 UseAP = true; 161 else 162 UseFP = true; 163 } 164 } 165 166 unsigned Opc = MI.getOpcode(); 167 bool ValidSP = HII.isValidOffset(Opc, FrameSize+Offset); 168 bool ValidFP = HII.isValidOffset(Opc, Offset); 169 170 // Calculate the actual offset in the instruction. 171 int64_t RealOffset = Offset; 172 if (!UseFP && !UseAP) 173 RealOffset = FrameSize+Offset; 174 175 switch (Opc) { 176 case Hexagon::TFR_FIA: 177 MI.setDesc(HII.get(Hexagon::A2_addi)); 178 MI.getOperand(FIOp).ChangeToImmediate(RealOffset); 179 MI.RemoveOperand(FIOp+1); 180 return; 181 case Hexagon::TFR_FI: 182 // Set up the instruction for updating below. 183 MI.setDesc(HII.get(Hexagon::A2_addi)); 184 break; 185 } 186 187 unsigned BP = 0; 188 bool Valid = false; 189 if (UseFP) { 190 BP = FP; 191 Valid = ValidFP; 192 } else if (UseAP) { 193 BP = AP; 194 Valid = ValidFP; 195 } else { 196 BP = SP; 197 Valid = ValidSP; 198 } 199 200 if (Valid) { 201 MI.getOperand(FIOp).ChangeToRegister(BP, false); 202 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset); 203 return; 204 } 205 206 #ifndef NDEBUG 207 const Function *F = MF.getFunction(); 208 dbgs() << "In function "; 209 if (F) dbgs() << F->getName(); 210 else dbgs() << "<?>"; 211 dbgs() << ", BB#" << MB.getNumber() << "\n" << MI; 212 #endif 213 llvm_unreachable("Unhandled instruction"); 214 } 215 216 217 unsigned HexagonRegisterInfo::getRARegister() const { 218 return Hexagon::R31; 219 } 220 221 222 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 223 &MF) const { 224 const HexagonFrameLowering *TFI = getFrameLowering(MF); 225 if (TFI->hasFP(MF)) 226 return Hexagon::R30; 227 return Hexagon::R29; 228 } 229 230 231 unsigned HexagonRegisterInfo::getFrameRegister() const { 232 return Hexagon::R30; 233 } 234 235 236 unsigned HexagonRegisterInfo::getStackRegister() const { 237 return Hexagon::R29; 238 } 239 240 241 bool 242 HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 243 const HexagonFrameLowering *TFI = getFrameLowering(MF); 244 return TFI->hasFP(MF); 245 } 246 247 248 bool 249 HexagonRegisterInfo::needsStackRealignment(const MachineFunction &MF) const { 250 const MachineFrameInfo *MFI = MF.getFrameInfo(); 251 return MFI->getMaxAlignment() > 8; 252 } 253 254 255 unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { 256 return Hexagon::R6; 257 } 258 259 260 #define GET_REGINFO_TARGET_DESC 261 #include "HexagonGenRegisterInfo.inc" 262