SparcRegisterInfo.cpp revision 171049d10f71fdeffdfd9592243d7af40db86c71
1//===- SparcV8RegisterInfo.cpp - SparcV8 Register Information ---*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the SparcV8 implementation of the MRegisterInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "SparcV8.h" 15#include "SparcV8RegisterInfo.h" 16#include "llvm/CodeGen/MachineInstrBuilder.h" 17#include "llvm/CodeGen/MachineFunction.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/Type.h" 20#include "llvm/ADT/STLExtras.h" 21#include <iostream> 22using namespace llvm; 23 24SparcV8RegisterInfo::SparcV8RegisterInfo() 25 : SparcV8GenRegisterInfo(V8::ADJCALLSTACKDOWN, 26 V8::ADJCALLSTACKUP) {} 27 28void SparcV8RegisterInfo:: 29storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 30 unsigned SrcReg, int FrameIdx, 31 const TargetRegisterClass *RC) const { 32 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 33 if (RC == V8::IntRegsRegisterClass) 34 BuildMI (MBB, I, V8::STri, 3).addFrameIndex (FrameIdx).addSImm (0) 35 .addReg (SrcReg); 36 else if (RC == V8::FPRegsRegisterClass) 37 BuildMI (MBB, I, V8::STFri, 3).addFrameIndex (FrameIdx).addSImm (0) 38 .addReg (SrcReg); 39 else if (RC == V8::DFPRegsRegisterClass) 40 BuildMI (MBB, I, V8::STDFri, 3).addFrameIndex (FrameIdx).addSImm (0) 41 .addReg (SrcReg); 42 else 43 assert (0 && "Can't store this register to stack slot"); 44} 45 46void SparcV8RegisterInfo:: 47loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 48 unsigned DestReg, int FrameIdx, 49 const TargetRegisterClass *RC) const { 50 if (RC == V8::IntRegsRegisterClass) 51 BuildMI (MBB, I, V8::LDri, 2, DestReg).addFrameIndex (FrameIdx).addSImm (0); 52 else if (RC == V8::FPRegsRegisterClass) 53 BuildMI (MBB, I, V8::LDFri, 2, DestReg).addFrameIndex (FrameIdx) 54 .addSImm (0); 55 else if (RC == V8::DFPRegsRegisterClass) 56 BuildMI (MBB, I, V8::LDDFri, 2, DestReg).addFrameIndex (FrameIdx) 57 .addSImm (0); 58 else 59 assert(0 && "Can't load this register from stack slot"); 60} 61 62void SparcV8RegisterInfo::copyRegToReg(MachineBasicBlock &MBB, 63 MachineBasicBlock::iterator I, 64 unsigned DestReg, unsigned SrcReg, 65 const TargetRegisterClass *RC) const { 66 if (RC == V8::IntRegsRegisterClass) 67 BuildMI (MBB, I, V8::ORrr, 2, DestReg).addReg (V8::G0).addReg (SrcReg); 68 else if (RC == V8::FPRegsRegisterClass) 69 BuildMI (MBB, I, V8::FMOVS, 1, DestReg).addReg (SrcReg); 70 else if (RC == V8::DFPRegsRegisterClass) 71 BuildMI (MBB, I, V8::FpMOVD, 1, DestReg).addReg (SrcReg); 72 else 73 assert (0 && "Can't copy this register"); 74} 75 76void SparcV8RegisterInfo:: 77eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 78 MachineBasicBlock::iterator I) const { 79 MachineInstr &MI = *I; 80 int Size = MI.getOperand(0).getImmedValue(); 81 if (MI.getOpcode() == V8::ADJCALLSTACKDOWN) 82 Size = -Size; 83 if (Size) 84 BuildMI(MBB, I, V8::ADDri, 2, V8::O6).addReg(V8::O6).addSImm(Size); 85 MBB.erase(I); 86} 87 88void 89SparcV8RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const { 90 unsigned i = 0; 91 MachineInstr &MI = *II; 92 while (!MI.getOperand(i).isFrameIndex()) { 93 ++i; 94 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 95 } 96 97 int FrameIndex = MI.getOperand(i).getFrameIndex(); 98 99 // Addressable stack objects are accessed using neg. offsets from %fp 100 MachineFunction &MF = *MI.getParent()->getParent(); 101 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 102 MI.getOperand(i+1).getImmedValue(); 103 104 // Replace frame index with a frame pointer reference. 105 if (Offset >= -4096 && Offset <= 4095) { 106 // If the offset is small enough to fit in the immediate field, directly 107 // encode it. 108 MI.SetMachineOperandReg(i, V8::I6); 109 MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,Offset); 110 } else { 111 // Otherwise, emit a G1 = SETHI %hi(offset). FIXME: it would be better to 112 // scavenge a register here instead of reserving G1 all of the time. 113 unsigned OffHi = (unsigned)Offset >> 10U; 114 BuildMI(*MI.getParent(), II, V8::SETHIi, 1, V8::G1).addImm(OffHi); 115 // Emit G1 = G1 + I6 116 BuildMI(*MI.getParent(), II, V8::ADDrr, 2, 117 V8::G1).addReg(V8::G1).addReg(V8::I6); 118 // Insert: G1+%lo(offset) into the user. 119 MI.SetMachineOperandReg(i, V8::I1); 120 MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed, 121 Offset & ((1 << 10)-1)); 122 } 123} 124 125void SparcV8RegisterInfo:: 126processFunctionBeforeFrameFinalized(MachineFunction &MF) const {} 127 128void SparcV8RegisterInfo::emitPrologue(MachineFunction &MF) const { 129 MachineBasicBlock &MBB = MF.front(); 130 MachineFrameInfo *MFI = MF.getFrameInfo(); 131 132 // Get the number of bytes to allocate from the FrameInfo 133 int NumBytes = (int) MFI->getStackSize(); 134 135 // Emit the correct save instruction based on the number of bytes in 136 // the frame. Minimum stack frame size according to V8 ABI is: 137 // 16 words for register window spill 138 // 1 word for address of returned aggregate-value 139 // + 6 words for passing parameters on the stack 140 // ---------- 141 // 23 words * 4 bytes per word = 92 bytes 142 NumBytes += 92; 143 // Round up to next doubleword boundary -- a double-word boundary 144 // is required by the ABI. 145 NumBytes = (NumBytes + 7) & ~7; 146 NumBytes = -NumBytes; 147 148 if (NumBytes >= -4096) { 149 BuildMI(MBB, MBB.begin(), V8::SAVEri, 2, 150 V8::O6).addImm(NumBytes).addReg(V8::O6); 151 } else { 152 MachineBasicBlock::iterator InsertPt = MBB.begin(); 153 // Emit this the hard way. This clobbers G1 which we always know is 154 // available here. 155 unsigned OffHi = (unsigned)NumBytes >> 10U; 156 BuildMI(MBB, InsertPt, V8::SETHIi, 1, V8::G1).addImm(OffHi); 157 // Emit G1 = G1 + I6 158 BuildMI(MBB, InsertPt, V8::ORri, 2, V8::G1) 159 .addReg(V8::G1).addImm(NumBytes & ((1 << 10)-1)); 160 BuildMI(MBB, InsertPt, V8::SAVErr, 2, 161 V8::O6).addReg(V8::O6).addReg(V8::G1); 162 } 163} 164 165void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF, 166 MachineBasicBlock &MBB) const { 167 MachineBasicBlock::iterator MBBI = prior(MBB.end()); 168 // FIXME: RETVOID should be removed. See SparcV8InstrInfo.td 169 assert((MBBI->getOpcode() == V8::RETL || MBBI->getOpcode() == V8::RETVOID) && 170 "Can only put epilog before 'retl' instruction!"); 171 BuildMI(MBB, MBBI, V8::RESTORErr, 2, V8::G0).addReg(V8::G0).addReg(V8::G0); 172} 173 174#include "SparcV8GenRegisterInfo.inc" 175 176const TargetRegisterClass* 177SparcV8RegisterInfo::getRegClassForType(const Type* Ty) const { 178 switch (Ty->getTypeID()) { 179 case Type::FloatTyID: return V8::FPRegsRegisterClass; 180 case Type::DoubleTyID: return V8::DFPRegsRegisterClass; 181 case Type::LongTyID: 182 case Type::ULongTyID: assert(0 && "Long values do not fit in registers!"); 183 default: assert(0 && "Invalid type to getClass!"); 184 case Type::BoolTyID: 185 case Type::SByteTyID: 186 case Type::UByteTyID: 187 case Type::ShortTyID: 188 case Type::UShortTyID: 189 case Type::IntTyID: 190 case Type::UIntTyID: 191 case Type::PointerTyID: return V8::IntRegsRegisterClass; 192 } 193} 194 195