aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-08-28 16:33:36 +0000
committerChris Lattner <sabre@nondot.org>2010-08-28 16:33:36 +0000
commit885b661e1004978f39cd1d74e586f193dfc0b0a6 (patch)
treea94f664646bc8d8463cf362ef07e4e7926c05a62
parent9df0a0a8711596eaa3c7dd3413c0835ad99d3929 (diff)
remove the MSIL backend. It isn't maintained, is buggy, has no testcases
and hasn't kept up with ToT. Approved by Anton. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112375 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--autoconf/configure.ac5
-rwxr-xr-xconfigure5
-rw-r--r--docs/ReleaseNotes.html9
-rw-r--r--lib/Target/MSIL/CMakeLists.txt3
-rw-r--r--lib/Target/MSIL/MSILWriter.cpp1706
-rw-r--r--lib/Target/MSIL/MSILWriter.h258
-rw-r--r--lib/Target/MSIL/Makefile16
-rw-r--r--lib/Target/MSIL/README.TXT26
-rw-r--r--lib/Target/MSIL/TargetInfo/CMakeLists.txt6
-rw-r--r--lib/Target/MSIL/TargetInfo/MSILTargetInfo.cpp26
-rw-r--r--lib/Target/MSIL/TargetInfo/Makefile15
11 files changed, 9 insertions, 2066 deletions
diff --git a/autoconf/configure.ac b/autoconf/configure.ac
index 0271386234..5a8a5f99fb 100644
--- a/autoconf/configure.ac
+++ b/autoconf/configure.ac
@@ -543,13 +543,13 @@ TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
[Build specific host targets: all or target1,target2,... Valid targets are:
host, x86, x86_64, sparc, powerpc, alpha, arm, mips, spu, pic16,
- xcore, msp430, systemz, blackfin, cbe, msil, and cpp (default=all)]),,
+ xcore, msp430, systemz, blackfin, cbe, and cpp (default=all)]),,
enableval=all)
if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -566,7 +566,6 @@ case "$enableval" in
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
- msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
diff --git a/configure b/configure
index 272895b9cc..948e7ccd93 100755
--- a/configure
+++ b/configure
@@ -1414,7 +1414,7 @@ Optional Features:
--enable-targets Build specific host targets: all or
target1,target2,... Valid targets are: host, x86,
x86_64, sparc, powerpc, alpha, arm, mips, spu,
- pic16, xcore, msp430, systemz, blackfin, cbe, msil,
+ pic16, xcore, msp430, systemz, blackfin, cbe,
and cpp (default=all)
--enable-cbe-printf-a Enable C Backend output with hex floating point via
%a (default is YES)
@@ -4955,7 +4955,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend CppBackend MBlaze" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -4972,7 +4972,6 @@ case "$enableval" in
systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
blackfin) TARGETS_TO_BUILD="Blackfin $TARGETS_TO_BUILD" ;;
cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
- msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
host) case "$llvm_cv_target_arch" in
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index 3595735033..f9f492c263 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -68,7 +68,6 @@ Almost dead code.
lib/Transforms/IPO/MergeFunctions.cpp => consider for 2.8.
llvm/Analysis/PointerTracking.h => Edwin wants this, consider for 2.8.
GEPSplitterPass
- MSIL backend?
-->
@@ -77,6 +76,7 @@ Almost dead code.
strong phi elim
llvm.dbg.value: variable debug info for optimized code
loop dependence analysis
+ TBAA
-->
<!-- for announcement email:
@@ -489,8 +489,9 @@ on LLVM 2.7, this section lists some "gotchas" that you may run into upgrading
from the previous release.</p>
<ul>
-
-<li>.</li>
+<li>MSIL Backend removed.</li>
+<li>ABCD and SSI passes removed.</li>
+<li>'Union' LLVM IR feature removed.</li>
</ul>
<p>In addition, many APIs have changed in this release. Some of the major LLVM
@@ -575,7 +576,7 @@ components, please contact us on the <a
href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list</a>.</p>
<ul>
-<li>The MSIL, Alpha, SPU, MIPS, PIC16, Blackfin, MSP430, SystemZ and MicroBlaze
+<li>The Alpha, SPU, MIPS, PIC16, Blackfin, MSP430, SystemZ and MicroBlaze
backends are experimental.</li>
<li><tt>llc</tt> "<tt>-filetype=asm</tt>" (the default) is the only
supported value for this option. XXX Update me</li>
diff --git a/lib/Target/MSIL/CMakeLists.txt b/lib/Target/MSIL/CMakeLists.txt
deleted file mode 100644
index b1d47ef05e..0000000000
--- a/lib/Target/MSIL/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_llvm_target(MSIL
- MSILWriter.cpp
- )
diff --git a/lib/Target/MSIL/MSILWriter.cpp b/lib/Target/MSIL/MSILWriter.cpp
deleted file mode 100644
index cc350e8a4f..0000000000
--- a/lib/Target/MSIL/MSILWriter.cpp
+++ /dev/null
@@ -1,1706 +0,0 @@
-//===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This library converts LLVM code to MSIL code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MSILWriter.h"
-#include "llvm/CallingConv.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/TypeSymbolTable.h"
-#include "llvm/Analysis/ConstantsScanner.h"
-#include "llvm/Support/CallSite.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/InstVisitor.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/CodeGen/Passes.h"
-using namespace llvm;
-
-namespace llvm {
- // TargetMachine for the MSIL
- struct MSILTarget : public TargetMachine {
- MSILTarget(const Target &T, const std::string &TT, const std::string &FS)
- : TargetMachine(T) {}
-
- virtual bool addPassesToEmitFile(PassManagerBase &PM,
- formatted_raw_ostream &Out,
- CodeGenFileType FileType,
- CodeGenOpt::Level OptLevel,
- bool DisableVerify);
-
- virtual const TargetData *getTargetData() const { return 0; }
- };
-}
-
-extern "C" void LLVMInitializeMSILTarget() {
- // Register the target.
- RegisterTargetMachine<MSILTarget> X(TheMSILTarget);
-}
-
-bool MSILModule::runOnModule(Module &M) {
- ModulePtr = &M;
- TD = &getAnalysis<TargetData>();
- bool Changed = false;
- // Find named types.
- TypeSymbolTable& Table = M.getTypeSymbolTable();
- std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes();
- for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) {
- if (!I->second->isStructTy() && !I->second->isOpaqueTy())
- Table.remove(I++);
- else {
- std::set<const Type *>::iterator T = Types.find(I->second);
- if (T==Types.end())
- Table.remove(I++);
- else {
- Types.erase(T);
- ++I;
- }
- }
- }
- // Find unnamed types.
- unsigned RenameCounter = 0;
- for (std::set<const Type *>::const_iterator I = Types.begin(),
- E = Types.end(); I!=E; ++I)
- if (const StructType *STy = dyn_cast<StructType>(*I)) {
- while (ModulePtr->addTypeName("unnamed$"+utostr(RenameCounter), STy))
- ++RenameCounter;
- Changed = true;
- }
- // Pointer for FunctionPass.
- UsedTypes = &getAnalysis<FindUsedTypes>().getTypes();
- return Changed;
-}
-
-char MSILModule::ID = 0;
-char MSILWriter::ID = 0;
-
-bool MSILWriter::runOnFunction(Function &F) {
- if (F.isDeclaration()) return false;
-
- // Do not codegen any 'available_externally' functions at all, they have
- // definitions outside the translation unit.
- if (F.hasAvailableExternallyLinkage())
- return false;
-
- LInfo = &getAnalysis<LoopInfo>();
- printFunction(F);
- return false;
-}
-
-
-bool MSILWriter::doInitialization(Module &M) {
- ModulePtr = &M;
- Out << ".assembly extern mscorlib {}\n";
- Out << ".assembly MSIL {}\n\n";
- Out << "// External\n";
- printExternals();
- Out << "// Declarations\n";
- printDeclarations(M.getTypeSymbolTable());
- Out << "// Definitions\n";
- printGlobalVariables();
- Out << "// Startup code\n";
- printModuleStartup();
- return false;
-}
-
-
-bool MSILWriter::doFinalization(Module &M) {
- return false;
-}
-
-
-void MSILWriter::printModuleStartup() {
- Out <<
- ".method static public int32 $MSIL_Startup() {\n"
- "\t.entrypoint\n"
- "\t.locals (native int i)\n"
- "\t.locals (native int argc)\n"
- "\t.locals (native int ptr)\n"
- "\t.locals (void* argv)\n"
- "\t.locals (string[] args)\n"
- "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n"
- "\tdup\n"
- "\tstloc\targs\n"
- "\tldlen\n"
- "\tconv.i4\n"
- "\tdup\n"
- "\tstloc\targc\n";
- printPtrLoad(TD->getPointerSize());
- Out <<
- "\tmul\n"
- "\tlocalloc\n"
- "\tstloc\targv\n"
- "\tldc.i4.0\n"
- "\tstloc\ti\n"
- "L_01:\n"
- "\tldloc\ti\n"
- "\tldloc\targc\n"
- "\tceq\n"
- "\tbrtrue\tL_02\n"
- "\tldloc\targs\n"
- "\tldloc\ti\n"
- "\tldelem.ref\n"
- "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::"
- "StringToHGlobalAnsi(string)\n"
- "\tstloc\tptr\n"
- "\tldloc\targv\n"
- "\tldloc\ti\n";
- printPtrLoad(TD->getPointerSize());
- Out <<
- "\tmul\n"
- "\tadd\n"
- "\tldloc\tptr\n"
- "\tstind.i\n"
- "\tldloc\ti\n"
- "\tldc.i4.1\n"
- "\tadd\n"
- "\tstloc\ti\n"
- "\tbr\tL_01\n"
- "L_02:\n"
- "\tcall void $MSIL_Init()\n";
-
- // Call user 'main' function.
- const Function* F = ModulePtr->getFunction("main");
- if (!F || F->isDeclaration()) {
- Out << "\tldc.i4.0\n\tret\n}\n";
- return;
- }
- bool BadSig = true;
- std::string Args("");
- Function::const_arg_iterator Arg1,Arg2;
-
- switch (F->arg_size()) {
- case 0:
- BadSig = false;
- break;
- case 1:
- Arg1 = F->arg_begin();
- if (Arg1->getType()->isIntegerTy()) {
- Out << "\tldloc\targc\n";
- Args = getTypeName(Arg1->getType());
- BadSig = false;
- }
- break;
- case 2:
- Arg1 = Arg2 = F->arg_begin(); ++Arg2;
- if (Arg1->getType()->isIntegerTy() &&
- Arg2->getType()->getTypeID() == Type::PointerTyID) {
- Out << "\tldloc\targc\n\tldloc\targv\n";
- Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType());
- BadSig = false;
- }
- break;
- default:
- BadSig = true;
- }
-
- bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
- if (BadSig || (!F->getReturnType()->isIntegerTy() && !RetVoid)) {
- Out << "\tldc.i4.0\n";
- } else {
- Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
- getConvModopt(F->getCallingConv()) << "main(" << Args << ")\n";
- if (RetVoid)
- Out << "\tldc.i4.0\n";
- else
- Out << "\tconv.i4\n";
- }
- Out << "\tret\n}\n";
-}
-
-bool MSILWriter::isZeroValue(const Value* V) {
- if (const Constant *C = dyn_cast<Constant>(V))
- return C->isNullValue();
- return false;
-}
-
-
-std::string MSILWriter::getValueName(const Value* V) {
- std::string Name;
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = GV->getName();
- else {
- unsigned &No = AnonValueNumbers[V];
- if (No == 0) No = ++NextAnonValueNumber;
- Name = "tmp" + utostr(No);
- }
-
- // Name into the quotes allow control and space characters.
- return "'"+Name+"'";
-}
-
-
-std::string MSILWriter::getLabelName(const std::string& Name) {
- if (Name.find('.')!=std::string::npos) {
- std::string Tmp(Name);
- // Replace unaccepable characters in the label name.
- for (std::string::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I)
- if (*I=='.') *I = '@';
- return Tmp;
- }
- return Name;
-}
-
-
-std::string MSILWriter::getLabelName(const Value* V) {
- std::string Name;
- if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
- Name = GV->getName();
- else {
- unsigned &No = AnonValueNumbers[V];
- if (No == 0) No = ++NextAnonValueNumber;
- Name = "tmp" + utostr(No);
- }
-
- return getLabelName(Name);
-}
-
-
-std::string MSILWriter::getConvModopt(CallingConv::ID CallingConvID) {
- switch (CallingConvID) {
- case CallingConv::C:
- case CallingConv::Cold:
- case CallingConv::Fast:
- return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) ";
- case CallingConv::X86_FastCall:
- return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) ";
- case CallingConv::X86_StdCall:
- return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
- case CallingConv::X86_ThisCall:
- return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvThiscall) ";
- default:
- errs() << "CallingConvID = " << CallingConvID << '\n';
- llvm_unreachable("Unsupported calling convention");
- }
- return ""; // Not reached
-}
-
-
-std::string MSILWriter::getArrayTypeName(Type::TypeID TyID, const Type* Ty) {
- std::string Tmp = "";
- const Type* ElemTy = Ty;
- assert(Ty->getTypeID()==TyID && "Invalid type passed");
- // Walk trought array element types.
- for (;;) {
- // Multidimensional array.
- if (ElemTy->getTypeID()==TyID) {
- if (const ArrayType* ATy = dyn_cast<ArrayType>(ElemTy))
- Tmp += utostr(ATy->getNumElements());
- else if (const VectorType* VTy = dyn_cast<VectorType>(ElemTy))
- Tmp += utostr(VTy->getNumElements());
- ElemTy = cast<SequentialType>(ElemTy)->getElementType();
- }
- // Base element type found.
- if (ElemTy->getTypeID()!=TyID) break;
- Tmp += ",";
- }
- return getTypeName(ElemTy, false, true)+"["+Tmp+"]";
-}
-
-
-std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
- unsigned NumBits = 0;
- switch (Ty->getTypeID()) {
- case Type::VoidTyID:
- return "void ";
- case Type::IntegerTyID:
- NumBits = getBitWidth(Ty);
- if(NumBits==1)
- return "bool ";
- if (!isSigned)
- return "unsigned int"+utostr(NumBits)+" ";
- return "int"+utostr(NumBits)+" ";
- case Type::FloatTyID:
- return "float32 ";
- case Type::DoubleTyID:
- return "float64 ";
- default:
- errs() << "Type = " << *Ty << '\n';
- llvm_unreachable("Invalid primitive type");
- }
- return ""; // Not reached
-}
-
-
-std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
- bool isNested) {
- if (Ty->isPrimitiveType() || Ty->isIntegerTy())
- return getPrimitiveTypeName(Ty,isSigned);
- // FIXME: "OpaqueType" support
- switch (Ty->getTypeID()) {
- case Type::PointerTyID:
- return "void* ";
- case Type::StructTyID:
- if (isNested)
- return ModulePtr->getTypeName(Ty);
- return "valuetype '"+ModulePtr->getTypeName(Ty)+"' ";
- case Type::ArrayTyID:
- if (isNested)
- return getArrayTypeName(Ty->getTypeID(),Ty);
- return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
- case Type::VectorTyID:
- if (isNested)
- return getArrayTypeName(Ty->getTypeID(),Ty);
- return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
- default:
- errs() << "Type = " << *Ty << '\n';
- llvm_unreachable("Invalid type in getTypeName()");
- }
- return ""; // Not reached
-}
-
-
-MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) {
- // Function argument
- if (isa<Argument>(V))
- return ArgumentVT;
- // Function
- else if (const Function* F = dyn_cast<Function>(V))
- return F->hasLocalLinkage() ? InternalVT : GlobalVT;
- // Variable
- else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V))
- return G->hasLocalLinkage() ? InternalVT : GlobalVT;
- // Constant
- else if (isa<Constant>(V))
- return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT;
- // Local variable
- return LocalVT;
-}
-
-
-std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
- bool isSigned) {
- unsigned NumBits = 0;
- switch (Ty->getTypeID()) {
- // Integer constant, expanding for stack operations.
- case Type::IntegerTyID:
- NumBits = getBitWidth(Ty);
- // Expand integer value to "int32" or "int64".
- if (Expand) return (NumBits<=32 ? "i4" : "i8");
- if (NumBits==1) return "i1";
- return (isSigned ? "i" : "u")+utostr(NumBits/8);
- // Float constant.
- case Type::FloatTyID:
- return "r4";
- case Type::DoubleTyID:
- return "r8";
- case Type::PointerTyID:
- return "i"+utostr(TD->getTypeAllocSize(Ty));
- default:
- errs() << "TypeID = " << Ty->getTypeID() << '\n';
- llvm_unreachable("Invalid type in TypeToPostfix()");
- }
- return ""; // Not reached
-}
-
-
-void MSILWriter::printConvToPtr() {
- switch (ModulePtr->getPointerSize()) {
- case Module::Pointer32:
- printSimpleInstruction("conv.u4");
- break;
- case Module::Pointer64:
- printSimpleInstruction("conv.u8");
- break;
- default:
- llvm_unreachable("Module use not supporting pointer size");
- }
-}
-
-
-void MSILWriter::printPtrLoad(uint64_t N) {
- switch (ModulePtr->getPointerSize()) {
- case Module::Pointer32:
- printSimpleInstruction("ldc.i4",utostr(N).c_str());
- // FIXME: Need overflow test?
- if (!isUInt<32>(N)) {
- errs() << "Value = " << utostr(N) << '\n';
- llvm_unreachable("32-bit pointer overflowed");
- }
- break;
- case Module::Pointer64:
- printSimpleInstruction("ldc.i8",utostr(N).c_str());
- break;
- default:
- llvm_unreachable("Module use not supporting pointer size");
- }
-}
-
-
-void MSILWriter::printValuePtrLoad(const Value* V) {
- printValueLoad(V);
- printConvToPtr();
-}
-
-
-void MSILWriter::printConstLoad(const Constant* C) {
- if (const ConstantInt* CInt = dyn_cast<ConstantInt>(C)) {
- // Integer constant
- Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t';
- if (CInt->isMinValue(true))
- Out << CInt->getSExtValue();
- else
- Out << CInt->getZExtValue();
- } else if (const ConstantFP* FP = dyn_cast<ConstantFP>(C)) {
- // Float constant
- uint64_t X;
- unsigned Size;
- if (FP->getType()->getTypeID()==Type::FloatTyID) {
- X = (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue();
- Size = 4;
- } else {
- X = FP->getValueAPF().bitcastToAPInt().getZExtValue();
- Size = 8;
- }
- Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
- } else if (isa<UndefValue>(C)) {
- // Undefined constant value = NULL.
- printPtrLoad(0);
- } else {
- errs() << "Constant = " << *C << '\n';
- llvm_unreachable("Invalid constant value");
- }
- Out << '\n';
-}
-
-
-void MSILWriter::printValueLoad(const Value* V) {
- MSILWriter::ValueType Location = getValueLocation(V);
- switch (Location) {
- // Global variable or function address.
- case GlobalVT:
- case InternalVT:
- if (const Function* F = dyn_cast<Function>(V)) {
- std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
- printSimpleInstruction("ldftn",
- getCallSignature(F->getFunctionType(),NULL,Name).c_str());
- } else {
- std::string Tmp;
- const Type* ElemTy = cast<PointerType>(V->getType())->getElementType();
- if (Location==GlobalVT && cast<GlobalVariable>(V)->hasDLLImportLinkage()) {
- Tmp = "void* "+getValueName(V);
- printSimpleInstruction("ldsfld",Tmp.c_str());
- } else {
- Tmp = getTypeName(ElemTy)+getValueName(V);
- printSimpleInstruction("ldsflda",Tmp.c_str());
- }
- }
- break;
- // Function argument.
- case ArgumentVT:
- printSimpleInstruction("ldarg",getValueName(V).c_str());
- break;
- // Local function variable.
- case LocalVT:
- printSimpleInstruction("ldloc",getValueName(V).c_str());
- break;
- // Constant value.
- case ConstVT:
- if (isa<ConstantPointerNull>(V))
- printPtrLoad(0);
- else
- printConstLoad(cast<Constant>(V));
- break;
- // Constant expression.
- case ConstExprVT:
- printConstantExpr(cast<ConstantExpr>(V));
- break;
- default:
- errs() << "Value = " << *V << '\n';
- llvm_unreachable("Invalid value location");
- }
-}
-
-
-void MSILWriter::printValueSave(const Value* V) {
- switch (getValueLocation(V)) {
- case ArgumentVT:
- printSimpleInstruction("starg",getValueName(V).c_str());
- break;
- case LocalVT:
- printSimpleInstruction("stloc",getValueName(V).c_str());
- break;
- default:
- errs() << "Value = " << *V << '\n';
- llvm_unreachable("Invalid value location");
- }
-}
-
-
-void MSILWriter::printBinaryInstruction(const char* Name, const Value* Left,
- const Value* Right) {
- printValueLoad(Left);
- printValueLoad(Right);
- Out << '\t' << Name << '\n';
-}
-
-
-void MSILWriter::printSimpleInstruction(const char* Inst, const char* Operand) {
- if(Operand)
- Out << '\t' << Inst << '\t' << Operand << '\n';
- else
- Out << '\t' << Inst << '\n';
-}
-
-
-void MSILWriter::printPHICopy(const BasicBlock* Src, const BasicBlock* Dst) {
- for (BasicBlock::const_iterator I = Dst->begin(); isa<PHINode>(I); ++I) {
- const PHINode* Phi = cast<PHINode>(I);
- const Value* Val = Phi->getIncomingValueForBlock(Src);
- if (isa<UndefValue>(Val)) continue;
- printValueLoad(Val);
- printValueSave(Phi);
- }
-}
-
-
-void MSILWriter::printBranchToBlock(const BasicBlock* CurrBB,
- const BasicBlock* TrueBB,
- const BasicBlock* FalseBB) {
- if (TrueBB==FalseBB) {
- // "TrueBB" and "FalseBB" destination equals
- printPHICopy(CurrBB,TrueBB);
- printSimpleInstruction("pop");
- printSimpleInstruction("br",getLabelName(TrueBB).c_str());
- } else if (FalseBB==NULL) {
- // If "FalseBB" not used the jump have condition
- printPHICopy(CurrBB,TrueBB);
- printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
- } else if (TrueBB==NULL) {
- // If "TrueBB" not used the jump is unconditional
- printPHICopy(CurrBB,FalseBB);
- printSimpleInstruction("br",getLabelName(FalseBB).c_str());
- } else {
- // Copy PHI instructions for each block
- std::string TmpLabel;
- // Print PHI instructions for "TrueBB"
- if (isa<PHINode>(TrueBB->begin())) {
- TmpLabel = getLabelName(TrueBB)+"$phi_"+utostr(getUniqID());
- printSimpleInstruction("brtrue",TmpLabel.c_str());
- } else {
- printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
- }
- // Print PHI instructions for "FalseBB"
- if (isa<PHINode>(FalseBB->begin())) {
- printPHICopy(CurrBB,FalseBB);
- printSimpleInstruction("br",getLabelName(FalseBB).c_str());
- } else {
- printSimpleInstruction("br",getLabelName(FalseBB).c_str());
- }
- if (isa<PHINode>(TrueBB->begin())) {
- // Handle "TrueBB" PHI Copy
- Out << TmpLabel << ":\n";
- printPHICopy(CurrBB,TrueBB);
- printSimpleInstruction("br",getLabelName(TrueBB).c_str());
- }
- }
-}
-
-
-void MSILWriter::printBranchInstruction(const BranchInst* Inst) {
- if (Inst->isUnconditional()) {
- printBranchToBlock(Inst->getParent(),NULL,Inst->getSuccessor(0));
- } else {
- printValueLoad(Inst->getCondition());
- printBranchToBlock(Inst->getParent(),Inst->getSuccessor(0),
- Inst->getSuccessor(1));
- }
-}
-
-
-void MSILWriter::printSelectInstruction(const Value* Cond, const Value* VTrue,
- const Value* VFalse) {
- std::string TmpLabel = std::string("select$true_")+utostr(getUniqID());
- printValueLoad(VTrue);
- printValueLoad(Cond);
- printSimpleInstruction("brtrue",TmpLabel.c_str());
- printSimpleInstruction("pop");
- printValueLoad(VFalse);
- Out << TmpLabel << ":\n";
-}
-
-
-void MSILWriter::printIndirectLoad(const Value* V) {
- const Type* Ty = V->getType();
- printValueLoad(V);
- if (const PointerType* P = dyn_cast<PointerType>(Ty))
- Ty = P->getElementType();
- std::string Tmp = "ldind."+getTypePostfix(Ty, false);
- printSimpleInstruction(Tmp.c_str());
-}
-
-
-void MSILWriter::printIndirectSave(const Value* Ptr, const Value* Val) {
- printValueLoad(Ptr);
- printValueLoad(Val);
- printIndirectSave(Val->getType());
-}
-
-
-void MSILWriter::printIndirectSave(const Type* Ty) {
- // Instruction need signed postfix for any type.
- std::string postfix = getTypePostfix(Ty, false);
- if (*postfix.begin()=='u') *postfix.begin() = 'i';
- postfix = "stind."+postfix;
- printSimpleInstruction(postfix.c_str());
-}
-
-
-void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
- const Type* Ty, const Type* SrcTy) {
- std::string Tmp("");
- printValueLoad(V);
- switch (Op) {
- // Signed
- case Instruction::SExt:
- // If sign extending int, convert first from unsigned to signed
- // with the same bit size - because otherwise we will loose the sign.
- if (SrcTy) {
- Tmp = "conv."+getTypePostfix(SrcTy,false,true);
- printSimpleInstruction(Tmp.c_str());
- }
- // FALLTHROUGH
- case Instruction::SIToFP:
- case Instruction::FPToSI:
- Tmp = "conv."+getTypePostfix(Ty,false,true);
- printSimpleInstruction(Tmp.c_str());
- break;
- // Unsigned
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::UIToFP:
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::FPToUI:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
- Tmp = "conv."+getTypePostfix(Ty,false);
- printSimpleInstruction(Tmp.c_str());
- break;
- // Do nothing
- case Instruction::BitCast:
- // FIXME: meaning that ld*/st* instruction do not change data format.
- break;
- default:
- errs() << "Opcode = " << Op << '\n';
- llvm_unreachable("Invalid conversion instruction");
- }
-}
-
-
-void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I,
- gep_type_iterator E) {
- unsigned Size;
- // Load address
- printValuePtrLoad(V);
- // Calculate element offset.
- for (; I!=E; ++I){
- Size = 0;
- const Value* IndexValue = I.getOperand();
- if (const StructType* StrucTy = dyn_cast<StructType>(*I)) {
- uint64_t FieldIndex = cast<ConstantInt>(IndexValue)->getZExtValue();
- // Offset is the sum of all previous structure fields.
- for (uint64_t F = 0; F<FieldIndex; ++F)
- Size += TD->getTypeAllocSize(StrucTy->getContainedType((unsigned)F));
- printPtrLoad(Size);
- printSimpleInstruction("add");
- continue;
- } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) {
- Size = TD->getTypeAllocSize(SeqTy->getElementType());
- } else {
- Size = TD->getTypeAllocSize(*I);
- }
- // Add offset of current element to stack top.
- if (!isZeroValue(IndexValue)) {
- // Constant optimization.
- if (const ConstantInt* C = dyn_cast<ConstantInt>(IndexValue)) {
- if (C->getValue().isNegative()) {
- printPtrLoad(C->getValue().abs().getZExtValue()*Size);
- printSimpleInstruction("sub");
- continue;
- } else
- printPtrLoad(C->getZExtValue()*Size);
- } else {
- printPtrLoad(Size);
- printValuePtrLoad(IndexValue);
- printSimpleInstruction("mul");
- }
- printSimpleInstruction("add");
- }
- }
-}
-
-
-std::string MSILWriter::getCallSignature(const FunctionType* Ty,
- const Instruction* Inst,
- std::string Name) {
- std::string Tmp("");
- if (Ty->isVarArg()) Tmp += "vararg ";
- // Name and return type.
- Tmp += getTypeName(Ty->getReturnType())+Name+"(";
- // Function argument type list.
- unsigned NumParams = Ty->getNumParams();
- for (unsigned I = 0; I!=NumParams; ++I) {
- if (I!=0) Tmp += ",";
- Tmp += getTypeName(Ty->getParamType(I));
- }
- // CLR needs to know the exact amount of parameters received by vararg
- // function, because caller cleans the stack.
- if (Ty->isVarArg() && Inst) {
- // Origin to function arguments in "CallInst" or "InvokeInst".
- unsigned Org = isa<InvokeInst>(Inst) ? 3 : 1;
- // Print variable argument types.
- unsigned NumOperands = Inst->getNumOperands()-Org;
- if (NumParams<NumOperands) {
- if (NumParams!=0) Tmp += ", ";
- Tmp += "... , ";
- for (unsigned J = NumParams; J!=NumOperands; ++J) {
- if (J!=NumParams) Tmp += ", ";
- Tmp += getTypeName(Inst->getOperand(J+Org)->getType());
- }
- }
- }
- return Tmp+")";
-}
-
-
-void MSILWriter::printFunctionCall(const Value* FnVal,
- const Instruction* Inst) {
- // Get function calling convention.
- std::string Name = "";
- if (const CallInst* Call = dyn_cast<CallInst>(Inst))
- Name = getConvModopt(Call->getCallingConv());
- else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst))
- Name = getConvModopt(Invoke->getCallingConv());
- else {
- errs() << "Instruction = " << Inst->getName() << '\n';
- llvm_unreachable("Need \"Invoke\" or \"Call\" instruction only");
- }
- if (const Function* F = dyn_cast<Function>(FnVal)) {
- // Direct call.
- Name += getValueName(F);
- printSimpleInstruction("call",
- getCallSignature(F->getFunctionType(),Inst,Name).c_str());
- } else {
- // Indirect function call.
- const PointerType* PTy = cast<PointerType>(FnVal->getType());
- const FunctionType* FTy = cast<FunctionType>(PTy->getElementType());
- // Load function address.
- printValueLoad(FnVal);
- printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str());
- }
-}
-
-
-void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
- std::string Name;
- switch (Inst->getIntrinsicID()) {
- case Intrinsic::vastart:
- Name = getValueName(Inst->getArgOperand(0));
- Name.insert(Name.length()-1,"$valist");
- // Obtain the argument handle.
- printSimpleInstruction("ldloca",Name.c_str());
- printSimpleInstruction("arglist");
- printSimpleInstruction("call",
- "instance void [mscorlib]System.ArgIterator::.ctor"
- "(valuetype [mscorlib]System.RuntimeArgumentHandle)");
- // Save as pointer type "void*"
- printValueLoad(Inst->getArgOperand(0));
- printSimpleInstruction("ldloca",Name.c_str());
- printIndirectSave(PointerType::getUnqual(
- IntegerType::get(Inst->getContext(), 8)));
- break;
- case Intrinsic::vaend:
- // Close argument list handle.
- printIndirectLoad(Inst->getArgOperand(0));
- printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()");
- break;
- case Intrinsic::vacopy:
- // Copy "ArgIterator" valuetype.
- printIndirectLoad(Inst->getArgOperand(0));
- printIndirectLoad(Inst->getArgOperand(1));
- printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator");
- b