]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/utils/TableGen/CodeEmitterGen.cpp
Import mandoc 1.4.1rc2
[FreeBSD/FreeBSD.git] / contrib / llvm / utils / TableGen / CodeEmitterGen.cpp
1 //===- CodeEmitterGen.cpp - Code Emitter Generator ------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // 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 "CodeGenTarget.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/TableGen/Record.h"
20 #include "llvm/TableGen/TableGenBackend.h"
21 #include <map>
22 #include <string>
23 #include <vector>
24 using namespace llvm;
25
26 namespace {
27
28 class CodeEmitterGen {
29   RecordKeeper &Records;
30 public:
31   CodeEmitterGen(RecordKeeper &R) : Records(R) {}
32
33   void run(raw_ostream &o);
34 private:
35   int getVariableBit(const std::string &VarName, BitsInit *BI, int bit);
36   std::string getInstructionCase(Record *R, CodeGenTarget &Target);
37   void AddCodeToMergeInOperand(Record *R, BitsInit *BI,
38                                const std::string &VarName,
39                                unsigned &NumberedOp,
40                                std::set<unsigned> &NamedOpIndices,
41                                std::string &Case, CodeGenTarget &Target);
42
43 };
44
45 // If the VarBitInit at position 'bit' matches the specified variable then
46 // return the variable bit position.  Otherwise return -1.
47 int CodeEmitterGen::getVariableBit(const std::string &VarName,
48                                    BitsInit *BI, int bit) {
49   if (VarBitInit *VBI = dyn_cast<VarBitInit>(BI->getBit(bit))) {
50     if (VarInit *VI = dyn_cast<VarInit>(VBI->getBitVar()))
51       if (VI->getName() == VarName)
52         return VBI->getBitNum();
53   } else if (VarInit *VI = dyn_cast<VarInit>(BI->getBit(bit))) {
54     if (VI->getName() == VarName)
55       return 0;
56   }
57
58   return -1;
59 }
60
61 void CodeEmitterGen::
62 AddCodeToMergeInOperand(Record *R, BitsInit *BI, const std::string &VarName,
63                         unsigned &NumberedOp,
64                         std::set<unsigned> &NamedOpIndices,
65                         std::string &Case, CodeGenTarget &Target) {
66   CodeGenInstruction &CGI = Target.getInstruction(R);
67
68   // Determine if VarName actually contributes to the Inst encoding.
69   int bit = BI->getNumBits()-1;
70
71   // Scan for a bit that this contributed to.
72   for (; bit >= 0; ) {
73     if (getVariableBit(VarName, BI, bit) != -1)
74       break;
75     
76     --bit;
77   }
78   
79   // If we found no bits, ignore this value, otherwise emit the call to get the
80   // operand encoding.
81   if (bit < 0) return;
82   
83   // If the operand matches by name, reference according to that
84   // operand number. Non-matching operands are assumed to be in
85   // order.
86   unsigned OpIdx;
87   if (CGI.Operands.hasOperandNamed(VarName, OpIdx)) {
88     // Get the machine operand number for the indicated operand.
89     OpIdx = CGI.Operands[OpIdx].MIOperandNo;
90     assert(!CGI.Operands.isFlatOperandNotEmitted(OpIdx) &&
91            "Explicitly used operand also marked as not emitted!");
92   } else {
93     unsigned NumberOps = CGI.Operands.size();
94     /// If this operand is not supposed to be emitted by the
95     /// generated emitter, skip it.
96     while (NumberedOp < NumberOps &&
97            (CGI.Operands.isFlatOperandNotEmitted(NumberedOp) ||
98               (!NamedOpIndices.empty() && NamedOpIndices.count(
99                 CGI.Operands.getSubOperandNumber(NumberedOp).first)))) {
100       ++NumberedOp;
101
102       if (NumberedOp >= CGI.Operands.back().MIOperandNo +
103                         CGI.Operands.back().MINumOperands) {
104         errs() << "Too few operands in record " << R->getName() <<
105                   " (no match for variable " << VarName << "):\n";
106         errs() << *R;
107         errs() << '\n';
108
109         return;
110       }
111     }
112
113     OpIdx = NumberedOp++;
114   }
115   
116   std::pair<unsigned, unsigned> SO = CGI.Operands.getSubOperandNumber(OpIdx);
117   std::string &EncoderMethodName = CGI.Operands[SO.first].EncoderMethodName;
118   
119   // If the source operand has a custom encoder, use it. This will
120   // get the encoding for all of the suboperands.
121   if (!EncoderMethodName.empty()) {
122     // A custom encoder has all of the information for the
123     // sub-operands, if there are more than one, so only
124     // query the encoder once per source operand.
125     if (SO.second == 0) {
126       Case += "      // op: " + VarName + "\n" +
127               "      op = " + EncoderMethodName + "(MI, " + utostr(OpIdx);
128       Case += ", Fixups, STI";
129       Case += ");\n";
130     }
131   } else {
132     Case += "      // op: " + VarName + "\n" +
133       "      op = getMachineOpValue(MI, MI.getOperand(" + utostr(OpIdx) + ")";
134     Case += ", Fixups, STI";
135     Case += ");\n";
136   }
137   
138   for (; bit >= 0; ) {
139     int varBit = getVariableBit(VarName, BI, bit);
140     
141     // If this bit isn't from a variable, skip it.
142     if (varBit == -1) {
143       --bit;
144       continue;
145     }
146     
147     // Figure out the consecutive range of bits covered by this operand, in
148     // order to generate better encoding code.
149     int beginInstBit = bit;
150     int beginVarBit = varBit;
151     int N = 1;
152     for (--bit; bit >= 0;) {
153       varBit = getVariableBit(VarName, BI, bit);
154       if (varBit == -1 || varBit != (beginVarBit - N)) break;
155       ++N;
156       --bit;
157     }
158      
159     uint64_t opMask = ~(uint64_t)0 >> (64-N);
160     int opShift = beginVarBit - N + 1;
161     opMask <<= opShift;
162     opShift = beginInstBit - beginVarBit;
163     
164     if (opShift > 0) {
165       Case += "      Value |= (op & UINT64_C(" + utostr(opMask) + ")) << " +
166               itostr(opShift) + ";\n";
167     } else if (opShift < 0) {
168       Case += "      Value |= (op & UINT64_C(" + utostr(opMask) + ")) >> " + 
169               itostr(-opShift) + ";\n";
170     } else {
171       Case += "      Value |= op & UINT64_C(" + utostr(opMask) + ");\n";
172     }
173   }
174 }
175
176
177 std::string CodeEmitterGen::getInstructionCase(Record *R,
178                                                CodeGenTarget &Target) {
179   std::string Case;
180   
181   BitsInit *BI = R->getValueAsBitsInit("Inst");
182   const std::vector<RecordVal> &Vals = R->getValues();
183   unsigned NumberedOp = 0;
184
185   std::set<unsigned> NamedOpIndices;
186   // Collect the set of operand indices that might correspond to named
187   // operand, and skip these when assigning operands based on position.
188   if (Target.getInstructionSet()->
189        getValueAsBit("noNamedPositionallyEncodedOperands")) {
190     CodeGenInstruction &CGI = Target.getInstruction(R);
191     for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
192       unsigned OpIdx;
193       if (!CGI.Operands.hasOperandNamed(Vals[i].getName(), OpIdx))
194         continue;
195
196       NamedOpIndices.insert(OpIdx);
197     }
198   }
199
200   // Loop over all of the fields in the instruction, determining which are the
201   // operands to the instruction.
202   for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
203     // Ignore fixed fields in the record, we're looking for values like:
204     //    bits<5> RST = { ?, ?, ?, ?, ? };
205     if (Vals[i].getPrefix() || Vals[i].getValue()->isComplete())
206       continue;
207     
208     AddCodeToMergeInOperand(R, BI, Vals[i].getName(), NumberedOp,
209                             NamedOpIndices, Case, Target);
210   }
211   
212   std::string PostEmitter = R->getValueAsString("PostEncoderMethod");
213   if (!PostEmitter.empty()) {
214     Case += "      Value = " + PostEmitter + "(MI, Value";
215     Case += ", STI";
216     Case += ");\n";
217   }
218   
219   return Case;
220 }
221
222 void CodeEmitterGen::run(raw_ostream &o) {
223   CodeGenTarget Target(Records);
224   std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
225
226   // For little-endian instruction bit encodings, reverse the bit order
227   Target.reverseBitsForLittleEndianEncoding();
228
229   ArrayRef<const CodeGenInstruction*> NumberedInstructions =
230     Target.getInstructionsByEnumValue();
231
232   // Emit function declaration
233   o << "uint64_t " << Target.getName();
234   o << "MCCodeEmitter::getBinaryCodeForInstr(const MCInst &MI,\n"
235     << "    SmallVectorImpl<MCFixup> &Fixups,\n"
236     << "    const MCSubtargetInfo &STI) const {\n";
237
238   // Emit instruction base values
239   o << "  static const uint64_t InstBits[] = {\n";
240   for (const CodeGenInstruction *CGI : NumberedInstructions) {
241     Record *R = CGI->TheDef;
242
243     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
244         R->getValueAsBit("isPseudo")) {
245       o << "    UINT64_C(0),\n";
246       continue;
247     }
248
249     BitsInit *BI = R->getValueAsBitsInit("Inst");
250
251     // Start by filling in fixed values.
252     uint64_t Value = 0;
253     for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i) {
254       if (BitInit *B = dyn_cast<BitInit>(BI->getBit(e-i-1)))
255         Value |= (uint64_t)B->getValue() << (e-i-1);
256     }
257     o << "    UINT64_C(" << Value << ")," << '\t' << "// " << R->getName() << "\n";
258   }
259   o << "    UINT64_C(0)\n  };\n";
260
261   // Map to accumulate all the cases.
262   std::map<std::string, std::vector<std::string> > CaseMap;
263
264   // Construct all cases statement for each opcode
265   for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
266         IC != EC; ++IC) {
267     Record *R = *IC;
268     if (R->getValueAsString("Namespace") == "TargetOpcode" ||
269         R->getValueAsBit("isPseudo"))
270       continue;
271     const std::string &InstName = R->getValueAsString("Namespace") + "::"
272       + R->getName();
273     std::string Case = getInstructionCase(R, Target);
274
275     CaseMap[Case].push_back(InstName);
276   }
277
278   // Emit initial function code
279   o << "  const unsigned opcode = MI.getOpcode();\n"
280     << "  uint64_t Value = InstBits[opcode];\n"
281     << "  uint64_t op = 0;\n"
282     << "  (void)op;  // suppress warning\n"
283     << "  switch (opcode) {\n";
284
285   // Emit each case statement
286   std::map<std::string, std::vector<std::string> >::iterator IE, EE;
287   for (IE = CaseMap.begin(), EE = CaseMap.end(); IE != EE; ++IE) {
288     const std::string &Case = IE->first;
289     std::vector<std::string> &InstList = IE->second;
290
291     for (int i = 0, N = InstList.size(); i < N; i++) {
292       if (i) o << "\n";
293       o << "    case " << InstList[i]  << ":";
294     }
295     o << " {\n";
296     o << Case;
297     o << "      break;\n"
298       << "    }\n";
299   }
300
301   // Default case: unhandled opcode
302   o << "  default:\n"
303     << "    std::string msg;\n"
304     << "    raw_string_ostream Msg(msg);\n"
305     << "    Msg << \"Not supported instr: \" << MI;\n"
306     << "    report_fatal_error(Msg.str());\n"
307     << "  }\n"
308     << "  return Value;\n"
309     << "}\n\n";
310 }
311
312 } // End anonymous namespace
313
314 namespace llvm {
315
316 void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS) {
317   emitSourceFileHeader("Machine Code Emitter", OS);
318   CodeEmitterGen(RK).run(OS);
319 }
320
321 } // End llvm namespace