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 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 return CalleeSavedRegsV3; 67 } 68 llvm_unreachable("Callee saved registers requested for unknown architecture " 69 "version"); 70} 71 72BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 73 const { 74 BitVector Reserved(getNumRegs()); 75 Reserved.set(HEXAGON_RESERVED_REG_1); 76 Reserved.set(HEXAGON_RESERVED_REG_2); 77 Reserved.set(Hexagon::R29); 78 Reserved.set(Hexagon::R30); 79 Reserved.set(Hexagon::R31); 80 Reserved.set(Hexagon::D14); 81 Reserved.set(Hexagon::D15); 82 Reserved.set(Hexagon::LC0); 83 Reserved.set(Hexagon::LC1); 84 Reserved.set(Hexagon::SA0); 85 Reserved.set(Hexagon::SA1); 86 return Reserved; 87} 88 89 90const TargetRegisterClass* const* 91HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 92 static const TargetRegisterClass * const CalleeSavedRegClassesV2[] = { 93 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 94 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 95 }; 96 static const TargetRegisterClass * const CalleeSavedRegClassesV3[] = { 97 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 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 }; 104 105 switch(Subtarget.getHexagonArchVersion()) { 106 case HexagonSubtarget::V1: 107 break; 108 case HexagonSubtarget::V2: 109 return CalleeSavedRegClassesV2; 110 case HexagonSubtarget::V3: 111 case HexagonSubtarget::V4: 112 return CalleeSavedRegClassesV3; 113 } 114 llvm_unreachable("Callee saved register classes requested for unknown " 115 "architecture version"); 116} 117 118void HexagonRegisterInfo:: 119eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 120 MachineBasicBlock::iterator I) const { 121 MachineInstr &MI = *I; 122 123 if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) { 124 // Hexagon_TODO: add code 125 } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { 126 // Hexagon_TODO: add code 127 } else { 128 llvm_unreachable("Cannot handle this call frame pseudo instruction"); 129 } 130 MBB.erase(I); 131} 132 133void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 134 int SPAdj, RegScavenger *RS) const { 135 136 // 137 // Hexagon_TODO: Do we need to enforce this for Hexagon? 138 assert(SPAdj == 0 && "Unexpected"); 139 140 141 unsigned i = 0; 142 MachineInstr &MI = *II; 143 while (!MI.getOperand(i).isFI()) { 144 ++i; 145 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 146 } 147 148 int FrameIndex = MI.getOperand(i).getIndex(); 149 150 // Addressable stack objects are accessed using neg. offsets from %fp. 151 MachineFunction &MF = *MI.getParent()->getParent(); 152 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 153 MachineFrameInfo &MFI = *MF.getFrameInfo(); 154 155 unsigned FrameReg = getFrameRegister(MF); 156 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 157 if (!TFI->hasFP(MF)) { 158 // We will not reserve space on the stack for the lr and fp registers. 159 Offset -= 2 * Hexagon_WordSize; 160 } 161 162 const unsigned FrameSize = MFI.getStackSize(); 163 164 if (!MFI.hasVarSizedObjects() && 165 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset)) && 166 !TII.isSpillPredRegOp(&MI)) { 167 // Replace frame index with a stack pointer reference. 168 MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, true); 169 MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); 170 } else { 171 // Replace frame index with a frame pointer reference. 172 if (!TII.isValidOffset(MI.getOpcode(), Offset)) { 173 174 // If the offset overflows, then correct it. 175 // 176 // For loads, we do not need a reserved register 177 // r0 = memw(r30 + #10000) to: 178 // 179 // r0 = add(r30, #10000) 180 // r0 = memw(r0) 181 if ( (MI.getOpcode() == Hexagon::LDriw) || 182 (MI.getOpcode() == Hexagon::LDrid) || 183 (MI.getOpcode() == Hexagon::LDrih) || 184 (MI.getOpcode() == Hexagon::LDriuh) || 185 (MI.getOpcode() == Hexagon::LDrib) || 186 (MI.getOpcode() == Hexagon::LDriub) ) { 187 unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ? 188 *getSubRegisters(MI.getOperand(0).getReg()) : 189 MI.getOperand(0).getReg(); 190 191 // Check if offset can fit in addi. 192 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 193 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 194 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 195 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 196 TII.get(Hexagon::ADD_rr), 197 dstReg).addReg(FrameReg).addReg(dstReg); 198 } else { 199 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 200 TII.get(Hexagon::ADD_ri), 201 dstReg).addReg(FrameReg).addImm(Offset); 202 } 203 204 MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); 205 MI.getOperand(i+1).ChangeToImmediate(0); 206 } else if ((MI.getOpcode() == Hexagon::STriw) || 207 (MI.getOpcode() == Hexagon::STrid) || 208 (MI.getOpcode() == Hexagon::STrih) || 209 (MI.getOpcode() == Hexagon::STrib)) { 210 // For stores, we need a reserved register. Change 211 // memw(r30 + #10000) = r0 to: 212 // 213 // rs = add(r30, #10000); 214 // memw(rs) = r0 215 unsigned resReg = HEXAGON_RESERVED_REG_1; 216 217 // Check if offset can fit in addi. 218 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 219 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 220 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 221 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 222 TII.get(Hexagon::ADD_rr), 223 resReg).addReg(FrameReg).addReg(resReg); 224 } else { 225 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 226 TII.get(Hexagon::ADD_ri), 227 resReg).addReg(FrameReg).addImm(Offset); 228 } 229 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 230 MI.getOperand(i+1).ChangeToImmediate(0); 231 } else if (TII.isMemOp(&MI)) { 232 unsigned resReg = HEXAGON_RESERVED_REG_1; 233 if (!MFI.hasVarSizedObjects() && 234 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) { 235 MI.getOperand(i).ChangeToRegister(getStackRegister(), false, false, 236 true); 237 MI.getOperand(i+1).ChangeToImmediate(FrameSize+Offset); 238 } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 239 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 240 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 241 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 242 TII.get(Hexagon::ADD_rr), 243 resReg).addReg(FrameReg).addReg(resReg); 244 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 245 MI.getOperand(i+1).ChangeToImmediate(0); 246 } else { 247 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 248 TII.get(Hexagon::ADD_ri), 249 resReg).addReg(FrameReg).addImm(Offset); 250 MI.getOperand(i).ChangeToRegister(resReg, false, false, true); 251 MI.getOperand(i+1).ChangeToImmediate(0); 252 } 253 } else { 254 unsigned dstReg = MI.getOperand(0).getReg(); 255 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 256 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 257 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 258 TII.get(Hexagon::ADD_rr), 259 dstReg).addReg(FrameReg).addReg(dstReg); 260 // Can we delete MI??? r2 = add (r2, #0). 261 MI.getOperand(i).ChangeToRegister(dstReg, false, false, true); 262 MI.getOperand(i+1).ChangeToImmediate(0); 263 } 264 } else { 265 // If the offset is small enough to fit in the immediate field, directly 266 // encode it. 267 MI.getOperand(i).ChangeToRegister(FrameReg, false); 268 MI.getOperand(i+1).ChangeToImmediate(Offset); 269 } 270 } 271 272} 273 274unsigned HexagonRegisterInfo::getRARegister() const { 275 return Hexagon::R31; 276} 277 278unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 279 &MF) const { 280 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 281 if (TFI->hasFP(MF)) { 282 return Hexagon::R30; 283 } 284 285 return Hexagon::R29; 286} 287 288unsigned HexagonRegisterInfo::getFrameRegister() const { 289 return Hexagon::R30; 290} 291 292unsigned HexagonRegisterInfo::getStackRegister() const { 293 return Hexagon::R29; 294} 295 296void HexagonRegisterInfo::getInitialFrameState(std::vector<MachineMove> 297 &Moves) const 298{ 299 // VirtualFP = (R30 + #0). 300 unsigned FPReg = getFrameRegister(); 301 MachineLocation Dst(MachineLocation::VirtualFP); 302 MachineLocation Src(FPReg, 0); 303 Moves.push_back(MachineMove(0, Dst, Src)); 304} 305 306unsigned HexagonRegisterInfo::getEHExceptionRegister() const { 307 llvm_unreachable("What is the exception register"); 308} 309 310unsigned HexagonRegisterInfo::getEHHandlerRegister() const { 311 llvm_unreachable("What is the exception handler register"); 312} 313 314#define GET_REGINFO_TARGET_DESC 315#include "HexagonGenRegisterInfo.inc" 316