SparcInstrInfo.cpp revision 208599
1254721Semaste//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste// 10254721Semaste// This file contains the Sparc implementation of the TargetInstrInfo class. 11254721Semaste// 12254721Semaste//===----------------------------------------------------------------------===// 13254721Semaste 14254721Semaste#include "SparcInstrInfo.h" 15254721Semaste#include "SparcSubtarget.h" 16254721Semaste#include "Sparc.h" 17254721Semaste#include "llvm/ADT/STLExtras.h" 18254721Semaste#include "llvm/ADT/SmallVector.h" 19254721Semaste#include "llvm/CodeGen/MachineInstrBuilder.h" 20254721Semaste#include "llvm/CodeGen/MachineRegisterInfo.h" 21254721Semaste#include "llvm/Support/ErrorHandling.h" 22254721Semaste#include "SparcGenInstrInfo.inc" 23254721Semaste#include "SparcMachineFunctionInfo.h" 24254721Semasteusing namespace llvm; 25254721Semaste 26254721SemasteSparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 27254721Semaste : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 28254721Semaste RI(ST, *this), Subtarget(ST) { 29254721Semaste} 30254721Semaste 31254721Semastestatic bool isZeroImm(const MachineOperand &op) { 32254721Semaste return op.isImm() && op.getImm() == 0; 33254721Semaste} 34254721Semaste 35254721Semaste/// Return true if the instruction is a register to register move and 36254721Semaste/// leave the source and dest operands in the passed parameters. 37254721Semaste/// 38254721Semastebool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 39254721Semaste unsigned &SrcReg, unsigned &DstReg, 40254721Semaste unsigned &SrcSR, unsigned &DstSR) const { 41254721Semaste SrcSR = DstSR = 0; // No sub-registers. 42254721Semaste 43254721Semaste // We look for 3 kinds of patterns here: 44254721Semaste // or with G0 or 0 45254721Semaste // add with G0 or 0 46254721Semaste // fmovs or FpMOVD (pseudo double move). 47254721Semaste if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 48254721Semaste if (MI.getOperand(1).getReg() == SP::G0) { 49254721Semaste DstReg = MI.getOperand(0).getReg(); 50254721Semaste SrcReg = MI.getOperand(2).getReg(); 51254721Semaste return true; 52254721Semaste } else if (MI.getOperand(2).getReg() == SP::G0) { 53254721Semaste DstReg = MI.getOperand(0).getReg(); 54254721Semaste SrcReg = MI.getOperand(1).getReg(); 55254721Semaste return true; 56254721Semaste } 57254721Semaste } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 58254721Semaste isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) { 59254721Semaste DstReg = MI.getOperand(0).getReg(); 60254721Semaste SrcReg = MI.getOperand(1).getReg(); 61254721Semaste return true; 62254721Semaste } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 63254721Semaste MI.getOpcode() == SP::FMOVD) { 64254721Semaste SrcReg = MI.getOperand(1).getReg(); 65254721Semaste DstReg = MI.getOperand(0).getReg(); 66254721Semaste return true; 67254721Semaste } 68254721Semaste return false; 69254721Semaste} 70254721Semaste 71254721Semaste/// isLoadFromStackSlot - If the specified machine instruction is a direct 72254721Semaste/// load from a stack slot, return the virtual or physical register number of 73254721Semaste/// the destination along with the FrameIndex of the loaded stack slot. If 74254721Semaste/// not, return 0. This predicate must return 0 if the instruction has 75254721Semaste/// any side effects other than loading from the stack slot. 76254721Semasteunsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 77254721Semaste int &FrameIndex) const { 78254721Semaste if (MI->getOpcode() == SP::LDri || 79 MI->getOpcode() == SP::LDFri || 80 MI->getOpcode() == SP::LDDFri) { 81 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 82 MI->getOperand(2).getImm() == 0) { 83 FrameIndex = MI->getOperand(1).getIndex(); 84 return MI->getOperand(0).getReg(); 85 } 86 } 87 return 0; 88} 89 90/// isStoreToStackSlot - If the specified machine instruction is a direct 91/// store to a stack slot, return the virtual or physical register number of 92/// the source reg along with the FrameIndex of the loaded stack slot. If 93/// not, return 0. This predicate must return 0 if the instruction has 94/// any side effects other than storing to the stack slot. 95unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 96 int &FrameIndex) const { 97 if (MI->getOpcode() == SP::STri || 98 MI->getOpcode() == SP::STFri || 99 MI->getOpcode() == SP::STDFri) { 100 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && 101 MI->getOperand(1).getImm() == 0) { 102 FrameIndex = MI->getOperand(0).getIndex(); 103 return MI->getOperand(2).getReg(); 104 } 105 } 106 return 0; 107} 108 109unsigned 110SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 111 MachineBasicBlock *FBB, 112 const SmallVectorImpl<MachineOperand> &Cond)const{ 113 // FIXME this should probably take a DebugLoc argument 114 DebugLoc dl; 115 // Can only insert uncond branches so far. 116 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 117 BuildMI(&MBB, dl, get(SP::BA)).addMBB(TBB); 118 return 1; 119} 120 121bool SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 122 MachineBasicBlock::iterator I, 123 unsigned DestReg, unsigned SrcReg, 124 const TargetRegisterClass *DestRC, 125 const TargetRegisterClass *SrcRC, 126 DebugLoc DL) const { 127 if (DestRC != SrcRC) { 128 // Not yet supported! 129 return false; 130 } 131 132 if (DestRC == SP::IntRegsRegisterClass) 133 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 134 else if (DestRC == SP::FPRegsRegisterClass) 135 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg).addReg(SrcReg); 136 else if (DestRC == SP::DFPRegsRegisterClass) 137 BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 138 .addReg(SrcReg); 139 else 140 // Can't copy this register 141 return false; 142 143 return true; 144} 145 146void SparcInstrInfo:: 147storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 148 unsigned SrcReg, bool isKill, int FI, 149 const TargetRegisterClass *RC, 150 const TargetRegisterInfo *TRI) const { 151 DebugLoc DL; 152 if (I != MBB.end()) DL = I->getDebugLoc(); 153 154 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 155 if (RC == SP::IntRegsRegisterClass) 156 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 157 .addReg(SrcReg, getKillRegState(isKill)); 158 else if (RC == SP::FPRegsRegisterClass) 159 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 160 .addReg(SrcReg, getKillRegState(isKill)); 161 else if (RC == SP::DFPRegsRegisterClass) 162 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 163 .addReg(SrcReg, getKillRegState(isKill)); 164 else 165 llvm_unreachable("Can't store this register to stack slot"); 166} 167 168void SparcInstrInfo:: 169loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 170 unsigned DestReg, int FI, 171 const TargetRegisterClass *RC, 172 const TargetRegisterInfo *TRI) const { 173 DebugLoc DL; 174 if (I != MBB.end()) DL = I->getDebugLoc(); 175 176 if (RC == SP::IntRegsRegisterClass) 177 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 178 else if (RC == SP::FPRegsRegisterClass) 179 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 180 else if (RC == SP::DFPRegsRegisterClass) 181 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 182 else 183 llvm_unreachable("Can't load this register from stack slot"); 184} 185 186MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 187 MachineInstr* MI, 188 const SmallVectorImpl<unsigned> &Ops, 189 int FI) const { 190 if (Ops.size() != 1) return NULL; 191 192 unsigned OpNum = Ops[0]; 193 bool isFloat = false; 194 MachineInstr *NewMI = NULL; 195 switch (MI->getOpcode()) { 196 case SP::ORrr: 197 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 198 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 199 if (OpNum == 0) // COPY -> STORE 200 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::STri)) 201 .addFrameIndex(FI) 202 .addImm(0) 203 .addReg(MI->getOperand(2).getReg()); 204 else // COPY -> LOAD 205 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::LDri), 206 MI->getOperand(0).getReg()) 207 .addFrameIndex(FI) 208 .addImm(0); 209 } 210 break; 211 case SP::FMOVS: 212 isFloat = true; 213 // FALLTHROUGH 214 case SP::FMOVD: 215 if (OpNum == 0) { // COPY -> STORE 216 unsigned SrcReg = MI->getOperand(1).getReg(); 217 bool isKill = MI->getOperand(1).isKill(); 218 bool isUndef = MI->getOperand(1).isUndef(); 219 NewMI = BuildMI(MF, MI->getDebugLoc(), 220 get(isFloat ? SP::STFri : SP::STDFri)) 221 .addFrameIndex(FI) 222 .addImm(0) 223 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)); 224 } else { // COPY -> LOAD 225 unsigned DstReg = MI->getOperand(0).getReg(); 226 bool isDead = MI->getOperand(0).isDead(); 227 bool isUndef = MI->getOperand(0).isUndef(); 228 NewMI = BuildMI(MF, MI->getDebugLoc(), 229 get(isFloat ? SP::LDFri : SP::LDDFri)) 230 .addReg(DstReg, RegState::Define | 231 getDeadRegState(isDead) | getUndefRegState(isUndef)) 232 .addFrameIndex(FI) 233 .addImm(0); 234 } 235 break; 236 } 237 238 return NewMI; 239} 240 241unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const 242{ 243 SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>(); 244 unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg(); 245 if (GlobalBaseReg != 0) 246 return GlobalBaseReg; 247 248 // Insert the set of GlobalBaseReg into the first MBB of the function 249 MachineBasicBlock &FirstMBB = MF->front(); 250 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 251 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 252 253 GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 254 255 256 DebugLoc dl; 257 258 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg); 259 SparcFI->setGlobalBaseReg(GlobalBaseReg); 260 return GlobalBaseReg; 261} 262