AsmWriter.cpp revision d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfa
1009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===-- Writer.cpp - Library for Printing VM assembly files ------*- C++ -*--=//
2009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
3009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library implements the functionality defined in llvm/Assembly/Writer.h
4009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
5009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// This library uses the Analysis library to figure out offsets for
6009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// variables in the method tables...
7009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
8009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// TODO: print out the type name instead of the full type if a particular type
9009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//       is in the symbol table...
10009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
11009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
12009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
13009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Assembly/Writer.h"
14009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Analysis/SlotCalculator.h"
15009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Module.h"
16009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/Method.h"
17009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/BasicBlock.h"
18009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/ConstPoolVals.h"
19009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/iOther.h"
20009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner#include "llvm/iMemory.h"
21009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
22d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattnervoid DebugValue(const Value *V) {
23d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner  cerr << V << endl;
24d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner}
25d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner
26d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner
27009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerclass AssemblyWriter : public ModuleAnalyzer {
28009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ostream &Out;
29009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator &Table;
30009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic:
31009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) {
32009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
33009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
34009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Module *M)         { processModule(M);      }
35009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Method *M)         { processMethod(M);      }
36009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const BasicBlock *BB)    { processBasicBlock(BB); }
37009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const Instruction *I)    { processInstruction(I); }
38009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  inline void write(const ConstPoolVal *CPV) { processConstant(CPV);  }
39009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
40009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprotected:
41009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool visitMethod(const Method *M);
42009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processConstPool(const ConstantPool &CP, bool isMethod);
43009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processConstant(const ConstPoolVal *CPV);
44009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processMethod(const Method *M);
45009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processMethodArgument(const MethodArgument *MA);
46009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processBasicBlock(const BasicBlock *BB);
47009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  virtual bool processInstruction(const Instruction *I);
48009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
49009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate :
50009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
51009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner};
52009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
53009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
54009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
55009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// visitMethod - This member is called after the above two steps, visting each
56009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// method, because they are effectively values that go into the constant pool.
57009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
58009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::visitMethod(const Method *M) {
59009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
60009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
61009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
62009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processConstPool(const ConstantPool &CP, bool isMethod) {
63009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Done printing arguments...
64009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (isMethod) Out << ")\n";
65009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
66009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ModuleAnalyzer::processConstPool(CP, isMethod);
67009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
68009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (isMethod)
69009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "begin";
70009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  else
71009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "implementation\n";
72009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
73009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
74009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
75009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
76009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processConstant - Print out a constant pool entry...
77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "\t";
80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out name if it exists...
82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (CPV->hasName())
83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "%" << CPV->getName() << " = ";
84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the opcode...
86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << CPV->getType();
87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Write the value out now...
89009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  writeOperand(CPV, false, false);
90009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
91009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (!CPV->hasName() && CPV->getType() != Type::VoidTy) {
92009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(CPV); // Print out the def slot taken...
93009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\t\t; <" << CPV->getType() << ">:";
94009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0) Out << Slot;
95009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else Out << "<badref>";
96009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
97009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << endl;
99009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
102009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethod - Process all aspects of a method.
103009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
104009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processMethod(const Method *M) {
105009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the return type and name...
106009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "\n" << M->getReturnType() << " \"" << M->getName() << "\"(";
107009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Table.incorporateMethod(M);
108009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ModuleAnalyzer::processMethod(M);
109009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Table.purgeMethod();
110009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "end\n";
111009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
112009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
113009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
114009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethodArgument - This member is called for every argument that
115009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// is passed into the method.  Simply print it out
116009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
117009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
118009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Insert commas as we go... the first arg doesn't get a comma
119009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
120009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
121009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output type...
122009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << Arg->getType();
123009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
124009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Output name, if available...
125009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Arg->hasName())
126009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " %" << Arg->getName();
127009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  else if (Table.getValSlot(Arg) < 0)
128009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "<badref>";
129009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
130009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
131009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
132009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
133009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processBasicBlock - This member is called for each basic block in a methd.
134009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
135009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
136009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (BB->hasName()) {              // Print out the label if it exists...
137b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n" << BB->getName() << ":";
138009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else {
139009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(BB);
140b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\n; <label>:";
141009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (Slot >= 0)
142b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << Slot;         // Extra newline seperates out label's
143009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    else
144b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      Out << "<badref>";
145009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
146b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner  Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n";  // Output # uses
147009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  ModuleAnalyzer::processBasicBlock(BB);
149009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
150009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
151009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
152009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processInstruction - This member is called for each Instruction in a methd.
153009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//
154009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerbool AssemblyWriter::processInstruction(const Instruction *I) {
155009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << "\t";
156009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
157009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out name if it exists...
158009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (I && I->hasName())
159009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "%" << I->getName() << " = ";
160009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
161009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the opcode...
162a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  Out << I->getOpcodeName();
163009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
164009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print out the type of the operands...
165c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner  const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
166009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
167009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Special case conditional branches to swizzle the condition out to the front
168a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
169009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(2), true);
170009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
171009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand, true);
172009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << ",";
173009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true);
174009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
175a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Switch) {
176009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // Special case switch statement to get formatting nice and correct...
177009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand         , true); Out << ",";
178009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(I->getOperand(1), true); Out << " [";
179009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
180c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
181009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << "\n\t\t";
182c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), true); Out << ",";
183009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      writeOperand(I->getOperand(op+1), true);
184009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
185009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\n\t]";
1867fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner  } else if (I->isPHINode()) {
187c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    Out << " " << Operand->getType();
188009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
189c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    Out << " [";  writeOperand(Operand, false); Out << ",";
19028d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner    writeOperand(I->getOperand(1), false); Out << " ]";
191c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
192c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << ", [";
193c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op  ), false); Out << ",";
19428d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner      writeOperand(I->getOperand(op+1), false); Out << " ]";
195c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner    }
196a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Ret && !Operand) {
197009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " void";
198a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Call) {
199009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    writeOperand(Operand, true);
200009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "(";
201c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
202c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
203009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << ",";
204c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(op), true);
205009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
206009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
207009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " )";
208a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner  } else if (I->getOpcode() == Instruction::Malloc ||
209a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner	     I->getOpcode() == Instruction::Alloca) {
210c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    Out << " " << ((const PointerType*)I->getType())->getValueType();
211c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (I->getNumOperands()) {
212c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << ",";
213c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(0), true);
214009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
2150908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner  } else if (I->getOpcode() == Instruction::Cast) {
2160908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner    writeOperand(Operand, true);
2170908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner    Out << " to " << I->getType();
218009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else if (Operand) {   // Print the normal way...
219009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
220009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // PrintAllTypes - Instructions who have operands of all the same type
221009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // omit the type from all but the first operand.  If the instruction has
222009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    // different type operands (for example br), then they are all printed.
223009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    bool PrintAllTypes = false;
224009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    const Type *TheType = Operand->getType();
225009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
226c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
227c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Operand = I->getOperand(i);
228009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (Operand->getType() != TheType) {
229009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	PrintAllTypes = true;       // We have differing types!  Print them all!
230009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner	break;
231009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      }
232009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
233009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
234009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    if (!PrintAllTypes)
235009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      Out << " " << I->getOperand(0)->getType();
236009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
237c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
238009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (i) Out << ",";
239c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      writeOperand(I->getOperand(i), PrintAllTypes);
240009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
241009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
242009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
243009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // Print a little comment after the instruction indicating which slot it
244009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // occupies.
245009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  //
246b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner  if (I->getType() != Type::VoidTy) {
247b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    Out << "\t\t; <" << I->getType() << ">";
248009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
249b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    if (!I->hasName()) {
250b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      int Slot = Table.getValSlot(I); // Print out the def slot taken...
251b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      if (Slot >= 0) Out << ":" << Slot;
252b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner      else Out << ":<badref>";
253b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner    }
254009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << "\t[#uses=" << I->use_size() << "]";  // Output # uses
255009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
256009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  Out << endl;
257009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
258009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  return false;
259009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
260009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
261009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
262009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
263009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner				  bool PrintName) {
264009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (PrintType)
265009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " " << Operand->getType();
266009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
267009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (Operand->hasName() && PrintName) {
268009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    Out << " %" << Operand->getName();
269009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else {
270009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    int Slot = Table.getValSlot(Operand);
271009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
272c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner    if (const ConstPoolVal *CPV = Operand->castConstant()) {
273c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner      Out << " " << CPV->getStrValue();
274009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    } else {
275009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      if (Slot >= 0)  Out << " %" << Slot;
276009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner      else if (PrintName)
277009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner        Out << "<badref>";     // Not embeded into a location?
278009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    }
279009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
280009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
281009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
282009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
283009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
284009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//                       External Interface declarations
285009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===//
286009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
287009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
288009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
289009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Module *M, ostream &o) {
290009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (M == 0) { o << "<null> module\n"; return; }
291009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(M, true);
292009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
293009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
294009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(M);
295009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
296009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
297009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Method *M, ostream &o) {
298009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (M == 0) { o << "<null> method\n"; return; }
299009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(M->getParent(), true);
300009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
301009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
302009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(M);
303009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
304009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
305009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
306009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const BasicBlock *BB, ostream &o) {
307009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (BB == 0) { o << "<null> basic block\n"; return; }
308009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
309009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(BB->getParent(), true);
310009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
311009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
312009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(BB);
313009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
314009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
315009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const ConstPoolVal *CPV, ostream &o) {
316009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (CPV == 0) { o << "<null> constant pool value\n"; return; }
317009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
318009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator *SlotTable;
319009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
320009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // A Constant pool value may have a parent that is either a method or a
321009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  // module.  Untangle this now...
322009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  //
3237fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner  if (CPV->getParent() == 0 || CPV->getParent()->isMethod()) {
324009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner    SlotTable = new SlotCalculator((Method*)CPV->getParent(), true);
325009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  } else {
3267fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner    SlotTable =
3277fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner      new SlotCalculator(CPV->getParent()->castModuleAsserting(), true);
328009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  }
329009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
330009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, *SlotTable);
331009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(CPV);
332009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
333009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  delete SlotTable;
334009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
335009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
336009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Instruction *I, ostream &o) {
337009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  if (I == 0) { o << "<null> instruction\n"; return; }
338009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
339009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0,
340009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner			   true);
341009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  AssemblyWriter W(o, SlotTable);
342009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner
343009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner  W.write(I);
344009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}
345