1 //===- AlphaRegisterInfo.cpp - Alpha Register Information -------*- C++ -*-===// 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 Alpha implementation of the TargetRegisterInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define DEBUG_TYPE "reginfo" 15 #include "Alpha.h" 16 #include "AlphaRegisterInfo.h" 17 #include "llvm/Constants.h" 18 #include "llvm/Type.h" 19 #include "llvm/Function.h" 20 #include "llvm/CodeGen/ValueTypes.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/CodeGen/MachineFunction.h" 23 #include "llvm/CodeGen/MachineFrameInfo.h" 24 #include "llvm/Target/TargetFrameLowering.h" 25 #include "llvm/Target/TargetMachine.h" 26 #include "llvm/Target/TargetOptions.h" 27 #include "llvm/Target/TargetInstrInfo.h" 28 #include "llvm/Support/CommandLine.h" 29 #include "llvm/Support/Debug.h" 30 #include "llvm/Support/ErrorHandling.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include "llvm/ADT/BitVector.h" 33 #include "llvm/ADT/STLExtras.h" 34 #include <cstdlib> 35 36 #define GET_REGINFO_TARGET_DESC 37 #include "AlphaGenRegisterInfo.inc" 38 39 using namespace llvm; 40 41 AlphaRegisterInfo::AlphaRegisterInfo(const TargetInstrInfo &tii) 42 : AlphaGenRegisterInfo(Alpha::R26), TII(tii) { 43 } 44 45 static long getUpper16(long l) { 46 long y = l / Alpha::IMM_MULT; 47 if (l % Alpha::IMM_MULT > Alpha::IMM_HIGH) 48 ++y; 49 return y; 50 } 51 52 static long getLower16(long l) { 53 long h = getUpper16(l); 54 return l - h * Alpha::IMM_MULT; 55 } 56 57 const unsigned* AlphaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 58 const { 59 static const unsigned CalleeSavedRegs[] = { 60 Alpha::R9, Alpha::R10, 61 Alpha::R11, Alpha::R12, 62 Alpha::R13, Alpha::R14, 63 Alpha::F2, Alpha::F3, 64 Alpha::F4, Alpha::F5, 65 Alpha::F6, Alpha::F7, 66 Alpha::F8, Alpha::F9, 0 67 }; 68 return CalleeSavedRegs; 69 } 70 71 BitVector AlphaRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 72 BitVector Reserved(getNumRegs()); 73 Reserved.set(Alpha::R15); 74 Reserved.set(Alpha::R29); 75 Reserved.set(Alpha::R30); 76 Reserved.set(Alpha::R31); 77 return Reserved; 78 } 79 80 //===----------------------------------------------------------------------===// 81 // Stack Frame Processing methods 82 //===----------------------------------------------------------------------===// 83 84 void AlphaRegisterInfo:: 85 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 86 MachineBasicBlock::iterator I) const { 87 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 88 89 if (TFI->hasFP(MF)) { 90 // If we have a frame pointer, turn the adjcallstackup instruction into a 91 // 'sub ESP, <amt>' and the adjcallstackdown instruction into 'add ESP, 92 // <amt>' 93 MachineInstr *Old = I; 94 uint64_t Amount = Old->getOperand(0).getImm(); 95 if (Amount != 0) { 96 // We need to keep the stack aligned properly. To do this, we round the 97 // amount of space needed for the outgoing arguments up to the next 98 // alignment boundary. 99 unsigned Align = TFI->getStackAlignment(); 100 Amount = (Amount+Align-1)/Align*Align; 101 102 MachineInstr *New; 103 if (Old->getOpcode() == Alpha::ADJUSTSTACKDOWN) { 104 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Alpha::LDA), Alpha::R30) 105 .addImm(-Amount).addReg(Alpha::R30); 106 } else { 107 assert(Old->getOpcode() == Alpha::ADJUSTSTACKUP); 108 New=BuildMI(MF, Old->getDebugLoc(), TII.get(Alpha::LDA), Alpha::R30) 109 .addImm(Amount).addReg(Alpha::R30); 110 } 111 112 // Replace the pseudo instruction with a new instruction... 113 MBB.insert(I, New); 114 } 115 } 116 117 MBB.erase(I); 118 } 119 120 //Alpha has a slightly funny stack: 121 //Args 122 //<- incoming SP 123 //fixed locals (and spills, callee saved, etc) 124 //<- FP 125 //variable locals 126 //<- SP 127 128 void 129 AlphaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 130 int SPAdj, RegScavenger *RS) const { 131 assert(SPAdj == 0 && "Unexpected"); 132 133 unsigned i = 0; 134 MachineInstr &MI = *II; 135 MachineBasicBlock &MBB = *MI.getParent(); 136 MachineFunction &MF = *MBB.getParent(); 137 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 138 139 bool FP = TFI->hasFP(MF); 140 141 while (!MI.getOperand(i).isFI()) { 142 ++i; 143 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 144 } 145 146 int FrameIndex = MI.getOperand(i).getIndex(); 147 148 // Add the base register of R30 (SP) or R15 (FP). 149 MI.getOperand(i + 1).ChangeToRegister(FP ? Alpha::R15 : Alpha::R30, false); 150 151 // Now add the frame object offset to the offset from the virtual frame index. 152 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 153 154 DEBUG(errs() << "FI: " << FrameIndex << " Offset: " << Offset << "\n"); 155 156 Offset += MF.getFrameInfo()->getStackSize(); 157 158 DEBUG(errs() << "Corrected Offset " << Offset 159 << " for stack size: " << MF.getFrameInfo()->getStackSize() << "\n"); 160 161 if (Offset > Alpha::IMM_HIGH || Offset < Alpha::IMM_LOW) { 162 DEBUG(errs() << "Unconditionally using R28 for evil purposes Offset: " 163 << Offset << "\n"); 164 //so in this case, we need to use a temporary register, and move the 165 //original inst off the SP/FP 166 //fix up the old: 167 MI.getOperand(i + 1).ChangeToRegister(Alpha::R28, false); 168 MI.getOperand(i).ChangeToImmediate(getLower16(Offset)); 169 //insert the new 170 MachineInstr* nMI=BuildMI(MF, MI.getDebugLoc(), 171 TII.get(Alpha::LDAH), Alpha::R28) 172 .addImm(getUpper16(Offset)).addReg(FP ? Alpha::R15 : Alpha::R30); 173 MBB.insert(II, nMI); 174 } else { 175 MI.getOperand(i).ChangeToImmediate(Offset); 176 } 177 } 178 179 unsigned AlphaRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 180 const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 181 182 return TFI->hasFP(MF) ? Alpha::R15 : Alpha::R30; 183 } 184 185 unsigned AlphaRegisterInfo::getEHExceptionRegister() const { 186 llvm_unreachable("What is the exception register"); 187 return 0; 188 } 189 190 unsigned AlphaRegisterInfo::getEHHandlerRegister() const { 191 llvm_unreachable("What is the exception handler register"); 192 return 0; 193 } 194 195 std::string AlphaRegisterInfo::getPrettyName(unsigned reg) 196 { 197 std::string s(AlphaRegDesc[reg].Name); 198 return s; 199 } 200