From 78a4f23a8e2c14d708899d1bd2011b64584fafa7 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Tue, 27 May 2003 00:02:22 +0000 Subject: [PATCH] Added special register class containing (for now) %fsr. Fixed spilling of %fcc[0-3] which are part of %fsr. Moved some machine-independent reg-class code to class TargetRegInfo from SparcReg{Class,}Info. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6339 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SparcV9/SparcV9AsmPrinter.cpp | 26 ++-- lib/Target/SparcV9/SparcV9InstrSelection.cpp | 4 +- lib/Target/SparcV9/SparcV9Internals.h | 60 ++------ lib/Target/SparcV9/SparcV9RegClassInfo.h | 37 ++++- lib/Target/SparcV9/SparcV9RegInfo.cpp | 142 ++++++++----------- 5 files changed, 111 insertions(+), 158 deletions(-) diff --git a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp index 1509fdbb94e..f6761d03cfe 100644 --- a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp +++ b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp @@ -302,7 +302,7 @@ private : void emitMachineInst(const MachineInstr *MI); unsigned int printOperands(const MachineInstr *MI, unsigned int opNum); - void printOneOperand(const MachineOperand &Op); + void printOneOperand(const MachineOperand &Op, MachineOpCode opCode); bool OpIsBranchTargetLabel(const MachineInstr *MI, unsigned int opNum); bool OpIsMemoryAddressBase(const MachineInstr *MI, unsigned int opNum); @@ -341,10 +341,10 @@ SparcFunctionAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI, } -#define PrintOp1PlusOp2(mop1, mop2) \ - printOneOperand(mop1); \ +#define PrintOp1PlusOp2(mop1, mop2, opCode) \ + printOneOperand(mop1, opCode); \ toAsm << "+"; \ - printOneOperand(mop2); + printOneOperand(mop2, opCode); unsigned int SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI, @@ -354,26 +354,26 @@ SparcFunctionAsmPrinter::printOperands(const MachineInstr *MI, if (OpIsBranchTargetLabel(MI, opNum)) { - PrintOp1PlusOp2(mop, MI->getOperand(opNum+1)); + PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); return 2; } else if (OpIsMemoryAddressBase(MI, opNum)) { toAsm << "["; - PrintOp1PlusOp2(mop, MI->getOperand(opNum+1)); + PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode()); toAsm << "]"; return 2; } else { - printOneOperand(mop); + printOneOperand(mop, MI->getOpCode()); return 1; } } - void -SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop) +SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop, + MachineOpCode opCode) { bool needBitsFlag = true; @@ -394,13 +394,13 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop) case MachineOperand::MO_CCRegister: case MachineOperand::MO_MachineRegister: { - int RegNum = (int)mop.getAllocatedRegNum(); + int regNum = (int)mop.getAllocatedRegNum(); - // better to print code with NULL registers than to die - if (RegNum == Target.getRegInfo().getInvalidRegNum()) { + if (regNum == Target.getRegInfo().getInvalidRegNum()) { + // better to print code with NULL registers than to die toAsm << ""; } else { - toAsm << "%" << Target.getRegInfo().getUnifiedRegName(RegNum); + toAsm << "%" << Target.getRegInfo().getUnifiedRegName(regNum); } break; } diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp index 99754a7f18f..30881ce6ee7 100644 --- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp +++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp @@ -1318,8 +1318,8 @@ ForwardOperand(InstructionNode* treeNode, for (unsigned i=0,numOps=minstr->getNumImplicitRefs(); igetImplicitRef(i) == unusedOp) minstr->setImplicitRef(i, fwdOp, - minstr->implicitRefIsDefined(i), - minstr->implicitRefIsDefinedAndUsed(i)); + minstr->getImplicitOp(i).opIsDefOnly(), + minstr->getImplicitOp(i).opIsDefAndUse()); } } } diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h index f49f6158333..d2177e7b67c 100644 --- a/lib/Target/SparcV9/SparcV9Internals.h +++ b/lib/Target/SparcV9/SparcV9Internals.h @@ -255,7 +255,8 @@ class UltraSparcRegInfo : public TargetRegInfo { IntRegClassID, // Integer FloatRegClassID, // Float (both single/double) IntCCRegClassID, // Int Condition Code - FloatCCRegClassID // Float Condition code + FloatCCRegClassID, // Float Condition code + SpecialRegClassID // Special (unallocated) registers }; @@ -268,7 +269,8 @@ class UltraSparcRegInfo : public TargetRegInfo { FPSingleRegType, FPDoubleRegType, IntCCRegType, - FloatCCRegType + FloatCCRegType, + SpecialRegType }; // **** WARNING: If the above enum order is changed, also modify @@ -308,6 +310,9 @@ class UltraSparcRegInfo : public TargetRegInfo { std::vector& AddedInstrnsBefore) const; + // Get the register type for a register identified different ways. + // The first function is a helper used by the all the hoter functions. + int getRegTypeForClassAndType(unsigned regClassID, const Type* type) const; int getRegType(const Type* type) const; int getRegType(const LiveRange *LR) const; int getRegType(int unifiedRegNum) const; @@ -352,7 +357,6 @@ public: // To find the register class to which a specified register belongs // - unsigned getRegClassIDOfReg(int unifiedRegNum) const; unsigned getRegClassIDOfRegType(int regType) const; // getZeroRegNum - returns the register that contains always zero this is the @@ -403,56 +407,8 @@ public: // method used for printing a register for debugging purposes // - static void printReg(const LiveRange *LR); - - // Each register class has a seperate space for register IDs. To convert - // a regId in a register class to a common Id, or vice versa, - // we use the folloing methods. - // - // This method provides a unique number for each register - inline int getUnifiedRegNum(unsigned regClassID, int reg) const { - - if (regClassID == IntRegClassID) { - assert(reg < 32 && "Invalid reg. number"); - return reg; - } - else if (regClassID == FloatRegClassID) { - assert(reg < 64 && "Invalid reg. number"); - return reg + 32; // we have 32 int regs - } - else if (regClassID == FloatCCRegClassID) { - assert(reg < 4 && "Invalid reg. number"); - return reg + 32 + 64; // 32 int, 64 float - } - else if (regClassID == IntCCRegClassID ) { - assert(reg == 0 && "Invalid reg. number"); - return reg + 4+ 32 + 64; // only one int CC reg - } - else if (reg==InvalidRegNum) { - return InvalidRegNum; - } - else - assert(0 && "Invalid register class"); - return 0; - } + void printReg(const LiveRange *LR) const; - // This method converts the unified number to the number in its class, - // and returns the class ID in regClassID. - inline int getClassRegNum(int ureg, unsigned& regClassID) const { - if (ureg < 32) { regClassID = IntRegClassID; return ureg; } - else if (ureg < 32+64) { regClassID = FloatRegClassID; return ureg-32; } - else if (ureg < 4 +96) { regClassID = FloatCCRegClassID; return ureg-96; } - else if (ureg < 1 +100) { regClassID = IntCCRegClassID; return ureg-100;} - else if (ureg == InvalidRegNum) { return InvalidRegNum; } - else { assert(0 && "Invalid unified register number"); } - return 0; - } - - // Returns the assembly-language name of the specified machine register. - // - virtual const char * const getUnifiedRegName(int reg) const; - - // returns the # of bytes of stack space allocated for each register // type. For Sparc, currently we allocate 8 bytes on stack for all // register types. We can optimize this later if necessary to save stack diff --git a/lib/Target/SparcV9/SparcV9RegClassInfo.h b/lib/Target/SparcV9/SparcV9RegClassInfo.h index a8a39eb86a7..bc9b445d5d0 100644 --- a/lib/Target/SparcV9/SparcV9RegClassInfo.h +++ b/lib/Target/SparcV9/SparcV9RegClassInfo.h @@ -63,7 +63,7 @@ struct SparcIntRegClass : public TargetRegClassInfo { StartOfAllRegs = o0, }; - static const char * const getRegName(unsigned reg); + const char * const getRegName(unsigned reg) const; }; @@ -104,7 +104,7 @@ public: StartOfAllRegs = f0, }; - static const char * const getRegName(unsigned reg); + const char * const getRegName(unsigned reg) const; }; @@ -138,7 +138,7 @@ struct SparcIntCCRegClass : public TargetRegClassInfo { xcc, ccr // only one is available - see the note above }; - static const char * const getRegName(unsigned reg); + const char * const getRegName(unsigned reg) const; }; @@ -146,12 +146,12 @@ struct SparcIntCCRegClass : public TargetRegClassInfo { //----------------------------------------------------------------------------- // Float CC Register Class -// Only 4 Float CC registers are available +// Only 4 Float CC registers are available for allocation. //----------------------------------------------------------------------------- struct SparcFloatCCRegClass : public TargetRegClassInfo { SparcFloatCCRegClass(unsigned ID) - : TargetRegClassInfo(ID, 4, 4) { } + : TargetRegClassInfo(ID, 4, 5) { } void colorIGNode(IGNode *Node, std::vector &IsColorUsedArr) const { for(unsigned c = 0; c != 4; ++c) @@ -168,10 +168,33 @@ struct SparcFloatCCRegClass : public TargetRegClassInfo { inline bool isRegVolatile(int Reg) const { return true; } enum { - fcc0, fcc1, fcc2, fcc3 + fcc0, fcc1, fcc2, fcc3, fsr // fsr is not used in allocation + }; // but has a name in getRegName() + + const char * const getRegName(unsigned reg) const; +}; + +//----------------------------------------------------------------------------- +// Sparc special register class. These registers are not used for allocation +// but are used as arguments of some instructions. +//----------------------------------------------------------------------------- + +struct SparcSpecialRegClass : public TargetRegClassInfo { + SparcSpecialRegClass(unsigned ID) + : TargetRegClassInfo(ID, 0, 1) { } + + void colorIGNode(IGNode *Node, std::vector &IsColorUsedArr) const { + assert(0 && "SparcSpecialRegClass should never be used for allocation"); + } + + // all currently included special regs are volatile + inline bool isRegVolatile(int Reg) const { return true; } + + enum { + fsr // floating point state register }; - static const char * const getRegName(unsigned reg); + const char * const getRegName(unsigned reg) const; }; #endif diff --git a/lib/Target/SparcV9/SparcV9RegInfo.cpp b/lib/Target/SparcV9/SparcV9RegInfo.cpp index 1e5c09e56cf..de83adf56f3 100644 --- a/lib/Target/SparcV9/SparcV9RegInfo.cpp +++ b/lib/Target/SparcV9/SparcV9RegInfo.cpp @@ -32,6 +32,7 @@ UltraSparcRegInfo::UltraSparcRegInfo(const UltraSparc &tgt) MachineRegClassArr.push_back(new SparcFloatRegClass(FloatRegClassID)); MachineRegClassArr.push_back(new SparcIntCCRegClass(IntCCRegClassID)); MachineRegClassArr.push_back(new SparcFloatCCRegClass(FloatCCRegClassID)); + MachineRegClassArr.push_back(new SparcSpecialRegClass(SpecialRegClassID)); assert(SparcFloatRegClass::StartOfNonVolatileRegs == 32 && "32 Float regs are used for float arg passing"); @@ -75,7 +76,7 @@ static const char * const IntRegNames[] = { "o6" }; -const char * const SparcIntRegClass::getRegName(unsigned reg) { +const char * const SparcIntRegClass::getRegName(unsigned reg) const { assert(reg < NumOfAllRegs); return IntRegNames[reg]; } @@ -90,7 +91,7 @@ static const char * const FloatRegNames[] = { "f60", "f61", "f62", "f63" }; -const char * const SparcFloatRegClass::getRegName(unsigned reg) { +const char * const SparcFloatRegClass::getRegName(unsigned reg) const { assert (reg < NumOfAllRegs); return FloatRegNames[reg]; } @@ -100,7 +101,7 @@ static const char * const IntCCRegNames[] = { "xcc", "ccr" }; -const char * const SparcIntCCRegClass::getRegName(unsigned reg) { +const char * const SparcIntCCRegClass::getRegName(unsigned reg) const { assert(reg < 2); return IntCCRegNames[reg]; } @@ -109,28 +110,18 @@ static const char * const FloatCCRegNames[] = { "fcc0", "fcc1", "fcc2", "fcc3" }; -const char * const SparcFloatCCRegClass::getRegName(unsigned reg) { - assert (reg < 4); +const char * const SparcFloatCCRegClass::getRegName(unsigned reg) const { + assert (reg < 5); return FloatCCRegNames[reg]; } -// given the unified register number, this gives the name -// for generating assembly code or debugging. -// -const char * const UltraSparcRegInfo::getUnifiedRegName(int reg) const { - if( reg < 32 ) - return SparcIntRegClass::getRegName(reg); - else if ( reg < (64 + 32) ) - return SparcFloatRegClass::getRegName( reg - 32); - else if( reg < (64+32+4) ) - return SparcFloatCCRegClass::getRegName( reg -32 - 64); - else if( reg < (64+32+4+2) ) // two names: %xcc and %ccr - return SparcIntCCRegClass::getRegName( reg -32 - 64 - 4); - else if (reg== InvalidRegNum) //****** TODO: Remove */ - return "<*NoReg*>"; - else - assert(0 && "Invalid register number"); - return ""; +static const char * const SpecialRegNames[] = { + "fsr" +}; + +const char * const SparcSpecialRegClass::getRegName(unsigned reg) const { + assert (reg < 1); + return SpecialRegNames[reg]; } // Get unified reg number for frame pointer @@ -230,43 +221,34 @@ UltraSparcRegInfo::regNumForFPArg(unsigned regType, // The following 4 methods are used to find the RegType (SparcInternals.h) // of a LiveRange, a Value, and for a given register unified reg number. // -int UltraSparcRegInfo::getRegType(const Type* type) const { - unsigned regClassID = getRegClassIDOfType(type); +int UltraSparcRegInfo::getRegTypeForClassAndType(unsigned regClassID, + const Type* type) const +{ switch (regClassID) { - case IntRegClassID: return IntRegType; - case FloatRegClassID: { - if (type == Type::FloatTy) - return FPSingleRegType; - else if (type == Type::DoubleTy) - return FPDoubleRegType; - assert(0 && "Unknown type in FloatRegClass"); - } - case IntCCRegClassID: return IntCCRegType; - case FloatCCRegClassID: return FloatCCRegType; + case IntRegClassID: return IntRegType; + case FloatRegClassID: + if (type == Type::FloatTy) return FPSingleRegType; + else if (type == Type::DoubleTy) return FPDoubleRegType; + assert(0 && "Unknown type in FloatRegClass"); return 0; + case IntCCRegClassID: return IntCCRegType; + case FloatCCRegClassID: return FloatCCRegType; + case SpecialRegClassID: return SpecialRegType; default: assert( 0 && "Unknown reg class ID"); return 0; } } -int UltraSparcRegInfo::getRegType(const LiveRange *LR) const { - const Type* type = LR->getType(); - - unsigned regClassID = LR->getRegClassID(); - switch (regClassID) { - default: assert( 0 && "Unknown reg class ID"); - case IntRegClassID: return IntRegType; - case FloatRegClassID: - if (type == Type::FloatTy) - return FPSingleRegType; - else if (type == Type::DoubleTy) - return FPDoubleRegType; - assert(0 && "Unknown type in FloatRegClass"); - case IntCCRegClassID: return IntCCRegType; - case FloatCCRegClassID: return FloatCCRegType; - } +int UltraSparcRegInfo::getRegType(const Type* type) const +{ + return getRegTypeForClassAndType(getRegClassIDOfType(type), type); } +int UltraSparcRegInfo::getRegType(const LiveRange *LR) const +{ + return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType()); +} -int UltraSparcRegInfo::getRegType(int unifiedRegNum) const { +int UltraSparcRegInfo::getRegType(int unifiedRegNum) const +{ if (unifiedRegNum < 32) return IntRegType; else if (unifiedRegNum < (32 + 32)) @@ -308,14 +290,6 @@ unsigned UltraSparcRegInfo::getRegClassIDOfType(const Type *type, return res; } -// To find the register class to which a specified register belongs -// -unsigned UltraSparcRegInfo::getRegClassIDOfReg(int unifiedRegNum) const { - unsigned classId = 0; - (void) getClassRegNum(unifiedRegNum, classId); - return classId; -} - unsigned UltraSparcRegInfo::getRegClassIDOfRegType(int regType) const { switch(regType) { case IntRegType: return IntRegClassID; @@ -1183,13 +1157,14 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector& mvec, cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType); return; - case FloatCCRegType: - assert(0 && "Tell Vikram if this assertion fails: we may have to mask out the other bits here"); + case FloatCCRegType: { assert(target.getInstrInfo().constantFitsInImmedField(V9::STXFSR, Offset)); - MI = BuildMI(V9::STXFSR, 3).addMReg(SrcReg).addMReg(DestPtrReg) - .addSImm(Offset); + unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID, + SparcSpecialRegClass::fsr); + MI = BuildMI(V9::STXFSR, 3) + .addMReg(fsrRegNum).addMReg(DestPtrReg).addSImm(Offset); break; - + } default: assert(0 && "Unknown RegType in cpReg2MemMI"); } @@ -1239,14 +1214,14 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector& mvec, MI = BuildMI(V9::WRCCR, 2).addMReg(scratchReg).addMReg(DestReg+1,MOTy::Def); break; - case FloatCCRegType: - assert(0 && "Tell Vikram if this assertion fails: we may have to mask " - "out the other bits here"); + case FloatCCRegType: { assert(target.getInstrInfo().constantFitsInImmedField(V9::LDXFSR, Offset)); + unsigned fsrRegNum = getUnifiedRegNum(UltraSparcRegInfo::SpecialRegClassID, + SparcSpecialRegClass::fsr); MI = BuildMI(V9::LDXFSR, 3).addMReg(SrcPtrReg).addSImm(Offset) - .addMReg(DestReg, MOTy::Def); + .addMReg(fsrRegNum, MOTy::UseAndDef); break; - + } default: assert(0 && "Unknown RegType in cpMem2RegMI"); } @@ -1462,7 +1437,7 @@ UltraSparcRegInfo::insertCallerSavingCode // Print the register assigned to a LR //--------------------------------------------------------------------------- -void UltraSparcRegInfo::printReg(const LiveRange *LR) { +void UltraSparcRegInfo::printReg(const LiveRange *LR) const { unsigned RegClassID = LR->getRegClassID(); std::cerr << " *Node " << (LR->getUserIGNode())->getIndex(); @@ -1475,15 +1450,13 @@ void UltraSparcRegInfo::printReg(const LiveRange *LR) { std::cerr << " colored with color "<< LR->getColor(); - if (RegClassID == IntRegClassID) { - std::cerr<< " [" << SparcIntRegClass::getRegName(LR->getColor()) << "]\n"; - - } else if (RegClassID == FloatRegClassID) { - std::cerr << "[" << SparcFloatRegClass::getRegName(LR->getColor()); - if( LR->getType() == Type::DoubleTy) - std::cerr << "+" << SparcFloatRegClass::getRegName(LR->getColor()+1); - std::cerr << "]\n"; - } + unsigned uRegName = getUnifiedRegNum(RegClassID, LR->getColor()); + + std::cerr << "["; + std::cerr<< getUnifiedRegName(uRegName); + if (RegClassID == FloatRegClassID && LR->getType() == Type::DoubleTy) + std::cerr << "+" << getUnifiedRegName(uRegName+1); + std::cerr << "]\n"; } //--------------------------------------------------------------------------- @@ -1559,7 +1532,7 @@ void UltraSparcRegInfo::OrderAddedInstrns(std::vector &UnordVec, // last operand is the def (unless for a store which has no def reg) MachineOperand& DefOp = DefInst->getOperand(DefInst->getNumOperands()-1); - if (DefOp.opIsDef() && + if ((DefOp.opIsDefOnly() || DefOp.opIsDefAndUse()) && DefOp.getType() == MachineOperand::MO_MachineRegister) { // If the operand in DefInst is a def ... @@ -1576,7 +1549,7 @@ void UltraSparcRegInfo::OrderAddedInstrns(std::vector &UnordVec, // for each inst (UseInst) that is below the DefInst do ... MachineOperand& UseOp = UseInst->getOperand(0); - if (!UseOp.opIsDef() && + if (!UseOp.opIsDefOnly() && UseOp.getType() == MachineOperand::MO_MachineRegister) { // if use is a register ... @@ -1637,7 +1610,7 @@ void UltraSparcRegInfo::moveInst2OrdVec(std::vector &OrdVec, PhyRegAlloc &PRA) const { MachineOperand& UseOp = UnordInst->getOperand(0); - if (!UseOp.opIsDef() && + if (!UseOp.opIsDefOnly() && UseOp.getType() == MachineOperand::MO_MachineRegister) { // for the use of UnordInst, see whether there is a defining instr @@ -1653,7 +1626,7 @@ void UltraSparcRegInfo::moveInst2OrdVec(std::vector &OrdVec, MachineOperand& DefOp = OrdInst->getOperand(OrdInst->getNumOperands()-1); - if( DefOp.opIsDef() && + if( (DefOp.opIsDefOnly() || DefOp.opIsDefAndUse()) && DefOp.getType() == MachineOperand::MO_MachineRegister) { //std::cerr << "\nDefining Ord Inst: " << *OrdInst; @@ -1686,7 +1659,8 @@ void UltraSparcRegInfo::moveInst2OrdVec(std::vector &OrdVec, // Load directly into DReg (%oy) MachineOperand& DOp= (UnordInst->getOperand(UnordInst->getNumOperands()-1)); - assert(DOp.opIsDef() && "Last operand is not the def"); + assert((DOp.opIsDefOnly() || DefOp.opIsDefAndUse()) && + "Last operand is not the def"); const int DReg = DOp.getMachineRegNum(); cpMem2RegMI(OrdVec, getFramePointer(), StackOff, DReg, RegType);