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