LLVM API Documentation
00001 //===-- MipsSERegisterInfo.cpp - MIPS32/64 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 MIPS32/64 implementation of the TargetRegisterInfo 00011 // class. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "MipsSERegisterInfo.h" 00016 #include "Mips.h" 00017 #include "MipsAnalyzeImmediate.h" 00018 #include "MipsMachineFunction.h" 00019 #include "MipsSEInstrInfo.h" 00020 #include "MipsSubtarget.h" 00021 #include "llvm/ADT/BitVector.h" 00022 #include "llvm/ADT/STLExtras.h" 00023 #include "llvm/CodeGen/MachineFrameInfo.h" 00024 #include "llvm/CodeGen/MachineFunction.h" 00025 #include "llvm/CodeGen/MachineInstrBuilder.h" 00026 #include "llvm/CodeGen/MachineRegisterInfo.h" 00027 #include "llvm/CodeGen/ValueTypes.h" 00028 #include "llvm/DebugInfo.h" 00029 #include "llvm/IR/Constants.h" 00030 #include "llvm/IR/Function.h" 00031 #include "llvm/IR/Type.h" 00032 #include "llvm/Support/CommandLine.h" 00033 #include "llvm/Support/Debug.h" 00034 #include "llvm/Support/ErrorHandling.h" 00035 #include "llvm/Support/raw_ostream.h" 00036 #include "llvm/Target/TargetFrameLowering.h" 00037 #include "llvm/Target/TargetInstrInfo.h" 00038 #include "llvm/Target/TargetMachine.h" 00039 #include "llvm/Target/TargetOptions.h" 00040 00041 using namespace llvm; 00042 00043 MipsSERegisterInfo::MipsSERegisterInfo(const MipsSubtarget &ST, 00044 const MipsSEInstrInfo &I) 00045 : MipsRegisterInfo(ST), TII(I) {} 00046 00047 bool MipsSERegisterInfo:: 00048 requiresRegisterScavenging(const MachineFunction &MF) const { 00049 return true; 00050 } 00051 00052 bool MipsSERegisterInfo:: 00053 requiresFrameIndexScavenging(const MachineFunction &MF) const { 00054 return true; 00055 } 00056 00057 const TargetRegisterClass * 00058 MipsSERegisterInfo::intRegClass(unsigned Size) const { 00059 if (Size == 4) 00060 return &Mips::CPURegsRegClass; 00061 00062 assert(Size == 8); 00063 return &Mips::CPU64RegsRegClass; 00064 } 00065 00066 void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II, 00067 unsigned OpNo, int FrameIndex, 00068 uint64_t StackSize, 00069 int64_t SPOffset) const { 00070 MachineInstr &MI = *II; 00071 MachineFunction &MF = *MI.getParent()->getParent(); 00072 MachineFrameInfo *MFI = MF.getFrameInfo(); 00073 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 00074 00075 const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 00076 int MinCSFI = 0; 00077 int MaxCSFI = -1; 00078 00079 if (CSI.size()) { 00080 MinCSFI = CSI[0].getFrameIdx(); 00081 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 00082 } 00083 00084 bool EhDataRegFI = MipsFI->isEhDataRegFI(FrameIndex); 00085 00086 // The following stack frame objects are always referenced relative to $sp: 00087 // 1. Outgoing arguments. 00088 // 2. Pointer to dynamically allocated stack space. 00089 // 3. Locations for callee-saved registers. 00090 // 4. Locations for eh data registers. 00091 // Everything else is referenced relative to whatever register 00092 // getFrameRegister() returns. 00093 unsigned FrameReg; 00094 00095 if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI) || EhDataRegFI) 00096 FrameReg = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP; 00097 else 00098 FrameReg = getFrameRegister(MF); 00099 00100 // Calculate final offset. 00101 // - There is no need to change the offset if the frame object is one of the 00102 // following: an outgoing argument, pointer to a dynamically allocated 00103 // stack space or a $gp restore location, 00104 // - If the frame object is any of the following, its offset must be adjusted 00105 // by adding the size of the stack: 00106 // incoming argument, callee-saved register location or local variable. 00107 bool IsKill = false; 00108 int64_t Offset; 00109 00110 Offset = SPOffset + (int64_t)StackSize; 00111 Offset += MI.getOperand(OpNo + 1).getImm(); 00112 00113 DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); 00114 00115 // If MI is not a debug value, make sure Offset fits in the 16-bit immediate 00116 // field. 00117 if (!MI.isDebugValue() && !isInt<16>(Offset)) { 00118 MachineBasicBlock &MBB = *MI.getParent(); 00119 DebugLoc DL = II->getDebugLoc(); 00120 unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu; 00121 unsigned NewImm; 00122 00123 unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL, &NewImm); 00124 BuildMI(MBB, II, DL, TII.get(ADDu), Reg).addReg(FrameReg) 00125 .addReg(Reg, RegState::Kill); 00126 00127 FrameReg = Reg; 00128 Offset = SignExtend64<16>(NewImm); 00129 IsKill = true; 00130 } 00131 00132 MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill); 00133 MI.getOperand(OpNo + 1).ChangeToImmediate(Offset); 00134 }