diff options
author | Chris Lattner <sabre@nondot.org> | 2003-08-11 21:28:59 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-08-11 21:28:59 +0000 |
commit | abb215e588a79b07e416156cc6c125fc8c81c0bb (patch) | |
tree | b516f0dd071ac7d1309aa77b5a7a525f3c965826 /utils | |
parent | 57fb6ab871ffd829983b1d76fd00065cf4aec67d (diff) |
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
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/InstrSelectorEmitter.cpp | 34 | ||||
-rw-r--r-- | utils/TableGen/InstrSelectorEmitter.h | 19 |
2 files changed, 42 insertions, 11 deletions
diff --git a/utils/TableGen/InstrSelectorEmitter.cpp b/utils/TableGen/InstrSelectorEmitter.cpp index d9f333be6e..4f6a018413 100644 --- a/utils/TableGen/InstrSelectorEmitter.cpp +++ b/utils/TableGen/InstrSelectorEmitter.cpp @@ -117,7 +117,7 @@ void TreePatternNode::dump() const { std::cerr << *this; } // Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec, InstrSelectorEmitter &ise) - : PTy(pty), Result(0), TheRecord(TheRec), ISE(ise) { + : PTy(pty), ResultNode(0), TheRecord(TheRec), ISE(ise) { // First, parse the pattern... Tree = ParseTreePattern(RawPat); @@ -137,7 +137,7 @@ Pattern::Pattern(PatternType pty, DagInit *RawPat, Record *TheRec, assert(Tree->getNumChildren() == 2 && "Set with != 2 arguments?"); if (!Tree->getChild(0)->isLeaf()) 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); Tree = Tree->getChild(1); } @@ -855,11 +855,14 @@ static void ReduceAllOperands(TreePatternNode *N, const std::string &Name, /// name. void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg, const std::string &NameVar, - Record *ArgDecl, + TreePatternNode *ArgDeclNode, Pattern *P, bool PrintArg, std::ostream &OS) { if (DefInit *DI = dynamic_cast<DefInit*>(Arg)) { Record *Arg = DI->getDef(); + if (!ArgDeclNode->isLeaf()) + P->error("Expected leaf node as argument!"); + Record *ArgDecl = ArgDeclNode->getValueRecord(); if (Arg->isSubClassOf("Register")) { // This is a physical register reference... make sure that the instruction // requested a register! @@ -882,8 +885,28 @@ void InstrSelectorEmitter::PrintExpanderOperand(Init *Arg, OS << NameVar; if (PrintArg) OS << ")"; 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!"); + } 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!"); } @@ -1201,7 +1224,8 @@ void InstrSelectorEmitter::run(std::ostream &OS) { std::string ArgNameVal = getArgName(P, DIInst->getArgName(0), Operands); PrintExpanderOperand(DIInst->getArg(0), ArgNameVal, - R, P, false, OS << ", "); + InstPat->getResultNode(), P, false, + OS << ", "); } OS << ")"; @@ -1210,7 +1234,7 @@ void InstrSelectorEmitter::run(std::ostream &OS) { getArgName(P, DIInst->getArgName(i), Operands); PrintExpanderOperand(DIInst->getArg(i), ArgNameVal, - InstPat->getArgRec(i-hasResult), P, true, OS); + InstPat->getArg(i-hasResult), P, true, OS); } OS << ";\n"; diff --git a/utils/TableGen/InstrSelectorEmitter.h b/utils/TableGen/InstrSelectorEmitter.h index 9588130b61..a8ab145c87 100644 --- a/utils/TableGen/InstrSelectorEmitter.h +++ b/utils/TableGen/InstrSelectorEmitter.h @@ -141,8 +141,8 @@ private: /// Result - If this is an instruction or expander pattern, this is the /// 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. /// @@ -172,8 +172,9 @@ public: /// Pattern - Constructor used for cloning nonterminal patterns Pattern(TreePatternNode *tree, Record *rec, bool res, - InstrSelectorEmitter &ise) : PTy(Nonterminal), Tree(tree), Result(0), - TheRecord(rec), Resolved(res), ISE(ise) { + InstrSelectorEmitter &ise) + : PTy(Nonterminal), Tree(tree), ResultNode(0), TheRecord(rec), + Resolved(res), ISE(ise) { calculateArgs(Tree, ""); } @@ -185,8 +186,11 @@ public: /// 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; } + TreePatternNode *getResultNode() const { return ResultNode; } /// getRecord - Return the actual TableGen record corresponding to this /// pattern. @@ -201,6 +205,9 @@ public: Record *getArgRec(unsigned i) const { return getArg(i)->getValueRecord(); } + Init *getArgVal(unsigned i) const { + return getArg(i)->getValue(); + } const std::string &getArgName(unsigned i) const { assert(i < Args.size() && "Argument reference out of range!"); return Args[i].second; @@ -372,7 +379,7 @@ private: /// to the BuildMI call. If it is false, we are printing the result register /// name. void PrintExpanderOperand(Init *Arg, const std::string &NameVar, - Record *ArgDecl, Pattern *P, + TreePatternNode *ArgDecl, Pattern *P, bool PrintArg, std::ostream &OS); }; |