summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2003-07-06 20:13:59 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2003-07-06 20:13:59 +0000
commit786833ad3498036db72776f9b708ff08a6f8e29a (patch)
tree50a5d92bc2e7b19ebb00e933bcdf1041aa8d1c21 /lib
parent6e5031e0b80db455b7139a6a40fe0a35d10492b4 (diff)
downloadllvm-786833ad3498036db72776f9b708ff08a6f8e29a.tar.gz
llvm-786833ad3498036db72776f9b708ff08a6f8e29a.tar.bz2
llvm-786833ad3498036db72776f9b708ff08a6f8e29a.tar.xz
Major bug fix though it happened rarely (only on a compare after an
integer overflow): We need to use %icc and not %xcc for comparisons on 32-bit or smaller integer values. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7111 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/SparcV9/SparcV9AsmPrinter.cpp19
-rw-r--r--lib/Target/SparcV9/SparcV9InstrSelection.cpp16
-rw-r--r--lib/Target/SparcV9/SparcV9RegClassInfo.cpp41
-rw-r--r--lib/Target/SparcV9/SparcV9RegClassInfo.h21
-rw-r--r--lib/Target/SparcV9/SparcV9RegInfo.cpp22
5 files changed, 82 insertions, 37 deletions
diff --git a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
index f66b36f9be..829a3b8bb3 100644
--- a/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
+++ b/lib/Target/SparcV9/SparcV9AsmPrinter.cpp
@@ -393,12 +393,27 @@ SparcFunctionAsmPrinter::printOneOperand(const MachineOperand &mop,
switch (mop.getType())
{
- case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_CCRegister:
+ {
+ // We need to print %icc or %xcc as %ccr for certain opcodes.
+ int regNum = (int)mop.getAllocatedRegNum();
+ if (regNum != Target.getRegInfo().getInvalidRegNum() &&
+ Target.getRegInfo().getRegClassIDOfReg(regNum)
+ == UltraSparcRegInfo::IntCCRegClassID)
+ {
+ if (opCode == V9::RDCCR || opCode == V9::WRCCRi || opCode == V9::WRCCRr)
+ {
+ toAsm << "%" << Target.getRegInfo().getMachineRegClass(UltraSparcRegInfo::IntCCRegClassID)->getRegName(SparcIntCCRegClass::ccr);
+ break;
+ }
+ }
+ // all other cases can be handled like any other register
+ }
+
+ case MachineOperand::MO_VirtualRegister:
case MachineOperand::MO_MachineRegister:
{
int regNum = (int)mop.getAllocatedRegNum();
-
if (regNum == Target.getRegInfo().getInvalidRegNum()) {
// better to print code with NULL registers than to die
toAsm << "<NULL VALUE>";
diff --git a/lib/Target/SparcV9/SparcV9InstrSelection.cpp b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
index 58c15edc29..abb7fbecc8 100644
--- a/lib/Target/SparcV9/SparcV9InstrSelection.cpp
+++ b/lib/Target/SparcV9/SparcV9InstrSelection.cpp
@@ -386,16 +386,14 @@ GetTmpForCC(Value* boolVal, const Function *F, const Type* ccType,
static inline MachineOpCode
ChooseBccInstruction(const InstructionNode* instrNode,
- bool& isFPBranch)
+ const Type*& setCCType)
{
InstructionNode* setCCNode = (InstructionNode*) instrNode->leftChild();
assert(setCCNode->getOpLabel() == SetCCOp);
BinaryOperator* setCCInstr =cast<BinaryOperator>(setCCNode->getInstruction());
- const Type* setCCType = setCCInstr->getOperand(0)->getType();
+ setCCType = setCCInstr->getOperand(0)->getType();
- isFPBranch = setCCType->isFloatingPoint(); // Return value: don't delete!
-
- if (isFPBranch)
+ if (setCCType->isFloatingPoint())
return ChooseBFpccInstruction(instrNode, setCCInstr);
else
return ChooseBpccInstruction(instrNode, setCCInstr);
@@ -1604,11 +1602,11 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
// TmpInstruction representing that CC.
//
BranchInst* brInst = cast<BranchInst>(subtreeRoot->getInstruction());
- bool isFPBranch;
- unsigned Opcode = ChooseBccInstruction(subtreeRoot, isFPBranch);
+ const Type* setCCType;
+ unsigned Opcode = ChooseBccInstruction(subtreeRoot, setCCType);
Value* ccValue = GetTmpForCC(subtreeRoot->leftChild()->getValue(),
brInst->getParent()->getParent(),
- isFPBranch? Type::FloatTy : Type::IntTy,
+ setCCType,
MachineCodeForInstruction::get(brInst));
M = BuildMI(Opcode, 2).addCCReg(ccValue)
.addPCDisp(brInst->getSuccessor(0));
@@ -2058,7 +2056,7 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
//
TmpInstruction* tmpForCC = GetTmpForCC(setCCInstr,
setCCInstr->getParent()->getParent(),
- isFPCompare ? Type::FloatTy : Type::IntTy,
+ leftVal->getType(),
MachineCodeForInstruction::get(setCCInstr));
if (! isFPCompare) {
// Integer condition: set CC and discard result.
diff --git a/lib/Target/SparcV9/SparcV9RegClassInfo.cpp b/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
index 63b39c1624..1640dcab6c 100644
--- a/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9RegClassInfo.cpp
@@ -112,6 +112,47 @@ void SparcIntRegClass::colorIGNode(IGNode * Node,
LR->markForSpill(); // no color found - must spill
}
+//-----------------------------------------------------------------------------
+// Int CC Register Class - method for coloring a node in the interference graph.
+//
+// Algorithm:
+//
+// If the single int CC register is used (either as icc or xcc)
+// mark the LR for spilling
+// else {
+// if (the LR is a 64-bit comparison) use %xcc
+// else /*32-bit or smaller*/ use %icc
+// }
+//
+// Note: The third name (%ccr) is essentially an assembly mnemonic and
+// depends solely on the opcode, so the name can be chosen in EmitAssembly.
+//-----------------------------------------------------------------------------
+void SparcIntCCRegClass::colorIGNode(IGNode *Node,
+ std::vector<bool> &IsColorUsedArr) const
+{
+ if (IsColorUsedArr[xcc] && IsColorUsedArr[icc])
+ Node->getParentLR()->markForSpill();
+ else {
+ // Choose whether to use %xcc or %icc based on type of value compared
+ const LiveRange* ccLR = Node->getParentLR();
+ const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
+ assert(setCCType->isIntegral());
+ int ccReg = (setCCType == Type::LongTy)? xcc : icc;
+
+#ifndef NDEBUG
+ // Let's just make sure values of two different types have not been
+ // coalesced into this LR.
+ for (ValueSet::const_iterator I=ccLR->begin(), E=ccLR->end(); I != E; ++I)
+ assert(setCCType->isIntegral() &&
+ ((ccReg == xcc && (*I)->getType() == Type::LongTy) ||
+ (ccReg == icc && (*I)->getType() != Type::LongTy))
+ && "Comparisons needing different intCC regs coalesced in LR!");
+#endif
+
+ Node->setColor(ccReg); // only one int cc reg is available
+ }
+}
+
//-----------------------------------------------------------------------------
// Float Register Class - method for coloring a node in the interference graph.
diff --git a/lib/Target/SparcV9/SparcV9RegClassInfo.h b/lib/Target/SparcV9/SparcV9RegClassInfo.h
index bc9b445d5d..50cccb6621 100644
--- a/lib/Target/SparcV9/SparcV9RegClassInfo.h
+++ b/lib/Target/SparcV9/SparcV9RegClassInfo.h
@@ -113,29 +113,24 @@ public:
//-----------------------------------------------------------------------------
// Int CC Register Class
// 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.
+// referred to as %xcc or %icc 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, three ids are
+// allocated for the three names.
//-----------------------------------------------------------------------------
struct SparcIntCCRegClass : public TargetRegClassInfo {
SparcIntCCRegClass(unsigned ID)
- : TargetRegClassInfo(ID, 1, 2) { }
-
- void colorIGNode(IGNode *Node, std::vector<bool> &IsColorUsedArr) const {
- if (IsColorUsedArr[0])
- Node->getParentLR()->markForSpill();
- else
- Node->setColor(0); // only one int cc reg is available
- }
+ : TargetRegClassInfo(ID, 1, 3) { }
+ void colorIGNode(IGNode *Node, std::vector<bool> &IsColorUsedArr) const;
+
// according to Sparc 64 ABI, %ccr is volatile
//
inline bool isRegVolatile(int Reg) const { return true; }
enum {
- xcc, ccr // only one is available - see the note above
+ xcc, icc, ccr // only one is available - see the note above
};
const char * const getRegName(unsigned reg) const;
diff --git a/lib/Target/SparcV9/SparcV9RegInfo.cpp b/lib/Target/SparcV9/SparcV9RegInfo.cpp
index 95bd87f950..962b9f68d1 100644
--- a/lib/Target/SparcV9/SparcV9RegInfo.cpp
+++ b/lib/Target/SparcV9/SparcV9RegInfo.cpp
@@ -98,11 +98,11 @@ const char * const SparcFloatRegClass::getRegName(unsigned reg) const {
static const char * const IntCCRegNames[] = {
- "xcc", "ccr"
+ "xcc", "icc", "ccr"
};
const char * const SparcIntCCRegClass::getRegName(unsigned reg) const {
- assert(reg < 2);
+ assert(reg < 3);
return IntCCRegNames[reg];
}
@@ -1088,15 +1088,14 @@ UltraSparcRegInfo::cpReg2RegMI(std::vector<MachineInstr*>& mvec,
case IntCCRegType:
if (getRegType(DestReg) == IntRegType) {
// copy intCC reg to int reg
- // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
- MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(DestReg,MOTy::Def);
+ MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr).
+ addMReg(DestReg,MOTy::Def));
} else {
// copy int reg to intCC reg
- // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
assert(getRegType(SrcReg) == IntRegType
&& "Can only copy CC reg to/from integer reg");
- MI = BuildMI(V9::WRCCRr, 3).addMReg(SrcReg)
- .addMReg(SparcIntRegClass::g0).addMReg(DestReg+1, MOTy::Def);
+ MI = (BuildMI(V9::WRCCRr, 3).addMReg(SrcReg).addMReg(SparcIntRegClass::g0)
+ .addMReg(SparcIntCCRegClass::ccr, MOTy::Def));
}
break;
@@ -1161,9 +1160,8 @@ UltraSparcRegInfo::cpReg2MemMI(std::vector<MachineInstr*>& mvec,
case IntCCRegType:
assert(scratchReg >= 0 && "Need scratch reg to store %ccr to memory");
assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
-
- // Use SrcReg+1 to get the name "%ccr" instead of "%xcc" for RDCCR
- MI = BuildMI(V9::RDCCR, 2).addMReg(SrcReg+1).addMReg(scratchReg, MOTy::Def);
+ MI = (BuildMI(V9::RDCCR, 2).addMReg(SparcIntCCRegClass::ccr)
+ .addMReg(scratchReg, MOTy::Def));
mvec.push_back(MI);
cpReg2MemMI(mvec, scratchReg, DestPtrReg, Offset, IntRegType);
@@ -1221,10 +1219,8 @@ UltraSparcRegInfo::cpMem2RegMI(std::vector<MachineInstr*>& mvec,
assert(scratchReg >= 0 && "Need scratch reg to load %ccr from memory");
assert(getRegType(scratchReg) ==IntRegType && "Invalid scratch reg");
cpMem2RegMI(mvec, SrcPtrReg, Offset, scratchReg, IntRegType);
-
- // Use DestReg+1 to get the name "%ccr" instead of "%xcc" for WRCCR
MI = BuildMI(V9::WRCCRr, 3).addMReg(scratchReg)
- .addMReg(SparcIntRegClass::g0).addMReg(DestReg+1,MOTy::Def);
+ .addMReg(SparcIntRegClass::g0).addMReg(SparcIntCCRegClass::ccr,MOTy::Def);
break;
case FloatCCRegType: {