teak-llvm/llvm/lib/Target/Teak/TeakRegisterInfo.cpp

281 lines
9.7 KiB
C++

//===-- TeakRegisterInfo.cpp - Teak Register Information ----------------===//
//
// 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 Teak implementation of the MRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "TeakRegisterInfo.h"
#include "Teak.h"
#include "TeakFrameLowering.h"
#include "TeakInstrInfo.h"
#include "TeakSubtarget.h"
#include "TeakMachineFunctionInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "TeakGenRegisterInfo.inc"
TeakRegisterInfo::TeakRegisterInfo() : TeakGenRegisterInfo(0) {}
const MCPhysReg* TeakRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const
{
return CSR_SaveList;
}
BitVector TeakRegisterInfo::getReservedRegs(const MachineFunction &MF) const
{
BitVector Reserved(getNumRegs());
Reserved.set(Teak::SP);
Reserved.set(Teak::PC);
Reserved.set(Teak::R7);
Reserved.set(Teak::LC);
//Reserved.set(Teak::SV);
return Reserved;
}
const uint32_t* TeakRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID) const {
return CSR_RegMask;
}
const TargetRegisterClass* TeakRegisterInfo::getPointerRegClass(
const MachineFunction &MF, unsigned Kind) const
{
if(Kind == 1)
return &Teak::ABRegsRegClass;
return &Teak::GRRegsRegClass;
}
bool TeakRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const
{
return true;
}
bool TeakRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const
{
return true;
}
bool TeakRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const
{
return false;
}
bool TeakRegisterInfo::requiresFrameIndexScavenging(const MachineFunction &MF) const
{
return false;//true;
}
bool TeakRegisterInfo::requiresVirtualBaseRegisters(const MachineFunction &MF) const
{
return false;//true;
}
unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, MachineFunction &MF) const
{
switch (RC->getID())
{
default:
return 0;
case Teak::GRRegsRegClassID:
return 5;
case Teak::SVRegRegClassID:
return 0;
case Teak::ABRegsRegClassID:
return 4;
case Teak::ALRegsRegClassID:
return 2;
case Teak::ABLRegsRegClassID:
return 4;
case Teak::RegNoBRegs16_nohRegClassID:
return 9;
}
}
void TeakRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
dbgs() << "eliminateFrameIndex\n";
MachineInstr &MI = *II;
const MachineFunction &MF = *MI.getParent()->getParent();
const MachineFrameInfo& MFI = MF.getFrameInfo();
MachineOperand &FIOp = MI.getOperand(FIOperandNum);
unsigned FI = FIOp.getIndex();
// Determine if we can eliminate the index from this kind of instruction.
unsigned ImmOpIdx = 0;
switch (MI.getOpcode()) {
default:
// Not supported yet.
return;
case Teak::STORE_REG_TO_STACK_PSEUDO_16:
case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16:
case Teak::STORE_REG_TO_STACK_PSEUDO_32:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40:
ImmOpIdx = FIOperandNum + 1;
break;
}
// FIXME: check the size of offset.
MachineOperand &ImmOp = MI.getOperand(ImmOpIdx);
int Offset = MFI.getObjectOffset(FI) + MFI.getStackSize() + ImmOp.getImm();
FIOp.ChangeToRegister(Teak::R7, false);
ImmOp.setImm(-(Offset >> 1) - 1);
}
Register TeakRegisterInfo::getFrameRegister(const MachineFunction &MF) const
{
return Teak::R7;
}
bool TeakRegisterInfo::isFrameOffsetLegal(
const MachineInstr* MI, unsigned BaseReg, int64_t Offset) const
{
dbgs() << "isFrameOffsetLegal\n";
return true;//Offset == 0;
}
bool TeakRegisterInfo::needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const
{
return false;//Offset != 0;
}
int64_t TeakRegisterInfo::getFrameIndexInstrOffset(const MachineInstr* MI, int Idx) const
{
switch (MI->getOpcode())
{
default:
return 0;
case Teak::STORE_REG_TO_STACK_PSEUDO_16:
case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16:
case Teak::STORE_REG_TO_STACK_PSEUDO_32:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40:
return MI->getOperand(Idx + 1).getImm();
}
}
void TeakRegisterInfo::materializeFrameBaseRegister(MachineBasicBlock *MBB,
unsigned BaseReg, int FrameIdx, int64_t Offset) const
{
// dbgs() << "materializeFrameBaseRegister: " << BaseReg << "\n";
// MachineBasicBlock::iterator Ins = MBB->begin();
// DebugLoc DL; // Defaults to "unknown"
// if (Ins != MBB->end())
// DL = Ins->getDebugLoc();
// const MachineFunction &MF = *MBB->getParent();
// MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
// const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
// MRI.constrainRegClass(BaseReg, &Teak::FPRegClass);
// BuildMI(*MBB, Ins, DL, get(Teak::ADDV_imm16_RegNoBRegs16), BaseReg)
// .addImm(Offset)
// .addReg(Teak::R7);
}
void TeakRegisterInfo::resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const
{
dbgs() << "resolveFrameIndex\n";
MI.dump();
const MachineFunction &MF = *MI.getParent()->getParent();
const MachineFrameInfo& MFI = MF.getFrameInfo();
MachineOperand* FIOp;
//unsigned FI = FIOp.getIndex();
// Determine if we can eliminate the index from this kind of instruction.
unsigned ImmOpIdx = 0;
switch (MI.getOpcode()) {
default:
// Not supported yet.
return;
case Teak::STORE_REG_TO_STACK_PSEUDO_16:
case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16:
case Teak::STORE_REG_TO_STACK_PSEUDO_32:
FIOp = &MI.getOperand(1);
ImmOpIdx = 2;
break;
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40:
case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40:
FIOp = &MI.getOperand(1);
ImmOpIdx = 2;
break;
}
// FIXME: check the size of offset.
MachineOperand &ImmOp = MI.getOperand(ImmOpIdx);
FIOp->ChangeToRegister(BaseReg, false);
ImmOp.setImm(Offset);
}
bool TeakRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg,
const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const
{
dbgs() << "shouldCoalesce\n";
MI->dump();
dbgs() << "SrcRC: " << SrcRC->getID() << "\n";
dbgs() << "SubReg: " << SubReg << "\n";
dbgs() << "DstRC: " << DstRC->getID() << "\n";
dbgs() << "DstSubReg: " << DstSubReg << "\n";
dbgs() << "NewRC: " << NewRC->getID() << "\n";
if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
DstRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
NewRC->hasSuperClassEq(&Teak::SVRegRegClass))
return false;
if(DstSubReg == Teak::sub_16bit)
return true;
//if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
// return true;
if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true;
if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true;
//return true;//false;
if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return true;
if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass))
return true;
if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) ||
DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return false;
return true;
}