factor string table generation out to its own class. This changes
[oota-llvm.git] / utils / TableGen / AsmWriterEmitter.cpp
1 //===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
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 // This tablegen backend is emits an assembly printer for the current target.
11 // Note that this is currently fairly skeletal, but will grow over time.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AsmWriterEmitter.h"
16 #include "CodeGenTarget.h"
17 #include "Record.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringMap.h"
20 #include "llvm/Support/Debug.h"
21 #include "llvm/Support/MathExtras.h"
22 #include <algorithm>
23 using namespace llvm;
24
25 /// StringToOffsetTable - This class uniques a bunch of nul-terminated strings
26 /// and keeps track of their offset in a massive contiguous string allocation.
27 /// It can then output this string blob and use indexes into the string to
28 /// reference each piece.
29 class StringToOffsetTable {
30   StringMap<unsigned> StringOffset;
31   std::string AggregateString;
32 public:
33
34   unsigned GetOrAddStringOffset(StringRef Str) {
35     unsigned &Entry = StringOffset[Str];
36     if (Entry == 0) {
37       // Add the string to the aggregate if this is the first time found.
38       Entry = AggregateString.size();
39       AggregateString.append(Str.begin(), Str.end());
40       AggregateString += '\0';
41     }
42     
43     return Entry;
44   }
45   
46   void EmitString(raw_ostream &O) {
47     O << "    \"";
48     unsigned CharsPrinted = 0;
49     EscapeString(AggregateString);
50     for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
51       if (CharsPrinted > 70) {
52         O << "\"\n    \"";
53         CharsPrinted = 0;
54       }
55       O << AggregateString[i];
56       ++CharsPrinted;
57       
58       // Print escape sequences all together.
59       if (AggregateString[i] != '\\')
60         continue;
61       
62       assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
63       if (isdigit(AggregateString[i+1])) {
64         assert(isdigit(AggregateString[i+2]) && 
65                isdigit(AggregateString[i+3]) &&
66                "Expected 3 digit octal escape!");
67         O << AggregateString[++i];
68         O << AggregateString[++i];
69         O << AggregateString[++i];
70         CharsPrinted += 3;
71       } else {
72         O << AggregateString[++i];
73         ++CharsPrinted;
74       }
75     }
76     O << "\"";
77   }
78 };
79
80
81 static bool isIdentChar(char C) {
82   return (C >= 'a' && C <= 'z') ||
83          (C >= 'A' && C <= 'Z') ||
84          (C >= '0' && C <= '9') ||
85          C == '_';
86 }
87
88 // This should be an anon namespace, this works around a GCC warning.
89 namespace llvm {  
90   struct AsmWriterOperand {
91     enum OpType {
92       // Output this text surrounded by quotes to the asm.
93       isLiteralTextOperand, 
94       // This is the name of a routine to call to print the operand.
95       isMachineInstrOperand,
96       // Output this text verbatim to the asm writer.  It is code that
97       // will output some text to the asm.
98       isLiteralStatementOperand
99     } OperandType;
100
101     /// Str - For isLiteralTextOperand, this IS the literal text.  For
102     /// isMachineInstrOperand, this is the PrinterMethodName for the operand..
103     /// For isLiteralStatementOperand, this is the code to insert verbatim 
104     /// into the asm writer.
105     std::string Str;
106
107     /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
108     /// machine instruction.
109     unsigned MIOpNo;
110     
111     /// MiModifier - For isMachineInstrOperand, this is the modifier string for
112     /// an operand, specified with syntax like ${opname:modifier}.
113     std::string MiModifier;
114
115     // To make VS STL happy
116     AsmWriterOperand(OpType op = isLiteralTextOperand):OperandType(op) {}
117
118     AsmWriterOperand(const std::string &LitStr,
119                      OpType op = isLiteralTextOperand)
120       : OperandType(op), Str(LitStr) {}
121
122     AsmWriterOperand(const std::string &Printer, unsigned OpNo, 
123                      const std::string &Modifier,
124                      OpType op = isMachineInstrOperand) 
125       : OperandType(op), Str(Printer), MIOpNo(OpNo),
126       MiModifier(Modifier) {}
127
128     bool operator!=(const AsmWriterOperand &Other) const {
129       if (OperandType != Other.OperandType || Str != Other.Str) return true;
130       if (OperandType == isMachineInstrOperand)
131         return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
132       return false;
133     }
134     bool operator==(const AsmWriterOperand &Other) const {
135       return !operator!=(Other);
136     }
137     
138     /// getCode - Return the code that prints this operand.
139     std::string getCode() const;
140   };
141 }
142
143 namespace llvm {
144   class AsmWriterInst {
145   public:
146     std::vector<AsmWriterOperand> Operands;
147     const CodeGenInstruction *CGI;
148
149     AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter);
150
151     /// MatchesAllButOneOp - If this instruction is exactly identical to the
152     /// specified instruction except for one differing operand, return the
153     /// differing operand number.  Otherwise return ~0.
154     unsigned MatchesAllButOneOp(const AsmWriterInst &Other) const;
155
156   private:
157     void AddLiteralString(const std::string &Str) {
158       // If the last operand was already a literal text string, append this to
159       // it, otherwise add a new operand.
160       if (!Operands.empty() &&
161           Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
162         Operands.back().Str.append(Str);
163       else
164         Operands.push_back(AsmWriterOperand(Str));
165     }
166   };
167 }
168
169
170 std::string AsmWriterOperand::getCode() const {
171   if (OperandType == isLiteralTextOperand) {
172     if (Str.size() == 1)
173       return "O << '" + Str + "'; ";
174     return "O << \"" + Str + "\"; ";
175   }
176
177   if (OperandType == isLiteralStatementOperand)
178     return Str;
179
180   std::string Result = Str + "(MI";
181   if (MIOpNo != ~0U)
182     Result += ", " + utostr(MIOpNo);
183   if (!MiModifier.empty())
184     Result += ", \"" + MiModifier + '"';
185   return Result + "); ";
186 }
187
188
189 /// ParseAsmString - Parse the specified Instruction's AsmString into this
190 /// AsmWriterInst.
191 ///
192 AsmWriterInst::AsmWriterInst(const CodeGenInstruction &CGI, Record *AsmWriter) {
193   this->CGI = &CGI;
194   
195   unsigned Variant       = AsmWriter->getValueAsInt("Variant");
196   int FirstOperandColumn = AsmWriter->getValueAsInt("FirstOperandColumn");
197   int OperandSpacing     = AsmWriter->getValueAsInt("OperandSpacing");
198   
199   unsigned CurVariant = ~0U;  // ~0 if we are outside a {.|.|.} region, other #.
200
201   // This is the number of tabs we've seen if we're doing columnar layout.
202   unsigned CurColumn = 0;
203   
204   
205   // NOTE: Any extensions to this code need to be mirrored in the 
206   // AsmPrinter::printInlineAsm code that executes as compile time (assuming
207   // that inline asm strings should also get the new feature)!
208   const std::string &AsmString = CGI.AsmString;
209   std::string::size_type LastEmitted = 0;
210   while (LastEmitted != AsmString.size()) {
211     std::string::size_type DollarPos =
212       AsmString.find_first_of("${|}\\", LastEmitted);
213     if (DollarPos == std::string::npos) DollarPos = AsmString.size();
214
215     // Emit a constant string fragment.
216
217     if (DollarPos != LastEmitted) {
218       if (CurVariant == Variant || CurVariant == ~0U) {
219         for (; LastEmitted != DollarPos; ++LastEmitted)
220           switch (AsmString[LastEmitted]) {
221           case '\n':
222             AddLiteralString("\\n");
223             break;
224           case '\t':
225             // If the asm writer is not using a columnar layout, \t is not
226             // magic.
227             if (FirstOperandColumn == -1 || OperandSpacing == -1) {
228               AddLiteralString("\\t");
229             } else {
230               // We recognize a tab as an operand delimeter.
231               unsigned DestColumn = FirstOperandColumn + 
232                                     CurColumn++ * OperandSpacing;
233               Operands.push_back(
234                 AsmWriterOperand("O.PadToColumn(" +
235                                  utostr(DestColumn) + ");\n",
236                                  AsmWriterOperand::isLiteralStatementOperand));
237             }
238             break;
239           case '"':
240             AddLiteralString("\\\"");
241             break;
242           case '\\':
243             AddLiteralString("\\\\");
244             break;
245           default:
246             AddLiteralString(std::string(1, AsmString[LastEmitted]));
247             break;
248           }
249       } else {
250         LastEmitted = DollarPos;
251       }
252     } else if (AsmString[DollarPos] == '\\') {
253       if (DollarPos+1 != AsmString.size() &&
254           (CurVariant == Variant || CurVariant == ~0U)) {
255         if (AsmString[DollarPos+1] == 'n') {
256           AddLiteralString("\\n");
257         } else if (AsmString[DollarPos+1] == 't') {
258           // If the asm writer is not using a columnar layout, \t is not
259           // magic.
260           if (FirstOperandColumn == -1 || OperandSpacing == -1) {
261             AddLiteralString("\\t");
262             break;
263           }
264             
265           // We recognize a tab as an operand delimeter.
266           unsigned DestColumn = FirstOperandColumn + 
267                                 CurColumn++ * OperandSpacing;
268           Operands.push_back(
269             AsmWriterOperand("O.PadToColumn(" + utostr(DestColumn) + ");\n",
270                              AsmWriterOperand::isLiteralStatementOperand));
271           break;
272         } else if (std::string("${|}\\").find(AsmString[DollarPos+1]) 
273                    != std::string::npos) {
274           AddLiteralString(std::string(1, AsmString[DollarPos+1]));
275         } else {
276           throw "Non-supported escaped character found in instruction '" +
277             CGI.TheDef->getName() + "'!";
278         }
279         LastEmitted = DollarPos+2;
280         continue;
281       }
282     } else if (AsmString[DollarPos] == '{') {
283       if (CurVariant != ~0U)
284         throw "Nested variants found for instruction '" +
285               CGI.TheDef->getName() + "'!";
286       LastEmitted = DollarPos+1;
287       CurVariant = 0;   // We are now inside of the variant!
288     } else if (AsmString[DollarPos] == '|') {
289       if (CurVariant == ~0U)
290         throw "'|' character found outside of a variant in instruction '"
291           + CGI.TheDef->getName() + "'!";
292       ++CurVariant;
293       ++LastEmitted;
294     } else if (AsmString[DollarPos] == '}') {
295       if (CurVariant == ~0U)
296         throw "'}' character found outside of a variant in instruction '"
297           + CGI.TheDef->getName() + "'!";
298       ++LastEmitted;
299       CurVariant = ~0U;
300     } else if (DollarPos+1 != AsmString.size() &&
301                AsmString[DollarPos+1] == '$') {
302       if (CurVariant == Variant || CurVariant == ~0U) {
303         AddLiteralString("$");  // "$$" -> $
304       }
305       LastEmitted = DollarPos+2;
306     } else {
307       // Get the name of the variable.
308       std::string::size_type VarEnd = DollarPos+1;
309  
310       // handle ${foo}bar as $foo by detecting whether the character following
311       // the dollar sign is a curly brace.  If so, advance VarEnd and DollarPos
312       // so the variable name does not contain the leading curly brace.
313       bool hasCurlyBraces = false;
314       if (VarEnd < AsmString.size() && '{' == AsmString[VarEnd]) {
315         hasCurlyBraces = true;
316         ++DollarPos;
317         ++VarEnd;
318       }
319
320       while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
321         ++VarEnd;
322       std::string VarName(AsmString.begin()+DollarPos+1,
323                           AsmString.begin()+VarEnd);
324
325       // Modifier - Support ${foo:modifier} syntax, where "modifier" is passed
326       // into printOperand.  Also support ${:feature}, which is passed into
327       // PrintSpecial.
328       std::string Modifier;
329       
330       // In order to avoid starting the next string at the terminating curly
331       // brace, advance the end position past it if we found an opening curly
332       // brace.
333       if (hasCurlyBraces) {
334         if (VarEnd >= AsmString.size())
335           throw "Reached end of string before terminating curly brace in '"
336                 + CGI.TheDef->getName() + "'";
337         
338         // Look for a modifier string.
339         if (AsmString[VarEnd] == ':') {
340           ++VarEnd;
341           if (VarEnd >= AsmString.size())
342             throw "Reached end of string before terminating curly brace in '"
343               + CGI.TheDef->getName() + "'";
344           
345           unsigned ModifierStart = VarEnd;
346           while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
347             ++VarEnd;
348           Modifier = std::string(AsmString.begin()+ModifierStart,
349                                  AsmString.begin()+VarEnd);
350           if (Modifier.empty())
351             throw "Bad operand modifier name in '"+ CGI.TheDef->getName() + "'";
352         }
353         
354         if (AsmString[VarEnd] != '}')
355           throw "Variable name beginning with '{' did not end with '}' in '"
356                 + CGI.TheDef->getName() + "'";
357         ++VarEnd;
358       }
359       if (VarName.empty() && Modifier.empty())
360         throw "Stray '$' in '" + CGI.TheDef->getName() +
361               "' asm string, maybe you want $$?";
362
363       if (VarName.empty()) {
364         // Just a modifier, pass this into PrintSpecial.
365         Operands.push_back(AsmWriterOperand("PrintSpecial", ~0U, Modifier));
366       } else {
367         // Otherwise, normal operand.
368         unsigned OpNo = CGI.getOperandNamed(VarName);
369         CodeGenInstruction::OperandInfo OpInfo = CGI.OperandList[OpNo];
370
371         if (CurVariant == Variant || CurVariant == ~0U) {
372           unsigned MIOp = OpInfo.MIOperandNo;
373           Operands.push_back(AsmWriterOperand(OpInfo.PrinterMethodName, MIOp,
374                                               Modifier));
375         }
376       }
377       LastEmitted = VarEnd;
378     }
379   }
380   
381   Operands.push_back(AsmWriterOperand("return;",
382                                   AsmWriterOperand::isLiteralStatementOperand));
383 }
384
385 /// MatchesAllButOneOp - If this instruction is exactly identical to the
386 /// specified instruction except for one differing operand, return the differing
387 /// operand number.  If more than one operand mismatches, return ~1, otherwise
388 /// if the instructions are identical return ~0.
389 unsigned AsmWriterInst::MatchesAllButOneOp(const AsmWriterInst &Other)const{
390   if (Operands.size() != Other.Operands.size()) return ~1;
391
392   unsigned MismatchOperand = ~0U;
393   for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
394     if (Operands[i] != Other.Operands[i]) {
395       if (MismatchOperand != ~0U)  // Already have one mismatch?
396         return ~1U;
397       else
398         MismatchOperand = i;
399     }
400   }
401   return MismatchOperand;
402 }
403
404 static void PrintCases(std::vector<std::pair<std::string,
405                        AsmWriterOperand> > &OpsToPrint, raw_ostream &O) {
406   O << "    case " << OpsToPrint.back().first << ": ";
407   AsmWriterOperand TheOp = OpsToPrint.back().second;
408   OpsToPrint.pop_back();
409
410   // Check to see if any other operands are identical in this list, and if so,
411   // emit a case label for them.
412   for (unsigned i = OpsToPrint.size(); i != 0; --i)
413     if (OpsToPrint[i-1].second == TheOp) {
414       O << "\n    case " << OpsToPrint[i-1].first << ": ";
415       OpsToPrint.erase(OpsToPrint.begin()+i-1);
416     }
417
418   // Finally, emit the code.
419   O << TheOp.getCode();
420   O << "break;\n";
421 }
422
423
424 /// EmitInstructions - Emit the last instruction in the vector and any other
425 /// instructions that are suitably similar to it.
426 static void EmitInstructions(std::vector<AsmWriterInst> &Insts,
427                              raw_ostream &O) {
428   AsmWriterInst FirstInst = Insts.back();
429   Insts.pop_back();
430
431   std::vector<AsmWriterInst> SimilarInsts;
432   unsigned DifferingOperand = ~0;
433   for (unsigned i = Insts.size(); i != 0; --i) {
434     unsigned DiffOp = Insts[i-1].MatchesAllButOneOp(FirstInst);
435     if (DiffOp != ~1U) {
436       if (DifferingOperand == ~0U)  // First match!
437         DifferingOperand = DiffOp;
438
439       // If this differs in the same operand as the rest of the instructions in
440       // this class, move it to the SimilarInsts list.
441       if (DifferingOperand == DiffOp || DiffOp == ~0U) {
442         SimilarInsts.push_back(Insts[i-1]);
443         Insts.erase(Insts.begin()+i-1);
444       }
445     }
446   }
447
448   O << "  case " << FirstInst.CGI->Namespace << "::"
449     << FirstInst.CGI->TheDef->getName() << ":\n";
450   for (unsigned i = 0, e = SimilarInsts.size(); i != e; ++i)
451     O << "  case " << SimilarInsts[i].CGI->Namespace << "::"
452       << SimilarInsts[i].CGI->TheDef->getName() << ":\n";
453   for (unsigned i = 0, e = FirstInst.Operands.size(); i != e; ++i) {
454     if (i != DifferingOperand) {
455       // If the operand is the same for all instructions, just print it.
456       O << "    " << FirstInst.Operands[i].getCode();
457     } else {
458       // If this is the operand that varies between all of the instructions,
459       // emit a switch for just this operand now.
460       O << "    switch (MI->getOpcode()) {\n";
461       std::vector<std::pair<std::string, AsmWriterOperand> > OpsToPrint;
462       OpsToPrint.push_back(std::make_pair(FirstInst.CGI->Namespace + "::" +
463                                           FirstInst.CGI->TheDef->getName(),
464                                           FirstInst.Operands[i]));
465
466       for (unsigned si = 0, e = SimilarInsts.size(); si != e; ++si) {
467         AsmWriterInst &AWI = SimilarInsts[si];
468         OpsToPrint.push_back(std::make_pair(AWI.CGI->Namespace+"::"+
469                                             AWI.CGI->TheDef->getName(),
470                                             AWI.Operands[i]));
471       }
472       std::reverse(OpsToPrint.begin(), OpsToPrint.end());
473       while (!OpsToPrint.empty())
474         PrintCases(OpsToPrint, O);
475       O << "    }";
476     }
477     O << "\n";
478   }
479   O << "    break;\n";
480 }
481
482 void AsmWriterEmitter::
483 FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, 
484                           std::vector<unsigned> &InstIdxs,
485                           std::vector<unsigned> &InstOpsUsed) const {
486   InstIdxs.assign(NumberedInstructions.size(), ~0U);
487   
488   // This vector parallels UniqueOperandCommands, keeping track of which
489   // instructions each case are used for.  It is a comma separated string of
490   // enums.
491   std::vector<std::string> InstrsForCase;
492   InstrsForCase.resize(UniqueOperandCommands.size());
493   InstOpsUsed.assign(UniqueOperandCommands.size(), 0);
494   
495   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
496     const AsmWriterInst *Inst = getAsmWriterInstByID(i);
497     if (Inst == 0) continue;  // PHI, INLINEASM, DBG_LABEL, etc.
498     
499     std::string Command;
500     if (Inst->Operands.empty())
501       continue;   // Instruction already done.
502
503     Command = "    " + Inst->Operands[0].getCode() + "\n";
504
505     // Check to see if we already have 'Command' in UniqueOperandCommands.
506     // If not, add it.
507     bool FoundIt = false;
508     for (unsigned idx = 0, e = UniqueOperandCommands.size(); idx != e; ++idx)
509       if (UniqueOperandCommands[idx] == Command) {
510         InstIdxs[i] = idx;
511         InstrsForCase[idx] += ", ";
512         InstrsForCase[idx] += Inst->CGI->TheDef->getName();
513         FoundIt = true;
514         break;
515       }
516     if (!FoundIt) {
517       InstIdxs[i] = UniqueOperandCommands.size();
518       UniqueOperandCommands.push_back(Command);
519       InstrsForCase.push_back(Inst->CGI->TheDef->getName());
520
521       // This command matches one operand so far.
522       InstOpsUsed.push_back(1);
523     }
524   }
525   
526   // For each entry of UniqueOperandCommands, there is a set of instructions
527   // that uses it.  If the next command of all instructions in the set are
528   // identical, fold it into the command.
529   for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size();
530        CommandIdx != e; ++CommandIdx) {
531     
532     for (unsigned Op = 1; ; ++Op) {
533       // Scan for the first instruction in the set.
534       std::vector<unsigned>::iterator NIT =
535         std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
536       if (NIT == InstIdxs.end()) break;  // No commonality.
537
538       // If this instruction has no more operands, we isn't anything to merge
539       // into this command.
540       const AsmWriterInst *FirstInst = 
541         getAsmWriterInstByID(NIT-InstIdxs.begin());
542       if (!FirstInst || FirstInst->Operands.size() == Op)
543         break;
544
545       // Otherwise, scan to see if all of the other instructions in this command
546       // set share the operand.
547       bool AllSame = true;
548       // Keep track of the maximum, number of operands or any
549       // instruction we see in the group.
550       size_t MaxSize = FirstInst->Operands.size();
551
552       for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
553            NIT != InstIdxs.end();
554            NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) {
555         // Okay, found another instruction in this command set.  If the operand
556         // matches, we're ok, otherwise bail out.
557         const AsmWriterInst *OtherInst = 
558           getAsmWriterInstByID(NIT-InstIdxs.begin());
559
560         if (OtherInst &&
561             OtherInst->Operands.size() > FirstInst->Operands.size())
562           MaxSize = std::max(MaxSize, OtherInst->Operands.size());
563
564         if (!OtherInst || OtherInst->Operands.size() == Op ||
565             OtherInst->Operands[Op] != FirstInst->Operands[Op]) {
566           AllSame = false;
567           break;
568         }
569       }
570       if (!AllSame) break;
571       
572       // Okay, everything in this command set has the same next operand.  Add it
573       // to UniqueOperandCommands and remember that it was consumed.
574       std::string Command = "    " + FirstInst->Operands[Op].getCode() + "\n";
575       
576       UniqueOperandCommands[CommandIdx] += Command;
577       InstOpsUsed[CommandIdx]++;
578     }
579   }
580   
581   // Prepend some of the instructions each case is used for onto the case val.
582   for (unsigned i = 0, e = InstrsForCase.size(); i != e; ++i) {
583     std::string Instrs = InstrsForCase[i];
584     if (Instrs.size() > 70) {
585       Instrs.erase(Instrs.begin()+70, Instrs.end());
586       Instrs += "...";
587     }
588     
589     if (!Instrs.empty())
590       UniqueOperandCommands[i] = "    // " + Instrs + "\n" + 
591         UniqueOperandCommands[i];
592   }
593 }
594
595
596 /// EmitPrintInstruction - Generate the code for the "printInstruction" method
597 /// implementation.
598 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
599   CodeGenTarget Target;
600   Record *AsmWriter = Target.getAsmWriter();
601   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
602   
603   O <<
604   "/// printInstruction - This method is automatically generated by tablegen\n"
605   "/// from the instruction set description.\n"
606     "void " << Target.getName() << ClassName
607             << "::printInstruction(const MachineInstr *MI) {\n";
608
609   std::vector<AsmWriterInst> Instructions;
610
611   for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
612          E = Target.inst_end(); I != E; ++I)
613     if (!I->second.AsmString.empty() &&
614         I->second.TheDef->getName() != "PHI")
615       Instructions.push_back(AsmWriterInst(I->second, AsmWriter));
616
617   // Get the instruction numbering.
618   Target.getInstructionsByEnumValue(NumberedInstructions);
619   
620   // Compute the CodeGenInstruction -> AsmWriterInst mapping.  Note that not
621   // all machine instructions are necessarily being printed, so there may be
622   // target instructions not in this map.
623   for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
624     CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
625
626   // Build an aggregate string, and build a table of offsets into it.
627   StringToOffsetTable StringTable;
628   
629   /// OpcodeInfo - This encodes the index of the string to use for the first
630   /// chunk of the output as well as indices used for operand printing.
631   std::vector<unsigned> OpcodeInfo;
632   
633   unsigned MaxStringIdx = 0;
634   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
635     AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
636     unsigned Idx;
637     if (AWI == 0) {
638       // Something not handled by the asmwriter printer.
639       Idx = ~0U;
640     } else if (AWI->Operands[0].OperandType != 
641                         AsmWriterOperand::isLiteralTextOperand ||
642                AWI->Operands[0].Str.empty()) {
643       // Something handled by the asmwriter printer, but with no leading string.
644       Idx = StringTable.GetOrAddStringOffset("");
645     } else {
646       std::string Str = AWI->Operands[0].Str;
647       UnescapeString(Str);
648       Idx = StringTable.GetOrAddStringOffset(Str);
649       MaxStringIdx = std::max(MaxStringIdx, Idx);
650       
651       // Nuke the string from the operand list.  It is now handled!
652       AWI->Operands.erase(AWI->Operands.begin());
653     }
654     
655     // Bias offset by one since we want 0 as a sentinel.
656     OpcodeInfo.push_back(Idx+1);
657   }
658   
659   // Figure out how many bits we used for the string index.
660   unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2);
661   
662   // To reduce code size, we compactify common instructions into a few bits
663   // in the opcode-indexed table.
664   unsigned BitsLeft = 32-AsmStrBits;
665
666   std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
667   
668   while (1) {
669     std::vector<std::string> UniqueOperandCommands;
670     std::vector<unsigned> InstIdxs;
671     std::vector<unsigned> NumInstOpsHandled;
672     FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
673                               NumInstOpsHandled);
674     
675     // If we ran out of operands to print, we're done.
676     if (UniqueOperandCommands.empty()) break;
677     
678     // Compute the number of bits we need to represent these cases, this is
679     // ceil(log2(numentries)).
680     unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
681     
682     // If we don't have enough bits for this operand, don't include it.
683     if (NumBits > BitsLeft) {
684       DEBUG(errs() << "Not enough bits to densely encode " << NumBits
685                    << " more bits\n");
686       break;
687     }
688     
689     // Otherwise, we can include this in the initial lookup table.  Add it in.
690     BitsLeft -= NumBits;
691     for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
692       if (InstIdxs[i] != ~0U)
693         OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits);
694     
695     // Remove the info about this operand.
696     for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
697       if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
698         if (!Inst->Operands.empty()) {
699           unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
700           assert(NumOps <= Inst->Operands.size() &&
701                  "Can't remove this many ops!");
702           Inst->Operands.erase(Inst->Operands.begin(),
703                                Inst->Operands.begin()+NumOps);
704         }
705     }
706     
707     // Remember the handlers for this set of operands.
708     TableDrivenOperandPrinters.push_back(UniqueOperandCommands);
709   }
710   
711   
712   
713   O<<"  static const unsigned OpInfo[] = {\n";
714   for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
715     O << "    " << OpcodeInfo[i] << "U,\t// "
716       << NumberedInstructions[i]->TheDef->getName() << "\n";
717   }
718   // Add a dummy entry so the array init doesn't end with a comma.
719   O << "    0U\n";
720   O << "  };\n\n";
721   
722   // Emit the string itself.
723   O << "  const char *AsmStrs = \n";
724   StringTable.EmitString(O);
725   O << ";\n\n";
726
727   O << "\n#ifndef NO_ASM_WRITER_BOILERPLATE\n";
728   
729   O << "  if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n"
730     << "    O << \"\\t\";\n"
731     << "    printInlineAsm(MI);\n"
732     << "    return;\n"
733     << "  } else if (MI->isLabel()) {\n"
734     << "    printLabel(MI);\n"
735     << "    return;\n"
736     << "  } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n"
737     << "    printImplicitDef(MI);\n"
738     << "    return;\n"
739     << "  }\n\n";
740
741   O << "\n#endif\n";
742
743   O << "  O << \"\\t\";\n\n";
744
745   O << "  // Emit the opcode for the instruction.\n"
746     << "  unsigned Bits = OpInfo[MI->getOpcode()];\n"
747     << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
748     << "  O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n";
749
750   // Output the table driven operand information.
751   BitsLeft = 32-AsmStrBits;
752   for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
753     std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
754
755     // Compute the number of bits we need to represent these cases, this is
756     // ceil(log2(numentries)).
757     unsigned NumBits = Log2_32_Ceil(Commands.size());
758     assert(NumBits <= BitsLeft && "consistency error");
759     
760     // Emit code to extract this field from Bits.
761     BitsLeft -= NumBits;
762     
763     O << "\n  // Fragment " << i << " encoded into " << NumBits
764       << " bits for " << Commands.size() << " unique commands.\n";
765     
766     if (Commands.size() == 2) {
767       // Emit two possibilitys with if/else.
768       O << "  if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
769         << ((1 << NumBits)-1) << ") {\n"
770         << Commands[1]
771         << "  } else {\n"
772         << Commands[0]
773         << "  }\n\n";
774     } else {
775       O << "  switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
776         << ((1 << NumBits)-1) << ") {\n"
777         << "  default:   // unreachable.\n";
778       
779       // Print out all the cases.
780       for (unsigned i = 0, e = Commands.size(); i != e; ++i) {
781         O << "  case " << i << ":\n";
782         O << Commands[i];
783         O << "    break;\n";
784       }
785       O << "  }\n\n";
786     }
787   }
788   
789   // Okay, delete instructions with no operand info left.
790   for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
791     // Entire instruction has been emitted?
792     AsmWriterInst &Inst = Instructions[i];
793     if (Inst.Operands.empty()) {
794       Instructions.erase(Instructions.begin()+i);
795       --i; --e;
796     }
797   }
798
799     
800   // Because this is a vector, we want to emit from the end.  Reverse all of the
801   // elements in the vector.
802   std::reverse(Instructions.begin(), Instructions.end());
803   
804   if (!Instructions.empty()) {
805     // Find the opcode # of inline asm.
806     O << "  switch (MI->getOpcode()) {\n";
807     while (!Instructions.empty())
808       EmitInstructions(Instructions, O);
809
810     O << "  }\n";
811     O << "  return;\n";
812   }
813
814   O << "  return;\n";
815   O << "}\n";
816 }
817
818
819 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
820   CodeGenTarget Target;
821   Record *AsmWriter = Target.getAsmWriter();
822   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
823   const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
824   
825   O <<
826   "\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
827   "/// from the register set description.  This returns the assembler name\n"
828   "/// for the specified register.\n"
829   "const char *" << Target.getName() << ClassName
830   << "::getRegisterName(unsigned RegNo) {\n"
831   << "  assert(RegNo && RegNo < " << (Registers.size()+1)
832   << " && \"Invalid register number!\");\n"
833   << "\n"
834   << "  static const char *const RegAsmNames[] = {\n";
835   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
836     const CodeGenRegister &Reg = Registers[i];
837
838     std::string AsmName = Reg.TheDef->getValueAsString("AsmName");
839     if (AsmName.empty())
840       AsmName = Reg.getName();
841     O << "    \"" << AsmName << "\",\n";
842   }
843   O << "    0\n"
844     << "  };\n"
845     << "\n"
846     << "  return RegAsmNames[RegNo-1];\n"
847     << "}\n";
848 }
849
850
851 void AsmWriterEmitter::run(raw_ostream &O) {
852   EmitSourceFileHeader("Assembly Writer Source Fragment", O);
853   
854   EmitPrintInstruction(O);
855   EmitGetRegisterName(O);
856 }
857