SparcInstrInfo.cpp revision 746ad69e088176819981b4b2c5ac8dcd49f5e60e
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===// 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The LLVM Compiler Infrastructure 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// License. See LICENSE.TXT for details. 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===// 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This file contains the Sparc implementation of the TargetInstrInfo class. 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//===----------------------------------------------------------------------===// 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "SparcInstrInfo.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "SparcSubtarget.h" 163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "Sparc.h" 17ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "llvm/ADT/STLExtras.h" 18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "llvm/ADT/SmallVector.h" 19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "llvm/CodeGen/MachineInstrBuilder.h" 20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "llvm/CodeGen/MachineRegisterInfo.h" 21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "llvm/Support/ErrorHandling.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "SparcGenInstrInfo.inc" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "SparcMachineFunctionInfo.h" 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using namespace llvm; 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 26ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochSparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) 27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)), 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RI(ST, *this), Subtarget(ST) { 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic bool isZeroImm(const MachineOperand &op) { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return op.isImm() && op.getImm() == 0; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// Return true if the instruction is a register to register move and 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// leave the source and dest operands in the passed parameters. 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/// 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI, 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned &SrcReg, unsigned &DstReg, 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned &SrcSR, unsigned &DstSR) const { 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SrcSR = DstSR = 0; // No sub-registers. 42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // We look for 3 kinds of patterns here: 44ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch // or with G0 or 0 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // add with G0 or 0 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // fmovs or FpMOVD (pseudo double move). 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (MI.getOpcode() == SP::ORrr || MI.getOpcode() == SP::ADDrr) { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (MI.getOperand(1).getReg() == SP::G0) { 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SrcReg = MI.getOperand(2).getReg(); 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (MI.getOperand(2).getReg() == SP::G0) { 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SrcReg = MI.getOperand(1).getReg(); 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if ((MI.getOpcode() == SP::ORri || MI.getOpcode() == SP::ADDri) && 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) isZeroImm(MI.getOperand(2)) && MI.getOperand(1).isReg()) { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SrcReg = MI.getOperand(1).getReg(); 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (MI.getOpcode() == SP::FMOVS || MI.getOpcode() == SP::FpMOVD || 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MI.getOpcode() == SP::FMOVD) { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SrcReg = MI.getOperand(1).getReg(); 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DstReg = MI.getOperand(0).getReg(); 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/// isLoadFromStackSlot - If the specified machine instruction is a direct 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch/// load from a stack slot, return the virtual or physical register number of 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch/// the destination along with the FrameIndex of the loaded stack slot. If 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/// not, return 0. This predicate must return 0 if the instruction has 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/// any side effects other than loading from the stack slot. 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int &FrameIndex) const { 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (MI->getOpcode() == SP::LDri || 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MI->getOpcode() == SP::LDFri || 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MI->getOpcode() == SP::LDDFri) { 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) MI->getOperand(2).getImm() == 0) { 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) FrameIndex = MI->getOperand(1).getIndex(); 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return MI->getOperand(0).getReg(); 85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return 0; 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/// isStoreToStackSlot - If the specified machine instruction is a direct 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)/// store to a stack slot, return the virtual or physical register number of 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/// 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) const { 126 if (DestRC != SrcRC) { 127 // Not yet supported! 128 return false; 129 } 130 131 DebugLoc DL; 132 if (I != MBB.end()) DL = I->getDebugLoc(); 133 134 if (DestRC == SP::IntRegsRegisterClass) 135 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0).addReg(SrcReg); 136 else if (DestRC == SP::FPRegsRegisterClass) 137 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg).addReg(SrcReg); 138 else if (DestRC == SP::DFPRegsRegisterClass) 139 BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD),DestReg) 140 .addReg(SrcReg); 141 else 142 // Can't copy this register 143 return false; 144 145 return true; 146} 147 148void SparcInstrInfo:: 149storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 150 unsigned SrcReg, bool isKill, int FI, 151 const TargetRegisterClass *RC, 152 const TargetRegisterInfo *TRI) const { 153 DebugLoc DL; 154 if (I != MBB.end()) DL = I->getDebugLoc(); 155 156 // On the order of operands here: think "[FrameIdx + 0] = SrcReg". 157 if (RC == SP::IntRegsRegisterClass) 158 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) 159 .addReg(SrcReg, getKillRegState(isKill)); 160 else if (RC == SP::FPRegsRegisterClass) 161 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) 162 .addReg(SrcReg, getKillRegState(isKill)); 163 else if (RC == SP::DFPRegsRegisterClass) 164 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) 165 .addReg(SrcReg, getKillRegState(isKill)); 166 else 167 llvm_unreachable("Can't store this register to stack slot"); 168} 169 170void SparcInstrInfo:: 171loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 172 unsigned DestReg, int FI, 173 const TargetRegisterClass *RC, 174 const TargetRegisterInfo *TRI) const { 175 DebugLoc DL; 176 if (I != MBB.end()) DL = I->getDebugLoc(); 177 178 if (RC == SP::IntRegsRegisterClass) 179 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); 180 else if (RC == SP::FPRegsRegisterClass) 181 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); 182 else if (RC == SP::DFPRegsRegisterClass) 183 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); 184 else 185 llvm_unreachable("Can't load this register from stack slot"); 186} 187 188MachineInstr *SparcInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, 189 MachineInstr* MI, 190 const SmallVectorImpl<unsigned> &Ops, 191 int FI) const { 192 if (Ops.size() != 1) return NULL; 193 194 unsigned OpNum = Ops[0]; 195 bool isFloat = false; 196 MachineInstr *NewMI = NULL; 197 switch (MI->getOpcode()) { 198 case SP::ORrr: 199 if (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == SP::G0&& 200 MI->getOperand(0).isReg() && MI->getOperand(2).isReg()) { 201 if (OpNum == 0) // COPY -> STORE 202 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::STri)) 203 .addFrameIndex(FI) 204 .addImm(0) 205 .addReg(MI->getOperand(2).getReg()); 206 else // COPY -> LOAD 207 NewMI = BuildMI(MF, MI->getDebugLoc(), get(SP::LDri), 208 MI->getOperand(0).getReg()) 209 .addFrameIndex(FI) 210 .addImm(0); 211 } 212 break; 213 case SP::FMOVS: 214 isFloat = true; 215 // FALLTHROUGH 216 case SP::FMOVD: 217 if (OpNum == 0) { // COPY -> STORE 218 unsigned SrcReg = MI->getOperand(1).getReg(); 219 bool isKill = MI->getOperand(1).isKill(); 220 bool isUndef = MI->getOperand(1).isUndef(); 221 NewMI = BuildMI(MF, MI->getDebugLoc(), 222 get(isFloat ? SP::STFri : SP::STDFri)) 223 .addFrameIndex(FI) 224 .addImm(0) 225 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef)); 226 } else { // COPY -> LOAD 227 unsigned DstReg = MI->getOperand(0).getReg(); 228 bool isDead = MI->getOperand(0).isDead(); 229 bool isUndef = MI->getOperand(0).isUndef(); 230 NewMI = BuildMI(MF, MI->getDebugLoc(), 231 get(isFloat ? SP::LDFri : SP::LDDFri)) 232 .addReg(DstReg, RegState::Define | 233 getDeadRegState(isDead) | getUndefRegState(isUndef)) 234 .addFrameIndex(FI) 235 .addImm(0); 236 } 237 break; 238 } 239 240 return NewMI; 241} 242 243unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const 244{ 245 SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>(); 246 unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg(); 247 if (GlobalBaseReg != 0) 248 return GlobalBaseReg; 249 250 // Insert the set of GlobalBaseReg into the first MBB of the function 251 MachineBasicBlock &FirstMBB = MF->front(); 252 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 253 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 254 255 GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass); 256 257 258 DebugLoc dl; 259 260 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg); 261 SparcFI->setGlobalBaseReg(GlobalBaseReg); 262 return GlobalBaseReg; 263} 264