// RegClassArr.pushback( new SparcFloatCCRegClass(2) );
if(DEBUG_RA)
- cerr << "Created machine register classes." << endl;
+ cout << "Created machine register classes." << endl;
}
// This method should find a color which is not used by neighbors
// (i.e., a false position in IsColorUsedArr) and
virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0;
-
+ virtual bool isRegVolatile(const int Reg) const = 0;
MachineRegClassInfo(const unsigned ID, const unsigned NVR,
const unsigned NAR): RegClassID(ID), NumOfAvailRegs(NVR),
+ virtual MachineInstr *
+ cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
+ const int RegType) const=0;
+
+ virtual MachineInstr *
+ cpReg2MemMI(const unsigned SrcReg, const unsigned DestPtrReg,
+ const int Offset, const int RegType) const=0;
+
+ virtual MachineInstr *
+ cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
+ const unsigned DestReg, const int RegType) const=0;
+
+ virtual bool isRegVolatile(const int RegClassID, const int Reg) const=0;
+
+
+
//virtual bool handleSpecialMInstr(const MachineInstr * MInst,
// LiveRangeInfo& LRI, vector<RegClass *> RCL) const = 0;
virtual const string getUnifiedRegName(int UnifiedRegNum) const = 0;
+ virtual int getRegType(const LiveRange *const LR) const=0;
+
+
+ inline virtual unsigned getFramePointer() const=0;
+
+ inline virtual unsigned getStackPointer() const=0;
+
+ inline virtual int getInvalidRegNum() const=0;
+
+
//virtual void printReg(const LiveRange *const LR) const =0;
MachineRegInfo() { }
IG = NULL;
Size = 0;
if( DEBUG_RA) {
- cerr << "Interference graph created!" << endl;
+ cout << "Interference graph created!" << endl;
}
}
char *val;
if( DEBUG_RA > 1)
- cerr << "setting intf for: [" << row << "][" << col << "]" << endl;
+ cout << "setting intf for: [" << row << "][" << col << "]" << endl;
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
assertIGNode( SrcNode );
if( DEBUG_RA > 1) {
- cerr << "Merging LRs: \""; LR1->printSet();
- cerr << "\" and \""; LR2->printSet();
- cerr << "\"" << endl;
+ cout << "Merging LRs: \""; LR1->printSet();
+ cout << "\" and \""; LR2->printSet();
+ cout << "\"" << endl;
}
unsigned SrcDegree = SrcNode->getNumOfNeighbors();
setInterference(LR1, LROfNeigh );
}
- //cerr<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
- //cerr << NeighNode->getNumOfNeighbors();
- //cerr << " Dest: [" << DestNode->getIndex() << "] ";
- //cerr << DestNode->getNumOfNeighbors() << endl;
+ //cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
+ //cout << NeighNode->getNumOfNeighbors();
+ //cout << " Dest: [" << DestNode->getIndex() << "] ";
+ //cout << DestNode->getNumOfNeighbors() << endl;
}
if( ! Node )
continue; // skip empty rows
- cerr << " [" << i << "] ";
+ cout << " [" << i << "] ";
for( unsigned int j=0; j < Size; j++) {
if( j >= i) break;
- if( IG[i][j] ) cerr << "(" << i << "," << j << ") ";
+ if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
}
- cerr << endl;
+ cout << endl;
}
}
if( ! Node )
continue;
- cerr << " [" << Node->getIndex() << "] ";
+ cout << " [" << Node->getIndex() << "] ";
(Node->getParentLR())->printSet();
//int Deg = Node->getCurDegree();
- cerr << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
+ cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
}
}
{
if( DEBUG_RA)
- cerr << "Consturcting Live Ranges ..." << endl;
+ cout << "Consturcting Live Ranges ..." << endl;
// first find the live ranges for all incoming args of the method since
// those LRs start from the start of the method
if( DEBUG_RA > 1) {
- cerr << " adding LiveRange for argument ";
- printValue( (const Value *) *ArgIt); cerr << endl;
+ cout << " adding LiveRange for argument ";
+ printValue( (const Value *) *ArgIt); cout << endl;
}
}
OpI.getMachineOperand().getOperandType();
if ( OpTyp == MachineOperand::MO_CCRegister) {
- cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
+ cout << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
printValue( OpI.getMachineOperand().getVRegValue() );
- cerr << endl;
+ cout << endl;
}
}
// Only instruction values are accepted for live ranges here
if( Def->getValueType() != Value::InstructionVal ) {
- cerr << "\n**%%Error: Def is not an instruction val. Def=";
- printValue( Def ); cerr << endl;
+ cout << "\n**%%Error: Def is not an instruction val. Def=";
+ printValue( Def ); cout << endl;
continue;
}
LiveRangeMap[ Def ] = DefRange; // update the map
if( DEBUG_RA > 1) {
- cerr << " creating a LR for def: ";
- printValue(Def); cerr << endl;
+ cout << " creating a LR for def: ";
+ printValue(Def); cout << endl;
}
// set the register class of the new live range
if(isCC && DEBUG_RA) {
- cerr << "\a**created a LR for a CC reg:";
+ cout << "\a**created a LR for a CC reg:";
printValue( OpI.getMachineOperand().getVRegValue() );
}
LiveRangeMap[ Def ] = DefRange;
if( DEBUG_RA > 1) {
- cerr << " added to an existing LR for def: ";
- printValue( Def ); cerr << endl;
+ cout << " added to an existing LR for def: ";
+ printValue( Def ); cout << endl;
}
}
suggestRegs4CallRets();
if( DEBUG_RA)
- cerr << "Initial Live Ranges constructed!" << endl;
+ cout << "Initial Live Ranges constructed!" << endl;
}
*/
if( DEBUG_RA)
- cerr << endl << "Coalscing LRs ..." << endl;
+ cout << endl << "Coalscing LRs ..." << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
const MachineInstr * MInst = *MInstIterator;
if( DEBUG_RA > 1) {
- cerr << " *Iterating over machine instr ";
+ cout << " *Iterating over machine instr ";
MInst->dump();
- cerr << endl;
+ cout << endl;
}
//don't warn about labels
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
- cerr<<" !! Warning: No LR for use "; printValue(*UseI);
- cerr << endl;
+ cout<<" !! Warning: No LR for use "; printValue(*UseI);
+ cout << endl;
}
continue; // ignore and continue
}
} // for all BBs
if( DEBUG_RA)
- cerr << endl << "Coalscing Done!" << endl;
+ cout << endl << "Coalscing Done!" << endl;
}
void LiveRangeInfo::printLiveRanges()
{
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
- cerr << endl << "Printing Live Ranges from Hash Map:" << endl;
+ cout << endl << "Printing Live Ranges from Hash Map:" << endl;
for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
if( (*HMI).first && (*HMI).second ) {
- cerr <<" "; printValue((*HMI).first); cerr << "\t: ";
- ((*HMI).second)->printSet(); cerr << endl;
+ cout <<" "; printValue((*HMI).first); cout << "\t: ";
+ ((*HMI).second)->printSet(); cout << endl;
}
}
}
void PhyRegAlloc::createIGNodeListsAndIGs()
{
- if(DEBUG_RA ) cerr << "Creating LR lists ..." << endl;
+ if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
// hash map iterator
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
if( !L) {
if( DEBUG_RA) {
- cerr << "\n*?!?Warning: Null liver range found for: ";
- printValue( (*HMI).first) ; cerr << endl;
+ cout << "\n*?!?Warning: Null liver range found for: ";
+ printValue( (*HMI).first) ; cout << endl;
}
continue;
}
RegClassList[ rc ]->createInterferenceGraph();
if( DEBUG_RA)
- cerr << "LRLists Created!" << endl;
+ cout << "LRLists Created!" << endl;
}
for( ; LIt != LVSet->end(); ++LIt) {
if( DEBUG_RA > 1) {
- cerr << "< Def="; printValue(Def);
- cerr << ", Lvar="; printValue( *LIt); cerr << "> ";
+ cout << "< Def="; printValue(Def);
+ cout << ", Lvar="; printValue( *LIt); cout << "> ";
}
// get the live range corresponding to live var
}
//the live range of this var interferes with this call
- if( isCallInst )
+ if( isCallInst ) {
LROfVar->addCallInterference( (const Instruction *const) Def );
-
+ // cout << "\n ++Added Call Interf to set:";
+ // LROfVar->printSet();
+ }
}
else if(DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
- cerr << " warning: no live range for " ;
- printValue( *LIt); cerr << endl; }
+ cout << " warning: no live range for " ;
+ printValue( *LIt); cout << endl; }
}
void PhyRegAlloc::buildInterferenceGraphs()
{
- if(DEBUG_RA) cerr << "Creating interference graphs ..." << endl;
+ if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
+ // if( isCallInst) cout << "\n%%% Found call Inst:\n";
+
// iterate over MI operands to find defs
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
} // for all operands
+
+ // Also add interference for any implicit definitions in a machine
+ // instr (currently, only calls have this).
+
+ unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
+ if( NumOfImpRefs > 0 ) {
+ for(unsigned z=0; z < NumOfImpRefs; z++)
+ if( MInst->implicitRefIsDefined(z) )
+ addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
+ }
+
} // for all machine instructions in BB
else if( OpCode == Instruction::Ret )
RetInstrList.push_back( *InstIt );
- }
+ }
#endif
addInterferencesForArgs(); // add interference for method args
if( DEBUG_RA)
- cerr << "Interference graphs calculted!" << endl;
+ cout << "Interference graphs calculted!" << endl;
}
addInterference( *ArgIt, InSet, false ); // add interferences between
// args and LVars at start
if( DEBUG_RA > 1) {
- cerr << " - %% adding interference for argument ";
- printValue( (const Value *) *ArgIt); cerr << endl;
+ cout << " - %% adding interference for argument ";
+ printValue( (const Value *) *ArgIt); cout << endl;
}
}
}
-#if 0
-//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+// This method inserts caller saving/restoring instructons before/after
+// a call machine instruction.
//----------------------------------------------------------------------------
assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
int StackOff = 10; // ****TODO : Change
- set<unsigned> PushedRegSet();
+ hash_set<unsigned> PushedRegSet;
// Now find the LR of the return value of the call
// The last *implicit operand* is the return value of a call
if( MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
- const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1);
+ const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1);
LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
assert( RetValLR && "No LR for RetValue of call");
}
- LiveVarSet *LVSetAft = LVI->getLiveVarSetAfterMInst(MInst, BB);
+ const LiveVarSet *LVSetAft = LVI->getLiveVarSetAfterMInst(MInst, BB);
LiveVarSet::const_iterator LIt = LVSetAft->begin();
unsigned Reg = MRI.getUnifiedRegNum(RCID, Color);
- if( PuhsedRegSet.find(Reg) == PhusedRegSet.end() ) {
+ if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
// if we haven't already pushed that register
+
+ unsigned RegType = MRI.getRegType( LR );
+
+ // Now get two instructions - to push on stack and pop from stack
+ // and add them to InstrnsBefore and InstrnsAfter of the
+ // call instruction
- MachineInstr *AdI =
- MRI.saveRegOnStackMI(Reg, MRI.getFPReg(), StackOff );
-
- ((AddedInstrMap[MInst])->InstrnsBefore).push_front(AdI);
- ((AddedInstrMap[MInst])->InstrnsAfter).push_back(AdI);
-
+ MachineInstr *AdIBef =
+ MRI.cpReg2MemMI(Reg, MRI.getFramePointer(), StackOff, RegType );
+
+ MachineInstr *AdIAft =
+ MRI.cpMem2RegMI(MRI.getFramePointer(), StackOff, Reg, RegType );
+
+ ((AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
+ ((AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
PushedRegSet.insert( Reg );
StackOff += 4; // ****TODO: Correct ??????
- cerr << "Inserted caller saving instr");
+ cout << "\n $$$ Inserted caller saving instr";
} // if not already pushed
}
-#endif
//----------------------------------------------------------------------------
// This method is called after register allocation is complete to set the
MachineInstr *MInst = *MInstIterator;
+ // if this machine instr is call, insert caller saving code
+
+ if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
+ insertCallerSavingCode(MInst, *BBI );
- // If there are instructions before to be added, add them now
- // ***TODO: Add InstrnsAfter as well
+ // If there are instructions to be added, *before* this machine
+ // instruction, add them now.
+
if( AddedInstrMap[ MInst ] ) {
- deque<MachineInstr *> &IBef =
- (AddedInstrMap[MInst])->InstrnsBefore;
+ deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
if( ! IBef.empty() ) {
for( AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt ) {
- cerr << "*ADDED instr opcode: ";
- cerr << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
- cerr << endl;
+ cout << " *$* PREPENDed instr opcode: ";
+ cout << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
+ cout << endl;
MInstIterator = MIVec.insert( MInstIterator, *AdIt );
++MInstIterator;
}
- // restart from the topmost instruction added
- //MInst = *MInstIterator;
-
}
// delete this condition checking later (must assert if Val is null)
if( !Val) {
if (DEBUG_RA)
- cerr << "Warning: NULL Value found for operand" << endl;
+ cout << "Warning: NULL Value found for operand" << endl;
continue;
}
assert( Val && "Value is NULL");
// nothing to worry if it's a const or a label
if (DEBUG_RA) {
- cerr << "*NO LR for inst opcode: ";
- cerr << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+ cout << "*NO LR for inst opcode: ";
+ cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
}
+ // if register is not allocated, mark register as invalid
if( Op.getAllocatedRegNum() == -1)
- Op.setRegForValue( 1000 ); // mark register as invalid
+ Op.setRegForValue( MRI.getInvalidRegNum());
#if 0
if( ((Val->getType())->isLabelType()) ||
//TM.getInstrInfo().isReturn(MInst->getOpCode())
else if(TM.getInstrInfo().isReturn(MInst->getOpCode()) ) {
- if (DEBUG_RA) cerr << endl << "RETURN found" << endl;
+ if (DEBUG_RA) cout << endl << "RETURN found" << endl;
Op.setRegForValue( MRI.getReturnAddressReg() );
}
if (Val->getValueType() == Value::InstructionVal)
{
- cerr << "!Warning: No LiveRange for: ";
- printValue( Val); cerr << " Type: " << Val->getValueType();
- cerr << " RegVal=" << Op.getAllocatedRegNum() << endl;
+ cout << "!Warning: No LiveRange for: ";
+ printValue( Val); cout << " Type: " << Val->getValueType();
+ cout << " RegVal=" << Op.getAllocatedRegNum() << endl;
}
#endif
}
+ } // for each operand
+
+
+ // If there are instructions to be added *after* this machine
+ // instruction, add them now
+
+ if( AddedInstrMap[ MInst ] ) {
+
+ deque<MachineInstr *> &IAft = (AddedInstrMap[MInst])->InstrnsAfter;
+
+ if( ! IAft.empty() ) {
+
+ deque<MachineInstr *>::iterator AdIt;
+
+ ++MInstIterator; // advance to the next instruction
+
+ for( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) {
+
+ cout << " *#* APPENDed instr opcode: ";
+ cout << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
+ cout << endl;
+
+ MInstIterator = MIVec.insert( MInstIterator, *AdIt );
+ ++MInstIterator;
+ }
+
+ // MInsterator already points to the next instr. Since the
+ // for loop also increments it, decrement it to point to the
+ // instruction added last
+ --MInstIterator;
+
+ }
+
}
- }
+ } // for each machine instruction
}
}
void PhyRegAlloc::printMachineCode()
{
- cerr << endl << ";************** Method ";
- cerr << Meth->getName() << " *****************" << endl;
+ cout << endl << ";************** Method ";
+ cout << Meth->getName() << " *****************" << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
- cerr << endl ; printLabel( *BBI); cerr << ": ";
+ cout << endl ; printLabel( *BBI); cout << ": ";
// get the iterator for machine instructions
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
MachineInstr *const MInst = *MInstIterator;
- cerr << endl << "\t";
- cerr << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+ cout << endl << "\t";
+ cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
const Value *const Val = Op.getVRegValue () ;
// ****this code is temporary till NULL Values are fixed
if( ! Val ) {
- cerr << "\t<*NULL*>";
+ cout << "\t<*NULL*>";
continue;
}
// if a label or a constant
if( (Val->getValueType() == Value::BasicBlockVal) ) {
- cerr << "\t"; printLabel( Op.getVRegValue () );
+ cout << "\t"; printLabel( Op.getVRegValue () );
}
else {
// else it must be a register value
//if( RegNum != 1000)
- cerr << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
- // else cerr << "\t<*NoReg*>";
+ cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
+ // else cout << "\t<*NoReg*>";
}
}
else if(Op.getOperandType() == MachineOperand::MO_MachineRegister) {
- cerr << "\t" << "%" << MRI.getUnifiedRegName(Op.getMachineRegNum());
+ cout << "\t" << "%" << MRI.getUnifiedRegName(Op.getMachineRegNum());
}
else
- cerr << "\t" << Op; // use dump field
+ cout << "\t" << Op; // use dump field
}
- }
+
- cerr << endl;
+ unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
+ if( NumOfImpRefs > 0 ) {
+
+ cout << "\tImplicit:";
- }
+ for(unsigned z=0; z < NumOfImpRefs; z++) {
+ printValue( MInst->getImplicitRef(z) );
+ cout << "\t";
+ }
+
+ }
+
+ } // for all machine instructions
+
+
+ cout << endl;
+
+ } // for all BBs
- cerr << endl;
+ cout << endl;
}
void PhyRegAlloc::printLabel(const Value *const Val)
{
if( Val->hasName() )
- cerr << Val->getName();
+ cout << Val->getName();
else
- cerr << "Label" << Val;
+ cout << "Label" << Val;
}
void addInterferencesForArgs();
void createIGNodeListsAndIGs();
void buildInterferenceGraphs();
+ void insertCallerSavingCode(const MachineInstr *MInst,
+ const BasicBlock *BB );
+
inline void constructLiveRanges()
{ LRI.constructLiveRanges(); }
IG(this), IGNodeStack(), ReservedColorList(RCL)
{
if( DEBUG_RA)
- cerr << "Created Reg Class: " << RegClassID << endl;
+ cout << "Created Reg Class: " << RegClassID << endl;
// This constructor inits IG. The actual matrix is created by a call to
// createInterferenceGraph() above.
void RegClass::colorAllRegs()
{
- if(DEBUG_RA) cerr << "Coloring IGs ..." << endl;
+ if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
//preColorIGNodes(); // pre-color IGNodes
pushAllIGNodes(); // push all IG Nodes
bool PushedAll = pushUnconstrainedIGNodes();
if( DEBUG_RA) {
- cerr << " Puhsed all-unconstrained IGNodes. ";
- if( PushedAll ) cerr << " No constrained nodes left.";
- cerr << endl;
+ cout << " Puhsed all-unconstrained IGNodes. ";
+ if( PushedAll ) cout << " No constrained nodes left.";
+ cout << endl;
}
if( PushedAll ) // if NO constrained nodes left
IGNode->pushOnStack(); // set OnStack and dec deg of neighs
if (DEBUG_RA > 1) {
- cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ;
- cerr << " on to stack" << endl;
+ cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
+ cout << " on to stack" << endl;
}
}
else pushedall = false; // we didn't push all live ranges
}
else {
if( DEBUG_RA ) {
- cerr << " Node " << Node->getIndex();
- cerr << " already colored with color " << Node->getColor() << endl;
+ cout << " Node " << Node->getIndex();
+ cout << " already colored with color " << Node->getColor() << endl;
}
}
if( !Node->hasColor() ) {
if( DEBUG_RA ) {
- cerr << " Node " << Node->getIndex();
- cerr << " - could not find a color (needs spilling)" << endl;
+ cout << " Node " << Node->getIndex();
+ cout << " - could not find a color (needs spilling)" << endl;
}
}
IG = NULL;
Size = 0;
if( DEBUG_RA) {
- cerr << "Interference graph created!" << endl;
+ cout << "Interference graph created!" << endl;
}
}
char *val;
if( DEBUG_RA > 1)
- cerr << "setting intf for: [" << row << "][" << col << "]" << endl;
+ cout << "setting intf for: [" << row << "][" << col << "]" << endl;
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
assertIGNode( SrcNode );
if( DEBUG_RA > 1) {
- cerr << "Merging LRs: \""; LR1->printSet();
- cerr << "\" and \""; LR2->printSet();
- cerr << "\"" << endl;
+ cout << "Merging LRs: \""; LR1->printSet();
+ cout << "\" and \""; LR2->printSet();
+ cout << "\"" << endl;
}
unsigned SrcDegree = SrcNode->getNumOfNeighbors();
setInterference(LR1, LROfNeigh );
}
- //cerr<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
- //cerr << NeighNode->getNumOfNeighbors();
- //cerr << " Dest: [" << DestNode->getIndex() << "] ";
- //cerr << DestNode->getNumOfNeighbors() << endl;
+ //cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
+ //cout << NeighNode->getNumOfNeighbors();
+ //cout << " Dest: [" << DestNode->getIndex() << "] ";
+ //cout << DestNode->getNumOfNeighbors() << endl;
}
if( ! Node )
continue; // skip empty rows
- cerr << " [" << i << "] ";
+ cout << " [" << i << "] ";
for( unsigned int j=0; j < Size; j++) {
if( j >= i) break;
- if( IG[i][j] ) cerr << "(" << i << "," << j << ") ";
+ if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
}
- cerr << endl;
+ cout << endl;
}
}
if( ! Node )
continue;
- cerr << " [" << Node->getIndex() << "] ";
+ cout << " [" << Node->getIndex() << "] ";
(Node->getParentLR())->printSet();
//int Deg = Node->getCurDegree();
- cerr << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
+ cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
}
}
{
if( DEBUG_RA)
- cerr << "Consturcting Live Ranges ..." << endl;
+ cout << "Consturcting Live Ranges ..." << endl;
// first find the live ranges for all incoming args of the method since
// those LRs start from the start of the method
if( DEBUG_RA > 1) {
- cerr << " adding LiveRange for argument ";
- printValue( (const Value *) *ArgIt); cerr << endl;
+ cout << " adding LiveRange for argument ";
+ printValue( (const Value *) *ArgIt); cout << endl;
}
}
OpI.getMachineOperand().getOperandType();
if ( OpTyp == MachineOperand::MO_CCRegister) {
- cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
+ cout << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
printValue( OpI.getMachineOperand().getVRegValue() );
- cerr << endl;
+ cout << endl;
}
}
// Only instruction values are accepted for live ranges here
if( Def->getValueType() != Value::InstructionVal ) {
- cerr << "\n**%%Error: Def is not an instruction val. Def=";
- printValue( Def ); cerr << endl;
+ cout << "\n**%%Error: Def is not an instruction val. Def=";
+ printValue( Def ); cout << endl;
continue;
}
LiveRangeMap[ Def ] = DefRange; // update the map
if( DEBUG_RA > 1) {
- cerr << " creating a LR for def: ";
- printValue(Def); cerr << endl;
+ cout << " creating a LR for def: ";
+ printValue(Def); cout << endl;
}
// set the register class of the new live range
if(isCC && DEBUG_RA) {
- cerr << "\a**created a LR for a CC reg:";
+ cout << "\a**created a LR for a CC reg:";
printValue( OpI.getMachineOperand().getVRegValue() );
}
LiveRangeMap[ Def ] = DefRange;
if( DEBUG_RA > 1) {
- cerr << " added to an existing LR for def: ";
- printValue( Def ); cerr << endl;
+ cout << " added to an existing LR for def: ";
+ printValue( Def ); cout << endl;
}
}
suggestRegs4CallRets();
if( DEBUG_RA)
- cerr << "Initial Live Ranges constructed!" << endl;
+ cout << "Initial Live Ranges constructed!" << endl;
}
*/
if( DEBUG_RA)
- cerr << endl << "Coalscing LRs ..." << endl;
+ cout << endl << "Coalscing LRs ..." << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
const MachineInstr * MInst = *MInstIterator;
if( DEBUG_RA > 1) {
- cerr << " *Iterating over machine instr ";
+ cout << " *Iterating over machine instr ";
MInst->dump();
- cerr << endl;
+ cout << endl;
}
//don't warn about labels
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
- cerr<<" !! Warning: No LR for use "; printValue(*UseI);
- cerr << endl;
+ cout<<" !! Warning: No LR for use "; printValue(*UseI);
+ cout << endl;
}
continue; // ignore and continue
}
} // for all BBs
if( DEBUG_RA)
- cerr << endl << "Coalscing Done!" << endl;
+ cout << endl << "Coalscing Done!" << endl;
}
void LiveRangeInfo::printLiveRanges()
{
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
- cerr << endl << "Printing Live Ranges from Hash Map:" << endl;
+ cout << endl << "Printing Live Ranges from Hash Map:" << endl;
for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
if( (*HMI).first && (*HMI).second ) {
- cerr <<" "; printValue((*HMI).first); cerr << "\t: ";
- ((*HMI).second)->printSet(); cerr << endl;
+ cout <<" "; printValue((*HMI).first); cout << "\t: ";
+ ((*HMI).second)->printSet(); cout << endl;
}
}
}
void PhyRegAlloc::createIGNodeListsAndIGs()
{
- if(DEBUG_RA ) cerr << "Creating LR lists ..." << endl;
+ if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
// hash map iterator
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
if( !L) {
if( DEBUG_RA) {
- cerr << "\n*?!?Warning: Null liver range found for: ";
- printValue( (*HMI).first) ; cerr << endl;
+ cout << "\n*?!?Warning: Null liver range found for: ";
+ printValue( (*HMI).first) ; cout << endl;
}
continue;
}
RegClassList[ rc ]->createInterferenceGraph();
if( DEBUG_RA)
- cerr << "LRLists Created!" << endl;
+ cout << "LRLists Created!" << endl;
}
for( ; LIt != LVSet->end(); ++LIt) {
if( DEBUG_RA > 1) {
- cerr << "< Def="; printValue(Def);
- cerr << ", Lvar="; printValue( *LIt); cerr << "> ";
+ cout << "< Def="; printValue(Def);
+ cout << ", Lvar="; printValue( *LIt); cout << "> ";
}
// get the live range corresponding to live var
}
//the live range of this var interferes with this call
- if( isCallInst )
+ if( isCallInst ) {
LROfVar->addCallInterference( (const Instruction *const) Def );
-
+ // cout << "\n ++Added Call Interf to set:";
+ // LROfVar->printSet();
+ }
}
else if(DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
- cerr << " warning: no live range for " ;
- printValue( *LIt); cerr << endl; }
+ cout << " warning: no live range for " ;
+ printValue( *LIt); cout << endl; }
}
void PhyRegAlloc::buildInterferenceGraphs()
{
- if(DEBUG_RA) cerr << "Creating interference graphs ..." << endl;
+ if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
+ // if( isCallInst) cout << "\n%%% Found call Inst:\n";
+
// iterate over MI operands to find defs
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
} // for all operands
+
+ // Also add interference for any implicit definitions in a machine
+ // instr (currently, only calls have this).
+
+ unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
+ if( NumOfImpRefs > 0 ) {
+ for(unsigned z=0; z < NumOfImpRefs; z++)
+ if( MInst->implicitRefIsDefined(z) )
+ addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
+ }
+
} // for all machine instructions in BB
else if( OpCode == Instruction::Ret )
RetInstrList.push_back( *InstIt );
- }
+ }
#endif
addInterferencesForArgs(); // add interference for method args
if( DEBUG_RA)
- cerr << "Interference graphs calculted!" << endl;
+ cout << "Interference graphs calculted!" << endl;
}
addInterference( *ArgIt, InSet, false ); // add interferences between
// args and LVars at start
if( DEBUG_RA > 1) {
- cerr << " - %% adding interference for argument ";
- printValue( (const Value *) *ArgIt); cerr << endl;
+ cout << " - %% adding interference for argument ";
+ printValue( (const Value *) *ArgIt); cout << endl;
}
}
}
-#if 0
-//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+// This method inserts caller saving/restoring instructons before/after
+// a call machine instruction.
//----------------------------------------------------------------------------
assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
int StackOff = 10; // ****TODO : Change
- set<unsigned> PushedRegSet();
+ hash_set<unsigned> PushedRegSet;
// Now find the LR of the return value of the call
// The last *implicit operand* is the return value of a call
if( MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
- const Value *RetVal = CallMI->getImplicitRef(NumOfImpRefs-1);
+ const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1);
LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
assert( RetValLR && "No LR for RetValue of call");
}
- LiveVarSet *LVSetAft = LVI->getLiveVarSetAfterMInst(MInst, BB);
+ const LiveVarSet *LVSetAft = LVI->getLiveVarSetAfterMInst(MInst, BB);
LiveVarSet::const_iterator LIt = LVSetAft->begin();
unsigned Reg = MRI.getUnifiedRegNum(RCID, Color);
- if( PuhsedRegSet.find(Reg) == PhusedRegSet.end() ) {
+ if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
// if we haven't already pushed that register
+
+ unsigned RegType = MRI.getRegType( LR );
+
+ // Now get two instructions - to push on stack and pop from stack
+ // and add them to InstrnsBefore and InstrnsAfter of the
+ // call instruction
- MachineInstr *AdI =
- MRI.saveRegOnStackMI(Reg, MRI.getFPReg(), StackOff );
-
- ((AddedInstrMap[MInst])->InstrnsBefore).push_front(AdI);
- ((AddedInstrMap[MInst])->InstrnsAfter).push_back(AdI);
-
+ MachineInstr *AdIBef =
+ MRI.cpReg2MemMI(Reg, MRI.getFramePointer(), StackOff, RegType );
+
+ MachineInstr *AdIAft =
+ MRI.cpMem2RegMI(MRI.getFramePointer(), StackOff, Reg, RegType );
+
+ ((AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
+ ((AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
PushedRegSet.insert( Reg );
StackOff += 4; // ****TODO: Correct ??????
- cerr << "Inserted caller saving instr");
+ cout << "\n $$$ Inserted caller saving instr";
} // if not already pushed
}
-#endif
//----------------------------------------------------------------------------
// This method is called after register allocation is complete to set the
MachineInstr *MInst = *MInstIterator;
+ // if this machine instr is call, insert caller saving code
+
+ if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
+ insertCallerSavingCode(MInst, *BBI );
- // If there are instructions before to be added, add them now
- // ***TODO: Add InstrnsAfter as well
+ // If there are instructions to be added, *before* this machine
+ // instruction, add them now.
+
if( AddedInstrMap[ MInst ] ) {
- deque<MachineInstr *> &IBef =
- (AddedInstrMap[MInst])->InstrnsBefore;
+ deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
if( ! IBef.empty() ) {
for( AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt ) {
- cerr << "*ADDED instr opcode: ";
- cerr << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
- cerr << endl;
+ cout << " *$* PREPENDed instr opcode: ";
+ cout << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
+ cout << endl;
MInstIterator = MIVec.insert( MInstIterator, *AdIt );
++MInstIterator;
}
- // restart from the topmost instruction added
- //MInst = *MInstIterator;
-
}
// delete this condition checking later (must assert if Val is null)
if( !Val) {
if (DEBUG_RA)
- cerr << "Warning: NULL Value found for operand" << endl;
+ cout << "Warning: NULL Value found for operand" << endl;
continue;
}
assert( Val && "Value is NULL");
// nothing to worry if it's a const or a label
if (DEBUG_RA) {
- cerr << "*NO LR for inst opcode: ";
- cerr << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+ cout << "*NO LR for inst opcode: ";
+ cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
}
+ // if register is not allocated, mark register as invalid
if( Op.getAllocatedRegNum() == -1)
- Op.setRegForValue( 1000 ); // mark register as invalid
+ Op.setRegForValue( MRI.getInvalidRegNum());
#if 0
if( ((Val->getType())->isLabelType()) ||
//TM.getInstrInfo().isReturn(MInst->getOpCode())
else if(TM.getInstrInfo().isReturn(MInst->getOpCode()) ) {
- if (DEBUG_RA) cerr << endl << "RETURN found" << endl;
+ if (DEBUG_RA) cout << endl << "RETURN found" << endl;
Op.setRegForValue( MRI.getReturnAddressReg() );
}
if (Val->getValueType() == Value::InstructionVal)
{
- cerr << "!Warning: No LiveRange for: ";
- printValue( Val); cerr << " Type: " << Val->getValueType();
- cerr << " RegVal=" << Op.getAllocatedRegNum() << endl;
+ cout << "!Warning: No LiveRange for: ";
+ printValue( Val); cout << " Type: " << Val->getValueType();
+ cout << " RegVal=" << Op.getAllocatedRegNum() << endl;
}
#endif
}
+ } // for each operand
+
+
+ // If there are instructions to be added *after* this machine
+ // instruction, add them now
+
+ if( AddedInstrMap[ MInst ] ) {
+
+ deque<MachineInstr *> &IAft = (AddedInstrMap[MInst])->InstrnsAfter;
+
+ if( ! IAft.empty() ) {
+
+ deque<MachineInstr *>::iterator AdIt;
+
+ ++MInstIterator; // advance to the next instruction
+
+ for( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) {
+
+ cout << " *#* APPENDed instr opcode: ";
+ cout << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
+ cout << endl;
+
+ MInstIterator = MIVec.insert( MInstIterator, *AdIt );
+ ++MInstIterator;
+ }
+
+ // MInsterator already points to the next instr. Since the
+ // for loop also increments it, decrement it to point to the
+ // instruction added last
+ --MInstIterator;
+
+ }
+
}
- }
+ } // for each machine instruction
}
}
void PhyRegAlloc::printMachineCode()
{
- cerr << endl << ";************** Method ";
- cerr << Meth->getName() << " *****************" << endl;
+ cout << endl << ";************** Method ";
+ cout << Meth->getName() << " *****************" << endl;
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
- cerr << endl ; printLabel( *BBI); cerr << ": ";
+ cout << endl ; printLabel( *BBI); cout << ": ";
// get the iterator for machine instructions
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
MachineInstr *const MInst = *MInstIterator;
- cerr << endl << "\t";
- cerr << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
+ cout << endl << "\t";
+ cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
const Value *const Val = Op.getVRegValue () ;
// ****this code is temporary till NULL Values are fixed
if( ! Val ) {
- cerr << "\t<*NULL*>";
+ cout << "\t<*NULL*>";
continue;
}
// if a label or a constant
if( (Val->getValueType() == Value::BasicBlockVal) ) {
- cerr << "\t"; printLabel( Op.getVRegValue () );
+ cout << "\t"; printLabel( Op.getVRegValue () );
}
else {
// else it must be a register value
//if( RegNum != 1000)
- cerr << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
- // else cerr << "\t<*NoReg*>";
+ cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
+ // else cout << "\t<*NoReg*>";
}
}
else if(Op.getOperandType() == MachineOperand::MO_MachineRegister) {
- cerr << "\t" << "%" << MRI.getUnifiedRegName(Op.getMachineRegNum());
+ cout << "\t" << "%" << MRI.getUnifiedRegName(Op.getMachineRegNum());
}
else
- cerr << "\t" << Op; // use dump field
+ cout << "\t" << Op; // use dump field
}
- }
+
- cerr << endl;
+ unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
+ if( NumOfImpRefs > 0 ) {
+
+ cout << "\tImplicit:";
- }
+ for(unsigned z=0; z < NumOfImpRefs; z++) {
+ printValue( MInst->getImplicitRef(z) );
+ cout << "\t";
+ }
+
+ }
+
+ } // for all machine instructions
+
+
+ cout << endl;
+
+ } // for all BBs
- cerr << endl;
+ cout << endl;
}
void PhyRegAlloc::printLabel(const Value *const Val)
{
if( Val->hasName() )
- cerr << Val->getName();
+ cout << Val->getName();
else
- cerr << "Label" << Val;
+ cout << "Label" << Val;
}
void addInterferencesForArgs();
void createIGNodeListsAndIGs();
void buildInterferenceGraphs();
+ void insertCallerSavingCode(const MachineInstr *MInst,
+ const BasicBlock *BB );
+
inline void constructLiveRanges()
{ LRI.constructLiveRanges(); }
IG(this), IGNodeStack(), ReservedColorList(RCL)
{
if( DEBUG_RA)
- cerr << "Created Reg Class: " << RegClassID << endl;
+ cout << "Created Reg Class: " << RegClassID << endl;
// This constructor inits IG. The actual matrix is created by a call to
// createInterferenceGraph() above.
void RegClass::colorAllRegs()
{
- if(DEBUG_RA) cerr << "Coloring IGs ..." << endl;
+ if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
//preColorIGNodes(); // pre-color IGNodes
pushAllIGNodes(); // push all IG Nodes
bool PushedAll = pushUnconstrainedIGNodes();
if( DEBUG_RA) {
- cerr << " Puhsed all-unconstrained IGNodes. ";
- if( PushedAll ) cerr << " No constrained nodes left.";
- cerr << endl;
+ cout << " Puhsed all-unconstrained IGNodes. ";
+ if( PushedAll ) cout << " No constrained nodes left.";
+ cout << endl;
}
if( PushedAll ) // if NO constrained nodes left
IGNode->pushOnStack(); // set OnStack and dec deg of neighs
if (DEBUG_RA > 1) {
- cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ;
- cerr << " on to stack" << endl;
+ cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
+ cout << " on to stack" << endl;
}
}
else pushedall = false; // we didn't push all live ranges
}
else {
if( DEBUG_RA ) {
- cerr << " Node " << Node->getIndex();
- cerr << " already colored with color " << Node->getColor() << endl;
+ cout << " Node " << Node->getIndex();
+ cout << " already colored with color " << Node->getColor() << endl;
}
}
if( !Node->hasColor() ) {
if( DEBUG_RA ) {
- cerr << " Node " << Node->getIndex();
- cerr << " - could not find a color (needs spilling)" << endl;
+ cout << " Node " << Node->getIndex();
+ cout << " - could not find a color (needs spilling)" << endl;
}
}
// %o0 to %o5 (cannot be changed)
unsigned const NumOfIntArgRegs;
unsigned const NumOfFloatArgRegs;
- unsigned const InvalidRegNum;
+ int const InvalidRegNum;
//void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
-
- MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
- const int RegType) const;
+ // ***TODO: See this method is necessary
MachineInstr * cpValue2RegMI(Value * Val, const unsigned DestReg,
const int RegType) const;
return reg + 32 + 64; // 32 int, 64 float
else if( RegClassID == IntCCRegClassID )
return 4+ 32 + 64; // only int cc reg
- else if (reg==1000) //****** TODO: Remove
- return 1000;
+ else if (reg==InvalidRegNum)
+ return InvalidRegNum;
else
assert(0 && "Invalid register class or reg number");
else if ( reg == 64+32+4)
return "xcc"; // only integer cc reg
- else if (reg==1000) //****** TODO: Remove
+ else if (reg== InvalidRegNum) //****** TODO: Remove
return "<*NoReg*>";
else
assert(0 && "Invalid register number");
}
+ MachineInstr * cpReg2RegMI(const unsigned SrcReg, const unsigned DestReg,
+ const int RegType) const;
+
+ MachineInstr * cpReg2MemMI(const unsigned SrcReg, const unsigned DestPtrReg,
+ const int Offset, const int RegType) const;
+
+ MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset,
+ const unsigned DestReg, const int RegType) const;
+
+ inline bool isRegVolatile(const int RegClassID, const int Reg) const {
+ return (MachineRegClassArr[RegClassID])->isRegVolatile(Reg);
+ }
+
+
+ inline unsigned getFramePointer() const {
+ return SparcIntRegOrder::i6;
+ }
+
+ inline unsigned getStackPointer() const {
+ return SparcIntRegOrder::o6;
+ }
+
+ inline int getInvalidRegNum() const {
+ return InvalidRegNum;
+ }
+
};
/*numEntries*/ 0,
/* V[] */ {
/*Cycle G */
- /*Cycle E */
+ /*Ccle E */
/*Cycle C */
/*Cycle N1*/
/*Cycle N1*/
g0, g1, g2, g3, g4, g5, g6, g7, i6, i7, o6
+ //*** NOTE: If we decide to use globals, some of them are volatile
+ //**** see sparc64ABI (change isRegVloatile method below)
};
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
+ inline bool isRegVolatile(const int Reg) const {
+ return (Reg < (int) SparcIntRegOrder::StartOfNonVolatileRegs);
+ }
+
};
//-----------------------------------------------------------------------------
void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
+ // according to Sparc 64 ABI, all %fp regs are volatile
+ inline bool isRegVolatile(const int Reg) const { return true; }
+
+
};
Node->setColor(0); // only one int cc reg is available
}
+ // *** TODO: Check this
+ inline bool isRegVolatile(const int Reg) const { return true; }
+
};
return FloatCCRegNames[reg];
}
+ // according to Sparc 64 ABI, all %fp regs are volatile
+ inline bool isRegVolatile(const int Reg) const { return true; }
+
+
};
Node->setColor(c);
}
+ // *** TODO: Check this
+ inline bool isRegVolatile(const int Reg) const { return true; }
+
+
};
// TODO (Optimize):
- //Instead of setting the color, we can suggest one. In that case,
+ // Instead of setting the color, we can suggest one. In that case,
// we have to test later whether it received the suggested color.
// In that case, a LR has to be created at the start of method.
// It has to be done as follows (remove the setRegVal above):
UniRetReg = getUnifiedRegNum( RegClassID, SparcFloatRegOrder::f0);
- AdMI = cpReg2RegMI(UniRetLRReg, UniRetReg, RegType );
+ AdMI = cpReg2RegMI(UniRetReg, UniRetLRReg, RegType );
CallAI->InstrnsAfter.push_back( AdMI );
const unsigned DestReg,
const int RegType) const {
- assert( (SrcReg != InvalidRegNum) && (DestReg != InvalidRegNum) &&
+ assert( ((int)SrcReg != InvalidRegNum) && ((int)DestReg != InvalidRegNum) &&
"Invalid Register");
MachineInstr * MI = NULL;
}
+//---------------------------------------------------------------------------
+// Copy from a register to memory. Register number must be the unified
+// register number
+//---------------------------------------------------------------------------
+
+
+MachineInstr * UltraSparcRegInfo::cpReg2MemMI(const unsigned SrcReg,
+ const unsigned DestPtrReg,
+ const int Offset,
+ const int RegType) const {
+
+
+ MachineInstr * MI = NULL;
+
+ switch( RegType ) {
+
+ case IntRegType:
+ MI = new MachineInstr(STX, 3);
+ MI->SetMachineOperand(0, DestPtrReg, false);
+ MI->SetMachineOperand(1, SrcReg, false);
+ MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ break;
+
+ case FPSingleRegType:
+ MI = new MachineInstr(ST, 3);
+ MI->SetMachineOperand(0, DestPtrReg, false);
+ MI->SetMachineOperand(1, SrcReg, false);
+ MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ break;
+
+ case FPDoubleRegType:
+ MI = new MachineInstr(STD, 3);
+ MI->SetMachineOperand(0, DestPtrReg, false);
+ MI->SetMachineOperand(1, SrcReg, false);
+ MI->SetMachineOperand(2, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ break;
+
+ default:
+ assert(0 && "Unknow RegType");
+ }
+
+ return MI;
+}
+
+
+//---------------------------------------------------------------------------
+// Copy from memory to a reg. Register number must be the unified
+// register number
+//---------------------------------------------------------------------------
+
+
+MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg,
+ const int Offset,
+ const unsigned DestReg,
+ const int RegType) const {
+
+ MachineInstr * MI = NULL;
+
+ switch( RegType ) {
+
+ case IntRegType:
+ MI = new MachineInstr(LDX, 3);
+ MI->SetMachineOperand(0, SrcPtrReg, false);
+ MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ MI->SetMachineOperand(2, DestReg, false);
+ break;
+
+ case FPSingleRegType:
+ MI = new MachineInstr(LD, 3);
+ MI->SetMachineOperand(0, SrcPtrReg, false);
+ MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ MI->SetMachineOperand(2, DestReg, false);
+
+ break;
+
+ case FPDoubleRegType:
+ MI = new MachineInstr(LDD, 3);
+ MI->SetMachineOperand(0, SrcPtrReg, false);
+ MI->SetMachineOperand(1, MachineOperand:: MO_SignExtendedImmed,
+ (int64_t) Offset, false);
+ MI->SetMachineOperand(2, DestReg, false);
+ break;
+
+ default:
+ assert(0 && "Unknow RegType");
+ }
+
+ return MI;
+}
+
+
+
+
+
+
+
//---------------------------------------------------------------------------
const unsigned DestReg,
const int RegType) const {
- assert( (DestReg != InvalidRegNum) && "Invalid Register");
+ assert( ((int)DestReg != InvalidRegNum) && "Invalid Register");
/*
unsigned MReg;