Enabling the target-independent garbage collection infrastructure by hooking it
[oota-llvm.git] / lib / Target / MSIL / MSILWriter.cpp
1 //===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This library converts LLVM code to MSIL code.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MSILWriter.h"
15 #include "llvm/CallingConv.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Intrinsics.h"
18 #include "llvm/IntrinsicInst.h"
19 #include "llvm/ParameterAttributes.h"
20 #include "llvm/TypeSymbolTable.h"
21 #include "llvm/Analysis/ConstantsScanner.h"
22 #include "llvm/Support/CallSite.h"
23 #include "llvm/Support/InstVisitor.h"
24 #include "llvm/Support/MathExtras.h"
25 #include "llvm/Transforms/Scalar.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/CodeGen/Passes.h"
28
29 namespace {
30   // TargetMachine for the MSIL 
31   struct VISIBILITY_HIDDEN MSILTarget : public TargetMachine {
32     const TargetData DataLayout;       // Calculates type size & alignment
33
34     MSILTarget(const Module &M, const std::string &FS)
35       : DataLayout(&M) {}
36
37     virtual bool WantsWholeFile() const { return true; }
38     virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
39                                          CodeGenFileType FileType, bool Fast);
40
41     // This class always works, but shouldn't be the default in most cases.
42     static unsigned getModuleMatchQuality(const Module &M) { return 1; }
43
44     virtual const TargetData *getTargetData() const { return &DataLayout; }
45   };
46 }
47
48
49 RegisterTarget<MSILTarget> X("msil", "  MSIL backend");
50
51 bool MSILModule::runOnModule(Module &M) {
52   ModulePtr = &M;
53   TD = &getAnalysis<TargetData>();
54   bool Changed = false;
55   // Find named types.  
56   TypeSymbolTable& Table = M.getTypeSymbolTable();
57   std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes();
58   for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) {
59     if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second))
60       Table.remove(I++);
61     else {
62       std::set<const Type *>::iterator T = Types.find(I->second);
63       if (T==Types.end())
64         Table.remove(I++);
65       else {
66         Types.erase(T);
67         ++I;
68       }
69     }
70   }
71   // Find unnamed types.
72   unsigned RenameCounter = 0;
73   for (std::set<const Type *>::const_iterator I = Types.begin(),
74        E = Types.end(); I!=E; ++I)
75     if (const StructType *STy = dyn_cast<StructType>(*I)) {
76       while (ModulePtr->addTypeName("unnamed$"+utostr(RenameCounter), STy))
77         ++RenameCounter;
78       Changed = true;
79     }
80   // Pointer for FunctionPass.
81   UsedTypes = &getAnalysis<FindUsedTypes>().getTypes();
82   return Changed;
83 }
84
85 char MSILModule::ID = 0;
86 char MSILWriter::ID = 0;
87
88 bool MSILWriter::runOnFunction(Function &F) {
89   if (F.isDeclaration()) return false;
90   LInfo = &getAnalysis<LoopInfo>();
91   printFunction(F);
92   return false;
93 }
94
95
96 bool MSILWriter::doInitialization(Module &M) {
97   ModulePtr = &M;
98   Mang = new Mangler(M);
99   Out << ".assembly extern mscorlib {}\n";
100   Out << ".assembly MSIL {}\n\n";
101   Out << "// External\n";
102   printExternals();
103   Out << "// Declarations\n";
104   printDeclarations(M.getTypeSymbolTable());
105   Out << "// Definitions\n";
106   printGlobalVariables();
107   Out << "// Startup code\n";
108   printModuleStartup();
109   return false;
110 }
111
112
113 bool MSILWriter::doFinalization(Module &M) {
114   delete Mang;
115   return false;
116 }
117
118
119 void MSILWriter::printModuleStartup() {
120   Out <<
121   ".method static public int32 $MSIL_Startup() {\n"
122   "\t.entrypoint\n"
123   "\t.locals (native int i)\n"
124   "\t.locals (native int argc)\n"
125   "\t.locals (native int ptr)\n"
126   "\t.locals (void* argv)\n"
127   "\t.locals (string[] args)\n"
128   "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n"
129   "\tdup\n"
130   "\tstloc\targs\n"
131   "\tldlen\n"
132   "\tconv.i4\n"
133   "\tdup\n"
134   "\tstloc\targc\n";
135   printPtrLoad(TD->getPointerSize());
136   Out <<
137   "\tmul\n"
138   "\tlocalloc\n"
139   "\tstloc\targv\n"
140   "\tldc.i4.0\n"
141   "\tstloc\ti\n"
142   "L_01:\n"
143   "\tldloc\ti\n"
144   "\tldloc\targc\n"
145   "\tceq\n"
146   "\tbrtrue\tL_02\n"
147   "\tldloc\targs\n"
148   "\tldloc\ti\n"
149   "\tldelem.ref\n"
150   "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::"
151            "StringToHGlobalAnsi(string)\n"
152   "\tstloc\tptr\n"
153   "\tldloc\targv\n"
154   "\tldloc\ti\n";
155   printPtrLoad(TD->getPointerSize());
156   Out << 
157   "\tmul\n"
158   "\tadd\n"
159   "\tldloc\tptr\n"
160   "\tstind.i\n"
161   "\tldloc\ti\n"
162   "\tldc.i4.1\n"
163   "\tadd\n"
164   "\tstloc\ti\n"
165   "\tbr\tL_01\n"
166   "L_02:\n"
167   "\tcall void $MSIL_Init()\n";
168
169   // Call user 'main' function.
170   const Function* F = ModulePtr->getFunction("main");
171   if (!F || F->isDeclaration()) {
172     Out << "\tldc.i4.0\n\tret\n}\n";
173     return;
174   }
175   bool BadSig = true;;
176   std::string Args("");
177   Function::const_arg_iterator Arg1,Arg2;
178
179   switch (F->arg_size()) {
180   case 0:
181     BadSig = false;
182     break;
183   case 1:
184     Arg1 = F->arg_begin();
185     if (Arg1->getType()->isInteger()) {
186       Out << "\tldloc\targc\n";
187       Args = getTypeName(Arg1->getType());
188       BadSig = false;
189     }
190     break;
191   case 2:
192     Arg1 = Arg2 = F->arg_begin(); ++Arg2;
193     if (Arg1->getType()->isInteger() && 
194         Arg2->getType()->getTypeID() == Type::PointerTyID) {
195       Out << "\tldloc\targc\n\tldloc\targv\n";
196       Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType());
197       BadSig = false;
198     }
199     break;
200   default:
201     BadSig = true;
202   }
203
204   bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
205   if (BadSig || !F->getReturnType()->isInteger() && !RetVoid) {
206     Out << "\tldc.i4.0\n";
207   } else {
208     Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
209       getConvModopt(F->getCallingConv()) << "main(" << Args << ")\n";
210     if (RetVoid)
211       Out << "\tldc.i4.0\n";
212     else
213       Out << "\tconv.i4\n";
214   }
215   Out << "\tret\n}\n";
216 }
217
218 bool MSILWriter::isZeroValue(const Value* V) {
219   if (const Constant *C = dyn_cast<Constant>(V))
220     return C->isNullValue();
221   return false;
222 }
223
224
225 std::string MSILWriter::getValueName(const Value* V) {
226   // Name into the quotes allow control and space characters.
227   return "'"+Mang->getValueName(V)+"'";
228 }
229
230
231 std::string MSILWriter::getLabelName(const std::string& Name) {
232   if (Name.find('.')!=std::string::npos) {
233     std::string Tmp(Name);
234     // Replace unaccepable characters in the label name.
235     for (std::string::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I)
236       if (*I=='.') *I = '@';
237     return Tmp;
238   }
239   return Name;
240 }
241
242
243 std::string MSILWriter::getLabelName(const Value* V) {
244   return getLabelName(Mang->getValueName(V));
245 }
246
247
248 std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
249   switch (CallingConvID) {
250   case CallingConv::C:
251   case CallingConv::Cold:
252   case CallingConv::Fast:
253     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) ";
254   case CallingConv::X86_FastCall:
255     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) ";
256   case CallingConv::X86_StdCall:
257     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
258   default:
259     cerr << "CallingConvID = " << CallingConvID << '\n';
260     assert(0 && "Unsupported calling convention");
261   }
262 }
263
264
265 std::string MSILWriter::getArrayTypeName(Type::TypeID TyID, const Type* Ty) {
266   std::string Tmp = "";
267   const Type* ElemTy = Ty;
268   assert(Ty->getTypeID()==TyID && "Invalid type passed");
269   // Walk trought array element types.
270   for (;;) {
271     // Multidimensional array.
272     if (ElemTy->getTypeID()==TyID) {
273       if (const ArrayType* ATy = dyn_cast<ArrayType>(ElemTy))
274         Tmp += utostr(ATy->getNumElements());
275       else if (const VectorType* VTy = dyn_cast<VectorType>(ElemTy))
276         Tmp += utostr(VTy->getNumElements());
277       ElemTy = cast<SequentialType>(ElemTy)->getElementType();
278     }
279     // Base element type found.
280     if (ElemTy->getTypeID()!=TyID) break;
281     Tmp += ",";
282   }
283   return getTypeName(ElemTy, false, true)+"["+Tmp+"]";
284 }
285
286
287 std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
288   unsigned NumBits = 0;
289   switch (Ty->getTypeID()) {
290   case Type::VoidTyID:
291     return "void ";
292   case Type::IntegerTyID:
293     NumBits = getBitWidth(Ty);
294     if(NumBits==1)
295       return "bool ";
296     if (!isSigned)
297       return "unsigned int"+utostr(NumBits)+" ";
298     return "int"+utostr(NumBits)+" ";
299   case Type::FloatTyID:
300     return "float32 ";
301   case Type::DoubleTyID:
302     return "float64 "; 
303   default:
304     cerr << "Type = " << *Ty << '\n';
305     assert(0 && "Invalid primitive type");
306   }
307 }
308
309
310 std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
311                                     bool isNested) {
312   if (Ty->isPrimitiveType() || Ty->isInteger())
313     return getPrimitiveTypeName(Ty,isSigned);
314   // FIXME: "OpaqueType" support
315   switch (Ty->getTypeID()) {
316   case Type::PointerTyID:
317     return "void* ";
318   case Type::StructTyID:
319     if (isNested)
320       return ModulePtr->getTypeName(Ty);
321     return "valuetype '"+ModulePtr->getTypeName(Ty)+"' ";
322   case Type::ArrayTyID:
323     if (isNested)
324       return getArrayTypeName(Ty->getTypeID(),Ty);
325     return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
326   case Type::VectorTyID:
327     if (isNested)
328       return getArrayTypeName(Ty->getTypeID(),Ty);
329     return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
330   default:
331     cerr << "Type = " << *Ty << '\n';
332     assert(0 && "Invalid type in getTypeName()");
333   }
334 }
335
336
337 MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) {
338   // Function argument
339   if (isa<Argument>(V))
340     return ArgumentVT;
341   // Function
342   else if (const Function* F = dyn_cast<Function>(V))
343     return F->hasInternalLinkage() ? InternalVT : GlobalVT;
344   // Variable
345   else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V))
346     return G->hasInternalLinkage() ? InternalVT : GlobalVT;
347   // Constant
348   else if (isa<Constant>(V))
349     return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT;
350   // Local variable
351   return LocalVT;
352 }
353
354
355 std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
356                                        bool isSigned) {
357   unsigned NumBits = 0;
358   switch (Ty->getTypeID()) {
359   // Integer constant, expanding for stack operations.
360   case Type::IntegerTyID:
361     NumBits = getBitWidth(Ty);
362     // Expand integer value to "int32" or "int64".
363     if (Expand) return (NumBits<=32 ? "i4" : "i8");
364     if (NumBits==1) return "i1";
365     return (isSigned ? "i" : "u")+utostr(NumBits/8);
366   // Float constant.
367   case Type::FloatTyID:
368     return "r4";
369   case Type::DoubleTyID:
370     return "r8";
371   case Type::PointerTyID:
372     return "i"+utostr(TD->getABITypeSize(Ty));
373   default:
374     cerr << "TypeID = " << Ty->getTypeID() << '\n';
375     assert(0 && "Invalid type in TypeToPostfix()");
376   }
377 }
378
379
380 void MSILWriter::printConvToPtr() {
381   switch (ModulePtr->getPointerSize()) {
382   case Module::Pointer32:
383     printSimpleInstruction("conv.u4");
384     break;
385   case Module::Pointer64:
386     printSimpleInstruction("conv.u8");
387     break;
388   default:
389     assert(0 && "Module use not supporting pointer size");
390   }
391 }
392
393
394 void MSILWriter::printPtrLoad(uint64_t N) {
395   switch (ModulePtr->getPointerSize()) {
396   case Module::Pointer32:
397     printSimpleInstruction("ldc.i4",utostr(N).c_str());
398     // FIXME: Need overflow test?
399     if (!isUInt32(N)) {
400       cerr << "Value = " << utostr(N) << '\n';
401       assert(0 && "32-bit pointer overflowed");
402     }
403     break;
404   case Module::Pointer64:
405     printSimpleInstruction("ldc.i8",utostr(N).c_str());
406     break;
407   default:
408     assert(0 && "Module use not supporting pointer size");
409   }
410 }
411
412
413 void MSILWriter::printValuePtrLoad(const Value* V) {
414   printValueLoad(V);
415   printConvToPtr();
416 }
417
418
419 void MSILWriter::printConstLoad(const Constant* C) {
420   if (const ConstantInt* CInt = dyn_cast<ConstantInt>(C)) {
421     // Integer constant
422     Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t';
423     if (CInt->isMinValue(true))
424       Out << CInt->getSExtValue();
425     else
426       Out << CInt->getZExtValue();
427   } else if (const ConstantFP* FP = dyn_cast<ConstantFP>(C)) {
428     // Float constant
429     uint64_t X;
430     unsigned Size;
431     if (FP->getType()->getTypeID()==Type::FloatTyID) {
432       X = (uint32_t)FP->getValueAPF().convertToAPInt().getZExtValue();
433       Size = 4;  
434     } else {
435       X = FP->getValueAPF().convertToAPInt().getZExtValue();
436       Size = 8;  
437     }
438     Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
439   } else if (isa<UndefValue>(C)) {
440     // Undefined constant value = NULL.
441     printPtrLoad(0);
442   } else {
443     cerr << "Constant = " << *C << '\n';
444     assert(0 && "Invalid constant value");
445   }
446   Out << '\n';
447 }
448
449
450 void MSILWriter::printValueLoad(const Value* V) {
451   MSILWriter::ValueType Location = getValueLocation(V);
452   switch (Location) {
453   // Global variable or function address.
454   case GlobalVT:
455   case InternalVT:
456     if (const Function* F = dyn_cast<Function>(V)) {
457       std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
458       printSimpleInstruction("ldftn",
459         getCallSignature(F->getFunctionType(),NULL,Name).c_str());
460     } else {
461       std::string Tmp;
462       const Type* ElemTy = cast<PointerType>(V->getType())->getElementType();
463       if (Location==GlobalVT && cast<GlobalVariable>(V)->hasDLLImportLinkage()) {
464         Tmp = "void* "+getValueName(V);
465         printSimpleInstruction("ldsfld",Tmp.c_str());
466       } else {
467         Tmp = getTypeName(ElemTy)+getValueName(V);
468         printSimpleInstruction("ldsflda",Tmp.c_str());
469       }
470     }
471     break;
472   // Function argument.
473   case ArgumentVT:
474     printSimpleInstruction("ldarg",getValueName(V).c_str());
475     break;
476   // Local function variable.
477   case LocalVT:
478     printSimpleInstruction("ldloc",getValueName(V).c_str());
479     break;
480   // Constant value.
481   case ConstVT:
482     if (isa<ConstantPointerNull>(V))
483       printPtrLoad(0);
484     else
485       printConstLoad(cast<Constant>(V));
486     break;
487   // Constant expression.
488   case ConstExprVT:
489     printConstantExpr(cast<ConstantExpr>(V));
490     break;
491   default:
492     cerr << "Value = " << *V << '\n';
493     assert(0 && "Invalid value location");
494   }
495 }
496
497
498 void MSILWriter::printValueSave(const Value* V) {
499   switch (getValueLocation(V)) {
500   case ArgumentVT:
501     printSimpleInstruction("starg",getValueName(V).c_str());
502     break;
503   case LocalVT:
504     printSimpleInstruction("stloc",getValueName(V).c_str());
505     break;
506   default:
507     cerr << "Value  = " << *V << '\n';
508     assert(0 && "Invalid value location");
509   }
510 }
511
512
513 void MSILWriter::printBinaryInstruction(const char* Name, const Value* Left,
514                                         const Value* Right) {
515   printValueLoad(Left);
516   printValueLoad(Right);
517   Out << '\t' << Name << '\n';
518 }
519
520
521 void MSILWriter::printSimpleInstruction(const char* Inst, const char* Operand) {
522   if(Operand) 
523     Out << '\t' << Inst << '\t' << Operand << '\n';
524   else
525     Out << '\t' << Inst << '\n';
526 }
527
528
529 void MSILWriter::printPHICopy(const BasicBlock* Src, const BasicBlock* Dst) {
530   for (BasicBlock::const_iterator I = Dst->begin(), E = Dst->end();
531        isa<PHINode>(I); ++I) {
532     const PHINode* Phi = cast<PHINode>(I);
533     const Value* Val = Phi->getIncomingValueForBlock(Src);
534     if (isa<UndefValue>(Val)) continue;
535     printValueLoad(Val);
536     printValueSave(Phi);
537   }
538 }
539
540
541 void MSILWriter::printBranchToBlock(const BasicBlock* CurrBB,
542                                     const BasicBlock* TrueBB,
543                                     const BasicBlock* FalseBB) {
544   if (TrueBB==FalseBB) {
545     // "TrueBB" and "FalseBB" destination equals
546     printPHICopy(CurrBB,TrueBB);
547     printSimpleInstruction("pop");
548     printSimpleInstruction("br",getLabelName(TrueBB).c_str());
549   } else if (FalseBB==NULL) {
550     // If "FalseBB" not used the jump have condition
551     printPHICopy(CurrBB,TrueBB);
552     printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
553   } else if (TrueBB==NULL) {
554     // If "TrueBB" not used the jump is unconditional
555     printPHICopy(CurrBB,FalseBB);
556     printSimpleInstruction("br",getLabelName(FalseBB).c_str());
557   } else {
558     // Copy PHI instructions for each block
559     std::string TmpLabel;
560     // Print PHI instructions for "TrueBB"
561     if (isa<PHINode>(TrueBB->begin())) {
562       TmpLabel = getLabelName(TrueBB)+"$phi_"+utostr(getUniqID());
563       printSimpleInstruction("brtrue",TmpLabel.c_str());
564     } else {
565       printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
566     }
567     // Print PHI instructions for "FalseBB"
568     if (isa<PHINode>(FalseBB->begin())) {
569       printPHICopy(CurrBB,FalseBB);
570       printSimpleInstruction("br",getLabelName(FalseBB).c_str());
571     } else {
572       printSimpleInstruction("br",getLabelName(FalseBB).c_str());
573     }
574     if (isa<PHINode>(TrueBB->begin())) {
575       // Handle "TrueBB" PHI Copy
576       Out << TmpLabel << ":\n";
577       printPHICopy(CurrBB,TrueBB);
578       printSimpleInstruction("br",getLabelName(TrueBB).c_str());
579     }
580   }
581 }
582
583
584 void MSILWriter::printBranchInstruction(const BranchInst* Inst) {
585   if (Inst->isUnconditional()) {
586     printBranchToBlock(Inst->getParent(),NULL,Inst->getSuccessor(0));
587   } else {
588     printValueLoad(Inst->getCondition());
589     printBranchToBlock(Inst->getParent(),Inst->getSuccessor(0),
590                        Inst->getSuccessor(1));
591   }
592 }
593
594
595 void MSILWriter::printSelectInstruction(const Value* Cond, const Value* VTrue,
596                                         const Value* VFalse) {
597   std::string TmpLabel = std::string("select$true_")+utostr(getUniqID());
598   printValueLoad(VTrue);
599   printValueLoad(Cond);
600   printSimpleInstruction("brtrue",TmpLabel.c_str());
601   printSimpleInstruction("pop");
602   printValueLoad(VFalse);
603   Out << TmpLabel << ":\n";
604 }
605
606
607 void MSILWriter::printIndirectLoad(const Value* V) {
608   const Type* Ty = V->getType();
609   printValueLoad(V);
610   if (const PointerType* P = dyn_cast<PointerType>(Ty))
611     Ty = P->getElementType();
612   std::string Tmp = "ldind."+getTypePostfix(Ty, false);
613   printSimpleInstruction(Tmp.c_str());
614 }
615
616
617 void MSILWriter::printIndirectSave(const Value* Ptr, const Value* Val) {
618   printValueLoad(Ptr);
619   printValueLoad(Val);
620   printIndirectSave(Val->getType());
621 }
622
623
624 void MSILWriter::printIndirectSave(const Type* Ty) {
625   // Instruction need signed postfix for any type.
626   std::string postfix = getTypePostfix(Ty, false);
627   if (*postfix.begin()=='u') *postfix.begin() = 'i';
628   postfix = "stind."+postfix;
629   printSimpleInstruction(postfix.c_str());
630 }
631
632
633 void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
634                                       const Type* Ty) {
635   std::string Tmp("");
636   printValueLoad(V);
637   switch (Op) {
638   // Signed
639   case Instruction::SExt:
640   case Instruction::SIToFP:
641   case Instruction::FPToSI:
642     Tmp = "conv."+getTypePostfix(Ty,false,true);
643     printSimpleInstruction(Tmp.c_str());
644     break;
645   // Unsigned
646   case Instruction::FPTrunc:
647   case Instruction::FPExt:
648   case Instruction::UIToFP:
649   case Instruction::Trunc:
650   case Instruction::ZExt:
651   case Instruction::FPToUI:
652   case Instruction::PtrToInt:
653   case Instruction::IntToPtr:
654     Tmp = "conv."+getTypePostfix(Ty,false);
655     printSimpleInstruction(Tmp.c_str());
656     break;
657   // Do nothing
658   case Instruction::BitCast:
659     // FIXME: meaning that ld*/st* instruction do not change data format.
660     break;
661   default:
662     cerr << "Opcode = " << Op << '\n';
663     assert(0 && "Invalid conversion instruction");
664   }
665 }
666
667
668 void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I,
669                                      gep_type_iterator E) {
670   unsigned Size;
671   // Load address
672   printValuePtrLoad(V);
673   // Calculate element offset.
674   for (; I!=E; ++I){
675     Size = 0;
676     const Value* IndexValue = I.getOperand();
677     if (const StructType* StrucTy = dyn_cast<StructType>(*I)) {
678       uint64_t FieldIndex = cast<ConstantInt>(IndexValue)->getZExtValue();
679       // Offset is the sum of all previous structure fields.
680       for (uint64_t F = 0; F<FieldIndex; ++F)
681         Size += TD->getABITypeSize(StrucTy->getContainedType((unsigned)F));
682       printPtrLoad(Size);
683       printSimpleInstruction("add");
684       continue;
685     } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) {
686       Size = TD->getABITypeSize(SeqTy->getElementType());
687     } else {
688       Size = TD->getABITypeSize(*I);
689     }
690     // Add offset of current element to stack top.
691     if (!isZeroValue(IndexValue)) {
692       // Constant optimization.
693       if (const ConstantInt* C = dyn_cast<ConstantInt>(IndexValue)) {
694         if (C->getValue().isNegative()) {
695           printPtrLoad(C->getValue().abs().getZExtValue()*Size);
696           printSimpleInstruction("sub");
697           continue;
698         } else
699           printPtrLoad(C->getZExtValue()*Size);
700       } else {
701         printPtrLoad(Size);
702         printValuePtrLoad(IndexValue);
703         printSimpleInstruction("mul");
704       }
705       printSimpleInstruction("add");
706     }
707   }
708 }
709
710
711 std::string MSILWriter::getCallSignature(const FunctionType* Ty,
712                                          const Instruction* Inst,
713                                          std::string Name) {
714   std::string Tmp("");
715   if (Ty->isVarArg()) Tmp += "vararg ";
716   // Name and return type.
717   Tmp += getTypeName(Ty->getReturnType())+Name+"(";
718   // Function argument type list.
719   unsigned NumParams = Ty->getNumParams();
720   for (unsigned I = 0; I!=NumParams; ++I) {
721     if (I!=0) Tmp += ",";
722     Tmp += getTypeName(Ty->getParamType(I));
723   }
724   // CLR needs to know the exact amount of parameters received by vararg
725   // function, because caller cleans the stack.
726   if (Ty->isVarArg() && Inst) {
727     // Origin to function arguments in "CallInst" or "InvokeInst".
728     unsigned Org = isa<InvokeInst>(Inst) ? 3 : 1;
729     // Print variable argument types.
730     unsigned NumOperands = Inst->getNumOperands()-Org;
731     if (NumParams<NumOperands) {
732       if (NumParams!=0) Tmp += ", ";
733       Tmp += "... , ";
734       for (unsigned J = NumParams; J!=NumOperands; ++J) {
735         if (J!=NumParams) Tmp += ", ";
736         Tmp += getTypeName(Inst->getOperand(J+Org)->getType());
737       }
738     }
739   }
740   return Tmp+")";
741 }
742
743
744 void MSILWriter::printFunctionCall(const Value* FnVal,
745                                    const Instruction* Inst) {
746   // Get function calling convention.
747   std::string Name = "";
748   if (const CallInst* Call = dyn_cast<CallInst>(Inst))
749     Name = getConvModopt(Call->getCallingConv());
750   else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst))
751     Name = getConvModopt(Invoke->getCallingConv());
752   else {
753     cerr << "Instruction = " << Inst->getName() << '\n';
754     assert(0 && "Need \"Invoke\" or \"Call\" instruction only");
755   }
756   if (const Function* F = dyn_cast<Function>(FnVal)) {
757     // Direct call.
758     Name += getValueName(F);
759     printSimpleInstruction("call",
760       getCallSignature(F->getFunctionType(),Inst,Name).c_str());
761   } else {
762     // Indirect function call.
763     const PointerType* PTy = cast<PointerType>(FnVal->getType());
764     const FunctionType* FTy = cast<FunctionType>(PTy->getElementType());
765     // Load function address.
766     printValueLoad(FnVal);
767     printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str());
768   }
769 }
770
771
772 void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
773   std::string Name;
774   switch (Inst->getIntrinsicID()) {
775   case Intrinsic::vastart:
776     Name = getValueName(Inst->getOperand(1));
777     Name.insert(Name.length()-1,"$valist");
778     // Obtain the argument handle.
779     printSimpleInstruction("ldloca",Name.c_str());
780     printSimpleInstruction("arglist");
781     printSimpleInstruction("call",
782       "instance void [mscorlib]System.ArgIterator::.ctor"
783       "(valuetype [mscorlib]System.RuntimeArgumentHandle)");
784     // Save as pointer type "void*"
785     printValueLoad(Inst->getOperand(1));
786     printSimpleInstruction("ldloca",Name.c_str());
787     printIndirectSave(PointerType::getUnqual(IntegerType::get(8)));
788     break;
789   case Intrinsic::vaend:
790     // Close argument list handle.
791     printIndirectLoad(Inst->getOperand(1));
792     printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()");
793     break;
794   case Intrinsic::vacopy:
795     // Copy "ArgIterator" valuetype.
796     printIndirectLoad(Inst->getOperand(1));
797     printIndirectLoad(Inst->getOperand(2));
798     printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator");
799     break;        
800   default:
801     cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n';
802     assert(0 && "Invalid intrinsic function");
803   }
804 }
805
806
807 void MSILWriter::printCallInstruction(const Instruction* Inst) {
808   if (isa<IntrinsicInst>(Inst)) {
809     // Handle intrinsic function.
810     printIntrinsicCall(cast<IntrinsicInst>(Inst));
811   } else {
812     // Load arguments to stack and call function.
813     for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I)
814       printValueLoad(Inst->getOperand(I));
815     printFunctionCall(Inst->getOperand(0),Inst);
816   }
817 }
818
819
820 void MSILWriter::printICmpInstruction(unsigned Predicate, const Value* Left,
821                                       const Value* Right) {
822   switch (Predicate) {
823   case ICmpInst::ICMP_EQ:
824     printBinaryInstruction("ceq",Left,Right);
825     break;
826   case ICmpInst::ICMP_NE:
827     // Emulate = not neg (Op1 eq Op2)
828     printBinaryInstruction("ceq",Left,Right);
829     printSimpleInstruction("neg");
830     printSimpleInstruction("not");
831     break;
832   case ICmpInst::ICMP_ULE:
833   case ICmpInst::ICMP_SLE:
834     // Emulate = (Op1 eq Op2) or (Op1 lt Op2)
835     printBinaryInstruction("ceq",Left,Right);
836     if (Predicate==ICmpInst::ICMP_ULE)
837       printBinaryInstruction("clt.un",Left,Right);
838     else
839       printBinaryInstruction("clt",Left,Right);
840     printSimpleInstruction("or");
841     break;
842   case ICmpInst::ICMP_UGE:
843   case ICmpInst::ICMP_SGE:
844     // Emulate = (Op1 eq Op2) or (Op1 gt Op2)
845     printBinaryInstruction("ceq",Left,Right);
846     if (Predicate==ICmpInst::ICMP_UGE)
847       printBinaryInstruction("cgt.un",Left,Right);
848     else
849       printBinaryInstruction("cgt",Left,Right);
850     printSimpleInstruction("or");
851     break;
852   case ICmpInst::ICMP_ULT:
853     printBinaryInstruction("clt.un",Left,Right);
854     break;
855   case ICmpInst::ICMP_SLT:
856     printBinaryInstruction("clt",Left,Right);
857     break;
858   case ICmpInst::ICMP_UGT:
859     printBinaryInstruction("cgt.un",Left,Right);
860   case ICmpInst::ICMP_SGT:
861     printBinaryInstruction("cgt",Left,Right);
862     break;
863   default:
864     cerr << "Predicate = " << Predicate << '\n';
865     assert(0 && "Invalid icmp predicate");
866   }
867 }
868
869
870 void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left,
871                                       const Value* Right) {
872   // FIXME: Correct comparison
873   std::string NanFunc = "bool [mscorlib]System.Double::IsNaN(float64)";
874   switch (Predicate) {
875   case FCmpInst::FCMP_UGT:
876     // X >  Y || llvm_fcmp_uno(X, Y)
877     printBinaryInstruction("cgt",Left,Right);
878     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
879     printSimpleInstruction("or");
880     break;
881   case FCmpInst::FCMP_OGT:
882     // X >  Y
883     printBinaryInstruction("cgt",Left,Right);
884     break;
885   case FCmpInst::FCMP_UGE:
886     // X >= Y || llvm_fcmp_uno(X, Y)
887     printBinaryInstruction("ceq",Left,Right);
888     printBinaryInstruction("cgt",Left,Right);
889     printSimpleInstruction("or");
890     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
891     printSimpleInstruction("or");
892     break;
893   case FCmpInst::FCMP_OGE:
894     // X >= Y
895     printBinaryInstruction("ceq",Left,Right);
896     printBinaryInstruction("cgt",Left,Right);
897     printSimpleInstruction("or");
898     break;
899   case FCmpInst::FCMP_ULT:
900     // X <  Y || llvm_fcmp_uno(X, Y)
901     printBinaryInstruction("clt",Left,Right);
902     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
903     printSimpleInstruction("or");
904     break;
905   case FCmpInst::FCMP_OLT:
906     // X <  Y
907     printBinaryInstruction("clt",Left,Right);
908     break;
909   case FCmpInst::FCMP_ULE:
910     // X <= Y || llvm_fcmp_uno(X, Y)
911     printBinaryInstruction("ceq",Left,Right);
912     printBinaryInstruction("clt",Left,Right);
913     printSimpleInstruction("or");
914     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
915     printSimpleInstruction("or");
916     break;
917   case FCmpInst::FCMP_OLE:
918     // X <= Y
919     printBinaryInstruction("ceq",Left,Right);
920     printBinaryInstruction("clt",Left,Right);
921     printSimpleInstruction("or");
922     break;
923   case FCmpInst::FCMP_UEQ:
924     // X == Y || llvm_fcmp_uno(X, Y)
925     printBinaryInstruction("ceq",Left,Right);
926     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
927     printSimpleInstruction("or");
928     break;
929   case FCmpInst::FCMP_OEQ:
930     // X == Y
931     printBinaryInstruction("ceq",Left,Right);
932     break;
933   case FCmpInst::FCMP_UNE:
934     // X != Y
935     printBinaryInstruction("ceq",Left,Right);
936     printSimpleInstruction("neg");
937     printSimpleInstruction("not");
938     break;
939   case FCmpInst::FCMP_ONE:
940     // X != Y && llvm_fcmp_ord(X, Y)
941     printBinaryInstruction("ceq",Left,Right);
942     printSimpleInstruction("not");
943     break;
944   case FCmpInst::FCMP_ORD:
945     // return X == X && Y == Y
946     printBinaryInstruction("ceq",Left,Left);
947     printBinaryInstruction("ceq",Right,Right);
948     printSimpleInstruction("or");
949     break;
950   case FCmpInst::FCMP_UNO:
951     // X != X || Y != Y
952     printBinaryInstruction("ceq",Left,Left);
953     printSimpleInstruction("not");
954     printBinaryInstruction("ceq",Right,Right);
955     printSimpleInstruction("not");
956     printSimpleInstruction("or");
957     break;
958   default:
959     assert(0 && "Illegal FCmp predicate");
960   }
961 }
962
963
964 void MSILWriter::printInvokeInstruction(const InvokeInst* Inst) {
965   std::string Label = "leave$normal_"+utostr(getUniqID());
966   Out << ".try {\n";
967   // Load arguments
968   for (int I = 3, E = Inst->getNumOperands(); I!=E; ++I)
969     printValueLoad(Inst->getOperand(I));
970   // Print call instruction
971   printFunctionCall(Inst->getOperand(0),Inst);
972   // Save function result and leave "try" block
973   printValueSave(Inst);
974   printSimpleInstruction("leave",Label.c_str());
975   Out << "}\n";
976   Out << "catch [mscorlib]System.Exception {\n";
977   // Redirect to unwind block
978   printSimpleInstruction("pop");
979   printBranchToBlock(Inst->getParent(),NULL,Inst->getUnwindDest());
980   Out << "}\n" << Label << ":\n";
981   // Redirect to continue block
982   printBranchToBlock(Inst->getParent(),NULL,Inst->getNormalDest());
983 }
984
985
986 void MSILWriter::printSwitchInstruction(const SwitchInst* Inst) {
987   // FIXME: Emulate with IL "switch" instruction
988   // Emulate = if () else if () else if () else ...
989   for (unsigned int I = 1, E = Inst->getNumCases(); I!=E; ++I) {
990     printValueLoad(Inst->getCondition());
991     printValueLoad(Inst->getCaseValue(I));
992     printSimpleInstruction("ceq");
993     // Condition jump to successor block
994     printBranchToBlock(Inst->getParent(),Inst->getSuccessor(I),NULL);
995   }
996   // Jump to default block
997   printBranchToBlock(Inst->getParent(),NULL,Inst->getDefaultDest());
998 }
999
1000
1001 void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
1002   printIndirectLoad(Inst->getOperand(0));
1003   printSimpleInstruction("call",
1004     "instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
1005   printSimpleInstruction("refanyval","void*");
1006   std::string Name = 
1007     "ldind."+getTypePostfix(PointerType::getUnqual(IntegerType::get(8)),false);
1008   printSimpleInstruction(Name.c_str());
1009 }
1010
1011
1012 void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
1013   uint64_t Size = TD->getABITypeSize(Inst->getAllocatedType());
1014   // Constant optimization.
1015   if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
1016     printPtrLoad(CInt->getZExtValue()*Size);
1017   } else {
1018     printPtrLoad(Size);
1019     printValueLoad(Inst->getOperand(0));
1020     printSimpleInstruction("mul");
1021   }
1022   printSimpleInstruction("localloc");
1023 }
1024
1025
1026 void MSILWriter::printInstruction(const Instruction* Inst) {
1027   const Value *Left = 0, *Right = 0;
1028   if (Inst->getNumOperands()>=1) Left = Inst->getOperand(0);
1029   if (Inst->getNumOperands()>=2) Right = Inst->getOperand(1);
1030   // Print instruction
1031   // FIXME: "ShuffleVector","ExtractElement","InsertElement" support.
1032   switch (Inst->getOpcode()) {
1033   // Terminator
1034   case Instruction::Ret:
1035     if (Inst->getNumOperands()) {
1036       printValueLoad(Left);
1037       printSimpleInstruction("ret");
1038     } else
1039       printSimpleInstruction("ret");
1040     break;
1041   case Instruction::Br:
1042     printBranchInstruction(cast<BranchInst>(Inst));
1043     break;
1044   // Binary
1045   case Instruction::Add:
1046     printBinaryInstruction("add",Left,Right);
1047     break;
1048   case Instruction::Sub:
1049     printBinaryInstruction("sub",Left,Right);
1050     break;
1051   case Instruction::Mul:  
1052     printBinaryInstruction("mul",Left,Right);
1053     break;
1054   case Instruction::UDiv:
1055     printBinaryInstruction("div.un",Left,Right);
1056     break;
1057   case Instruction::SDiv:
1058   case Instruction::FDiv:
1059     printBinaryInstruction("div",Left,Right);
1060     break;
1061   case Instruction::URem:
1062     printBinaryInstruction("rem.un",Left,Right);
1063     break;
1064   case Instruction::SRem:
1065   case Instruction::FRem:
1066     printBinaryInstruction("rem",Left,Right);
1067     break;
1068   // Binary Condition
1069   case Instruction::ICmp:
1070     printICmpInstruction(cast<ICmpInst>(Inst)->getPredicate(),Left,Right);
1071     break;
1072   case Instruction::FCmp:
1073     printFCmpInstruction(cast<FCmpInst>(Inst)->getPredicate(),Left,Right);
1074     break;
1075   // Bitwise Binary
1076   case Instruction::And:
1077     printBinaryInstruction("and",Left,Right);
1078     break;
1079   case Instruction::Or:
1080     printBinaryInstruction("or",Left,Right);
1081     break;
1082   case Instruction::Xor:
1083     printBinaryInstruction("xor",Left,Right);
1084     break;
1085   case Instruction::Shl:
1086     printValueLoad(Left);
1087     printValueLoad(Right);
1088     printSimpleInstruction("conv.i4");
1089     printSimpleInstruction("shl");
1090     break;
1091   case Instruction::LShr:
1092     printValueLoad(Left);
1093     printValueLoad(Right);
1094     printSimpleInstruction("conv.i4");
1095     printSimpleInstruction("shr.un");
1096     break;
1097   case Instruction::AShr:
1098     printValueLoad(Left);
1099     printValueLoad(Right);
1100     printSimpleInstruction("conv.i4");
1101     printSimpleInstruction("shr");
1102     break;
1103   case Instruction::Select:
1104     printSelectInstruction(Inst->getOperand(0),Inst->getOperand(1),Inst->getOperand(2));
1105     break;
1106   case Instruction::Load:
1107     printIndirectLoad(Inst->getOperand(0));
1108     break;
1109   case Instruction::Store:
1110     printIndirectSave(Inst->getOperand(1), Inst->getOperand(0));
1111     break;
1112   case Instruction::Trunc:
1113   case Instruction::ZExt:
1114   case Instruction::SExt:
1115   case Instruction::FPTrunc:
1116   case Instruction::FPExt:
1117   case Instruction::UIToFP:
1118   case Instruction::SIToFP:
1119   case Instruction::FPToUI:
1120   case Instruction::FPToSI:
1121   case Instruction::PtrToInt:
1122   case Instruction::IntToPtr:
1123   case Instruction::BitCast:
1124     printCastInstruction(Inst->getOpcode(),Left,
1125                          cast<CastInst>(Inst)->getDestTy());
1126     break;
1127   case Instruction::GetElementPtr:
1128     printGepInstruction(Inst->getOperand(0),gep_type_begin(Inst),
1129                         gep_type_end(Inst));
1130     break;
1131   case Instruction::Call:
1132     printCallInstruction(cast<CallInst>(Inst));
1133     break;
1134   case Instruction::Invoke:
1135     printInvokeInstruction(cast<InvokeInst>(Inst));
1136     break;
1137   case Instruction::Unwind:
1138     printSimpleInstruction("newobj",
1139       "instance void [mscorlib]System.Exception::.ctor()");
1140     printSimpleInstruction("throw");
1141     break;
1142   case Instruction::Switch:
1143     printSwitchInstruction(cast<SwitchInst>(Inst));
1144     break;
1145   case Instruction::Alloca:
1146     printAllocaInstruction(cast<AllocaInst>(Inst));
1147     break;
1148   case Instruction::Malloc:
1149     assert(0 && "LowerAllocationsPass used");
1150     break;
1151   case Instruction::Free:
1152     assert(0 && "LowerAllocationsPass used");
1153     break;
1154   case Instruction::Unreachable:
1155     printSimpleInstruction("ldstr", "\"Unreachable instruction\"");
1156     printSimpleInstruction("newobj",
1157       "instance void [mscorlib]System.Exception::.ctor(string)");
1158     printSimpleInstruction("throw");
1159     break;
1160   case Instruction::VAArg:
1161     printVAArgInstruction(cast<VAArgInst>(Inst));
1162     break;
1163   default:
1164     cerr << "Instruction = " << Inst->getName() << '\n';
1165     assert(0 && "Unsupported instruction");
1166   }
1167 }
1168
1169
1170 void MSILWriter::printLoop(const Loop* L) {
1171   Out << getLabelName(L->getHeader()->getName()) << ":\n";
1172   const std::vector<BasicBlock*>& blocks = L->getBlocks();
1173   for (unsigned I = 0, E = blocks.size(); I!=E; I++) {
1174     BasicBlock* BB = blocks[I];
1175     Loop* BBLoop = LInfo->getLoopFor(BB);
1176     if (BBLoop == L)
1177       printBasicBlock(BB);
1178     else if (BB==BBLoop->getHeader() && BBLoop->getParentLoop()==L)
1179       printLoop(BBLoop);
1180   }
1181   printSimpleInstruction("br",getLabelName(L->getHeader()->getName()).c_str());
1182 }
1183
1184
1185 void MSILWriter::printBasicBlock(const BasicBlock* BB) {
1186   Out << getLabelName(BB) << ":\n";
1187   for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
1188     const Instruction* Inst = I;
1189     // Comment llvm original instruction
1190     Out << "\n//" << *Inst << "\n";
1191     // Do not handle PHI instruction in current block
1192     if (Inst->getOpcode()==Instruction::PHI) continue;
1193     // Print instruction
1194     printInstruction(Inst);
1195     // Save result
1196     if (Inst->getType()!=Type::VoidTy) {
1197       // Do not save value after invoke, it done in "try" block
1198       if (Inst->getOpcode()==Instruction::Invoke) continue;
1199       printValueSave(Inst);
1200     }
1201   }
1202 }
1203
1204
1205 void MSILWriter::printLocalVariables(const Function& F) {
1206   std::string Name;
1207   const Type* Ty = NULL;
1208   std::set<const Value*> Printed;
1209   const Value* VaList = NULL;
1210   unsigned StackDepth = 8;
1211   // Find local variables
1212   for (const_inst_iterator I = inst_begin(&F), E = inst_end(&F); I!=E; ++I) {
1213     if (I->getOpcode()==Instruction::Call ||
1214         I->getOpcode()==Instruction::Invoke) {
1215       // Test stack depth.
1216       if (StackDepth<I->getNumOperands())
1217         StackDepth = I->getNumOperands();
1218     }
1219     const AllocaInst* AI = dyn_cast<AllocaInst>(&*I);
1220     if (AI && !isa<GlobalVariable>(AI)) {
1221       // Local variable allocation.
1222       Ty = PointerType::getUnqual(AI->getAllocatedType());
1223       Name = getValueName(AI);
1224       Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
1225     } else if (I->getType()!=Type::VoidTy) {
1226       // Operation result.
1227       Ty = I->getType();
1228       Name = getValueName(&*I);
1229       Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
1230     }
1231     // Test on 'va_list' variable    
1232     bool isVaList = false;     
1233     if (const VAArgInst* VaInst = dyn_cast<VAArgInst>(&*I)) {
1234       // "va_list" as "va_arg" instruction operand.
1235       isVaList = true;
1236       VaList = VaInst->getOperand(0);
1237     } else if (const IntrinsicInst* Inst = dyn_cast<IntrinsicInst>(&*I)) {
1238       // "va_list" as intrinsic function operand. 
1239       switch (Inst->getIntrinsicID()) {
1240       case Intrinsic::vastart:
1241       case Intrinsic::vaend:
1242       case Intrinsic::vacopy:
1243         isVaList = true;
1244         VaList = Inst->getOperand(1);
1245         break;
1246       default:
1247         isVaList = false;
1248       }
1249     }
1250     // Print "va_list" variable.
1251     if (isVaList && Printed.insert(VaList).second) {
1252       Name = getValueName(VaList);
1253       Name.insert(Name.length()-1,"$valist");
1254       Out << "\t.locals (valuetype [mscorlib]System.ArgIterator "
1255           << Name << ")\n";
1256     }
1257   }
1258   printSimpleInstruction(".maxstack",utostr(StackDepth*2).c_str());
1259 }
1260
1261
1262 void MSILWriter::printFunctionBody(const Function& F) {
1263   // Print body
1264   for (Function::const_iterator I = F.begin(), E = F.end(); I!=E; ++I) {
1265     if (Loop *L = LInfo->getLoopFor(I)) {
1266       if (L->getHeader()==I && L->getParentLoop()==0)
1267         printLoop(L);
1268     } else {
1269       printBasicBlock(I);
1270     }
1271   }
1272 }
1273
1274
1275 void MSILWriter::printConstantExpr(const ConstantExpr* CE) {
1276   const Value *left = 0, *right = 0;
1277   if (CE->getNumOperands()>=1) left = CE->getOperand(0);
1278   if (CE->getNumOperands()>=2) right = CE->getOperand(1);
1279   // Print instruction
1280   switch (CE->getOpcode()) {
1281   case Instruction::Trunc:
1282   case Instruction::ZExt:
1283   case Instruction::SExt:
1284   case Instruction::FPTrunc:
1285   case Instruction::FPExt:
1286   case Instruction::UIToFP:
1287   case Instruction::SIToFP:
1288   case Instruction::FPToUI:
1289   case Instruction::FPToSI:
1290   case Instruction::PtrToInt:
1291   case Instruction::IntToPtr:
1292   case Instruction::BitCast:
1293     printCastInstruction(CE->getOpcode(),left,CE->getType());
1294     break;
1295   case Instruction::GetElementPtr:
1296     printGepInstruction(CE->getOperand(0),gep_type_begin(CE),gep_type_end(CE));
1297     break;
1298   case Instruction::ICmp:
1299     printICmpInstruction(CE->getPredicate(),left,right);
1300     break;
1301   case Instruction::FCmp:
1302     printFCmpInstruction(CE->getPredicate(),left,right);
1303     break;
1304   case Instruction::Select:
1305     printSelectInstruction(CE->getOperand(0),CE->getOperand(1),CE->getOperand(2));
1306     break;
1307   case Instruction::Add:
1308     printBinaryInstruction("add",left,right);
1309     break;
1310   case Instruction::Sub:
1311     printBinaryInstruction("sub",left,right);
1312     break;
1313   case Instruction::Mul:
1314     printBinaryInstruction("mul",left,right);
1315     break;
1316   case Instruction::UDiv:
1317     printBinaryInstruction("div.un",left,right);
1318     break;
1319   case Instruction::SDiv:
1320   case Instruction::FDiv:
1321     printBinaryInstruction("div",left,right);
1322     break;
1323   case Instruction::URem:
1324     printBinaryInstruction("rem.un",left,right);
1325     break;
1326   case Instruction::SRem:
1327   case Instruction::FRem:
1328     printBinaryInstruction("rem",left,right);
1329     break;
1330   case Instruction::And:
1331     printBinaryInstruction("and",left,right);
1332     break;
1333   case Instruction::Or:
1334     printBinaryInstruction("or",left,right);
1335     break;
1336   case Instruction::Xor:
1337     printBinaryInstruction("xor",left,right);
1338     break;
1339   case Instruction::Shl:
1340     printBinaryInstruction("shl",left,right);
1341     break;
1342   case Instruction::LShr:
1343     printBinaryInstruction("shr.un",left,right);
1344     break;
1345   case Instruction::AShr:
1346     printBinaryInstruction("shr",left,right);
1347     break;
1348   default:
1349     cerr << "Expression = " << *CE << "\n";
1350     assert(0 && "Invalid constant expression");
1351   }
1352 }
1353
1354
1355 void MSILWriter::printStaticInitializerList() {
1356   // List of global variables with uninitialized fields.
1357   for (std::map<const GlobalVariable*,std::vector<StaticInitializer> >::iterator
1358        VarI = StaticInitList.begin(), VarE = StaticInitList.end(); VarI!=VarE;
1359        ++VarI) {
1360     const std::vector<StaticInitializer>& InitList = VarI->second;
1361     if (InitList.empty()) continue;
1362     // For each uninitialized field.
1363     for (std::vector<StaticInitializer>::const_iterator I = InitList.begin(),
1364          E = InitList.end(); I!=E; ++I) {
1365       if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(I->constant)) {
1366         Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
1367           utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
1368         // Load variable address
1369         printValueLoad(VarI->first);
1370         // Add offset
1371         if (I->offset!=0) {
1372           printPtrLoad(I->offset);
1373           printSimpleInstruction("add");
1374         }
1375         // Load value
1376         printConstantExpr(CE);
1377         // Save result at offset
1378         std::string postfix = getTypePostfix(CE->getType(),true);
1379         if (*postfix.begin()=='u') *postfix.begin() = 'i';
1380         postfix = "stind."+postfix;
1381         printSimpleInstruction(postfix.c_str());
1382       } else {
1383         cerr << "Constant = " << *I->constant << '\n';
1384         assert(0 && "Invalid static initializer");
1385       }
1386     }
1387   }
1388 }
1389
1390
1391 void MSILWriter::printFunction(const Function& F) {
1392   bool isSigned = F.paramHasAttr(0, ParamAttr::SExt);
1393   Out << "\n.method static ";
1394   Out << (F.hasInternalLinkage() ? "private " : "public ");
1395   if (F.isVarArg()) Out << "vararg ";
1396   Out << getTypeName(F.getReturnType(),isSigned) << 
1397     getConvModopt(F.getCallingConv()) << getValueName(&F) << '\n';
1398   // Arguments
1399   Out << "\t(";
1400   unsigned ArgIdx = 1;
1401   for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E;
1402        ++I, ++ArgIdx) {
1403     isSigned = F.paramHasAttr(ArgIdx, ParamAttr::SExt);
1404     if (I!=F.arg_begin()) Out << ", ";
1405     Out << getTypeName(I->getType(),isSigned) << getValueName(I);
1406   }
1407   Out << ") cil managed\n";
1408   // Body
1409   Out << "{\n";
1410   printLocalVariables(F);
1411   printFunctionBody(F);
1412   Out << "}\n";
1413 }
1414
1415
1416 void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
1417   std::string Name;
1418   std::set<const Type*> Printed;
1419   for (std::set<const Type*>::const_iterator
1420        UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) {
1421     const Type* Ty = *UI;
1422     if (isa<ArrayType>(Ty) || isa<VectorType>(Ty) || isa<StructType>(Ty))
1423       Name = getTypeName(Ty, false, true);
1424     // Type with no need to declare.
1425     else continue;
1426     // Print not duplicated type
1427     if (Printed.insert(Ty).second) {
1428       Out << ".class value explicit ansi sealed '" << Name << "'";
1429       Out << " { .pack " << 1 << " .size " << TD->getABITypeSize(Ty)<< " }\n\n";
1430     }
1431   }
1432 }
1433
1434
1435 unsigned int MSILWriter::getBitWidth(const Type* Ty) {
1436   unsigned int N = Ty->getPrimitiveSizeInBits();
1437   assert(N!=0 && "Invalid type in getBitWidth()");
1438   switch (N) {
1439   case 1:
1440   case 8:
1441   case 16:
1442   case 32:
1443   case 64:
1444     return N;
1445   default:
1446     cerr << "Bits = " << N << '\n';
1447     assert(0 && "Unsupported integer width");
1448   }
1449 }
1450
1451
1452 void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
1453   uint64_t TySize = 0;
1454   const Type* Ty = C->getType();
1455   // Print zero initialized constant.
1456   if (isa<ConstantAggregateZero>(C) || C->isNullValue()) {
1457     TySize = TD->getABITypeSize(C->getType());
1458     Offset += TySize;
1459     Out << "int8 (0) [" << TySize << "]";
1460     return;
1461   }
1462   // Print constant initializer
1463   switch (Ty->getTypeID()) {
1464   case Type::IntegerTyID: {
1465     TySize = TD->getABITypeSize(Ty);
1466     const ConstantInt* Int = cast<ConstantInt>(C);
1467     Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
1468     break;
1469   }
1470   case Type::FloatTyID:
1471   case Type::DoubleTyID: {
1472     TySize = TD->getABITypeSize(Ty);
1473     const ConstantFP* FP = cast<ConstantFP>(C);
1474     if (Ty->getTypeID() == Type::FloatTyID)
1475       Out << "int32 (" << 
1476         (uint32_t)FP->getValueAPF().convertToAPInt().getZExtValue() << ')';
1477     else
1478       Out << "int64 (" << 
1479         FP->getValueAPF().convertToAPInt().getZExtValue() << ')';
1480     break;
1481   }
1482   case Type::ArrayTyID:
1483   case Type::VectorTyID:
1484   case Type::StructTyID:
1485     for (unsigned I = 0, E = C->getNumOperands(); I<E; I++) {
1486       if (I!=0) Out << ",\n";
1487       printStaticConstant(C->getOperand(I),Offset);
1488     }
1489     break;
1490   case Type::PointerTyID:
1491     TySize = TD->getABITypeSize(C->getType());
1492     // Initialize with global variable address
1493     if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
1494       std::string name = getValueName(G);
1495       Out << "&(" << name.insert(name.length()-1,"$data") << ")";
1496     } else {
1497       // Dynamic initialization
1498       if (!isa<ConstantPointerNull>(C) && !C->isNullValue())
1499         InitListPtr->push_back(StaticInitializer(C,Offset));
1500       // Null pointer initialization
1501       if (TySize==4) Out << "int32 (0)";
1502       else if (TySize==8) Out << "int64 (0)";
1503       else assert(0 && "Invalid pointer size");
1504     }
1505     break;
1506   default:
1507     cerr << "TypeID = " << Ty->getTypeID() << '\n';
1508     assert(0 && "Invalid type in printStaticConstant()");
1509   }
1510   // Increase offset.
1511   Offset += TySize;
1512 }
1513
1514
1515 void MSILWriter::printStaticInitializer(const Constant* C,
1516                                         const std::string& Name) {
1517   switch (C->getType()->getTypeID()) {
1518   case Type::IntegerTyID:
1519   case Type::FloatTyID:
1520   case Type::DoubleTyID: 
1521     Out << getPrimitiveTypeName(C->getType(), false);
1522     break;
1523   case Type::ArrayTyID:
1524   case Type::VectorTyID:
1525   case Type::StructTyID:
1526   case Type::PointerTyID:
1527     Out << getTypeName(C->getType());
1528     break;
1529   default:
1530     cerr << "Type = " << *C << "\n";
1531     assert(0 && "Invalid constant type");
1532   }
1533   // Print initializer
1534   std::string label = Name;
1535   label.insert(label.length()-1,"$data");
1536   Out << Name << " at " << label << '\n';
1537   Out << ".data " << label << " = {\n";
1538   uint64_t offset = 0;
1539   printStaticConstant(C,offset);
1540   Out << "\n}\n\n";
1541 }
1542
1543
1544 void MSILWriter::printVariableDefinition(const GlobalVariable* G) {
1545   const Constant* C = G->getInitializer();
1546   if (C->isNullValue() || isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
1547     InitListPtr = 0;
1548   else
1549     InitListPtr = &StaticInitList[G];
1550   printStaticInitializer(C,getValueName(G));
1551 }
1552
1553
1554 void MSILWriter::printGlobalVariables() {
1555   if (ModulePtr->global_empty()) return;
1556   Module::global_iterator I,E;
1557   for (I = ModulePtr->global_begin(), E = ModulePtr->global_end(); I!=E; ++I) {
1558     // Variable definition
1559     Out << ".field static " << (I->isDeclaration() ? "public " :
1560                                                      "private ");
1561     if (I->isDeclaration()) {
1562       Out << getTypeName(I->getType()) << getValueName(&*I) << "\n\n";
1563     } else
1564       printVariableDefinition(&*I);
1565   }
1566 }
1567
1568
1569 const char* MSILWriter::getLibraryName(const Function* F) {
1570   return getLibraryForSymbol(F->getName().c_str(), true, F->getCallingConv());
1571 }
1572
1573
1574 const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
1575   return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0);
1576 }
1577
1578
1579 const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction,
1580                                            unsigned CallingConv) {
1581   // TODO: Read *.def file with function and libraries definitions.
1582   return "MSVCRT.DLL";  
1583 }
1584
1585
1586 void MSILWriter::printExternals() {
1587   Module::const_iterator I,E;
1588   // Functions.
1589   for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
1590     // Skip intrisics
1591     if (I->isIntrinsic()) continue;
1592     if (I->isDeclaration()) {
1593       const Function* F = I; 
1594       std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
1595       std::string Sig = 
1596         getCallSignature(cast<FunctionType>(F->getFunctionType()), NULL, Name);
1597       Out << ".method static hidebysig pinvokeimpl(\""
1598           << getLibraryName(F) << "\")\n\t" << Sig << " preservesig {}\n\n";
1599     }
1600   }
1601   // External variables and static initialization.
1602   Out <<
1603   ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1604   "  native int LoadLibrary(string) preservesig {}\n"
1605   ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1606   "  native int GetProcAddress(native int, string) preservesig {}\n";
1607   Out <<
1608   ".method private static void* $MSIL_Import(string lib,string sym)\n"
1609   " managed cil\n{\n"
1610   "\tldarg\tlib\n"
1611   "\tcall\tnative int LoadLibrary(string)\n"
1612   "\tldarg\tsym\n"
1613   "\tcall\tnative int GetProcAddress(native int,string)\n"
1614   "\tdup\n"
1615   "\tbrtrue\tL_01\n"
1616   "\tldstr\t\"Can no import variable\"\n"
1617   "\tnewobj\tinstance void [mscorlib]System.Exception::.ctor(string)\n"
1618   "\tthrow\n"
1619   "L_01:\n"
1620   "\tret\n"
1621   "}\n\n"
1622   ".method static private void $MSIL_Init() managed cil\n{\n";
1623   printStaticInitializerList();
1624   // Foreach global variable.
1625   for (Module::global_iterator I = ModulePtr->global_begin(),
1626        E = ModulePtr->global_end(); I!=E; ++I) {
1627     if (!I->isDeclaration() || !I->hasDLLImportLinkage()) continue;
1628     // Use "LoadLibrary"/"GetProcAddress" to recive variable address.
1629     std::string Label = "not_null$_"+utostr(getUniqID());
1630     std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
1631     printSimpleInstruction("ldsflda",Tmp.c_str());
1632     Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
1633     Out << "\tldstr\t\"" << Mang->getValueName(&*I) << "\"\n";
1634     printSimpleInstruction("call","void* $MSIL_Import(string,string)");
1635     printIndirectSave(I->getType());
1636   }
1637   printSimpleInstruction("ret");
1638   Out << "}\n\n";
1639 }
1640
1641
1642 //===----------------------------------------------------------------------===//
1643 //                       External Interface declaration
1644 //===----------------------------------------------------------------------===//
1645
1646 bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
1647                                           CodeGenFileType FileType, bool Fast)
1648 {
1649   if (FileType != TargetMachine::AssemblyFile) return true;
1650   MSILWriter* Writer = new MSILWriter(o);
1651   PM.add(createGCLoweringPass());
1652   PM.add(createLowerAllocationsPass(true));
1653   // FIXME: Handle switch trougth native IL instruction "switch"
1654   PM.add(createLowerSwitchPass());
1655   PM.add(createCFGSimplificationPass());
1656   PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
1657   PM.add(Writer);
1658   PM.add(createCollectorMetadataDeleter());
1659   return false;
1660 }