AsmWriter.cpp revision 007377f381e253cc559db8d3c94fa89b0eb55fad
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" 21007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include "llvm/Support/STLExtras.h" 22007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include "llvm/SymbolTable.h" 23007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner#include <algorithm> 24009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 25d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattnervoid DebugValue(const Value *V) { 26d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner cerr << V << endl; 27d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner} 28d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner 29622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// WriteAsOperand - Write the name of the specified value out to the specified 30622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// ostream. This can be useful when you just want to print int %reg126, not the 31622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// whole instruction that generated it. 32622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner// 33622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattnerostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType, 34622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner bool PrintName, SlotCalculator *Table) { 35622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner if (PrintType) 36622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Out << " " << V->getType(); 37622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner 38007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (PrintName && V->hasName()) { 39622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Out << " %" << V->getName(); 40622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else { 41622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner if (const ConstPoolVal *CPV = V->castConstant()) { 42622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Out << " " << CPV->getStrValue(); 43622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else { 44622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner int Slot; 45622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner if (Table) { 46622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Slot = Table->getValSlot(V); 47622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else { 48622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner if (const Type *Ty = V->castType()) { 49622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner return Out << " " << Ty; 50622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else if (const MethodArgument *MA = V->castMethodArgument()) { 51622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Table = new SlotCalculator(MA->getParent(), true); 52622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else if (const Instruction *I = V->castInstruction()) { 53622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Table = new SlotCalculator(I->getParent()->getParent(), true); 54622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else if (const BasicBlock *BB = V->castBasicBlock()) { 55622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Table = new SlotCalculator(BB->getParent(), true); 56622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else if (const Method *Meth = V->castMethod()) { 57622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Table = new SlotCalculator(Meth, true); 58622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else if (const Module *Mod = V->castModule()) { 59622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Table = new SlotCalculator(Mod, true); 60622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } else { 61622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner return Out << "BAD VALUE TYPE!"; 62622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } 63622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Slot = Table->getValSlot(V); 64622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner delete Table; 65622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } 66622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner if (Slot >= 0) Out << " %" << Slot; 67622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner else if (PrintName) 68622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner Out << "<badref>"; // Not embeded into a location? 69622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } 70622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner } 71622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner return Out; 72622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner} 73622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner 74622f740a7dcf0b3520244e58b2233898fd4a46e4Chris Lattner 75d8c2e42aeff8bdb3ac905b4721b3d3ca1f904cfaChris Lattner 76007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnerclass AssemblyWriter { 77009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner ostream &Out; 78009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator &Table; 79009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerpublic: 80009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline AssemblyWriter(ostream &o, SlotCalculator &Tab) : Out(o), Table(Tab) { 81009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 82009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 83009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Module *M) { processModule(M); } 84009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Method *M) { processMethod(M); } 85009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const BasicBlock *BB) { processBasicBlock(BB); } 86009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const Instruction *I) { processInstruction(I); } 87009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner inline void write(const ConstPoolVal *CPV) { processConstant(CPV); } 88009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 89009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnerprivate : 90007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processModule(const Module *M); 91007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processSymbolTable(const SymbolTable &ST); 92007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processConstant(const ConstPoolVal *CPV); 93007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processMethod(const Method *M); 94007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processMethodArgument(const MethodArgument *MA); 95007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processBasicBlock(const BasicBlock *BB); 96007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner void processInstruction(const Instruction *I); 97007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 98009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner void writeOperand(const Value *Op, bool PrintType, bool PrintName = true); 99009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner}; 100009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 101009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 102007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::writeOperand(const Value *Operand, bool PrintType, 103007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner bool PrintName) { 104007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner WriteAsOperand(Out, Operand, PrintType, PrintName, &Table); 105007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner} 106007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 107007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 108007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processModule(const Module *M) { 109007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Loop over the symbol table, emitting all named constants... 110007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (M->hasSymbolTable()) 111007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner processSymbolTable(*M->getSymbolTable()); 112009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 113007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Out << "implementation\n"; 114007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 115007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Output all of the methods... 116007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::processMethod)); 117009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 118009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 119009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 120007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// processSymbolTable - Run through symbol table looking for named constants 121007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// if a named constant is found, emit it's declaration... 122007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner// 123007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processSymbolTable(const SymbolTable &ST) { 124007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) { 125007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner SymbolTable::type_const_iterator I = ST.type_begin(TI->first); 126007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner SymbolTable::type_const_iterator End = ST.type_end(TI->first); 127007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 128007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for (; I != End; ++I) { 129007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner const Value *V = I->second; 130007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (const ConstPoolVal *CPV = V->castConstant()) { 131007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner processConstant(CPV); 132007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner } else if (const Type *Ty = V->castType()) { 133007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl; 134007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner } 135007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner } 136739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner } 137009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 138009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 139009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 140009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processConstant - Print out a constant pool entry... 141009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 142007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processConstant(const ConstPoolVal *CPV) { 143007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Don't print out unnamed constants, they will be inlined 144007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (!CPV->hasName()) return; 145009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 1461333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner // Print out name... 1471333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner Out << "\t%" << CPV->getName() << " = "; 148009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 1491333ed5b4fd3d30ba9ef56741af4d345a9e43953Chris Lattner // Print out the constant type... 150009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << CPV->getType(); 151009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 152009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Write the value out now... 153009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(CPV, false, false); 154009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 155009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!CPV->hasName() && CPV->getType() != Type::VoidTy) { 156009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner int Slot = Table.getValSlot(CPV); // Print out the def slot taken... 157009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t\t; <" << CPV->getType() << ">:"; 158009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Slot >= 0) Out << Slot; 159009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else Out << "<badref>"; 160009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 161009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 162009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << endl; 163009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 164009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 165009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethod - Process all aspects of a method. 166009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 167007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processMethod(const Method *M) { 168009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the return type and name... 169739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner Out << "\n" << (M->isExternal() ? "declare " : "") 170739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner << M->getReturnType() << " \"" << M->getName() << "\"("; 171009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Table.incorporateMethod(M); 172007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 173007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Loop over the arguments, processing them... 174007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for_each(M->getArgumentList().begin(), M->getArgumentList().end(), 175007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner bind_obj(this, &AssemblyWriter::processMethodArgument)); 176007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 177007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 178007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Finish printing arguments... 179007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner const MethodType *MT = (const MethodType*)M->getType(); 180007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (MT->isVarArg()) { 181007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (MT->getParamTypes().size()) Out << ", "; 182007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Out << "..."; // Output varargs portion of signature! 183007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner } 184007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Out << ")\n"; 185007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 186007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (!M->isExternal()) { 187007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Loop over the symbol table, emitting all named constants... 188007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner if (M->hasSymbolTable()) 189007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner processSymbolTable(*M->getSymbolTable()); 190007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 191007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Out << "begin"; 192007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 193007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Output all of its basic blocks... for the method 194007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for_each(M->begin(), M->end(), 195007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner bind_obj(this, &AssemblyWriter::processBasicBlock)); 196007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 197739a56d26ddd76f7d073745d8be25c53cf39dce5Chris Lattner Out << "end\n"; 198007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner } 199007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner 200007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner Table.purgeMethod(); 201009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 202009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 203009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processMethodArgument - This member is called for every argument that 204009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// is passed into the method. Simply print it out 205009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 206007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processMethodArgument(const MethodArgument *Arg) { 207009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Insert commas as we go... the first arg doesn't get a comma 208009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", "; 209009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 210009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Output type... 211009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << Arg->getType(); 212009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 213009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Output name, if available... 214009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Arg->hasName()) 215009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " %" << Arg->getName(); 216009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else if (Table.getValSlot(Arg) < 0) 217009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "<badref>"; 218009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 219009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 220009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processBasicBlock - This member is called for each basic block in a methd. 221009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 222007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processBasicBlock(const BasicBlock *BB) { 223009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (BB->hasName()) { // Print out the label if it exists... 224b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\n" << BB->getName() << ":"; 225009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else { 226009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner int Slot = Table.getValSlot(BB); 227b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\n; <label>:"; 228009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Slot >= 0) 229b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << Slot; // Extra newline seperates out label's 230009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner else 231b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "<badref>"; 232009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 233b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n"; // Output # uses 234009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 235007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner // Output all of the instructions in the basic block... 236007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner for_each(BB->begin(), BB->end(), 237007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattner bind_obj(this, &AssemblyWriter::processInstruction)); 238009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 239009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 240009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// processInstruction - This member is called for each Instruction in a methd. 241009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// 242007377f381e253cc559db8d3c94fa89b0eb55fadChris Lattnervoid AssemblyWriter::processInstruction(const Instruction *I) { 243009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t"; 244009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 245009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out name if it exists... 246009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (I && I->hasName()) 247009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "%" << I->getName() << " = "; 248009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 249009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the opcode... 250a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner Out << I->getOpcodeName(); 251009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 252009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print out the type of the operands... 253c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0; 254009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 255009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Special case conditional branches to swizzle the condition out to the front 256a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) { 257009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(2), true); 258009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 259009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand, true); 260009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 261009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(1), true); 262009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 263a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Switch) { 264009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Special case switch statement to get formatting nice and correct... 265009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand , true); Out << ","; 266009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(1), true); Out << " ["; 267009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 268c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { 269009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\n\t\t"; 270c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op ), true); Out << ","; 271009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(I->getOperand(op+1), true); 272009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 273009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\n\t]"; 2747fc9fe34390c66ca58646d09a87f7dbaacb6c1f8Chris Lattner } else if (I->isPHINode()) { 275c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner Out << " " << Operand->getType(); 276009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 277c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner Out << " ["; writeOperand(Operand, false); Out << ","; 27828d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner writeOperand(I->getOperand(1), false); Out << " ]"; 279c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) { 280c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << ", ["; 281c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op ), false); Out << ","; 28228d480b31623371e9d738d17a62dd0bd6cdce1cdChris Lattner writeOperand(I->getOperand(op+1), false); Out << " ]"; 283c24d2088dc3d79e3b7e38a358b4a71f156c06836Chris Lattner } 284a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Ret && !Operand) { 285009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " void"; 286a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Call) { 287009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner writeOperand(Operand, true); 288009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "("; 289c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true); 290c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) { 291009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << ","; 292c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(op), true); 293009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 294009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 295009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " )"; 296a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner } else if (I->getOpcode() == Instruction::Malloc || 297a41f50dea8573e4a610b5aa5e45b5c368559b084Chris Lattner I->getOpcode() == Instruction::Alloca) { 298c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << " " << ((const PointerType*)I->getType())->getValueType(); 299c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner if (I->getNumOperands()) { 300c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Out << ","; 301c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(0), true); 302009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 3030908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner } else if (I->getOpcode() == Instruction::Cast) { 3040908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner writeOperand(Operand, true); 3050908309e3c4b4f423e88d8d8fe8060cb10eaa1c9Chris Lattner Out << " to " << I->getType(); 306009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } else if (Operand) { // Print the normal way... 307009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 308009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // PrintAllTypes - Instructions who have operands of all the same type 309009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // omit the type from all but the first operand. If the instruction has 310009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // different type operands (for example br), then they are all printed. 311009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner bool PrintAllTypes = false; 312009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner const Type *TheType = Operand->getType(); 313009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 314c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) { 315c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner Operand = I->getOperand(i); 316009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (Operand->getType() != TheType) { 317009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner PrintAllTypes = true; // We have differing types! Print them all! 318009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner break; 319009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 320009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 321009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 322009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (!PrintAllTypes) 323009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << " " << I->getOperand(0)->getType(); 324009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 325c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) { 326009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (i) Out << ","; 327c8b25d40cbec063b1ca99cc1adf794399c6d05c0Chris Lattner writeOperand(I->getOperand(i), PrintAllTypes); 328009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 329009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 330009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 331009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // Print a little comment after the instruction indicating which slot it 332009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // occupies. 333009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner // 334b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (I->getType() != Type::VoidTy) { 335b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner Out << "\t\t; <" << I->getType() << ">"; 336009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 337b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (!I->hasName()) { 338b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner int Slot = Table.getValSlot(I); // Print out the def slot taken... 339b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner if (Slot >= 0) Out << ":" << Slot; 340b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner else Out << ":<badref>"; 341b9a4578df5e240d2e2e5d3f1f538188a054d70b4Chris Lattner } 342009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses 343009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner } 344009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner Out << endl; 345009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 346009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 347009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 348009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 349009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner// External Interface declarations 350009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner//===----------------------------------------------------------------------===// 351009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 352009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 353009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 354009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Module *M, ostream &o) { 355009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (M == 0) { o << "<null> module\n"; return; } 356009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(M, true); 357009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 358009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 359009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(M); 360009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 361009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 362009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Method *M, ostream &o) { 363009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (M == 0) { o << "<null> method\n"; return; } 364009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(M->getParent(), true); 365009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 366009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 367009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(M); 368009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 369009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 370009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 371009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const BasicBlock *BB, ostream &o) { 372009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (BB == 0) { o << "<null> basic block\n"; return; } 373009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 374009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(BB->getParent(), true); 375009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 376009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 377009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(BB); 378009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 379009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 380009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const ConstPoolVal *CPV, ostream &o) { 381009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (CPV == 0) { o << "<null> constant pool value\n"; return; } 38281e29632f70bcd789af6d27b4622ea3cba162abaChris Lattner WriteAsOperand(o, CPV, true, true, 0); 383009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 384009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 385009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattnervoid WriteToAssembly(const Instruction *I, ostream &o) { 386009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner if (I == 0) { o << "<null> instruction\n"; return; } 387009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 388009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner SlotCalculator SlotTable(I->getParent() ? I->getParent()->getParent() : 0, 389009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner true); 390009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner AssemblyWriter W(o, SlotTable); 391009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner 392009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner W.write(I); 393009505452b713ed2e3a8e99c5545a6e721c65495Chris Lattner} 394