mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-04 21:30:49 +00:00
First steps to getting PredicateOperand's to work. This handles instruction
and pat pattern definitions. Codegen is not right for them yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31444 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5d52894783
commit
dfdaeb276e
@ -759,27 +759,40 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) {
|
|||||||
MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
|
MadeChange = UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getNumChildren() != Inst.getNumOperands())
|
unsigned ChildNo = 0;
|
||||||
TP.error("Instruction '" + getOperator()->getName() + " expects " +
|
for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) {
|
||||||
utostr(Inst.getNumOperands()) + " operands, not " +
|
|
||||||
utostr(getNumChildren()) + " operands!");
|
|
||||||
for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
|
|
||||||
Record *OperandNode = Inst.getOperand(i);
|
Record *OperandNode = Inst.getOperand(i);
|
||||||
|
|
||||||
|
// If the instruction expects a predicate operand, we codegen this by
|
||||||
|
// setting the predicate to it's "execute always" value.
|
||||||
|
if (OperandNode->isSubClassOf("PredicateOperand"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Verify that we didn't run out of provided operands.
|
||||||
|
if (ChildNo >= getNumChildren())
|
||||||
|
TP.error("Instruction '" + getOperator()->getName() +
|
||||||
|
"' expects more operands than were provided.");
|
||||||
|
|
||||||
MVT::ValueType VT;
|
MVT::ValueType VT;
|
||||||
|
TreePatternNode *Child = getChild(ChildNo++);
|
||||||
if (OperandNode->isSubClassOf("RegisterClass")) {
|
if (OperandNode->isSubClassOf("RegisterClass")) {
|
||||||
const CodeGenRegisterClass &RC =
|
const CodeGenRegisterClass &RC =
|
||||||
ISE.getTargetInfo().getRegisterClass(OperandNode);
|
ISE.getTargetInfo().getRegisterClass(OperandNode);
|
||||||
MadeChange |=getChild(i)->UpdateNodeType(ConvertVTs(RC.getValueTypes()),
|
MadeChange |= Child->UpdateNodeType(ConvertVTs(RC.getValueTypes()), TP);
|
||||||
TP);
|
|
||||||
} else if (OperandNode->isSubClassOf("Operand")) {
|
} else if (OperandNode->isSubClassOf("Operand")) {
|
||||||
VT = getValueType(OperandNode->getValueAsDef("Type"));
|
VT = getValueType(OperandNode->getValueAsDef("Type"));
|
||||||
MadeChange |= getChild(i)->UpdateNodeType(VT, TP);
|
MadeChange |= Child->UpdateNodeType(VT, TP);
|
||||||
} else {
|
} else {
|
||||||
assert(0 && "Unknown operand type!");
|
assert(0 && "Unknown operand type!");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
MadeChange |= getChild(i)->ApplyTypeConstraints(TP, NotRegisters);
|
MadeChange |= Child->ApplyTypeConstraints(TP, NotRegisters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ChildNo != getNumChildren())
|
||||||
|
TP.error("Instruction '" + getOperator()->getName() +
|
||||||
|
"' was provided too many operands!");
|
||||||
|
|
||||||
return MadeChange;
|
return MadeChange;
|
||||||
} else {
|
} else {
|
||||||
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
|
assert(getOperator()->isSubClassOf("SDNodeXForm") && "Unknown node type!");
|
||||||
@ -1471,25 +1484,35 @@ void DAGISelEmitter::ParseInstructions() {
|
|||||||
std::vector<TreePatternNode*> ResultNodeOperands;
|
std::vector<TreePatternNode*> ResultNodeOperands;
|
||||||
std::vector<Record*> Operands;
|
std::vector<Record*> Operands;
|
||||||
for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
|
for (unsigned i = NumResults, e = CGI.OperandList.size(); i != e; ++i) {
|
||||||
const std::string &OpName = CGI.OperandList[i].Name;
|
CodeGenInstruction::OperandInfo &Op = CGI.OperandList[i];
|
||||||
|
const std::string &OpName = Op.Name;
|
||||||
if (OpName.empty())
|
if (OpName.empty())
|
||||||
I->error("Operand #" + utostr(i) + " in operands list has no name!");
|
I->error("Operand #" + utostr(i) + " in operands list has no name!");
|
||||||
|
|
||||||
if (!InstInputsCheck.count(OpName))
|
if (!InstInputsCheck.count(OpName)) {
|
||||||
|
// If this is an predicate operand with an ExecuteAlways set filled in,
|
||||||
|
// we can ignore this. When we codegen it, we will do so as always
|
||||||
|
// executed.
|
||||||
|
if (Op.Rec->isSubClassOf("PredicateOperand")) {
|
||||||
|
// Does it have a non-empty ExecuteAlways field? If so, ignore this
|
||||||
|
// operand.
|
||||||
|
if (Op.Rec->getValueAsDag("ExecuteAlways")->getNumArgs())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
I->error("Operand $" + OpName +
|
I->error("Operand $" + OpName +
|
||||||
" does not appear in the instruction pattern");
|
" does not appear in the instruction pattern");
|
||||||
|
}
|
||||||
TreePatternNode *InVal = InstInputsCheck[OpName];
|
TreePatternNode *InVal = InstInputsCheck[OpName];
|
||||||
InstInputsCheck.erase(OpName); // It occurred, remove from map.
|
InstInputsCheck.erase(OpName); // It occurred, remove from map.
|
||||||
|
|
||||||
if (InVal->isLeaf() &&
|
if (InVal->isLeaf() &&
|
||||||
dynamic_cast<DefInit*>(InVal->getLeafValue())) {
|
dynamic_cast<DefInit*>(InVal->getLeafValue())) {
|
||||||
Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
|
Record *InRec = static_cast<DefInit*>(InVal->getLeafValue())->getDef();
|
||||||
if (CGI.OperandList[i].Rec != InRec &&
|
if (Op.Rec != InRec && !InRec->isSubClassOf("ComplexPattern"))
|
||||||
!InRec->isSubClassOf("ComplexPattern"))
|
|
||||||
I->error("Operand $" + OpName + "'s register class disagrees"
|
I->error("Operand $" + OpName + "'s register class disagrees"
|
||||||
" between the operand and pattern");
|
" between the operand and pattern");
|
||||||
}
|
}
|
||||||
Operands.push_back(CGI.OperandList[i].Rec);
|
Operands.push_back(Op.Rec);
|
||||||
|
|
||||||
// Construct the result for the dest-pattern operand list.
|
// Construct the result for the dest-pattern operand list.
|
||||||
TreePatternNode *OpNode = InVal->clone();
|
TreePatternNode *OpNode = InVal->clone();
|
||||||
|
Loading…
Reference in New Issue
Block a user