mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-26 07:34:06 +00:00
* Assembly writer is not a module analyzer anymore
* There is no constant pool anymore git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@447 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
30c8979bcb
commit
007377f381
@ -18,6 +18,9 @@
|
|||||||
#include "llvm/ConstPoolVals.h"
|
#include "llvm/ConstPoolVals.h"
|
||||||
#include "llvm/iOther.h"
|
#include "llvm/iOther.h"
|
||||||
#include "llvm/iMemory.h"
|
#include "llvm/iMemory.h"
|
||||||
|
#include "llvm/Support/STLExtras.h"
|
||||||
|
#include "llvm/SymbolTable.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
void DebugValue(const Value *V) {
|
void DebugValue(const Value *V) {
|
||||||
cerr << V << endl;
|
cerr << V << endl;
|
||||||
@ -32,7 +35,7 @@ ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
|
|||||||
if (PrintType)
|
if (PrintType)
|
||||||
Out << " " << V->getType();
|
Out << " " << V->getType();
|
||||||
|
|
||||||
if (V->hasName() && PrintName) {
|
if (PrintName && V->hasName()) {
|
||||||
Out << " %" << V->getName();
|
Out << " %" << V->getName();
|
||||||
} else {
|
} else {
|
||||||
if (const ConstPoolVal *CPV = V->castConstant()) {
|
if (const ConstPoolVal *CPV = V->castConstant()) {
|
||||||
@ -70,7 +73,7 @@ ostream &WriteAsOperand(ostream &Out, const Value *V, bool PrintType,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AssemblyWriter : public ModuleAnalyzer {
|
class AssemblyWriter {
|
||||||
ostream &Out;
|
ostream &Out;
|
||||||
SlotCalculator &Table;
|
SlotCalculator &Table;
|
||||||
public:
|
public:
|
||||||
@ -83,58 +86,62 @@ public:
|
|||||||
inline void write(const Instruction *I) { processInstruction(I); }
|
inline void write(const Instruction *I) { processInstruction(I); }
|
||||||
inline void write(const ConstPoolVal *CPV) { processConstant(CPV); }
|
inline void write(const ConstPoolVal *CPV) { processConstant(CPV); }
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool visitMethod(const Method *M);
|
|
||||||
virtual bool processConstPool(const ConstantPool &CP, bool isMethod);
|
|
||||||
virtual bool processConstant(const ConstPoolVal *CPV);
|
|
||||||
virtual bool processMethod(const Method *M);
|
|
||||||
virtual bool processMethodArgument(const MethodArgument *MA);
|
|
||||||
virtual bool processBasicBlock(const BasicBlock *BB);
|
|
||||||
virtual bool processInstruction(const Instruction *I);
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
void processModule(const Module *M);
|
||||||
|
void processSymbolTable(const SymbolTable &ST);
|
||||||
|
void processConstant(const ConstPoolVal *CPV);
|
||||||
|
void processMethod(const Method *M);
|
||||||
|
void processMethodArgument(const MethodArgument *MA);
|
||||||
|
void processBasicBlock(const BasicBlock *BB);
|
||||||
|
void processInstruction(const Instruction *I);
|
||||||
|
|
||||||
void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
|
void writeOperand(const Value *Op, bool PrintType, bool PrintName = true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
|
||||||
// visitMethod - This member is called after the above two steps, visting each
|
bool PrintName) {
|
||||||
// method, because they are effectively values that go into the constant pool.
|
WriteAsOperand(Out, Operand, PrintType, PrintName, &Table);
|
||||||
//
|
|
||||||
bool AssemblyWriter::visitMethod(const Method *M) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssemblyWriter::processConstPool(const ConstantPool &CP, bool isMethod) {
|
|
||||||
// Done printing arguments...
|
|
||||||
if (isMethod) {
|
|
||||||
const MethodType *MT = CP.getParentV()->castMethodAsserting()->getType()->
|
|
||||||
isMethodType();
|
|
||||||
if (MT->isVarArg()) {
|
|
||||||
if (MT->getParamTypes().size())
|
|
||||||
Out << ", ";
|
|
||||||
Out << "..."; // Output varargs portion of signature!
|
|
||||||
}
|
|
||||||
Out << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleAnalyzer::processConstPool(CP, isMethod);
|
void AssemblyWriter::processModule(const Module *M) {
|
||||||
|
// Loop over the symbol table, emitting all named constants...
|
||||||
if (isMethod) {
|
if (M->hasSymbolTable())
|
||||||
if (!CP.getParentV()->castMethodAsserting()->isExternal())
|
processSymbolTable(*M->getSymbolTable());
|
||||||
Out << "begin";
|
|
||||||
} else {
|
Out << "implementation\n";
|
||||||
Out << "implementation\n";
|
|
||||||
|
// Output all of the methods...
|
||||||
|
for_each(M->begin(), M->end(), bind_obj(this,&AssemblyWriter::processMethod));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// processSymbolTable - Run through symbol table looking for named constants
|
||||||
|
// if a named constant is found, emit it's declaration...
|
||||||
|
//
|
||||||
|
void AssemblyWriter::processSymbolTable(const SymbolTable &ST) {
|
||||||
|
for (SymbolTable::const_iterator TI = ST.begin(); TI != ST.end(); ++TI) {
|
||||||
|
SymbolTable::type_const_iterator I = ST.type_begin(TI->first);
|
||||||
|
SymbolTable::type_const_iterator End = ST.type_end(TI->first);
|
||||||
|
|
||||||
|
for (; I != End; ++I) {
|
||||||
|
const Value *V = I->second;
|
||||||
|
if (const ConstPoolVal *CPV = V->castConstant()) {
|
||||||
|
processConstant(CPV);
|
||||||
|
} else if (const Type *Ty = V->castType()) {
|
||||||
|
Out << "\t%" << I->first << " = type " << Ty->getDescription() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// processConstant - Print out a constant pool entry...
|
// processConstant - Print out a constant pool entry...
|
||||||
//
|
//
|
||||||
bool AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
|
void AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
|
||||||
if (!CPV->hasName())
|
// Don't print out unnamed constants, they will be inlined
|
||||||
return false; // Don't print out unnamed constants, they will be inlined
|
if (!CPV->hasName()) return;
|
||||||
|
|
||||||
// Print out name...
|
// Print out name...
|
||||||
Out << "\t%" << CPV->getName() << " = ";
|
Out << "\t%" << CPV->getName() << " = ";
|
||||||
@ -153,27 +160,50 @@ bool AssemblyWriter::processConstant(const ConstPoolVal *CPV) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Out << endl;
|
Out << endl;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// processMethod - Process all aspects of a method.
|
// processMethod - Process all aspects of a method.
|
||||||
//
|
//
|
||||||
bool AssemblyWriter::processMethod(const Method *M) {
|
void AssemblyWriter::processMethod(const Method *M) {
|
||||||
// Print out the return type and name...
|
// Print out the return type and name...
|
||||||
Out << "\n" << (M->isExternal() ? "declare " : "")
|
Out << "\n" << (M->isExternal() ? "declare " : "")
|
||||||
<< M->getReturnType() << " \"" << M->getName() << "\"(";
|
<< M->getReturnType() << " \"" << M->getName() << "\"(";
|
||||||
Table.incorporateMethod(M);
|
Table.incorporateMethod(M);
|
||||||
ModuleAnalyzer::processMethod(M);
|
|
||||||
Table.purgeMethod();
|
// Loop over the arguments, processing them...
|
||||||
if (!M->isExternal())
|
for_each(M->getArgumentList().begin(), M->getArgumentList().end(),
|
||||||
|
bind_obj(this, &AssemblyWriter::processMethodArgument));
|
||||||
|
|
||||||
|
|
||||||
|
// Finish printing arguments...
|
||||||
|
const MethodType *MT = (const MethodType*)M->getType();
|
||||||
|
if (MT->isVarArg()) {
|
||||||
|
if (MT->getParamTypes().size()) Out << ", ";
|
||||||
|
Out << "..."; // Output varargs portion of signature!
|
||||||
|
}
|
||||||
|
Out << ")\n";
|
||||||
|
|
||||||
|
if (!M->isExternal()) {
|
||||||
|
// Loop over the symbol table, emitting all named constants...
|
||||||
|
if (M->hasSymbolTable())
|
||||||
|
processSymbolTable(*M->getSymbolTable());
|
||||||
|
|
||||||
|
Out << "begin";
|
||||||
|
|
||||||
|
// Output all of its basic blocks... for the method
|
||||||
|
for_each(M->begin(), M->end(),
|
||||||
|
bind_obj(this, &AssemblyWriter::processBasicBlock));
|
||||||
|
|
||||||
Out << "end\n";
|
Out << "end\n";
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
Table.purgeMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
// processMethodArgument - This member is called for every argument that
|
// processMethodArgument - This member is called for every argument that
|
||||||
// is passed into the method. Simply print it out
|
// is passed into the method. Simply print it out
|
||||||
//
|
//
|
||||||
bool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
|
void AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
|
||||||
// Insert commas as we go... the first arg doesn't get a comma
|
// Insert commas as we go... the first arg doesn't get a comma
|
||||||
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
|
if (Arg != Arg->getParent()->getArgumentList().front()) Out << ", ";
|
||||||
|
|
||||||
@ -185,13 +215,11 @@ bool AssemblyWriter::processMethodArgument(const MethodArgument *Arg) {
|
|||||||
Out << " %" << Arg->getName();
|
Out << " %" << Arg->getName();
|
||||||
else if (Table.getValSlot(Arg) < 0)
|
else if (Table.getValSlot(Arg) < 0)
|
||||||
Out << "<badref>";
|
Out << "<badref>";
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// processBasicBlock - This member is called for each basic block in a methd.
|
// processBasicBlock - This member is called for each basic block in a methd.
|
||||||
//
|
//
|
||||||
bool AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
|
void AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
|
||||||
if (BB->hasName()) { // Print out the label if it exists...
|
if (BB->hasName()) { // Print out the label if it exists...
|
||||||
Out << "\n" << BB->getName() << ":";
|
Out << "\n" << BB->getName() << ":";
|
||||||
} else {
|
} else {
|
||||||
@ -204,13 +232,14 @@ bool AssemblyWriter::processBasicBlock(const BasicBlock *BB) {
|
|||||||
}
|
}
|
||||||
Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n"; // Output # uses
|
Out << "\t\t\t\t\t;[#uses=" << BB->use_size() << "]\n"; // Output # uses
|
||||||
|
|
||||||
ModuleAnalyzer::processBasicBlock(BB);
|
// Output all of the instructions in the basic block...
|
||||||
return false;
|
for_each(BB->begin(), BB->end(),
|
||||||
|
bind_obj(this, &AssemblyWriter::processInstruction));
|
||||||
}
|
}
|
||||||
|
|
||||||
// processInstruction - This member is called for each Instruction in a methd.
|
// processInstruction - This member is called for each Instruction in a methd.
|
||||||
//
|
//
|
||||||
bool AssemblyWriter::processInstruction(const Instruction *I) {
|
void AssemblyWriter::processInstruction(const Instruction *I) {
|
||||||
Out << "\t";
|
Out << "\t";
|
||||||
|
|
||||||
// Print out name if it exists...
|
// Print out name if it exists...
|
||||||
@ -313,14 +342,6 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
|
|||||||
Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses
|
Out << "\t[#uses=" << I->use_size() << "]"; // Output # uses
|
||||||
}
|
}
|
||||||
Out << endl;
|
Out << endl;
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
|
|
||||||
bool PrintName) {
|
|
||||||
WriteAsOperand(Out, Operand, PrintType, PrintName, &Table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user