LLVM API Documentation
00001 //===-- SparcRegisterInfo.cpp - SPARC 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 SPARC implementation of the TargetRegisterInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "SparcRegisterInfo.h" 00015 #include "Sparc.h" 00016 #include "SparcMachineFunctionInfo.h" 00017 #include "SparcSubtarget.h" 00018 #include "llvm/ADT/BitVector.h" 00019 #include "llvm/ADT/STLExtras.h" 00020 #include "llvm/CodeGen/MachineFrameInfo.h" 00021 #include "llvm/CodeGen/MachineFunction.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/IR/Type.h" 00024 #include "llvm/Support/CommandLine.h" 00025 #include "llvm/Support/ErrorHandling.h" 00026 #include "llvm/Target/TargetInstrInfo.h" 00027 00028 using namespace llvm; 00029 00030 #define GET_REGINFO_TARGET_DESC 00031 #include "SparcGenRegisterInfo.inc" 00032 00033 static cl::opt<bool> 00034 ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false), 00035 cl::desc("Reserve application registers (%g2-%g4)")); 00036 00037 SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st) 00038 : SparcGenRegisterInfo(SP::O7), Subtarget(st) { 00039 } 00040 00041 const MCPhysReg* 00042 SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 00043 return CSR_SaveList; 00044 } 00045 00046 const uint32_t* 00047 SparcRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const { 00048 return CSR_RegMask; 00049 } 00050 00051 const uint32_t* 00052 SparcRegisterInfo::getRTCallPreservedMask(CallingConv::ID CC) const { 00053 return RTCSR_RegMask; 00054 } 00055 00056 BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 00057 BitVector Reserved(getNumRegs()); 00058 // FIXME: G1 reserved for now for large imm generation by frame code. 00059 Reserved.set(SP::G1); 00060 00061 // G1-G4 can be used in applications. 00062 if (ReserveAppRegisters) { 00063 Reserved.set(SP::G2); 00064 Reserved.set(SP::G3); 00065 Reserved.set(SP::G4); 00066 } 00067 // G5 is not reserved in 64 bit mode. 00068 if (!Subtarget.is64Bit()) 00069 Reserved.set(SP::G5); 00070 00071 Reserved.set(SP::O6); 00072 Reserved.set(SP::I6); 00073 Reserved.set(SP::I7); 00074 Reserved.set(SP::G0); 00075 Reserved.set(SP::G6); 00076 Reserved.set(SP::G7); 00077 00078 // Unaliased double registers are not available in non-V9 targets. 00079 if (!Subtarget.isV9()) { 00080 for (unsigned n = 0; n != 16; ++n) { 00081 for (MCRegAliasIterator AI(SP::D16 + n, this, true); AI.isValid(); ++AI) 00082 Reserved.set(*AI); 00083 } 00084 } 00085 00086 return Reserved; 00087 } 00088 00089 const TargetRegisterClass* 00090 SparcRegisterInfo::getPointerRegClass(const MachineFunction &MF, 00091 unsigned Kind) const { 00092 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass; 00093 } 00094 00095 static void replaceFI(MachineFunction &MF, 00096 MachineBasicBlock::iterator II, 00097 MachineInstr &MI, 00098 DebugLoc dl, 00099 unsigned FIOperandNum, int Offset, 00100 unsigned FramePtr) 00101 { 00102 // Replace frame index with a frame pointer reference. 00103 if (Offset >= -4096 && Offset <= 4095) { 00104 // If the offset is small enough to fit in the immediate field, directly 00105 // encode it. 00106 MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false); 00107 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 00108 return; 00109 } 00110 00111 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 00112 00113 // FIXME: it would be better to scavenge a register here instead of 00114 // reserving G1 all of the time. 00115 if (Offset >= 0) { 00116 // Emit nonnegaive immediates with sethi + or. 00117 // sethi %hi(Offset), %g1 00118 // add %g1, %fp, %g1 00119 // Insert G1+%lo(offset) into the user. 00120 BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1) 00121 .addImm(HI22(Offset)); 00122 00123 00124 // Emit G1 = G1 + I6 00125 BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1) 00126 .addReg(FramePtr); 00127 // Insert: G1+%lo(offset) into the user. 00128 MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false); 00129 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(LO10(Offset)); 00130 return; 00131 } 00132 00133 // Emit Negative numbers with sethi + xor 00134 // sethi %hix(Offset), %g1 00135 // xor %g1, %lox(offset), %g1 00136 // add %g1, %fp, %g1 00137 // Insert: G1 + 0 into the user. 00138 BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1) 00139 .addImm(HIX22(Offset)); 00140 BuildMI(*MI.getParent(), II, dl, TII.get(SP::XORri), SP::G1) 00141 .addReg(SP::G1).addImm(LOX10(Offset)); 00142 00143 BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1) 00144 .addReg(FramePtr); 00145 // Insert: G1+%lo(offset) into the user. 00146 MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false); 00147 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); 00148 } 00149 00150 00151 void 00152 SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00153 int SPAdj, unsigned FIOperandNum, 00154 RegScavenger *RS) const { 00155 assert(SPAdj == 0 && "Unexpected"); 00156 00157 MachineInstr &MI = *II; 00158 DebugLoc dl = MI.getDebugLoc(); 00159 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 00160 00161 // Addressable stack objects are accessed using neg. offsets from %fp 00162 MachineFunction &MF = *MI.getParent()->getParent(); 00163 int64_t Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00164 MI.getOperand(FIOperandNum + 1).getImm() + 00165 Subtarget.getStackPointerBias(); 00166 SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 00167 unsigned FramePtr = SP::I6; 00168 if (FuncInfo->isLeafProc()) { 00169 // Use %sp and adjust offset if needed. 00170 FramePtr = SP::O6; 00171 int stackSize = MF.getFrameInfo()->getStackSize(); 00172 Offset += (stackSize) ? Subtarget.getAdjustedFrameSize(stackSize) : 0 ; 00173 } 00174 00175 if (!Subtarget.isV9() || !Subtarget.hasHardQuad()) { 00176 if (MI.getOpcode() == SP::STQFri) { 00177 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 00178 unsigned SrcReg = MI.getOperand(2).getReg(); 00179 unsigned SrcEvenReg = getSubReg(SrcReg, SP::sub_even64); 00180 unsigned SrcOddReg = getSubReg(SrcReg, SP::sub_odd64); 00181 MachineInstr *StMI = 00182 BuildMI(*MI.getParent(), II, dl, TII.get(SP::STDFri)) 00183 .addReg(FramePtr).addImm(0).addReg(SrcEvenReg); 00184 replaceFI(MF, II, *StMI, dl, 0, Offset, FramePtr); 00185 MI.setDesc(TII.get(SP::STDFri)); 00186 MI.getOperand(2).setReg(SrcOddReg); 00187 Offset += 8; 00188 } else if (MI.getOpcode() == SP::LDQFri) { 00189 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 00190 unsigned DestReg = MI.getOperand(0).getReg(); 00191 unsigned DestEvenReg = getSubReg(DestReg, SP::sub_even64); 00192 unsigned DestOddReg = getSubReg(DestReg, SP::sub_odd64); 00193 MachineInstr *StMI = 00194 BuildMI(*MI.getParent(), II, dl, TII.get(SP::LDDFri), DestEvenReg) 00195 .addReg(FramePtr).addImm(0); 00196 replaceFI(MF, II, *StMI, dl, 1, Offset, FramePtr); 00197 00198 MI.setDesc(TII.get(SP::LDDFri)); 00199 MI.getOperand(0).setReg(DestOddReg); 00200 Offset += 8; 00201 } 00202 } 00203 00204 replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FramePtr); 00205 00206 } 00207 00208 unsigned SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 00209 return SP::I6; 00210 } 00211