2006-02-05 05:50:24 +00:00
|
|
|
//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===//
|
2005-04-21 23:30:14 +00:00
|
|
|
//
|
2004-02-25 19:28:19 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:36:04 +00:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 23:30:14 +00:00
|
|
|
//
|
2004-02-25 19:28:19 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2006-02-05 05:50:24 +00:00
|
|
|
// This file contains the Sparc implementation of the TargetInstrInfo class.
|
2004-02-25 19:28:19 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2006-02-05 05:50:24 +00:00
|
|
|
#include "SparcInstrInfo.h"
|
2007-12-31 06:32:00 +00:00
|
|
|
#include "SparcSubtarget.h"
|
2006-02-05 05:50:24 +00:00
|
|
|
#include "Sparc.h"
|
2007-09-07 04:06:50 +00:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2009-01-05 17:59:02 +00:00
|
|
|
#include "llvm/ADT/SmallVector.h"
|
2004-02-25 19:28:19 +00:00
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
2009-09-15 17:46:24 +00:00
|
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
2009-07-11 20:10:48 +00:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2006-02-05 05:50:24 +00:00
|
|
|
#include "SparcGenInstrInfo.inc"
|
2009-09-15 17:46:24 +00:00
|
|
|
#include "SparcMachineFunctionInfo.h"
|
2004-02-29 05:59:33 +00:00
|
|
|
using namespace llvm;
|
2004-02-25 19:28:19 +00:00
|
|
|
|
2006-02-05 05:50:24 +00:00
|
|
|
SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
|
2008-01-01 01:03:04 +00:00
|
|
|
: TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)),
|
2007-12-31 06:32:00 +00:00
|
|
|
RI(ST, *this), Subtarget(ST) {
|
2004-02-25 19:28:19 +00:00
|
|
|
}
|
|
|
|
|
2006-02-03 06:44:54 +00:00
|
|
|
/// isLoadFromStackSlot - If the specified machine instruction is a direct
|
|
|
|
/// load from a stack slot, return the virtual or physical register number of
|
|
|
|
/// the destination along with the FrameIndex of the loaded stack slot. If
|
|
|
|
/// not, return 0. This predicate must return 0 if the instruction has
|
|
|
|
/// any side effects other than loading from the stack slot.
|
2008-11-18 19:49:32 +00:00
|
|
|
unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
2006-02-05 05:50:24 +00:00
|
|
|
int &FrameIndex) const {
|
|
|
|
if (MI->getOpcode() == SP::LDri ||
|
|
|
|
MI->getOpcode() == SP::LDFri ||
|
|
|
|
MI->getOpcode() == SP::LDDFri) {
|
2008-10-03 15:45:36 +00:00
|
|
|
if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
|
2007-12-30 20:49:49 +00:00
|
|
|
MI->getOperand(2).getImm() == 0) {
|
2007-12-30 23:10:15 +00:00
|
|
|
FrameIndex = MI->getOperand(1).getIndex();
|
2006-02-03 06:44:54 +00:00
|
|
|
return MI->getOperand(0).getReg();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// isStoreToStackSlot - If the specified machine instruction is a direct
|
|
|
|
/// store to a stack slot, return the virtual or physical register number of
|
|
|
|
/// the source reg along with the FrameIndex of the loaded stack slot. If
|
|
|
|
/// not, return 0. This predicate must return 0 if the instruction has
|
|
|
|
/// any side effects other than storing to the stack slot.
|
2008-11-18 19:49:32 +00:00
|
|
|
unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
2006-02-05 05:50:24 +00:00
|
|
|
int &FrameIndex) const {
|
|
|
|
if (MI->getOpcode() == SP::STri ||
|
|
|
|
MI->getOpcode() == SP::STFri ||
|
|
|
|
MI->getOpcode() == SP::STDFri) {
|
2008-10-03 15:45:36 +00:00
|
|
|
if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
|
2007-12-30 20:49:49 +00:00
|
|
|
MI->getOperand(1).getImm() == 0) {
|
2007-12-30 23:10:15 +00:00
|
|
|
FrameIndex = MI->getOperand(0).getIndex();
|
2006-02-03 06:44:54 +00:00
|
|
|
return MI->getOperand(2).getReg();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2006-10-24 16:39:19 +00:00
|
|
|
|
2007-05-18 00:18:17 +00:00
|
|
|
unsigned
|
|
|
|
SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
|
|
|
|
MachineBasicBlock *FBB,
|
2010-06-17 22:43:56 +00:00
|
|
|
const SmallVectorImpl<MachineOperand> &Cond,
|
|
|
|
DebugLoc DL)const{
|
2006-10-24 16:39:19 +00:00
|
|
|
// Can only insert uncond branches so far.
|
|
|
|
assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
|
2010-06-17 22:43:56 +00:00
|
|
|
BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
|
2007-05-18 00:18:17 +00:00
|
|
|
return 1;
|
2006-10-24 17:07:11 +00:00
|
|
|
}
|
2007-12-31 06:32:00 +00:00
|
|
|
|
2010-07-11 07:56:09 +00:00
|
|
|
void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
|
|
|
MachineBasicBlock::iterator I, DebugLoc DL,
|
|
|
|
unsigned DestReg, unsigned SrcReg,
|
|
|
|
bool KillSrc) const {
|
|
|
|
if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
|
|
|
|
BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
|
|
|
|
.addReg(SrcReg, getKillRegState(KillSrc));
|
|
|
|
else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
|
|
|
|
BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
|
|
|
|
.addReg(SrcReg, getKillRegState(KillSrc));
|
|
|
|
else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg))
|
|
|
|
BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg)
|
|
|
|
.addReg(SrcReg, getKillRegState(KillSrc));
|
2007-12-31 06:32:00 +00:00
|
|
|
else
|
2010-07-11 07:56:09 +00:00
|
|
|
llvm_unreachable("Impossible reg-to-reg copy");
|
2007-12-31 06:32:00 +00:00
|
|
|
}
|
2008-01-01 21:11:32 +00:00
|
|
|
|
|
|
|
void SparcInstrInfo::
|
|
|
|
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|
|
|
unsigned SrcReg, bool isKill, int FI,
|
2010-05-06 19:06:44 +00:00
|
|
|
const TargetRegisterClass *RC,
|
|
|
|
const TargetRegisterInfo *TRI) const {
|
2010-04-02 20:16:16 +00:00
|
|
|
DebugLoc DL;
|
2009-02-12 00:02:55 +00:00
|
|
|
if (I != MBB.end()) DL = I->getDebugLoc();
|
|
|
|
|
2008-01-01 21:11:32 +00:00
|
|
|
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
|
|
|
|
if (RC == SP::IntRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
|
2009-05-13 21:33:08 +00:00
|
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
2008-01-01 21:11:32 +00:00
|
|
|
else if (RC == SP::FPRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
|
2009-05-13 21:33:08 +00:00
|
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
2008-01-01 21:11:32 +00:00
|
|
|
else if (RC == SP::DFPRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
|
2009-05-13 21:33:08 +00:00
|
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
2008-01-01 21:11:32 +00:00
|
|
|
else
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Can't store this register to stack slot");
|
2008-01-01 21:11:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SparcInstrInfo::
|
|
|
|
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|
|
|
unsigned DestReg, int FI,
|
2010-05-06 19:06:44 +00:00
|
|
|
const TargetRegisterClass *RC,
|
|
|
|
const TargetRegisterInfo *TRI) const {
|
2010-04-02 20:16:16 +00:00
|
|
|
DebugLoc DL;
|
2009-02-12 00:02:55 +00:00
|
|
|
if (I != MBB.end()) DL = I->getDebugLoc();
|
|
|
|
|
2008-01-01 21:11:32 +00:00
|
|
|
if (RC == SP::IntRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
|
2008-01-01 21:11:32 +00:00
|
|
|
else if (RC == SP::FPRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
|
2008-01-01 21:11:32 +00:00
|
|
|
else if (RC == SP::DFPRegsRegisterClass)
|
2009-02-12 00:02:55 +00:00
|
|
|
BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
|
2008-01-01 21:11:32 +00:00
|
|
|
else
|
2009-07-14 16:55:14 +00:00
|
|
|
llvm_unreachable("Can't load this register from stack slot");
|
2008-01-01 21:11:32 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 17:46:24 +00:00
|
|
|
unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
|
|
|
|
{
|
|
|
|
SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
|
|
|
|
unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg();
|
|
|
|
if (GlobalBaseReg != 0)
|
|
|
|
return GlobalBaseReg;
|
|
|
|
|
|
|
|
// Insert the set of GlobalBaseReg into the first MBB of the function
|
|
|
|
MachineBasicBlock &FirstMBB = MF->front();
|
|
|
|
MachineBasicBlock::iterator MBBI = FirstMBB.begin();
|
|
|
|
MachineRegisterInfo &RegInfo = MF->getRegInfo();
|
|
|
|
|
|
|
|
GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
|
|
|
|
|
|
|
|
|
2010-04-02 20:16:16 +00:00
|
|
|
DebugLoc dl;
|
2009-09-15 17:46:24 +00:00
|
|
|
|
|
|
|
BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
|
|
|
|
SparcFI->setGlobalBaseReg(GlobalBaseReg);
|
|
|
|
return GlobalBaseReg;
|
|
|
|
}
|