//===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
//
//		       The LLVM Compiler Infrastructure
//
// This file was developed by Roman Samoilov and 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/ParameterAttributes.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/Analysis/ConstantsScanner.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/ADT/StringExtras.h"

namespace {
  // TargetMachine for the MSIL 
  struct VISIBILITY_HIDDEN MSILTarget : public TargetMachine {
    const TargetData DataLayout;       // Calculates type size & alignment

    MSILTarget(const Module &M, const std::string &FS)
      : DataLayout(&M) {}

    virtual bool WantsWholeFile() const { return true; }
    virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
                                         CodeGenFileType FileType, bool Fast);

    // This class always works, but shouldn't be the default in most cases.
    static unsigned getModuleMatchQuality(const Module &M) { return 1; }

    virtual const TargetData *getTargetData() const { return &DataLayout; }
  };
}


RegisterTarget<MSILTarget> X("msil", "  MSIL backend");

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 (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second))
      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;
  LInfo = &getAnalysis<LoopInfo>();
  printFunction(F);
  return false;
}


bool MSILWriter::doInitialization(Module &M) {
  ModulePtr = &M;
  Mang = new Mangler(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) {
  delete Mang;
  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()->isInteger()) {
      Out << "\tldloc\targc\n";
      Args = getTypeName(Arg1->getType());
      BadSig = false;
    }
    break;
  case 2:
    Arg1 = Arg2 = F->arg_begin(); ++Arg2;
    if (Arg1->getType()->isInteger() && 
        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()->isInteger() && !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) {
  // Name into the quotes allow control and space characters.
  return "'"+Mang->getValueName(V)+"'";
}


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) {
  return getLabelName(Mang->getValueName(V));
}


std::string MSILWriter::getConvModopt(unsigned 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) ";
  default:
    cerr << "CallingConvID = " << CallingConvID << '\n';
    assert(0 && "Unsupported calling convention");
  }
}


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:
    cerr << "Type = " << *Ty << '\n';
    assert(0 && "Invalid primitive type");
  }
}


std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
                                    bool isNested) {
  if (Ty->isPrimitiveType() || Ty->isInteger())
    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:
    cerr << "Type = " << *Ty << '\n';
    assert(0 && "Invalid type in getTypeName()");
  }
}


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->hasInternalLinkage() ? InternalVT : GlobalVT;
  // Variable
  else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V))
    return G->hasInternalLinkage() ? 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->getTypeSize(Ty));
  default:
    cerr << "TypeID = " << Ty->getTypeID() << '\n';
    assert(0 && "Invalid type in TypeToPostfix()");
  }
}


void MSILWriter::printConvToPtr() {
  switch (ModulePtr->getPointerSize()) {
  case Module::Pointer32:
    printSimpleInstruction("conv.u4");
    break;
  case Module::Pointer64:
    printSimpleInstruction("conv.u8");
    break;
  default:
    assert(0 && "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 (!isUInt32(N)) {
      cerr << "Value = " << utostr(N) << '\n';
      assert(0 && "32-bit pointer overflowed");
    }
    break;
  case Module::Pointer64:
    printSimpleInstruction("ldc.i8",utostr(N).c_str());
    break;
  default:
    assert(0 && "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().convertToAPInt().getRawData();
      Size = 4;  
    } else {
      X = *FP->getValueAPF().convertToAPInt().getRawData();
      Size = 8;  
    }
    Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
  } else if (isa<UndefValue>(C)) {
    // Undefined constant value = NULL.
    printPtrLoad(0);
  } else {
    cerr << "Constant = " << *C << '\n';
    assert(0 && "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:
    cerr << "Value = " << *V << '\n';
    assert(0 && "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:
    cerr << "Value  = " << *V << '\n';
    assert(0 && "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(), E = Dst->end();
       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) {
  std::string Tmp("");
  printValueLoad(V);
  switch (Op) {
  // Signed
  case Instruction::SExt:
  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:
    cerr << "Opcode = " << Op << '\n';
    assert(0 && "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->getTypeSize(StrucTy->getContainedType((unsigned)F));
      printPtrLoad(Size);
      printSimpleInstruction("add");
      continue;
    } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) {
      Size = TD->getTypeSize(SeqTy->getElementType());
    } else {
      Size = TD->getTypeSize(*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 {
    cerr << "Instruction = " << Inst->getName() << '\n';
    assert(0 && "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->getOperand(1));
    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->getOperand(1));
    printSimpleInstruction("ldloca",Name.c_str());
    printIndirectSave(PointerType::get(IntegerType::get(8)));
    break;
  case Intrinsic::vaend:
    // Close argument list handle.
    printIndirectLoad(Inst->getOperand(1));
    printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()");
    break;
  case Intrinsic::vacopy:
    // Copy "ArgIterator" valuetype.
    printIndirectLoad(Inst->getOperand(1));
    printIndirectLoad(Inst->getOperand(2));
    printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator");
    break;        
  default:
    cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n';
    assert(0 && "Invalid intrinsic function");
  }
}


void MSILWriter::printCallInstruction(const Instruction* Inst) {
  if (isa<IntrinsicInst>(Inst)) {
    // Handle intrinsic function.
    printIntrinsicCall(cast<IntrinsicInst>(Inst));
  } else {
    // Load arguments to stack and call function.
    for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I)
      printValueLoad(Inst->getOperand(I));
    printFunctionCall(Inst->getOperand(0),Inst);
  }
}


void MSILWriter::printICmpInstruction(unsigned Predicate, const Value* Left,
                                      const Value* Right) {
  switch (Predicate) {
  case ICmpInst::ICMP_EQ:
    printBinaryInstruction("ceq",Left,Right);
    break;
  case ICmpInst::ICMP_NE:
    // Emulate = not neg (Op1 eq Op2)
    printBinaryInstruction("ceq",Left,Right);
    printSimpleInstruction("neg");
    printSimpleInstruction("not");
    break;
  case ICmpInst::ICMP_ULE:
  case ICmpInst::ICMP_SLE:
    // Emulate = (Op1 eq Op2) or (Op1 lt Op2)
    printBinaryInstruction("ceq",Left,Right);
    if (Predicate==ICmpInst::ICMP_ULE)
      printBinaryInstruction("clt.un",Left,Right);
    else
      printBinaryInstruction("clt",Left,Right);
    printSimpleInstruction("or");
    break;
  case ICmpInst::ICMP_UGE:
  case ICmpInst::ICMP_SGE:
    // Emulate = (Op1 eq Op2) or (Op1 gt Op2)
    printBinaryInstruction("ceq",Left,Right);
    if (Predicate==ICmpInst::ICMP_UGE)
      printBinaryInstruction("cgt.un",Left,Right);
    else
      printBinaryInstruction("cgt",Left,Right);
    printSimpleInstruction("or");
    break;
  case ICmpInst::ICMP_ULT:
    printBinaryInstruction("clt.un",Left,Right);
    break;
  case ICmpInst::ICMP_SLT:
    printBinaryInstruction("clt",Left,Right);
    break;
  case ICmpInst::ICMP_UGT:
    printBinaryInstruction("cgt.un",Left,Right);
  case ICmpInst::ICMP_SGT:
    printBinaryInstruction("cgt",Left,Right);
    break;
  default:
    cerr << "Predicate = " << Predicate << '\n';
    assert(0 && "Invalid icmp predicate");
  }
}


void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left,
                                      const Value* Right) {
  // FIXME: Correct comparison
  std::string NanFunc = "bool [mscorlib]System.Double::IsNaN(float64)";
  switch (Predicate) {
  case FCmpInst::FCMP_UGT:
    // X >  Y || llvm_fcmp_uno(X, Y)
    printBinaryInstruction("cgt",Left,Right);
    printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_OGT:
    // X >  Y
    printBinaryInstruction("cgt",Left,Right);
    break;
  case FCmpInst::FCMP_UGE:
    // X >= Y || llvm_fcmp_uno(X, Y)
    printBinaryInstruction("ceq",Left,Right);
    printBinaryInstruction("cgt",Left,Right);
    printSimpleInstruction("or");
    printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_OGE:
    // X >= Y
    printBinaryInstruction("ceq",Left,Right);
    printBinaryInstruction("cgt",Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_ULT:
    // X <  Y || llvm_fcmp_uno(X, Y)
    printBinaryInstruction("clt",Left,Right);
    printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_OLT:
    // X <  Y
    printBinaryInstruction("clt",Left,Right);
    break;
  case FCmpInst::FCMP_ULE:
    // X <= Y || llvm_fcmp_uno(X, Y)
    printBinaryInstruction("ceq",Left,Right);
    printBinaryInstruction("clt",Left,Right);
    printSimpleInstruction("or");
    printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_OLE:
    // X <= Y
    printBinaryInstruction("ceq",Left,Right);
    printBinaryInstruction("clt",Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_UEQ:
    // X == Y || llvm_fcmp_uno(X, Y)
    printBinaryInstruction("ceq",Left,Right);
    printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_OEQ:
    // X == Y
    printBinaryInstruction("ceq",Left,Right);
    break;
  case FCmpInst::FCMP_UNE:
    // X != Y
    printBinaryInstruction("ceq",Left,Right);
    printSimpleInstruction("neg");
    printSimpleInstruction("not");
    break;
  case FCmpInst::FCMP_ONE:
    // X != Y && llvm_fcmp_ord(X, Y)
    printBinaryInstruction("ceq",Left,Right);
    printSimpleInstruction("not");
    break;
  case FCmpInst::FCMP_ORD:
    // return X == X && Y == Y
    printBinaryInstruction("ceq",Left,Left);
    printBinaryInstruction("ceq",Right,Right);
    printSimpleInstruction("or");
    break;
  case FCmpInst::FCMP_UNO:
    // X != X || Y != Y
    printBinaryInstruction("ceq",Left,Left);
    printSimpleInstruction("not");
    printBinaryInstruction("ceq",Right,Right);
    printSimpleInstruction("not");
    printSimpleInstruction("or");
    break;
  default:
    assert(0 && "Illegal FCmp predicate");
  }
}


void MSILWriter::printInvokeInstruction(const InvokeInst* Inst) {
  std::string Label = "leave$normal_"+utostr(getUniqID());
  Out << ".try {\n";
  // Load arguments
  for (int I = 3, E = Inst->getNumOperands(); I!=E; ++I)
    printValueLoad(Inst->getOperand(I));
  // Print call instruction
  printFunctionCall(Inst->getOperand(0),Inst);
  // Save function result and leave "try" block
  printValueSave(Inst);
  printSimpleInstruction("leave",Label.c_str());
  Out << "}\n";
  Out << "catch [mscorlib]System.Exception {\n";
  // Redirect to unwind block
  printSimpleInstruction("pop");
  printBranchToBlock(Inst->getParent(),NULL,Inst->getUnwindDest());
  Out << "}\n" << Label << ":\n";
  // Redirect to continue block
  printBranchToBlock(Inst->getParent(),NULL,Inst->getNormalDest());
}


void MSILWriter::printSwitchInstruction(const SwitchInst* Inst) {
  // FIXME: Emulate with IL "switch" instruction
  // Emulate = if () else if () else if () else ...
  for (unsigned int I = 1, E = Inst->getNumCases(); I!=E; ++I) {
    printValueLoad(Inst->getCondition());
    printValueLoad(Inst->getCaseValue(I));
    printSimpleInstruction("ceq");
    // Condition jump to successor block
    printBranchToBlock(Inst->getParent(),Inst->getSuccessor(I),NULL);
  }
  // Jump to default block
  printBranchToBlock(Inst->getParent(),NULL,Inst->getDefaultDest());
}


void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
  printIndirectLoad(Inst->getOperand(0));
  printSimpleInstruction("call",
    "instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
  printSimpleInstruction("refanyval","void*");
  std::string Name = "ldind."+getTypePostfix(PointerType::get(IntegerType::get(8)),false);
  printSimpleInstruction(Name.c_str());
}


void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
  uint64_t Size = TD->getTypeSize(Inst->getAllocatedType());
  // Constant optimization.
  if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
    printPtrLoad(CInt->getZExtValue()*Size);
  } else {
    printPtrLoad(Size);
    printValueLoad(Inst->getOperand(0));
    printSimpleInstruction("mul");
  }
  printSimpleInstruction("localloc");
}


void MSILWriter::printInstruction(const Instruction* Inst) {
  const Value *Left = 0, *Right = 0;
  if (Inst->getNumOperands()>=1) Left = Inst->getOperand(0);
  if (Inst->getNumOperands()>=2) Right = Inst->getOperand(1);
  // Print instruction
  // FIXME: "ShuffleVector","ExtractElement","InsertElement" support.
  switch (Inst->getOpcode()) {
  // Terminator
  case Instruction::Ret:
    if (Inst->getNumOperands()) {
      printValueLoad(Left);
      printSimpleInstruction("ret");
    } else
      printSimpleInstruction("ret");
    break;
  case Instruction::Br:
    printBranchInstruction(cast<BranchInst>(Inst));
    break;
  // Binary
  case Instruction::Add:
    printBinaryInstruction("add",Left,Right);
    break;
  case Instruction::Sub:
    printBinaryInstruction("sub",Left,Right);
    break;
  case Instruction::Mul:  
    printBinaryInstruction("mul",Left,Right);
    break;
  case Instruction::UDiv:
    printBinaryInstruction("div.un",Left,Right);
    break;
  case Instruction::SDiv:
  case Instruction::FDiv:
    printBinaryInstruction("div",Left,Right);
    break;
  case Instruction::URem:
    printBinaryInstruction("rem.un",Left,Right);
    break;
  case Instruction::SRem:
  case Instruction::FRem:
    printBinaryInstruction("rem",Left,Right);
    break;
  // Binary Condition
  case Instruction::ICmp:
    printICmpInstruction(cast<ICmpInst>(Inst)->getPredicate(),Left,Right);
    break;
  case Instruction::FCmp:
    printFCmpInstruction(cast<FCmpInst>(Inst)->getPredicate(),Left,Right);
    break;
  // Bitwise Binary
  case Instruction::And:
    printBinaryInstruction("and",Left,Right);
    break;
  case Instruction::Or:
    printBinaryInstruction("or",Left,Right);
    break;
  case Instruction::Xor:
    printBinaryInstruction("xor",Left,Right);
    break;
  case Instruction::Shl:
    printValueLoad(Left);
    printValueLoad(Right);
    printSimpleInstruction("conv.i4");
    printSimpleInstruction("shl");
    break;
  case Instruction::LShr:
    printValueLoad(Left);
    printValueLoad(Right);
    printSimpleInstruction("conv.i4");
    printSimpleInstruction("shr.un");
    break;
  case Instruction::AShr:
    printValueLoad(Left);
    printValueLoad(Right);
    printSimpleInstruction("conv.i4");
    printSimpleInstruction("shr");
    break;
  case Instruction::Select:
    printSelectInstruction(Inst->getOperand(0),Inst->getOperand(1),Inst->getOperand(2));
    break;
  case Instruction::Load:
    printIndirectLoad(Inst->getOperand(0));
    break;
  case Instruction::Store:
    printIndirectSave(Inst->getOperand(1), Inst->getOperand(0));
    break;
  case Instruction::Trunc:
  case Instruction::ZExt:
  case Instruction::SExt:
  case Instruction::FPTrunc:
  case Instruction::FPExt:
  case Instruction::UIToFP:
  case Instruction::SIToFP:
  case Instruction::FPToUI:
  case Instruction::FPToSI:
  case Instruction::PtrToInt:
  case Instruction::IntToPtr:
  case Instruction::BitCast:
    printCastInstruction(Inst->getOpcode(),Left,
                         cast<CastInst>(Inst)->getDestTy());
    break;
  case Instruction::GetElementPtr:
    printGepInstruction(Inst->getOperand(0),gep_type_begin(Inst),
                        gep_type_end(Inst));
    break;
  case Instruction::Call:
    printCallInstruction(cast<CallInst>(Inst));
    break;
  case Instruction::Invoke:
    printInvokeInstruction(cast<InvokeInst>(Inst));
    break;
  case Instruction::Unwind:
    printSimpleInstruction("newobj",
      "instance void [mscorlib]System.Exception::.ctor()");
    printSimpleInstruction("throw");
    break;
  case Instruction::Switch:
    printSwitchInstruction(cast<SwitchInst>(Inst));
    break;
  case Instruction::Alloca:
    printAllocaInstruction(cast<AllocaInst>(Inst));
    break;
  case Instruction::Malloc:
    assert(0 && "LowerAllocationsPass used");
    break;
  case Instruction::Free:
    assert(0 && "LowerAllocationsPass used");
    break;
  case Instruction::Unreachable:
    printSimpleInstruction("ldstr", "\"Unreachable instruction\"");
    printSimpleInstruction("newobj",
      "instance void [mscorlib]System.Exception::.ctor(string)");
    printSimpleInstruction("throw");
    break;
  case Instruction::VAArg:
    printVAArgInstruction(cast<VAArgInst>(Inst));
    break;
  default:
    cerr << "Instruction = " << Inst->getName() << '\n';
    assert(0 && "Unsupported instruction");
  }
}


void MSILWriter::printLoop(const Loop* L) {
  Out << getLabelName(L->getHeader()->getName()) << ":\n";
  const std::vector<BasicBlock*>& blocks = L->getBlocks();
  for (unsigned I = 0, E = blocks.size(); I!=E; I++) {
    BasicBlock* BB = blocks[I];
    Loop* BBLoop = LInfo->getLoopFor(BB);
    if (BBLoop == L)
      printBasicBlock(BB);
    else if (BB==BBLoop->getHeader() && BBLoop->getParentLoop()==L)
      printLoop(BBLoop);
  }
  printSimpleInstruction("br",getLabelName(L->getHeader()->getName()).c_str());
}


void MSILWriter::printBasicBlock(const BasicBlock* BB) {
  Out << getLabelName(BB) << ":\n";
  for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
    const Instruction* Inst = I;
    // Comment llvm original instruction
    Out << "\n//" << *Inst << "\n";
    // Do not handle PHI instruction in current block
    if (Inst->getOpcode()==Instruction::PHI) continue;
    // Print instruction
    printInstruction(Inst);
    // Save result
    if (Inst->getType()!=Type::VoidTy) {
      // Do not save value after invoke, it done in "try" block
      if (Inst->getOpcode()==Instruction::Invoke) continue;
      printValueSave(Inst);
    }
  }
}


void MSILWriter::printLocalVariables(const Function& F) {
  std::string Name;
  const Type* Ty = NULL;
  std::set<const Value*> Printed;
  const Value* VaList = NULL;
  unsigned StackDepth = 8;
  // Find local variables
  for (const_inst_iterator I = inst_begin(&F), E = inst_end(&F); I!=E; ++I) {
    if (I->getOpcode()==Instruction::Call ||
        I->getOpcode()==Instruction::Invoke) {
      // Test stack depth.
      if (StackDepth<I->getNumOperands())
        StackDepth = I->getNumOperands();
    }
    const AllocaInst* AI = dyn_cast<AllocaInst>(&*I);
    if (AI && !isa<GlobalVariable>(AI)) {
      // Local variable allocation.
      Ty = PointerType::get(AI->getAllocatedType());
      Name = getValueName(AI);
      Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
    } else if (I->getType()!=Type::VoidTy) {
      // Operation result.
      Ty = I->getType();
      Name = getValueName(&*I);
      Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
    }
    // Test on 'va_list' variable    
    bool isVaList = false;     
    if (const VAArgInst* VaInst = dyn_cast<VAArgInst>(&*I)) {
      // "va_list" as "va_arg" instruction operand.
      isVaList = true;
      VaList = VaInst->getOperand(0);
    } else if (const IntrinsicInst* Inst = dyn_cast<IntrinsicInst>(&*I)) {
      // "va_list" as intrinsic function operand. 
      switch (Inst->getIntrinsicID()) {
      case Intrinsic::vastart:
      case Intrinsic::vaend:
      case Intrinsic::vacopy:
        isVaList = true;
        VaList = Inst->getOperand(1);
        break;
      default:
        isVaList = false;
      }
    }
    // Print "va_list" variable.
    if (isVaList && Printed.insert(VaList).second) {
      Name = getValueName(VaList);
      Name.insert(Name.length()-1,"$valist");
      Out << "\t.locals (valuetype [mscorlib]System.ArgIterator "
          << Name << ")\n";
    }
  }
  printSimpleInstruction(".maxstack",utostr(StackDepth*2).c_str());
}


void MSILWriter::printFunctionBody(const Function& F) {
  // Print body
  for (Function::const_iterator I = F.begin(), E = F.end(); I!=E; ++I) {
    if (Loop *L = LInfo->getLoopFor(I)) {
      if (L->getHeader()==I && L->getParentLoop()==0)
        printLoop(L);
    } else {
      printBasicBlock(I);
    }
  }
}


void MSILWriter::printConstantExpr(const ConstantExpr* CE) {
  const Value *left = 0, *right = 0;
  if (CE->getNumOperands()>=1) left = CE->getOperand(0);
  if (CE->getNumOperands()>=2) right = CE->getOperand(1);
  // Print instruction
  switch (CE->getOpcode()) {
  case Instruction::Trunc:
  case Instruction::ZExt:
  case Instruction::SExt:
  case Instruction::FPTrunc:
  case Instruction::FPExt:
  case Instruction::UIToFP:
  case Instruction::SIToFP:
  case Instruction::FPToUI:
  case Instruction::FPToSI:
  case Instruction::PtrToInt:
  case Instruction::IntToPtr:
  case Instruction::BitCast:
    printCastInstruction(CE->getOpcode(),left,CE->getType());
    break;
  case Instruction::GetElementPtr:
    printGepInstruction(CE->getOperand(0),gep_type_begin(CE),gep_type_end(CE));
    break;
  case Instruction::ICmp:
    printICmpInstruction(CE->getPredicate(),left,right);
    break;
  case Instruction::FCmp:
    printFCmpInstruction(CE->getPredicate(),left,right);
    break;
  case Instruction::Select:
    printSelectInstruction(CE->getOperand(0),CE->getOperand(1),CE->getOperand(2));
    break;
  case Instruction::Add:
    printBinaryInstruction("add",left,right);
    break;
  case Instruction::Sub:
    printBinaryInstruction("sub",left,right);
    break;
  case Instruction::Mul:
    printBinaryInstruction("mul",left,right);
    break;
  case Instruction::UDiv:
    printBinaryInstruction("div.un",left,right);
    break;
  case Instruction::SDiv:
  case Instruction::FDiv:
    printBinaryInstruction("div",left,right);
    break;
  case Instruction::URem:
    printBinaryInstruction("rem.un",left,right);
    break;
  case Instruction::SRem:
  case Instruction::FRem:
    printBinaryInstruction("rem",left,right);
    break;
  case Instruction::And:
    printBinaryInstruction("and",left,right);
    break;
  case Instruction::Or:
    printBinaryInstruction("or",left,right);
    break;
  case Instruction::Xor:
    printBinaryInstruction("xor",left,right);
    break;
  case Instruction::Shl:
    printBinaryInstruction("shl",left,right);
    break;
  case Instruction::LShr:
    printBinaryInstruction("shr.un",left,right);
    break;
  case Instruction::AShr:
    printBinaryInstruction("shr",left,right);
    break;
  default:
    cerr << "Expression = " << *CE << "\n";
    assert(0 && "Invalid constant expression");
  }
}


void MSILWriter::printStaticInitializerList() {
  // List of global variables with uninitialized fields.
  for (std::map<const GlobalVariable*,std::vector<StaticInitializer> >::iterator
       VarI = StaticInitList.begin(), VarE = StaticInitList.end(); VarI!=VarE;
       ++VarI) {
    const std::vector<StaticInitializer>& InitList = VarI->second;
    if (InitList.empty()) continue;
    // For each uninitialized field.
    for (std::vector<StaticInitializer>::const_iterator I = InitList.begin(),
         E = InitList.end(); I!=E; ++I) {
      if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(I->constant)) {
        Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
          utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
        // Load variable address
        printValueLoad(VarI->first);
        // Add offset
        if (I->offset!=0) {
          printPtrLoad(I->offset);
          printSimpleInstruction("add");
        }
        // Load value
        printConstantExpr(CE);
        // Save result at offset
        std::string postfix = getTypePostfix(CE->getType(),true);
        if (*postfix.begin()=='u') *postfix.begin() = 'i';
        postfix = "stind."+postfix;
        printSimpleInstruction(postfix.c_str());
      } else {
        cerr << "Constant = " << *I->constant << '\n';
        assert(0 && "Invalid static initializer");
      }
    }
  }
}


void MSILWriter::printFunction(const Function& F) {
  const FunctionType* FTy = F.getFunctionType();
  const ParamAttrsList *Attrs = FTy->getParamAttrs();
  bool isSigned = Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt);
  Out << "\n.method static ";
  Out << (F.hasInternalLinkage() ? "private " : "public ");
  if (F.isVarArg()) Out << "vararg ";
  Out << getTypeName(F.getReturnType(),isSigned) << 
    getConvModopt(F.getCallingConv()) << getValueName(&F) << '\n';
  // Arguments
  Out << "\t(";
  unsigned ArgIdx = 1;
  for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E;
       ++I, ++ArgIdx) {
    isSigned = Attrs && Attrs->paramHasAttr(ArgIdx, ParamAttr::SExt);
    if (I!=F.arg_begin()) Out << ", ";
    Out << getTypeName(I->getType(),isSigned) << getValueName(I);
  }
  Out << ") cil managed\n";
  // Body
  Out << "{\n";
  printLocalVariables(F);
  printFunctionBody(F);
  Out << "}\n";
}


void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
  std::string Name;
  std::set<const Type*> Printed;
  for (std::set<const Type*>::const_iterator
       UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) {
    const Type* Ty = *UI;
    if (isa<ArrayType>(Ty) || isa<VectorType>(Ty) || isa<StructType>(Ty))
      Name = getTypeName(Ty, false, true);
    // Type with no need to declare.
    else continue;
    // Print not duplicated type
    if (Printed.insert(Ty).second) {
      Out << ".class value explicit ansi sealed '" << Name << "'";
      Out << " { .pack " << 1 << " .size " << TD->getTypeSize(Ty) << " }\n\n";
    }
  }
}


unsigned int MSILWriter::getBitWidth(const Type* Ty) {
  unsigned int N = Ty->getPrimitiveSizeInBits();
  assert(N!=0 && "Invalid type in getBitWidth()");
  switch (N) {
  case 1:
  case 8:
  case 16:
  case 32:
  case 64:
    return N;
  default:
    cerr << "Bits = " << N << '\n';
    assert(0 && "Unsupported integer width");
  }
}


void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
  uint64_t TySize = 0;
  const Type* Ty = C->getType();
  // Print zero initialized constant.
  if (isa<ConstantAggregateZero>(C) || C->isNullValue()) {
    TySize = TD->getTypeSize(C->getType());
    Offset += TySize;
    Out << "int8 (0) [" << TySize << "]";
    return;
  }
  // Print constant initializer
  switch (Ty->getTypeID()) {
  case Type::IntegerTyID: {
    TySize = TD->getTypeSize(Ty);
    const ConstantInt* Int = cast<ConstantInt>(C);
    Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
    break;
  }
  case Type::FloatTyID:
  case Type::DoubleTyID: {
    TySize = TD->getTypeSize(Ty);
    const ConstantFP* FP = cast<ConstantFP>(C);
    if (Ty->getTypeID() == Type::FloatTyID)
      Out << "int32 (" << 
        (uint32_t)*FP->getValueAPF().convertToAPInt().getRawData() << ')';
    else
      Out << "int64 (" << 
        *FP->getValueAPF().convertToAPInt().getRawData() << ')';
    break;
  }
  case Type::ArrayTyID:
  case Type::VectorTyID:
  case Type::StructTyID:
    for (unsigned I = 0, E = C->getNumOperands(); I<E; I++) {
      if (I!=0) Out << ",\n";
      printStaticConstant(C->getOperand(I),Offset);
    }
    break;
  case Type::PointerTyID:
    TySize = TD->getTypeSize(C->getType());
    // Initialize with global variable address
    if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
      std::string name = getValueName(G);
      Out << "&(" << name.insert(name.length()-1,"$data") << ")";
    } else {
      // Dynamic initialization
      if (!isa<ConstantPointerNull>(C) && !C->isNullValue())
        InitListPtr->push_back(StaticInitializer(C,Offset));
      // Null pointer initialization
      if (TySize==4) Out << "int32 (0)";
      else if (TySize==8) Out << "int64 (0)";
      else assert(0 && "Invalid pointer size");
    }
    break;
  default:
    cerr << "TypeID = " << Ty->getTypeID() << '\n';
    assert(0 && "Invalid type in printStaticConstant()");
  }
  // Increase offset.
  Offset += TySize;
}


void MSILWriter::printStaticInitializer(const Constant* C,
                                        const std::string& Name) {
  switch (C->getType()->getTypeID()) {
  case Type::IntegerTyID:
  case Type::FloatTyID:
  case Type::DoubleTyID: 
    Out << getPrimitiveTypeName(C->getType(), false);
    break;
  case Type::ArrayTyID:
  case Type::VectorTyID:
  case Type::StructTyID:
  case Type::PointerTyID:
    Out << getTypeName(C->getType());
    break;
  default:
    cerr << "Type = " << *C << "\n";
    assert(0 && "Invalid constant type");
  }
  // Print initializer
  std::string label = Name;
  label.insert(label.length()-1,"$data");
  Out << Name << " at " << label << '\n';
  Out << ".data " << label << " = {\n";
  uint64_t offset = 0;
  printStaticConstant(C,offset);
  Out << "\n}\n\n";
}


void MSILWriter::printVariableDefinition(const GlobalVariable* G) {
  const Constant* C = G->getInitializer();
  if (C->isNullValue() || isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
    InitListPtr = 0;
  else
    InitListPtr = &StaticInitList[G];
  printStaticInitializer(C,getValueName(G));
}


void MSILWriter::printGlobalVariables() {
  if (ModulePtr->global_empty()) return;
  Module::global_iterator I,E;
  for (I = ModulePtr->global_begin(), E = ModulePtr->global_end(); I!=E; ++I) {
    // Variable definition
    Out << ".field static " << (I->isDeclaration() ? "public " :
                                                     "private ");
    if (I->isDeclaration()) {
      Out << getTypeName(I->getType()) << getValueName(&*I) << "\n\n";
    } else
      printVariableDefinition(&*I);
  }
}


const char* MSILWriter::getLibraryName(const Function* F) {
  return getLibraryForSymbol(F->getName().c_str(), true, F->getCallingConv());
}


const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
  return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0);
}


const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction,
                                           unsigned CallingConv) {
  // TODO: Read *.def file with function and libraries definitions.
  return "MSVCRT.DLL";  
}


void MSILWriter::printExternals() {
  Module::const_iterator I,E;
  // Functions.
  for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
    // Skip intrisics
    if (I->getIntrinsicID()) continue;
    if (I->isDeclaration()) {
      const Function* F = I; 
      std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
      std::string Sig = 
        getCallSignature(cast<FunctionType>(F->getFunctionType()), NULL, Name);
      Out << ".method static hidebysig pinvokeimpl(\""
          << getLibraryName(F) << "\")\n\t" << Sig << " preservesig {}\n\n";
    }
  }
  // External variables and static initialization.
  Out <<
  ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
  "  native int LoadLibrary(string) preservesig {}\n"
  ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
  "  native int GetProcAddress(native int, string) preservesig {}\n";
  Out <<
  ".method private static void* $MSIL_Import(string lib,string sym)\n"
  " managed cil\n{\n"
  "\tldarg\tlib\n"
  "\tcall\tnative int LoadLibrary(string)\n"
  "\tldarg\tsym\n"
  "\tcall\tnative int GetProcAddress(native int,string)\n"
  "\tdup\n"
  "\tbrtrue\tL_01\n"
  "\tldstr\t\"Can no import variable\"\n"
  "\tnewobj\tinstance void [mscorlib]System.Exception::.ctor(string)\n"
  "\tthrow\n"
  "L_01:\n"
  "\tret\n"
  "}\n\n"
  ".method static private void $MSIL_Init() managed cil\n{\n";
  printStaticInitializerList();
  // Foreach global variable.
  for (Module::global_iterator I = ModulePtr->global_begin(),
       E = ModulePtr->global_end(); I!=E; ++I) {
    if (!I->isDeclaration() || !I->hasDLLImportLinkage()) continue;
    // Use "LoadLibrary"/"GetProcAddress" to recive variable address.
    std::string Label = "not_null$_"+utostr(getUniqID());
    std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
    printSimpleInstruction("ldsflda",Tmp.c_str());
    Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
    Out << "\tldstr\t\"" << Mang->getValueName(&*I) << "\"\n";
    printSimpleInstruction("call","void* $MSIL_Import(string,string)");
    printIndirectSave(I->getType());
  }
  printSimpleInstruction("ret");
  Out << "}\n\n";
}


//===----------------------------------------------------------------------===//
//			 External Interface declaration
//===----------------------------------------------------------------------===//

bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
                                          CodeGenFileType FileType, bool Fast)
{
  if (FileType != TargetMachine::AssemblyFile) return true;
  MSILWriter* Writer = new MSILWriter(o);
  PM.add(createLowerGCPass());
  PM.add(createLowerAllocationsPass(true));
  // FIXME: Handle switch trougth native IL instruction "switch"
  PM.add(createLowerSwitchPass());
  PM.add(createCFGSimplificationPass());
  PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
  PM.add(Writer);
  return false;
}
