0619967f7708d0dddf47096b91fa69f664d3daee
[oota-llvm.git] / utils / TableGen / CodeEmitterGen.cpp
1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
2 //
3 // FIXME: Document.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "CodeEmitterGen.h"
8 #include "Record.h"
9 #include "Support/Statistic.h"
10
11 void CodeEmitterGen::run(std::ostream &o) {
12   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
13
14   std::string Namespace = "V9::";
15   std::string ClassName = "SparcV9CodeEmitter::";
16
17   //const std::string &Namespace = Inst->getValue("Namespace")->getName();
18   o << "unsigned " << ClassName
19     << "getBinaryCodeForInstr(MachineInstr &MI) {\n"
20     << "  unsigned Value = 0;\n"
21     << "  DEBUG(std::cerr << MI);\n"
22     << "  switch (MI.getOpcode()) {\n";
23   for (std::vector<Record*>::iterator I = Insts.begin(), E = Insts.end();
24        I != E; ++I) {
25     Record *R = *I;
26     o << "    case " << Namespace << R->getName() << ": {\n"
27       << "      DEBUG(std::cerr << \"Emitting " << R->getName() << "\\n\");\n";
28
29     const RecordVal *InstVal = R->getValue("Inst");
30     if (!InstVal)
31       throw std::string("No 'Inst' record found in target description file!");
32
33     Init *InitVal = InstVal->getValue();
34     assert(dynamic_cast<BitsInit*>(InitVal) &&
35            "Can only handle undefined bits<> types!");
36     BitsInit *BI = (BitsInit*)InitVal;
37
38     unsigned Value = 0;
39     const std::vector<RecordVal> &Vals = R->getValues();
40
41     DEBUG(o << "      // prefilling: ");
42     // Start by filling in fixed values...
43     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
44       if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(e-i-1))) {
45         Value |= B->getValue() << (e-i-1);
46         DEBUG(o << B->getValue());
47       } else {
48         DEBUG(o << "0");
49       }
50     }
51     DEBUG(o << "\n");
52
53     DEBUG(o << "      // " << *InstVal << "\n");
54     o << "      Value = " << Value << "U;\n\n";
55     
56     // Loop over all of the fields in the instruction adding in any
57     // contributions to this value (due to bit references).
58     //
59     unsigned op = 0;
60     std::map<const std::string,unsigned> OpOrder;
61     std::map<const std::string,bool> OpContinuous;
62     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
63       if (Vals[i].getName() != "Inst" && 
64           !Vals[i].getValue()->isComplete() &&
65           /* ignore annul and predict bits since no one sets them yet */
66           Vals[i].getName() != "annul" && 
67           Vals[i].getName() != "predict")
68       {
69         o << "      // op" << op << ": " << Vals[i].getName() << "\n"
70           << "      int64_t op" << op 
71           <<" = getMachineOpValue(MI, MI.getOperand("<<op<<"));\n";
72         //<< "      MachineOperand &op" << op <<" = MI.getOperand("<<op<<");\n";
73         OpOrder[Vals[i].getName()] = op++;
74
75         // Is the operand continuous? If so, we can just mask and OR it in
76         // instead of doing it bit-by-bit, saving a lot in runtime cost.        
77         const BitsInit *InstInit = BI;
78         int beginBitInVar = -1, endBitInVar = -1,
79           beginBitInInst = -1, endBitInInst = -1;
80         bool continuous = true;
81
82         for (int bit = InstInit->getNumBits()-1; bit >= 0; --bit) {
83           if (VarBitInit *VBI =
84               dynamic_cast<VarBitInit*>(InstInit->getBit(bit))) {
85             TypedInit *TI = VBI->getVariable();
86             if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
87               // only process the current variable
88               if (VI->getName() != Vals[i].getName())
89                 continue;
90
91               if (beginBitInVar == -1)
92                 beginBitInVar = VBI->getBitNum();
93
94               if (endBitInVar == -1)
95                 endBitInVar = VBI->getBitNum();
96               else {
97                 if (endBitInVar == (int)VBI->getBitNum() + 1)
98                   endBitInVar = VBI->getBitNum();
99                 else {
100                   continuous = false;
101                   break;
102                 }
103               }
104
105               if (beginBitInInst == -1)
106                 beginBitInInst = bit;
107               if (endBitInInst == -1)
108                 endBitInInst = bit;
109               else {
110                 if (endBitInInst == bit + 1)
111                   endBitInInst = bit;
112                 else {
113                   continuous = false;
114                   break;
115                 }
116               }
117
118               // maintain same distance between bits in field and bits in
119               // instruction. if the relative distances stay the same
120               // throughout,
121               if ((beginBitInVar - (int)VBI->getBitNum()) !=
122                   (beginBitInInst - bit))
123               {
124                 continuous = false;
125                 break;
126               }
127             }
128           }
129         }
130
131         DEBUG(o << "      // Var: begin = " << beginBitInVar 
132                 << ", end = " << endBitInVar
133                 << "; Inst: begin = " << beginBitInInst
134                 << ", end = " << endBitInInst << "\n");
135
136         if (continuous) {
137           DEBUG(o << "      // continuous: op" << OpOrder[Vals[i].getName()]
138                   << "\n");
139           
140           // Mask off the right bits
141           // Low mask (ie. shift, if necessary)
142           if (endBitInVar != 0) {
143             o << "      op" << OpOrder[Vals[i].getName()]
144               << " >>= " << endBitInVar << ";\n";
145             beginBitInVar -= endBitInVar;
146             endBitInVar = 0;
147           }
148
149           // High mask
150           o << "      op" << OpOrder[Vals[i].getName()]
151             << " &= (1<<" << beginBitInVar+1 << ") - 1;\n";
152
153           // Shift the value to the correct place (according to place in instr)
154           if (endBitInInst != 0)
155             o << "      op" << OpOrder[Vals[i].getName()]
156               << " <<= " << endBitInInst << ";\n";
157
158           // Just OR in the result
159           o << "      Value |= op" << OpOrder[Vals[i].getName()] << ";\n";
160         }
161
162         // otherwise, will be taken care of in the loop below using this value:
163         OpContinuous[Vals[i].getName()] = continuous;
164       }
165     }
166
167     for (unsigned f = 0, e = Vals.size(); f != e; ++f) {
168       if (Vals[f].getPrefix()) {
169         BitsInit *FieldInitializer = (BitsInit*)Vals[f].getValue();
170
171         // Scan through the field looking for bit initializers of the current
172         // variable...
173         for (int i = FieldInitializer->getNumBits()-1; i >= 0; --i) {
174           if (BitInit *BI=dynamic_cast<BitInit*>(FieldInitializer->getBit(i)))
175           {
176             DEBUG(o << "      // bit init: f: " << f << ", i: " << i << "\n");
177           } else if (UnsetInit *UI =
178                      dynamic_cast<UnsetInit*>(FieldInitializer->getBit(i))) {
179             DEBUG(o << "      // unset init: f: " << f << ", i: " << i << "\n");
180           } else if (VarBitInit *VBI =
181                      dynamic_cast<VarBitInit*>(FieldInitializer->getBit(i))) {
182             TypedInit *TI = VBI->getVariable();
183             if (VarInit *VI = dynamic_cast<VarInit*>(TI)) {
184               // If the bits of the field are laid out consecutively in the
185               // instruction, then instead of separately ORing in bits, just
186               // mask and shift the entire field for efficiency.
187               if (OpContinuous[VI->getName()]) {
188                 // already taken care of in the loop above, thus there is no
189                 // need to individually OR in the bits
190
191                 // for debugging, output the regular version anyway, commented
192                 DEBUG(o << "      // Value |= getValueBit(op"
193                         << OpOrder[VI->getName()] << ", " << VBI->getBitNum()
194                         << ")" << " << " << i << ";\n");
195               } else {
196                 o << "      Value |= getValueBit(op" << OpOrder[VI->getName()]
197                   << ", " << VBI->getBitNum()
198                   << ")" << " << " << i << ";\n";
199               }
200             } else if (FieldInit *FI = dynamic_cast<FieldInit*>(TI)) {
201               // FIXME: implement this!
202               o << "FIELD INIT not implemented yet!\n";
203             } else {
204               o << "Error: UNIMPLEMENTED\n";
205             }
206           }
207         }
208       } else {
209         // ignore annul and predict bits since no one sets them yet
210         if (Vals[f].getName() == "annul" || Vals[f].getName() == "predict") {
211           o << "      // found " << Vals[f].getName() << "\n";
212         }
213       }
214     }
215
216     o << "      break;\n"
217       << "    }\n";
218   }
219
220   o << "  default:\n"
221     << "    DEBUG(std::cerr << \"Not supported instr: \" << MI << \"\\n\");\n"
222     << "    abort();\n"
223     << "  }\n"
224     << "  return Value;\n"
225     << "}\n";
226 }