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 "HexagonSubtarget.h" 18 #include "HexagonTargetMachine.h" 19 #include "HexagonMachineFunctionInfo.h" 20 #include "llvm/Function.h" 21 #include "llvm/Type.h" 22 #include "llvm/ADT/BitVector.h" 23 #include "llvm/ADT/STLExtras.h" 24 #include "llvm/CodeGen/MachineInstrBuilder.h" 25 #include "llvm/CodeGen/MachineFunction.h" 26 #include "llvm/CodeGen/MachineFunctionPass.h" 27 #include "llvm/CodeGen/MachineFrameInfo.h" 28 #include "llvm/CodeGen/MachineRegisterInfo.h" 29 #include "llvm/CodeGen/RegisterScavenging.h" 30 #include "llvm/MC/MachineLocation.h" 31 #include "llvm/Target/TargetInstrInfo.h" 32 #include "llvm/Target/TargetMachine.h" 33 #include "llvm/Target/TargetOptions.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/ErrorHandling.h" 36 37 using namespace llvm; 38 39 40 HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st, 41 const HexagonInstrInfo &tii) 42 : HexagonGenRegisterInfo(Hexagon::R31), 43 Subtarget(st), 44 TII(tii) { 45 } 46 47 const uint16_t* HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction 48 *MF) 49 const { 50 static const uint16_t CalleeSavedRegsV2[] = { 51 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 52 }; 53 static const uint16_t CalleeSavedRegsV3[] = { 54 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 55 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 56 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 57 }; 58 59 switch(Subtarget.getHexagonArchVersion()) { 60 case HexagonSubtarget::V1: 61 break; 62 case HexagonSubtarget::V2: 63 return CalleeSavedRegsV2; 64 case HexagonSubtarget::V3: 65 case HexagonSubtarget::V4: 66 case HexagonSubtarget::V5: 67 return CalleeSavedRegsV3; 68 } 69 llvm_unreachable("Callee saved registers requested for unknown architecture " 70 "version"); 71 } 72 73 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 74 const { 75 BitVector Reserved(getNumRegs()); 76 Reserved.set(HEXAGON_RESERVED_REG_1); 77 Reserved.set(HEXAGON_RESERVED_REG_2); 78 Reserved.set(Hexagon::R29); 79 Reserved.set(Hexagon::R30); 80 Reserved.set(Hexagon::R31); 81 Reserved.set(Hexagon::D14); 82 Reserved.set(Hexagon::D15); 83 Reserved.set(Hexagon::LC0); 84 Reserved.set(Hexagon::LC1); 85 Reserved.set(Hexagon::SA0); 86 Reserved.set(Hexagon::SA1); 87 return Reserved; 88 } 89 90 91 const TargetRegisterClass* const* 92 HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 93 static const TargetRegisterClass * const CalleeSavedRegClassesV2[] = { 94 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 95 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 96 }; 97 static const TargetRegisterClass * const CalleeSavedRegClassesV3[] = { 98 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 99 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 100 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 101 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 102 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 103 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 104 }; 105 106 switch(Subtarget.getHexagonArchVersion()) { 107 case HexagonSubtarget::V1: 108 break; 109 case HexagonSubtarget::V2: 110 return CalleeSavedRegClassesV2; 111 case HexagonSubtarget::V3: 112 case HexagonSubtarget::V4: 113 case HexagonSubtarget::V5: 114 return CalleeSavedRegClassesV3; 115 } 116 llvm_unreachable("Callee saved register classes requested for unknown " 117 "architecture version"); 118 } 119 120 void HexagonRegisterInfo:: 121 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 122 MachineBasicBlock::iterator I) const { 123 MachineInstr &MI = *I; 124 125 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { 126 // Hexagon_TODO: add code 127 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { 128 // Hexagon_TODO: add code 129 } else { 130 llvm_unreachable("Cannot handle this call frame pseudo instruction"); 131 } 132 MBB.erase(I); 133 } 134 135 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 136 int SPAdj, RegScavenger *RS) const { 137 138 // 139 // Hexagon_TODO: Do we need to enforce this for Hexagon? 140 assert(SPAdj == 0 && "Unexpected"); 141 142 143 unsigned i = 0; 144 MachineInstr &MI = *II; 145 while (!MI.getOperand(i).isFI()) { 146 ++i; 147 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 148 } 149 150 int FrameIndex = MI.getOperand(i).getIndex(); 151 152 // Addressable stack objects are accessed using neg. offsets from %fp. 153 MachineFunction &MF = *MI.getParent()->getParent(); 154 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 155 MachineFrameInfo &MFI = *MF.getFrameInfo(); 156 157 unsigned FrameReg = getFrameRegister(MF); 158 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 159 if (!TFI->hasFP(MF)) { 160 // We will not reserve space on the stack for the lr and fp registers. 161 Offset -= 2 * Hexagon_WordSize; 162 } 163 164 const unsigned FrameSize = MFI.getStackSize(); 165 166 if (!MFI.hasVarSizedObjects() && 167 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset)) && 168 !TII.isSpillPredRegOp(&MI)) { 169 // Replace frame index with a stack pointer reference. 170 MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, true); 171 MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); 172 } else { 173 // Replace frame index with a frame pointer reference. 174 if (!TII.isValidOffset(MI.getOpcode(), Offset)) { 175 176 // If the offset overflows, then correct it. 177 // 178 // For loads, we do not need a reserved register 179 // r0 = memw(r30 + #10000) to: 180 // 181 // r0 = add(r30, #10000) 182 // r0 = memw(r0) 183 if ( (MI.getOpcode() == Hexagon::LDriw) || 184 (MI.getOpcode() == Hexagon::LDrid) || 185 (MI.getOpcode() == Hexagon::LDrih) || 186 (MI.getOpcode() == Hexagon::LDriuh) || 187 (MI.getOpcode() == Hexagon::LDrib) || 188 (MI.getOpcode() == Hexagon::LDriub) || 189 (MI.getOpcode() == Hexagon::LDriw_f) || 190 (MI.getOpcode() == Hexagon::LDrid_f)) { 191 unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ? 192 getSubReg(MI.getOperand(0).getReg(), Hexagon::subreg_loreg) : 193 MI.getOperand(0).getReg(); 194 195 // Check if offset can fit in addi. 196 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 197 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 198 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 199 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 200 TII.get(Hexagon::ADD_rr), 201 dstReg).addReg(FrameReg).addReg(dstReg); 202 } else { 203 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 204 TII.get(Hexagon::ADD_ri), 205 dstReg).addReg(FrameReg).addImm(Offset); 206 } 207 208 MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); 209 MI.getOperand(i+1).ChangeToImmediate(0); 210 } else if ((MI.getOpcode() == Hexagon::STriw_indexed) || 211 (MI.getOpcode() == Hexagon::STriw) || 212 (MI.getOpcode() == Hexagon::STrid) || 213 (MI.getOpcode() == Hexagon::STrih) || 214 (MI.getOpcode() == Hexagon::STrib) || 215 (MI.getOpcode() == Hexagon::STrid_f) || 216 (MI.getOpcode() == Hexagon::STriw_f)) { 217 // For stores, we need a reserved register. Change 218 // memw(r30 + #10000) = r0 to: 219 // 220 // rs = add(r30, #10000); 221 // memw(rs) = r0 222 unsigned resReg = HEXAGON_RESERVED_REG_1; 223 224 // Check if offset can fit in addi. 225 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 226 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 227 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 228 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 229 TII.get(Hexagon::ADD_rr), 230 resReg).addReg(FrameReg).addReg(resReg); 231 } else { 232 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 233 TII.get(Hexagon::ADD_ri), 234 resReg).addReg(FrameReg).addImm(Offset); 235 } 236 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 237 MI.getOperand(i+1).ChangeToImmediate(0); 238 } else if (TII.isMemOp(&MI)) { 239 unsigned resReg = HEXAGON_RESERVED_REG_1; 240 if (!MFI.hasVarSizedObjects() && 241 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) { 242 MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, 243 true); 244 MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); 245 } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 246 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 247 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 248 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 249 TII.get(Hexagon::ADD_rr), 250 resReg).addReg(FrameReg).addReg(resReg); 251 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 252 MI.getOperand(i+1).ChangeToImmediate(0); 253 } else { 254 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 255 TII.get(Hexagon::ADD_ri), 256 resReg).addReg(FrameReg).addImm(Offset); 257 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 258 MI.getOperand(i+1).ChangeToImmediate(0); 259 } 260 } else { 261 unsigned dstReg = MI.getOperand(0).getReg(); 262 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 263 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 264 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 265 TII.get(Hexagon::ADD_rr), 266 dstReg).addReg(FrameReg).addReg(dstReg); 267 // Can we delete MI??? r2 = add (r2, #0). 268 MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); 269 MI.getOperand(i+1).ChangeToImmediate(0); 270 } 271 } else { 272 // If the offset is small enough to fit in the immediate field, directly 273 // encode it. 274 MI.getOperand(i).ChangeToRegister(FrameReg, false); 275 MI.getOperand(i+1).ChangeToImmediate(Offset); 276 } 277 } 278 279 } 280 281 unsigned HexagonRegisterInfo::getRARegister() const { 282 return Hexagon::R31; 283 } 284 285 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 286 &MF) const { 287 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 288 if (TFI->hasFP(MF)) { 289 return Hexagon::R30; 290 } 291 292 return Hexagon::R29; 293 } 294 295 unsigned HexagonRegisterInfo::getFrameRegister() const { 296 return Hexagon::R30; 297 } 298 299 unsigned HexagonRegisterInfo::getStackRegister() const { 300 return Hexagon::R29; 301 } 302 303 void HexagonRegisterInfo::getInitialFrameState(std::vector<MachineMove> 304 &Moves) const 305 { 306 // VirtualFP = (R30 + #0). 307 unsigned FPReg = getFrameRegister(); 308 MachineLocation Dst(MachineLocation::VirtualFP); 309 MachineLocation Src(FPReg, 0); 310 Moves.push_back(MachineMove(0, Dst, Src)); 311 } 312 313 // Get the weight in units of pressure for this register class. 314 const RegClassWeight & 315 HexagonRegisterInfo::getRegClassWeight(const TargetRegisterClass *RC) const { 316 // Each TargetRegisterClass has a per register weight, and weight 317 // limit which must be less than the limits of its pressure sets. 318 static const RegClassWeight RCWeightTable[] = { 319 {1, 32}, // IntRegs 320 {1, 8}, // CRRegs 321 {1, 4}, // PredRegs 322 {2, 16}, // DoubleRegs 323 {0, 0} }; 324 return RCWeightTable[RC->getID()]; 325 } 326 327 /// Get the number of dimensions of register pressure. 328 unsigned HexagonRegisterInfo::getNumRegPressureSets() const { 329 return 4; 330 } 331 332 /// Get the name of this register unit pressure set. 333 const char *HexagonRegisterInfo::getRegPressureSetName(unsigned Idx) const { 334 static const char *const RegPressureSetName[] = { 335 "IntRegsRegSet", 336 "CRRegsRegSet", 337 "PredRegsRegSet", 338 "DoubleRegsRegSet" 339 }; 340 assert((Idx < 4) && "Index out of bounds"); 341 return RegPressureSetName[Idx]; 342 } 343 344 /// Get the register unit pressure limit for this dimension. 345 /// This limit must be adjusted dynamically for reserved registers. 346 unsigned HexagonRegisterInfo::getRegPressureSetLimit(unsigned Idx) const { 347 static const int RegPressureLimit [] = { 16, 4, 2, 8 }; 348 assert((Idx < 4) && "Index out of bounds"); 349 return RegPressureLimit[Idx]; 350 } 351 352 const int* 353 HexagonRegisterInfo::getRegClassPressureSets(const TargetRegisterClass *RC) 354 const { 355 static const int RCSetsTable[] = { 356 0, -1, // IntRegs 357 1, -1, // CRRegs 358 2, -1, // PredRegs 359 0, -1, // DoubleRegs 360 -1 }; 361 static const unsigned RCSetStartTable[] = { 0, 2, 4, 6, 0 }; 362 unsigned SetListStart = RCSetStartTable[RC->getID()]; 363 return &RCSetsTable[SetListStart]; 364 } 365 unsigned HexagonRegisterInfo::getEHExceptionRegister() const { 366 llvm_unreachable("What is the exception register"); 367 } 368 369 unsigned HexagonRegisterInfo::getEHHandlerRegister() const { 370 llvm_unreachable("What is the exception handler register"); 371 } 372 373 #define GET_REGINFO_TARGET_DESC 374 #include "HexagonGenRegisterInfo.inc" 375