forked from OSchip/llvm-project
158 lines
6.2 KiB
C++
158 lines
6.2 KiB
C++
//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains the Sparc implementation of the TargetInstrInfo class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SparcInstrInfo.h"
|
|
#include "SparcSubtarget.h"
|
|
#include "Sparc.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "SparcGenInstrInfo.inc"
|
|
#include "SparcMachineFunctionInfo.h"
|
|
using namespace llvm;
|
|
|
|
SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
|
|
: TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)),
|
|
RI(ST, *this), Subtarget(ST) {
|
|
}
|
|
|
|
/// 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.
|
|
unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
|
int &FrameIndex) const {
|
|
if (MI->getOpcode() == SP::LDri ||
|
|
MI->getOpcode() == SP::LDFri ||
|
|
MI->getOpcode() == SP::LDDFri) {
|
|
if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
|
|
MI->getOperand(2).getImm() == 0) {
|
|
FrameIndex = MI->getOperand(1).getIndex();
|
|
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.
|
|
unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
|
int &FrameIndex) const {
|
|
if (MI->getOpcode() == SP::STri ||
|
|
MI->getOpcode() == SP::STFri ||
|
|
MI->getOpcode() == SP::STDFri) {
|
|
if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
|
|
MI->getOperand(1).getImm() == 0) {
|
|
FrameIndex = MI->getOperand(0).getIndex();
|
|
return MI->getOperand(2).getReg();
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned
|
|
SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
|
|
MachineBasicBlock *FBB,
|
|
const SmallVectorImpl<MachineOperand> &Cond,
|
|
DebugLoc DL)const{
|
|
// Can only insert uncond branches so far.
|
|
assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
|
|
BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
|
|
return 1;
|
|
}
|
|
|
|
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));
|
|
else
|
|
llvm_unreachable("Impossible reg-to-reg copy");
|
|
}
|
|
|
|
void SparcInstrInfo::
|
|
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|
unsigned SrcReg, bool isKill, int FI,
|
|
const TargetRegisterClass *RC,
|
|
const TargetRegisterInfo *TRI) const {
|
|
DebugLoc DL;
|
|
if (I != MBB.end()) DL = I->getDebugLoc();
|
|
|
|
// On the order of operands here: think "[FrameIdx + 0] = SrcReg".
|
|
if (RC == SP::IntRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
|
else if (RC == SP::FPRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
|
else if (RC == SP::DFPRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
|
|
.addReg(SrcReg, getKillRegState(isKill));
|
|
else
|
|
llvm_unreachable("Can't store this register to stack slot");
|
|
}
|
|
|
|
void SparcInstrInfo::
|
|
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
|
unsigned DestReg, int FI,
|
|
const TargetRegisterClass *RC,
|
|
const TargetRegisterInfo *TRI) const {
|
|
DebugLoc DL;
|
|
if (I != MBB.end()) DL = I->getDebugLoc();
|
|
|
|
if (RC == SP::IntRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
|
|
else if (RC == SP::FPRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
|
|
else if (RC == SP::DFPRegsRegisterClass)
|
|
BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
|
|
else
|
|
llvm_unreachable("Can't load this register from stack slot");
|
|
}
|
|
|
|
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);
|
|
|
|
|
|
DebugLoc dl;
|
|
|
|
BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
|
|
SparcFI->setGlobalBaseReg(GlobalBaseReg);
|
|
return GlobalBaseReg;
|
|
}
|