mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-22 09:29:31 +00:00
add support for referencing registers and immediates,
building the tree to represent them but not emitting table entries for them yet. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96617 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
196c60a571
commit
845c042734
@ -203,7 +203,7 @@ GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
|
|||||||
enum BuiltinOpcodes {
|
enum BuiltinOpcodes {
|
||||||
OPC_Emit,
|
OPC_Emit,
|
||||||
OPC_Push,
|
OPC_Push,
|
||||||
OPC_Record,
|
OPC_RecordNode,
|
||||||
OPC_MoveChild,
|
OPC_MoveChild,
|
||||||
OPC_MoveParent,
|
OPC_MoveParent,
|
||||||
OPC_CheckSame,
|
OPC_CheckSame,
|
||||||
@ -294,7 +294,7 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
|
|||||||
MatchScopes.push_back(NewEntry);
|
MatchScopes.push_back(NewEntry);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case OPC_Record:
|
case OPC_RecordNode:
|
||||||
// Remember this node, it may end up being an operand in the pattern.
|
// Remember this node, it may end up being an operand in the pattern.
|
||||||
RecordedNodes.push_back(N);
|
RecordedNodes.push_back(N);
|
||||||
continue;
|
continue;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "DAGISelMatcher.h"
|
#include "DAGISelMatcher.h"
|
||||||
#include "CodeGenDAGPatterns.h"
|
#include "CodeGenDAGPatterns.h"
|
||||||
#include "CodeGenTarget.h"
|
#include "CodeGenTarget.h"
|
||||||
|
#include "Record.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -117,3 +118,19 @@ void CheckChainCompatibleMatcherNode::print(raw_ostream &OS,
|
|||||||
OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n";
|
OS.indent(indent) << "CheckChainCompatibleMatcherNode " << PreviousOp << "\n";
|
||||||
printNext(OS, indent);
|
printNext(OS, indent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitIntegerMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||||
|
OS.indent(indent) << "EmitIntegerMatcherNode " << Val << " VT=" << VT << '\n';
|
||||||
|
printNext(OS, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitRegisterMatcherNode::print(raw_ostream &OS, unsigned indent) const {
|
||||||
|
OS.indent(indent) << "EmitRegisterMatcherNode ";
|
||||||
|
if (Reg)
|
||||||
|
OS << Reg->getName();
|
||||||
|
else
|
||||||
|
OS << "zero_reg";
|
||||||
|
OS << " VT=" << VT << '\n';
|
||||||
|
printNext(OS, indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ namespace llvm {
|
|||||||
class PatternToMatch;
|
class PatternToMatch;
|
||||||
class raw_ostream;
|
class raw_ostream;
|
||||||
class ComplexPattern;
|
class ComplexPattern;
|
||||||
|
class Record;
|
||||||
|
|
||||||
MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
MatcherNode *ConvertPatternToMatcher(const PatternToMatch &Pattern,
|
||||||
const CodeGenDAGPatterns &CGP);
|
const CodeGenDAGPatterns &CGP);
|
||||||
@ -36,25 +37,31 @@ class MatcherNode {
|
|||||||
OwningPtr<MatcherNode> Next;
|
OwningPtr<MatcherNode> Next;
|
||||||
public:
|
public:
|
||||||
enum KindTy {
|
enum KindTy {
|
||||||
EmitNode,
|
// Stack manipulation.
|
||||||
Push, // [Push, Dest0, Dest1, Dest2, Dest3]
|
Push, // Push a checking scope.
|
||||||
Record, // [Record]
|
RecordNode, // Record the current node.
|
||||||
MoveChild, // [MoveChild, Child#]
|
MoveChild, // Move current node to specified child.
|
||||||
MoveParent, // [MoveParent]
|
MoveParent, // Move current node to parent.
|
||||||
|
|
||||||
CheckSame, // [CheckSame, N] Fail if not same as prev match.
|
// Predicate checking.
|
||||||
|
CheckSame, // Fail if not same as prev match.
|
||||||
CheckPatternPredicate,
|
CheckPatternPredicate,
|
||||||
CheckPredicate, // [CheckPredicate, P] Fail if predicate fails.
|
CheckPredicate, // Fail if node predicate fails.
|
||||||
CheckOpcode, // [CheckOpcode, Opcode] Fail if not opcode.
|
CheckOpcode, // Fail if not opcode.
|
||||||
CheckType, // [CheckType, MVT] Fail if not correct type.
|
CheckType, // Fail if not correct type.
|
||||||
CheckInteger, // [CheckInteger, int0,int1,int2,...int7] Fail if wrong val.
|
CheckInteger, // Fail if wrong val.
|
||||||
CheckCondCode, // [CheckCondCode, CondCode] Fail if not condcode.
|
CheckCondCode, // Fail if not condcode.
|
||||||
CheckValueType,
|
CheckValueType,
|
||||||
CheckComplexPat,
|
CheckComplexPat,
|
||||||
CheckAndImm,
|
CheckAndImm,
|
||||||
CheckOrImm,
|
CheckOrImm,
|
||||||
CheckFoldableChainNode,
|
CheckFoldableChainNode,
|
||||||
CheckChainCompatible
|
CheckChainCompatible,
|
||||||
|
|
||||||
|
// Node creation/emisssion.
|
||||||
|
EmitInteger, // Create a TargetConstant
|
||||||
|
EmitRegister, // Create a register.
|
||||||
|
EmitNode
|
||||||
};
|
};
|
||||||
const KindTy Kind;
|
const KindTy Kind;
|
||||||
|
|
||||||
@ -77,23 +84,6 @@ protected:
|
|||||||
void printNext(raw_ostream &OS, unsigned indent) const;
|
void printNext(raw_ostream &OS, unsigned indent) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// EmitNodeMatcherNode - This signals a successful match and generates a node.
|
|
||||||
class EmitNodeMatcherNode : public MatcherNode {
|
|
||||||
const PatternToMatch &Pattern;
|
|
||||||
public:
|
|
||||||
EmitNodeMatcherNode(const PatternToMatch &pattern)
|
|
||||||
: MatcherNode(EmitNode), Pattern(pattern) {}
|
|
||||||
|
|
||||||
const PatternToMatch &getPattern() const { return Pattern; }
|
|
||||||
|
|
||||||
static inline bool classof(const MatcherNode *N) {
|
|
||||||
return N->getKind() == EmitNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// PushMatcherNode - This pushes a failure scope on the stack and evaluates
|
/// PushMatcherNode - This pushes a failure scope on the stack and evaluates
|
||||||
/// 'Next'. If 'Next' fails to match, it pops its scope and attempts to
|
/// 'Next'. If 'Next' fails to match, it pops its scope and attempts to
|
||||||
/// match 'Failure'.
|
/// match 'Failure'.
|
||||||
@ -123,12 +113,12 @@ class RecordMatcherNode : public MatcherNode {
|
|||||||
std::string WhatFor;
|
std::string WhatFor;
|
||||||
public:
|
public:
|
||||||
RecordMatcherNode(const std::string &whatfor)
|
RecordMatcherNode(const std::string &whatfor)
|
||||||
: MatcherNode(Record), WhatFor(whatfor) {}
|
: MatcherNode(RecordNode), WhatFor(whatfor) {}
|
||||||
|
|
||||||
const std::string &getWhatFor() const { return WhatFor; }
|
const std::string &getWhatFor() const { return WhatFor; }
|
||||||
|
|
||||||
static inline bool classof(const MatcherNode *N) {
|
static inline bool classof(const MatcherNode *N) {
|
||||||
return N->getKind() == Record;
|
return N->getKind() == RecordNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
@ -388,7 +378,59 @@ public:
|
|||||||
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// EmitIntegerMatcherNode - This creates a new TargetConstant.
|
||||||
|
class EmitIntegerMatcherNode : public MatcherNode {
|
||||||
|
int64_t Val;
|
||||||
|
MVT::SimpleValueType VT;
|
||||||
|
public:
|
||||||
|
EmitIntegerMatcherNode(int64_t val, MVT::SimpleValueType vt)
|
||||||
|
: MatcherNode(EmitInteger), Val(val), VT(vt) {}
|
||||||
|
|
||||||
|
int64_t getVal() const { return Val; }
|
||||||
|
MVT::SimpleValueType getVT() const { return VT; }
|
||||||
|
|
||||||
|
static inline bool classof(const MatcherNode *N) {
|
||||||
|
return N->getKind() == EmitInteger;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// EmitRegisterMatcherNode - This creates a new TargetConstant.
|
||||||
|
class EmitRegisterMatcherNode : public MatcherNode {
|
||||||
|
/// Reg - The def for the register that we're emitting. If this is null, then
|
||||||
|
/// this is a reference to zero_reg.
|
||||||
|
Record *Reg;
|
||||||
|
MVT::SimpleValueType VT;
|
||||||
|
public:
|
||||||
|
EmitRegisterMatcherNode(Record *reg, MVT::SimpleValueType vt)
|
||||||
|
: MatcherNode(EmitRegister), Reg(reg), VT(vt) {}
|
||||||
|
|
||||||
|
Record *getReg() const { return Reg; }
|
||||||
|
MVT::SimpleValueType getVT() const { return VT; }
|
||||||
|
|
||||||
|
static inline bool classof(const MatcherNode *N) {
|
||||||
|
return N->getKind() == EmitRegister;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// EmitNodeMatcherNode - This signals a successful match and generates a node.
|
||||||
|
class EmitNodeMatcherNode : public MatcherNode {
|
||||||
|
const PatternToMatch &Pattern;
|
||||||
|
public:
|
||||||
|
EmitNodeMatcherNode(const PatternToMatch &pattern)
|
||||||
|
: MatcherNode(EmitNode), Pattern(pattern) {}
|
||||||
|
|
||||||
|
const PatternToMatch &getPattern() const { return Pattern; }
|
||||||
|
|
||||||
|
static inline bool classof(const MatcherNode *N) {
|
||||||
|
return N->getKind() == EmitNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(raw_ostream &OS, unsigned indent = 0) const;
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
||||||
|
@ -125,8 +125,8 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
|
|||||||
<< *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << "\n";
|
<< *cast<EmitNodeMatcherNode>(N)->getPattern().getDstPattern() << "\n";
|
||||||
OS.PadToColumn(Indent*2) << "OPC_Emit, /*XXX*/\n\n";
|
OS.PadToColumn(Indent*2) << "OPC_Emit, /*XXX*/\n\n";
|
||||||
return 1;
|
return 1;
|
||||||
case MatcherNode::Record:
|
case MatcherNode::RecordNode:
|
||||||
OS << "OPC_Record,";
|
OS << "OPC_RecordNode,";
|
||||||
OS.PadToColumn(CommentIndent) << "// "
|
OS.PadToColumn(CommentIndent) << "// "
|
||||||
<< cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
|
<< cast<RecordMatcherNode>(N)->getWhatFor() << '\n';
|
||||||
return 1;
|
return 1;
|
||||||
@ -212,6 +212,11 @@ EmitMatcher(const MatcherNode *N, unsigned Indent) {
|
|||||||
OS << "OPC_CheckChainCompatible, "
|
OS << "OPC_CheckChainCompatible, "
|
||||||
<< cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
|
<< cast<CheckChainCompatibleMatcherNode>(N)->getPreviousOp() << ",\n";
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
case MatcherNode::EmitInteger:
|
||||||
|
case MatcherNode::EmitRegister:
|
||||||
|
// FIXME: Implement.
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
assert(0 && "Unreachable");
|
assert(0 && "Unreachable");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -397,6 +397,38 @@ void MatcherGen::EmitMatcherCode() {
|
|||||||
|
|
||||||
void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
|
void MatcherGen::EmitResultLeafAsOperand(const TreePatternNode *N,
|
||||||
SmallVectorImpl<unsigned> &ResultOps) {
|
SmallVectorImpl<unsigned> &ResultOps) {
|
||||||
|
assert(N->isLeaf() && "Must be a leaf");
|
||||||
|
|
||||||
|
if (IntInit *II = dynamic_cast<IntInit*>(N->getLeafValue())) {
|
||||||
|
AddMatcherNode(new EmitIntegerMatcherNode(II->getValue(),N->getTypeNum(0)));
|
||||||
|
//ResultOps.push_back(TmpNode(TmpNo++));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is an explicit register reference, handle it.
|
||||||
|
if (DefInit *DI = dynamic_cast<DefInit*>(N->getLeafValue())) {
|
||||||
|
if (DI->getDef()->isSubClassOf("Register")) {
|
||||||
|
AddMatcherNode(new EmitRegisterMatcherNode(DI->getDef(),
|
||||||
|
N->getTypeNum(0)));
|
||||||
|
//ResultOps.push_back(TmpNode(TmpNo++));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DI->getDef()->getName() == "zero_reg") {
|
||||||
|
AddMatcherNode(new EmitRegisterMatcherNode(0, N->getTypeNum(0)));
|
||||||
|
//ResultOps.push_back(TmpNode(TmpNo++));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (DI->getDef()->isSubClassOf("RegisterClass")) {
|
||||||
|
// Handle a reference to a register class. This is used
|
||||||
|
// in COPY_TO_SUBREG instructions.
|
||||||
|
// FIXME: Implement.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
errs() << "unhandled leaf node: \n";
|
errs() << "unhandled leaf node: \n";
|
||||||
N->dump();
|
N->dump();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user