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 "SparcSubtarget.h" 00017 #include "llvm/ADT/BitVector.h" 00018 #include "llvm/ADT/STLExtras.h" 00019 #include "llvm/CodeGen/MachineFrameInfo.h" 00020 #include "llvm/CodeGen/MachineFunction.h" 00021 #include "llvm/CodeGen/MachineInstrBuilder.h" 00022 #include "llvm/IR/Type.h" 00023 #include "llvm/Support/CommandLine.h" 00024 #include "llvm/Support/ErrorHandling.h" 00025 #include "llvm/Target/TargetInstrInfo.h" 00026 00027 #define GET_REGINFO_TARGET_DESC 00028 #include "SparcGenRegisterInfo.inc" 00029 00030 using namespace llvm; 00031 00032 static cl::opt<bool> 00033 ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false), 00034 cl::desc("Reserve application registers (%g2-%g4)")); 00035 00036 SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st, 00037 const TargetInstrInfo &tii) 00038 : SparcGenRegisterInfo(SP::I7), Subtarget(st), TII(tii) { 00039 } 00040 00041 const uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 00042 const { 00043 static const uint16_t CalleeSavedRegs[] = { 0 }; 00044 return CalleeSavedRegs; 00045 } 00046 00047 BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 00048 BitVector Reserved(getNumRegs()); 00049 // FIXME: G1 reserved for now for large imm generation by frame code. 00050 Reserved.set(SP::G1); 00051 00052 //G1-G4 can be used in applications. 00053 if (ReserveAppRegisters) { 00054 Reserved.set(SP::G2); 00055 Reserved.set(SP::G3); 00056 Reserved.set(SP::G4); 00057 } 00058 //G5 is not reserved in 64 bit mode. 00059 if (!Subtarget.is64Bit()) 00060 Reserved.set(SP::G5); 00061 00062 Reserved.set(SP::O6); 00063 Reserved.set(SP::I6); 00064 Reserved.set(SP::I7); 00065 Reserved.set(SP::G0); 00066 Reserved.set(SP::G6); 00067 Reserved.set(SP::G7); 00068 return Reserved; 00069 } 00070 00071 const TargetRegisterClass* 00072 SparcRegisterInfo::getPointerRegClass(const MachineFunction &MF, 00073 unsigned Kind) const { 00074 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass; 00075 } 00076 00077 void 00078 SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 00079 int SPAdj, unsigned FIOperandNum, 00080 RegScavenger *RS) const { 00081 assert(SPAdj == 0 && "Unexpected"); 00082 00083 MachineInstr &MI = *II; 00084 DebugLoc dl = MI.getDebugLoc(); 00085 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 00086 00087 // Addressable stack objects are accessed using neg. offsets from %fp 00088 MachineFunction &MF = *MI.getParent()->getParent(); 00089 int64_t Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 00090 MI.getOperand(FIOperandNum + 1).getImm() + 00091 Subtarget.getStackPointerBias(); 00092 00093 // Replace frame index with a frame pointer reference. 00094 if (Offset >= -4096 && Offset <= 4095) { 00095 // If the offset is small enough to fit in the immediate field, directly 00096 // encode it. 00097 MI.getOperand(FIOperandNum).ChangeToRegister(SP::I6, false); 00098 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 00099 } else { 00100 // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to 00101 // scavenge a register here instead of reserving G1 all of the time. 00102 unsigned OffHi = (unsigned)Offset >> 10U; 00103 BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); 00104 // Emit G1 = G1 + I6 00105 BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1) 00106 .addReg(SP::I6); 00107 // Insert: G1+%lo(offset) into the user. 00108 MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false); 00109 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset & ((1 << 10)-1)); 00110 } 00111 } 00112 00113 unsigned SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 00114 return SP::I6; 00115 } 00116 00117 unsigned SparcRegisterInfo::getEHExceptionRegister() const { 00118 llvm_unreachable("What is the exception register"); 00119 } 00120 00121 unsigned SparcRegisterInfo::getEHHandlerRegister() const { 00122 llvm_unreachable("What is the exception handler register"); 00123 }