aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2005-12-20 07:37:41 +0000
committerEvan Cheng <evan.cheng@apple.com>2005-12-20 07:37:41 +0000
commit4fba28116cefb160cbe11e54777bb8cde89f5d73 (patch)
tree9ea33ed64a23f46c55f12a5ccc97ed8e0b82cfd9 /utils/TableGen
parent7226158d7e3986e55b58214a749aa4eabb3fb6d5 (diff)
downloadexternal_llvm-4fba28116cefb160cbe11e54777bb8cde89f5d73.zip
external_llvm-4fba28116cefb160cbe11e54777bb8cde89f5d73.tar.gz
external_llvm-4fba28116cefb160cbe11e54777bb8cde89f5d73.tar.bz2
Now support instructions with implicit write to non-flag registers.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24878 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/DAGISelEmitter.cpp142
1 files changed, 91 insertions, 51 deletions
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index 155dfad..3b0d4ea 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -1763,7 +1763,6 @@ private:
// Names of all the folded nodes which produce chains.
std::vector<std::pair<std::string, unsigned> > FoldedChains;
bool FoundChain;
- bool InFlag;
unsigned TmpNo;
public:
@@ -1771,7 +1770,7 @@ public:
TreePatternNode *pattern, TreePatternNode *instr,
unsigned PatNum, std::ostream &os) :
ISE(ise), Predicates(preds), Pattern(pattern), Instruction(instr),
- PatternNo(PatNum), OS(os), FoundChain(false), InFlag(false), TmpNo(0) {};
+ PatternNo(PatNum), OS(os), FoundChain(false), TmpNo(0) {};
/// EmitMatchCode - Emit a matcher for N, going to the label for PatternNo
/// if the match fails. At this point, we already know that the opcode for N
@@ -1884,10 +1883,6 @@ public:
if (LeafRec->isSubClassOf("RegisterClass")) {
// Handle register references. Nothing to do here.
} else if (LeafRec->isSubClassOf("Register")) {
- if (!InFlag) {
- OS << " SDOperand InFlag = SDOperand(0,0);\n";
- InFlag = true;
- }
} else if (LeafRec->isSubClassOf("ComplexPattern")) {
// Handle complex pattern. Nothing to do here.
} else if (LeafRec->getName() == "srcvalue") {
@@ -2015,6 +2010,16 @@ public:
Record *Op = N->getOperator();
if (Op->isSubClassOf("Instruction")) {
+ const DAGInstruction &Inst = ISE.getInstruction(Op);
+ unsigned NumImpResults = Inst.getNumImpResults();
+ unsigned NumImpOperands = Inst.getNumImpOperands();
+ bool InFlag = NumImpOperands > 0;
+ bool OutFlag = NumImpResults > 0;
+ bool IsCopyFromReg = false;
+
+ if (InFlag || OutFlag)
+ OS << " SDOperand InFlag = SDOperand(0,0);\n";
+
// Determine operand emission order. Complex pattern first.
std::vector<std::pair<unsigned, TreePatternNode*> > EmitOrder;
std::vector<std::pair<unsigned, TreePatternNode*> >::iterator OI;
@@ -2052,10 +2057,9 @@ public:
// Emit all the chain and CopyToReg stuff.
if (II.hasCtrlDep)
OS << " Chain = Select(Chain);\n";
- EmitCopyToRegs(Pattern, "N", II.hasCtrlDep);
+ if (InFlag)
+ EmitCopyToRegs(Pattern, "N", II.hasCtrlDep);
- const DAGInstruction &Inst = ISE.getInstruction(Op);
- unsigned NumImpResults = Inst.getNumImpResults();
unsigned NumResults = Inst.getNumResults();
unsigned ResNo = TmpNo++;
if (!isRoot) {
@@ -2063,11 +2067,8 @@ public:
<< II.Namespace << "::" << II.TheDef->getName();
if (N->getType() != MVT::isVoid)
OS << ", MVT::" << getEnumName(N->getType());
- for (unsigned i = 0; i < NumImpResults; i++) {
- Record *ImpResult = Inst.getImpResult(i);
- MVT::ValueType RVT = getRegisterValueType(ImpResult, CGT);
- OS << ", MVT::" << getEnumName(RVT);
- }
+ if (OutFlag)
+ OS << ", MVT::Flag";
unsigned LastOp = 0;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
@@ -2080,7 +2081,7 @@ public:
OS << " Chain = Tmp" << LastOp << ".getValue("
<< NumResults << ");\n";
}
- } else if (II.hasCtrlDep || NumImpResults > 0) {
+ } else if (II.hasCtrlDep || OutFlag) {
OS << " SDOperand Result = CurDAG->getTargetNode("
<< II.Namespace << "::" << II.TheDef->getName();
@@ -2093,11 +2094,8 @@ public:
}
if (II.hasCtrlDep)
OS << ", MVT::Other";
- for (unsigned i = 0; i < NumImpResults; i++) {
- Record *ImpResult = Inst.getImpResult(i);
- MVT::ValueType RVT = getRegisterValueType(ImpResult, CGT);
- OS << ", MVT::" << getEnumName(RVT);
- }
+ if (OutFlag)
+ OS << ", MVT::Flag";
// Inputs.
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
@@ -2114,33 +2112,43 @@ public:
}
if (II.hasCtrlDep) {
- OS << " Chain ";
- if (NodeHasChain(Pattern, ISE))
- OS << "= CodeGenMap[N.getValue(" << ValNo + NumImpResults << ")] ";
+ OS << " Chain = Result.getValue(" << ValNo << ");\n";
+ if (OutFlag)
+ OS << " InFlag = Result.getValue(" << ValNo+1 << ");\n";
+ } else if (OutFlag)
+ OS << " InFlag = Result.getValue(" << ValNo << ");\n";
+
+ if (OutFlag)
+ IsCopyFromReg = EmitCopyFromRegs(N, II.hasCtrlDep);
+ if (IsCopyFromReg)
+ OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = Result;\n";
+
+ if (OutFlag)
+ OS << " CodeGenMap[N.getValue(" << ValNo++ << ")] = InFlag;\n";
+
+ if (IsCopyFromReg || II.hasCtrlDep) {
+ OS << " ";
+ if (IsCopyFromReg || NodeHasChain(Pattern, ISE))
+ OS << "CodeGenMap[N.getValue(" << ValNo << ")] = ";
for (unsigned j = 0, e = FoldedChains.size(); j < e; j++)
- OS << "= CodeGenMap[" << FoldedChains[j].first << ".getValue("
- << FoldedChains[j].second << ")] ";
- OS << "= Result.getValue(" << ValNo << ");\n";
- for (unsigned i = 0; i < NumImpResults; i++) {
- OS << " CodeGenMap[N.getValue(" << ValNo << ")] = Result";
- OS << ".getValue(" << ValNo+1 << ");\n";
- ValNo++;
- }
- } else {
- for (unsigned i = 0; i < NumImpResults; i++) {
- OS << " CodeGenMap[N.getValue(" << ValNo << ")] = Result";
- OS << ".getValue(" << ValNo << ");\n";
- ValNo++;
- }
+ OS << "CodeGenMap[" << FoldedChains[j].first << ".getValue("
+ << FoldedChains[j].second << ")] = ";
+ OS << "Chain;\n";
}
// FIXME: this only works because (for now) an instruction can either
// produce a single result or a single flag.
- if (II.hasCtrlDep && NumImpResults > 0)
- OS << " return (N.ResNo) ? Chain : Result.getValue(1);"
- << " // Chain comes before flag.\n";
- else
+ if (II.hasCtrlDep && OutFlag) {
+ if (IsCopyFromReg)
+ OS << " return (N.ResNo == 0) ? Result : "
+ << "((N.ResNo == 2) ? Chain : InFlag);"
+ << " // Chain comes before flag.\n";
+ else
+ OS << " return (N.ResNo) ? Chain : InFlag;"
+ << " // Chain comes before flag.\n";
+ } else {
OS << " return Result.getValue(N.ResNo);\n";
+ }
} else {
// If this instruction is the root, and if there is only one use of it,
// use SelectNodeTo instead of getTargetNode to avoid an allocation.
@@ -2149,11 +2157,8 @@ public:
<< II.Namespace << "::" << II.TheDef->getName();
if (N->getType() != MVT::isVoid)
OS << ", MVT::" << getEnumName(N->getType());
- for (unsigned i = 0; i < NumImpResults; i++) {
- Record *ImpResult = Inst.getImpResult(i);
- MVT::ValueType RVT = getRegisterValueType(ImpResult, CGT);
- OS << ", MVT::" << getEnumName(RVT);
- }
+ if (OutFlag)
+ OS << ", MVT::Flag";
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
OS << ", Tmp" << Ops[i];
if (InFlag)
@@ -2164,11 +2169,8 @@ public:
<< II.Namespace << "::" << II.TheDef->getName();
if (N->getType() != MVT::isVoid)
OS << ", MVT::" << getEnumName(N->getType());
- for (unsigned i = 0; i < NumImpResults; i++) {
- Record *ImpResult = Inst.getImpResult(i);
- MVT::ValueType RVT = getRegisterValueType(ImpResult, CGT);
- OS << ", MVT::" << getEnumName(RVT);
- }
+ if (OutFlag)
+ OS << ", MVT::Flag";
for (unsigned i = 0, e = Ops.size(); i != e; ++i)
OS << ", Tmp" << Ops[i];
if (InFlag)
@@ -2176,6 +2178,7 @@ public:
OS << ");\n";
OS << " }\n";
}
+
return std::make_pair(1, ResNo);
} else if (Op->isSubClassOf("SDNodeXForm")) {
assert(N->getNumChildren() == 1 && "node xform should have one child!");
@@ -2259,6 +2262,43 @@ private:
}
}
}
+
+ /// EmitCopyFromRegs - Emit code to copy result to physical registers
+ /// as specified by the instruction.
+ bool EmitCopyFromRegs(TreePatternNode *N, bool HasCtrlDep) {
+ bool RetVal = false;
+ Record *Op = N->getOperator();
+ if (Op->isSubClassOf("Instruction")) {
+ const DAGInstruction &Inst = ISE.getInstruction(Op);
+ const CodeGenTarget &CGT = ISE.getTargetInfo();
+ CodeGenInstruction &II = CGT.getInstruction(Op->getName());
+ unsigned NumImpResults = Inst.getNumImpResults();
+ for (unsigned i = 0; i < NumImpResults; i++) {
+ Record *RR = Inst.getImpResult(i);
+ if (RR->isSubClassOf("Register")) {
+ MVT::ValueType RVT = getRegisterValueType(RR, CGT);
+ if (RVT != MVT::Flag) {
+ if (HasCtrlDep) {
+ OS << " Result = CurDAG->getCopyFromReg(Chain, "
+ << ISE.getQualifiedName(RR)
+ << ", MVT::" << getEnumName(RVT) << ", InFlag);\n";
+ OS << " Chain = Result.getValue(1);\n";
+ OS << " InFlag = Result.getValue(2);\n";
+ } else {
+ OS << " SDOperand Chain;\n";
+ OS << " Result = CurDAG->getCopyFromReg("
+ << "CurDAG->getEntryNode(), ISE.getQualifiedName(RR)"
+ << ", MVT::" << getEnumName(RVT) << ", InFlag);\n";
+ OS << " Chain = Result.getValue(1);\n";
+ OS << " InFlag = Result.getValue(2);\n";
+ }
+ RetVal = true;
+ }
+ }
+ }
+ }
+ return RetVal;
+ }
};
/// EmitCodeForPattern - Given a pattern to match, emit code to the specified