aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-11-19 07:05:57 +0000
committerChris Lattner <sabre@nondot.org>2005-11-19 07:05:57 +0000
commit65303d6bd777b76735ef179870678a1d14671c54 (patch)
tree19a39382164bd4b4030cd0e85d6bc08cfa0b3bc2
parent6adaf79ad7fd5f3b411e7ff326785891ee47e491 (diff)
Teach tblgen about instruction operands that have multiple MachineInstr
operands, digging into them to find register values (used on X86). Patch by Evan Cheng! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24424 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/CodeGenInstruction.h11
-rw-r--r--utils/TableGen/CodeGenTarget.cpp5
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp22
3 files changed, 29 insertions, 9 deletions
diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h
index cbf22db821..d400cadc0c 100644
--- a/utils/TableGen/CodeGenInstruction.h
+++ b/utils/TableGen/CodeGenInstruction.h
@@ -21,6 +21,7 @@
namespace llvm {
class Record;
+ class DagInit;
struct CodeGenInstruction {
Record *TheDef; // The actual record defining this instruction.
@@ -59,10 +60,16 @@ namespace llvm {
unsigned MIOperandNo;
unsigned MINumOperands; // The number of operands.
+ /// MIOperandInfo - Default MI operand type. Note an operand may be made up
+ /// of multiple MI operands.
+ DagInit *MIOperandInfo;
+
OperandInfo(Record *R, MVT::ValueType T, const std::string &N,
- const std::string &PMN, unsigned MION, unsigned MINO)
+ const std::string &PMN, unsigned MION, unsigned MINO,
+ DagInit *MIOI)
+
: Rec(R), Ty(T), Name(N), PrinterMethodName(PMN), MIOperandNo(MION),
- MINumOperands(MINO) {}
+ MINumOperands(MINO), MIOperandInfo(MIOI) {}
};
/// OperandList - The list of declared operands, along with their declared
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index e85170d5a6..f0786e5f39 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -267,12 +267,14 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
MVT::ValueType Ty;
std::string PrintMethod = "printOperand";
unsigned NumOps = 1;
+ DagInit *MIOpInfo;
if (Rec->isSubClassOf("RegisterClass")) {
Ty = getValueType(Rec->getValueAsDef("RegType"));
} else if (Rec->isSubClassOf("Operand")) {
Ty = getValueType(Rec->getValueAsDef("Type"));
PrintMethod = Rec->getValueAsString("PrintMethod");
NumOps = Rec->getValueAsInt("NumMIOperands");
+ MIOpInfo = Rec->getValueAsDag("MIOperandInfo");
} else if (Rec->getName() == "variable_ops") {
hasVariableNumberOfOperands = true;
continue;
@@ -289,7 +291,8 @@ CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr)
" has the same name as a previous operand!";
OperandList.push_back(OperandInfo(Rec, Ty, DI->getArgName(i),
- PrintMethod, MIOperandNo, NumOps));
+ PrintMethod, MIOperandNo, NumOps,
+ MIOpInfo));
MIOperandNo += NumOps;
}
}
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 3f7d5dbadc..c2fcf1a226 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -62,13 +62,21 @@ static std::vector<Record*> GetOperandInfo(const CodeGenInstruction &Inst) {
return Result; // No info for variable operand instrs.
for (unsigned i = 0, e = Inst.OperandList.size(); i != e; ++i) {
- if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass"))
+ if (Inst.OperandList[i].Rec->isSubClassOf("RegisterClass")) {
Result.push_back(Inst.OperandList[i].Rec);
- else {
+ } else {
// This might be a multiple operand thing.
- // FIXME: Targets like X86 have registers in their multi-operand operands.
- for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j)
- Result.push_back(0);
+ // Targets like X86 have registers in their multi-operand operands.
+ DagInit *MIOI = Inst.OperandList[i].MIOperandInfo;
+ unsigned NumDefs = MIOI->getNumArgs();
+ for (unsigned j = 0, e = Inst.OperandList[i].MINumOperands; j != e; ++j) {
+ if (NumDefs <= j) {
+ Result.push_back(0);
+ } else {
+ DefInit *Def = dynamic_cast<DefInit*>(MIOI->getArg(j));
+ Result.push_back(Def ? Def->getDef() : 0);
+ }
+ }
}
}
return Result;
@@ -124,7 +132,9 @@ void InstrInfoEmitter::run(std::ostream &OS) {
N = ++OperandListNum;
OS << "static const TargetOperandInfo OperandInfo" << N << "[] = { ";
for (unsigned i = 0, e = OperandInfo.size(); i != e; ++i) {
- if (Record *RC = OperandInfo[i]) {
+ Record *RC = OperandInfo[i];
+ // FIXME: We only care about register operands for now.
+ if (RC && RC->isSubClassOf("RegisterClass")) {
OS << "{ &" << getQualifiedName(RC) << "RegClass }, ";
} else {
OS << "{ 0 }, ";