SparcInstrInfo.cpp revision 600f171486708734e2b9c9c617528cfc51c16850
16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// The LLVM Compiler Infrastructure 46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// License. See LICENSE.TXT for details. 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//===----------------------------------------------------------------------===// 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This file contains the Sparc implementation of the TargetInstrInfo class. 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SparcInstrInfo.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SparcSubtarget.h" 166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "Sparc.h" 176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/ADT/STLExtras.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "llvm/ADT/SmallVector.h" 196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/CodeGen/MachineRegisterInfo.h" 216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h" 226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcGenInstrInfo.inc" 236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "SparcMachineFunctionInfo.h" 246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)using namespace llvm; 256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RI(ST, *this), Subtarget(ST) { 296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)static bool isZeroImm(const MachineOperand &op) { 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return op.isImm() && op.getImm() == 0; 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// Return true if the instruction is a register to register move and 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// leave the source and dest operands in the passed parameters. 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned &SrcReg, unsigned &DstReg, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsigned &SrcSR, unsigned &DstSR) const { 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SrcSR = DstSR = 0; // No sub-registers. 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // We look for 3 kinds of patterns here: 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // or with G0 or 0 456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // add with G0 or 0 466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // fmovs or FpMOVD (pseudo double move). 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (MI.getOperand(1).getReg() == SP::G0) { 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DstReg = MI.getOperand(0).getReg(); 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SrcReg = MI.getOperand(2).getReg(); 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (MI.getOperand(2).getReg() == SP::G0) { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DstReg = MI.getOperand(0).getReg(); 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SrcReg = MI.getOperand(1).getReg(); 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) { 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SrcReg = MI.getOperand(1).getReg(); 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MI.getOpcode() == SP::FMOVD) { 646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) SrcReg = MI.getOperand(1).getReg(); 656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return true; 676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return false; 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// isLoadFromStackSlot - If the specified machine instruction is a direct 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// load from a stack slot, return the virtual or physical register number of 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// the destination along with the FrameIndex of the loaded stack slot. If 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// not, return 0. This predicate must return 0 if the instruction has 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// any side effects other than loading from the stack slot. 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int &FrameIndex) const { 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (MI->getOpcode() == SP::LDri || 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MI->getOpcode() == SP::LDFri || 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MI->getOpcode() == SP::LDDFri) { 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MI->getOperand(2).getImm() == 0) { 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FrameIndex = MI->getOperand(1).getIndex(); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return MI->getOperand(0).getReg(); 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// isStoreToStackSlot - If the specified machine instruction is a direct 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci/// store to a stack slot, return the virtual or physical register number of 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// the source reg along with the FrameIndex of the loaded stack slot. If 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// not, return 0. This predicate must return 0 if the instruction has 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)/// any side effects other than storing to the stack slot. 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciunsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int &FrameIndex) const { 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (MI->getOpcode() == SP::STri || 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MI->getOpcode() == SP::STFri || 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MI->getOpcode() == SP::STDFri) { 1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && 1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MI->getOperand(1).getImm() == 0) { 1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) FrameIndex = MI->getOperand(0).getIndex(); 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return MI->getOperand(2).getReg(); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return 0; 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)unsigned 1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, 1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MachineBasicBlock *FBB, 1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const SmallVectorImpl<MachineOperand> &Cond, 1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DebugLoc DL)const{ 1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Can only insert uncond branches so far. 1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!"); 1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB); 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return 1; 1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MachineBasicBlock::iterator I, DebugLoc DL, 1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned DestReg, unsigned SrcReg, 1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) bool KillSrc) const { 1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (SP::IntRegsRegClass.contains(DestReg, SrcReg)) 1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0) 1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) .addReg(SrcReg, getKillRegState(KillSrc)); 1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else if (SP::FPRegsRegClass.contains(DestReg, SrcReg)) 1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg) 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci .addReg(SrcReg, getKillRegState(KillSrc)); 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) 1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg) 1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) .addReg(SrcReg, getKillRegState(KillSrc)); 1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) llvm_unreachable("Impossible reg-to-reg copy"); 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)} 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void SparcInstrInfo:: 1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) unsigned SrcReg, bool isKill, int FI, 1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const TargetRegisterClass *RC, 1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const TargetRegisterInfo *TRI) const { 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DebugLoc DL; 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (I != MBB.end()) DL = I->getDebugLoc(); 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 145 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 146 if (RC == SP::IntRegsRegisterClass) 147 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 148 .addReg(SrcReg, getKillRegState(isKill)); 149 else if (RC == SP::FPRegsRegisterClass) 150 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 151 .addReg(SrcReg, getKillRegState(isKill)); 152 else if (RC == SP::DFPRegsRegisterClass) 153 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 154 .addReg(SrcReg, getKillRegState(isKill)); 155 else 156 llvm_unreachable("Can't store this register to stack slot"); 157} 158 159void SparcInstrInfo:: 160loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 161 unsigned DestReg, int FI, 162 const TargetRegisterClass *RC, 163 const TargetRegisterInfo *TRI) const { 164 DebugLoc DL; 165 if (I != MBB.end()) DL = I->getDebugLoc(); 166 167 if (RC == SP::IntRegsRegisterClass) 168 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 169 else if (RC == SP::FPRegsRegisterClass) 170 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 171 else if (RC == SP::DFPRegsRegisterClass) 172 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 173 else 174 llvm_unreachable("Can't load this register from stack slot"); 175} 176 177unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const 178{ 179 SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>(); 180 unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg(); 181 if (GlobalBaseReg != 0) 182 return GlobalBaseReg; 183 184 // Insert the set of GlobalBaseReg into the first MBB of the function 185 MachineBasicBlock &FirstMBB = MF->front(); 186 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 187 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 188 189 GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 190 191 192 DebugLoc dl; 193 194 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg); 195 SparcFI->setGlobalBaseReg(GlobalBaseReg); 196 return GlobalBaseReg; 197} 198