SparcRegisterInfo.cpp revision 63b3d7113d93fda622c4954c6b1d046ce029044e
194b5036ee6ba866e1702848855b6d687d1e70afaAlexey Samsonov//===- SparcRegisterInfo.cpp - SPARC Register Information -------*- C++ -*-===//
29aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//
39aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//                     The LLVM Compiler Infrastructure
49aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//
59aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany// This file was developed by the LLVM research group and is distributed under
69aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany// the University of Illinois Open Source License. See LICENSE.TXT for details.
79aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//
89aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//===----------------------------------------------------------------------===//
99aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//
109aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany// This file contains the SPARC implementation of the MRegisterInfo class.
110a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov//
129aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany//===----------------------------------------------------------------------===//
139aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany
149aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany#include "Sparc.h"
159aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany#include "SparcRegisterInfo.h"
1624e13723f8477d8c42ab8b2a7f4f69fc089842f1Evgeniy Stepanov#include "SparcSubtarget.h"
1783cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#include "llvm/CodeGen/MachineInstrBuilder.h"
183c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov#include "llvm/CodeGen/MachineFunction.h"
1930e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov#include "llvm/CodeGen/MachineFrameInfo.h"
203c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov#include "llvm/CodeGen/MachineLocation.h"
213c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov#include "llvm/Type.h"
22250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov#include "llvm/ADT/STLExtras.h"
23250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov#include <iostream>
24250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanovusing namespace llvm;
25250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov
26250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovSparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st)
27250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  : SparcGenRegisterInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP),
28250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    Subtarget(st) {
29250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov}
30250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov
3178b580f3d40132816f813c3dbf073d824137436aAlexey Samsonovvoid SparcRegisterInfo::
32250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
33250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                    unsigned SrcReg, int FI,
34250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                    const TargetRegisterClass *RC) const {
35250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
36250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  if (RC == SP::IntRegsRegisterClass)
37e31eca900a1f8849af75100c2d92e838d79d0920Kostya Serebryany    BuildMI(MBB, I, SP::STri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
38250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::FPRegsRegisterClass)
39250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::STFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
40250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::DFPRegsRegisterClass)
41250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::STDFri, 3).addFrameIndex(FI).addImm(0).addReg(SrcReg);
42250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else
43250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    assert(0 && "Can't store this register to stack slot");
44250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov}
45250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov
46250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanovvoid SparcRegisterInfo::
47250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanovloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
48250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                     unsigned DestReg, int FI,
49250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                     const TargetRegisterClass *RC) const {
50250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  if (RC == SP::IntRegsRegisterClass)
51250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::LDri, 2, DestReg).addFrameIndex(FI).addImm(0);
52250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::FPRegsRegisterClass)
53250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::LDFri, 2, DestReg).addFrameIndex(FI).addImm (0);
54250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::DFPRegsRegisterClass)
55250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::LDDFri, 2, DestReg).addFrameIndex(FI).addImm(0);
56250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else
57250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    assert(0 && "Can't load this register from stack slot");
58250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov}
59250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov
60250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanovvoid SparcRegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
61250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                                     MachineBasicBlock::iterator I,
62250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                                     unsigned DestReg, unsigned SrcReg,
63250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                                     const TargetRegisterClass *RC) const {
64250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  if (RC == SP::IntRegsRegisterClass)
65250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::ORrr, 2, DestReg).addReg(SP::G0).addReg(SrcReg);
66250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::FPRegsRegisterClass)
67250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, SP::FMOVS, 1, DestReg).addReg(SrcReg);
68250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else if (RC == SP::DFPRegsRegisterClass)
69250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    BuildMI(MBB, I, Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD,
70ee7cc4454421a176d23442382afd9a01d36e7ad4Alexey Samsonov            1, DestReg).addReg(SrcReg);
71250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  else
726fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany    assert (0 && "Can't copy this register");
736fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany}
746fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany
756fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya SerebryanyMachineInstr *SparcRegisterInfo::foldMemoryOperand(MachineInstr* MI,
7630e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov                                                   unsigned OpNum,
776fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany                                                   int FI) const {
786fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany  bool isFloat = false;
796fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany  switch (MI->getOpcode()) {
806fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany  case SP::ORrr:
816fb47af2d2d305adbfc3d41bea589d1527a364a9Kostya Serebryany    if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == SP::G0&&
82250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov        MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) {
83250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov      if (OpNum == 0)    // COPY -> STORE
84250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov        return BuildMI(SP::STri, 3).addFrameIndex(FI).addImm(0)
85250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                                   .addReg(MI->getOperand(2).getReg());
863c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov      else               // COPY -> LOAD
873c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov        return BuildMI(SP::LDri, 2, MI->getOperand(0).getReg())
88250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov                      .addFrameIndex(FI).addImm(0);
89250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    }
90250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    break;
913c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov  case SP::FMOVS:
923c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov    isFloat = true;
93250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    // FALLTHROUGH
94250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov  case SP::FMOVD:
95250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov    if (OpNum == 0)  // COPY -> STORE
96250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov      return BuildMI(isFloat ? SP::STFri : SP::STDFri, 3)
973c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov               .addFrameIndex(FI).addImm(0).addReg(MI->getOperand(1).getReg());
983c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov    else             // COPY -> LOAD
992673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany      return BuildMI(isFloat ? SP::LDFri : SP::LDDFri, 2,
1002673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany                     MI->getOperand(0).getReg()).addFrameIndex(FI).addImm(0);
1012673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany    break;
1022673fd8406197c42f16cede6d287f72169298c2eKostya Serebryany  }
1033c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov  return 0;
1043c80c6c574850106481f82b9e23d1c728458d4a9Timur Iskhodzhanov}
105250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanov
106250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy Stepanovvoid SparcRegisterInfo::
107250f221ae0dee295098da8aa631977b6c2ebc99bEvgeniy StepanoveliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
1080a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov                              MachineBasicBlock::iterator I) const {
1099aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany  MachineInstr &MI = *I;
1109aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany  int Size = MI.getOperand(0).getImmedValue();
1119aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany  if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
1120a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    Size = -Size;
11340e16683f3fdf23dba20d9d0fc2eb00d562cc8dfTimur Iskhodzhanov  if (Size)
1140a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    BuildMI(MBB, I, SP::ADDri, 2, SP::O6).addReg(SP::O6).addImm(Size);
1150a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  MBB.erase(I);
1160a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov}
1170a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov
118bfa45e11e52081c55294355f36fa547f163dcc67Dmitry Vyukovvoid
11940e16683f3fdf23dba20d9d0fc2eb00d562cc8dfTimur IskhodzhanovSparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const {
1200a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  unsigned i = 0;
1210a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  MachineInstr &MI = *II;
1220a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  while (!MI.getOperand(i).isFrameIndex()) {
12315503b0a4331c7f27f9cebc25e25c2e494f61cb9Alexey Samsonov    ++i;
1240a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
1250a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  }
1260a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov
127d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov  int FrameIndex = MI.getOperand(i).getFrameIndex();
128e2462f7461961925f7f20577352c01e867365d8bDmitry Vyukov
129e2462f7461961925f7f20577352c01e867365d8bDmitry Vyukov  // Addressable stack objects are accessed using neg. offsets from %fp
130e2462f7461961925f7f20577352c01e867365d8bDmitry Vyukov  MachineFunction &MF = *MI.getParent()->getParent();
131e2462f7461961925f7f20577352c01e867365d8bDmitry Vyukov  int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
132b1bd208bfa496391085056b1709542b80dcfb21eDmitry Vyukov               MI.getOperand(i+1).getImmedValue();
133bfa45e11e52081c55294355f36fa547f163dcc67Dmitry Vyukov
134d475aa8578f4a1955cdb3e3159eda8b229f8c021Kostya Serebryany  // Replace frame index with a frame pointer reference.
1350a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  if (Offset >= -4096 && Offset <= 4095) {
1367c9ffde46a475d6dd739e977b547c27ac5968976Timur Iskhodzhanov    // If the offset is small enough to fit in the immediate field, directly
1377c9ffde46a475d6dd739e977b547c27ac5968976Timur Iskhodzhanov    // encode it.
1380a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    MI.SetMachineOperandReg(i, SP::I6);
13915503b0a4331c7f27f9cebc25e25c2e494f61cb9Alexey Samsonov    MI.SetMachineOperandConst(i+1, MachineOperand::MO_Immediate, Offset);
1400a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov  } else {
1410a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    // Otherwise, emit a G1 = SETHI %hi(offset).  FIXME: it would be better to
1420a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    // scavenge a register here instead of reserving G1 all of the time.
14397daee89b35f6141db09aee612f0f377f754092fDmitry Vyukov    unsigned OffHi = (unsigned)Offset >> 10U;
1440a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    BuildMI(*MI.getParent(), II, SP::SETHIi, 1, SP::G1).addImm(OffHi);
1450a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov    // Emit G1 = G1 + I6
1462ea978704a794e536d2801affcc7f301092d75daAlexey Samsonov    BuildMI(*MI.getParent(), II, SP::ADDrr, 2,
1470a4c906dbc8f150657ddd4f19a7192b779f1d605Alexey Samsonov            SP::G1).addReg(SP::G1).addReg(SP::I6);
1480c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov    // Insert: G1+%lo(offset) into the user.
1490c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov    MI.SetMachineOperandReg(i, SP::G1);
1500c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov    MI.SetMachineOperandConst(i+1, MachineOperand::MO_Immediate,
1510c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov                              Offset & ((1 << 10)-1));
1520c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov  }
1530c7f61c7f0a6981a1722aea325500ce80dc08a04Dmitry Vyukov}
154e2462f7461961925f7f20577352c01e867365d8bDmitry Vyukov
1559aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryanyvoid SparcRegisterInfo::
1567202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy StepanovprocessFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
1577202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov
1587202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanovvoid SparcRegisterInfo::emitPrologue(MachineFunction &MF) const {
1597202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov  MachineBasicBlock &MBB = MF.front();
1607202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov  MachineFrameInfo *MFI = MF.getFrameInfo();
1617202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov
1627202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov  // Get the number of bytes to allocate from the FrameInfo
1637202e79d5457477b9db24daf0af2c6c7464c3378Evgeniy Stepanov  int NumBytes = (int) MFI->getStackSize();
16430e110edf92303237d471f1cb8e3ad07954fb145Evgeniy Stepanov
165bb19294a1195fb320047bace7732f15e85ac4da5Dmitry Vyukov  // Emit the correct save instruction based on the number of bytes in
166dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  // the frame. Minimum stack frame size according to V8 ABI is:
167dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  //   16 words for register window spill
168dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  //    1 word for address of returned aggregate-value
169dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  // +  6 words for passing parameters on the stack
170dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  // ----------
171dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  //   23 words * 4 bytes per word = 92 bytes
172dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  NumBytes += 92;
173dd3a911e46b3f0416d60d9be5c84ccfc4b1c3aa8Alexey Samsonov  // Round up to next doubleword boundary -- a double-word boundary
1745af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  // is required by the ABI.
1755af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  NumBytes = (NumBytes + 7) & ~7;
1765af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  NumBytes = -NumBytes;
1775af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany
1785af39e50366f1aacbebc284f572f08ad1ad07357Kostya Serebryany  if (NumBytes >= -4096) {
1799aead37421a6e4bf43265e5195c6ac31fc519982Kostya Serebryany    BuildMI(MBB, MBB.begin(), SP::SAVEri, 2,
18015a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov            SP::O6).addImm(NumBytes).addReg(SP::O6);
18115a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  } else {
18215a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    MachineBasicBlock::iterator InsertPt = MBB.begin();
18315a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    // Emit this the hard way.  This clobbers G1 which we always know is
18415a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    // available here.
18515a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    unsigned OffHi = (unsigned)NumBytes >> 10U;
18615a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    BuildMI(MBB, InsertPt, SP::SETHIi, 1, SP::G1).addImm(OffHi);
18715a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov    // Emit G1 = G1 + I6
188230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov    BuildMI(MBB, InsertPt, SP::ORri, 2, SP::G1)
189230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov      .addReg(SP::G1).addImm(NumBytes & ((1 << 10)-1));
190230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov    BuildMI(MBB, InsertPt, SP::SAVErr, 2,
191230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov            SP::O6).addReg(SP::O6).addReg(SP::G1);
192230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov  }
193230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov}
194230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov
195230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonovvoid SparcRegisterInfo::emitEpilogue(MachineFunction &MF,
196230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov                                     MachineBasicBlock &MBB) const {
19715a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  MachineBasicBlock::iterator MBBI = prior(MBB.end());
19815a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  assert(MBBI->getOpcode() == SP::RETL &&
19915a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov         "Can only put epilog before 'retl' instruction!");
20015a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  BuildMI(MBB, MBBI, SP::RESTORErr, 2, SP::G0).addReg(SP::G0).addReg(SP::G0);
20115a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov}
20215a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov
20315a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonovunsigned SparcRegisterInfo::getRARegister() const {
20415a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  assert(0 && "What is the return address register");
20515a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  return 0;
20615a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov}
20715a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov
20815a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonovunsigned SparcRegisterInfo::getFrameRegister(MachineFunction &MF) const {
20915a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  assert(0 && "What is the frame register");
21015a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov  return SP::G1;
21115a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov}
21215a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov
21315a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov#include "SparcGenRegisterInfo.inc"
21415a77612e0a89c1df444a2034e531c8968d0cedfAlexey Samsonov
215fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov