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