SparcRegisterInfo.cpp revision d93969c32a6bbae3326a1f485c4c85be1cb39406
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===-- SparcRegisterInfo.cpp - SPARC Register Information ----------------===// 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// The LLVM Compiler Infrastructure 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// License. See LICENSE.TXT for details. 76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===----------------------------------------------------------------------===// 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file contains the SPARC implementation of the TargetRegisterInfo class. 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)//===----------------------------------------------------------------------===// 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcRegisterInfo.h" 156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "Sparc.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcMachineFunctionInfo.h" 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcSubtarget.h" 186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/ADT/BitVector.h" 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/ADT/STLExtras.h" 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/IR/Type.h" 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/Support/CommandLine.h" 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h" 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/Target/TargetInstrInfo.h" 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#define GET_REGINFO_TARGET_DESC 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcGenRegisterInfo.inc" 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using namespace llvm; 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static cl::opt<bool> 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false), 356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) cl::desc("Reserve application registers (%g2-%g4)")); 366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st) 386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : SparcGenRegisterInfo(SP::I7), Subtarget(st) { 396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const { 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return CSR_SaveList; 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const uint32_t* 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const { 486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return CSR_RegMask; 496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BitVector Reserved(getNumRegs()); 536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // FIXME: G1 reserved for now for large imm generation by frame code. 546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G1); 556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // G1-G4 can be used in applications. 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (ReserveAppRegisters) { 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G2); 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G3); 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G4); 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // G5 is not reserved in 64 bit mode. 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!Subtarget.is64Bit()) 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G5); 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::O6); 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::I6); 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::I7); 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G0); 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G6); 716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Reserved.set(SP::G7); 726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return Reserved; 736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 75const TargetRegisterClass* 76SparcRegisterInfo::getPointerRegClass(const MachineFunction &MF, 77 unsigned Kind) const { 78 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass; 79} 80 81void 82SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 83 int SPAdj, unsigned FIOperandNum, 84 RegScavenger *RS) const { 85 assert(SPAdj == 0 && "Unexpected"); 86 87 MachineInstr &MI = *II; 88 DebugLoc dl = MI.getDebugLoc(); 89 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 90 91 // Addressable stack objects are accessed using neg. offsets from %fp 92 MachineFunction &MF = *MI.getParent()->getParent(); 93 int64_t Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 94 MI.getOperand(FIOperandNum + 1).getImm() + 95 Subtarget.getStackPointerBias(); 96 SparcMachineFunctionInfo *FuncInfo = MF.getInfo<SparcMachineFunctionInfo>(); 97 unsigned FramePtr = SP::I6; 98 if (FuncInfo->isLeafProc()) { 99 // Use %sp and adjust offset if needed. 100 FramePtr = SP::O6; 101 int stackSize = MF.getFrameInfo()->getStackSize(); 102 Offset += (stackSize) ? Subtarget.getAdjustedFrameSize(stackSize) : 0 ; 103 } 104 105 // Replace frame index with a frame pointer reference. 106 if (Offset >= -4096 && Offset <= 4095) { 107 // If the offset is small enough to fit in the immediate field, directly 108 // encode it. 109 MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false); 110 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 111 } else { 112 // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to 113 // scavenge a register here instead of reserving G1 all of the time. 114 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 115 unsigned OffHi = (unsigned)Offset >> 10U; 116 BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi); 117 // Emit G1 = G1 + I6 118 BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1) 119 .addReg(FramePtr); 120 // Insert: G1+%lo(offset) into the user. 121 MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false); 122 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset & ((1 << 10)-1)); 123 } 124} 125 126unsigned SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 127 return SP::I6; 128} 129 130unsigned SparcRegisterInfo::getEHExceptionRegister() const { 131 llvm_unreachable("What is the exception register"); 132} 133 134unsigned SparcRegisterInfo::getEHHandlerRegister() const { 135 llvm_unreachable("What is the exception handler register"); 136} 137