#include "llvm/iOther.h"
#include "llvm/iMemory.h"
+void DebugValue(const Value *V) {
+ cerr << V << endl;
+}
+
+// WriteAsOperand - Write the name of the specified value out to the specified
+// ostream. This can be useful when you just want to print int %reg126, not the
+// whole instruction that generated it.
+//
+ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
+ bool PrintName, SlotCalculator *Table) {
+ if (PrintType)
+ Out << " " << V->getType();
+
+ if (V->hasName() && PrintName) {
+ Out << " %" << V->getName();
+ } else {
+ if (const ConstPoolVal *CPV = V->castConstant()) {
+ Out << " " << CPV->getStrValue();
+ } else {
+ int Slot;
+ if (Table) {
+ Slot = Table->getValSlot(V);
+ } else {
+ if (const Type *Ty = V->castType()) {
+ return Out << " " << Ty;
+ } else if (const MethodArgument *MA = V->castMethodArgument()) {
+ Table = new SlotCalculator(MA->getParent(), true);
+ } else if (const Instruction *I = V->castInstruction()) {
+ Table = new SlotCalculator(I->getParent()->getParent(), true);
+ } else if (const BasicBlock *BB = V->castBasicBlock()) {
+ Table = new SlotCalculator(BB->getParent(), true);
+ } else if (const Method *Meth = V->castMethod()) {
+ Table = new SlotCalculator(Meth, true);
+ } else if (const Module *Mod = V->castModule()) {
+ Table = new SlotCalculator(Mod, true);
+ } else {
+ return Out << "BAD VALUE TYPE!";
+ }
+ Slot = Table->getValSlot(V);
+ delete Table;
+ }
+ if (Slot >= 0) Out << " %" << Slot;
+ else if (PrintName)
+ Out << "<badref>"; // Not embeded into a location?
+ }
+ }
+ return Out;
+}
+
+
+
class AssemblyWriter : public ModuleAnalyzer {
ostream &Out;
SlotCalculator &Table;
ModuleAnalyzer::processConstPool(CP, isMethod);
- if (isMethod)
- Out << "begin";
- else
+ if (isMethod) {
+ if (!CP.getParentV()->castMethodAsserting()->isExternal())
+ Out << "begin";
+ } else {
Out << "implementation\n";
+ }
return false;
}
//
bool AssemblyWriter::processMethod(const Method *M) {
// Print out the return type and name...
- Out << "\n" << M->getReturnType() << " \"" << M->getName() << "\"(";
+ Out << "\n" << (M->isExternal() ? "declare " : "")
+ << M->getReturnType() << " \"" << M->getName() << "\"(";
Table.incorporateMethod(M);
ModuleAnalyzer::processMethod(M);
Table.purgeMethod();
- Out << "end\n";
+ if (!M->isExternal())
+ Out << "end\n";
return false;
}
Out << "%" << I->getName() << " = ";
// Print out the opcode...
- Out << I->getOpcode();
+ Out << I->getOpcodeName();
// Print out the type of the operands...
const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
// Special case conditional branches to swizzle the condition out to the front
- if (I->getInstType() == Instruction::Br && I->getNumOperands() > 1) {
+ if (I->getOpcode() == Instruction::Br && I->getNumOperands() > 1) {
writeOperand(I->getOperand(2), true);
Out << ",";
writeOperand(Operand, true);
Out << ",";
writeOperand(I->getOperand(1), true);
- } else if (I->getInstType() == Instruction::Switch) {
+ } else if (I->getOpcode() == Instruction::Switch) {
// Special case switch statement to get formatting nice and correct...
writeOperand(Operand , true); Out << ",";
writeOperand(I->getOperand(1), true); Out << " [";
writeOperand(I->getOperand(op ), false); Out << ",";
writeOperand(I->getOperand(op+1), false); Out << " ]";
}
- } else if (I->getInstType() == Instruction::Ret && !Operand) {
+ } else if (I->getOpcode() == Instruction::Ret && !Operand) {
Out << " void";
- } else if (I->getInstType() == Instruction::Call) {
+ } else if (I->getOpcode() == Instruction::Call) {
writeOperand(Operand, true);
Out << "(";
if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
}
Out << " )";
- } else if (I->getInstType() == Instruction::Malloc ||
- I->getInstType() == Instruction::Alloca) {
+ } else if (I->getOpcode() == Instruction::Malloc ||
+ I->getOpcode() == Instruction::Alloca) {
Out << " " << ((const PointerType*)I->getType())->getValueType();
if (I->getNumOperands()) {
Out << ",";
writeOperand(I->getOperand(0), true);
}
-
+ } else if (I->getOpcode() == Instruction::Cast) {
+ writeOperand(Operand, true);
+ Out << " to " << I->getType();
} else if (Operand) { // Print the normal way...
// PrintAllTypes - Instructions who have operands of all the same type
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
bool PrintName) {
- if (PrintType)
- Out << " " << Operand->getType();
-
- if (Operand->hasName() && PrintName) {
- Out << " %" << Operand->getName();
- } else {
- int Slot = Table.getValSlot(Operand);
-
- if (const ConstPoolVal *CPV = Operand->castConstant()) {
- Out << " " << CPV->getStrValue();
- } else {
- if (Slot >= 0) Out << " %" << Slot;
- else if (PrintName)
- Out << "<badref>"; // Not embeded into a location?
- }
- }
+ WriteAsOperand(Out, Operand, PrintType, PrintName, &Table);
}
// A Constant pool value may have a parent that is either a method or a
// module. Untangle this now...
//
- if (CPV->getParent() == 0 || CPV->getParent()->isMethod()) {
- SlotTable = new SlotCalculator((Method*)CPV->getParent(), true);
+ if (const Method *Meth = CPV->getParentV()->castMethod()) {
+ SlotTable = new SlotCalculator(Meth, true);
} else {
SlotTable =
- new SlotCalculator(CPV->getParent()->castModuleAsserting(), true);
+ new SlotCalculator(CPV->getParentV()->castModuleAsserting(), true);
}
AssemblyWriter W(o, *SlotTable);