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