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