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