mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-05 13:26:55 +00:00
Add support for frameidx and literal immediates for instructions
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@7749 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -117,7 +117,7 @@ void TreePatternNode::dump() const { std::cerr << *this; }
|
|||||||
//
|
//
|
||||||
Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
||||||
InstrSelectorEmitter &ise)
|
InstrSelectorEmitter &ise)
|
||||||
: PTy(pty), Result(0), TheRecord(TheRec), ISE(ise) {
|
: PTy(pty), ResultNode(0), TheRecord(TheRec), ISE(ise) {
|
||||||
|
|
||||||
// First, parse the pattern...
|
// First, parse the pattern...
|
||||||
Tree = ParseTreePattern(RawPat);
|
Tree = ParseTreePattern(RawPat);
|
||||||
@@ -137,7 +137,7 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
|||||||
assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
|
assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
|
||||||
if (!Tree->getChild(0)->isLeaf())
|
if (!Tree->getChild(0)->isLeaf())
|
||||||
error("Arg #0 of set should be a register or register class!");
|
error("Arg #0 of set should be a register or register class!");
|
||||||
Result = Tree->getChild(0)->getValueRecord();
|
ResultNode = Tree->getChild(0);
|
||||||
ResultName = Tree->getChildName(0);
|
ResultName = Tree->getChildName(0);
|
||||||
Tree = Tree->getChild(1);
|
Tree = Tree->getChild(1);
|
||||||
}
|
}
|
||||||
@@ -855,11 +855,14 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name,
|
|||||||
/// name.
|
/// name.
|
||||||
void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
||||||
const std::string &NameVar,
|
const std::string &NameVar,
|
||||||
Record *ArgDecl,
|
TreePatternNode *ArgDeclNode,
|
||||||
Pattern *P, bool PrintArg,
|
Pattern *P, bool PrintArg,
|
||||||
std::ostream &OS) {
|
std::ostream &OS) {
|
||||||
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
|
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
|
||||||
Record *Arg = DI->getDef();
|
Record *Arg = DI->getDef();
|
||||||
|
if (!ArgDeclNode->isLeaf())
|
||||||
|
P->error("Expected leaf node as argument!");
|
||||||
|
Record *ArgDecl = ArgDeclNode->getValueRecord();
|
||||||
if (Arg->isSubClassOf("Register")) {
|
if (Arg->isSubClassOf("Register")) {
|
||||||
// This is a physical register reference... make sure that the instruction
|
// This is a physical register reference... make sure that the instruction
|
||||||
// requested a register!
|
// requested a register!
|
||||||
@@ -882,8 +885,28 @@ void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
|||||||
OS << NameVar;
|
OS << NameVar;
|
||||||
if (PrintArg) OS << ")";
|
if (PrintArg) OS << ")";
|
||||||
return;
|
return;
|
||||||
|
} else if (Arg->getName() == "frameidx") {
|
||||||
|
if (!PrintArg) P->error("Cannot define a new frameidx value!");
|
||||||
|
OS << ".addFrameIndex(" << NameVar << ")";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
|
P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
|
||||||
|
} else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
|
||||||
|
if (!NameVar.empty())
|
||||||
|
P->error("Illegal to specify a name for a constant initializer arg!");
|
||||||
|
|
||||||
|
// Hack this check to allow R32 values with 0 as the initializer for memory
|
||||||
|
// references... FIXME!
|
||||||
|
if (ArgDeclNode->isLeaf() && II->getValue() == 0 &&
|
||||||
|
ArgDeclNode->getValueRecord()->getName() == "R32") {
|
||||||
|
OS << ".addReg(0)";
|
||||||
|
} else {
|
||||||
|
if (ArgDeclNode->isLeaf() || ArgDeclNode->getOperator()->getName()!="imm")
|
||||||
|
P->error("Illegal immediate int value '" + itostr(II->getValue()) +
|
||||||
|
"' operand!");
|
||||||
|
OS << ".addZImm(" << II->getValue() << ")";
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
P->error("Unknown operand type to expander!");
|
P->error("Unknown operand type to expander!");
|
||||||
}
|
}
|
||||||
@@ -1201,7 +1224,8 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
|
|||||||
std::string ArgNameVal =
|
std::string ArgNameVal =
|
||||||
getArgName(P, DIInst->getArgName(0), Operands);
|
getArgName(P, DIInst->getArgName(0), Operands);
|
||||||
PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
|
PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
|
||||||
R, P, false, OS << ", ");
|
InstPat->getResultNode(), P, false,
|
||||||
|
OS << ", ");
|
||||||
}
|
}
|
||||||
OS << ")";
|
OS << ")";
|
||||||
|
|
||||||
@@ -1210,7 +1234,7 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
|
|||||||
getArgName(P, DIInst->getArgName(i), Operands);
|
getArgName(P, DIInst->getArgName(i), Operands);
|
||||||
|
|
||||||
PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
|
PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
|
||||||
InstPat->getArgRec(i-hasResult), P, true, OS);
|
InstPat->getArg(i-hasResult), P, true, OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << ";\n";
|
OS << ";\n";
|
||||||
|
@@ -141,8 +141,8 @@ private:
|
|||||||
/// Result - If this is an instruction or expander pattern, this is the
|
/// Result - If this is an instruction or expander pattern, this is the
|
||||||
/// register result, specified with a (set) in the pattern.
|
/// register result, specified with a (set) in the pattern.
|
||||||
///
|
///
|
||||||
Record *Result;
|
std::string ResultName; // The name of the result value...
|
||||||
std::string ResultName; // The name of the result value...
|
TreePatternNode *ResultNode; // The leaf node for the result register...
|
||||||
|
|
||||||
/// TheRecord - The actual TableGen record corresponding to this pattern.
|
/// TheRecord - The actual TableGen record corresponding to this pattern.
|
||||||
///
|
///
|
||||||
@@ -172,8 +172,9 @@ public:
|
|||||||
|
|
||||||
/// Pattern - Constructor used for cloning nonterminal patterns
|
/// Pattern - Constructor used for cloning nonterminal patterns
|
||||||
Pattern(TreePatternNode *tree, Record *rec, bool res,
|
Pattern(TreePatternNode *tree, Record *rec, bool res,
|
||||||
InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0),
|
InstrSelectorEmitter &ise)
|
||||||
TheRecord(rec), Resolved(res), ISE(ise) {
|
: PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec),
|
||||||
|
Resolved(res), ISE(ise) {
|
||||||
calculateArgs(Tree, "");
|
calculateArgs(Tree, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,8 +186,11 @@ public:
|
|||||||
///
|
///
|
||||||
TreePatternNode *getTree() const { return Tree; }
|
TreePatternNode *getTree() const { return Tree; }
|
||||||
|
|
||||||
Record *getResult() const { return Result; }
|
Record *getResult() const {
|
||||||
|
return ResultNode ? ResultNode->getValueRecord() : 0;
|
||||||
|
}
|
||||||
const std::string &getResultName() const { return ResultName; }
|
const std::string &getResultName() const { return ResultName; }
|
||||||
|
TreePatternNode *getResultNode() const { return ResultNode; }
|
||||||
|
|
||||||
/// getRecord - Return the actual TableGen record corresponding to this
|
/// getRecord - Return the actual TableGen record corresponding to this
|
||||||
/// pattern.
|
/// pattern.
|
||||||
@@ -201,6 +205,9 @@ public:
|
|||||||
Record *getArgRec(unsigned i) const {
|
Record *getArgRec(unsigned i) const {
|
||||||
return getArg(i)->getValueRecord();
|
return getArg(i)->getValueRecord();
|
||||||
}
|
}
|
||||||
|
Init *getArgVal(unsigned i) const {
|
||||||
|
return getArg(i)->getValue();
|
||||||
|
}
|
||||||
const std::string &getArgName(unsigned i) const {
|
const std::string &getArgName(unsigned i) const {
|
||||||
assert(i < Args.size() && "Argument reference out of range!");
|
assert(i < Args.size() && "Argument reference out of range!");
|
||||||
return Args[i].second;
|
return Args[i].second;
|
||||||
@@ -372,7 +379,7 @@ private:
|
|||||||
/// to the BuildMI call. If it is false, we are printing the result register
|
/// to the BuildMI call. If it is false, we are printing the result register
|
||||||
/// name.
|
/// name.
|
||||||
void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
|
void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
|
||||||
Record *ArgDecl, Pattern *P,
|
TreePatternNode *ArgDecl, Pattern *P,
|
||||||
bool PrintArg, std::ostream &OS);
|
bool PrintArg, std::ostream &OS);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -117,7 +117,7 @@ void TreePatternNode::dump() const { std::cerr << *this; }
|
|||||||
//
|
//
|
||||||
Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
||||||
InstrSelectorEmitter &ise)
|
InstrSelectorEmitter &ise)
|
||||||
: PTy(pty), Result(0), TheRecord(TheRec), ISE(ise) {
|
: PTy(pty), ResultNode(0), TheRecord(TheRec), ISE(ise) {
|
||||||
|
|
||||||
// First, parse the pattern...
|
// First, parse the pattern...
|
||||||
Tree = ParseTreePattern(RawPat);
|
Tree = ParseTreePattern(RawPat);
|
||||||
@@ -137,7 +137,7 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec,
|
|||||||
assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
|
assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?");
|
||||||
if (!Tree->getChild(0)->isLeaf())
|
if (!Tree->getChild(0)->isLeaf())
|
||||||
error("Arg #0 of set should be a register or register class!");
|
error("Arg #0 of set should be a register or register class!");
|
||||||
Result = Tree->getChild(0)->getValueRecord();
|
ResultNode = Tree->getChild(0);
|
||||||
ResultName = Tree->getChildName(0);
|
ResultName = Tree->getChildName(0);
|
||||||
Tree = Tree->getChild(1);
|
Tree = Tree->getChild(1);
|
||||||
}
|
}
|
||||||
@@ -855,11 +855,14 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name,
|
|||||||
/// name.
|
/// name.
|
||||||
void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
||||||
const std::string &NameVar,
|
const std::string &NameVar,
|
||||||
Record *ArgDecl,
|
TreePatternNode *ArgDeclNode,
|
||||||
Pattern *P, bool PrintArg,
|
Pattern *P, bool PrintArg,
|
||||||
std::ostream &OS) {
|
std::ostream &OS) {
|
||||||
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
|
if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) {
|
||||||
Record *Arg = DI->getDef();
|
Record *Arg = DI->getDef();
|
||||||
|
if (!ArgDeclNode->isLeaf())
|
||||||
|
P->error("Expected leaf node as argument!");
|
||||||
|
Record *ArgDecl = ArgDeclNode->getValueRecord();
|
||||||
if (Arg->isSubClassOf("Register")) {
|
if (Arg->isSubClassOf("Register")) {
|
||||||
// This is a physical register reference... make sure that the instruction
|
// This is a physical register reference... make sure that the instruction
|
||||||
// requested a register!
|
// requested a register!
|
||||||
@@ -882,8 +885,28 @@ void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg,
|
|||||||
OS << NameVar;
|
OS << NameVar;
|
||||||
if (PrintArg) OS << ")";
|
if (PrintArg) OS << ")";
|
||||||
return;
|
return;
|
||||||
|
} else if (Arg->getName() == "frameidx") {
|
||||||
|
if (!PrintArg) P->error("Cannot define a new frameidx value!");
|
||||||
|
OS << ".addFrameIndex(" << NameVar << ")";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
|
P->error("Unknown operand type '" + Arg->getName() + "' to expander!");
|
||||||
|
} else if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
|
||||||
|
if (!NameVar.empty())
|
||||||
|
P->error("Illegal to specify a name for a constant initializer arg!");
|
||||||
|
|
||||||
|
// Hack this check to allow R32 values with 0 as the initializer for memory
|
||||||
|
// references... FIXME!
|
||||||
|
if (ArgDeclNode->isLeaf() && II->getValue() == 0 &&
|
||||||
|
ArgDeclNode->getValueRecord()->getName() == "R32") {
|
||||||
|
OS << ".addReg(0)";
|
||||||
|
} else {
|
||||||
|
if (ArgDeclNode->isLeaf() || ArgDeclNode->getOperator()->getName()!="imm")
|
||||||
|
P->error("Illegal immediate int value '" + itostr(II->getValue()) +
|
||||||
|
"' operand!");
|
||||||
|
OS << ".addZImm(" << II->getValue() << ")";
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
P->error("Unknown operand type to expander!");
|
P->error("Unknown operand type to expander!");
|
||||||
}
|
}
|
||||||
@@ -1201,7 +1224,8 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
|
|||||||
std::string ArgNameVal =
|
std::string ArgNameVal =
|
||||||
getArgName(P, DIInst->getArgName(0), Operands);
|
getArgName(P, DIInst->getArgName(0), Operands);
|
||||||
PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
|
PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
|
||||||
R, P, false, OS << ", ");
|
InstPat->getResultNode(), P, false,
|
||||||
|
OS << ", ");
|
||||||
}
|
}
|
||||||
OS << ")";
|
OS << ")";
|
||||||
|
|
||||||
@@ -1210,7 +1234,7 @@ void InstrSelectorEmitter::run(std::ostream &OS) {
|
|||||||
getArgName(P, DIInst->getArgName(i), Operands);
|
getArgName(P, DIInst->getArgName(i), Operands);
|
||||||
|
|
||||||
PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
|
PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
|
||||||
InstPat->getArgRec(i-hasResult), P, true, OS);
|
InstPat->getArg(i-hasResult), P, true, OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
OS << ";\n";
|
OS << ";\n";
|
||||||
|
@@ -141,8 +141,8 @@ private:
|
|||||||
/// Result - If this is an instruction or expander pattern, this is the
|
/// Result - If this is an instruction or expander pattern, this is the
|
||||||
/// register result, specified with a (set) in the pattern.
|
/// register result, specified with a (set) in the pattern.
|
||||||
///
|
///
|
||||||
Record *Result;
|
std::string ResultName; // The name of the result value...
|
||||||
std::string ResultName; // The name of the result value...
|
TreePatternNode *ResultNode; // The leaf node for the result register...
|
||||||
|
|
||||||
/// TheRecord - The actual TableGen record corresponding to this pattern.
|
/// TheRecord - The actual TableGen record corresponding to this pattern.
|
||||||
///
|
///
|
||||||
@@ -172,8 +172,9 @@ public:
|
|||||||
|
|
||||||
/// Pattern - Constructor used for cloning nonterminal patterns
|
/// Pattern - Constructor used for cloning nonterminal patterns
|
||||||
Pattern(TreePatternNode *tree, Record *rec, bool res,
|
Pattern(TreePatternNode *tree, Record *rec, bool res,
|
||||||
InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0),
|
InstrSelectorEmitter &ise)
|
||||||
TheRecord(rec), Resolved(res), ISE(ise) {
|
: PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec),
|
||||||
|
Resolved(res), ISE(ise) {
|
||||||
calculateArgs(Tree, "");
|
calculateArgs(Tree, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,8 +186,11 @@ public:
|
|||||||
///
|
///
|
||||||
TreePatternNode *getTree() const { return Tree; }
|
TreePatternNode *getTree() const { return Tree; }
|
||||||
|
|
||||||
Record *getResult() const { return Result; }
|
Record *getResult() const {
|
||||||
|
return ResultNode ? ResultNode->getValueRecord() : 0;
|
||||||
|
}
|
||||||
const std::string &getResultName() const { return ResultName; }
|
const std::string &getResultName() const { return ResultName; }
|
||||||
|
TreePatternNode *getResultNode() const { return ResultNode; }
|
||||||
|
|
||||||
/// getRecord - Return the actual TableGen record corresponding to this
|
/// getRecord - Return the actual TableGen record corresponding to this
|
||||||
/// pattern.
|
/// pattern.
|
||||||
@@ -201,6 +205,9 @@ public:
|
|||||||
Record *getArgRec(unsigned i) const {
|
Record *getArgRec(unsigned i) const {
|
||||||
return getArg(i)->getValueRecord();
|
return getArg(i)->getValueRecord();
|
||||||
}
|
}
|
||||||
|
Init *getArgVal(unsigned i) const {
|
||||||
|
return getArg(i)->getValue();
|
||||||
|
}
|
||||||
const std::string &getArgName(unsigned i) const {
|
const std::string &getArgName(unsigned i) const {
|
||||||
assert(i < Args.size() && "Argument reference out of range!");
|
assert(i < Args.size() && "Argument reference out of range!");
|
||||||
return Args[i].second;
|
return Args[i].second;
|
||||||
@@ -372,7 +379,7 @@ private:
|
|||||||
/// to the BuildMI call. If it is false, we are printing the result register
|
/// to the BuildMI call. If it is false, we are printing the result register
|
||||||
/// name.
|
/// name.
|
||||||
void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
|
void PrintExpanderOperand(Init *Arg, const std::string &NameVar,
|
||||||
Record *ArgDecl, Pattern *P,
|
TreePatternNode *ArgDecl, Pattern *P,
|
||||||
bool PrintArg, std::ostream &OS);
|
bool PrintArg, std::ostream &OS);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user