LLVM API Documentation
00001 //===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the Sparc implementation of the TargetInstrInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "SparcInstrInfo.h" 00015 #include "SparcSubtarget.h" 00016 #include "Sparc.h" 00017 #include "llvm/ADT/STLExtras.h" 00018 #include "llvm/ADT/SmallVector.h" 00019 #include "llvm/CodeGen/MachineInstrBuilder.h" 00020 #include "SparcGenInstrInfo.inc" 00021 using namespace llvm; 00022 00023 SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 00024 : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 00025 RI(ST, *this), Subtarget(ST) { 00026 } 00027 00028 static bool isZeroImm(const MachineOperand &op) { 00029 return op.isImm() && op.getImm() == 0; 00030 } 00031 00032 /// Return true if the instruction is a register to register move and 00033 /// leave the source and dest operands in the passed parameters. 00034 /// 00035 bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 00036 unsigned &SrcReg, unsigned &DstReg, 00037 unsigned &SrcSR, unsigned &DstSR) const { 00038 SrcSR = DstSR = 0; // No sub-registers. 00039 00040 // We look for 3 kinds of patterns here: 00041 // or with G0 or 0 00042 // add with G0 or 0 00043 // fmovs or FpMOVD (pseudo double move). 00044 if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 00045 if (MI.getOperand(1).getReg() == SP::G0) { 00046 DstReg = MI.getOperand(0).getReg(); 00047 SrcReg = MI.getOperand(2).getReg(); 00048 return true; 00049 } else if (MI.getOperand(2).getReg() == SP::G0) { 00050 DstReg = MI.getOperand(0).getReg(); 00051 SrcReg = MI.getOperand(1).getReg(); 00052 return true; 00053 } 00054 } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 00055 isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) { 00056 DstReg = MI.getOperand(0).getReg(); 00057 SrcReg = MI.getOperand(1).getReg(); 00058 return true; 00059 } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 00060 MI.getOpcode() == SP::FMOVD) { 00061 SrcReg = MI.getOperand(1).getReg(); 00062 DstReg = MI.getOperand(0).getReg(); 00063 return true; 00064 } 00065 return false; 00066 } 00067 00068 /// isLoadFromStackSlot - If the specified machine instruction is a direct 00069 /// load from a stack slot, return the virtual or physical register number of 00070 /// the destination along with the FrameIndex of the loaded stack slot. If 00071 /// not, return 0. This predicate must return 0 if the instruction has 00072 /// any side effects other than loading from the stack slot. 00073 unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 00074 int &FrameIndex) const { 00075 if (MI->getOpcode() == SP::LDri || 00076 MI->getOpcode() == SP::LDFri || 00077 MI->getOpcode() == SP::LDDFri) { 00078 if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 00079 MI->getOperand(2).getImm() == 0) { 00080 FrameIndex = MI->getOperand(1).getIndex(); 00081 return MI->getOperand(0).getReg(); 00082 } 00083 } 00084 return 0; 00085 } 00086 00087 /// isStoreToStackSlot - If the specified machine instruction is a direct 00088 /// store to a stack slot, return the virtual or physical register number of 00089 /// the source reg along with the FrameIndex of the loaded stack slot. If 00090 /// not, return 0. This predicate must return 0 if the instruction has 00091 /// any side effects other than storing to the stack slot. 00092 unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 00093 int &FrameIndex) const { 00094 if (MI->getOpcode() == SP::STri || 00095 MI->getOpcode() == SP::STFri || 00096 MI->getOpcode() == SP::STDFri) { 00097 if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && 00098 MI->getOperand(1).getImm() == 0) { 00099 FrameIndex = MI->getOperand(0).getIndex(); 00100 return MI->getOperand(2).getReg(); 00101 } 00102 } 00103 return 0; 00104 } 00105 00106 unsigned 00107 SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 00108 MachineBasicBlock *FBB, 00109 const SmallVectorImpl<MachineOperand> &Cond)const{ 00110 // Can only insert uncond branches so far. 00111 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 00112 BuildMI(&MBB, get(SP::BA)).addMBB(TBB); 00113 return 1; 00114 } 00115 00116 bool SparcInstrInfo::copyRegToReg(MachineBasicBlock &MBB, 00117 MachineBasicBlock::iterator I, 00118 unsigned DestReg, unsigned SrcReg, 00119 const TargetRegisterClass *DestRC, 00120 const TargetRegisterClass *SrcRC) const { 00121 if (DestRC != SrcRC) { 00122 // Not yet supported! 00123 return false; 00124 } 00125 00126 if (DestRC == SP::IntRegsRegisterClass) 00127 BuildMI(MBB, I, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 00128 else if (DestRC == SP::FPRegsRegisterClass) 00129 BuildMI(MBB, I, get(SP::FMOVS), DestReg).addReg(SrcReg); 00130 else if (DestRC == SP::DFPRegsRegisterClass) 00131 BuildMI(MBB, I, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 00132 .addReg(SrcReg); 00133 else 00134 // Can't copy this register 00135 return false; 00136 00137 return true; 00138 } 00139 00140 void SparcInstrInfo:: 00141 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00142 unsigned SrcReg, bool isKill, int FI, 00143 const TargetRegisterClass *RC) const { 00144 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 00145 if (RC == SP::IntRegsRegisterClass) 00146 BuildMI(MBB, I, get(SP::STri)).addFrameIndex(FI).addImm(0) 00147 .addReg(SrcReg, false, false, isKill); 00148 else if (RC == SP::FPRegsRegisterClass) 00149 BuildMI(MBB, I, get(SP::STFri)).addFrameIndex(FI).addImm(0) 00150 .addReg(SrcReg, false, false, isKill); 00151 else if (RC == SP::DFPRegsRegisterClass) 00152 BuildMI(MBB, I, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 00153 .addReg(SrcReg, false, false, isKill); 00154 else 00155 assert(0 && "Can't store this register to stack slot"); 00156 } 00157 00158 void SparcInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, 00159 bool isKill, 00160 SmallVectorImpl<MachineOperand> &Addr, 00161 const TargetRegisterClass *RC, 00162 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00163 unsigned Opc = 0; 00164 if (RC == SP::IntRegsRegisterClass) 00165 Opc = SP::STri; 00166 else if (RC == SP::FPRegsRegisterClass) 00167 Opc = SP::STFri; 00168 else if (RC == SP::DFPRegsRegisterClass) 00169 Opc = SP::STDFri; 00170 else 00171 assert(0 && "Can't load this register"); 00172 MachineInstrBuilder MIB = BuildMI(MF, get(Opc)); 00173 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 00174 MachineOperand &MO = Addr[i]; 00175 if (MO.isReg()) 00176 MIB.addReg(MO.getReg()); 00177 else if (MO.isImm()) 00178 MIB.addImm(MO.getImm()); 00179 else { 00180 assert(MO.isFI()); 00181 MIB.addFrameIndex(MO.getIndex()); 00182 } 00183 } 00184 MIB.addReg(SrcReg, false, false, isKill); 00185 NewMIs.push_back(MIB); 00186 return; 00187 } 00188 00189 void SparcInstrInfo:: 00190 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 00191 unsigned DestReg, int FI, 00192 const TargetRegisterClass *RC) const { 00193 if (RC == SP::IntRegsRegisterClass) 00194 BuildMI(MBB, I, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 00195 else if (RC == SP::FPRegsRegisterClass) 00196 BuildMI(MBB, I, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 00197 else if (RC == SP::DFPRegsRegisterClass) 00198 BuildMI(MBB, I, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 00199 else 00200 assert(0 && "Can't load this register from stack slot"); 00201 } 00202 00203 void SparcInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, 00204 SmallVectorImpl<MachineOperand> &Addr, 00205 const TargetRegisterClass *RC, 00206 SmallVectorImpl<MachineInstr*> &NewMIs) const { 00207 unsigned Opc = 0; 00208 if (RC == SP::IntRegsRegisterClass) 00209 Opc = SP::LDri; 00210 else if (RC == SP::FPRegsRegisterClass) 00211 Opc = SP::LDFri; 00212 else if (RC == SP::DFPRegsRegisterClass) 00213 Opc = SP::LDDFri; 00214 else 00215 assert(0 && "Can't load this register"); 00216 MachineInstrBuilder MIB = BuildMI(MF, get(Opc), DestReg); 00217 for (unsigned i = 0, e = Addr.size(); i != e; ++i) { 00218 MachineOperand &MO = Addr[i]; 00219 if (MO.isReg()) 00220 MIB.addReg(MO.getReg()); 00221 else if (MO.isImm()) 00222 MIB.addImm(MO.getImm()); 00223 else { 00224 assert(MO.isFI()); 00225 MIB.addFrameIndex(MO.getIndex()); 00226 } 00227 } 00228 NewMIs.push_back(MIB); 00229 return; 00230 } 00231 00232 MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 00233 MachineInstr* MI, 00234 const SmallVectorImpl<unsigned> &Ops, 00235 int FI) const { 00236 if (Ops.size() != 1) return NULL; 00237 00238 unsigned OpNum = Ops[0]; 00239 bool isFloat = false; 00240 MachineInstr *NewMI = NULL; 00241 switch (MI->getOpcode()) { 00242 case SP::ORrr: 00243 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 00244 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 00245 if (OpNum == 0) // COPY -> STORE 00246 NewMI = BuildMI(MF, get(SP::STri)).addFrameIndex(FI).addImm(0) 00247 .addReg(MI->getOperand(2).getReg()); 00248 else // COPY -> LOAD 00249 NewMI = BuildMI(MF, get(SP::LDri), MI->getOperand(0).getReg()) 00250 .addFrameIndex(FI).addImm(0); 00251 } 00252 break; 00253 case SP::FMOVS: 00254 isFloat = true; 00255 // FALLTHROUGH 00256 case SP::FMOVD: 00257 if (OpNum == 0) { // COPY -> STORE 00258 unsigned SrcReg = MI->getOperand(1).getReg(); 00259 bool isKill = MI->getOperand(1).isKill(); 00260 NewMI = BuildMI(MF, get(isFloat ? SP::STFri : SP::STDFri)) 00261 .addFrameIndex(FI).addImm(0).addReg(SrcReg, false, false, isKill); 00262 } else { // COPY -> LOAD 00263 unsigned DstReg = MI->getOperand(0).getReg(); 00264 bool isDead = MI->getOperand(0).isDead(); 00265 NewMI = BuildMI(MF, get(isFloat ? SP::LDFri : SP::LDDFri)) 00266 .addReg(DstReg, true, false, false, isDead).addFrameIndex(FI).addImm(0); 00267 } 00268 break; 00269 } 00270 00271 return NewMI; 00272 }