Output the opcode name of the instruction being emitted to cerr.
[oota-llvm.git] / utils / TableGen / CodeEmitterGen.cpp
1 #include "Record.h"
2 #include "CodeEmitterGen.h"
3 #include <ostream>
4
5 void CodeEmitterGen::createEmitter(std::ostream &o) {
6   std::vector<Record*> Insts;
7
8   const std::map<std::string, Record*> &Defs = Records.getDefs();
9   Record *Inst = Records.getClass("Instruction");
10   assert(Inst && "Couldn't find Instruction class!");
11
12   for (std::map<std::string, Record*>::const_iterator I = Defs.begin(),
13          E = Defs.end(); I != E; ++I)
14     if (I->second->isSubClassOf(Inst))
15       Insts.push_back(I->second);
16
17   std::string Namespace = "V9::";
18   std::string ClassName = "SparcV9CodeEmitter::";
19
20   //const std::string &Namespace = Inst->getValue("Namespace")->getName();
21   o << "unsigned " << ClassName
22     << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
23     << "  unsigned Value = 0;\n"
24     << "  std::cerr << MI;\n"
25     << "  switch (MI.getOpcode()) {\n";
26   for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
27        I != E; ++I)
28   {
29     Record *R = *I;
30     o << "    case " << Namespace << R->getName() << ": {\n"
31       << "      std::cerr << \"Emitting " << R->getName() << "\\n\";\n";
32
33     const RecordVal *InstVal = R->getValue("Inst");
34     Init *InitVal = InstVal->getValue();
35
36     assert(dynamic_cast<BitsInit*>(InitVal) &&
37            "Can only handle undefined bits<> types!");
38     BitsInit *BI = (BitsInit*)InitVal;
39
40     unsigned Value = 0;
41     const std::vector<RecordVal> &Vals = R->getValues();
42
43     o << "      // prefilling: ";
44     // Start by filling in fixed values...
45     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
46       if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
47         Value |= B->getValue() << (e-i-1);
48         o << B->getValue();
49       } else {
50         o << "0";
51       }
52     }
53     o << "\n";
54
55     o << "      // " << *InstVal << "\n";
56     o << "      Value = " << Value << "U;\n\n";
57     
58     // Loop over all of the fields in the instruction adding in any
59     // contributions to this value (due to bit references).
60     //
61     unsigned op = 0;
62     std::map<const std::string,unsigned> OpOrder;
63     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
64       if (Vals[i].getName() != "Inst" && 
65           !Vals[i].getValue()->isComplete() &&
66           Vals[i].getName() != "annul" && 
67           Vals[i].getName() != "cc" &&
68           Vals[i].getName() != "predict")
69       {
70         o << "      // op" << op << ": " << Vals[i].getName() << "\n"
71           << "      int64_t op" << op 
72           <<" = getMachineOpValue(MI.getOperand("<<op<<"));\n";
73         //<< "      MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
74         OpOrder[Vals[i].getName()] = op++;
75       }
76     }
77
78     unsigned Offset = 31;
79     for (int f = Vals.size()-1; f >= 0; --f) {
80       if (Vals[f].getPrefix()) {
81         BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
82
83         // Scan through the field looking for bit initializers of the current
84         // variable...
85         for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
86           if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i))){
87             --Offset;
88           } else if (UnsetInit *UI = 
89                      dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
90             --Offset;
91           } else if (VarBitInit *VBI =
92                      dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
93             TypedInit *TI = VBI->getVariable();
94             if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
95               o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
96                 << ", " << VBI->getBitNum()
97                 << ")" << " << " << Offset << ";\n";
98               --Offset;
99             } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
100               // FIXME: implement this!
101               o << "FIELD INIT not implemented yet!\n";
102             } else {
103               o << "Error: UNIMPLEMENTED\n";
104             }
105           }
106         } 
107       } else {
108         if (Vals[f].getName() == "annul" || Vals[f].getName() == "cc" ||
109             Vals[f].getName() == "predict")
110           --Offset;
111       }
112     }
113
114     o << "      break;\n"
115       << "    }\n";
116   }
117   o << "  default:\n"
118     << "    std::cerr << \"Not supported instr: \" << MI << \"\\n\";\n"
119     << "    abort();\n"
120     << "  }\n"
121     << "  return Value;\n"
122     << "}\n";
123 }