mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 07:34:33 +00:00
Tablegen: Add OperandWithDefaultOps Operand type
This Operand type takes a default argument, and is initialized to this value if it does not appear in a patter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163315 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4178946afb
commit
6d3d765653
@ -602,23 +602,31 @@ def f64imm : Operand<f64>;
|
||||
///
|
||||
def zero_reg;
|
||||
|
||||
/// OperandWithDefaultOps - This Operand class can be used as the parent class
|
||||
/// for an Operand that needs to be initialized with a default value if
|
||||
/// no value is supplied in a pattern. This class can be used to simplify the
|
||||
/// pattern definitions for instructions that have target specific flags
|
||||
/// encoded as immediate operands.
|
||||
class OperandWithDefaultOps<ValueType ty, dag defaultops>
|
||||
: Operand<ty> {
|
||||
dag DefaultOps = defaultops;
|
||||
}
|
||||
|
||||
/// PredicateOperand - This can be used to define a predicate operand for an
|
||||
/// instruction. OpTypes specifies the MIOperandInfo for the operand, and
|
||||
/// AlwaysVal specifies the value of this predicate when set to "always
|
||||
/// execute".
|
||||
class PredicateOperand<ValueType ty, dag OpTypes, dag AlwaysVal>
|
||||
: Operand<ty> {
|
||||
: OperandWithDefaultOps<ty, AlwaysVal> {
|
||||
let MIOperandInfo = OpTypes;
|
||||
dag DefaultOps = AlwaysVal;
|
||||
}
|
||||
|
||||
/// OptionalDefOperand - This is used to define a optional definition operand
|
||||
/// for an instruction. DefaultOps is the register the operand represents if
|
||||
/// none is supplied, e.g. zero_reg.
|
||||
class OptionalDefOperand<ValueType ty, dag OpTypes, dag defaultops>
|
||||
: Operand<ty> {
|
||||
: OperandWithDefaultOps<ty, defaultops> {
|
||||
let MIOperandInfo = OpTypes;
|
||||
dag DefaultOps = defaultops;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1575,8 +1575,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
||||
// If the instruction expects a predicate or optional def operand, we
|
||||
// codegen this by setting the operand to it's default value if it has a
|
||||
// non-empty DefaultOps field.
|
||||
if ((OperandNode->isSubClassOf("PredicateOperand") ||
|
||||
OperandNode->isSubClassOf("OptionalDefOperand")) &&
|
||||
if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
|
||||
!CDP.getDefaultOperand(OperandNode).DefaultOps.empty())
|
||||
continue;
|
||||
|
||||
@ -2173,53 +2172,46 @@ void CodeGenDAGPatterns::ParsePatternFragments() {
|
||||
}
|
||||
|
||||
void CodeGenDAGPatterns::ParseDefaultOperands() {
|
||||
std::vector<Record*> DefaultOps[2];
|
||||
DefaultOps[0] = Records.getAllDerivedDefinitions("PredicateOperand");
|
||||
DefaultOps[1] = Records.getAllDerivedDefinitions("OptionalDefOperand");
|
||||
std::vector<Record*> DefaultOps;
|
||||
DefaultOps = Records.getAllDerivedDefinitions("OperandWithDefaultOps");
|
||||
|
||||
// Find some SDNode.
|
||||
assert(!SDNodes.empty() && "No SDNodes parsed?");
|
||||
Init *SomeSDNode = DefInit::get(SDNodes.begin()->first);
|
||||
|
||||
for (unsigned iter = 0; iter != 2; ++iter) {
|
||||
for (unsigned i = 0, e = DefaultOps[iter].size(); i != e; ++i) {
|
||||
DagInit *DefaultInfo = DefaultOps[iter][i]->getValueAsDag("DefaultOps");
|
||||
for (unsigned i = 0, e = DefaultOps.size(); i != e; ++i) {
|
||||
DagInit *DefaultInfo = DefaultOps[i]->getValueAsDag("DefaultOps");
|
||||
|
||||
// Clone the DefaultInfo dag node, changing the operator from 'ops' to
|
||||
// SomeSDnode so that we can parse this.
|
||||
std::vector<std::pair<Init*, std::string> > Ops;
|
||||
for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
|
||||
Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
|
||||
DefaultInfo->getArgName(op)));
|
||||
DagInit *DI = DagInit::get(SomeSDNode, "", Ops);
|
||||
// Clone the DefaultInfo dag node, changing the operator from 'ops' to
|
||||
// SomeSDnode so that we can parse this.
|
||||
std::vector<std::pair<Init*, std::string> > Ops;
|
||||
for (unsigned op = 0, e = DefaultInfo->getNumArgs(); op != e; ++op)
|
||||
Ops.push_back(std::make_pair(DefaultInfo->getArg(op),
|
||||
DefaultInfo->getArgName(op)));
|
||||
DagInit *DI = DagInit::get(SomeSDNode, "", Ops);
|
||||
|
||||
// Create a TreePattern to parse this.
|
||||
TreePattern P(DefaultOps[iter][i], DI, false, *this);
|
||||
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
|
||||
// Create a TreePattern to parse this.
|
||||
TreePattern P(DefaultOps[i], DI, false, *this);
|
||||
assert(P.getNumTrees() == 1 && "This ctor can only produce one tree!");
|
||||
|
||||
// Copy the operands over into a DAGDefaultOperand.
|
||||
DAGDefaultOperand DefaultOpInfo;
|
||||
// Copy the operands over into a DAGDefaultOperand.
|
||||
DAGDefaultOperand DefaultOpInfo;
|
||||
|
||||
TreePatternNode *T = P.getTree(0);
|
||||
for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
|
||||
TreePatternNode *TPN = T->getChild(op);
|
||||
while (TPN->ApplyTypeConstraints(P, false))
|
||||
/* Resolve all types */;
|
||||
TreePatternNode *T = P.getTree(0);
|
||||
for (unsigned op = 0, e = T->getNumChildren(); op != e; ++op) {
|
||||
TreePatternNode *TPN = T->getChild(op);
|
||||
while (TPN->ApplyTypeConstraints(P, false))
|
||||
/* Resolve all types */;
|
||||
|
||||
if (TPN->ContainsUnresolvedType()) {
|
||||
if (iter == 0)
|
||||
throw "Value #" + utostr(i) + " of PredicateOperand '" +
|
||||
DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
|
||||
else
|
||||
throw "Value #" + utostr(i) + " of OptionalDefOperand '" +
|
||||
DefaultOps[iter][i]->getName() +"' doesn't have a concrete type!";
|
||||
}
|
||||
DefaultOpInfo.DefaultOps.push_back(TPN);
|
||||
if (TPN->ContainsUnresolvedType()) {
|
||||
throw "Value #" + utostr(i) + " of OperandWithDefaultOps '" +
|
||||
DefaultOps[i]->getName() +"' doesn't have a concrete type!";
|
||||
}
|
||||
|
||||
// Insert it into the DefaultOperands map so we can find it later.
|
||||
DefaultOperands[DefaultOps[iter][i]] = DefaultOpInfo;
|
||||
DefaultOpInfo.DefaultOps.push_back(TPN);
|
||||
}
|
||||
|
||||
// Insert it into the DefaultOperands map so we can find it later.
|
||||
DefaultOperands[DefaultOps[i]] = DefaultOpInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2687,11 +2679,9 @@ void CodeGenDAGPatterns::ParseInstructions() {
|
||||
I->error("Operand #" + utostr(i) + " in operands list has no name!");
|
||||
|
||||
if (!InstInputsCheck.count(OpName)) {
|
||||
// If this is an predicate operand or optional def operand with an
|
||||
// DefaultOps set filled in, we can ignore this. When we codegen it,
|
||||
// we will do so as always executed.
|
||||
if (Op.Rec->isSubClassOf("PredicateOperand") ||
|
||||
Op.Rec->isSubClassOf("OptionalDefOperand")) {
|
||||
// If this is an operand with a DefaultOps set filled in, we can ignore
|
||||
// this. When we codegen it, we will do so as always executed.
|
||||
if (Op.Rec->isSubClassOf("OperandWithDefaultOps")) {
|
||||
// Does it have a non-empty DefaultOps field? If so, ignore this
|
||||
// operand.
|
||||
if (!getDefaultOperand(Op.Rec).DefaultOps.empty())
|
||||
|
@ -582,8 +582,8 @@ private:
|
||||
void ComputeNamedNodes(TreePatternNode *N);
|
||||
};
|
||||
|
||||
/// DAGDefaultOperand - One of these is created for each PredicateOperand
|
||||
/// or OptionalDefOperand that has a set ExecuteAlways / DefaultOps field.
|
||||
/// DAGDefaultOperand - One of these is created for each OperandWithDefaultOps
|
||||
/// that has a set ExecuteAlways / DefaultOps field.
|
||||
struct DAGDefaultOperand {
|
||||
std::vector<TreePatternNode*> DefaultOps;
|
||||
};
|
||||
|
@ -727,8 +727,7 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
|
||||
|
||||
// Determine what to emit for this operand.
|
||||
Record *OperandNode = II.Operands[InstOpNo].Rec;
|
||||
if ((OperandNode->isSubClassOf("PredicateOperand") ||
|
||||
OperandNode->isSubClassOf("OptionalDefOperand")) &&
|
||||
if (OperandNode->isSubClassOf("OperandWithDefaultOps") &&
|
||||
!CGP.getDefaultOperand(OperandNode).DefaultOps.empty()) {
|
||||
// This is a predicate or optional def operand; emit the
|
||||
// 'default ops' operands.
|
||||
|
@ -156,7 +156,7 @@ void PseudoLoweringEmitter::evaluateExpansion(Record *Rec) {
|
||||
|
||||
// If there are more operands that weren't in the DAG, they have to
|
||||
// be operands that have default values, or we have an error. Currently,
|
||||
// PredicateOperand and OptionalDefOperand both have default values.
|
||||
// Operands that are a sublass of OperandWithDefaultOp have default values.
|
||||
|
||||
|
||||
// Validate that each result pattern argument has a matching (by name)
|
||||
|
Loading…
x
Reference in New Issue
Block a user