mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-11 14:16:59 +00:00
added register allocation code
llvm-svn: 585
This commit is contained in:
parent
474b31bae5
commit
422a5cb539
@ -5,7 +5,8 @@ LIBRARYNAME = sparc
|
||||
Source = \
|
||||
Sparc.o \
|
||||
Sparc.burm.o \
|
||||
SparcInstrSelection.o
|
||||
SparcInstrSelection.o \
|
||||
SparcRegInfo.o
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "llvm/CodeGen/InstrScheduling.h"
|
||||
#include "llvm/CodeGen/InstrSelection.h"
|
||||
|
||||
#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
|
||||
#include "llvm/CodeGen/PhyRegAlloc.h"
|
||||
|
||||
|
||||
// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
|
||||
// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
|
||||
//
|
||||
@ -85,6 +89,327 @@ UltraSparcSchedInfo::initializeResources()
|
||||
}
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class UltraSparcRegInfo
|
||||
//
|
||||
// Purpose:
|
||||
// This class provides info about sparc register classes.
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc *const USI ) :
|
||||
UltraSparcInfo(USI),
|
||||
NumOfIntArgRegs(6),
|
||||
NumOfFloatArgRegs(6)
|
||||
{
|
||||
MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
|
||||
|
||||
assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 &&
|
||||
"6 Float regs are used for float arg passing");
|
||||
}
|
||||
|
||||
// ***** TODO insert deletes for reg classes
|
||||
UltraSparcRegInfo::~UltraSparcRegInfo(void) { } // empty destructor
|
||||
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// UltraSparcRegInfo
|
||||
// Purpose:
|
||||
// This method will color incoming args to a method. If there are more
|
||||
// args than that can fit in regs, code will be inserted to pop them from
|
||||
// stack
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
void UltraSparcRegInfo::colorArgs(const Method *const Meth,
|
||||
LiveRangeInfo& LRI) const
|
||||
{
|
||||
|
||||
// get the argument list
|
||||
const Method::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
// get an iterator to arg list
|
||||
Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
unsigned intArgNo=0;
|
||||
|
||||
// to keep track of which float regs are allocated for argument passing
|
||||
bool FloatArgUsedArr[NumOfFloatArgRegs];
|
||||
|
||||
// init float arg used array
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
|
||||
FloatArgUsedArr[i] = false;
|
||||
|
||||
// for each argument
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) {
|
||||
|
||||
// get the LR of arg
|
||||
LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *ArgIt);
|
||||
unsigned RegClassID = (LR->getRegClass())->getID();
|
||||
|
||||
// if the arg is in int class - allocate a reg for an int arg
|
||||
if( RegClassID == IntRegClassID ) {
|
||||
|
||||
if( intArgNo < NumOfIntArgRegs) {
|
||||
LR->setColor( SparcIntRegOrder::i0 + intArgNo );
|
||||
|
||||
if( DEBUG_RA) printReg( LR );
|
||||
}
|
||||
|
||||
else {
|
||||
// TODO: Insert push code here
|
||||
assert( 0 && "Insert push code here!");
|
||||
}
|
||||
++intArgNo;
|
||||
}
|
||||
|
||||
// if the arg is float/double
|
||||
else if ( RegClassID == FloatRegClassID) {
|
||||
|
||||
if( LR->getTypeID() == Type::DoubleTyID ) {
|
||||
|
||||
// find the first reg # we can pass a double arg
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
|
||||
if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
|
||||
LR->setColor( SparcFloatRegOrder::f0 + i );
|
||||
FloatArgUsedArr[i] = true;
|
||||
FloatArgUsedArr[i+1] = true;
|
||||
if( DEBUG_RA) printReg( LR );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ! LR->hasColor() ) { // if LR was not colored above
|
||||
|
||||
assert(0 && "insert push code here for a double");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if( LR->getTypeID() == Type::FloatTyID ) {
|
||||
|
||||
// find the first reg # we can pass a float arg
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
|
||||
if ( !FloatArgUsedArr[i] ) {
|
||||
LR->setColor( SparcFloatRegOrder::f0 + i );
|
||||
FloatArgUsedArr[i] = true;
|
||||
if( DEBUG_RA) printReg( LR );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ! LR->hasColor() ) { // if LR was not colored above
|
||||
assert(0 && "insert push code here for a float");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
assert(0 && "unknown float type in method arg");
|
||||
|
||||
} // float register class
|
||||
|
||||
else
|
||||
assert(0 && "Unknown RegClassID");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void UltraSparcRegInfo::printReg(const LiveRange *const LR) {
|
||||
|
||||
unsigned RegClassID = (LR->getRegClass())->getID();
|
||||
|
||||
cout << " *Node " << (LR->getUserIGNode())->getIndex();
|
||||
|
||||
if( ! LR->hasColor() ) {
|
||||
cout << " - could not find a color" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// if a color is found
|
||||
|
||||
cout << " colored with color "<< LR->getColor();
|
||||
|
||||
if( RegClassID == IntRegClassID ) {
|
||||
|
||||
cout<< " [" << SparcIntRegOrder::getRegName(LR->getColor()) ;
|
||||
cout << "]" << endl;
|
||||
}
|
||||
else if ( RegClassID == FloatRegClassID) {
|
||||
cout << "[" << SparcFloatRegOrder::getRegName(LR->getColor());
|
||||
if( LR->getTypeID() == Type::DoubleTyID )
|
||||
cout << "+" << SparcFloatRegOrder::getRegName(LR->getColor()+1);
|
||||
cout << "]" << endl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void UltraSparcRegInfo::colorCallArgs(vector<const Instruction *> &
|
||||
CallInstrList, LiveRangeInfo& LRI,
|
||||
AddedInstrMapType &AddedInstrMap) const
|
||||
{
|
||||
|
||||
vector<const Instruction *>::const_iterator InstIt = CallInstrList.begin();
|
||||
|
||||
for( ; InstIt != CallInstrList.end(); ++InstIt) {
|
||||
|
||||
// Inst = LLVM call instruction
|
||||
const Instruction *const CallI = *InstIt;
|
||||
|
||||
MachineCodeForVMInstr & MInstVec = CallI->getMachineInstrVec();
|
||||
MachineCodeForVMInstr::const_iterator MIIt = MInstVec.begin();
|
||||
|
||||
// find the CALL/JMMPL machine instruction
|
||||
for( ; MIIt != MInstVec.end() &&
|
||||
! getUltraSparcInfo().getInstrInfo().isCall((*MIIt)->getOpCode());
|
||||
++MIIt );
|
||||
|
||||
assert( (MIIt != MInstVec.end()) && "CALL/JMPL not found");
|
||||
|
||||
// CallMI = CALL/JMPL machine isntruction
|
||||
const MachineInstr *const CallMI = *MIIt;
|
||||
|
||||
Instruction::op_const_iterator OpIt = CallI->op_begin();
|
||||
|
||||
unsigned intArgNo=0;
|
||||
//unsigned NumOfCallInterfs = LR->getNumOfCallInterferences();
|
||||
|
||||
// to keep track of which float regs are allocated for argument passing
|
||||
bool FloatArgUsedArr[NumOfFloatArgRegs];
|
||||
|
||||
// init float arg used array
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; ++i)
|
||||
FloatArgUsedArr[i] = false;
|
||||
|
||||
// go thru all the operands of LLVM instruction
|
||||
for( ; OpIt != CallI->op_end(); ++OpIt ) {
|
||||
|
||||
// get the LR of call operand (parameter)
|
||||
LiveRange *const LR = LRI.getLiveRangeForValue((const Value *) *OpIt);
|
||||
|
||||
if ( !LR ) {
|
||||
cout << " Warning: In call instr, no LR for arg: " ;
|
||||
printValue(*OpIt);
|
||||
cout << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned RegClassID = (LR->getRegClass())->getID();
|
||||
|
||||
// if the arg is in int class - allocate a reg for an int arg
|
||||
if( RegClassID == IntRegClassID ) {
|
||||
|
||||
if( intArgNo < NumOfIntArgRegs) {
|
||||
setCallArgColor( LR, SparcIntRegOrder::o0 + intArgNo );
|
||||
}
|
||||
|
||||
else {
|
||||
// TODO: Insert push code here
|
||||
assert( 0 && "Insert push code here!");
|
||||
|
||||
AddedInstrns * AI = AddedInstrMap[ CallMI ];
|
||||
if( ! AI ) AI = new AddedInstrns();
|
||||
|
||||
// AI->InstrnsBefore.push_back( getStackPushInstr(LR) );
|
||||
AddedInstrMap[ CallMI ] = AI;
|
||||
|
||||
}
|
||||
++intArgNo;
|
||||
}
|
||||
|
||||
// if the arg is float/double
|
||||
else if ( RegClassID == FloatRegClassID) {
|
||||
|
||||
if( LR->getTypeID() == Type::DoubleTyID ) {
|
||||
|
||||
// find the first reg # we can pass a double arg
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; i+= 2) {
|
||||
if ( !FloatArgUsedArr[i] && !FloatArgUsedArr[i+1] ) {
|
||||
setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
|
||||
FloatArgUsedArr[i] = true;
|
||||
FloatArgUsedArr[i+1] = true;
|
||||
//if( DEBUG_RA) printReg( LR );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ! LR->hasColor() ) { // if LR was not colored above
|
||||
|
||||
assert(0 && "insert push code here for a double");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if( LR->getTypeID() == Type::FloatTyID ) {
|
||||
|
||||
// find the first reg # we can pass a float arg
|
||||
for(unsigned i=0; i < NumOfFloatArgRegs; ++i) {
|
||||
if ( !FloatArgUsedArr[i] ) {
|
||||
setCallArgColor(LR, SparcFloatRegOrder::f0 + i );
|
||||
FloatArgUsedArr[i] = true;
|
||||
// LR->setColor( SparcFloatRegOrder::f0 + i );
|
||||
// if( DEBUG_RA) printReg( LR );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( ! LR->hasColor() ) { // if LR was not colored above
|
||||
assert(0 && "insert push code here for a float");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
assert(0 && "unknown float type in method arg");
|
||||
|
||||
} // float register class
|
||||
|
||||
else
|
||||
assert(0 && "Unknown RegClassID");
|
||||
|
||||
|
||||
} // for each operand in a call instruction
|
||||
|
||||
|
||||
|
||||
|
||||
} // for all call instrctions in CallInstrList
|
||||
|
||||
}
|
||||
|
||||
|
||||
void UltraSparcRegInfo::setCallArgColor(LiveRange *const LR,
|
||||
const unsigned RegNo) const {
|
||||
|
||||
// if no call interference and LR is NOT previously colored (e.g., as an
|
||||
// incoming arg)
|
||||
if( ! LR->getNumOfCallInterferences() && ! LR->hasColor() ) {
|
||||
// we can directly allocate a %o register
|
||||
LR->setColor( RegNo);
|
||||
if( DEBUG_RA) printReg( LR );
|
||||
}
|
||||
else { // there are call interferences
|
||||
|
||||
/*
|
||||
// insert a copy machine instr to copy from LR to %o(reg)
|
||||
PreMInstrMap[ CallMI ] =
|
||||
getNewCopyMInstr( LR->, SparcIntRegOrder::o0 + intArgNo );
|
||||
*/
|
||||
cout << " $$$ TODO: Insert a copy for call argument!: " << endl;
|
||||
|
||||
// We don't color LR here. It's colored as any other normal LR
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class UltraSparcMachine
|
||||
//
|
||||
@ -97,13 +422,47 @@ UltraSparcSchedInfo::initializeResources()
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
UltraSparc::UltraSparc() : TargetMachine("UltraSparc-Native"),
|
||||
InstSchedulingInfo(&InstInfo) {
|
||||
InstSchedulingInfo(&InstInfo),
|
||||
RegInfo( this ) {
|
||||
optSizeForSubWordData = 4;
|
||||
minMemOpWordSize = 8;
|
||||
maxAtomicMemOpWordSize = 8;
|
||||
zeroRegNum = 0; // %g0 always gives 0 on Sparc
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Entry point for register allocation for a module
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void AllocateRegisters(Method *M, TargetMachine &TM)
|
||||
{
|
||||
|
||||
if ( (M)->isExternal() ) // don't process prototypes
|
||||
return;
|
||||
|
||||
if( DEBUG_RA ) {
|
||||
cout << endl << "******************** Method "<< (M)->getName();
|
||||
cout << " ********************" <<endl;
|
||||
}
|
||||
|
||||
MethodLiveVarInfo LVI(M ); // Analyze live varaibles
|
||||
LVI.analyze();
|
||||
|
||||
|
||||
PhyRegAlloc PRA(M, TM , &LVI); // allocate registers
|
||||
PRA.allocateRegisters();
|
||||
|
||||
|
||||
if( DEBUG_RA ) cout << endl << "Register allocation complete!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool UltraSparc::compileMethod(Method *M) {
|
||||
if (SelectInstructionsForMethod(M, *this)) {
|
||||
cerr << "Instruction selection failed for method " << M->getName()
|
||||
@ -116,6 +475,10 @@ bool UltraSparc::compileMethod(Method *M) {
|
||||
<< M->getName() << "\n\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
AllocateRegisters(M, *this); // allocate registers
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -853,20 +853,34 @@ public:
|
||||
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// class UltraSparcInstrInfo
|
||||
// class UltraSparcRegInfo
|
||||
//
|
||||
// Purpose:
|
||||
// This class provides info about sparc register classes.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class LiveRange;
|
||||
class UltraSparc;
|
||||
|
||||
|
||||
class UltraSparcRegInfo : public MachineRegInfo
|
||||
{
|
||||
|
||||
private:
|
||||
enum RegClassIDs { IntRegClassID, FloatRegClassID, FloatCCREgClassID };
|
||||
|
||||
enum RegClassIDs {
|
||||
IntRegClassID,
|
||||
FloatRegClassID,
|
||||
IntCCRegClassID,
|
||||
FloatCCRegClassID
|
||||
};
|
||||
|
||||
// WARNING: If the above enum order must be changed, also modify
|
||||
// getRegisterClassOfValue method below since it assumes this particular
|
||||
// order for efficiency.
|
||||
|
||||
|
||||
// reverse pointer to get info about the ultra sparc machine
|
||||
const UltraSparc *const UltraSparcInfo;
|
||||
@ -883,37 +897,70 @@ class UltraSparcRegInfo : public MachineRegInfo
|
||||
|
||||
public:
|
||||
|
||||
UltraSparcRegInfo(const UltraSparc *USI ) : UltraSparcInfo(USI),
|
||||
NumOfIntArgRegs(6),
|
||||
NumOfFloatArgRegs(6)
|
||||
{
|
||||
|
||||
UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
|
||||
NumOfIntArgRegs(6),
|
||||
NumOfFloatArgRegs(6)
|
||||
{
|
||||
MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcIntCCRegClass(IntCCRegClassID) );
|
||||
MachineRegClassArr.push_back( new SparcFloatCCRegClass(FloatCCRegClassID));
|
||||
|
||||
assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 6 &&
|
||||
"6 Float regs are used for float arg passing");
|
||||
|
||||
}
|
||||
|
||||
// ***** TODO Delete
|
||||
~UltraSparcRegInfo(void) { } // empty destructor
|
||||
|
||||
|
||||
inline const UltraSparc & getUltraSparcInfo() const {
|
||||
return *UltraSparcInfo;
|
||||
}
|
||||
|
||||
inline unsigned getRegClassIDOfValue (const Value *const Val) const {
|
||||
|
||||
|
||||
inline unsigned getRegClassIDOfValue (const Value *const Val,
|
||||
bool isCCReg = false) const {
|
||||
|
||||
Type::PrimitiveID ty = (Val->getType())->getPrimitiveID();
|
||||
|
||||
unsigned res;
|
||||
|
||||
if( ty && ty <= Type::LongTyID || (ty == Type::PointerTyID) )
|
||||
return IntRegClassID; // sparc int reg (ty=0: void)
|
||||
res = IntRegClassID; // sparc int reg (ty=0: void)
|
||||
else if( ty <= Type::DoubleTyID)
|
||||
return FloatRegClassID; // sparc float reg class
|
||||
res = FloatRegClassID; // sparc float reg class
|
||||
else {
|
||||
cout << "TypeID: " << ty << endl;
|
||||
assert(0 && "Cannot resolve register class for type");
|
||||
|
||||
}
|
||||
|
||||
if(isCCReg)
|
||||
return res + 2; // corresponidng condition code regiser
|
||||
|
||||
else
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
unsigned getRCIDOfMachineOp (const MachineOperand & Op) const {
|
||||
|
||||
unsigned Type = getRegClassIDOfValue( Op.getVRegValue() );
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_CCRegister )
|
||||
return Type + 2; // because of the order of CC classes
|
||||
else return Type;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const;
|
||||
|
||||
static void printReg(const LiveRange *const LR) ;
|
||||
@ -929,9 +976,11 @@ class UltraSparcRegInfo : public MachineRegInfo
|
||||
return reg;
|
||||
else if ( RegClassID == FloatRegClassID && reg < 64)
|
||||
return reg + 32; // we have 32 int regs
|
||||
else if( RegClassID == FloatCCREgClassID && reg < 4)
|
||||
else if( RegClassID == FloatCCRegClassID && reg < 4)
|
||||
return reg + 32 + 64; // 32 int, 64 float
|
||||
else
|
||||
else if( RegClassID == IntCCRegClassID )
|
||||
return 4+ 32 + 64; // only int cc reg
|
||||
else
|
||||
assert(0 && "Invalid register class or reg number");
|
||||
|
||||
}
|
||||
@ -944,8 +993,9 @@ class UltraSparcRegInfo : public MachineRegInfo
|
||||
else if ( reg < (64 + 32) )
|
||||
return SparcFloatRegOrder::getRegName( reg - 32);
|
||||
else if( reg < (64+32+4) )
|
||||
assert( 0 && "no float condition reg class yet");
|
||||
// return reg + 32 + 64;
|
||||
return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
|
||||
else if ( reg == 64+32+4)
|
||||
return "xcc"; // only integer cc reg
|
||||
else
|
||||
assert(0 && "Invalid register number");
|
||||
}
|
||||
@ -956,9 +1006,6 @@ class UltraSparcRegInfo : public MachineRegInfo
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
Scheduling guidelines for SPARC IIi:
|
||||
|
||||
@ -1667,12 +1714,15 @@ protected:
|
||||
class UltraSparc : public TargetMachine {
|
||||
UltraSparcInstrInfo InstInfo;
|
||||
UltraSparcSchedInfo InstSchedulingInfo;
|
||||
UltraSparcRegInfo RegInfo;
|
||||
public:
|
||||
UltraSparc();
|
||||
virtual ~UltraSparc() {}
|
||||
|
||||
virtual const MachineInstrInfo& getInstrInfo() const { return InstInfo; }
|
||||
|
||||
virtual const MachineRegInfo& getRegInfo() const { return RegInfo; }
|
||||
|
||||
// compileMethod - For the sparc, we do instruction selection, followed by
|
||||
// delay slot scheduling, then register allocation.
|
||||
//
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
#include "SparcRegInfo.h"
|
||||
#include "SparcInternals.h"
|
||||
|
||||
#include "llvm/Target/Sparc.h"
|
||||
|
||||
|
@ -4,17 +4,20 @@
|
||||
Purpose: Contains the description of integer register class of Sparc
|
||||
*/
|
||||
|
||||
#ifndef SPARC_INT_REG_CLASS_H
|
||||
#define SPARC_INT_REG_CLASS_H
|
||||
|
||||
#ifndef SPARC_REG_INFO_CLASS_H
|
||||
#define SPARC_REG_INFO_CLASS_H
|
||||
|
||||
#include "llvm/Target/RegInfo.h"
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Integer Register Class
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Int register names in same order as enum in class SparcIntRegOrder
|
||||
//
|
||||
|
||||
static string const IntRegNames[] =
|
||||
{ "g1", "g2", "g3", "g4", "g5", "g6", "g7",
|
||||
"o0", "o1", "o2", "o3", "o4", "o5", "o7",
|
||||
@ -80,7 +83,7 @@ class SparcIntRegClass : public MachineRegClassInfo
|
||||
public:
|
||||
|
||||
SparcIntRegClass(unsigned ID)
|
||||
: MachineRegClassInfo(0,
|
||||
: MachineRegClassInfo(ID,
|
||||
SparcIntRegOrder::NumOfAvailRegs,
|
||||
SparcIntRegOrder::NumOfAllRegs)
|
||||
{ }
|
||||
@ -141,6 +144,7 @@ class SparcFloatRegOrder{
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SparcFloatRegClass : public MachineRegClassInfo
|
||||
{
|
||||
private:
|
||||
@ -151,7 +155,7 @@ class SparcFloatRegClass : public MachineRegClassInfo
|
||||
public:
|
||||
|
||||
SparcFloatRegClass(unsigned ID)
|
||||
: MachineRegClassInfo(1,
|
||||
: MachineRegClassInfo(ID,
|
||||
SparcFloatRegOrder::NumOfAvailRegs,
|
||||
SparcFloatRegOrder::NumOfAllRegs)
|
||||
{ }
|
||||
@ -162,4 +166,75 @@ class SparcFloatRegClass : public MachineRegClassInfo
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Int CC Register Class
|
||||
// Only one integer cc register is available
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class SparcIntCCRegClass : public MachineRegClassInfo
|
||||
{
|
||||
public:
|
||||
|
||||
SparcIntCCRegClass(unsigned ID)
|
||||
: MachineRegClassInfo(ID,1, 1) { }
|
||||
|
||||
inline void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
|
||||
Node->setColor(0); // only one int cc reg is available
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Float CC Register Class
|
||||
// Only 4 Float CC registers are available
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
static string const FloatCCRegNames[] =
|
||||
{
|
||||
"fcc0", "fcc1", "fcc2", "fcc3"
|
||||
};
|
||||
|
||||
|
||||
class SparcFloatCCRegOrder{
|
||||
|
||||
public:
|
||||
|
||||
enum RegsInPrefOrder {
|
||||
|
||||
fcc0, fcc1, fcc2, fcc3
|
||||
};
|
||||
|
||||
static const string getRegName(const unsigned reg) {
|
||||
assert( reg < 4 );
|
||||
return FloatCCRegNames[reg];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SparcFloatCCRegClass : public MachineRegClassInfo
|
||||
{
|
||||
public:
|
||||
|
||||
SparcFloatCCRegClass(unsigned ID)
|
||||
: MachineRegClassInfo(ID, 4, 4) { }
|
||||
|
||||
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
|
||||
int c;
|
||||
for(c=0; c < 4 && IsColorUsedArr[c] ; ++c) ; // find color
|
||||
assert( (c < 4) && "Can allocate only 4 float cc registers");
|
||||
Node->setColor(c);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user