summaryrefslogtreecommitdiff
path: root/utils/TableGen
diff options
context:
space:
mode:
authorMisha Brukman <brukman+llvm@gmail.com>2003-05-24 00:15:53 +0000
committerMisha Brukman <brukman+llvm@gmail.com>2003-05-24 00:15:53 +0000
commit9fff7e194a2d8aa3abe92efa506b1fbe83583f53 (patch)
tree7f3dccb981941c8dc60e57adf75105d25807aa99 /utils/TableGen
parente9d883828ad92f3a1d06e3c9e98c4e3df937197d (diff)
downloadllvm-9fff7e194a2d8aa3abe92efa506b1fbe83583f53.tar.gz
llvm-9fff7e194a2d8aa3abe92efa506b1fbe83583f53.tar.bz2
llvm-9fff7e194a2d8aa3abe92efa506b1fbe83583f53.tar.xz
First cut at the Code Generator using the TableGen methodology.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6321 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen')
-rw-r--r--utils/TableGen/CodeEmitterGen.cpp105
-rw-r--r--utils/TableGen/CodeEmitterGen.h23
2 files changed, 128 insertions, 0 deletions
diff --git a/utils/TableGen/CodeEmitterGen.cpp b/utils/TableGen/CodeEmitterGen.cpp
new file mode 100644
index 0000000000..0d378871e8
--- /dev/null
+++ b/utils/TableGen/CodeEmitterGen.cpp
@@ -0,0 +1,105 @@
+#include "Record.h"
+#include "CodeEmitterGen.h"
+#include <ostream>
+
+void CodeEmitterGen::createEmitter(std::ostream &o) {
+ std::vector<Record*> Insts;
+
+ const std::map<std::string, Record*> &Defs = Records.getDefs();
+ Record *Inst = Records.getClass("Instruction");
+ assert(Inst && "Couldn't find Instruction class!");
+
+ for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
+ E = Defs.end(); I != E; ++I)
+ if (I->second->isSubClassOf(Inst))
+ Insts.push_back(I->second);
+
+ std::string Namespace = "V9::";
+ std::string ClassName = "SparcV9CodeEmitter::";
+
+ //const std::string &Namespace = Inst->getValue("Namespace")->getName();
+ o << "unsigned " << ClassName
+ << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
+ << " unsigned Value = 0;\n"
+ << " switch (MI.getOpcode()) {\n";
+ for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
+ I != E; ++I)
+ {
+ Record *R = *I;
+ o << " case " << Namespace << R->getName() << ": {\n";
+
+ const RecordVal *InstVal = R->getValue("Inst");
+ Init *InitVal = InstVal->getValue();
+
+ assert(dynamic_cast<BitsInit*>(InitVal) &&
+ "Can only handle undefined bits<> types!");
+ BitsInit *BI = (BitsInit*)InitVal;
+
+ unsigned Value = 0;
+ const std::vector<RecordVal> &Vals = R->getValues();
+
+ // Start by filling in fixed values...
+ for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
+ if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(i)))
+ Value |= B->getValue() << i;
+
+ o << " Value = " << Value << "U;\n";
+ o << " // " << *InstVal << "\n";
+
+ // Loop over all of the fields in the instruction adding in any
+ // contributions to this value (due to bit references).
+ //
+ unsigned Offset = 31, opNum=0;
+ std::map<const std::string,unsigned> OpOrder;
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
+ if (Vals[i].getName() != "Inst" &&
+ !Vals[i].getValue()->isComplete() &&
+ Vals[i].getName() != "annul" &&
+ Vals[i].getName() != "cc" &&
+ Vals[i].getName() != "predict")
+ {
+ o << " // " << opNum << ": " << Vals[i].getName() << "\n";
+ OpOrder[Vals[i].getName()] = opNum++;
+ }
+ }
+
+ for (int f = Vals.size()-1; f >= 0; --f) {
+ if (Vals[f].getPrefix()) {
+ BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
+
+ // Scan through the field looking for bit initializers of the current
+ // variable...
+ for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
+
+ if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){
+ --Offset;
+ } else if (UnsetInit *UI =
+ dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
+ --Offset;
+ } else if (VarBitInit *VBI =
+ dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
+ TypedInit *TI = VBI->getVariable();
+ if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
+ o << " Value |= getValueBit(MI.getOperand("
+ << OpOrder[VI->getName()]
+ << "), " << VBI->getBitNum()
+ << ")" << " << " << Offset << ";\n";
+ --Offset;
+ } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
+ // FIXME: implement this!
+ o << "FIELD INIT not implemented yet!\n";
+ } else {
+ o << "something else\n";
+ }
+ }
+ }
+ }
+ }
+
+ o << " break;\n"
+ << " }\n";
+ }
+ o << " }\n"
+ << " return Value;\n"
+ << "}\n";
+}
diff --git a/utils/TableGen/CodeEmitterGen.h b/utils/TableGen/CodeEmitterGen.h
new file mode 100644
index 0000000000..18ebcd4bd4
--- /dev/null
+++ b/utils/TableGen/CodeEmitterGen.h
@@ -0,0 +1,23 @@
+//===- CodeEmitterGen.h - Code Emitter Generator ----------------*- C++ -*-===//
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEMITTERGEN_H
+#define CODEMITTERGEN_H
+
+#include "Record.h"
+#include <ostream>
+
+struct CodeEmitterGen {
+ RecordKeeper &Records;
+
+public:
+ CodeEmitterGen(RecordKeeper &R) : Records(R) {}
+
+ void createEmitter(std::ostream &o);
+ void emitMachineOpEmitter(std::ostream &o, const std::string &Namespace);
+ void emitGetValueBit(std::ostream &o, const std::string &Namespace);
+};
+
+#endif