LLVM API Documentation
00001 //===-- HexagonRegisterInfo.cpp - Hexagon Register Information ------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the Hexagon implementation of the TargetRegisterInfo 00011 // class. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "HexagonRegisterInfo.h" 00016 #include "Hexagon.h" 00017 #include "HexagonMachineFunctionInfo.h" 00018 #include "HexagonSubtarget.h" 00019 #include "HexagonTargetMachine.h" 00020 #include "llvm/ADT/BitVector.h" 00021 #include "llvm/ADT/STLExtras.h" 00022 #include "llvm/CodeGen/MachineFrameInfo.h" 00023 #include "llvm/CodeGen/MachineFunction.h" 00024 #include "llvm/CodeGen/MachineFunctionPass.h" 00025 #include "llvm/CodeGen/MachineInstrBuilder.h" 00026 #include "llvm/CodeGen/MachineRegisterInfo.h" 00027 #include "llvm/CodeGen/PseudoSourceValue.h" 00028 #include "llvm/CodeGen/RegisterScavenging.h" 00029 #include "llvm/IR/Function.h" 00030 #include "llvm/IR/Type.h" 00031 #include "llvm/MC/MachineLocation.h" 00032 #include "llvm/Support/CommandLine.h" 00033 #include "llvm/Support/ErrorHandling.h" 00034 #include "llvm/Target/TargetInstrInfo.h" 00035 #include "llvm/Target/TargetMachine.h" 00036 #include "llvm/Target/TargetOptions.h" 00037 00038 using namespace llvm; 00039 00040 00041 HexagonRegisterInfo::HexagonRegisterInfo(HexagonSubtarget &st) 00042 : HexagonGenRegisterInfo(Hexagon::R31), 00043 Subtarget(st) { 00044 } 00045 00046 const MCPhysReg * 00047 HexagonRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 00048 static const MCPhysReg CalleeSavedRegsV2[] = { 00049 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 00050 }; 00051 static const MCPhysReg CalleeSavedRegsV3[] = { 00052 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 00053 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, 00054 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0 00055 }; 00056 00057 switch(Subtarget.getHexagonArchVersion()) { 00058 case HexagonSubtarget::V1: 00059 break; 00060 case HexagonSubtarget::V2: 00061 return CalleeSavedRegsV2; 00062 case HexagonSubtarget::V3: 00063 case HexagonSubtarget::V4: 00064 case HexagonSubtarget::V5: 00065 return CalleeSavedRegsV3; 00066 } 00067 llvm_unreachable("Callee saved registers requested for unknown architecture " 00068 "version"); 00069 } 00070 00071 BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) 00072 const { 00073 BitVector Reserved(getNumRegs()); 00074 Reserved.set(HEXAGON_RESERVED_REG_1); 00075 Reserved.set(HEXAGON_RESERVED_REG_2); 00076 Reserved.set(Hexagon::R29); 00077 Reserved.set(Hexagon::R30); 00078 Reserved.set(Hexagon::R31); 00079 Reserved.set(Hexagon::D14); 00080 Reserved.set(Hexagon::D15); 00081 Reserved.set(Hexagon::LC0); 00082 Reserved.set(Hexagon::LC1); 00083 Reserved.set(Hexagon::SA0); 00084 Reserved.set(Hexagon::SA1); 00085 return Reserved; 00086 } 00087 00088 00089 const TargetRegisterClass* const* 00090 HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { 00091 static const TargetRegisterClass * const CalleeSavedRegClassesV2[] = { 00092 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00093 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00094 }; 00095 static const TargetRegisterClass * const CalleeSavedRegClassesV3[] = { 00096 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00097 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00098 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00099 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00100 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00101 &Hexagon::IntRegsRegClass, &Hexagon::IntRegsRegClass, 00102 }; 00103 00104 switch(Subtarget.getHexagonArchVersion()) { 00105 case HexagonSubtarget::V1: 00106 break; 00107 case HexagonSubtarget::V2: 00108 return CalleeSavedRegClassesV2; 00109 case HexagonSubtarget::V3: 00110 case HexagonSubtarget::V4: 00111 case HexagonSubtarget::V5: 00112 return CalleeSavedRegClassesV3; 00113 } 00114 llvm_unreachable("Callee saved register classes requested for unknown " 00115 "architecture version"); 00116 } 00117 00118 void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00119 int SPAdj, unsigned FIOperandNum, 00120 RegScavenger *RS) const { 00121 // 00122 // Hexagon_TODO: Do we need to enforce this for Hexagon? 00123 assert(SPAdj == 0 && "Unexpected"); 00124 00125 MachineInstr &MI = *II; 00126 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 00127 00128 // Addressable stack objects are accessed using neg. offsets from %fp. 00129 MachineFunction &MF = *MI.getParent()->getParent(); 00130 const HexagonInstrInfo &TII = 00131 *static_cast<const HexagonInstrInfo *>(MF.getSubtarget().getInstrInfo()); 00132 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 00133 MachineFrameInfo &MFI = *MF.getFrameInfo(); 00134 00135 unsigned FrameReg = getFrameRegister(MF); 00136 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 00137 if (!TFI->hasFP(MF)) { 00138 // We will not reserve space on the stack for the lr and fp registers. 00139 Offset -= 2 * Hexagon_WordSize; 00140 } 00141 00142 const unsigned FrameSize = MFI.getStackSize(); 00143 00144 if (!MFI.hasVarSizedObjects() && 00145 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset)) && 00146 !TII.isSpillPredRegOp(&MI)) { 00147 // Replace frame index with a stack pointer reference. 00148 MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(), false, 00149 false, true); 00150 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(FrameSize+Offset); 00151 } else { 00152 // Replace frame index with a frame pointer reference. 00153 if (!TII.isValidOffset(MI.getOpcode(), Offset)) { 00154 00155 // If the offset overflows, then correct it. 00156 // 00157 // For loads, we do not need a reserved register 00158 // r0 = memw(r30 + #10000) to: 00159 // 00160 // r0 = add(r30, #10000) 00161 // r0 = memw(r0) 00162 if ( (MI.getOpcode() == Hexagon::LDriw) || 00163 (MI.getOpcode() == Hexagon::LDrid) || 00164 (MI.getOpcode() == Hexagon::LDrih) || 00165 (MI.getOpcode() == Hexagon::LDriuh) || 00166 (MI.getOpcode() == Hexagon::LDrib) || 00167 (MI.getOpcode() == Hexagon::LDriub) || 00168 (MI.getOpcode() == Hexagon::LDriw_f) || 00169 (MI.getOpcode() == Hexagon::LDrid_f)) { 00170 unsigned dstReg = (MI.getOpcode() == Hexagon::LDrid) ? 00171 getSubReg(MI.getOperand(0).getReg(), Hexagon::subreg_loreg) : 00172 MI.getOperand(0).getReg(); 00173 00174 // Check if offset can fit in addi. 00175 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 00176 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00177 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 00178 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00179 TII.get(Hexagon::ADD_rr), 00180 dstReg).addReg(FrameReg).addReg(dstReg); 00181 } else { 00182 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00183 TII.get(Hexagon::ADD_ri), 00184 dstReg).addReg(FrameReg).addImm(Offset); 00185 } 00186 00187 MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true); 00188 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 00189 } else if ((MI.getOpcode() == Hexagon::STriw_indexed) || 00190 (MI.getOpcode() == Hexagon::STriw) || 00191 (MI.getOpcode() == Hexagon::STrid) || 00192 (MI.getOpcode() == Hexagon::STrih) || 00193 (MI.getOpcode() == Hexagon::STrib) || 00194 (MI.getOpcode() == Hexagon::STrid_f) || 00195 (MI.getOpcode() == Hexagon::STriw_f)) { 00196 // For stores, we need a reserved register. Change 00197 // memw(r30 + #10000) = r0 to: 00198 // 00199 // rs = add(r30, #10000); 00200 // memw(rs) = r0 00201 unsigned resReg = HEXAGON_RESERVED_REG_1; 00202 00203 // Check if offset can fit in addi. 00204 if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 00205 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00206 TII.get(Hexagon::CONST32_Int_Real), resReg).addImm(Offset); 00207 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00208 TII.get(Hexagon::ADD_rr), 00209 resReg).addReg(FrameReg).addReg(resReg); 00210 } else { 00211 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00212 TII.get(Hexagon::ADD_ri), 00213 resReg).addReg(FrameReg).addImm(Offset); 00214 } 00215 MI.getOperand(FIOperandNum).ChangeToRegister(resReg, false, false,true); 00216 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 00217 } else if (TII.isMemOp(&MI)) { 00218 // use the constant extender if the instruction provides it 00219 // and we are V4TOps. 00220 if (Subtarget.hasV4TOps()) { 00221 if (TII.isConstExtended(&MI)) { 00222 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 00223 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 00224 TII.immediateExtend(&MI); 00225 } else { 00226 llvm_unreachable("Need to implement for memops"); 00227 } 00228 } else { 00229 // Only V3 and older instructions here. 00230 unsigned ResReg = HEXAGON_RESERVED_REG_1; 00231 if (!MFI.hasVarSizedObjects() && 00232 TII.isValidOffset(MI.getOpcode(), (FrameSize+Offset))) { 00233 MI.getOperand(FIOperandNum).ChangeToRegister(getStackRegister(), 00234 false, false, false); 00235 MI.getOperand(FIOperandNum+1).ChangeToImmediate(FrameSize+Offset); 00236 } else if (!TII.isValidOffset(Hexagon::ADD_ri, Offset)) { 00237 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00238 TII.get(Hexagon::CONST32_Int_Real), ResReg).addImm(Offset); 00239 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00240 TII.get(Hexagon::ADD_rr), ResReg).addReg(FrameReg). 00241 addReg(ResReg); 00242 MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false, 00243 true); 00244 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 00245 } else { 00246 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00247 TII.get(Hexagon::ADD_ri), ResReg).addReg(FrameReg). 00248 addImm(Offset); 00249 MI.getOperand(FIOperandNum).ChangeToRegister(ResReg, false, false, 00250 true); 00251 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 00252 } 00253 } 00254 } else { 00255 unsigned dstReg = MI.getOperand(0).getReg(); 00256 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00257 TII.get(Hexagon::CONST32_Int_Real), dstReg).addImm(Offset); 00258 BuildMI(*MI.getParent(), II, MI.getDebugLoc(), 00259 TII.get(Hexagon::ADD_rr), 00260 dstReg).addReg(FrameReg).addReg(dstReg); 00261 // Can we delete MI??? r2 = add (r2, #0). 00262 MI.getOperand(FIOperandNum).ChangeToRegister(dstReg, false, false,true); 00263 MI.getOperand(FIOperandNum+1).ChangeToImmediate(0); 00264 } 00265 } else { 00266 // If the offset is small enough to fit in the immediate field, directly 00267 // encode it. 00268 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 00269 MI.getOperand(FIOperandNum+1).ChangeToImmediate(Offset); 00270 } 00271 } 00272 00273 } 00274 00275 unsigned HexagonRegisterInfo::getRARegister() const { 00276 return Hexagon::R31; 00277 } 00278 00279 unsigned HexagonRegisterInfo::getFrameRegister(const MachineFunction 00280 &MF) const { 00281 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 00282 if (TFI->hasFP(MF)) { 00283 return Hexagon::R30; 00284 } 00285 00286 return Hexagon::R29; 00287 } 00288 00289 unsigned HexagonRegisterInfo::getFrameRegister() const { 00290 return Hexagon::R30; 00291 } 00292 00293 unsigned HexagonRegisterInfo::getStackRegister() const { 00294 return Hexagon::R29; 00295 } 00296 00297 #define GET_REGINFO_TARGET_DESC 00298 #include "HexagonGenRegisterInfo.inc"