SparcRegisterInfo.cpp revision 234353
1193323Sed//===-- SparcRegisterInfo.cpp - SPARC Register Information ----------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file contains the SPARC implementation of the TargetRegisterInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#include "SparcRegisterInfo.h"
15193323Sed#include "Sparc.h"
16193323Sed#include "SparcSubtarget.h"
17198090Srdivacky#include "llvm/Type.h"
18198090Srdivacky#include "llvm/CodeGen/MachineInstrBuilder.h"
19193323Sed#include "llvm/CodeGen/MachineFunction.h"
20193323Sed#include "llvm/CodeGen/MachineFrameInfo.h"
21195340Sed#include "llvm/Support/ErrorHandling.h"
22193323Sed#include "llvm/Target/TargetInstrInfo.h"
23193323Sed#include "llvm/ADT/BitVector.h"
24198090Srdivacky#include "llvm/ADT/STLExtras.h"
25193323Sed
26193323Sed#define GET_REGINFO_TARGET_DESC
27193323Sed#include "SparcGenRegisterInfo.inc"
28193323Sed
29193323Sedusing namespace llvm;
30195340Sed
31193323SedSparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st,
32193323Sed                                     const TargetInstrInfo &tii)
33193323Sed  : SparcGenRegisterInfo(SP::I7), Subtarget(st), TII(tii) {
34193323Sed}
35193323Sed
36193323Sedconst uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
37193323Sed                                                                         const {
38193323Sed  static const uint16_t CalleeSavedRegs[] = { 0 };
39193323Sed  return CalleeSavedRegs;
40193323Sed}
41193323Sed
42193323SedBitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
43193323Sed  BitVector Reserved(getNumRegs());
44193323Sed  // FIXME: G1 reserved for now for large imm generation by frame code.
45193323Sed  Reserved.set(SP::G1);
46193323Sed  Reserved.set(SP::G2);
47193323Sed  Reserved.set(SP::G3);
48193323Sed  Reserved.set(SP::G4);
49193323Sed  Reserved.set(SP::O6);
50193323Sed  Reserved.set(SP::I6);
51193323Sed  Reserved.set(SP::I7);
52193323Sed  Reserved.set(SP::G0);
53193323Sed  Reserved.set(SP::G5);
54193323Sed  Reserved.set(SP::G6);
55193323Sed  Reserved.set(SP::G7);
56193323Sed  return Reserved;
57193323Sed}
58193323Sed
59193323Sedvoid SparcRegisterInfo::
60193323SedeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
61193323Sed                              MachineBasicBlock::iterator I) const {
62193323Sed  MachineInstr &MI = *I;
63193323Sed  DebugLoc dl = MI.getDebugLoc();
64193323Sed  int Size = MI.getOperand(0).getImm();
65193323Sed  if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
66193323Sed    Size = -Size;
67193323Sed  if (Size)
68193323Sed    BuildMI(MBB, I, dl, TII.get(SP::ADDri), SP::O6).addReg(SP::O6).addImm(Size);
69193323Sed  MBB.erase(I);
70193323Sed}
71193323Sed
72193323Sedvoid
73193323SedSparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
74193323Sed                                       int SPAdj, RegScavenger *RS) const {
75193323Sed  assert(SPAdj == 0 && "Unexpected");
76193323Sed
77193323Sed  unsigned i = 0;
78193323Sed  MachineInstr &MI = *II;
79193323Sed  DebugLoc dl = MI.getDebugLoc();
80193323Sed  while (!MI.getOperand(i).isFI()) {
81193323Sed    ++i;
82193323Sed    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
83193323Sed  }
84193323Sed
85193323Sed  int FrameIndex = MI.getOperand(i).getIndex();
86193323Sed
87193323Sed  // Addressable stack objects are accessed using neg. offsets from %fp
88193323Sed  MachineFunction &MF = *MI.getParent()->getParent();
89193323Sed  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
90193323Sed               MI.getOperand(i+1).getImm();
91193323Sed
92193323Sed  // Replace frame index with a frame pointer reference.
93193323Sed  if (Offset >= -4096 && Offset <= 4095) {
94193323Sed    // If the offset is small enough to fit in the immediate field, directly
95193323Sed    // encode it.
96193323Sed    MI.getOperand(i).ChangeToRegister(SP::I6, false);
97193323Sed    MI.getOperand(i+1).ChangeToImmediate(Offset);
98193323Sed  } else {
99193323Sed    // Otherwise, emit a G1 = SETHI %hi(offset).  FIXME: it would be better to
100193323Sed    // scavenge a register here instead of reserving G1 all of the time.
101193323Sed    unsigned OffHi = (unsigned)Offset >> 10U;
102193323Sed    BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1).addImm(OffHi);
103193323Sed    // Emit G1 = G1 + I6
104193323Sed    BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)
105193323Sed      .addReg(SP::I6);
106193323Sed    // Insert: G1+%lo(offset) into the user.
107193323Sed    MI.getOperand(i).ChangeToRegister(SP::G1, false);
108193323Sed    MI.getOperand(i+1).ChangeToImmediate(Offset & ((1 << 10)-1));
109193323Sed  }
110193323Sed}
111193323Sed
112193323Sedvoid SparcRegisterInfo::
113193323SedprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
114193323Sed
115193323Sedunsigned SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
116193323Sed  return SP::I6;
117193323Sed}
118193323Sed
119193323Sedunsigned SparcRegisterInfo::getEHExceptionRegister() const {
120193323Sed  llvm_unreachable("What is the exception register");
121193323Sed}
122193323Sed
123193323Sedunsigned SparcRegisterInfo::getEHHandlerRegister() const {
124193323Sed  llvm_unreachable("What is the exception handler register");
125193323Sed}
126193323Sed