//===-- 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");
    break;        
  default:
    errs() << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n';
    llvm_unreachable("Invalid intrinsic function");
  }
}


void MSILWriter::printCallInstruction(const Instruction* Inst) {
  if (isa<IntrinsicInst>(Inst)) {
    // Handle intrinsic function.
    printIntrinsicCall(cast<IntrinsicInst>(Inst));
  } else {
    const CallInst *CI = cast<CallInst>(Inst);
    // Load arguments to stack and call function.
    for (int I = 0, E = CI->getNumArgOperands(); I!=E; ++I)
      printValueLoad(CI->getArgOperand(I));
    printFunctionCall(CI->getCalledFunction(), 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);
    break;
  case ICmpInst::ICMP_SGT:
    printBinaryInstruction("cgt",Left,Right);
    break;
  default:
    errs() << "Predicate = " << Predicate << '\n';
    llvm_unreachable("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:
    llvm_unreachable("Illegal FCmp predicate");
  }
}


void MSILWriter::printInvokeInstruction(const InvokeInst* Inst) {
  std::string Label = "leave$normal_"+utostr(getUniqID());
  Out << ".try {\n";
  // Load arguments
  for (int I = 0, E = Inst->getNumArgOperands(); I!=E; ++I)
    printValueLoad(Inst->getArgOperand(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::getUnqual(
            IntegerType::get(Inst->getContext(), 8)),false);
  printSimpleInstruction(Name.c_str());
}


void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
  uint64_t Size = TD->getTypeAllocSize(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:
  case Instruction::FAdd:
    printBinaryInstruction("add",Left,Right);
    break;
  case Instruction::Sub:
  case Instruction::FSub:
    printBinaryInstruction("sub",Left,Right);
    break;
  case Instruction::Mul:
  case Instruction::FMul:
    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::SExt:
    printCastInstruction(Inst->getOpcode(),Left,
                         cast<CastInst>(Inst)->getDestTy(),
                         cast<CastInst>(Inst)->getSrcTy());
    break;
  case Instruction::Trunc:
  case Instruction::ZExt:
  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::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:
    errs() << "Instruction = " << Inst->getName() << '\n';
    llvm_unreachable("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::getVoidTy(BB->getContext())) {
      // 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::getUnqual(AI->getAllocatedType());
      Name = getValueName(AI);
      Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
    } else if (I->getType()!=Type::getVoidTy(F.getContext())) {
      // 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->getArgOperand(0);
        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:
  case Instruction::FAdd:
    printBinaryInstruction("add",left,right);
    break;
  case Instruction::Sub:
  case Instruction::FSub:
    printBinaryInstruction("sub",left,right);
    break;
  case Instruction::Mul:
  case Instruction::FMul:
    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:
    errs() << "Expression = " << *CE << "\n";
    llvm_unreachable("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 {
        errs() << "Constant = " << *I->constant << '\n';
        llvm_unreachable("Invalid static initializer");
      }
    }
  }
}


void MSILWriter::printFunction(const Function& F) {
  bool isSigned = F.paramHasAttr(0, Attribute::SExt);
  Out << "\n.method static ";
  Out << (F.hasLocalLinkage() ? "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 = F.paramHasAttr(ArgIdx, Attribute::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 (Ty->isArrayTy() || Ty->isVectorTy() || Ty->isStructTy())
      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->getTypeAllocSize(Ty);
      Out << " }\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:
    errs() << "Bits = " << N << '\n';
    llvm_unreachable("Unsupported integer width");
  }
  return 0; // Not reached
}


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->getTypeAllocSize(C->getType());
    Offset += TySize;
    Out << "int8 (0) [" << TySize << "]";
    return;
  }
  // Print constant initializer
  switch (Ty->getTypeID()) {
  case Type::IntegerTyID: {
    TySize = TD->getTypeAllocSize(Ty);
    const ConstantInt* Int = cast<ConstantInt>(C);
    Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
    break;
  }
  case Type::FloatTyID:
  case Type::DoubleTyID: {
    TySize = TD->getTypeAllocSize(Ty);
    const ConstantFP* FP = cast<ConstantFP>(C);
    if (Ty->getTypeID() == Type::FloatTyID)
      Out << "int32 (" << 
        (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
    else
      Out << "int64 (" << 
        FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
    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(cast<Constant>(C->getOperand(I)), Offset);
    }
    break;
  case Type::PointerTyID:
    TySize = TD->getTypeAllocSize(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 llvm_unreachable("Invalid pointer size");
    }
    break;
  default:
    errs() << "TypeID = " << Ty->getTypeID() << '\n';
    llvm_unreachable("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:
    errs() << "Type = " << *C << "\n";
    llvm_unreachable("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(), true, F->getCallingConv());
}


const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
  return getLibraryForSymbol(GV->getName(), false, CallingConv::C);
}


const char* MSILWriter::getLibraryForSymbol(StringRef Name, bool isFunction,
                                            CallingConv::ID 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->isIntrinsic()) 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 Tmp = getTypeName(I->getType())+getValueName(&*I);
    printSimpleInstruction("ldsflda",Tmp.c_str());
    Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
    Out << "\tldstr\t\"" << I->getName() << "\"\n";
    printSimpleInstruction("call","void* $MSIL_Import(string,string)");
    printIndirectSave(I->getType());
  }
  printSimpleInstruction("ret");
  Out << "}\n\n";
}


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

bool MSILTarget::addPassesToEmitFile(PassManagerBase &PM,
                                     formatted_raw_ostream &o,
                                     CodeGenFileType FileType,
                                     CodeGenOpt::Level OptLevel,
                                     bool DisableVerify)
{
  if (FileType != TargetMachine::CGFT_AssemblyFile) return true;
  MSILWriter* Writer = new MSILWriter(o);
  PM.add(createGCLoweringPass());
  // FIXME: Handle switch through native IL instruction "switch"
  PM.add(createLowerSwitchPass());
  PM.add(createCFGSimplificationPass());
  PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
  PM.add(Writer);
  PM.add(createGCInfoDeleter());
  return false;
}
