mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
First complete version of llvm2cpp that doesn't crash on any of the Feature
tests. The output in a few cases still doesn't compile, however. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28547 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
40932272c7
commit
66c873479f
@ -26,6 +26,7 @@
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -33,6 +34,7 @@ namespace {
|
||||
typedef std::vector<const Type*> TypeList;
|
||||
typedef std::map<const Type*,std::string> TypeMap;
|
||||
typedef std::map<const Value*,std::string> ValueMap;
|
||||
typedef std::set<std::string> NameSet;
|
||||
|
||||
class CppWriter {
|
||||
std::ostream &Out;
|
||||
@ -42,6 +44,7 @@ class CppWriter {
|
||||
ValueMap ValueNames;
|
||||
TypeMap UnresolvedTypes;
|
||||
TypeList TypeStack;
|
||||
NameSet UsedNames;
|
||||
|
||||
public:
|
||||
inline CppWriter(std::ostream &o, const Module *M)
|
||||
@ -57,7 +60,8 @@ private:
|
||||
void printConstants(const Module* M);
|
||||
void printConstant(const Constant *CPV);
|
||||
void printGlobal(const GlobalVariable *GV);
|
||||
void printFunction(const Function *F);
|
||||
void printFunctionHead(const Function *F);
|
||||
void printFunctionBody(const Function *F);
|
||||
void printInstruction(const Instruction *I, const std::string& bbname);
|
||||
void printSymbolTable(const SymbolTable &ST);
|
||||
void printLinkageType(GlobalValue::LinkageTypes LT);
|
||||
@ -89,39 +93,57 @@ CppWriter::printEscapedString(const std::string &Str) {
|
||||
}
|
||||
}
|
||||
|
||||
inline const char*
|
||||
getTypePrefix(const Type* Ty ) {
|
||||
const char* prefix;
|
||||
switch (Ty->getTypeID()) {
|
||||
case Type::VoidTyID: prefix = "void_"; break;
|
||||
case Type::BoolTyID: prefix = "bool_"; break;
|
||||
case Type::UByteTyID: prefix = "ubyte_"; break;
|
||||
case Type::SByteTyID: prefix = "sbyte_"; break;
|
||||
case Type::UShortTyID: prefix = "ushort_"; break;
|
||||
case Type::ShortTyID: prefix = "short_"; break;
|
||||
case Type::UIntTyID: prefix = "uint_"; break;
|
||||
case Type::IntTyID: prefix = "int_"; break;
|
||||
case Type::ULongTyID: prefix = "ulong_"; break;
|
||||
case Type::LongTyID: prefix = "long_"; break;
|
||||
case Type::FloatTyID: prefix = "float_"; break;
|
||||
case Type::DoubleTyID: prefix = "double_"; break;
|
||||
case Type::LabelTyID: prefix = "label_"; break;
|
||||
case Type::FunctionTyID: prefix = "func_"; break;
|
||||
case Type::StructTyID: prefix = "struct_"; break;
|
||||
case Type::ArrayTyID: prefix = "array_"; break;
|
||||
case Type::PointerTyID: prefix = "ptr_"; break;
|
||||
case Type::PackedTyID: prefix = "packed_"; break;
|
||||
case Type::OpaqueTyID: prefix = "opaque_"; break;
|
||||
default: prefix = "other_"; break;
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
std::string
|
||||
CppWriter::getCppName(const Value* val) {
|
||||
std::string name;
|
||||
ValueMap::iterator I = ValueNames.find(val);
|
||||
if (I != ValueNames.end()) {
|
||||
name = I->second;
|
||||
if (I != ValueNames.end() && I->first == val)
|
||||
return I->second;
|
||||
|
||||
if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
|
||||
name = std::string("gvar_") +
|
||||
getTypePrefix(GV->getType()->getElementType());
|
||||
} else if (const Function* F = dyn_cast<Function>(val)) {
|
||||
name = std::string("func_");
|
||||
} else if (const Constant* C = dyn_cast<Constant>(val)) {
|
||||
name = std::string("const_") + getTypePrefix(C->getType());
|
||||
} else {
|
||||
const char* prefix;
|
||||
switch (val->getType()->getTypeID()) {
|
||||
case Type::VoidTyID: prefix = "void_"; break;
|
||||
case Type::BoolTyID: prefix = "bool_"; break;
|
||||
case Type::UByteTyID: prefix = "ubyte_"; break;
|
||||
case Type::SByteTyID: prefix = "sbyte_"; break;
|
||||
case Type::UShortTyID: prefix = "ushort_"; break;
|
||||
case Type::ShortTyID: prefix = "short_"; break;
|
||||
case Type::UIntTyID: prefix = "uint_"; break;
|
||||
case Type::IntTyID: prefix = "int_"; break;
|
||||
case Type::ULongTyID: prefix = "ulong_"; break;
|
||||
case Type::LongTyID: prefix = "long_"; break;
|
||||
case Type::FloatTyID: prefix = "float_"; break;
|
||||
case Type::DoubleTyID: prefix = "double_"; break;
|
||||
case Type::LabelTyID: prefix = "label_"; break;
|
||||
case Type::FunctionTyID: prefix = "func_"; break;
|
||||
case Type::StructTyID: prefix = "struct_"; break;
|
||||
case Type::ArrayTyID: prefix = "array_"; break;
|
||||
case Type::PointerTyID: prefix = "ptr_"; break;
|
||||
case Type::PackedTyID: prefix = "packed_"; break;
|
||||
default: prefix = "other_"; break;
|
||||
}
|
||||
name = ValueNames[val] = std::string(prefix) +
|
||||
(val->hasName() ? val->getName() : utostr(uniqueNum++));
|
||||
name = getTypePrefix(val->getType());
|
||||
}
|
||||
return name;
|
||||
name += (val->hasName() ? val->getName() : utostr(uniqueNum++));
|
||||
NameSet::iterator NI = UsedNames.find(name);
|
||||
if (NI != UsedNames.end())
|
||||
name += std::string("_") + utostr(uniqueNum++);
|
||||
UsedNames.insert(name);
|
||||
return ValueNames[val] = name;
|
||||
}
|
||||
|
||||
void
|
||||
@ -246,32 +268,42 @@ void CppWriter::printModule(const Module *M) {
|
||||
printTypes(M);
|
||||
|
||||
// Print out all the constants declarations
|
||||
Out << "\n// Constants Construction\n";
|
||||
Out << "\n// Constant Definitions\n";
|
||||
printConstants(M);
|
||||
|
||||
// Process the global variables
|
||||
Out << "\n// Global Variable Construction\n";
|
||||
Out << "\n// Global Variable Definitions\n";
|
||||
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
|
||||
I != E; ++I) {
|
||||
printGlobal(I);
|
||||
}
|
||||
|
||||
// Output all of the functions.
|
||||
Out << "\n// Function Construction\n";
|
||||
// Functions can call each other so define all the functions first before
|
||||
// emitting their function bodies.
|
||||
Out << "\n// Function Declarations\n";
|
||||
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I)
|
||||
printFunction(I);
|
||||
printFunctionHead(I);
|
||||
|
||||
// Output all of the function bodies.
|
||||
Out << "\n// Function Definitions\n";
|
||||
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
|
||||
Out << "\n// Function: " << I->getName() << "(" << getCppName(I) << ")\n";
|
||||
Out << "{\n";
|
||||
printFunctionBody(I);
|
||||
Out << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CppWriter::printCallingConv(unsigned cc){
|
||||
// Print the calling convention.
|
||||
switch (cc) {
|
||||
default:
|
||||
case CallingConv::C: Out << "CallingConv::C"; break;
|
||||
case CallingConv::CSRet: Out << "CallingConv::CSRet"; break;
|
||||
case CallingConv::Fast: Out << "CallingConv::Fast"; break;
|
||||
case CallingConv::Cold: Out << "CallingConv::Cold"; break;
|
||||
case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
|
||||
default: Out << cc; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -643,7 +675,7 @@ void CppWriter::printConstant(const Constant *CV) {
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
printConstant(CS->getOperand(i));
|
||||
Out << constName << "_fields.push_back("
|
||||
<< getCppName(CA->getOperand(i)) << ");\n";
|
||||
<< getCppName(CS->getOperand(i)) << ");\n";
|
||||
}
|
||||
Out << "Constant* " << constName << " = ConstantStruct::get("
|
||||
<< typeName << ", " << constName << "_fields);";
|
||||
@ -712,14 +744,9 @@ void CppWriter::printConstant(const Constant *CV) {
|
||||
Out << "\n";
|
||||
}
|
||||
|
||||
/// printFunction - Print all aspects of a function.
|
||||
///
|
||||
void CppWriter::printFunction(const Function *F) {
|
||||
std::string funcTypeName(getCppName(F->getFunctionType()));
|
||||
|
||||
Out << "Function* ";
|
||||
printCppName(F);
|
||||
Out << " = new Function(" << funcTypeName << ", " ;
|
||||
void CppWriter::printFunctionHead(const Function* F) {
|
||||
Out << "Function* " << getCppName(F) << " = new Function("
|
||||
<< getCppName(F->getFunctionType()) << ", " ;
|
||||
printLinkageType(F->getLinkage());
|
||||
Out << ",\n \"" << F->getName() << "\", mod);\n";
|
||||
printCppName(F);
|
||||
@ -734,39 +761,44 @@ void CppWriter::printFunction(const Function *F) {
|
||||
printCppName(F);
|
||||
Out << "->setAlignment(" << F->getAlignment() << ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (!F->isExternal()) {
|
||||
Out << "{\n";
|
||||
// Create all the argument values
|
||||
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
|
||||
AI != AE; ++AI) {
|
||||
Out << " Argument* " << getCppName(AI) << " = new Argument("
|
||||
<< getCppName(AI->getType()) << ", \"";
|
||||
printEscapedString(AI->getName());
|
||||
Out << "\", " << getCppName(F) << ");\n";
|
||||
}
|
||||
// Create all the basic blocks
|
||||
for (Function::const_iterator BI = F->begin(), BE = F->end();
|
||||
BI != BE; ++BI) {
|
||||
void CppWriter::printFunctionBody(const Function *F) {
|
||||
if (F->isExternal())
|
||||
return; // external functions have no bodies.
|
||||
|
||||
// Create all the argument values
|
||||
if (!F->arg_empty()) {
|
||||
Out << " Function::arg_iterator args = " << getCppName(F)
|
||||
<< "->arg_begin();\n";
|
||||
}
|
||||
for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
|
||||
AI != AE; ++AI) {
|
||||
Out << " Value* " << getCppName(AI) << " = args++;\n";
|
||||
if (AI->hasName())
|
||||
Out << " " << getCppName(AI) << "->setName(\"" << AI->getName()
|
||||
<< "\");\n";
|
||||
}
|
||||
|
||||
// Create all the basic blocks
|
||||
for (Function::const_iterator BI = F->begin(), BE = F->end();
|
||||
BI != BE; ++BI) {
|
||||
std::string bbname(getCppName(BI));
|
||||
Out << " BasicBlock* " << bbname << " = new BasicBlock(\"";
|
||||
if (BI->hasName())
|
||||
printEscapedString(BI->getName());
|
||||
Out << "\"," << getCppName(BI->getParent()) << ",0);\n";
|
||||
}
|
||||
|
||||
// Output all of its basic blocks... for the function
|
||||
for (Function::const_iterator BI = F->begin(), BE = F->end();
|
||||
BI != BE; ++BI) {
|
||||
// Output all of the instructions in the basic block...
|
||||
for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
|
||||
I != E; ++I) {
|
||||
std::string bbname(getCppName(BI));
|
||||
Out << " BasicBlock* " << bbname << " = new BasicBlock(\"";
|
||||
if (BI->hasName())
|
||||
printEscapedString(BI->getName());
|
||||
Out << "\"," << getCppName(BI->getParent()) << ",0);\n";
|
||||
printInstruction(I,bbname);
|
||||
}
|
||||
// Output all of its basic blocks... for the function
|
||||
for (Function::const_iterator BI = F->begin(), BE = F->end();
|
||||
BI != BE; ++BI) {
|
||||
// Output all of the instructions in the basic block...
|
||||
Out << " {\n";
|
||||
for (BasicBlock::const_iterator I = BI->begin(), E = BI->end();
|
||||
I != E; ++I) {
|
||||
std::string bbname(getCppName(BI));
|
||||
printInstruction(I,bbname);
|
||||
}
|
||||
Out << " }\n";
|
||||
}
|
||||
Out << "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -779,7 +811,7 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::Ret: {
|
||||
const ReturnInst* ret = cast<ReturnInst>(I);
|
||||
Out << " ReturnInst* " << iName << " = new ReturnInst(";
|
||||
Out << " ReturnInst* " << iName << " = new ReturnInst(";
|
||||
if (ret->getReturnValue())
|
||||
Out << getCppName(ret->getReturnValue()) << ", ";
|
||||
Out << bbname << ");";
|
||||
@ -787,7 +819,7 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
}
|
||||
case Instruction::Br: {
|
||||
const BranchInst* br = cast<BranchInst>(I);
|
||||
Out << " BranchInst* " << iName << " = new BranchInst(" ;
|
||||
Out << " BranchInst* " << iName << " = new BranchInst(" ;
|
||||
if (br->getNumOperands() == 3 ) {
|
||||
Out << getCppName(br->getOperand(0)) << ", "
|
||||
<< getCppName(br->getOperand(1)) << ", "
|
||||
@ -801,10 +833,47 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
Out << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Switch:
|
||||
case Instruction::Invoke:
|
||||
case Instruction::Unwind:
|
||||
case Instruction::Unreachable:
|
||||
case Instruction::Switch: {
|
||||
const SwitchInst* sw = cast<SwitchInst>(I);
|
||||
Out << " SwitchInst* " << iName << " = new SwitchInst("
|
||||
<< getCppName(sw->getOperand(0)) << ", "
|
||||
<< getCppName(sw->getOperand(1)) << ", "
|
||||
<< sw->getNumCases() << ", " << bbname << ");";
|
||||
for (unsigned i = 1; i < sw->getNumCases(); i++ ) {
|
||||
Out << " " << iName << "->addCase("
|
||||
<< getCppName(sw->getCaseValue(i)) << ", "
|
||||
<< getCppName(sw->getSuccessor(i)) << ");\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Instruction::Invoke: {
|
||||
const InvokeInst* inv = cast<InvokeInst>(I);
|
||||
Out << " std::vector<Value*> " << iName << "_params;\n";
|
||||
for (unsigned i = 3; i < inv->getNumOperands(); ++i)
|
||||
Out << " " << iName << "_params.push_back("
|
||||
<< getCppName(inv->getOperand(i)) << ");\n";
|
||||
Out << " InvokeInst* " << iName << " = new InvokeInst("
|
||||
<< getCppName(inv->getCalledFunction()) << ", "
|
||||
<< getCppName(inv->getNormalDest()) << ", "
|
||||
<< getCppName(inv->getUnwindDest()) << ", "
|
||||
<< iName << "_params, \"";
|
||||
printEscapedString(inv->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
Out << iName << "->setCallingConv(";
|
||||
printCallingConv(inv->getCallingConv());
|
||||
Out << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Unwind: {
|
||||
Out << " UnwindInst* " << iName << " = new UnwindInst("
|
||||
<< bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Unreachable:{
|
||||
Out << " UnreachableInst* " << iName << " = new UnreachableInst("
|
||||
<< bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Add:
|
||||
case Instruction::Sub:
|
||||
case Instruction::Mul:
|
||||
@ -813,16 +882,53 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:{
|
||||
Out << " BinaryOperator* " << iName << " = BinaryOperator::create(";
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::Add: Out << "Instruction::Add"; break;
|
||||
case Instruction::Sub: Out << "Instruction::Sub"; break;
|
||||
case Instruction::Mul: Out << "Instruction::Mul"; break;
|
||||
case Instruction::Div: Out << "Instruction::Div"; break;
|
||||
case Instruction::Rem: Out << "Instruction::Rem"; break;
|
||||
case Instruction::And: Out << "Instruction::And"; break;
|
||||
case Instruction::Or: Out << "Instruction::Or"; break;
|
||||
case Instruction::Xor: Out << "Instruction::Xor"; break;
|
||||
case Instruction::Shl: Out << "Instruction::Shl"; break;
|
||||
case Instruction::Shr: Out << "Instruction::Shr"; break;
|
||||
default: Out << "Instruction::BadOpCode"; break;
|
||||
}
|
||||
Out << ", " << getCppName(I->getOperand(0));
|
||||
Out << ", " << getCppName(I->getOperand(1)) << ", \"";
|
||||
printEscapedString(I->getName());
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::SetEQ:
|
||||
case Instruction::SetNE:
|
||||
case Instruction::SetLE:
|
||||
case Instruction::SetGE:
|
||||
case Instruction::SetLT:
|
||||
case Instruction::SetGT:
|
||||
break;
|
||||
case Instruction::SetGT: {
|
||||
Out << " SetCondInst* " << iName << " = new SetCondInst(";
|
||||
switch (I->getOpcode()) {
|
||||
case Instruction::SetEQ: Out << "Instruction::SetEQ"; break;
|
||||
case Instruction::SetNE: Out << "Instruction::SetNE"; break;
|
||||
case Instruction::SetLE: Out << "Instruction::SetLE"; break;
|
||||
case Instruction::SetGE: Out << "Instruction::SetGE"; break;
|
||||
case Instruction::SetLT: Out << "Instruction::SetLT"; break;
|
||||
case Instruction::SetGT: Out << "Instruction::SetGT"; break;
|
||||
default: Out << "Instruction::BadOpCode"; break;
|
||||
}
|
||||
Out << ", " << getCppName(I->getOperand(0));
|
||||
Out << ", " << getCppName(I->getOperand(1)) << ", \"";
|
||||
printEscapedString(I->getName());
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Malloc: {
|
||||
const MallocInst* mallocI = cast<MallocInst>(I);
|
||||
Out << " MallocInst* " << iName << " = new MallocInst("
|
||||
Out << " MallocInst* " << iName << " = new MallocInst("
|
||||
<< getCppName(mallocI->getAllocatedType()) << ", ";
|
||||
if (mallocI->isArrayAllocation())
|
||||
Out << getCppName(mallocI->getArraySize()) << ", ";
|
||||
@ -834,10 +940,14 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
<< mallocI->getAlignment() << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Free:
|
||||
case Instruction::Free: {
|
||||
Out << " FreeInst* " << iName << " = new FreeInst("
|
||||
<< getCppName(I->getOperand(0)) << ", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Alloca: {
|
||||
const AllocaInst* allocaI = cast<AllocaInst>(I);
|
||||
Out << " AllocaInst* " << iName << " = new AllocaInst("
|
||||
Out << " AllocaInst* " << iName << " = new AllocaInst("
|
||||
<< getCppName(allocaI->getAllocatedType()) << ", ";
|
||||
if (allocaI->isArrayAllocation())
|
||||
Out << getCppName(allocaI->getArraySize()) << ", ";
|
||||
@ -849,11 +959,17 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
<< allocaI->getAlignment() << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Load:
|
||||
break;
|
||||
case Instruction::Load:{
|
||||
const LoadInst* load = cast<LoadInst>(I);
|
||||
Out << " LoadInst* " << iName << " = new LoadInst("
|
||||
<< getCppName(load->getOperand(0)) << ", " << bbname << ");\n";
|
||||
if (load->isVolatile())
|
||||
Out << "iName->setVolatile(true);";
|
||||
break;
|
||||
}
|
||||
case Instruction::Store: {
|
||||
const StoreInst* store = cast<StoreInst>(I);
|
||||
Out << " StoreInst* " << iName << " = new StoreInst("
|
||||
Out << " StoreInst* " << iName << " = new StoreInst("
|
||||
<< getCppName(store->getOperand(0)) << ", "
|
||||
<< getCppName(store->getOperand(1)) << ", " << bbname << ");\n";
|
||||
if (store->isVolatile())
|
||||
@ -863,18 +979,18 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
case Instruction::GetElementPtr: {
|
||||
const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
|
||||
if (gep->getNumOperands() <= 2) {
|
||||
Out << " GetElementPtrInst* " << iName << " = new GetElementPtrInst("
|
||||
Out << " GetElementPtrInst* " << iName << " = new GetElementPtrInst("
|
||||
<< getCppName(gep->getOperand(0));
|
||||
if (gep->getNumOperands() == 2)
|
||||
Out << ", " << getCppName(gep->getOperand(1));
|
||||
Out << ", " << bbname;
|
||||
} else {
|
||||
Out << " std::vector<Value*> " << iName << "_indices;\n";
|
||||
Out << " std::vector<Value*> " << iName << "_indices;\n";
|
||||
for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
|
||||
Out << " " << iName << "_indices.push_back("
|
||||
Out << " " << iName << "_indices.push_back("
|
||||
<< getCppName(gep->getOperand(i)) << ");\n";
|
||||
}
|
||||
Out << " Instruction* " << iName << " = new GetElementPtrInst("
|
||||
Out << " Instruction* " << iName << " = new GetElementPtrInst("
|
||||
<< getCppName(gep->getOperand(0)) << ", " << iName << "_indices";
|
||||
}
|
||||
Out << ", \"";
|
||||
@ -882,201 +998,119 @@ CppWriter::printInstruction(const Instruction *I, const std::string& bbname)
|
||||
Out << "\", " << bbname << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::PHI:
|
||||
case Instruction::Cast:
|
||||
case Instruction::Call:
|
||||
case Instruction::Shl:
|
||||
case Instruction::Shr:
|
||||
case Instruction::Select:
|
||||
case Instruction::UserOp1:
|
||||
case Instruction::UserOp2:
|
||||
case Instruction::VAArg:
|
||||
case Instruction::ExtractElement:
|
||||
case Instruction::InsertElement:
|
||||
case Instruction::ShuffleVector:
|
||||
break;
|
||||
}
|
||||
Out << "\n";
|
||||
|
||||
/*
|
||||
// Print out name if it exists...
|
||||
if (I.hasName())
|
||||
Out << getLLVMName(I.getName()) << " = ";
|
||||
|
||||
// If this is a volatile load or store, print out the volatile marker.
|
||||
if ((isa<LoadInst>(I) && cast<LoadInst>(I).isVolatile()) ||
|
||||
(isa<StoreInst>(I) && cast<StoreInst>(I).isVolatile())) {
|
||||
Out << "volatile ";
|
||||
} else if (isa<CallInst>(I) && cast<CallInst>(I).isTailCall()) {
|
||||
// If this is a call, check if it's a tail call.
|
||||
Out << "tail ";
|
||||
}
|
||||
|
||||
// Print out the opcode...
|
||||
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 (isa<BranchInst>(I) && I.getNumOperands() > 1) {
|
||||
writeOperand(I.getOperand(2), true);
|
||||
Out << ',';
|
||||
writeOperand(Operand, true);
|
||||
Out << ',';
|
||||
writeOperand(I.getOperand(1), true);
|
||||
|
||||
} else if (isa<SwitchInst>(I)) {
|
||||
// Special case switch statement to get formatting nice and correct...
|
||||
writeOperand(Operand , true); Out << ',';
|
||||
writeOperand(I.getOperand(1), true); Out << " [";
|
||||
|
||||
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; op += 2) {
|
||||
Out << "\n\t\t";
|
||||
writeOperand(I.getOperand(op ), true); Out << ',';
|
||||
writeOperand(I.getOperand(op+1), true);
|
||||
}
|
||||
Out << "\n\t]";
|
||||
} else if (isa<PHINode>(I)) {
|
||||
Out << ' ';
|
||||
printType(I.getType());
|
||||
Out << ' ';
|
||||
|
||||
for (unsigned op = 0, Eop = I.getNumOperands(); op < Eop; op += 2) {
|
||||
if (op) Out << ", ";
|
||||
Out << '[';
|
||||
writeOperand(I.getOperand(op ), false); Out << ',';
|
||||
writeOperand(I.getOperand(op+1), false); Out << " ]";
|
||||
}
|
||||
} else if (isa<ReturnInst>(I) && !Operand) {
|
||||
Out << " void";
|
||||
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
|
||||
// Print the calling convention being used.
|
||||
switch (CI->getCallingConv()) {
|
||||
case CallingConv::C: break; // default
|
||||
case CallingConv::CSRet: Out << " csretcc"; break;
|
||||
case CallingConv::Fast: Out << " fastcc"; break;
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
default: Out << " cc" << CI->getCallingConv(); break;
|
||||
}
|
||||
|
||||
const PointerType *PTy = cast<PointerType>(Operand->getType());
|
||||
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||
const Type *RetTy = FTy->getReturnType();
|
||||
|
||||
// If possible, print out the short form of the call instruction. We can
|
||||
// only do this if the first argument is a pointer to a nonvararg function,
|
||||
// and if the return type is not a pointer to a function.
|
||||
//
|
||||
if (!FTy->isVarArg() &&
|
||||
(!isa<PointerType>(RetTy) ||
|
||||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
|
||||
Out << ' '; printType(RetTy);
|
||||
writeOperand(Operand, false);
|
||||
} else {
|
||||
writeOperand(Operand, true);
|
||||
}
|
||||
Out << '(';
|
||||
if (CI->getNumOperands() > 1) writeOperand(CI->getOperand(1), true);
|
||||
for (unsigned op = 2, Eop = I.getNumOperands(); op < Eop; ++op) {
|
||||
Out << ',';
|
||||
writeOperand(I.getOperand(op), true);
|
||||
}
|
||||
|
||||
Out << " )";
|
||||
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
||||
const PointerType *PTy = cast<PointerType>(Operand->getType());
|
||||
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||
const Type *RetTy = FTy->getReturnType();
|
||||
|
||||
// Print the calling convention being used.
|
||||
switch (II->getCallingConv()) {
|
||||
case CallingConv::C: break; // default
|
||||
case CallingConv::CSRet: Out << " csretcc"; break;
|
||||
case CallingConv::Fast: Out << " fastcc"; break;
|
||||
case CallingConv::Cold: Out << " coldcc"; break;
|
||||
default: Out << " cc" << II->getCallingConv(); break;
|
||||
}
|
||||
|
||||
// If possible, print out the short form of the invoke instruction. We can
|
||||
// only do this if the first argument is a pointer to a nonvararg function,
|
||||
// and if the return type is not a pointer to a function.
|
||||
//
|
||||
if (!FTy->isVarArg() &&
|
||||
(!isa<PointerType>(RetTy) ||
|
||||
!isa<FunctionType>(cast<PointerType>(RetTy)->getElementType()))) {
|
||||
Out << ' '; printType(RetTy);
|
||||
writeOperand(Operand, false);
|
||||
} else {
|
||||
writeOperand(Operand, true);
|
||||
}
|
||||
|
||||
Out << '(';
|
||||
if (I.getNumOperands() > 3) writeOperand(I.getOperand(3), true);
|
||||
for (unsigned op = 4, Eop = I.getNumOperands(); op < Eop; ++op) {
|
||||
Out << ',';
|
||||
writeOperand(I.getOperand(op), true);
|
||||
}
|
||||
|
||||
Out << " )\n\t\t\tto";
|
||||
writeOperand(II->getNormalDest(), true);
|
||||
Out << " unwind";
|
||||
writeOperand(II->getUnwindDest(), true);
|
||||
|
||||
} else if (const AllocationInst *AI = dyn_cast<AllocationInst>(&I)) {
|
||||
Out << ' ';
|
||||
printType(AI->getType()->getElementType());
|
||||
if (AI->isArrayAllocation()) {
|
||||
Out << ',';
|
||||
writeOperand(AI->getArraySize(), true);
|
||||
}
|
||||
if (AI->getAlignment()) {
|
||||
Out << ", align " << AI->getAlignment();
|
||||
}
|
||||
} else if (isa<CastInst>(I)) {
|
||||
if (Operand) writeOperand(Operand, true); // Work with broken code
|
||||
Out << " to ";
|
||||
printType(I.getType());
|
||||
} else if (isa<VAArgInst>(I)) {
|
||||
if (Operand) writeOperand(Operand, true); // Work with broken code
|
||||
Out << ", ";
|
||||
printType(I.getType());
|
||||
} else if (Operand) { // Print the normal way...
|
||||
|
||||
// PrintAllTypes - Instructions who have operands of all the same type
|
||||
// omit the type from all but the first operand. If the instruction has
|
||||
// different type operands (for example br), then they are all printed.
|
||||
bool PrintAllTypes = false;
|
||||
const Type *TheType = Operand->getType();
|
||||
|
||||
// Shift Left & Right print both types even for Ubyte LHS, and select prints
|
||||
// types even if all operands are bools.
|
||||
if (isa<ShiftInst>(I) || isa<SelectInst>(I) || isa<StoreInst>(I) ||
|
||||
isa<ShuffleVectorInst>(I)) {
|
||||
PrintAllTypes = true;
|
||||
} else {
|
||||
for (unsigned i = 1, E = I.getNumOperands(); i != E; ++i) {
|
||||
Operand = I.getOperand(i);
|
||||
if (Operand->getType() != TheType) {
|
||||
PrintAllTypes = true; // We have differing types! Print them all!
|
||||
break;
|
||||
}
|
||||
case Instruction::PHI: {
|
||||
const PHINode* phi = cast<PHINode>(I);
|
||||
Out << " PHINode* " << iName << " = new PHINode("
|
||||
<< getCppName(phi->getType()) << ", \"";
|
||||
printEscapedString(phi->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
Out << iName << "->reserveOperandSpace(" << phi->getNumIncomingValues()
|
||||
<< ");\n";
|
||||
for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
|
||||
Out << iName << "->addIncomingValue("
|
||||
<< getCppName(phi->getIncomingValue(i)) << ", "
|
||||
<< getCppName(phi->getIncomingBlock(i)) << ");\n";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!PrintAllTypes) {
|
||||
Out << ' ';
|
||||
printType(TheType);
|
||||
case Instruction::Cast: {
|
||||
const CastInst* cst = cast<CastInst>(I);
|
||||
Out << " CastInst* " << iName << " = new CastInst("
|
||||
<< getCppName(cst->getOperand(0)) << ", "
|
||||
<< getCppName(cst->getType()) << ", \"";
|
||||
printEscapedString(cst->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, E = I.getNumOperands(); i != E; ++i) {
|
||||
if (i) Out << ',';
|
||||
writeOperand(I.getOperand(i), PrintAllTypes);
|
||||
case Instruction::Call:{
|
||||
const CallInst* call = cast<CallInst>(I);
|
||||
if (call->getNumOperands() > 3) {
|
||||
Out << " std::vector<Value*> " << iName << "_params;\n";
|
||||
for (unsigned i = 1; i < call->getNumOperands(); ++i) {
|
||||
Out << " " << iName << "_params.push_back("
|
||||
<< getCppName(call->getOperand(i)) << ");\n";
|
||||
}
|
||||
Out << " CallInst* " << iName << " = new CallInst("
|
||||
<< getCppName(call->getOperand(0)) << ", "
|
||||
<< iName << "_params, \"";
|
||||
} else if (call->getNumOperands() == 3) {
|
||||
Out << " CallInst* " << iName << " = new CallInst("
|
||||
<< getCppName(call->getOperand(0)) << ", "
|
||||
<< getCppName(call->getOperand(1)) << ", "
|
||||
<< getCppName(call->getOperand(2)) << ", \"";
|
||||
} else if (call->getNumOperands() == 2) {
|
||||
Out << " CallInst* " << iName << " = new CallInst("
|
||||
<< getCppName(call->getOperand(0)) << ", "
|
||||
<< getCppName(call->getOperand(1)) << ", \"";
|
||||
} else {
|
||||
Out << " CallInst* " << iName << " = new CallInst("
|
||||
<< getCppName(call->getOperand(0)) << ", \"";
|
||||
}
|
||||
printEscapedString(call->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
Out << iName << "->setCallingConv(";
|
||||
printCallingConv(call->getCallingConv());
|
||||
Out << ");\n";
|
||||
Out << iName << "->setTailCall(" << (call->isTailCall() ? "true":"false");
|
||||
Out << ");";
|
||||
break;
|
||||
}
|
||||
case Instruction::Select: {
|
||||
const SelectInst* sel = cast<SelectInst>(I);
|
||||
Out << " SelectInst* " << getCppName(sel) << " = new SelectInst(";
|
||||
Out << getCppName(sel->getCondition()) << ", ";
|
||||
Out << getCppName(sel->getTrueValue()) << ", ";
|
||||
Out << getCppName(sel->getFalseValue()) << ", \"";
|
||||
printEscapedString(sel->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
case Instruction::UserOp1:
|
||||
/// FALL THROUGH
|
||||
case Instruction::UserOp2: {
|
||||
/// FIXME: What should be done here?
|
||||
break;
|
||||
}
|
||||
case Instruction::VAArg: {
|
||||
const VAArgInst* va = cast<VAArgInst>(I);
|
||||
Out << " VAArgInst* " << getCppName(va) << " = new VAArgInst("
|
||||
<< getCppName(va->getOperand(0)) << ", "
|
||||
<< getCppName(va->getType()) << ", \"";
|
||||
printEscapedString(va->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
case Instruction::ExtractElement: {
|
||||
const ExtractElementInst* eei = cast<ExtractElementInst>(I);
|
||||
Out << " ExtractElementInst* " << getCppName(eei)
|
||||
<< " = new ExtractElementInst(" << getCppName(eei->getOperand(0))
|
||||
<< ", " << getCppName(eei->getOperand(1)) << ", \"";
|
||||
printEscapedString(eei->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
case Instruction::InsertElement: {
|
||||
const InsertElementInst* iei = cast<InsertElementInst>(I);
|
||||
Out << " InsertElementInst* " << getCppName(iei)
|
||||
<< " = new InsertElementInst(" << getCppName(iei->getOperand(0))
|
||||
<< ", " << getCppName(iei->getOperand(1)) << ", "
|
||||
<< ", " << getCppName(iei->getOperand(2)) << ", \"";
|
||||
printEscapedString(iei->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
case Instruction::ShuffleVector: {
|
||||
const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
|
||||
Out << " ShuffleVectorInst* " << getCppName(svi)
|
||||
<< " = new ShuffleVectorInst(" << getCppName(svi->getOperand(0))
|
||||
<< ", " << getCppName(svi->getOperand(1)) << ", "
|
||||
<< ", " << getCppName(svi->getOperand(2)) << ", \"";
|
||||
printEscapedString(svi->getName());
|
||||
Out << "\", " << bbname << ");\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Out << "\n";
|
||||
*/
|
||||
}
|
||||
|
||||
} // end anonymous llvm
|
||||
|
Loading…
Reference in New Issue
Block a user