AsmWriterEmitter.cpp revision b0b55e74a090454711b1bb17e4f872d62d6e6b65
12e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===//
22e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//
32e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//                     The LLVM Compiler Infrastructure
42e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//
52e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// This file was developed by the LLVM research group and is distributed under
62e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details.
72e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//
82e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===//
92e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//
102e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// This tablegen backend is emits an assembly printer for the current target.
112e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner// Note that this is currently fairly skeletal, but will grow over time.
122e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//
132e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner//===----------------------------------------------------------------------===//
142e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
152e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "AsmWriterEmitter.h"
162e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "CodeGenTarget.h"
17175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner#include "Record.h"
182e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include <ostream>
192e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnerusing namespace llvm;
202e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
21076efa771aa634801202f7b8189e33ee79dfc4edChris Lattnerstatic bool isIdentChar(char C) {
22076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner  return (C >= 'a' && C <= 'z') ||
23076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner         (C >= 'A' && C <= 'Z') ||
24076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner         (C >= '0' && C <= '9') ||
25076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner         C == '_';
26076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner}
27076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner
28b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnernamespace {
29b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  struct AsmWriterOperand {
30b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    enum { isLiteralTextOperand, isMachineInstrOperand } OperandType;
31b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
32b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// Str - For isLiteralTextOperand, this IS the literal text.  For
33b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// isMachineInstrOperand, this is the PrinterMethodName for the operand.
34b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    std::string Str;
35b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
36b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// MiOpNo - For isMachineInstrOperand, this is the operand number of the
37b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// machine instruction.
38b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    unsigned MIOpNo;
39b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
40b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// OpVT - For isMachineInstrOperand, this is the value type for the
41b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    /// operand.
42b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    MVT::ValueType OpVT;
43b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
44b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    AsmWriterOperand(const std::string &LitStr)
45b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      : OperandType(isLiteralTextOperand),  Str(LitStr) {}
46b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
47b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    AsmWriterOperand(const std::string &Printer, unsigned OpNo,
48b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                     MVT::ValueType VT) : OperandType(isMachineInstrOperand),
49b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                                          Str(Printer), MIOpNo(OpNo), OpVT(VT){}
50b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
51b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    void EmitCode(std::ostream &OS) const;
52b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  };
53b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
54b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  struct AsmWriterInst {
55b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    std::vector<AsmWriterOperand> Operands;
56b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
57b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    void ParseAsmString(const CodeGenInstruction &CGI, unsigned Variant);
58b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    void EmitCode(std::ostream &OS) const {
59b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      for (unsigned i = 0, e = Operands.size(); i != e; ++i)
60b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        Operands[i].EmitCode(OS);
61b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    }
62b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  private:
63b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    void AddLiteralString(const std::string &Str) {
64b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // If the last operand was already a literal text string, append this to
65b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // it, otherwise add a new operand.
66b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (!Operands.empty() &&
67b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          Operands.back().OperandType == AsmWriterOperand::isLiteralTextOperand)
68b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        Operands.back().Str.append(Str);
69b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      else
70b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        Operands.push_back(AsmWriterOperand(Str));
71b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    }
72b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  };
73b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner}
74b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
75b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
76b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnervoid AsmWriterOperand::EmitCode(std::ostream &OS) const {
77b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  if (OperandType == isLiteralTextOperand)
78b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    OS << "O << \"" << Str << "\"; ";
79b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  else
80b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    OS << Str << "(MI, " << MIOpNo << ", MVT::" << getName(OpVT) << "); ";
81b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner}
82b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
83b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
84b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// ParseAsmString - Parse the specified Instruction's AsmString into this
85b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner/// AsmWriterInst.
86b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner///
87b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattnervoid AsmWriterInst::ParseAsmString(const CodeGenInstruction &CGI,
88b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                                   unsigned Variant) {
89b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  bool inVariant = false;  // True if we are inside a {.|.|.} region.
90b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
91b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  const std::string &AsmString = CGI.AsmString;
92b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  std::string::size_type LastEmitted = 0;
93b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  while (LastEmitted != AsmString.size()) {
94b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    std::string::size_type DollarPos =
95b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AsmString.find_first_of("${|}", LastEmitted);
96b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    if (DollarPos == std::string::npos) DollarPos = AsmString.size();
97b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
98b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    // Emit a constant string fragment.
99b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    if (DollarPos != LastEmitted) {
100b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // TODO: this should eventually handle escaping.
101b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AddLiteralString(std::string(AsmString.begin()+LastEmitted,
102b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                                   AsmString.begin()+DollarPos));
103b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = DollarPos;
104b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    } else if (AsmString[DollarPos] == '{') {
105b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (inVariant)
106b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        throw "Nested variants found for instruction '" + CGI.Name + "'!";
107b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = DollarPos+1;
108b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      inVariant = true;   // We are now inside of the variant!
109b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      for (unsigned i = 0; i != Variant; ++i) {
110b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        // Skip over all of the text for an irrelevant variant here.  The
111b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        // next variant starts at |, or there may not be text for this
112b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        // variant if we see a }.
113b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        std::string::size_type NP =
114b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          AsmString.find_first_of("|}", LastEmitted);
115b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        if (NP == std::string::npos)
116b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          throw "Incomplete variant for instruction '" + CGI.Name + "'!";
117b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        LastEmitted = NP+1;
118b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        if (AsmString[NP] == '}') {
119b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          inVariant = false;        // No text for this variant.
120b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          break;
121b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        }
122b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      }
123b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    } else if (AsmString[DollarPos] == '|') {
124b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (!inVariant)
125b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        throw "'|' character found outside of a variant in instruction '"
126b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          + CGI.Name + "'!";
127b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // Move to the end of variant list.
128b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      std::string::size_type NP = AsmString.find('}', LastEmitted);
129b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (NP == std::string::npos)
130b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        throw "Incomplete variant for instruction '" + CGI.Name + "'!";
131b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = NP+1;
132b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      inVariant = false;
133b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    } else if (AsmString[DollarPos] == '}') {
134b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (!inVariant)
135b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        throw "'}' character found outside of a variant in instruction '"
136b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          + CGI.Name + "'!";
137b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = DollarPos+1;
138b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      inVariant = false;
139b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    } else if (DollarPos+1 != AsmString.size() &&
140b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner               AsmString[DollarPos+1] == '$') {
141b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AddLiteralString("$");  // "$$" -> $
142b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = DollarPos+2;
143b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    } else {
144b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // Get the name of the variable.
145b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // TODO: should eventually handle ${foo}bar as $foo
146b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      std::string::size_type VarEnd = DollarPos+1;
147b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      while (VarEnd < AsmString.size() && isIdentChar(AsmString[VarEnd]))
148b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        ++VarEnd;
149b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      std::string VarName(AsmString.begin()+DollarPos+1,
150b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                          AsmString.begin()+VarEnd);
151b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (VarName.empty())
152b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        throw "Stray '$' in '" + CGI.Name + "' asm string, maybe you want $$?";
153b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
154b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      unsigned OpNo = CGI.getOperandNamed(VarName);
155b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
156b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // If this is a two-address instruction and we are not accessing the
157b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      // 0th operand, remove an operand.
158b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      unsigned MIOp = CGI.OperandList[OpNo].MIOperandNo;
159b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      if (CGI.isTwoAddress && MIOp != 0) {
160b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        if (MIOp == 1)
161b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner          throw "Should refer to operand #0 instead of #1 for two-address"
162b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner            " instruction '" + CGI.Name + "'!";
163b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner        --MIOp;
164b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      }
165b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
166b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      Operands.push_back(AsmWriterOperand(CGI.OperandList[OpNo].PrinterMethodName,
167b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner                                          MIOp, CGI.OperandList[OpNo].Ty));
168b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      LastEmitted = VarEnd;
169b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner    }
170b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  }
171b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
172b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner  AddLiteralString("\\n");
173b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner}
174b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
175b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner
1762e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattnervoid AsmWriterEmitter::run(std::ostream &O) {
1772e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  EmitSourceFileHeader("Assembly Writer Source Fragment", O);
1782e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
1792e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  CodeGenTarget Target;
180175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner  Record *AsmWriter = Target.getAsmWriter();
181953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner  std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
182953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner  unsigned Variant = AsmWriter->getValueAsInt("Variant");
183175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner
1842e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  O <<
1852e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  "/// printInstruction - This method is automatically generated by tablegen\n"
1862e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  "/// from the instruction set description.  This method returns true if the\n"
1872e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  "/// machine instruction was sufficiently described to print it, otherwise\n"
1882e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  "/// it returns false.\n"
189953c6fe11277c2511744440f5d8d90aca1354e18Chris Lattner    "bool " << Target.getName() << ClassName
190175580c0f36b026daf9de0adabdb7ddcf7619db6Chris Lattner            << "::printInstruction(const MachineInstr *MI) {\n";
1912e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  O << "  switch (MI->getOpcode()) {\n"
1922e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner       "  default: return false;\n";
1932e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
1942e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  std::string Namespace = Target.inst_begin()->second.Namespace;
1952e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
1962e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
1972e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner         E = Target.inst_end(); I != E; ++I)
1982e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner    if (!I->second.AsmString.empty()) {
199b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      O << "  case " << Namespace << "::" << I->first << ": ";
200076efa771aa634801202f7b8189e33ee79dfc4edChris Lattner
201b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AsmWriterInst AWI;
202b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AWI.ParseAsmString(I->second, Variant);
203b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      AWI.EmitCode(O);
204b0b55e74a090454711b1bb17e4f872d62d6e6b65Chris Lattner      O << " break;\n";
2052e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner    }
2062e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
2072e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner  O << "  }\n"
2082e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner       "  return true;\n"
2092e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner       "}\n";
2102e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner}
211