1193323Sed//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This tablegen backend is emits an assembly printer for the current target.
11193323Sed// Note that this is currently fairly skeletal, but will grow over time.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15203954Srdivacky#include "AsmWriterInst.h"
16193323Sed#include "CodeGenTarget.h"
17234353Sdim#include "SequenceToOffsetTable.h"
18239462Sdim#include "llvm/ADT/StringExtras.h"
19224145Sdim#include "llvm/ADT/Twine.h"
20193323Sed#include "llvm/Support/Debug.h"
21263508Sdim#include "llvm/Support/Format.h"
22193323Sed#include "llvm/Support/MathExtras.h"
23226633Sdim#include "llvm/TableGen/Error.h"
24226633Sdim#include "llvm/TableGen/Record.h"
25239462Sdim#include "llvm/TableGen/TableGenBackend.h"
26193323Sed#include <algorithm>
27239462Sdim#include <cassert>
28239462Sdim#include <map>
29239462Sdim#include <vector>
30193323Sedusing namespace llvm;
31193323Sed
32239462Sdimnamespace {
33239462Sdimclass AsmWriterEmitter {
34239462Sdim  RecordKeeper &Records;
35263508Sdim  CodeGenTarget Target;
36239462Sdim  std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap;
37239462Sdim  std::vector<const CodeGenInstruction*> NumberedInstructions;
38263508Sdim  std::vector<AsmWriterInst> Instructions;
39239462Sdimpublic:
40263508Sdim  AsmWriterEmitter(RecordKeeper &R);
41239462Sdim
42239462Sdim  void run(raw_ostream &o);
43239462Sdim
44239462Sdimprivate:
45239462Sdim  void EmitPrintInstruction(raw_ostream &o);
46239462Sdim  void EmitGetRegisterName(raw_ostream &o);
47239462Sdim  void EmitPrintAliasInstruction(raw_ostream &O);
48239462Sdim
49239462Sdim  AsmWriterInst *getAsmWriterInstByID(unsigned ID) const {
50239462Sdim    assert(ID < NumberedInstructions.size());
51239462Sdim    std::map<const CodeGenInstruction*, AsmWriterInst*>::const_iterator I =
52239462Sdim      CGIAWIMap.find(NumberedInstructions[ID]);
53239462Sdim    assert(I != CGIAWIMap.end() && "Didn't find inst!");
54239462Sdim    return I->second;
55239462Sdim  }
56239462Sdim  void FindUniqueOperandCommands(std::vector<std::string> &UOC,
57239462Sdim                                 std::vector<unsigned> &InstIdxs,
58239462Sdim                                 std::vector<unsigned> &InstOpsUsed) const;
59239462Sdim};
60239462Sdim} // end anonymous namespace
61239462Sdim
62193323Sedstatic void PrintCases(std::vector<std::pair<std::string,
63195340Sed                       AsmWriterOperand> > &OpsToPrint, raw_ostream &O) {
64193323Sed  O << "    case " << OpsToPrint.back().first << ": ";
65193323Sed  AsmWriterOperand TheOp = OpsToPrint.back().second;
66193323Sed  OpsToPrint.pop_back();
67193323Sed
68193323Sed  // Check to see if any other operands are identical in this list, and if so,
69193323Sed  // emit a case label for them.
70193323Sed  for (unsigned i = OpsToPrint.size(); i != 0; --i)
71193323Sed    if (OpsToPrint[i-1].second == TheOp) {
72193323Sed      O << "\n    case " << OpsToPrint[i-1].first << ": ";
73193323Sed      OpsToPrint.erase(OpsToPrint.begin()+i-1);
74193323Sed    }
75193323Sed
76193323Sed  // Finally, emit the code.
77193323Sed  O << TheOp.getCode();
78193323Sed  O << "break;\n";
79193323Sed}
80193323Sed
81193323Sed
82193323Sed/// EmitInstructions - Emit the last instruction in the vector and any other
83193323Sed/// instructions that are suitably similar to it.
84193323Sedstatic void EmitInstructions(std::vector<AsmWriterInst> &Insts,
85195340Sed                             raw_ostream &O) {
86193323Sed  AsmWriterInst FirstInst = Insts.back();
87193323Sed  Insts.pop_back();
88193323Sed
89193323Sed  std::vector<AsmWriterInst> SimilarInsts;
90193323Sed  unsigned DifferingOperand = ~0;
91193323Sed  for (unsigned i = Insts.size(); i != 0; --i) {
92193323Sed    unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst);
93193323Sed    if (DiffOp != ~1U) {
94193323Sed      if (DifferingOperand == ~0U)  // First match!
95193323Sed        DifferingOperand = DiffOp;
96193323Sed
97193323Sed      // If this differs in the same operand as the rest of the instructions in
98193323Sed      // this class, move it to the SimilarInsts list.
99193323Sed      if (DifferingOperand == DiffOp || DiffOp == ~0U) {
100193323Sed        SimilarInsts.push_back(Insts[i-1]);
101193323Sed        Insts.erase(Insts.begin()+i-1);
102193323Sed      }
103193323Sed    }
104193323Sed  }
105193323Sed
106193323Sed  O << "  case " << FirstInst.CGI->Namespace << "::"
107193323Sed    << FirstInst.CGI->TheDef->getName() << ":\n";
108193323Sed  for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i)
109193323Sed    O << "  case " << SimilarInsts[i].CGI->Namespace << "::"
110193323Sed      << SimilarInsts[i].CGI->TheDef->getName() << ":\n";
111193323Sed  for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) {
112193323Sed    if (i != DifferingOperand) {
113193323Sed      // If the operand is the same for all instructions, just print it.
114193323Sed      O << "    " << FirstInst.Operands[i].getCode();
115193323Sed    } else {
116193323Sed      // If this is the operand that varies between all of the instructions,
117193323Sed      // emit a switch for just this operand now.
118193323Sed      O << "    switch (MI->getOpcode()) {\n";
119193323Sed      std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint;
120193323Sed      OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" +
121193323Sed                                          FirstInst.CGI->TheDef->getName(),
122193323Sed                                          FirstInst.Operands[i]));
123193323Sed
124193323Sed      for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) {
125193323Sed        AsmWriterInst &AWI = SimilarInsts[si];
126193323Sed        OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+
127193323Sed                                            AWI.CGI->TheDef->getName(),
128193323Sed                                            AWI.Operands[i]));
129193323Sed      }
130193323Sed      std::reverse(OpsToPrint.begin(), OpsToPrint.end());
131193323Sed      while (!OpsToPrint.empty())
132193323Sed        PrintCases(OpsToPrint, O);
133193323Sed      O << "    }";
134193323Sed    }
135193323Sed    O << "\n";
136193323Sed  }
137193323Sed  O << "    break;\n";
138193323Sed}
139193323Sed
140193323Sedvoid AsmWriterEmitter::
141218893SdimFindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
142193323Sed                          std::vector<unsigned> &InstIdxs,
143193323Sed                          std::vector<unsigned> &InstOpsUsed) const {
144193323Sed  InstIdxs.assign(NumberedInstructions.size(), ~0U);
145218893Sdim
146193323Sed  // This vector parallels UniqueOperandCommands, keeping track of which
147193323Sed  // instructions each case are used for.  It is a comma separated string of
148193323Sed  // enums.
149193323Sed  std::vector<std::string> InstrsForCase;
150193323Sed  InstrsForCase.resize(UniqueOperandCommands.size());
151193323Sed  InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
152218893Sdim
153193323Sed  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
154193323Sed    const AsmWriterInst *Inst = getAsmWriterInstByID(i);
155212904Sdim    if (Inst == 0) continue;  // PHI, INLINEASM, PROLOG_LABEL, etc.
156218893Sdim
157193323Sed    std::string Command;
158193323Sed    if (Inst->Operands.empty())
159193323Sed      continue;   // Instruction already done.
160193323Sed
161193323Sed    Command = "    " + Inst->Operands[0].getCode() + "\n";
162193323Sed
163193323Sed    // Check to see if we already have 'Command' in UniqueOperandCommands.
164193323Sed    // If not, add it.
165193323Sed    bool FoundIt = false;
166193323Sed    for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx)
167193323Sed      if (UniqueOperandCommands[idx] == Command) {
168193323Sed        InstIdxs[i] = idx;
169193323Sed        InstrsForCase[idx] += ", ";
170193323Sed        InstrsForCase[idx] += Inst->CGI->TheDef->getName();
171193323Sed        FoundIt = true;
172193323Sed        break;
173193323Sed      }
174193323Sed    if (!FoundIt) {
175193323Sed      InstIdxs[i] = UniqueOperandCommands.size();
176193323Sed      UniqueOperandCommands.push_back(Command);
177193323Sed      InstrsForCase.push_back(Inst->CGI->TheDef->getName());
178193323Sed
179193323Sed      // This command matches one operand so far.
180193323Sed      InstOpsUsed.push_back(1);
181193323Sed    }
182193323Sed  }
183218893Sdim
184193323Sed  // For each entry of UniqueOperandCommands, there is a set of instructions
185193323Sed  // that uses it.  If the next command of all instructions in the set are
186193323Sed  // identical, fold it into the command.
187193323Sed  for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size();
188193323Sed       CommandIdx != e; ++CommandIdx) {
189218893Sdim
190193323Sed    for (unsigned Op = 1; ; ++Op) {
191193323Sed      // Scan for the first instruction in the set.
192193323Sed      std::vector<unsigned>::iterator NIT =
193193323Sed        std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
194193323Sed      if (NIT == InstIdxs.end()) break;  // No commonality.
195193323Sed
196193323Sed      // If this instruction has no more operands, we isn't anything to merge
197193323Sed      // into this command.
198218893Sdim      const AsmWriterInst *FirstInst =
199193323Sed        getAsmWriterInstByID(NIT-InstIdxs.begin());
200193323Sed      if (!FirstInst || FirstInst->Operands.size() == Op)
201193323Sed        break;
202193323Sed
203193323Sed      // Otherwise, scan to see if all of the other instructions in this command
204193323Sed      // set share the operand.
205193323Sed      bool AllSame = true;
206198090Srdivacky      // Keep track of the maximum, number of operands or any
207198090Srdivacky      // instruction we see in the group.
208198090Srdivacky      size_t MaxSize = FirstInst->Operands.size();
209198090Srdivacky
210193323Sed      for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
211193323Sed           NIT != InstIdxs.end();
212193323Sed           NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) {
213193323Sed        // Okay, found another instruction in this command set.  If the operand
214193323Sed        // matches, we're ok, otherwise bail out.
215218893Sdim        const AsmWriterInst *OtherInst =
216193323Sed          getAsmWriterInstByID(NIT-InstIdxs.begin());
217198090Srdivacky
218198090Srdivacky        if (OtherInst &&
219198090Srdivacky            OtherInst->Operands.size() > FirstInst->Operands.size())
220198090Srdivacky          MaxSize = std::max(MaxSize, OtherInst->Operands.size());
221198090Srdivacky
222193323Sed        if (!OtherInst || OtherInst->Operands.size() == Op ||
223193323Sed            OtherInst->Operands[Op] != FirstInst->Operands[Op]) {
224193323Sed          AllSame = false;
225193323Sed          break;
226193323Sed        }
227193323Sed      }
228193323Sed      if (!AllSame) break;
229218893Sdim
230193323Sed      // Okay, everything in this command set has the same next operand.  Add it
231193323Sed      // to UniqueOperandCommands and remember that it was consumed.
232193323Sed      std::string Command = "    " + FirstInst->Operands[Op].getCode() + "\n";
233218893Sdim
234193323Sed      UniqueOperandCommands[CommandIdx] += Command;
235193323Sed      InstOpsUsed[CommandIdx]++;
236193323Sed    }
237193323Sed  }
238218893Sdim
239193323Sed  // Prepend some of the instructions each case is used for onto the case val.
240193323Sed  for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) {
241193323Sed    std::string Instrs = InstrsForCase[i];
242193323Sed    if (Instrs.size() > 70) {
243193323Sed      Instrs.erase(Instrs.begin()+70, Instrs.end());
244193323Sed      Instrs += "...";
245193323Sed    }
246218893Sdim
247193323Sed    if (!Instrs.empty())
248218893Sdim      UniqueOperandCommands[i] = "    // " + Instrs + "\n" +
249193323Sed        UniqueOperandCommands[i];
250193323Sed  }
251193323Sed}
252193323Sed
253193323Sed
254198396Srdivackystatic void UnescapeString(std::string &Str) {
255198396Srdivacky  for (unsigned i = 0; i != Str.size(); ++i) {
256198396Srdivacky    if (Str[i] == '\\' && i != Str.size()-1) {
257198396Srdivacky      switch (Str[i+1]) {
258198396Srdivacky      default: continue;  // Don't execute the code after the switch.
259198396Srdivacky      case 'a': Str[i] = '\a'; break;
260198396Srdivacky      case 'b': Str[i] = '\b'; break;
261198396Srdivacky      case 'e': Str[i] = 27; break;
262198396Srdivacky      case 'f': Str[i] = '\f'; break;
263198396Srdivacky      case 'n': Str[i] = '\n'; break;
264198396Srdivacky      case 'r': Str[i] = '\r'; break;
265198396Srdivacky      case 't': Str[i] = '\t'; break;
266198396Srdivacky      case 'v': Str[i] = '\v'; break;
267198396Srdivacky      case '"': Str[i] = '\"'; break;
268198396Srdivacky      case '\'': Str[i] = '\''; break;
269198396Srdivacky      case '\\': Str[i] = '\\'; break;
270198396Srdivacky      }
271198396Srdivacky      // Nuke the second character.
272198396Srdivacky      Str.erase(Str.begin()+i+1);
273198396Srdivacky    }
274198396Srdivacky  }
275198396Srdivacky}
276198396Srdivacky
277198090Srdivacky/// EmitPrintInstruction - Generate the code for the "printInstruction" method
278263508Sdim/// implementation. Destroys all instances of AsmWriterInst information, by
279263508Sdim/// clearing the Instructions vector.
280198090Srdivackyvoid AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
281193323Sed  Record *AsmWriter = Target.getAsmWriter();
282193323Sed  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
283218893Sdim  bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter");
284218893Sdim  const char *MachineInstrClassName = isMC ? "MCInst" : "MachineInstr";
285218893Sdim
286193323Sed  O <<
287193323Sed  "/// printInstruction - This method is automatically generated by tablegen\n"
288198090Srdivacky  "/// from the instruction set description.\n"
289198090Srdivacky    "void " << Target.getName() << ClassName
290218893Sdim            << "::printInstruction(const " << MachineInstrClassName
291218893Sdim            << " *MI, raw_ostream &O) {\n";
292193323Sed
293193323Sed  // Build an aggregate string, and build a table of offsets into it.
294234353Sdim  SequenceToOffsetTable<std::string> StringTable;
295218893Sdim
296193323Sed  /// OpcodeInfo - This encodes the index of the string to use for the first
297193323Sed  /// chunk of the output as well as indices used for operand printing.
298243830Sdim  /// To reduce the number of unhandled cases, we expand the size from 32-bit
299243830Sdim  /// to 32+16 = 48-bit.
300243830Sdim  std::vector<uint64_t> OpcodeInfo;
301218893Sdim
302234353Sdim  // Add all strings to the string table upfront so it can generate an optimized
303234353Sdim  // representation.
304234353Sdim  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
305234353Sdim    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
306234353Sdim    if (AWI != 0 &&
307234982Sdim        AWI->Operands[0].OperandType ==
308234982Sdim                 AsmWriterOperand::isLiteralTextOperand &&
309234353Sdim        !AWI->Operands[0].Str.empty()) {
310234353Sdim      std::string Str = AWI->Operands[0].Str;
311234353Sdim      UnescapeString(Str);
312234353Sdim      StringTable.add(Str);
313234353Sdim    }
314234353Sdim  }
315234353Sdim
316234353Sdim  StringTable.layout();
317234353Sdim
318193323Sed  unsigned MaxStringIdx = 0;
319193323Sed  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
320193323Sed    AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
321193323Sed    unsigned Idx;
322193323Sed    if (AWI == 0) {
323193323Sed      // Something not handled by the asmwriter printer.
324198090Srdivacky      Idx = ~0U;
325218893Sdim    } else if (AWI->Operands[0].OperandType !=
326193323Sed                        AsmWriterOperand::isLiteralTextOperand ||
327193323Sed               AWI->Operands[0].Str.empty()) {
328193323Sed      // Something handled by the asmwriter printer, but with no leading string.
329234353Sdim      Idx = StringTable.get("");
330193323Sed    } else {
331198090Srdivacky      std::string Str = AWI->Operands[0].Str;
332198090Srdivacky      UnescapeString(Str);
333234353Sdim      Idx = StringTable.get(Str);
334198090Srdivacky      MaxStringIdx = std::max(MaxStringIdx, Idx);
335218893Sdim
336193323Sed      // Nuke the string from the operand list.  It is now handled!
337193323Sed      AWI->Operands.erase(AWI->Operands.begin());
338193323Sed    }
339218893Sdim
340198090Srdivacky    // Bias offset by one since we want 0 as a sentinel.
341198090Srdivacky    OpcodeInfo.push_back(Idx+1);
342193323Sed  }
343218893Sdim
344193323Sed  // Figure out how many bits we used for the string index.
345198090Srdivacky  unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2);
346218893Sdim
347193323Sed  // To reduce code size, we compactify common instructions into a few bits
348193323Sed  // in the opcode-indexed table.
349243830Sdim  unsigned BitsLeft = 64-AsmStrBits;
350193323Sed
351193323Sed  std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
352218893Sdim
353193323Sed  while (1) {
354193323Sed    std::vector<std::string> UniqueOperandCommands;
355193323Sed    std::vector<unsigned> InstIdxs;
356193323Sed    std::vector<unsigned> NumInstOpsHandled;
357193323Sed    FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
358193323Sed                              NumInstOpsHandled);
359218893Sdim
360193323Sed    // If we ran out of operands to print, we're done.
361193323Sed    if (UniqueOperandCommands.empty()) break;
362218893Sdim
363193323Sed    // Compute the number of bits we need to represent these cases, this is
364193323Sed    // ceil(log2(numentries)).
365193323Sed    unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
366218893Sdim
367193323Sed    // If we don't have enough bits for this operand, don't include it.
368193323Sed    if (NumBits > BitsLeft) {
369198090Srdivacky      DEBUG(errs() << "Not enough bits to densely encode " << NumBits
370198090Srdivacky                   << " more bits\n");
371193323Sed      break;
372193323Sed    }
373218893Sdim
374193323Sed    // Otherwise, we can include this in the initial lookup table.  Add it in.
375243830Sdim    for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
376243830Sdim      if (InstIdxs[i] != ~0U) {
377243830Sdim        OpcodeInfo[i] |= (uint64_t)InstIdxs[i] << (64-BitsLeft);
378243830Sdim      }
379193323Sed    BitsLeft -= NumBits;
380218893Sdim
381193323Sed    // Remove the info about this operand.
382193323Sed    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
383193323Sed      if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
384193323Sed        if (!Inst->Operands.empty()) {
385193323Sed          unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
386193323Sed          assert(NumOps <= Inst->Operands.size() &&
387193323Sed                 "Can't remove this many ops!");
388193323Sed          Inst->Operands.erase(Inst->Operands.begin(),
389193323Sed                               Inst->Operands.begin()+NumOps);
390193323Sed        }
391193323Sed    }
392218893Sdim
393193323Sed    // Remember the handlers for this set of operands.
394193323Sed    TableDrivenOperandPrinters.push_back(UniqueOperandCommands);
395193323Sed  }
396218893Sdim
397218893Sdim
398243830Sdim  // We always emit at least one 32-bit table. A second table is emitted if
399243830Sdim  // more bits are needed.
400243830Sdim  O<<"  static const uint32_t OpInfo[] = {\n";
401193323Sed  for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
402243830Sdim    O << "    " << (OpcodeInfo[i] & 0xffffffff) << "U,\t// "
403193323Sed      << NumberedInstructions[i]->TheDef->getName() << "\n";
404193323Sed  }
405193323Sed  // Add a dummy entry so the array init doesn't end with a comma.
406193323Sed  O << "    0U\n";
407193323Sed  O << "  };\n\n";
408218893Sdim
409243830Sdim  if (BitsLeft < 32) {
410243830Sdim    // Add a second OpInfo table only when it is necessary.
411243830Sdim    // Adjust the type of the second table based on the number of bits needed.
412243830Sdim    O << "  static const uint"
413243830Sdim      << ((BitsLeft < 16) ? "32" : (BitsLeft < 24) ? "16" : "8")
414243830Sdim      << "_t OpInfo2[] = {\n";
415243830Sdim    for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
416243830Sdim      O << "    " << (OpcodeInfo[i] >> 32) << "U,\t// "
417243830Sdim        << NumberedInstructions[i]->TheDef->getName() << "\n";
418243830Sdim    }
419243830Sdim    // Add a dummy entry so the array init doesn't end with a comma.
420243830Sdim    O << "    0U\n";
421243830Sdim    O << "  };\n\n";
422243830Sdim  }
423243830Sdim
424193323Sed  // Emit the string itself.
425234353Sdim  O << "  const char AsmStrs[] = {\n";
426234353Sdim  StringTable.emit(O, printChar);
427234353Sdim  O << "  };\n\n";
428193323Sed
429193323Sed  O << "  O << \"\\t\";\n\n";
430193323Sed
431243830Sdim  O << "  // Emit the opcode for the instruction.\n";
432243830Sdim  if (BitsLeft < 32) {
433243830Sdim    // If we have two tables then we need to perform two lookups and combine
434243830Sdim    // the results into a single 64-bit value.
435243830Sdim    O << "  uint64_t Bits1 = OpInfo[MI->getOpcode()];\n"
436243830Sdim      << "  uint64_t Bits2 = OpInfo2[MI->getOpcode()];\n"
437243830Sdim      << "  uint64_t Bits = (Bits2 << 32) | Bits1;\n";
438243830Sdim  } else {
439243830Sdim    // If only one table is used we just need to perform a single lookup.
440243830Sdim    O << "  uint32_t Bits = OpInfo[MI->getOpcode()];\n";
441243830Sdim  }
442243830Sdim  O << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
443198090Srdivacky    << "  O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
444193323Sed
445193323Sed  // Output the table driven operand information.
446243830Sdim  BitsLeft = 64-AsmStrBits;
447193323Sed  for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
448193323Sed    std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
449193323Sed
450193323Sed    // Compute the number of bits we need to represent these cases, this is
451193323Sed    // ceil(log2(numentries)).
452193323Sed    unsigned NumBits = Log2_32_Ceil(Commands.size());
453193323Sed    assert(NumBits <= BitsLeft && "consistency error");
454218893Sdim
455193323Sed    // Emit code to extract this field from Bits.
456193323Sed    O << "\n  // Fragment " << i << " encoded into " << NumBits
457193323Sed      << " bits for " << Commands.size() << " unique commands.\n";
458218893Sdim
459193323Sed    if (Commands.size() == 2) {
460193323Sed      // Emit two possibilitys with if/else.
461243830Sdim      O << "  if ((Bits >> "
462243830Sdim        << (64-BitsLeft) << ") & "
463193323Sed        << ((1 << NumBits)-1) << ") {\n"
464193323Sed        << Commands[1]
465193323Sed        << "  } else {\n"
466193323Sed        << Commands[0]
467193323Sed        << "  }\n\n";
468218893Sdim    } else if (Commands.size() == 1) {
469218893Sdim      // Emit a single possibility.
470218893Sdim      O << Commands[0] << "\n\n";
471193323Sed    } else {
472243830Sdim      O << "  switch ((Bits >> "
473243830Sdim        << (64-BitsLeft) << ") & "
474193323Sed        << ((1 << NumBits)-1) << ") {\n"
475193323Sed        << "  default:   // unreachable.\n";
476218893Sdim
477193323Sed      // Print out all the cases.
478193323Sed      for (unsigned i = 0, e = Commands.size(); i != e; ++i) {
479193323Sed        O << "  case " << i << ":\n";
480193323Sed        O << Commands[i];
481193323Sed        O << "    break;\n";
482193323Sed      }
483193323Sed      O << "  }\n\n";
484193323Sed    }
485243830Sdim    BitsLeft -= NumBits;
486193323Sed  }
487218893Sdim
488193323Sed  // Okay, delete instructions with no operand info left.
489193323Sed  for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
490193323Sed    // Entire instruction has been emitted?
491193323Sed    AsmWriterInst &Inst = Instructions[i];
492193323Sed    if (Inst.Operands.empty()) {
493193323Sed      Instructions.erase(Instructions.begin()+i);
494193323Sed      --i; --e;
495193323Sed    }
496193323Sed  }
497193323Sed
498218893Sdim
499193323Sed  // Because this is a vector, we want to emit from the end.  Reverse all of the
500193323Sed  // elements in the vector.
501193323Sed  std::reverse(Instructions.begin(), Instructions.end());
502218893Sdim
503218893Sdim
504198090Srdivacky  // Now that we've emitted all of the operand info that fit into 32 bits, emit
505198090Srdivacky  // information for those instructions that are left.  This is a less dense
506198090Srdivacky  // encoding, but we expect the main 32-bit table to handle the majority of
507198090Srdivacky  // instructions.
508193323Sed  if (!Instructions.empty()) {
509193323Sed    // Find the opcode # of inline asm.
510193323Sed    O << "  switch (MI->getOpcode()) {\n";
511193323Sed    while (!Instructions.empty())
512193323Sed      EmitInstructions(Instructions, O);
513193323Sed
514193323Sed    O << "  }\n";
515198090Srdivacky    O << "  return;\n";
516193323Sed  }
517198090Srdivacky
518193323Sed  O << "}\n";
519193323Sed}
520198090Srdivacky
521224145Sdimstatic void
522224145SdimemitRegisterNameString(raw_ostream &O, StringRef AltName,
523234353Sdim                       const std::vector<CodeGenRegister*> &Registers) {
524234353Sdim  SequenceToOffsetTable<std::string> StringTable;
525234353Sdim  SmallVector<std::string, 4> AsmNames(Registers.size());
526224145Sdim  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
527224145Sdim    const CodeGenRegister &Reg = *Registers[i];
528234353Sdim    std::string &AsmName = AsmNames[i];
529198090Srdivacky
530224145Sdim    // "NoRegAltName" is special. We don't need to do a lookup for that,
531224145Sdim    // as it's just a reference to the default register name.
532224145Sdim    if (AltName == "" || AltName == "NoRegAltName") {
533224145Sdim      AsmName = Reg.TheDef->getValueAsString("AsmName");
534224145Sdim      if (AsmName.empty())
535224145Sdim        AsmName = Reg.getName();
536224145Sdim    } else {
537224145Sdim      // Make sure the register has an alternate name for this index.
538224145Sdim      std::vector<Record*> AltNameList =
539224145Sdim        Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices");
540224145Sdim      unsigned Idx = 0, e;
541224145Sdim      for (e = AltNameList.size();
542224145Sdim           Idx < e && (AltNameList[Idx]->getName() != AltName);
543224145Sdim           ++Idx)
544224145Sdim        ;
545224145Sdim      // If the register has an alternate name for this index, use it.
546224145Sdim      // Otherwise, leave it empty as an error flag.
547224145Sdim      if (Idx < e) {
548224145Sdim        std::vector<std::string> AltNames =
549224145Sdim          Reg.TheDef->getValueAsListOfStrings("AltNames");
550224145Sdim        if (AltNames.size() <= Idx)
551243830Sdim          PrintFatalError(Reg.TheDef->getLoc(),
552243830Sdim            (Twine("Register definition missing alt name for '") +
553243830Sdim             AltName + "'.").str());
554224145Sdim        AsmName = AltNames[Idx];
555224145Sdim      }
556224145Sdim    }
557234353Sdim    StringTable.add(AsmName);
558234353Sdim  }
559224145Sdim
560234353Sdim  StringTable.layout();
561234353Sdim  O << "  static const char AsmStrs" << AltName << "[] = {\n";
562234353Sdim  StringTable.emit(O, printChar);
563234353Sdim  O << "  };\n\n";
564224145Sdim
565243830Sdim  O << "  static const uint32_t RegAsmOffset" << AltName << "[] = {";
566234353Sdim  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
567234353Sdim    if ((i % 14) == 0)
568234353Sdim      O << "\n    ";
569234353Sdim    O << StringTable.get(AsmNames[i]) << ", ";
570224145Sdim  }
571234353Sdim  O << "\n  };\n"
572224145Sdim    << "\n";
573224145Sdim}
574224145Sdim
575198090Srdivackyvoid AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
576198090Srdivacky  Record *AsmWriter = Target.getAsmWriter();
577198090Srdivacky  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
578224145Sdim  const std::vector<CodeGenRegister*> &Registers =
579224145Sdim    Target.getRegBank().getRegisters();
580224145Sdim  std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices();
581224145Sdim  bool hasAltNames = AltNameIndices.size() > 1;
582218893Sdim
583198090Srdivacky  O <<
584198090Srdivacky  "\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
585198090Srdivacky  "/// from the register set description.  This returns the assembler name\n"
586198090Srdivacky  "/// for the specified register.\n"
587224145Sdim  "const char *" << Target.getName() << ClassName << "::";
588224145Sdim  if (hasAltNames)
589224145Sdim    O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
590224145Sdim  else
591224145Sdim    O << "getRegisterName(unsigned RegNo) {\n";
592224145Sdim  O << "  assert(RegNo && RegNo < " << (Registers.size()+1)
593224145Sdim    << " && \"Invalid register number!\");\n"
594224145Sdim    << "\n";
595198090Srdivacky
596224145Sdim  if (hasAltNames) {
597224145Sdim    for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i)
598224145Sdim      emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers);
599224145Sdim  } else
600224145Sdim    emitRegisterNameString(O, "", Registers);
601218893Sdim
602224145Sdim  if (hasAltNames) {
603243830Sdim    O << "  const uint32_t *RegAsmOffset;\n"
604224145Sdim      << "  const char *AsmStrs;\n"
605224145Sdim      << "  switch(AltIdx) {\n"
606234353Sdim      << "  default: llvm_unreachable(\"Invalid register alt name index!\");\n";
607224145Sdim    for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
608224145Sdim      StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace");
609224145Sdim      StringRef AltName(AltNameIndices[i]->getName());
610224145Sdim      O << "  case " << Namespace << "::" << AltName
611224145Sdim        << ":\n"
612224145Sdim        << "    AsmStrs = AsmStrs" << AltName  << ";\n"
613224145Sdim        << "    RegAsmOffset = RegAsmOffset" << AltName << ";\n"
614224145Sdim        << "    break;\n";
615224145Sdim    }
616224145Sdim    O << "}\n";
617198090Srdivacky  }
618218893Sdim
619224145Sdim  O << "  assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
620224145Sdim    << "          \"Invalid alt name index for register!\");\n"
621224145Sdim    << "  return AsmStrs+RegAsmOffset[RegNo-1];\n"
622198090Srdivacky    << "}\n";
623198090Srdivacky}
624198090Srdivacky
625221345Sdimnamespace {
626221345Sdim// IAPrinter - Holds information about an InstAlias. Two InstAliases match if
627221345Sdim// they both have the same conditionals. In which case, we cannot print out the
628221345Sdim// alias for that pattern.
629221345Sdimclass IAPrinter {
630221345Sdim  std::vector<std::string> Conds;
631221345Sdim  std::map<StringRef, unsigned> OpMap;
632221345Sdim  std::string Result;
633221345Sdim  std::string AsmString;
634234982Sdim  SmallVector<Record*, 4> ReqFeatures;
635221345Sdimpublic:
636224145Sdim  IAPrinter(std::string R, std::string AS)
637224145Sdim    : Result(R), AsmString(AS) {}
638221345Sdim
639221345Sdim  void addCond(const std::string &C) { Conds.push_back(C); }
640221345Sdim
641263508Sdim  void addOperand(StringRef Op, unsigned Idx) {
642263508Sdim    assert(Idx < 0xFF && "Index too large!");
643263508Sdim    OpMap[Op] = Idx;
644263508Sdim  }
645221345Sdim  unsigned getOpIndex(StringRef Op) { return OpMap[Op]; }
646221345Sdim  bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); }
647221345Sdim
648224145Sdim  void print(raw_ostream &O) {
649221345Sdim    if (Conds.empty() && ReqFeatures.empty()) {
650221345Sdim      O.indent(6) << "return true;\n";
651224145Sdim      return;
652221345Sdim    }
653221345Sdim
654221345Sdim    O << "if (";
655221345Sdim
656221345Sdim    for (std::vector<std::string>::iterator
657221345Sdim           I = Conds.begin(), E = Conds.end(); I != E; ++I) {
658221345Sdim      if (I != Conds.begin()) {
659221345Sdim        O << " &&\n";
660221345Sdim        O.indent(8);
661221345Sdim      }
662221345Sdim
663221345Sdim      O << *I;
664221345Sdim    }
665221345Sdim
666221345Sdim    O << ") {\n";
667221345Sdim    O.indent(6) << "// " << Result << "\n";
668221345Sdim
669263508Sdim    // Directly mangle mapped operands into the string. Each operand is
670263508Sdim    // identified by a '$' sign followed by a byte identifying the number of the
671263508Sdim    // operand. We add one to the index to avoid zero bytes.
672263508Sdim    std::pair<StringRef, StringRef> ASM = StringRef(AsmString).split(' ');
673263508Sdim    SmallString<128> OutString = ASM.first;
674263508Sdim    if (!ASM.second.empty()) {
675263508Sdim      raw_svector_ostream OS(OutString);
676263508Sdim      OS << ' ';
677263508Sdim      for (StringRef::iterator I = ASM.second.begin(), E = ASM.second.end();
678263508Sdim           I != E;) {
679263508Sdim        OS << *I;
680263508Sdim        if (*I == '$') {
681263508Sdim          StringRef::iterator Start = ++I;
682263508Sdim          while (I != E &&
683263508Sdim                 ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') ||
684263508Sdim                  (*I >= '0' && *I <= '9') || *I == '_'))
685263508Sdim            ++I;
686263508Sdim          StringRef Name(Start, I - Start);
687263508Sdim          assert(isOpMapped(Name) && "Unmapped operand!");
688263508Sdim          OS << format("\\x%02X", (unsigned char)getOpIndex(Name) + 1);
689263508Sdim        } else {
690263508Sdim          ++I;
691263508Sdim        }
692263508Sdim      }
693263508Sdim    }
694221345Sdim
695263508Sdim    // Emit the string.
696263508Sdim    O.indent(6) << "AsmString = \"" << OutString.str() << "\";\n";
697263508Sdim
698221345Sdim    O.indent(6) << "break;\n";
699221345Sdim    O.indent(4) << '}';
700221345Sdim  }
701221345Sdim
702221345Sdim  bool operator==(const IAPrinter &RHS) {
703221345Sdim    if (Conds.size() != RHS.Conds.size())
704221345Sdim      return false;
705221345Sdim
706221345Sdim    unsigned Idx = 0;
707221345Sdim    for (std::vector<std::string>::iterator
708221345Sdim           I = Conds.begin(), E = Conds.end(); I != E; ++I)
709221345Sdim      if (*I != RHS.Conds[Idx++])
710221345Sdim        return false;
711221345Sdim
712221345Sdim    return true;
713221345Sdim  }
714221345Sdim
715221345Sdim  bool operator()(const IAPrinter &RHS) {
716221345Sdim    if (Conds.size() < RHS.Conds.size())
717221345Sdim      return true;
718221345Sdim
719221345Sdim    unsigned Idx = 0;
720221345Sdim    for (std::vector<std::string>::iterator
721221345Sdim           I = Conds.begin(), E = Conds.end(); I != E; ++I)
722221345Sdim      if (*I != RHS.Conds[Idx++])
723221345Sdim        return *I < RHS.Conds[Idx++];
724221345Sdim
725221345Sdim    return false;
726221345Sdim  }
727221345Sdim};
728221345Sdim
729221345Sdim} // end anonymous namespace
730221345Sdim
731224145Sdimstatic unsigned CountNumOperands(StringRef AsmString) {
732224145Sdim  unsigned NumOps = 0;
733224145Sdim  std::pair<StringRef, StringRef> ASM = AsmString.split(' ');
734224145Sdim
735224145Sdim  while (!ASM.second.empty()) {
736224145Sdim    ++NumOps;
737224145Sdim    ASM = ASM.second.split(' ');
738224145Sdim  }
739224145Sdim
740224145Sdim  return NumOps;
741224145Sdim}
742224145Sdim
743224145Sdimstatic unsigned CountResultNumOperands(StringRef AsmString) {
744224145Sdim  unsigned NumOps = 0;
745224145Sdim  std::pair<StringRef, StringRef> ASM = AsmString.split('\t');
746224145Sdim
747224145Sdim  if (!ASM.second.empty()) {
748224145Sdim    size_t I = ASM.second.find('{');
749224145Sdim    StringRef Str = ASM.second;
750224145Sdim    if (I != StringRef::npos)
751224145Sdim      Str = ASM.second.substr(I, ASM.second.find('|', I));
752224145Sdim
753224145Sdim    ASM = Str.split(' ');
754224145Sdim
755224145Sdim    do {
756224145Sdim      ++NumOps;
757224145Sdim      ASM = ASM.second.split(' ');
758224145Sdim    } while (!ASM.second.empty());
759224145Sdim  }
760224145Sdim
761224145Sdim  return NumOps;
762224145Sdim}
763224145Sdim
764221345Sdimvoid AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
765221345Sdim  Record *AsmWriter = Target.getAsmWriter();
766221345Sdim
767224145Sdim  if (!AsmWriter->getValueAsBit("isMCAsmWriter"))
768224145Sdim    return;
769224145Sdim
770221345Sdim  O << "\n#ifdef PRINT_ALIAS_INSTR\n";
771221345Sdim  O << "#undef PRINT_ALIAS_INSTR\n\n";
772221345Sdim
773219077Sdim  // Emit the method that prints the alias instruction.
774219077Sdim  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
775219077Sdim
776219077Sdim  std::vector<Record*> AllInstAliases =
777219077Sdim    Records.getAllDerivedDefinitions("InstAlias");
778219077Sdim
779219077Sdim  // Create a map from the qualified name to a list of potential matches.
780219077Sdim  std::map<std::string, std::vector<CodeGenInstAlias*> > AliasMap;
781219077Sdim  for (std::vector<Record*>::iterator
782219077Sdim         I = AllInstAliases.begin(), E = AllInstAliases.end(); I != E; ++I) {
783219077Sdim    CodeGenInstAlias *Alias = new CodeGenInstAlias(*I, Target);
784219077Sdim    const Record *R = *I;
785221345Sdim    if (!R->getValueAsBit("EmitAlias"))
786221345Sdim      continue; // We were told not to emit the alias, but to emit the aliasee.
787219077Sdim    const DagInit *DI = R->getValueAsDag("ResultInst");
788243830Sdim    const DefInit *Op = cast<DefInit>(DI->getOperator());
789219077Sdim    AliasMap[getQualifiedName(Op->getDef())].push_back(Alias);
790219077Sdim  }
791219077Sdim
792221345Sdim  // A map of which conditions need to be met for each instruction operand
793221345Sdim  // before it can be matched to the mnemonic.
794221345Sdim  std::map<std::string, std::vector<IAPrinter*> > IAPrinterMap;
795219077Sdim
796219077Sdim  for (std::map<std::string, std::vector<CodeGenInstAlias*> >::iterator
797219077Sdim         I = AliasMap.begin(), E = AliasMap.end(); I != E; ++I) {
798219077Sdim    std::vector<CodeGenInstAlias*> &Aliases = I->second;
799219077Sdim
800219077Sdim    for (std::vector<CodeGenInstAlias*>::iterator
801219077Sdim           II = Aliases.begin(), IE = Aliases.end(); II != IE; ++II) {
802219077Sdim      const CodeGenInstAlias *CGA = *II;
803224145Sdim      unsigned LastOpNo = CGA->ResultInstOperandIndex.size();
804224145Sdim      unsigned NumResultOps =
805224145Sdim        CountResultNumOperands(CGA->ResultInst->AsmString);
806221345Sdim
807224145Sdim      // Don't emit the alias if it has more operands than what it's aliasing.
808224145Sdim      if (NumResultOps < CountNumOperands(CGA->AsmString))
809224145Sdim        continue;
810221345Sdim
811224145Sdim      IAPrinter *IAP = new IAPrinter(CGA->Result->getAsString(),
812224145Sdim                                     CGA->AsmString);
813219077Sdim
814219077Sdim      std::string Cond;
815221345Sdim      Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo);
816221345Sdim      IAP->addCond(Cond);
817219077Sdim
818219077Sdim      bool CantHandle = false;
819219077Sdim
820219077Sdim      for (unsigned i = 0, e = LastOpNo; i != e; ++i) {
821219077Sdim        const CodeGenInstAlias::ResultOperand &RO = CGA->ResultOperands[i];
822219077Sdim
823219077Sdim        switch (RO.Kind) {
824219077Sdim        case CodeGenInstAlias::ResultOperand::K_Record: {
825219077Sdim          const Record *Rec = RO.getRecord();
826219077Sdim          StringRef ROName = RO.getName();
827219077Sdim
828224145Sdim
829224145Sdim          if (Rec->isSubClassOf("RegisterOperand"))
830224145Sdim            Rec = Rec->getValueAsDef("RegClass");
831219077Sdim          if (Rec->isSubClassOf("RegisterClass")) {
832221345Sdim            Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
833221345Sdim            IAP->addCond(Cond);
834221345Sdim
835221345Sdim            if (!IAP->isOpMapped(ROName)) {
836221345Sdim              IAP->addOperand(ROName, i);
837249423Sdim              Record *R = CGA->ResultOperands[i].getRecord();
838249423Sdim              if (R->isSubClassOf("RegisterOperand"))
839249423Sdim                R = R->getValueAsDef("RegClass");
840234353Sdim              Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" +
841249423Sdim                R->getName() + "RegClassID)"
842234353Sdim                ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())";
843221345Sdim              IAP->addCond(Cond);
844219077Sdim            } else {
845221345Sdim              Cond = std::string("MI->getOperand(") +
846221345Sdim                llvm::utostr(i) + ").getReg() == MI->getOperand(" +
847221345Sdim                llvm::utostr(IAP->getOpIndex(ROName)) + ").getReg()";
848221345Sdim              IAP->addCond(Cond);
849219077Sdim            }
850219077Sdim          } else {
851219077Sdim            assert(Rec->isSubClassOf("Operand") && "Unexpected operand!");
852224145Sdim            // FIXME: We may need to handle these situations.
853221345Sdim            delete IAP;
854221345Sdim            IAP = 0;
855219077Sdim            CantHandle = true;
856219077Sdim            break;
857219077Sdim          }
858219077Sdim
859219077Sdim          break;
860219077Sdim        }
861249423Sdim        case CodeGenInstAlias::ResultOperand::K_Imm: {
862249423Sdim          std::string Op = "MI->getOperand(" + llvm::utostr(i) + ")";
863249423Sdim
864249423Sdim          // Just because the alias has an immediate result, doesn't mean the
865249423Sdim          // MCInst will. An MCExpr could be present, for example.
866249423Sdim          IAP->addCond(Op + ".isImm()");
867249423Sdim
868249423Sdim          Cond = Op + ".getImm() == "
869249423Sdim            + llvm::utostr(CGA->ResultOperands[i].getImm());
870221345Sdim          IAP->addCond(Cond);
871219077Sdim          break;
872249423Sdim        }
873219077Sdim        case CodeGenInstAlias::ResultOperand::K_Reg:
874234353Sdim          // If this is zero_reg, something's playing tricks we're not
875234353Sdim          // equipped to handle.
876234353Sdim          if (!CGA->ResultOperands[i].getRegister()) {
877234353Sdim            CantHandle = true;
878234353Sdim            break;
879234353Sdim          }
880234353Sdim
881221345Sdim          Cond = std::string("MI->getOperand(") +
882221345Sdim            llvm::utostr(i) + ").getReg() == " + Target.getName() +
883221345Sdim            "::" + CGA->ResultOperands[i].getRegister()->getName();
884221345Sdim          IAP->addCond(Cond);
885219077Sdim          break;
886219077Sdim        }
887219077Sdim
888221345Sdim        if (!IAP) break;
889219077Sdim      }
890219077Sdim
891219077Sdim      if (CantHandle) continue;
892221345Sdim      IAPrinterMap[I->first].push_back(IAP);
893221345Sdim    }
894221345Sdim  }
895219077Sdim
896223017Sdim  std::string Header;
897223017Sdim  raw_string_ostream HeaderO(Header);
898219077Sdim
899223017Sdim  HeaderO << "bool " << Target.getName() << ClassName
900224145Sdim          << "::printAliasInstr(const MCInst"
901223017Sdim          << " *MI, raw_ostream &OS) {\n";
902223017Sdim
903221345Sdim  std::string Cases;
904221345Sdim  raw_string_ostream CasesO(Cases);
905219077Sdim
906221345Sdim  for (std::map<std::string, std::vector<IAPrinter*> >::iterator
907221345Sdim         I = IAPrinterMap.begin(), E = IAPrinterMap.end(); I != E; ++I) {
908221345Sdim    std::vector<IAPrinter*> &IAPs = I->second;
909221345Sdim    std::vector<IAPrinter*> UniqueIAPs;
910219077Sdim
911221345Sdim    for (std::vector<IAPrinter*>::iterator
912221345Sdim           II = IAPs.begin(), IE = IAPs.end(); II != IE; ++II) {
913221345Sdim      IAPrinter *LHS = *II;
914221345Sdim      bool IsDup = false;
915221345Sdim      for (std::vector<IAPrinter*>::iterator
916221345Sdim             III = IAPs.begin(), IIE = IAPs.end(); III != IIE; ++III) {
917221345Sdim        IAPrinter *RHS = *III;
918221345Sdim        if (LHS != RHS && *LHS == *RHS) {
919221345Sdim          IsDup = true;
920221345Sdim          break;
921221345Sdim        }
922221345Sdim      }
923221345Sdim
924221345Sdim      if (!IsDup) UniqueIAPs.push_back(LHS);
925219077Sdim    }
926219077Sdim
927221345Sdim    if (UniqueIAPs.empty()) continue;
928219077Sdim
929221345Sdim    CasesO.indent(2) << "case " << I->first << ":\n";
930221345Sdim
931221345Sdim    for (std::vector<IAPrinter*>::iterator
932221345Sdim           II = UniqueIAPs.begin(), IE = UniqueIAPs.end(); II != IE; ++II) {
933221345Sdim      IAPrinter *IAP = *II;
934221345Sdim      CasesO.indent(4);
935224145Sdim      IAP->print(CasesO);
936221345Sdim      CasesO << '\n';
937219077Sdim    }
938219077Sdim
939221345Sdim    CasesO.indent(4) << "return false;\n";
940221345Sdim  }
941219077Sdim
942224145Sdim  if (CasesO.str().empty()) {
943223017Sdim    O << HeaderO.str();
944221345Sdim    O << "  return false;\n";
945221345Sdim    O << "}\n\n";
946221345Sdim    O << "#endif // PRINT_ALIAS_INSTR\n";
947221345Sdim    return;
948219077Sdim  }
949219077Sdim
950223017Sdim  O << HeaderO.str();
951263508Sdim  O.indent(2) << "const char *AsmString;\n";
952221345Sdim  O.indent(2) << "switch (MI->getOpcode()) {\n";
953221345Sdim  O.indent(2) << "default: return false;\n";
954221345Sdim  O << CasesO.str();
955221345Sdim  O.indent(2) << "}\n\n";
956219077Sdim
957219077Sdim  // Code that prints the alias, replacing the operands with the ones from the
958219077Sdim  // MCInst.
959263508Sdim  O << "  unsigned I = 0;\n";
960263508Sdim  O << "  while (AsmString[I] != ' ' && AsmString[I] != '\\0')\n";
961263508Sdim  O << "    ++I;\n";
962263508Sdim  O << "  OS << '\\t' << StringRef(AsmString, I);\n";
963219077Sdim
964263508Sdim  O << "  if (AsmString[I] != '\\0') {\n";
965219077Sdim  O << "    OS << '\\t';\n";
966263508Sdim  O << "    do {\n";
967263508Sdim  O << "      if (AsmString[I] == '$') {\n";
968263508Sdim  O << "        ++I;\n";
969263508Sdim  O << "        printOperand(MI, unsigned(AsmString[I++]) - 1, OS);\n";
970219077Sdim  O << "      } else {\n";
971263508Sdim  O << "        OS << AsmString[I++];\n";
972219077Sdim  O << "      }\n";
973263508Sdim  O << "    } while (AsmString[I] != '\\0');\n";
974219077Sdim  O << "  }\n\n";
975234982Sdim
976221345Sdim  O << "  return true;\n";
977219077Sdim  O << "}\n\n";
978219077Sdim
979219077Sdim  O << "#endif // PRINT_ALIAS_INSTR\n";
980219077Sdim}
981219077Sdim
982263508SdimAsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
983263508Sdim  Record *AsmWriter = Target.getAsmWriter();
984263508Sdim  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
985263508Sdim                                    E = Target.inst_end();
986263508Sdim       I != E; ++I)
987263508Sdim    if (!(*I)->AsmString.empty() && (*I)->TheDef->getName() != "PHI")
988263508Sdim      Instructions.push_back(
989263508Sdim          AsmWriterInst(**I, AsmWriter->getValueAsInt("Variant"),
990263508Sdim                        AsmWriter->getValueAsInt("FirstOperandColumn"),
991263508Sdim                        AsmWriter->getValueAsInt("OperandSpacing")));
992263508Sdim
993263508Sdim  // Get the instruction numbering.
994263508Sdim  NumberedInstructions = Target.getInstructionsByEnumValue();
995263508Sdim
996263508Sdim  // Compute the CodeGenInstruction -> AsmWriterInst mapping.  Note that not
997263508Sdim  // all machine instructions are necessarily being printed, so there may be
998263508Sdim  // target instructions not in this map.
999263508Sdim  for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
1000263508Sdim    CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
1001263508Sdim}
1002263508Sdim
1003198090Srdivackyvoid AsmWriterEmitter::run(raw_ostream &O) {
1004198090Srdivacky  EmitPrintInstruction(O);
1005198090Srdivacky  EmitGetRegisterName(O);
1006219077Sdim  EmitPrintAliasInstruction(O);
1007198090Srdivacky}
1008198090Srdivacky
1009239462Sdim
1010239462Sdimnamespace llvm {
1011239462Sdim
1012239462Sdimvoid EmitAsmWriter(RecordKeeper &RK, raw_ostream &OS) {
1013239462Sdim  emitSourceFileHeader("Assembly Writer Source Fragment", OS);
1014239462Sdim  AsmWriterEmitter(RK).run(OS);
1015239462Sdim}
1016239462Sdim
1017239462Sdim} // End llvm namespace
1018