// 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.
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)
//-----------------------------------------------------------------------------
// 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; }
};
switch( RegType ) {
case IntRegType:
- case IntCCRegType:
case FloatCCRegType:
MI = new MachineInstr(STX, 3);
MI->SetMachineOperand(0, SrcReg, false);
(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;
switch( RegType ) {
case IntRegType:
- case IntCCRegType:
case FloatCCRegType:
MI = new MachineInstr(LDX, 3);
MI->SetMachineOperand(0, SrcPtrReg, false);
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;
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);
- MachineInstr *AdIBef =
- cpReg2MemMI(Reg, getStackPointer(), StackOff, RegType );
+ 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 );
- MachineInstr *AdIAft =
- cpMem2RegMI(getStackPointer(), StackOff, Reg, RegType );
+ ((PRA.AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
- ((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
}
+//---------------------------------------------------------------------------
+// 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;
+}