1*0b57cec5SDimitry Andric //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains the Hexagon implementation of the TargetRegisterInfo 10*0b57cec5SDimitry Andric // class. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "HexagonRegisterInfo.h" 15*0b57cec5SDimitry Andric #include "Hexagon.h" 16*0b57cec5SDimitry Andric #include "HexagonMachineFunctionInfo.h" 17*0b57cec5SDimitry Andric #include "HexagonSubtarget.h" 18*0b57cec5SDimitry Andric #include "HexagonTargetMachine.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/BitVector.h" 20*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h" 22*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 24*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 25*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 26*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 27*0b57cec5SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h" 28*0b57cec5SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 30*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 31*0b57cec5SDimitry Andric #include "llvm/IR/Type.h" 32*0b57cec5SDimitry Andric #include "llvm/MC/MachineLocation.h" 33*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 34*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 35*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 36*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 37*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric #define GET_REGINFO_TARGET_DESC 40*0b57cec5SDimitry Andric #include "HexagonGenRegisterInfo.inc" 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric using namespace llvm; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode) 45*0b57cec5SDimitry Andric : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/, 46*0b57cec5SDimitry Andric 0/*PC*/, HwMode) {} 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric bool HexagonRegisterInfo::isEHReturnCalleeSaveReg(unsigned R) const { 50*0b57cec5SDimitry Andric return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 || 51*0b57cec5SDimitry Andric R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1; 52*0b57cec5SDimitry Andric } 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric const MCPhysReg * 55*0b57cec5SDimitry Andric HexagonRegisterInfo::getCallerSavedRegs(const MachineFunction *MF, 56*0b57cec5SDimitry Andric const TargetRegisterClass *RC) const { 57*0b57cec5SDimitry Andric using namespace Hexagon; 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric static const MCPhysReg Int32[] = { 60*0b57cec5SDimitry Andric R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0 61*0b57cec5SDimitry Andric }; 62*0b57cec5SDimitry Andric static const MCPhysReg Int64[] = { 63*0b57cec5SDimitry Andric D0, D1, D2, D3, D4, D5, D6, D7, 0 64*0b57cec5SDimitry Andric }; 65*0b57cec5SDimitry Andric static const MCPhysReg Pred[] = { 66*0b57cec5SDimitry Andric P0, P1, P2, P3, 0 67*0b57cec5SDimitry Andric }; 68*0b57cec5SDimitry Andric static const MCPhysReg VecSgl[] = { 69*0b57cec5SDimitry Andric V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, 70*0b57cec5SDimitry Andric V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27, 71*0b57cec5SDimitry Andric V28, V29, V30, V31, 0 72*0b57cec5SDimitry Andric }; 73*0b57cec5SDimitry Andric static const MCPhysReg VecDbl[] = { 74*0b57cec5SDimitry Andric W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0 75*0b57cec5SDimitry Andric }; 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric switch (RC->getID()) { 78*0b57cec5SDimitry Andric case IntRegsRegClassID: 79*0b57cec5SDimitry Andric return Int32; 80*0b57cec5SDimitry Andric case DoubleRegsRegClassID: 81*0b57cec5SDimitry Andric return Int64; 82*0b57cec5SDimitry Andric case PredRegsRegClassID: 83*0b57cec5SDimitry Andric return Pred; 84*0b57cec5SDimitry Andric case HvxVRRegClassID: 85*0b57cec5SDimitry Andric return VecSgl; 86*0b57cec5SDimitry Andric case HvxWRRegClassID: 87*0b57cec5SDimitry Andric return VecDbl; 88*0b57cec5SDimitry Andric default: 89*0b57cec5SDimitry Andric break; 90*0b57cec5SDimitry Andric } 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric static const MCPhysReg Empty[] = { 0 }; 93*0b57cec5SDimitry Andric #ifndef NDEBUG 94*0b57cec5SDimitry Andric dbgs() << "Register class: " << getRegClassName(RC) << "\n"; 95*0b57cec5SDimitry Andric #endif 96*0b57cec5SDimitry Andric llvm_unreachable("Unexpected register class"); 97*0b57cec5SDimitry Andric return Empty; 98*0b57cec5SDimitry Andric } 99*0b57cec5SDimitry Andric 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric const MCPhysReg * 102*0b57cec5SDimitry Andric HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 103*0b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegsV3[] = { 104*0b57cec5SDimitry Andric Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 105*0b57cec5SDimitry Andric Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 106*0b57cec5SDimitry Andric Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 107*0b57cec5SDimitry Andric }; 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric // Functions that contain a call to __builtin_eh_return also save the first 4 110*0b57cec5SDimitry Andric // parameter registers. 111*0b57cec5SDimitry Andric static const MCPhysReg CalleeSavedRegsV3EHReturn[] = { 112*0b57cec5SDimitry Andric Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, 113*0b57cec5SDimitry Andric Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 114*0b57cec5SDimitry Andric Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 115*0b57cec5SDimitry Andric Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 116*0b57cec5SDimitry Andric }; 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric bool HasEHReturn = MF->getInfo<HexagonMachineFunctionInfo>()->hasEHReturn(); 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3; 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric const uint32_t *HexagonRegisterInfo::getCallPreservedMask( 125*0b57cec5SDimitry Andric const MachineFunction &MF, CallingConv::ID) const { 126*0b57cec5SDimitry Andric return HexagonCSR_RegMask; 127*0b57cec5SDimitry Andric } 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 131*0b57cec5SDimitry Andric const { 132*0b57cec5SDimitry Andric BitVector Reserved(getNumRegs()); 133*0b57cec5SDimitry Andric Reserved.set(Hexagon::R29); 134*0b57cec5SDimitry Andric Reserved.set(Hexagon::R30); 135*0b57cec5SDimitry Andric Reserved.set(Hexagon::R31); 136*0b57cec5SDimitry Andric Reserved.set(Hexagon::VTMP); 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric // Guest registers. 139*0b57cec5SDimitry Andric Reserved.set(Hexagon::GELR); // G0 140*0b57cec5SDimitry Andric Reserved.set(Hexagon::GSR); // G1 141*0b57cec5SDimitry Andric Reserved.set(Hexagon::GOSP); // G2 142*0b57cec5SDimitry Andric Reserved.set(Hexagon::G3); // G3 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric // Control registers. 145*0b57cec5SDimitry Andric Reserved.set(Hexagon::SA0); // C0 146*0b57cec5SDimitry Andric Reserved.set(Hexagon::LC0); // C1 147*0b57cec5SDimitry Andric Reserved.set(Hexagon::SA1); // C2 148*0b57cec5SDimitry Andric Reserved.set(Hexagon::LC1); // C3 149*0b57cec5SDimitry Andric Reserved.set(Hexagon::P3_0); // C4 150*0b57cec5SDimitry Andric Reserved.set(Hexagon::USR); // C8 151*0b57cec5SDimitry Andric Reserved.set(Hexagon::PC); // C9 152*0b57cec5SDimitry Andric Reserved.set(Hexagon::UGP); // C10 153*0b57cec5SDimitry Andric Reserved.set(Hexagon::GP); // C11 154*0b57cec5SDimitry Andric Reserved.set(Hexagon::CS0); // C12 155*0b57cec5SDimitry Andric Reserved.set(Hexagon::CS1); // C13 156*0b57cec5SDimitry Andric Reserved.set(Hexagon::UPCYCLELO); // C14 157*0b57cec5SDimitry Andric Reserved.set(Hexagon::UPCYCLEHI); // C15 158*0b57cec5SDimitry Andric Reserved.set(Hexagon::FRAMELIMIT); // C16 159*0b57cec5SDimitry Andric Reserved.set(Hexagon::FRAMEKEY); // C17 160*0b57cec5SDimitry Andric Reserved.set(Hexagon::PKTCOUNTLO); // C18 161*0b57cec5SDimitry Andric Reserved.set(Hexagon::PKTCOUNTHI); // C19 162*0b57cec5SDimitry Andric Reserved.set(Hexagon::UTIMERLO); // C30 163*0b57cec5SDimitry Andric Reserved.set(Hexagon::UTIMERHI); // C31 164*0b57cec5SDimitry Andric // Out of the control registers, only C8 is explicitly defined in 165*0b57cec5SDimitry Andric // HexagonRegisterInfo.td. If others are defined, make sure to add 166*0b57cec5SDimitry Andric // them here as well. 167*0b57cec5SDimitry Andric Reserved.set(Hexagon::C8); 168*0b57cec5SDimitry Andric Reserved.set(Hexagon::USR_OVF); 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric if (MF.getSubtarget<HexagonSubtarget>().hasReservedR19()) 171*0b57cec5SDimitry Andric Reserved.set(Hexagon::R19); 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric for (int x = Reserved.find_first(); x >= 0; x = Reserved.find_next(x)) 174*0b57cec5SDimitry Andric markSuperRegs(Reserved, x); 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andric return Reserved; 177*0b57cec5SDimitry Andric } 178*0b57cec5SDimitry Andric 179*0b57cec5SDimitry Andric 180*0b57cec5SDimitry Andric void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 181*0b57cec5SDimitry Andric int SPAdj, unsigned FIOp, 182*0b57cec5SDimitry Andric RegScavenger *RS) const { 183*0b57cec5SDimitry Andric // 184*0b57cec5SDimitry Andric // Hexagon_TODO: Do we need to enforce this for Hexagon? 185*0b57cec5SDimitry Andric assert(SPAdj == 0 && "Unexpected"); 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric MachineInstr &MI = *II; 188*0b57cec5SDimitry Andric MachineBasicBlock &MB = *MI.getParent(); 189*0b57cec5SDimitry Andric MachineFunction &MF = *MB.getParent(); 190*0b57cec5SDimitry Andric auto &HST = MF.getSubtarget<HexagonSubtarget>(); 191*0b57cec5SDimitry Andric auto &HII = *HST.getInstrInfo(); 192*0b57cec5SDimitry Andric auto &HFI = *HST.getFrameLowering(); 193*0b57cec5SDimitry Andric 194*0b57cec5SDimitry Andric unsigned BP = 0; 195*0b57cec5SDimitry Andric int FI = MI.getOperand(FIOp).getIndex(); 196*0b57cec5SDimitry Andric // Select the base pointer (BP) and calculate the actual offset from BP 197*0b57cec5SDimitry Andric // to the beginning of the object at index FI. 198*0b57cec5SDimitry Andric int Offset = HFI.getFrameIndexReference(MF, FI, BP); 199*0b57cec5SDimitry Andric // Add the offset from the instruction. 200*0b57cec5SDimitry Andric int RealOffset = Offset + MI.getOperand(FIOp+1).getImm(); 201*0b57cec5SDimitry Andric bool IsKill = false; 202*0b57cec5SDimitry Andric 203*0b57cec5SDimitry Andric unsigned Opc = MI.getOpcode(); 204*0b57cec5SDimitry Andric switch (Opc) { 205*0b57cec5SDimitry Andric case Hexagon::PS_fia: 206*0b57cec5SDimitry Andric MI.setDesc(HII.get(Hexagon::A2_addi)); 207*0b57cec5SDimitry Andric MI.getOperand(FIOp).ChangeToImmediate(RealOffset); 208*0b57cec5SDimitry Andric MI.RemoveOperand(FIOp+1); 209*0b57cec5SDimitry Andric return; 210*0b57cec5SDimitry Andric case Hexagon::PS_fi: 211*0b57cec5SDimitry Andric // Set up the instruction for updating below. 212*0b57cec5SDimitry Andric MI.setDesc(HII.get(Hexagon::A2_addi)); 213*0b57cec5SDimitry Andric break; 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric if (!HII.isValidOffset(Opc, RealOffset, this)) { 217*0b57cec5SDimitry Andric // If the offset is not valid, calculate the address in a temporary 218*0b57cec5SDimitry Andric // register and use it with offset 0. 219*0b57cec5SDimitry Andric auto &MRI = MF.getRegInfo(); 220*0b57cec5SDimitry Andric unsigned TmpR = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass); 221*0b57cec5SDimitry Andric const DebugLoc &DL = MI.getDebugLoc(); 222*0b57cec5SDimitry Andric BuildMI(MB, II, DL, HII.get(Hexagon::A2_addi), TmpR) 223*0b57cec5SDimitry Andric .addReg(BP) 224*0b57cec5SDimitry Andric .addImm(RealOffset); 225*0b57cec5SDimitry Andric BP = TmpR; 226*0b57cec5SDimitry Andric RealOffset = 0; 227*0b57cec5SDimitry Andric IsKill = true; 228*0b57cec5SDimitry Andric } 229*0b57cec5SDimitry Andric 230*0b57cec5SDimitry Andric MI.getOperand(FIOp).ChangeToRegister(BP, false, false, IsKill); 231*0b57cec5SDimitry Andric MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset); 232*0b57cec5SDimitry Andric } 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric bool HexagonRegisterInfo::shouldCoalesce(MachineInstr *MI, 236*0b57cec5SDimitry Andric const TargetRegisterClass *SrcRC, unsigned SubReg, 237*0b57cec5SDimitry Andric const TargetRegisterClass *DstRC, unsigned DstSubReg, 238*0b57cec5SDimitry Andric const TargetRegisterClass *NewRC, LiveIntervals &LIS) const { 239*0b57cec5SDimitry Andric // Coalescing will extend the live interval of the destination register. 240*0b57cec5SDimitry Andric // If the destination register is a vector pair, avoid introducing function 241*0b57cec5SDimitry Andric // calls into the interval, since it could result in a spilling of a pair 242*0b57cec5SDimitry Andric // instead of a single vector. 243*0b57cec5SDimitry Andric MachineFunction &MF = *MI->getParent()->getParent(); 244*0b57cec5SDimitry Andric const HexagonSubtarget &HST = MF.getSubtarget<HexagonSubtarget>(); 245*0b57cec5SDimitry Andric if (!HST.useHVXOps() || NewRC->getID() != Hexagon::HvxWRRegClass.getID()) 246*0b57cec5SDimitry Andric return true; 247*0b57cec5SDimitry Andric bool SmallSrc = SrcRC->getID() == Hexagon::HvxVRRegClass.getID(); 248*0b57cec5SDimitry Andric bool SmallDst = DstRC->getID() == Hexagon::HvxVRRegClass.getID(); 249*0b57cec5SDimitry Andric if (!SmallSrc && !SmallDst) 250*0b57cec5SDimitry Andric return true; 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric unsigned DstReg = MI->getOperand(0).getReg(); 253*0b57cec5SDimitry Andric unsigned SrcReg = MI->getOperand(1).getReg(); 254*0b57cec5SDimitry Andric const SlotIndexes &Indexes = *LIS.getSlotIndexes(); 255*0b57cec5SDimitry Andric auto HasCall = [&Indexes] (const LiveInterval::Segment &S) { 256*0b57cec5SDimitry Andric for (SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex(); 257*0b57cec5SDimitry Andric I != E; I = I.getNextIndex()) { 258*0b57cec5SDimitry Andric if (const MachineInstr *MI = Indexes.getInstructionFromIndex(I)) 259*0b57cec5SDimitry Andric if (MI->isCall()) 260*0b57cec5SDimitry Andric return true; 261*0b57cec5SDimitry Andric } 262*0b57cec5SDimitry Andric return false; 263*0b57cec5SDimitry Andric }; 264*0b57cec5SDimitry Andric 265*0b57cec5SDimitry Andric if (SmallSrc == SmallDst) { 266*0b57cec5SDimitry Andric // Both must be true, because the case for both being false was 267*0b57cec5SDimitry Andric // checked earlier. Both registers will be coalesced into a register 268*0b57cec5SDimitry Andric // of a wider class (HvxWR), and we don't want its live range to 269*0b57cec5SDimitry Andric // span over calls. 270*0b57cec5SDimitry Andric return !any_of(LIS.getInterval(DstReg), HasCall) && 271*0b57cec5SDimitry Andric !any_of(LIS.getInterval(SrcReg), HasCall); 272*0b57cec5SDimitry Andric } 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric // If one register is large (HvxWR) and the other is small (HvxVR), then 275*0b57cec5SDimitry Andric // coalescing is ok if the large is already live across a function call, 276*0b57cec5SDimitry Andric // or if the small one is not. 277*0b57cec5SDimitry Andric unsigned SmallReg = SmallSrc ? SrcReg : DstReg; 278*0b57cec5SDimitry Andric unsigned LargeReg = SmallSrc ? DstReg : SrcReg; 279*0b57cec5SDimitry Andric return any_of(LIS.getInterval(LargeReg), HasCall) || 280*0b57cec5SDimitry Andric !any_of(LIS.getInterval(SmallReg), HasCall); 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric 284*0b57cec5SDimitry Andric unsigned HexagonRegisterInfo::getRARegister() const { 285*0b57cec5SDimitry Andric return Hexagon::R31; 286*0b57cec5SDimitry Andric } 287*0b57cec5SDimitry Andric 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric Register HexagonRegisterInfo::getFrameRegister(const MachineFunction 290*0b57cec5SDimitry Andric &MF) const { 291*0b57cec5SDimitry Andric const HexagonFrameLowering *TFI = getFrameLowering(MF); 292*0b57cec5SDimitry Andric if (TFI->hasFP(MF)) 293*0b57cec5SDimitry Andric return getFrameRegister(); 294*0b57cec5SDimitry Andric return getStackRegister(); 295*0b57cec5SDimitry Andric } 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric unsigned HexagonRegisterInfo::getFrameRegister() const { 299*0b57cec5SDimitry Andric return Hexagon::R30; 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric unsigned HexagonRegisterInfo::getStackRegister() const { 304*0b57cec5SDimitry Andric return Hexagon::R29; 305*0b57cec5SDimitry Andric } 306*0b57cec5SDimitry Andric 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric unsigned HexagonRegisterInfo::getHexagonSubRegIndex( 309*0b57cec5SDimitry Andric const TargetRegisterClass &RC, unsigned GenIdx) const { 310*0b57cec5SDimitry Andric assert(GenIdx == Hexagon::ps_sub_lo || GenIdx == Hexagon::ps_sub_hi); 311*0b57cec5SDimitry Andric 312*0b57cec5SDimitry Andric static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi }; 313*0b57cec5SDimitry Andric static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi }; 314*0b57cec5SDimitry Andric static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi }; 315*0b57cec5SDimitry Andric 316*0b57cec5SDimitry Andric switch (RC.getID()) { 317*0b57cec5SDimitry Andric case Hexagon::CtrRegs64RegClassID: 318*0b57cec5SDimitry Andric case Hexagon::DoubleRegsRegClassID: 319*0b57cec5SDimitry Andric return ISub[GenIdx]; 320*0b57cec5SDimitry Andric case Hexagon::HvxWRRegClassID: 321*0b57cec5SDimitry Andric return VSub[GenIdx]; 322*0b57cec5SDimitry Andric case Hexagon::HvxVQRRegClassID: 323*0b57cec5SDimitry Andric return WSub[GenIdx]; 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses()) 327*0b57cec5SDimitry Andric return getHexagonSubRegIndex(*SuperRC, GenIdx); 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric llvm_unreachable("Invalid register class"); 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric bool HexagonRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) 333*0b57cec5SDimitry Andric const { 334*0b57cec5SDimitry Andric return MF.getSubtarget<HexagonSubtarget>().getFrameLowering()->hasFP(MF); 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric const TargetRegisterClass * 338*0b57cec5SDimitry Andric HexagonRegisterInfo::getPointerRegClass(const MachineFunction &MF, 339*0b57cec5SDimitry Andric unsigned Kind) const { 340*0b57cec5SDimitry Andric return &Hexagon::IntRegsRegClass; 341*0b57cec5SDimitry Andric } 342*0b57cec5SDimitry Andric 343*0b57cec5SDimitry Andric unsigned HexagonRegisterInfo::getFirstCallerSavedNonParamReg() const { 344*0b57cec5SDimitry Andric return Hexagon::R6; 345*0b57cec5SDimitry Andric } 346*0b57cec5SDimitry Andric 347