Removed tabs everywhere except autogenerated & external files. Add make
[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 was developed by Roman Samoilov and is distributed under
6 // the University of Illinois Open Source 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/Transforms/Scalar.h"
25 #include "llvm/ADT/StringExtras.h"
26
27 namespace {
28   // TargetMachine for the MSIL 
29   struct VISIBILITY_HIDDEN MSILTarget : public TargetMachine {
30     const TargetData DataLayout;       // Calculates type size & alignment
31
32     MSILTarget(const Module &M, const std::string &FS)
33       : DataLayout(&M) {}
34
35     virtual bool WantsWholeFile() const { return true; }
36     virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
37                                          CodeGenFileType FileType, bool Fast);
38
39     // This class always works, but shouldn't be the default in most cases.
40     static unsigned getModuleMatchQuality(const Module &M) { return 1; }
41
42     virtual const TargetData *getTargetData() const { return &DataLayout; }
43   };
44 }
45
46
47 RegisterTarget<MSILTarget> X("msil", "  MSIL backend");
48
49 bool MSILModule::runOnModule(Module &M) {
50   ModulePtr = &M;
51   TD = &getAnalysis<TargetData>();
52   bool Changed = false;
53   // Find named types.  
54   TypeSymbolTable& Table = M.getTypeSymbolTable();
55   std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes();
56   for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) {
57     if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second))
58       Table.remove(I++);
59     else {
60       std::set<const Type *>::iterator T = Types.find(I->second);
61       if (T==Types.end())
62         Table.remove(I++);
63       else {
64         Types.erase(T);
65         ++I;
66       }
67     }
68   }
69   // Find unnamed types.
70   unsigned RenameCounter = 0;
71   for (std::set<const Type *>::const_iterator I = Types.begin(),
72        E = Types.end(); I!=E; ++I)
73     if (const StructType *STy = dyn_cast<StructType>(*I)) {
74       while (ModulePtr->addTypeName("unnamed$"+utostr(RenameCounter), STy))
75         ++RenameCounter;
76       Changed = true;
77     }
78   // Pointer for FunctionPass.
79   UsedTypes = &getAnalysis<FindUsedTypes>().getTypes();
80   return Changed;
81 }
82
83
84 bool MSILWriter::runOnFunction(Function &F) {
85   if (F.isDeclaration()) return false;
86   LInfo = &getAnalysis<LoopInfo>();
87   printFunction(F);
88   return false;
89 }
90
91
92 bool MSILWriter::doInitialization(Module &M) {
93   ModulePtr = &M;
94   Mang = new Mangler(M); 
95   Out << ".assembly extern mscorlib {}\n";
96   Out << ".assembly MSIL {}\n\n";
97   Out << "// External\n";
98   printExternals();
99   Out << "// Declarations\n";
100   printDeclarations(M.getTypeSymbolTable());
101   Out << "// Definitions\n";
102   printGlobalVariables();
103   return false;
104 }
105
106
107 bool MSILWriter::doFinalization(Module &M) {
108   delete Mang;
109   return false;
110 }
111
112
113 bool MSILWriter::isZeroValue(const Value* V) {
114   if (const Constant *C = dyn_cast<Constant>(V))
115     return C->isNullValue();
116   return false;
117 }
118
119
120 std::string MSILWriter::getValueName(const Value* V) {
121   // Name into the quotes allow control and space characters.
122   return "'"+Mang->getValueName(V)+"'";
123 }
124
125
126 std::string MSILWriter::getLabelName(const std::string& Name) {
127   if (Name.find('.')!=std::string::npos) {
128     std::string Tmp(Name);
129     // Replace unaccepable characters in the label name.
130     for (std::string::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I)
131       if (*I=='.') *I = '@';
132     return Tmp;
133   }
134   return Name;
135 }
136
137
138 std::string MSILWriter::getLabelName(const Value* V) {
139   return getLabelName(Mang->getValueName(V));
140 }
141
142
143 std::string MSILWriter::getConvModopt(unsigned CallingConvID) {
144   switch (CallingConvID) {
145   case CallingConv::C:
146   case CallingConv::Cold:
147   case CallingConv::Fast:
148     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) ";
149   case CallingConv::X86_FastCall:
150     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) ";
151   case CallingConv::X86_StdCall:
152     return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
153   default:
154     cerr << "CallingConvID = " << CallingConvID << '\n';
155     assert(0 && "Unsupported calling convention");
156   }
157 }
158
159
160 std::string MSILWriter::getArrayTypeName(Type::TypeID TyID, const Type* Ty) {
161   std::string Tmp = "";
162   const Type* ElemTy = Ty;
163   assert(Ty->getTypeID()==TyID && "Invalid type passed");
164   // Walk trought array element types.
165   for (;;) {
166     // Multidimensional array.
167     if (ElemTy->getTypeID()==TyID) {
168       if (const ArrayType* ATy = dyn_cast<ArrayType>(ElemTy))
169         Tmp += utostr(ATy->getNumElements());
170       else if (const VectorType* VTy = dyn_cast<VectorType>(ElemTy))
171         Tmp += utostr(VTy->getNumElements());
172       ElemTy = cast<SequentialType>(ElemTy)->getElementType();
173     }
174     // Base element type found.
175     if (ElemTy->getTypeID()!=TyID) break;
176     Tmp += ",";
177   }
178   return getTypeName(ElemTy)+"["+Tmp+"]";
179 }
180
181
182 std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) {
183   unsigned NumBits = 0;
184   switch (Ty->getTypeID()) {
185   case Type::VoidTyID:
186     return "void ";
187   case Type::IntegerTyID:
188     NumBits = getBitWidth(Ty);
189     if(NumBits==1)
190       return "bool ";
191     if (!isSigned)
192       return "unsigned int"+utostr(NumBits)+" ";
193     return "int"+utostr(NumBits)+" ";
194   case Type::FloatTyID:
195     return "float32 ";
196   case Type::DoubleTyID:
197     return "float64 "; 
198   default:
199     cerr << "Type = " << *Ty << '\n';
200     assert(0 && "Invalid primitive type");
201   }
202 }
203
204
205 std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned) {
206   if (Ty->isPrimitiveType() || Ty->isInteger())
207     return getPrimitiveTypeName(Ty,isSigned);
208   // FIXME: "OpaqueType" support
209   switch (Ty->getTypeID()) {
210   case Type::PointerTyID:
211     return "void* ";
212   case Type::StructTyID:
213     return "valuetype '"+ModulePtr->getTypeName(Ty)+"' ";
214   case Type::ArrayTyID:
215     return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
216   case Type::VectorTyID:
217     return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
218   default:
219     cerr << "Type = " << *Ty << '\n';
220     assert(0 && "Invalid type in getTypeName()");
221   }
222 }
223
224
225 MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) {
226   // Function argument
227   if (isa<Argument>(V))
228     return ArgumentVT;
229   // Function
230   else if (const Function* F = dyn_cast<Function>(V))
231     return F->hasInternalLinkage() ? InternalVT : GlobalVT;
232   // Variable
233   else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V))
234     return G->hasInternalLinkage() ? InternalVT : GlobalVT;
235   // Constant
236   else if (isa<Constant>(V))
237     return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT;
238   // Local variable
239   return LocalVT;
240 }
241
242
243 std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand,
244                                        bool isSigned) {
245   unsigned NumBits = 0;
246   switch (Ty->getTypeID()) {
247   // Integer constant, expanding for stack operations.
248   case Type::IntegerTyID:
249     NumBits = getBitWidth(Ty);
250     // Expand integer value to "int32" or "int64".
251     if (Expand) return (NumBits<=32 ? "i4" : "i8");
252     if (NumBits==1) return "i1";
253     return (isSigned ? "i" : "u")+utostr(NumBits/8);
254   // Float constant.
255   case Type::FloatTyID:
256     return "r4";
257   case Type::DoubleTyID:
258     return "r8";
259   case Type::PointerTyID:
260     return "i"+utostr(TD->getTypeSize(Ty));
261   default:
262     cerr << "TypeID = " << Ty->getTypeID() << '\n';
263     assert(0 && "Invalid type in TypeToPostfix()");
264   }
265 }
266
267
268 void MSILWriter::printPtrLoad(uint64_t N) {
269   switch (ModulePtr->getPointerSize()) {
270   case Module::Pointer32:
271     printSimpleInstruction("ldc.i4",utostr(N).c_str());
272     // FIXME: Need overflow test?
273     assert(N<0xFFFFFFFF && "32-bit pointer overflowed");
274     break;
275   case Module::Pointer64:
276     printSimpleInstruction("ldc.i8",utostr(N).c_str());
277     break;
278   default:
279     assert(0 && "Module use not supporting pointer size");
280   }
281 }
282
283
284 void MSILWriter::printConstLoad(const Constant* C) {
285   if (const ConstantInt* CInt = dyn_cast<ConstantInt>(C)) {
286     // Integer constant
287     Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t';
288     if (CInt->isMinValue(true))
289       Out << CInt->getSExtValue();
290     else
291       Out << CInt->getZExtValue();
292   } else if (const ConstantFP* CFp = dyn_cast<ConstantFP>(C)) {
293     // Float constant
294     Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t' <<
295       CFp->getValue();
296   } else {
297     cerr << "Constant = " << *C << '\n';
298     assert(0 && "Invalid constant value");
299   }
300   Out << '\n';
301 }
302
303
304 void MSILWriter::printValueLoad(const Value* V) {
305   switch (getValueLocation(V)) {
306   // Global variable or function address.
307   case GlobalVT:
308   case InternalVT:
309     if (const Function* F = dyn_cast<Function>(V)) {
310       std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
311       printSimpleInstruction("ldftn",
312         getCallSignature(F->getFunctionType(),NULL,Name).c_str());
313     } else {
314       const Type* ElemTy = cast<PointerType>(V->getType())->getElementType();
315       std::string Tmp = getTypeName(ElemTy)+getValueName(V);
316       printSimpleInstruction("ldsflda",Tmp.c_str());
317     }
318     break;
319   // Function argument.
320   case ArgumentVT:
321     printSimpleInstruction("ldarg",getValueName(V).c_str());
322     break;
323   // Local function variable.
324   case LocalVT:
325     printSimpleInstruction("ldloc",getValueName(V).c_str());
326     break;
327   // Constant value.
328   case ConstVT:
329     if (isa<ConstantPointerNull>(V))
330       printPtrLoad(0);
331     else
332       printConstLoad(cast<Constant>(V));
333     break;
334   // Constant expression.
335   case ConstExprVT:
336     printConstantExpr(cast<ConstantExpr>(V));
337     break;
338   default:
339     cerr << "Value = " << *V << '\n';
340     assert(0 && "Invalid value location");
341   }
342 }
343
344
345 void MSILWriter::printValueSave(const Value* V) {
346   switch (getValueLocation(V)) {
347   case ArgumentVT:
348     printSimpleInstruction("starg",getValueName(V).c_str());
349     break;
350   case LocalVT:
351     printSimpleInstruction("stloc",getValueName(V).c_str());
352     break;
353   default:
354     cerr << "Value  = " << *V << '\n';
355     assert(0 && "Invalid value location");
356   }
357 }
358
359
360 void MSILWriter::printBinaryInstruction(const char* Name, const Value* Left,
361                                         const Value* Right) {
362   printValueLoad(Left);
363   printValueLoad(Right);
364   Out << '\t' << Name << '\n';
365 }
366
367
368 void MSILWriter::printSimpleInstruction(const char* Inst, const char* Operand) {
369   if(Operand) 
370     Out << '\t' << Inst << '\t' << Operand << '\n';
371   else
372     Out << '\t' << Inst << '\n';
373 }
374
375
376 void MSILWriter::printPHICopy(const BasicBlock* Src, const BasicBlock* Dst) {
377   for (BasicBlock::const_iterator I = Dst->begin(), E = Dst->end();
378        isa<PHINode>(I); ++I) {
379     const PHINode* Phi = cast<PHINode>(I);
380     const Value* Val = Phi->getIncomingValueForBlock(Src);
381     if (isa<UndefValue>(Val)) continue;
382     printValueLoad(Val);
383     printValueSave(Phi);
384   }
385 }
386
387
388 void MSILWriter::printBranchToBlock(const BasicBlock* CurrBB,
389                                     const BasicBlock* TrueBB,
390                                     const BasicBlock* FalseBB) {
391   if (TrueBB==FalseBB) {
392     // "TrueBB" and "FalseBB" destination equals
393     printPHICopy(CurrBB,TrueBB);
394     printSimpleInstruction("pop");
395     printSimpleInstruction("br",getLabelName(TrueBB).c_str());
396   } else if (FalseBB==NULL) {
397     // If "FalseBB" not used the jump have condition
398     printPHICopy(CurrBB,TrueBB);
399     printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
400   } else if (TrueBB==NULL) {
401     // If "TrueBB" not used the jump is unconditional
402     printPHICopy(CurrBB,FalseBB);
403     printSimpleInstruction("br",getLabelName(FalseBB).c_str());
404   } else {
405     // Copy PHI instructions for each block
406     std::string TmpLabel;
407     // Print PHI instructions for "TrueBB"
408     if (isa<PHINode>(TrueBB->begin())) {
409       TmpLabel = getLabelName(TrueBB)+"$phi_"+utostr(getUniqID());
410       printSimpleInstruction("brtrue",TmpLabel.c_str());
411     } else {
412       printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str());
413     }
414     // Print PHI instructions for "FalseBB"
415     if (isa<PHINode>(FalseBB->begin())) {
416       printPHICopy(CurrBB,FalseBB);
417       printSimpleInstruction("br",getLabelName(FalseBB).c_str());
418     } else {
419       printSimpleInstruction("br",getLabelName(FalseBB).c_str());
420     }
421     if (isa<PHINode>(TrueBB->begin())) {
422       // Handle "TrueBB" PHI Copy
423       Out << TmpLabel << ":\n";
424       printPHICopy(CurrBB,TrueBB);
425       printSimpleInstruction("br",getLabelName(TrueBB).c_str());
426     }
427   }
428 }
429
430
431 void MSILWriter::printBranchInstruction(const BranchInst* Inst) {
432   if (Inst->isUnconditional()) {
433     printBranchToBlock(Inst->getParent(),NULL,Inst->getSuccessor(0));
434   } else {
435     printValueLoad(Inst->getCondition());
436     printBranchToBlock(Inst->getParent(),Inst->getSuccessor(0),
437                        Inst->getSuccessor(1));
438   }
439 }
440
441
442 void MSILWriter::printSelectInstruction(const Value* Cond, const Value* VTrue,
443                                         const Value* VFalse) {
444   std::string TmpLabel = std::string("select$true_")+utostr(getUniqID());
445   printValueLoad(VTrue);
446   printValueLoad(Cond);
447   printSimpleInstruction("brtrue",TmpLabel.c_str());
448   printSimpleInstruction("pop");
449   printValueLoad(VFalse);
450   Out << TmpLabel << ":\n";
451 }
452
453
454 void MSILWriter::printIndirectLoad(const Value* V) {
455   printValueLoad(V);
456   std::string Tmp = "ldind."+getTypePostfix(V->getType(),false);
457   printSimpleInstruction(Tmp.c_str());
458 }
459
460
461 void MSILWriter::printStoreInstruction(const Instruction* Inst) {
462   const Value* Val = Inst->getOperand(0);
463   const Value* Ptr = Inst->getOperand(1);
464   // Load destination address.
465   printValueLoad(Ptr);
466   // Load value.
467   printValueLoad(Val);
468   // Instruction need signed postfix for any type.
469   std::string postfix = getTypePostfix(Val->getType(),false);
470   if (*postfix.begin()=='u') *postfix.begin() = 'i';
471   postfix = "stind."+postfix;
472   printSimpleInstruction(postfix.c_str());
473 }
474
475
476 void MSILWriter::printCastInstruction(unsigned int Op, const Value* V,
477                                       const Type* Ty) {
478   std::string Tmp("");
479   printValueLoad(V);
480   switch (Op) {
481   // Signed
482   case Instruction::SExt:
483   case Instruction::SIToFP:
484   case Instruction::FPToSI:
485     Tmp = "conv."+getTypePostfix(Ty,false,true);
486     printSimpleInstruction(Tmp.c_str());
487     break;
488   // Unsigned
489   case Instruction::FPTrunc:
490   case Instruction::FPExt:
491   case Instruction::UIToFP:
492   case Instruction::Trunc:
493   case Instruction::ZExt:
494   case Instruction::FPToUI:
495   case Instruction::PtrToInt:
496   case Instruction::IntToPtr:
497     Tmp = "conv."+getTypePostfix(Ty,false);
498     printSimpleInstruction(Tmp.c_str());
499     break;
500   // Do nothing
501   case Instruction::BitCast:
502     // FIXME: meaning that ld*/st* instruction do not change data format.
503     break;
504   default:
505     cerr << "Opcode = " << Op << '\n';
506     assert(0 && "Invalid conversion instruction");
507   }
508 }
509
510
511 void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I,
512                                      gep_type_iterator E) {
513   // Load address
514   printValueLoad(V);
515   // Calculate element offset.
516   unsigned TySize;
517   for (++I; I!=E; ++I){
518     const Type* Ty = I.getIndexedType();
519     const Value* Idx = I.getOperand();
520     // Get size of type.
521     switch (Ty->getTypeID()) {
522     case Type::IntegerTyID:
523     case Type::FloatTyID:
524     case Type::DoubleTyID:
525     case Type::PointerTyID:
526       TySize = TD->getTypeSize(Ty);
527       break;
528     case Type::StructTyID:
529       TySize = 0;
530       break;
531     case Type::ArrayTyID:
532       TySize = TD->getTypeSize(cast<ArrayType>(Ty)->getElementType());
533       break;
534     case Type::VectorTyID:
535       TySize = TD->getTypeSize(cast<VectorType>(Ty)->getElementType());
536       break;
537     default:
538       cerr << "Type = " << *Ty << '\n';
539       assert(0 && "Invalid index type in printGepInstruction()");
540     }
541     // Calculate offset to structure field.
542     if (const StructType* STy = dyn_cast<StructType>(Ty)) {
543       TySize = 0;
544       uint64_t FieldIdx = cast<ConstantInt>(Idx)->getZExtValue();
545       // Offset is the summ of all previous structure fields.
546       for (uint64_t F = 0; F<FieldIdx; ++F)
547         TySize += TD->getTypeSize(STy->getContainedType(unsigned(F)));
548       // Add field offset to stack top.
549       printPtrLoad(TySize);
550       printSimpleInstruction("add");
551       continue;
552     }
553     // Add offset of current element to stack top.
554     if (!isZeroValue(Idx)) {
555       uint64_t TySize = TD->getTypeSize(I.getIndexedType());
556       // Constant optimization
557       if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Idx)) {
558         printPtrLoad(CInt->getZExtValue()*TySize);
559       } else {
560         printPtrLoad(TySize);
561         printValueLoad(Idx);
562         printSimpleInstruction("mul");
563       }
564       printSimpleInstruction("add");
565     }
566   }
567 }
568
569
570 std::string MSILWriter::getCallSignature(const FunctionType* Ty,
571                                          const Instruction* Inst,
572                                          std::string Name) {
573   std::string Tmp = "";
574   if (Ty->isVarArg()) Tmp += "vararg ";
575   // Name and return type.
576   Tmp += getTypeName(Ty->getReturnType())+Name+"(";
577   // Function argument type list.
578   unsigned NumParams = Ty->getNumParams();
579   for (unsigned I = 0; I!=NumParams; ++I) {
580     if (I!=0) Tmp += ",";
581     Tmp += getTypeName(Ty->getParamType(I));
582   }
583   // CLR needs to know the exact amount of parameters received by vararg
584   // function, because caller cleans the stack.
585   if (Ty->isVarArg() && Inst) {
586     // Origin to function arguments in "CallInst" or "InvokeInst"
587     unsigned Org = isa<InvokeInst>(Inst) ? 3 : 1;
588     // Print variable argument types.
589     unsigned NumOperands = Inst->getNumOperands()-Org;
590     if (NumParams<NumOperands) {
591       if (NumParams!=0) Tmp += ", ";
592       Tmp += "... , ";
593       for (unsigned J = NumParams; J!=NumOperands; ++J) {
594         if (J!=NumParams) Tmp += ", ";
595         Tmp += getTypeName(Inst->getOperand(J+Org)->getType());
596       }
597     }
598   }
599   return Tmp+")";
600 }
601
602
603 void MSILWriter::printFunctionCall(const Value* FnVal,
604                                    const Instruction* Inst) {
605   // Get function calling convention
606   std::string Name = "";
607   if (const CallInst* Call = dyn_cast<CallInst>(Inst))
608     Name = getConvModopt(Call->getCallingConv());
609   else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst))
610     Name = getConvModopt(Invoke->getCallingConv());
611   else {
612     cerr << "Instruction = " << Inst->getName() << '\n';
613     assert(0 && "Need \"Invoke\" or \"Call\" instruction only");
614   }
615   
616   if (const Function* F = dyn_cast<Function>(FnVal)) {
617     // Direct call
618     Name += getValueName(F);
619     printSimpleInstruction("call",
620       getCallSignature(F->getFunctionType(),Inst,Name).c_str());
621   } else {
622     // Indirect function call
623     const PointerType* PTy = cast<PointerType>(FnVal->getType());
624     const FunctionType* FTy = cast<FunctionType>(PTy->getElementType());
625     // Load function address
626     printValueLoad(FnVal);
627     printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str());
628   }
629 }
630
631
632 void MSILWriter::printCallInstruction(const Instruction* Inst) {
633   // Load arguments to stack
634   for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I)
635     printValueLoad(Inst->getOperand(I));
636   printFunctionCall(Inst->getOperand(0),Inst);
637 }
638
639
640 void MSILWriter::printICmpInstruction(unsigned Predicate, const Value* Left,
641                                       const Value* Right) {
642   switch (Predicate) {
643   case ICmpInst::ICMP_EQ:
644     printBinaryInstruction("ceq",Left,Right);
645     break;
646   case ICmpInst::ICMP_NE:
647     // Emulate = not (Op1 eq Op2)
648     printBinaryInstruction("ceq",Left,Right);
649     printSimpleInstruction("not");
650     break;
651   case ICmpInst::ICMP_ULE:
652   case ICmpInst::ICMP_SLE:
653     // Emulate = (Op1 eq Op2) or (Op1 lt Op2)
654     printBinaryInstruction("ceq",Left,Right);
655     if (Predicate==ICmpInst::ICMP_ULE)
656       printBinaryInstruction("clt.un",Left,Right);
657     else
658       printBinaryInstruction("clt",Left,Right);
659     printSimpleInstruction("or");
660     break;
661   case ICmpInst::ICMP_UGE:
662   case ICmpInst::ICMP_SGE:
663     // Emulate = (Op1 eq Op2) or (Op1 gt Op2)
664     printBinaryInstruction("ceq",Left,Right);
665     if (Predicate==ICmpInst::ICMP_UGE)
666       printBinaryInstruction("cgt.un",Left,Right);
667     else
668       printBinaryInstruction("cgt",Left,Right);
669     printSimpleInstruction("or");
670     break;
671   case ICmpInst::ICMP_ULT:
672     printBinaryInstruction("clt.un",Left,Right);
673     break;
674   case ICmpInst::ICMP_SLT:
675     printBinaryInstruction("clt",Left,Right);
676     break;
677   case ICmpInst::ICMP_UGT:
678     printBinaryInstruction("cgt.un",Left,Right);
679   case ICmpInst::ICMP_SGT:
680     printBinaryInstruction("cgt",Left,Right);
681     break;
682   default:
683     cerr << "Predicate = " << Predicate << '\n';
684     assert(0 && "Invalid icmp predicate");
685   }
686 }
687
688
689 void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left,
690                                       const Value* Right) {
691   // FIXME: Correct comparison
692   std::string NanFunc = "bool [mscorlib]System.Double::IsNaN(float64)";
693   switch (Predicate) {
694   case FCmpInst::FCMP_UGT:
695     // X >  Y || llvm_fcmp_uno(X, Y)
696     printBinaryInstruction("cgt",Left,Right);
697     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
698     printSimpleInstruction("or");
699     break;
700   case FCmpInst::FCMP_OGT:
701     // X >  Y
702     printBinaryInstruction("cgt",Left,Right);
703     break;
704   case FCmpInst::FCMP_UGE:
705     // X >= Y || llvm_fcmp_uno(X, Y)
706     printBinaryInstruction("ceq",Left,Right);
707     printBinaryInstruction("cgt",Left,Right);
708     printSimpleInstruction("or");
709     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
710     printSimpleInstruction("or");
711     break;
712   case FCmpInst::FCMP_OGE:
713     // X >= Y
714     printBinaryInstruction("ceq",Left,Right);
715     printBinaryInstruction("cgt",Left,Right);
716     printSimpleInstruction("or");
717     break;
718   case FCmpInst::FCMP_ULT:
719     // X <  Y || llvm_fcmp_uno(X, Y)
720     printBinaryInstruction("clt",Left,Right);
721     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
722     printSimpleInstruction("or");
723     break;
724   case FCmpInst::FCMP_OLT:
725     // X <  Y
726     printBinaryInstruction("clt",Left,Right);
727     break;
728   case FCmpInst::FCMP_ULE:
729     // X <= Y || llvm_fcmp_uno(X, Y)
730     printBinaryInstruction("ceq",Left,Right);
731     printBinaryInstruction("clt",Left,Right);
732     printSimpleInstruction("or");
733     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
734     printSimpleInstruction("or");
735     break;
736   case FCmpInst::FCMP_OLE:
737     // X <= Y
738     printBinaryInstruction("ceq",Left,Right);
739     printBinaryInstruction("clt",Left,Right);
740     printSimpleInstruction("or");
741     break;
742   case FCmpInst::FCMP_UEQ:
743     // X == Y || llvm_fcmp_uno(X, Y)
744     printBinaryInstruction("ceq",Left,Right);
745     printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right);
746     printSimpleInstruction("or");
747     break;
748   case FCmpInst::FCMP_OEQ:
749     // X == Y
750     printBinaryInstruction("ceq",Left,Right);
751     break;
752   case FCmpInst::FCMP_UNE:
753     // X != Y
754     printBinaryInstruction("ceq",Left,Right);
755     printSimpleInstruction("not");
756     break;
757   case FCmpInst::FCMP_ONE:
758     // X != Y && llvm_fcmp_ord(X, Y)
759     printBinaryInstruction("ceq",Left,Right);
760     printSimpleInstruction("not");
761     break;
762   case FCmpInst::FCMP_ORD:
763     // return X == X && Y == Y
764     printBinaryInstruction("ceq",Left,Left);
765     printBinaryInstruction("ceq",Right,Right);
766     printSimpleInstruction("or");
767     break;
768   case FCmpInst::FCMP_UNO:
769     // X != X || Y != Y
770     printBinaryInstruction("ceq",Left,Left);
771     printSimpleInstruction("not");
772     printBinaryInstruction("ceq",Right,Right);
773     printSimpleInstruction("not");
774     printSimpleInstruction("or");
775     break;
776   default:
777     assert(0 && "Illegal FCmp predicate");
778   }
779 }
780
781
782 void MSILWriter::printInvokeInstruction(const InvokeInst* Inst) {
783   std::string Label = "leave$normal_"+utostr(getUniqID());
784   Out << ".try {\n";
785   // Load arguments
786   for (int I = 3, E = Inst->getNumOperands(); I!=E; ++I)
787     printValueLoad(Inst->getOperand(I));
788   // Print call instruction
789   printFunctionCall(Inst->getOperand(0),Inst);
790   // Save function result and leave "try" block
791   printValueSave(Inst);
792   printSimpleInstruction("leave",Label.c_str());
793   Out << "}\n";
794   Out << "catch [mscorlib]System.Exception {\n";
795   // Redirect to unwind block
796   printSimpleInstruction("pop");
797   printBranchToBlock(Inst->getParent(),NULL,Inst->getUnwindDest());
798   Out << "}\n" << Label << ":\n";
799   // Redirect to continue block
800   printBranchToBlock(Inst->getParent(),NULL,Inst->getNormalDest());
801 }
802
803
804 void MSILWriter::printSwitchInstruction(const SwitchInst* Inst) {
805   // FIXME: Emulate with IL "switch" instruction
806   // Emulate = if () else if () else if () else ...
807   for (unsigned int I = 1, E = Inst->getNumCases(); I!=E; ++I) {
808     printValueLoad(Inst->getCondition());
809     printValueLoad(Inst->getCaseValue(I));
810     printSimpleInstruction("ceq");
811     // Condition jump to successor block
812     printBranchToBlock(Inst->getParent(),Inst->getSuccessor(I),NULL);
813   }
814   // Jump to default block
815   printBranchToBlock(Inst->getParent(),NULL,Inst->getDefaultDest());
816 }
817
818
819 void MSILWriter::printInstruction(const Instruction* Inst) {
820   const Value *Left = 0, *Right = 0;
821   if (Inst->getNumOperands()>=1) Left = Inst->getOperand(0);
822   if (Inst->getNumOperands()>=2) Right = Inst->getOperand(1);
823   // Print instruction
824   // FIXME: "ShuffleVector","ExtractElement","InsertElement","VAArg" support.
825   switch (Inst->getOpcode()) {
826   // Terminator
827   case Instruction::Ret:
828     if (Inst->getNumOperands()) {
829       printValueLoad(Left);
830       printSimpleInstruction("ret");
831     } else
832       printSimpleInstruction("ret");
833     break;
834   case Instruction::Br:
835     printBranchInstruction(cast<BranchInst>(Inst));
836     break;
837   // Binary
838   case Instruction::Add:
839     printBinaryInstruction("add",Left,Right);
840     break;
841   case Instruction::Sub:
842     printBinaryInstruction("sub",Left,Right);
843     break;
844   case Instruction::Mul:  
845     printBinaryInstruction("mul",Left,Right);
846     break;
847   case Instruction::UDiv:
848     printBinaryInstruction("div.un",Left,Right);
849     break;
850   case Instruction::SDiv:
851   case Instruction::FDiv:
852     printBinaryInstruction("div",Left,Right);
853     break;
854   case Instruction::URem:
855     printBinaryInstruction("rem.un",Left,Right);
856     break;
857   case Instruction::SRem:
858   case Instruction::FRem:
859     printBinaryInstruction("rem",Left,Right);
860     break;
861   // Binary Condition
862   case Instruction::ICmp:
863     printICmpInstruction(cast<ICmpInst>(Inst)->getPredicate(),Left,Right);
864     break;
865   case Instruction::FCmp:
866     printFCmpInstruction(cast<FCmpInst>(Inst)->getPredicate(),Left,Right);
867     break;
868   // Bitwise Binary
869   case Instruction::And:
870     printBinaryInstruction("and",Left,Right);
871     break;
872   case Instruction::Or:
873     printBinaryInstruction("or",Left,Right);
874     break;
875   case Instruction::Xor:
876     printBinaryInstruction("xor",Left,Right);
877     break;
878   case Instruction::Shl:
879     printBinaryInstruction("shl",Left,Right);
880     break;
881   case Instruction::LShr:
882     printBinaryInstruction("shr.un",Left,Right);
883     break;
884   case Instruction::AShr:
885     printBinaryInstruction("shr",Left,Right);
886     break;
887   case Instruction::Select:
888     printSelectInstruction(Inst->getOperand(0),Inst->getOperand(1),Inst->getOperand(2));
889     break;
890   case Instruction::Load:
891     printIndirectLoad(Inst->getOperand(0));
892     break;
893   case Instruction::Store:
894     printStoreInstruction(Inst);
895     break;
896   case Instruction::Trunc:
897   case Instruction::ZExt:
898   case Instruction::SExt:
899   case Instruction::FPTrunc:
900   case Instruction::FPExt:
901   case Instruction::UIToFP:
902   case Instruction::SIToFP:
903   case Instruction::FPToUI:
904   case Instruction::FPToSI:
905   case Instruction::PtrToInt:
906   case Instruction::IntToPtr:
907   case Instruction::BitCast:
908     printCastInstruction(Inst->getOpcode(),Left,
909                          cast<CastInst>(Inst)->getDestTy());
910     break;
911   case Instruction::GetElementPtr:
912     printGepInstruction(Inst->getOperand(0),gep_type_begin(Inst),
913                         gep_type_end(Inst));
914     break;
915   case Instruction::Call:
916     printCallInstruction(cast<CallInst>(Inst));
917     break;
918   case Instruction::Invoke:
919     printInvokeInstruction(cast<InvokeInst>(Inst));
920     break;
921   case Instruction::Unwind: {
922     std::string Class = "instance void [mscorlib]System.Exception::.ctor()";
923     printSimpleInstruction("newobj",Class.c_str());
924     printSimpleInstruction("throw");
925     break;
926   }
927   case Instruction::Switch:
928     printSwitchInstruction(cast<SwitchInst>(Inst));
929     break;
930   case Instruction::Alloca:
931     printValueLoad(Inst->getOperand(0));
932     printSimpleInstruction("localloc");
933     break;
934   case Instruction::Malloc:
935     assert(0 && "LowerAllocationsPass used");
936     break;
937   case Instruction::Free:
938     assert(0 && "LowerAllocationsPass used");
939     break;
940   case Instruction::Unreachable:
941     printSimpleInstruction("ldnull");
942     printSimpleInstruction("throw");
943     break;
944   default:
945     cerr << "Instruction = " << Inst->getName() << '\n';
946     assert(0 && "Unsupported instruction");
947   }
948 }
949
950
951 void MSILWriter::printLoop(const Loop* L) {
952   Out << getLabelName(L->getHeader()->getName()) << ":\n";
953   const std::vector<BasicBlock*>& blocks = L->getBlocks();
954   for (unsigned I = 0, E = blocks.size(); I!=E; I++) {
955     BasicBlock* BB = blocks[I];
956     Loop* BBLoop = LInfo->getLoopFor(BB);
957     if (BBLoop == L)
958       printBasicBlock(BB);
959     else if (BB==BBLoop->getHeader() && BBLoop->getParentLoop()==L)
960       printLoop(BBLoop);
961   }
962   printSimpleInstruction("br",getLabelName(L->getHeader()->getName()).c_str());
963 }
964
965
966 void MSILWriter::printBasicBlock(const BasicBlock* BB) {
967   Out << getLabelName(BB) << ":\n";
968   for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
969     const Instruction* Inst = I;
970     // Comment llvm original instruction
971     Out << "\n//" << *Inst << "\n";
972     // Do not handle PHI instruction in current block
973     if (Inst->getOpcode()==Instruction::PHI) continue;
974     // Print instruction
975     printInstruction(Inst);
976     // Save result
977     if (Inst->getType()!=Type::VoidTy) {
978       // Do not save value after invoke, it done in "try" block
979       if (Inst->getOpcode()==Instruction::Invoke) continue;
980       printValueSave(Inst);
981     }
982   }
983 }
984
985
986 void MSILWriter::printLocalVariables(const Function& F) {
987   std::string Name;
988   const Type* Ty = NULL;
989   // Find variables
990   for (const_inst_iterator I = inst_begin(&F), E = inst_end(&F); I!=E; ++I) {
991     const AllocaInst* AI = dyn_cast<AllocaInst>(&*I);
992     if (AI && !isa<GlobalVariable>(AI)) {
993       Ty = PointerType::get(AI->getAllocatedType());
994       Name = getValueName(AI);
995     } else if (I->getType()!=Type::VoidTy) {
996       Ty = I->getType();
997       Name = getValueName(&*I);
998     } else continue;
999     Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
1000   }
1001 }
1002
1003
1004 void MSILWriter::printFunctionBody(const Function& F) {
1005   // Print body
1006   for (Function::const_iterator I = F.begin(), E = F.end(); I!=E; ++I) {
1007     if (Loop *L = LInfo->getLoopFor(I)) {
1008       if (L->getHeader()==I && L->getParentLoop()==0)
1009         printLoop(L);
1010     } else {
1011       printBasicBlock(I);
1012     }
1013   }
1014 }
1015
1016
1017 void MSILWriter::printConstantExpr(const ConstantExpr* CE) {
1018   const Value *left = 0, *right = 0;
1019   if (CE->getNumOperands()>=1) left = CE->getOperand(0);
1020   if (CE->getNumOperands()>=2) right = CE->getOperand(1);
1021   // Print instruction
1022   switch (CE->getOpcode()) {
1023   case Instruction::Trunc:
1024   case Instruction::ZExt:
1025   case Instruction::SExt:
1026   case Instruction::FPTrunc:
1027   case Instruction::FPExt:
1028   case Instruction::UIToFP:
1029   case Instruction::SIToFP:
1030   case Instruction::FPToUI:
1031   case Instruction::FPToSI:
1032   case Instruction::PtrToInt:
1033   case Instruction::IntToPtr:
1034   case Instruction::BitCast:
1035     printCastInstruction(CE->getOpcode(),left,CE->getType());
1036     break;
1037   case Instruction::GetElementPtr:
1038     printGepInstruction(CE->getOperand(0),gep_type_begin(CE),gep_type_end(CE));
1039     break;
1040   case Instruction::ICmp:
1041     printICmpInstruction(CE->getPredicate(),left,right);
1042     break;
1043   case Instruction::FCmp:
1044     printFCmpInstruction(CE->getPredicate(),left,right);
1045     break;
1046   case Instruction::Select:
1047     printSelectInstruction(CE->getOperand(0),CE->getOperand(1),CE->getOperand(2));
1048     break;
1049   case Instruction::Add:
1050     printBinaryInstruction("add",left,right);
1051     break;
1052   case Instruction::Sub:
1053     printBinaryInstruction("sub",left,right);
1054     break;
1055   case Instruction::Mul:
1056     printBinaryInstruction("mul",left,right);
1057     break;
1058   case Instruction::UDiv:
1059     printBinaryInstruction("div.un",left,right);
1060     break;
1061   case Instruction::SDiv:
1062   case Instruction::FDiv:
1063     printBinaryInstruction("div",left,right);
1064     break;
1065   case Instruction::URem:
1066     printBinaryInstruction("rem.un",left,right);
1067     break;
1068   case Instruction::SRem:
1069   case Instruction::FRem:
1070     printBinaryInstruction("rem",left,right);
1071     break;
1072   case Instruction::And:
1073     printBinaryInstruction("and",left,right);
1074     break;
1075   case Instruction::Or:
1076     printBinaryInstruction("or",left,right);
1077     break;
1078   case Instruction::Xor:
1079     printBinaryInstruction("xor",left,right);
1080     break;
1081   case Instruction::Shl:
1082     printBinaryInstruction("shl",left,right);
1083     break;
1084   case Instruction::LShr:
1085     printBinaryInstruction("shr.un",left,right);
1086     break;
1087   case Instruction::AShr:
1088     printBinaryInstruction("shr",left,right);
1089     break;
1090   default:
1091     cerr << "Expression = " << *CE << "\n";
1092     assert(0 && "Invalid constant expression");
1093   }
1094 }
1095
1096
1097 void MSILWriter::printStaticInitializerList() {
1098   // List of global variables with uninitialized fields.
1099   for (std::map<const GlobalVariable*,std::vector<StaticInitializer> >::iterator
1100        VarI = StaticInitList.begin(), VarE = StaticInitList.end(); VarI!=VarE;
1101        ++VarI) {
1102     const std::vector<StaticInitializer>& InitList = VarI->second;
1103     if (InitList.empty()) continue;
1104     // For each uninitialized field.
1105     for (std::vector<StaticInitializer>::const_iterator I = InitList.begin(),
1106          E = InitList.end(); I!=E; ++I) {
1107       if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(I->constant)) {
1108         Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
1109           utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
1110         // Load variable address
1111         printValueLoad(VarI->first);
1112         // Add offset
1113         if (I->offset!=0) {
1114           printPtrLoad(I->offset);
1115           printSimpleInstruction("add");
1116         }
1117         // Load value
1118         printConstantExpr(CE);
1119         // Save result at offset
1120         std::string postfix = getTypePostfix(CE->getType(),true);
1121         if (*postfix.begin()=='u') *postfix.begin() = 'i';
1122         postfix = "stind."+postfix;
1123         printSimpleInstruction(postfix.c_str());
1124       } else {
1125         cerr << "Constant = " << *I->constant << '\n';
1126         assert(0 && "Invalid static initializer");
1127       }
1128     }
1129   }
1130 }
1131
1132
1133 void MSILWriter::printFunction(const Function& F) {
1134   const FunctionType* FTy = F.getFunctionType();
1135   const ParamAttrsList *Attrs = FTy->getParamAttrs();
1136   bool isSigned = Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt);
1137   Out << "\n.method static ";
1138   Out << (F.hasInternalLinkage() ? "private " : "public ");
1139   if (F.isVarArg()) Out << "vararg ";
1140   Out << getTypeName(F.getReturnType(),isSigned) << 
1141     getConvModopt(F.getCallingConv()) << getValueName(&F) << '\n';
1142   // Arguments
1143   Out << "\t(";
1144   unsigned ArgIdx = 1;
1145   for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E;
1146        ++I, ++ArgIdx) {
1147     isSigned = Attrs && Attrs->paramHasAttr(ArgIdx, ParamAttr::SExt);
1148     if (I!=F.arg_begin()) Out << ", ";
1149     Out << getTypeName(I->getType(),isSigned) << getValueName(I);
1150   }
1151   Out << ") cil managed\n";
1152   // Body
1153   Out << "{\n";
1154   // FIXME: Convert "string[]" to "argc,argv"
1155   if (F.getName()=="main") {
1156     printSimpleInstruction(".entrypoint");
1157     printLocalVariables(F);
1158     printStaticInitializerList();
1159   } else {
1160     printLocalVariables(F);  
1161   }
1162   printFunctionBody(F);
1163   Out << "}\n";
1164 }
1165
1166
1167 void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
1168   std::string Name;
1169   std::set<const Type*> Printed;
1170   //cerr << "UsedTypes = " << UsedTypes << '\n';
1171   for (std::set<const Type*>::const_iterator
1172        UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) {
1173     const Type* Ty = *UI;
1174     if (isa<ArrayType>(Ty))
1175       Name = getArrayTypeName(Ty->getTypeID(),Ty);
1176     else if (isa<VectorType>(Ty))
1177       Name = getArrayTypeName(Ty->getTypeID(),Ty);
1178     else if (isa<StructType>(Ty))
1179       Name = ModulePtr->getTypeName(Ty);
1180     // Type with no need to declare.
1181     else continue;
1182     // Print not duplicated type
1183     if (Printed.insert(Ty).second) {
1184       Out << ".class value explicit ansi sealed '" << Name << "'";
1185       Out << " { .pack " << 1 << " .size " << TD->getTypeSize(Ty) << " }\n\n";
1186     }
1187   }
1188 }
1189
1190
1191 unsigned int MSILWriter::getBitWidth(const Type* Ty) {
1192   unsigned int N = Ty->getPrimitiveSizeInBits();
1193   assert(N!=0 && "Invalid type in getBitWidth()");
1194   switch (N) {
1195   case 1:
1196   case 8:
1197   case 16:
1198   case 32:
1199   case 64:
1200     return N;
1201   default:
1202     cerr << "Bits = " << N << '\n';
1203     assert(0 && "Unsupported integer width");
1204   }
1205 }
1206
1207
1208 void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) {
1209   uint64_t TySize = 0;
1210   const Type* Ty = C->getType();
1211   // Print zero initialized constant.
1212   if (isa<ConstantAggregateZero>(C) || C->isNullValue()) {
1213     TySize = TD->getTypeSize(C->getType());
1214     Offset += TySize;
1215     Out << "int8 (0) [" << TySize << "]";
1216     return;
1217   }
1218   // Print constant initializer
1219   switch (Ty->getTypeID()) {
1220   case Type::IntegerTyID: {
1221     TySize = TD->getTypeSize(Ty);
1222     const ConstantInt* Int = cast<ConstantInt>(C);
1223     Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")";
1224     break;
1225   }
1226   case Type::FloatTyID:
1227   case Type::DoubleTyID: {
1228     TySize = TD->getTypeSize(Ty);
1229     const ConstantFP* CFp = cast<ConstantFP>(C);
1230     Out << getPrimitiveTypeName(Ty,true) << "(" << CFp->getValue() << ")";
1231     break;
1232   }
1233   case Type::ArrayTyID:
1234   case Type::VectorTyID:
1235   case Type::StructTyID:
1236     for (unsigned I = 0, E = C->getNumOperands(); I<E; I++) {
1237       if (I!=0) Out << ",\n";
1238       printStaticConstant(C->getOperand(I),Offset);
1239     }
1240     break;
1241   case Type::PointerTyID:
1242     TySize = TD->getTypeSize(C->getType());
1243     // Initialize with global variable address
1244     if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) {
1245       std::string name = getValueName(G);
1246       Out << "&(" << name.insert(name.length()-1,"$data") << ")";
1247     } else {
1248       // Dynamic initialization
1249       if (!isa<ConstantPointerNull>(C) && !C->isNullValue())
1250         InitListPtr->push_back(StaticInitializer(C,Offset));
1251       // Null pointer initialization
1252       if (TySize==4) Out << "int32 (0)";
1253       else if (TySize==8) Out << "int64 (0)";
1254       else assert(0 && "Invalid pointer size");
1255     }
1256     break;
1257   default:
1258     cerr << "TypeID = " << Ty->getTypeID() << '\n';
1259     assert(0 && "Invalid type in printStaticConstant()");
1260   }
1261   // Increase offset.
1262   Offset += TySize;
1263 }
1264
1265
1266 void MSILWriter::printStaticInitializer(const Constant* C,
1267                                         const std::string& Name) {
1268   switch (C->getType()->getTypeID()) {
1269   case Type::IntegerTyID:
1270   case Type::FloatTyID:
1271   case Type::DoubleTyID: 
1272     Out << getPrimitiveTypeName(C->getType(),true);
1273     break;
1274   case Type::ArrayTyID:
1275   case Type::VectorTyID:
1276   case Type::StructTyID:
1277   case Type::PointerTyID:
1278     Out << getTypeName(C->getType());
1279     break;
1280   default:
1281     cerr << "Type = " << *C << "\n";
1282     assert(0 && "Invalid constant type");
1283   }
1284   // Print initializer
1285   std::string label = Name;
1286   label.insert(label.length()-1,"$data");
1287   Out << Name << " at " << label << '\n';
1288   Out << ".data " << label << " = {\n";
1289   uint64_t offset = 0;
1290   printStaticConstant(C,offset);
1291   Out << "\n}\n\n";
1292 }
1293
1294
1295 void MSILWriter::printVariableDefinition(const GlobalVariable* G) {
1296   const Constant* C = G->getInitializer();
1297   if (C->isNullValue() || isa<ConstantAggregateZero>(C) || isa<UndefValue>(C))
1298     InitListPtr = 0;
1299   else
1300     InitListPtr = &StaticInitList[G];
1301   printStaticInitializer(C,getValueName(G));
1302 }
1303
1304
1305 void MSILWriter::printGlobalVariables() {
1306   if (ModulePtr->global_empty()) return;
1307   Module::global_iterator I,E;
1308   for (I = ModulePtr->global_begin(), E = ModulePtr->global_end(); I!=E; ++I) {
1309     // Variable definition
1310     if (I->isDeclaration()) continue;
1311     Out << ".field static " << (I->hasExternalLinkage() ? "public " :
1312                                                           "private ");
1313     printVariableDefinition(&*I);
1314   }
1315 }
1316
1317
1318 void MSILWriter::printExternals() {
1319   Module::const_iterator I,E;
1320   for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
1321     // Skip intrisics
1322     if (I->getIntrinsicID()) continue;
1323     // FIXME: Treat as standard library function
1324     if (I->isDeclaration()) {
1325       const Function* F = &*I; 
1326       const FunctionType* FTy = F->getFunctionType();
1327       std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
1328       std::string Sig = getCallSignature(FTy,NULL,Name);
1329       Out << ".method static hidebysig pinvokeimpl(\"msvcrt.dll\" cdecl)\n\t" 
1330         << Sig << " preservesig {}\n\n";
1331     }
1332   }
1333 }
1334
1335 //===----------------------------------------------------------------------===//
1336 //                      External Interface declaration
1337 //===----------------------------------------------------------------------===//
1338
1339 bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
1340                                           CodeGenFileType FileType, bool Fast)
1341 {
1342   if (FileType != TargetMachine::AssemblyFile) return true;
1343   MSILWriter* Writer = new MSILWriter(o);
1344   PM.add(createLowerGCPass());
1345   PM.add(createLowerAllocationsPass(true));
1346   // FIXME: Handle switch trougth native IL instruction "switch"
1347   PM.add(createLowerSwitchPass());
1348   PM.add(createCFGSimplificationPass());
1349   PM.add(new MSILModule(Writer->UsedTypes,Writer->TD));
1350   PM.add(Writer);
1351   return false;
1352 }