SparcInstrInfo.cpp revision 9f1c8317a4676945b4961ddb9827ef2412551620
1//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Sparc implementation of the TargetInstrInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "SparcInstrInfo.h" 15#include "SparcSubtarget.h" 16#include "Sparc.h" 17#include "llvm/ADT/STLExtras.h" 18#include "llvm/CodeGen/MachineInstrBuilder.h" 19#include "SparcGenInstrInfo.inc" 20using namespace llvm; 21 22SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 23 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 24 RI(ST, *this), Subtarget(ST) { 25} 26 27static bool isZeroImm(const MachineOperand &op) { 28 return op.isImmediate() && op.getImm() == 0; 29} 30 31/// Return true if the instruction is a register to register move and 32/// leave the source and dest operands in the passed parameters. 33/// 34bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 35 unsigned &SrcReg, unsigned &DstReg) const { 36 // We look for 3 kinds of patterns here: 37 // or with G0 or 0 38 // add with G0 or 0 39 // fmovs or FpMOVD (pseudo double move). 40 if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 41 if (MI.getOperand(1).getReg() == SP::G0) { 42 DstReg = MI.getOperand(0).getReg(); 43 SrcReg = MI.getOperand(2).getReg(); 44 return true; 45 } else if (MI.getOperand(2).getReg() == SP::G0) { 46 DstReg = MI.getOperand(0).getReg(); 47 SrcReg = MI.getOperand(1).getReg(); 48 return true; 49 } 50 } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 51 isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isRegister()) { 52 DstReg = MI.getOperand(0).getReg(); 53 SrcReg = MI.getOperand(1).getReg(); 54 return true; 55 } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 56 MI.getOpcode() == SP::FMOVD) { 57 SrcReg = MI.getOperand(1).getReg(); 58 DstReg = MI.getOperand(0).getReg(); 59 return true; 60 } 61 return false; 62} 63 64/// isLoadFromStackSlot - If the specified machine instruction is a direct 65/// load from a stack slot, return the virtual or physical register number of 66/// the destination along with the FrameIndex of the loaded stack slot. If 67/// not, return 0. This predicate must return 0 if the instruction has 68/// any side effects other than loading from the stack slot. 69unsigned SparcInstrInfo::isLoadFromStackSlot(MachineInstr *MI, 70 int &FrameIndex) const { 71 if (MI->getOpcode() == SP::LDri || 72 MI->getOpcode() == SP::LDFri || 73 MI->getOpcode() == SP::LDDFri) { 74 if (MI->getOperand(1).isFrameIndex() && MI->getOperand(2).isImmediate() && 75 MI->getOperand(2).getImm() == 0) { 76 FrameIndex = MI->getOperand(1).getIndex(); 77 return MI->getOperand(0).getReg(); 78 } 79 } 80 return 0; 81} 82 83/// isStoreToStackSlot - If the specified machine instruction is a direct 84/// store to a stack slot, return the virtual or physical register number of 85/// the source reg along with the FrameIndex of the loaded stack slot. If 86/// not, return 0. This predicate must return 0 if the instruction has 87/// any side effects other than storing to the stack slot. 88unsigned SparcInstrInfo::isStoreToStackSlot(MachineInstr *MI, 89 int &FrameIndex) const { 90 if (MI->getOpcode() == SP::STri || 91 MI->getOpcode() == SP::STFri || 92 MI->getOpcode() == SP::STDFri) { 93 if (MI->getOperand(0).isFrameIndex() && MI->getOperand(1).isImmediate() && 94 MI->getOperand(1).getImm() == 0) { 95 FrameIndex = MI->getOperand(0).getIndex(); 96 return MI->getOperand(2).getReg(); 97 } 98 } 99 return 0; 100} 101 102unsigned 103SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 104 MachineBasicBlock *FBB, 105 const std::vector<MachineOperand> &Cond)const{ 106 // Can only insert uncond branches so far. 107 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 108 BuildMI(&MBB, get(SP::BA)).addMBB(TBB); 109 return 1; 110} 111 112void SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 113 MachineBasicBlock::iterator I, 114 unsigned DestReg, unsigned SrcReg, 115 const TargetRegisterClass *DestRC, 116 const TargetRegisterClass *SrcRC) const { 117 if (DestRC != SrcRC) { 118 cerr << "Not yet supported!"; 119 abort(); 120 } 121 122 if (DestRC == SP::IntRegsRegisterClass) 123 BuildMI(MBB, I, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 124 else if (DestRC == SP::FPRegsRegisterClass) 125 BuildMI(MBB, I, get(SP::FMOVS), DestReg).addReg(SrcReg); 126 else if (DestRC == SP::DFPRegsRegisterClass) 127 BuildMI(MBB, I, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 128 .addReg(SrcReg); 129 else 130 assert (0 && "Can't copy this register"); 131} 132 133void SparcInstrInfo:: 134storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 135 unsigned SrcReg, bool isKill, int FI, 136 const TargetRegisterClass *RC) const { 137 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 138 if (RC == SP::IntRegsRegisterClass) 139 BuildMI(MBB, I, get(SP::STri)).addFrameIndex(FI).addImm(0) 140 .addReg(SrcReg, false, false, isKill); 141 else if (RC == SP::FPRegsRegisterClass) 142 BuildMI(MBB, I, get(SP::STFri)).addFrameIndex(FI).addImm(0) 143 .addReg(SrcReg, false, false, isKill); 144 else if (RC == SP::DFPRegsRegisterClass) 145 BuildMI(MBB, I, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 146 .addReg(SrcReg, false, false, isKill); 147 else 148 assert(0 && "Can't store this register to stack slot"); 149} 150 151void SparcInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 152 bool isKill, 153 SmallVectorImpl<MachineOperand> &Addr, 154 const TargetRegisterClass *RC, 155 SmallVectorImpl<MachineInstr*> &NewMIs) const { 156 unsigned Opc = 0; 157 if (RC == SP::IntRegsRegisterClass) 158 Opc = SP::STri; 159 else if (RC == SP::FPRegsRegisterClass) 160 Opc = SP::STFri; 161 else if (RC == SP::DFPRegsRegisterClass) 162 Opc = SP::STDFri; 163 else 164 assert(0 && "Can't load this register"); 165 MachineInstrBuilder MIB = BuildMI(get(Opc)); 166 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 167 MachineOperand &MO = Addr[i]; 168 if (MO.isRegister()) 169 MIB.addReg(MO.getReg()); 170 else if (MO.isImmediate()) 171 MIB.addImm(MO.getImm()); 172 else { 173 assert(MO.isFI()); 174 MIB.addFrameIndex(MO.getIndex()); 175 } 176 } 177 MIB.addReg(SrcReg, false, false, isKill); 178 NewMIs.push_back(MIB); 179 return; 180} 181 182void SparcInstrInfo:: 183loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 184 unsigned DestReg, int FI, 185 const TargetRegisterClass *RC) const { 186 if (RC == SP::IntRegsRegisterClass) 187 BuildMI(MBB, I, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 188 else if (RC == SP::FPRegsRegisterClass) 189 BuildMI(MBB, I, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 190 else if (RC == SP::DFPRegsRegisterClass) 191 BuildMI(MBB, I, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 192 else 193 assert(0 && "Can't load this register from stack slot"); 194} 195 196void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 197 SmallVectorImpl<MachineOperand> &Addr, 198 const TargetRegisterClass *RC, 199 SmallVectorImpl<MachineInstr*> &NewMIs) const { 200 unsigned Opc = 0; 201 if (RC == SP::IntRegsRegisterClass) 202 Opc = SP::LDri; 203 else if (RC == SP::FPRegsRegisterClass) 204 Opc = SP::LDFri; 205 else if (RC == SP::DFPRegsRegisterClass) 206 Opc = SP::LDDFri; 207 else 208 assert(0 && "Can't load this register"); 209 MachineInstrBuilder MIB = BuildMI(get(Opc), DestReg); 210 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 211 MachineOperand &MO = Addr[i]; 212 if (MO.isReg()) 213 MIB.addReg(MO.getReg()); 214 else if (MO.isImm()) 215 MIB.addImm(MO.getImm()); 216 else { 217 assert(MO.isFI()); 218 MIB.addFrameIndex(MO.getIndex()); 219 } 220 } 221 NewMIs.push_back(MIB); 222 return; 223} 224 225MachineInstr *SparcInstrInfo::foldMemoryOperand(MachineFunction &MF, 226 MachineInstr* MI, 227 SmallVectorImpl<unsigned> &Ops, 228 int FI) const { 229 if (Ops.size() != 1) return NULL; 230 231 unsigned OpNum = Ops[0]; 232 bool isFloat = false; 233 MachineInstr *NewMI = NULL; 234 switch (MI->getOpcode()) { 235 case SP::ORrr: 236 if (MI->getOperand(1).isRegister() && MI->getOperand(1).getReg() == SP::G0&& 237 MI->getOperand(0).isRegister() && MI->getOperand(2).isRegister()) { 238 if (OpNum == 0) // COPY -> STORE 239 NewMI = BuildMI(get(SP::STri)).addFrameIndex(FI).addImm(0) 240 .addReg(MI->getOperand(2).getReg()); 241 else // COPY -> LOAD 242 NewMI = BuildMI(get(SP::LDri), MI->getOperand(0).getReg()) 243 .addFrameIndex(FI).addImm(0); 244 } 245 break; 246 case SP::FMOVS: 247 isFloat = true; 248 // FALLTHROUGH 249 case SP::FMOVD: 250 if (OpNum == 0) { // COPY -> STORE 251 unsigned SrcReg = MI->getOperand(1).getReg(); 252 bool isKill = MI->getOperand(1).isKill(); 253 NewMI = BuildMI(get(isFloat ? SP::STFri : SP::STDFri)) 254 .addFrameIndex(FI).addImm(0).addReg(SrcReg, false, false, isKill); 255 } else { // COPY -> LOAD 256 unsigned DstReg = MI->getOperand(0).getReg(); 257 bool isDead = MI->getOperand(0).isDead(); 258 NewMI = BuildMI(get(isFloat ? SP::LDFri : SP::LDDFri)) 259 .addReg(DstReg, true, false, false, isDead).addFrameIndex(FI).addImm(0); 260 } 261 break; 262 } 263 264 return NewMI; 265} 266