Added code to support correct saving of %ccr across calls

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1111 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ruchira Sasanka 2001-11-03 19:59:59 +00:00
parent b20807f23e
commit 3839e6e309
4 changed files with 162 additions and 25 deletions

View File

@ -38,6 +38,7 @@
// instr class flags (defined in MachineInstrInfo.h)
I(NOP, "nop", 0, -1, 0, false, 0, 1, SPARC_NONE, M_NOP_FLAG)
// Synthetic SPARC assembly opcodes for setting a register to a constant.
@ -430,6 +431,11 @@ I(RETURN, "return", 2, -1, 0, false, 1, 2, SPARC_CTI, M_BRANCH_FLAG | M_RET_
I(SAVE , "save", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
I(RESTORE, "restore", 3, 2, B12, true , 0, 1, SPARC_SINGLE, M_INT_FLAG | M_ARITH_FLAG)
// Read and Write CCR register from/to an int reg
I(RDCCR, "rd", 2, 1, 0, false, 0, 1, SPARC_IEUN, M_INT_FLAG)
I(WRCCR, "wr", 3, 2, 0, false, 0, 1, SPARC_IEUN, M_INT_FLAG)
// Synthetic phi operation for near-SSA form of machine code
// Number of operands is variable, indicated by -1. Result is the first op.
I(PHI, "<phi>", -1, 0, 0, false, 0, 0, SPARC_INV, M_DUMMY_PHI_FLAG)

View File

@ -254,6 +254,9 @@ class UltraSparcRegInfo : public MachineRegInfo
const unsigned getCallInstNumArgs(const MachineInstr *CallMI) const;
MachineInstr * cpCCR2IntMI(const unsigned IntReg) const;
MachineInstr * cpInt2CCRMI(const unsigned IntReg) const;
public:
@ -371,9 +374,8 @@ class UltraSparcRegInfo : public MachineRegInfo
return SparcFloatRegOrder::getRegName( reg - 32);
else if( reg < (64+32+4) )
return SparcFloatCCRegOrder::getRegName( reg -32 - 64);
else if ( reg == 64+32+4)
return "xcc"; // only integer cc reg
else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr
return SparcIntCCRegOrder::getRegName( reg -32 - 64 - 4);
else if (reg== InvalidRegNum) //****** TODO: Remove */
return "<*NoReg*>";
else

View File

@ -191,22 +191,54 @@ class SparcFloatRegClass : public MachineRegClassInfo
//-----------------------------------------------------------------------------
// Int CC Register Class
// Only one integer cc register is available
// Only one integer cc register is available. However, this register is
// referred to as %xcc when instructions like subcc are executed but
// referred to as %ccr (i.e., %xcc + %icc") when this register is moved
// into an integer register using RD or WR instrcutions. So, two ids are
// allocated for two names.
//-----------------------------------------------------------------------------
static string const IntCCRegNames[] =
{
"xcc", "ccr"
};
class SparcIntCCRegOrder{
public:
enum RegsInPrefOrder {
xcc, ccr // only one is available - see the note above
};
static const string getRegName(const unsigned reg) {
assert( reg < 2 );
return IntCCRegNames[reg];
}
// according to Sparc 64 ABI, %ccr is volatile
inline bool isRegVolatile(const int Reg) const { return true; }
};
class SparcIntCCRegClass : public MachineRegClassInfo
{
public:
SparcIntCCRegClass(unsigned ID)
: MachineRegClassInfo(ID,1, 1) { }
: MachineRegClassInfo(ID, 1, 2) { }
inline void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
Node->setColor(0); // only one int cc reg is available
}
// *** TODO: Check this
inline bool isRegVolatile(const int Reg) const { return true; }
};

View File

@ -896,7 +896,6 @@ MachineInstr * UltraSparcRegInfo::cpReg2MemMI(const unsigned SrcReg,
switch( RegType ) {
case IntRegType:
case IntCCRegType:
case FloatCCRegType:
MI = new MachineInstr(STX, 3);
MI->SetMachineOperand(0, SrcReg, false);
@ -921,8 +920,11 @@ MachineInstr * UltraSparcRegInfo::cpReg2MemMI(const unsigned SrcReg,
(int64_t) Offset, false);
break;
case IntCCRegType:
assert( 0 && "Cannot directly store %ccr to memory");
default:
assert(0 && "Unknow RegType");
assert(0 && "Unknow RegType in cpReg2MemMI");
}
return MI;
@ -945,7 +947,6 @@ MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg,
switch( RegType ) {
case IntRegType:
case IntCCRegType:
case FloatCCRegType:
MI = new MachineInstr(LDX, 3);
MI->SetMachineOperand(0, SrcPtrReg, false);
@ -971,14 +972,21 @@ MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg,
MI->SetMachineOperand(2, DestReg, false);
break;
case IntCCRegType:
assert( 0 && "Cannot directly load into %ccr from memory");
default:
assert(0 && "Unknow RegType");
assert(0 && "Unknow RegType in cpMem2RegMI");
}
return MI;
}
// Following method is Not needed now
MachineInstr* UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest) const {
MachineInstr * MI = NULL;
@ -1071,28 +1079,91 @@ void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
int StackOff = PRA.StackOffsets. getNewTmpPosOffFromFP();
/**** TODO - Handle IntCCRegType
MachineInstr *AdIBefCC, *AdIAftCC, *AdICpCC;
//---- Insert code for pushing the reg on stack ----------
if( RegType == IntCCRegType ) {
// Handle IntCCRegType specially since we cannot directly
// push %ccr on to the stack
const LiveVarSet *LVSetBef =
PRA.LVI->getLiveVarSetBeforeMInst(MInst, BB);
// get a free INTEGER register
int FreeIntReg =
PRA.getUsableRegAtMI(LR->getRegClass(), IntRegType, MInst,
LVSetBef, AdIBefCC, AdIAftCC);
// insert the instructions in reverse order since we are
// adding them to the front of InstrnsBefore
if(AdIAftCC)
(PRA.AddedInstrMap[MInst]->InstrnsBefore).push_front(AdIAftCC);
AdICpCC = cpCCR2IntMI(FreeIntReg);
(PRA.AddedInstrMap[MInst]->InstrnsBefore).push_front(AdICpCC);
if(AdIBefCC)
(PRA.AddedInstrMap[MInst]->InstrnsBefore).push_front(AdIBefCC);
cerr << "\n!! Inserted caller saving (push) inst for %ccr:";
if(AdIBefCC) cerr << "\t" << *(AdIBefCC);
cerr << "\t" << *AdICpCC;
if(AdIAftCC) cerr << "\t" << *(AdIAftCC);
} else {
// for any other register type, just add the push inst
MachineInstr *AdIBef =
cpReg2MemMI(Reg, getStackPointer(), StackOff, RegType );
((PRA.AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
}
//---- Insert code for popping the reg from the stack ----------
if( RegType == IntCCRegType ) {
// Handle IntCCRegType specially since we cannot directly
// pop %ccr on from the stack
// get a free INT register
int FreeIntReg =
PRA.getUsableRegAtMI(LR->getRegClass(), IntRegType, MInst,
LVSetAft, AdIBefCC, AdIAftCC);
if(AdIBefCC)
(PRA.AddedInstrMap[MInst]->InstrnsAfter).push_back(AdIBefCC);
AdICpCC = cpInt2CCRMI(FreeIntReg);
(PRA.AddedInstrMap[MInst]->InstrnsAfter).push_back(AdICpCC);
if(AdIAftCC)
(PRA.AddedInstrMap[MInst]->InstrnsAfter).push_back(AdIAftCC);
cerr << "\n!! Inserted caller saving (pop) inst for %ccr:";
if(AdIBefCC) cerr << "\t" << *(AdIBefCC);
cerr << "\t" << *AdICpCC;
if(AdIAftCC) cerr << "\t" << *(AdIAftCC);
} else {
// for any other register type, just add the pop inst
MachineInstr *AdIAft =
cpMem2RegMI(getStackPointer(), StackOff, Reg, RegType );
((PRA.AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
}
*/
MachineInstr *AdIBef =
cpReg2MemMI(Reg, getStackPointer(), StackOff, RegType );
MachineInstr *AdIAft =
cpMem2RegMI(getStackPointer(), StackOff, Reg, RegType );
((PRA.AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
((PRA.AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
PushedRegSet.insert( Reg );
if(DEBUG_RA) {
cerr << "\nFor callee save call inst:" << *MInst;
if(1) {
cerr << "\nFor call inst:" << *MInst;
cerr << "\n -inserted caller saving instrs:\n\t ";
cerr << *AdIBef << "\n\t" << *AdIAft ;
cerr << *AdIBefCC << "\n\t" << *AdIAftCC ;
}
} // if not already pushed
@ -1106,10 +1177,36 @@ void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
}
//---------------------------------------------------------------------------
// Copies %ccr into an integer register. IntReg is the UNIFIED register
// number.
//---------------------------------------------------------------------------
MachineInstr * UltraSparcRegInfo::cpCCR2IntMI(const unsigned IntReg) const {
MachineInstr * MI = NULL;
MI = new MachineInstr(RDCCR, 2);
MI->SetMachineOperand(0, SparcIntCCRegOrder::ccr, false);
MI->SetMachineOperand(1, IntReg, true);
return MI;
}
//---------------------------------------------------------------------------
// Copies an integer register into %ccr. IntReg is the UNIFIED register
// number.
//---------------------------------------------------------------------------
MachineInstr * UltraSparcRegInfo::cpInt2CCRMI(const unsigned IntReg) const {
MachineInstr * MI = NULL;
MI = new MachineInstr(WRCCR, 3);
MI->SetMachineOperand(0, IntReg, false);
MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
MI->SetMachineOperand(2, SparcIntCCRegOrder::ccr, true);
return MI;
}