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/RegisterScavenging.h" 28#include "llvm/IR/Function.h" 29#include "llvm/IR/Type.h" 30#include "llvm/MC/MachineLocation.h" 31#include "llvm/Support/CommandLine.h" 32#include "llvm/Support/ErrorHandling.h" 33#include "llvm/Target/TargetInstrInfo.h" 34#include "llvm/Target/TargetMachine.h" 35#include "llvm/Target/TargetOptions.h" 36 37using namespace llvm; 38 39 40HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st, 41 const HexagonInstrInfo &tii) 42 : HexagonGenRegisterInfo(Hexagon::R31), 43 Subtarget(st), 44 TII(tii) { 45} 46 47const 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 73BitVector 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 91const TargetRegisterClass* const* 92HexagonRegisterInfo::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 120void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 121 int SPAdj, unsigned FIOperandNum, 122 RegScavenger *RS) const { 123 // 124 // Hexagon_TODO: Do we need to enforce this for Hexagon? 125 assert(SPAdj == 0 && "Unexpected"); 126 127 MachineInstr &MI = *II; 128 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 129 130 // Addressable stack objects are accessed using neg. offsets from %fp. 131 MachineFunction &MF = *MI.getParent()->getParent(); 132 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 133 MachineFrameInfo &MFI = *MF.getFrameInfo(); 134 135 unsigned FrameReg = getFrameRegister(MF); 136 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 137 if (!TFI->hasFP(MF)) { 138 // We will not reserve space on the stack for the lr and fp registers. 139 Offset -= 2 * Hexagon_WordSize; 140 } 141 142 const unsigned FrameSize = MFI.getStackSize(); 143 144 if (!MFI.hasVarSizedObjects() && 145 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset)) && 146 !TII.isSpillPredRegOp(&MI)) { 147 // Replace frame index with a stack pointer reference. 148 MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(), false, 149 false, true); 150 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(FrameSize+Offset); 151 } else { 152 // Replace frame index with a frame pointer reference. 153 if (!TII.isValidOffset(MI.getOpcode(), Offset)) { 154 155 // If the offset overflows, then correct it. 156 // 157 // For loads, we do not need a reserved register 158 // r0 = memw(r30 + #10000) to: 159 // 160 // r0 = add(r30, #10000) 161 // r0 = memw(r0) 162 if ( (MI.getOpcode() == Hexagon::LDriw) || 163 (MI.getOpcode() == Hexagon::LDrid) || 164 (MI.getOpcode() == Hexagon::LDrih) || 165 (MI.getOpcode() == Hexagon::LDriuh) || 166 (MI.getOpcode() == Hexagon::LDrib) || 167 (MI.getOpcode() == Hexagon::LDriub) || 168 (MI.getOpcode() == Hexagon::LDriw_f) || 169 (MI.getOpcode() == Hexagon::LDrid_f)) { 170 unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ? 171 getSubReg(MI.getOperand(0).getReg(), Hexagon::subreg_loreg) : 172 MI.getOperand(0).getReg(); 173 174 // Check if offset can fit in addi. 175 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 176 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 177 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 178 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 179 TII.get(Hexagon::ADD_rr), 180 dstReg).addReg(FrameReg).addReg(dstReg); 181 } else { 182 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 183 TII.get(Hexagon::ADD_ri), 184 dstReg).addReg(FrameReg).addImm(Offset); 185 } 186 187 MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true); 188 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 189 } else if ((MI.getOpcode() == Hexagon::STriw_indexed) || 190 (MI.getOpcode() == Hexagon::STriw) || 191 (MI.getOpcode() == Hexagon::STrid) || 192 (MI.getOpcode() == Hexagon::STrih) || 193 (MI.getOpcode() == Hexagon::STrib) || 194 (MI.getOpcode() == Hexagon::STrid_f) || 195 (MI.getOpcode() == Hexagon::STriw_f)) { 196 // For stores, we need a reserved register. Change 197 // memw(r30 + #10000) = r0 to: 198 // 199 // rs = add(r30, #10000); 200 // memw(rs) = r0 201 unsigned resReg = HEXAGON_RESERVED_REG_1; 202 203 // Check if offset can fit in addi. 204 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 205 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 206 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 207 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 208 TII.get(Hexagon::ADD_rr), 209 resReg).addReg(FrameReg).addReg(resReg); 210 } else { 211 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 212 TII.get(Hexagon::ADD_ri), 213 resReg).addReg(FrameReg).addImm(Offset); 214 } 215 MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,true); 216 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 217 } else if (TII.isMemOp(&MI)) { 218 unsigned resReg = HEXAGON_RESERVED_REG_1; 219 if (!MFI.hasVarSizedObjects() && 220 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) { 221 MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(), 222 false, false, true); 223 MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset); 224 } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 225 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 226 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 227 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 228 TII.get(Hexagon::ADD_rr), 229 resReg).addReg(FrameReg).addReg(resReg); 230 MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false, 231 true); 232 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 233 } else { 234 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 235 TII.get(Hexagon::ADD_ri), 236 resReg).addReg(FrameReg).addImm(Offset); 237 MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false, 238 true); 239 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 240 } 241 } else { 242 unsigned dstReg = MI.getOperand(0).getReg(); 243 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 244 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 245 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 246 TII.get(Hexagon::ADD_rr), 247 dstReg).addReg(FrameReg).addReg(dstReg); 248 // Can we delete MI??? r2 = add (r2, #0). 249 MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true); 250 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 251 } 252 } else { 253 // If the offset is small enough to fit in the immediate field, directly 254 // encode it. 255 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 256 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 257 } 258 } 259 260} 261 262unsigned HexagonRegisterInfo::getRARegister() const { 263 return Hexagon::R31; 264} 265 266unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 267 &MF) const { 268 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 269 if (TFI->hasFP(MF)) { 270 return Hexagon::R30; 271 } 272 273 return Hexagon::R29; 274} 275 276unsigned HexagonRegisterInfo::getFrameRegister() const { 277 return Hexagon::R30; 278} 279 280unsigned HexagonRegisterInfo::getStackRegister() const { 281 return Hexagon::R29; 282} 283 284void HexagonRegisterInfo::getInitialFrameState(std::vector<MachineMove> 285 &Moves) const 286{ 287 // VirtualFP = (R30 + #0). 288 unsigned FPReg = getFrameRegister(); 289 MachineLocation Dst(MachineLocation::VirtualFP); 290 MachineLocation Src(FPReg, 0); 291 Moves.push_back(MachineMove(0, Dst, Src)); 292} 293 294unsigned HexagonRegisterInfo::getEHExceptionRegister() const { 295 llvm_unreachable("What is the exception register"); 296} 297 298unsigned HexagonRegisterInfo::getEHHandlerRegister() const { 299 llvm_unreachable("What is the exception handler register"); 300} 301 302#define GET_REGINFO_TARGET_DESC 303#include "HexagonGenRegisterInfo.inc" 304