aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/TargetMachine/Sparc/Sparc.cpp')
-rw-r--r--lib/CodeGen/TargetMachine/Sparc/Sparc.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp
index f66d10e749..372b7e0dca 100644
--- a/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp
+++ b/lib/CodeGen/TargetMachine/Sparc/Sparc.cpp
@@ -9,11 +9,307 @@
// 7/15/01 - Vikram Adve - Created
//**************************************************************************/
+#include "llvm/Method.h"
+#include "llvm/Instruction.h"
+
+#include "llvm/CodeGen/LiveRange.h"
+#include "llvm/CodeGen/LiveRangeInfo.h"
#include "llvm/CodeGen/Sparc.h"
+#include "llvm/CodeGen/SparcRegInfo.h"
//************************ Class Implementations **************************/
+
+
+
+//---------------------------------------------------------------------------
+// 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 ) 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!");
+ }
+ ++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 UltraSparcInstrInfo
//
@@ -79,6 +375,11 @@ UltraSparcSchedInfo::initializeResources()
}
+
+
+
+
+
//---------------------------------------------------------------------------
// class UltraSparcMachine
//
@@ -91,10 +392,12 @@ UltraSparcSchedInfo::initializeResources()
//---------------------------------------------------------------------------
UltraSparc::UltraSparc()
+
: TargetMachine("UltraSparc-Native")
{
machineInstrInfo = new UltraSparcInstrInfo;
machineSchedInfo = new UltraSparcSchedInfo(machineInstrInfo);
+ machineRegInfo = new UltraSparcRegInfo(this);
optSizeForSubWordData = 4;
minMemOpWordSize = 8;
@@ -105,6 +408,7 @@ UltraSparc::UltraSparc()
UltraSparc::~UltraSparc()
{
delete (UltraSparcInstrInfo*) machineInstrInfo;
+ delete (UltraSparcRegInfo*) machineRegInfo;
delete (UltraSparcSchedInfo*) machineSchedInfo;
}