1 //===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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/ErrorHandling.h"
23 #include "llvm/Support/InstVisitor.h"
24 #include "llvm/Support/MathExtras.h"
25 #include "llvm/Target/TargetRegistry.h"
26 #include "llvm/Transforms/Scalar.h"
27 #include "llvm/ADT/StringExtras.h"
28 #include "llvm/CodeGen/Passes.h"
32 // TargetMachine for the MSIL
33 struct VISIBILITY_HIDDEN MSILTarget
: public TargetMachine
{
34 MSILTarget(const Target
&T
, const std::string
&TT
, const std::string
&FS
)
37 virtual bool WantsWholeFile() const { return true; }
38 virtual bool addPassesToEmitWholeFile(PassManager
&PM
,
39 formatted_raw_ostream
&Out
,
40 CodeGenFileType FileType
,
41 CodeGenOpt::Level OptLevel
);
43 virtual const TargetData
*getTargetData() const { return 0; }
47 extern "C" void LLVMInitializeMSILTarget() {
48 // Register the target.
49 RegisterTargetMachine
<MSILTarget
> X(TheMSILTarget
);
52 bool MSILModule::runOnModule(Module
&M
) {
54 TD
= &getAnalysis
<TargetData
>();
57 TypeSymbolTable
& Table
= M
.getTypeSymbolTable();
58 std::set
<const Type
*> Types
= getAnalysis
<FindUsedTypes
>().getTypes();
59 for (TypeSymbolTable::iterator I
= Table
.begin(), E
= Table
.end(); I
!=E
; ) {
60 if (!isa
<StructType
>(I
->second
) && !isa
<OpaqueType
>(I
->second
))
63 std::set
<const Type
*>::iterator T
= Types
.find(I
->second
);
72 // Find unnamed types.
73 unsigned RenameCounter
= 0;
74 for (std::set
<const Type
*>::const_iterator I
= Types
.begin(),
75 E
= Types
.end(); I
!=E
; ++I
)
76 if (const StructType
*STy
= dyn_cast
<StructType
>(*I
)) {
77 while (ModulePtr
->addTypeName("unnamed$"+utostr(RenameCounter
), STy
))
81 // Pointer for FunctionPass.
82 UsedTypes
= &getAnalysis
<FindUsedTypes
>().getTypes();
86 char MSILModule::ID
= 0;
87 char MSILWriter::ID
= 0;
89 bool MSILWriter::runOnFunction(Function
&F
) {
90 if (F
.isDeclaration()) return false;
92 // Do not codegen any 'available_externally' functions at all, they have
93 // definitions outside the translation unit.
94 if (F
.hasAvailableExternallyLinkage())
97 LInfo
= &getAnalysis
<LoopInfo
>();
103 bool MSILWriter::doInitialization(Module
&M
) {
105 Mang
= new Mangler(M
);
106 Out
<< ".assembly extern mscorlib {}\n";
107 Out
<< ".assembly MSIL {}\n\n";
108 Out
<< "// External\n";
110 Out
<< "// Declarations\n";
111 printDeclarations(M
.getTypeSymbolTable());
112 Out
<< "// Definitions\n";
113 printGlobalVariables();
114 Out
<< "// Startup code\n";
115 printModuleStartup();
120 bool MSILWriter::doFinalization(Module
&M
) {
126 void MSILWriter::printModuleStartup() {
128 ".method static public int32 $MSIL_Startup() {\n"
130 "\t.locals (native int i)\n"
131 "\t.locals (native int argc)\n"
132 "\t.locals (native int ptr)\n"
133 "\t.locals (void* argv)\n"
134 "\t.locals (string[] args)\n"
135 "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n"
142 printPtrLoad(TD
->getPointerSize());
157 "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::"
158 "StringToHGlobalAnsi(string)\n"
162 printPtrLoad(TD
->getPointerSize());
174 "\tcall void $MSIL_Init()\n";
176 // Call user 'main' function.
177 const Function
* F
= ModulePtr
->getFunction("main");
178 if (!F
|| F
->isDeclaration()) {
179 Out
<< "\tldc.i4.0\n\tret\n}\n";
183 std::string
Args("");
184 Function::const_arg_iterator Arg1
,Arg2
;
186 switch (F
->arg_size()) {
191 Arg1
= F
->arg_begin();
192 if (Arg1
->getType()->isInteger()) {
193 Out
<< "\tldloc\targc\n";
194 Args
= getTypeName(Arg1
->getType());
199 Arg1
= Arg2
= F
->arg_begin(); ++Arg2
;
200 if (Arg1
->getType()->isInteger() &&
201 Arg2
->getType()->getTypeID() == Type::PointerTyID
) {
202 Out
<< "\tldloc\targc\n\tldloc\targv\n";
203 Args
= getTypeName(Arg1
->getType())+","+getTypeName(Arg2
->getType());
211 bool RetVoid
= (F
->getReturnType()->getTypeID() == Type::VoidTyID
);
212 if (BadSig
|| (!F
->getReturnType()->isInteger() && !RetVoid
)) {
213 Out
<< "\tldc.i4.0\n";
215 Out
<< "\tcall\t" << getTypeName(F
->getReturnType()) <<
216 getConvModopt(F
->getCallingConv()) << "main(" << Args
<< ")\n";
218 Out
<< "\tldc.i4.0\n";
220 Out
<< "\tconv.i4\n";
225 bool MSILWriter::isZeroValue(const Value
* V
) {
226 if (const Constant
*C
= dyn_cast
<Constant
>(V
))
227 return C
->isNullValue();
232 std::string
MSILWriter::getValueName(const Value
* V
) {
234 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(V
))
235 Name
= Mang
->getMangledName(GV
);
237 unsigned &No
= AnonValueNumbers
[V
];
238 if (No
== 0) No
= ++NextAnonValueNumber
;
239 Name
= "tmp" + utostr(No
);
242 // Name into the quotes allow control and space characters.
247 std::string
MSILWriter::getLabelName(const std::string
& Name
) {
248 if (Name
.find('.')!=std::string::npos
) {
249 std::string
Tmp(Name
);
250 // Replace unaccepable characters in the label name.
251 for (std::string::iterator I
= Tmp
.begin(), E
= Tmp
.end(); I
!=E
; ++I
)
252 if (*I
=='.') *I
= '@';
259 std::string
MSILWriter::getLabelName(const Value
* V
) {
261 if (const GlobalValue
*GV
= dyn_cast
<GlobalValue
>(V
))
262 Name
= Mang
->getMangledName(GV
);
264 unsigned &No
= AnonValueNumbers
[V
];
265 if (No
== 0) No
= ++NextAnonValueNumber
;
266 Name
= "tmp" + utostr(No
);
269 return getLabelName(Name
);
273 std::string
MSILWriter::getConvModopt(CallingConv::ID CallingConvID
) {
274 switch (CallingConvID
) {
276 case CallingConv::Cold
:
277 case CallingConv::Fast
:
278 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) ";
279 case CallingConv::X86_FastCall
:
280 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) ";
281 case CallingConv::X86_StdCall
:
282 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) ";
284 errs() << "CallingConvID = " << CallingConvID
<< '\n';
285 llvm_unreachable("Unsupported calling convention");
287 return ""; // Not reached
291 std::string
MSILWriter::getArrayTypeName(Type::TypeID TyID
, const Type
* Ty
) {
292 std::string Tmp
= "";
293 const Type
* ElemTy
= Ty
;
294 assert(Ty
->getTypeID()==TyID
&& "Invalid type passed");
295 // Walk trought array element types.
297 // Multidimensional array.
298 if (ElemTy
->getTypeID()==TyID
) {
299 if (const ArrayType
* ATy
= dyn_cast
<ArrayType
>(ElemTy
))
300 Tmp
+= utostr(ATy
->getNumElements());
301 else if (const VectorType
* VTy
= dyn_cast
<VectorType
>(ElemTy
))
302 Tmp
+= utostr(VTy
->getNumElements());
303 ElemTy
= cast
<SequentialType
>(ElemTy
)->getElementType();
305 // Base element type found.
306 if (ElemTy
->getTypeID()!=TyID
) break;
309 return getTypeName(ElemTy
, false, true)+"["+Tmp
+"]";
313 std::string
MSILWriter::getPrimitiveTypeName(const Type
* Ty
, bool isSigned
) {
314 unsigned NumBits
= 0;
315 switch (Ty
->getTypeID()) {
318 case Type::IntegerTyID
:
319 NumBits
= getBitWidth(Ty
);
323 return "unsigned int"+utostr(NumBits
)+" ";
324 return "int"+utostr(NumBits
)+" ";
325 case Type::FloatTyID
:
327 case Type::DoubleTyID
:
330 errs() << "Type = " << *Ty
<< '\n';
331 llvm_unreachable("Invalid primitive type");
333 return ""; // Not reached
337 std::string
MSILWriter::getTypeName(const Type
* Ty
, bool isSigned
,
339 if (Ty
->isPrimitiveType() || Ty
->isInteger())
340 return getPrimitiveTypeName(Ty
,isSigned
);
341 // FIXME: "OpaqueType" support
342 switch (Ty
->getTypeID()) {
343 case Type::PointerTyID
:
345 case Type::StructTyID
:
347 return ModulePtr
->getTypeName(Ty
);
348 return "valuetype '"+ModulePtr
->getTypeName(Ty
)+"' ";
349 case Type::ArrayTyID
:
351 return getArrayTypeName(Ty
->getTypeID(),Ty
);
352 return "valuetype '"+getArrayTypeName(Ty
->getTypeID(),Ty
)+"' ";
353 case Type::VectorTyID
:
355 return getArrayTypeName(Ty
->getTypeID(),Ty
);
356 return "valuetype '"+getArrayTypeName(Ty
->getTypeID(),Ty
)+"' ";
358 errs() << "Type = " << *Ty
<< '\n';
359 llvm_unreachable("Invalid type in getTypeName()");
361 return ""; // Not reached
365 MSILWriter::ValueType
MSILWriter::getValueLocation(const Value
* V
) {
367 if (isa
<Argument
>(V
))
370 else if (const Function
* F
= dyn_cast
<Function
>(V
))
371 return F
->hasLocalLinkage() ? InternalVT
: GlobalVT
;
373 else if (const GlobalVariable
* G
= dyn_cast
<GlobalVariable
>(V
))
374 return G
->hasLocalLinkage() ? InternalVT
: GlobalVT
;
376 else if (isa
<Constant
>(V
))
377 return isa
<ConstantExpr
>(V
) ? ConstExprVT
: ConstVT
;
383 std::string
MSILWriter::getTypePostfix(const Type
* Ty
, bool Expand
,
385 unsigned NumBits
= 0;
386 switch (Ty
->getTypeID()) {
387 // Integer constant, expanding for stack operations.
388 case Type::IntegerTyID
:
389 NumBits
= getBitWidth(Ty
);
390 // Expand integer value to "int32" or "int64".
391 if (Expand
) return (NumBits
<=32 ? "i4" : "i8");
392 if (NumBits
==1) return "i1";
393 return (isSigned
? "i" : "u")+utostr(NumBits
/8);
395 case Type::FloatTyID
:
397 case Type::DoubleTyID
:
399 case Type::PointerTyID
:
400 return "i"+utostr(TD
->getTypeAllocSize(Ty
));
402 errs() << "TypeID = " << Ty
->getTypeID() << '\n';
403 llvm_unreachable("Invalid type in TypeToPostfix()");
405 return ""; // Not reached
409 void MSILWriter::printConvToPtr() {
410 switch (ModulePtr
->getPointerSize()) {
411 case Module::Pointer32
:
412 printSimpleInstruction("conv.u4");
414 case Module::Pointer64
:
415 printSimpleInstruction("conv.u8");
418 llvm_unreachable("Module use not supporting pointer size");
423 void MSILWriter::printPtrLoad(uint64_t N
) {
424 switch (ModulePtr
->getPointerSize()) {
425 case Module::Pointer32
:
426 printSimpleInstruction("ldc.i4",utostr(N
).c_str());
427 // FIXME: Need overflow test?
429 errs() << "Value = " << utostr(N
) << '\n';
430 llvm_unreachable("32-bit pointer overflowed");
433 case Module::Pointer64
:
434 printSimpleInstruction("ldc.i8",utostr(N
).c_str());
437 llvm_unreachable("Module use not supporting pointer size");
442 void MSILWriter::printValuePtrLoad(const Value
* V
) {
448 void MSILWriter::printConstLoad(const Constant
* C
) {
449 if (const ConstantInt
* CInt
= dyn_cast
<ConstantInt
>(C
)) {
451 Out
<< "\tldc." << getTypePostfix(C
->getType(),true) << '\t';
452 if (CInt
->isMinValue(true))
453 Out
<< CInt
->getSExtValue();
455 Out
<< CInt
->getZExtValue();
456 } else if (const ConstantFP
* FP
= dyn_cast
<ConstantFP
>(C
)) {
460 if (FP
->getType()->getTypeID()==Type::FloatTyID
) {
461 X
= (uint32_t)FP
->getValueAPF().bitcastToAPInt().getZExtValue();
464 X
= FP
->getValueAPF().bitcastToAPInt().getZExtValue();
467 Out
<< "\tldc.r" << Size
<< "\t( " << utohexstr(X
) << ')';
468 } else if (isa
<UndefValue
>(C
)) {
469 // Undefined constant value = NULL.
472 errs() << "Constant = " << *C
<< '\n';
473 llvm_unreachable("Invalid constant value");
479 void MSILWriter::printValueLoad(const Value
* V
) {
480 MSILWriter::ValueType Location
= getValueLocation(V
);
482 // Global variable or function address.
485 if (const Function
* F
= dyn_cast
<Function
>(V
)) {
486 std::string Name
= getConvModopt(F
->getCallingConv())+getValueName(F
);
487 printSimpleInstruction("ldftn",
488 getCallSignature(F
->getFunctionType(),NULL
,Name
).c_str());
491 const Type
* ElemTy
= cast
<PointerType
>(V
->getType())->getElementType();
492 if (Location
==GlobalVT
&& cast
<GlobalVariable
>(V
)->hasDLLImportLinkage()) {
493 Tmp
= "void* "+getValueName(V
);
494 printSimpleInstruction("ldsfld",Tmp
.c_str());
496 Tmp
= getTypeName(ElemTy
)+getValueName(V
);
497 printSimpleInstruction("ldsflda",Tmp
.c_str());
501 // Function argument.
503 printSimpleInstruction("ldarg",getValueName(V
).c_str());
505 // Local function variable.
507 printSimpleInstruction("ldloc",getValueName(V
).c_str());
511 if (isa
<ConstantPointerNull
>(V
))
514 printConstLoad(cast
<Constant
>(V
));
516 // Constant expression.
518 printConstantExpr(cast
<ConstantExpr
>(V
));
521 errs() << "Value = " << *V
<< '\n';
522 llvm_unreachable("Invalid value location");
527 void MSILWriter::printValueSave(const Value
* V
) {
528 switch (getValueLocation(V
)) {
530 printSimpleInstruction("starg",getValueName(V
).c_str());
533 printSimpleInstruction("stloc",getValueName(V
).c_str());
536 errs() << "Value = " << *V
<< '\n';
537 llvm_unreachable("Invalid value location");
542 void MSILWriter::printBinaryInstruction(const char* Name
, const Value
* Left
,
543 const Value
* Right
) {
544 printValueLoad(Left
);
545 printValueLoad(Right
);
546 Out
<< '\t' << Name
<< '\n';
550 void MSILWriter::printSimpleInstruction(const char* Inst
, const char* Operand
) {
552 Out
<< '\t' << Inst
<< '\t' << Operand
<< '\n';
554 Out
<< '\t' << Inst
<< '\n';
558 void MSILWriter::printPHICopy(const BasicBlock
* Src
, const BasicBlock
* Dst
) {
559 for (BasicBlock::const_iterator I
= Dst
->begin(), E
= Dst
->end();
560 isa
<PHINode
>(I
); ++I
) {
561 const PHINode
* Phi
= cast
<PHINode
>(I
);
562 const Value
* Val
= Phi
->getIncomingValueForBlock(Src
);
563 if (isa
<UndefValue
>(Val
)) continue;
570 void MSILWriter::printBranchToBlock(const BasicBlock
* CurrBB
,
571 const BasicBlock
* TrueBB
,
572 const BasicBlock
* FalseBB
) {
573 if (TrueBB
==FalseBB
) {
574 // "TrueBB" and "FalseBB" destination equals
575 printPHICopy(CurrBB
,TrueBB
);
576 printSimpleInstruction("pop");
577 printSimpleInstruction("br",getLabelName(TrueBB
).c_str());
578 } else if (FalseBB
==NULL
) {
579 // If "FalseBB" not used the jump have condition
580 printPHICopy(CurrBB
,TrueBB
);
581 printSimpleInstruction("brtrue",getLabelName(TrueBB
).c_str());
582 } else if (TrueBB
==NULL
) {
583 // If "TrueBB" not used the jump is unconditional
584 printPHICopy(CurrBB
,FalseBB
);
585 printSimpleInstruction("br",getLabelName(FalseBB
).c_str());
587 // Copy PHI instructions for each block
588 std::string TmpLabel
;
589 // Print PHI instructions for "TrueBB"
590 if (isa
<PHINode
>(TrueBB
->begin())) {
591 TmpLabel
= getLabelName(TrueBB
)+"$phi_"+utostr(getUniqID());
592 printSimpleInstruction("brtrue",TmpLabel
.c_str());
594 printSimpleInstruction("brtrue",getLabelName(TrueBB
).c_str());
596 // Print PHI instructions for "FalseBB"
597 if (isa
<PHINode
>(FalseBB
->begin())) {
598 printPHICopy(CurrBB
,FalseBB
);
599 printSimpleInstruction("br",getLabelName(FalseBB
).c_str());
601 printSimpleInstruction("br",getLabelName(FalseBB
).c_str());
603 if (isa
<PHINode
>(TrueBB
->begin())) {
604 // Handle "TrueBB" PHI Copy
605 Out
<< TmpLabel
<< ":\n";
606 printPHICopy(CurrBB
,TrueBB
);
607 printSimpleInstruction("br",getLabelName(TrueBB
).c_str());
613 void MSILWriter::printBranchInstruction(const BranchInst
* Inst
) {
614 if (Inst
->isUnconditional()) {
615 printBranchToBlock(Inst
->getParent(),NULL
,Inst
->getSuccessor(0));
617 printValueLoad(Inst
->getCondition());
618 printBranchToBlock(Inst
->getParent(),Inst
->getSuccessor(0),
619 Inst
->getSuccessor(1));
624 void MSILWriter::printSelectInstruction(const Value
* Cond
, const Value
* VTrue
,
625 const Value
* VFalse
) {
626 std::string TmpLabel
= std::string("select$true_")+utostr(getUniqID());
627 printValueLoad(VTrue
);
628 printValueLoad(Cond
);
629 printSimpleInstruction("brtrue",TmpLabel
.c_str());
630 printSimpleInstruction("pop");
631 printValueLoad(VFalse
);
632 Out
<< TmpLabel
<< ":\n";
636 void MSILWriter::printIndirectLoad(const Value
* V
) {
637 const Type
* Ty
= V
->getType();
639 if (const PointerType
* P
= dyn_cast
<PointerType
>(Ty
))
640 Ty
= P
->getElementType();
641 std::string Tmp
= "ldind."+getTypePostfix(Ty
, false);
642 printSimpleInstruction(Tmp
.c_str());
646 void MSILWriter::printIndirectSave(const Value
* Ptr
, const Value
* Val
) {
649 printIndirectSave(Val
->getType());
653 void MSILWriter::printIndirectSave(const Type
* Ty
) {
654 // Instruction need signed postfix for any type.
655 std::string postfix
= getTypePostfix(Ty
, false);
656 if (*postfix
.begin()=='u') *postfix
.begin() = 'i';
657 postfix
= "stind."+postfix
;
658 printSimpleInstruction(postfix
.c_str());
662 void MSILWriter::printCastInstruction(unsigned int Op
, const Value
* V
,
663 const Type
* Ty
, const Type
* SrcTy
) {
668 case Instruction::SExt
:
669 // If sign extending int, convert first from unsigned to signed
670 // with the same bit size - because otherwise we will loose the sign.
672 Tmp
= "conv."+getTypePostfix(SrcTy
,false,true);
673 printSimpleInstruction(Tmp
.c_str());
676 case Instruction::SIToFP
:
677 case Instruction::FPToSI
:
678 Tmp
= "conv."+getTypePostfix(Ty
,false,true);
679 printSimpleInstruction(Tmp
.c_str());
682 case Instruction::FPTrunc
:
683 case Instruction::FPExt
:
684 case Instruction::UIToFP
:
685 case Instruction::Trunc
:
686 case Instruction::ZExt
:
687 case Instruction::FPToUI
:
688 case Instruction::PtrToInt
:
689 case Instruction::IntToPtr
:
690 Tmp
= "conv."+getTypePostfix(Ty
,false);
691 printSimpleInstruction(Tmp
.c_str());
694 case Instruction::BitCast
:
695 // FIXME: meaning that ld*/st* instruction do not change data format.
698 errs() << "Opcode = " << Op
<< '\n';
699 llvm_unreachable("Invalid conversion instruction");
704 void MSILWriter::printGepInstruction(const Value
* V
, gep_type_iterator I
,
705 gep_type_iterator E
) {
708 printValuePtrLoad(V
);
709 // Calculate element offset.
712 const Value
* IndexValue
= I
.getOperand();
713 if (const StructType
* StrucTy
= dyn_cast
<StructType
>(*I
)) {
714 uint64_t FieldIndex
= cast
<ConstantInt
>(IndexValue
)->getZExtValue();
715 // Offset is the sum of all previous structure fields.
716 for (uint64_t F
= 0; F
<FieldIndex
; ++F
)
717 Size
+= TD
->getTypeAllocSize(StrucTy
->getContainedType((unsigned)F
));
719 printSimpleInstruction("add");
721 } else if (const SequentialType
* SeqTy
= dyn_cast
<SequentialType
>(*I
)) {
722 Size
= TD
->getTypeAllocSize(SeqTy
->getElementType());
724 Size
= TD
->getTypeAllocSize(*I
);
726 // Add offset of current element to stack top.
727 if (!isZeroValue(IndexValue
)) {
728 // Constant optimization.
729 if (const ConstantInt
* C
= dyn_cast
<ConstantInt
>(IndexValue
)) {
730 if (C
->getValue().isNegative()) {
731 printPtrLoad(C
->getValue().abs().getZExtValue()*Size
);
732 printSimpleInstruction("sub");
735 printPtrLoad(C
->getZExtValue()*Size
);
738 printValuePtrLoad(IndexValue
);
739 printSimpleInstruction("mul");
741 printSimpleInstruction("add");
747 std::string
MSILWriter::getCallSignature(const FunctionType
* Ty
,
748 const Instruction
* Inst
,
751 if (Ty
->isVarArg()) Tmp
+= "vararg ";
752 // Name and return type.
753 Tmp
+= getTypeName(Ty
->getReturnType())+Name
+"(";
754 // Function argument type list.
755 unsigned NumParams
= Ty
->getNumParams();
756 for (unsigned I
= 0; I
!=NumParams
; ++I
) {
757 if (I
!=0) Tmp
+= ",";
758 Tmp
+= getTypeName(Ty
->getParamType(I
));
760 // CLR needs to know the exact amount of parameters received by vararg
761 // function, because caller cleans the stack.
762 if (Ty
->isVarArg() && Inst
) {
763 // Origin to function arguments in "CallInst" or "InvokeInst".
764 unsigned Org
= isa
<InvokeInst
>(Inst
) ? 3 : 1;
765 // Print variable argument types.
766 unsigned NumOperands
= Inst
->getNumOperands()-Org
;
767 if (NumParams
<NumOperands
) {
768 if (NumParams
!=0) Tmp
+= ", ";
770 for (unsigned J
= NumParams
; J
!=NumOperands
; ++J
) {
771 if (J
!=NumParams
) Tmp
+= ", ";
772 Tmp
+= getTypeName(Inst
->getOperand(J
+Org
)->getType());
780 void MSILWriter::printFunctionCall(const Value
* FnVal
,
781 const Instruction
* Inst
) {
782 // Get function calling convention.
783 std::string Name
= "";
784 if (const CallInst
* Call
= dyn_cast
<CallInst
>(Inst
))
785 Name
= getConvModopt(Call
->getCallingConv());
786 else if (const InvokeInst
* Invoke
= dyn_cast
<InvokeInst
>(Inst
))
787 Name
= getConvModopt(Invoke
->getCallingConv());
789 errs() << "Instruction = " << Inst
->getName() << '\n';
790 llvm_unreachable("Need \"Invoke\" or \"Call\" instruction only");
792 if (const Function
* F
= dyn_cast
<Function
>(FnVal
)) {
794 Name
+= getValueName(F
);
795 printSimpleInstruction("call",
796 getCallSignature(F
->getFunctionType(),Inst
,Name
).c_str());
798 // Indirect function call.
799 const PointerType
* PTy
= cast
<PointerType
>(FnVal
->getType());
800 const FunctionType
* FTy
= cast
<FunctionType
>(PTy
->getElementType());
801 // Load function address.
802 printValueLoad(FnVal
);
803 printSimpleInstruction("calli",getCallSignature(FTy
,Inst
,Name
).c_str());
808 void MSILWriter::printIntrinsicCall(const IntrinsicInst
* Inst
) {
810 switch (Inst
->getIntrinsicID()) {
811 case Intrinsic::vastart
:
812 Name
= getValueName(Inst
->getOperand(1));
813 Name
.insert(Name
.length()-1,"$valist");
814 // Obtain the argument handle.
815 printSimpleInstruction("ldloca",Name
.c_str());
816 printSimpleInstruction("arglist");
817 printSimpleInstruction("call",
818 "instance void [mscorlib]System.ArgIterator::.ctor"
819 "(valuetype [mscorlib]System.RuntimeArgumentHandle)");
820 // Save as pointer type "void*"
821 printValueLoad(Inst
->getOperand(1));
822 printSimpleInstruction("ldloca",Name
.c_str());
823 printIndirectSave(PointerType::getUnqual(
824 IntegerType::get(Inst
->getContext(), 8)));
826 case Intrinsic::vaend
:
827 // Close argument list handle.
828 printIndirectLoad(Inst
->getOperand(1));
829 printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()");
831 case Intrinsic::vacopy
:
832 // Copy "ArgIterator" valuetype.
833 printIndirectLoad(Inst
->getOperand(1));
834 printIndirectLoad(Inst
->getOperand(2));
835 printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator");
838 errs() << "Intrinsic ID = " << Inst
->getIntrinsicID() << '\n';
839 llvm_unreachable("Invalid intrinsic function");
844 void MSILWriter::printCallInstruction(const Instruction
* Inst
) {
845 if (isa
<IntrinsicInst
>(Inst
)) {
846 // Handle intrinsic function.
847 printIntrinsicCall(cast
<IntrinsicInst
>(Inst
));
849 // Load arguments to stack and call function.
850 for (int I
= 1, E
= Inst
->getNumOperands(); I
!=E
; ++I
)
851 printValueLoad(Inst
->getOperand(I
));
852 printFunctionCall(Inst
->getOperand(0),Inst
);
857 void MSILWriter::printICmpInstruction(unsigned Predicate
, const Value
* Left
,
858 const Value
* Right
) {
860 case ICmpInst::ICMP_EQ
:
861 printBinaryInstruction("ceq",Left
,Right
);
863 case ICmpInst::ICMP_NE
:
864 // Emulate = not neg (Op1 eq Op2)
865 printBinaryInstruction("ceq",Left
,Right
);
866 printSimpleInstruction("neg");
867 printSimpleInstruction("not");
869 case ICmpInst::ICMP_ULE
:
870 case ICmpInst::ICMP_SLE
:
871 // Emulate = (Op1 eq Op2) or (Op1 lt Op2)
872 printBinaryInstruction("ceq",Left
,Right
);
873 if (Predicate
==ICmpInst::ICMP_ULE
)
874 printBinaryInstruction("clt.un",Left
,Right
);
876 printBinaryInstruction("clt",Left
,Right
);
877 printSimpleInstruction("or");
879 case ICmpInst::ICMP_UGE
:
880 case ICmpInst::ICMP_SGE
:
881 // Emulate = (Op1 eq Op2) or (Op1 gt Op2)
882 printBinaryInstruction("ceq",Left
,Right
);
883 if (Predicate
==ICmpInst::ICMP_UGE
)
884 printBinaryInstruction("cgt.un",Left
,Right
);
886 printBinaryInstruction("cgt",Left
,Right
);
887 printSimpleInstruction("or");
889 case ICmpInst::ICMP_ULT
:
890 printBinaryInstruction("clt.un",Left
,Right
);
892 case ICmpInst::ICMP_SLT
:
893 printBinaryInstruction("clt",Left
,Right
);
895 case ICmpInst::ICMP_UGT
:
896 printBinaryInstruction("cgt.un",Left
,Right
);
898 case ICmpInst::ICMP_SGT
:
899 printBinaryInstruction("cgt",Left
,Right
);
902 errs() << "Predicate = " << Predicate
<< '\n';
903 llvm_unreachable("Invalid icmp predicate");
908 void MSILWriter::printFCmpInstruction(unsigned Predicate
, const Value
* Left
,
909 const Value
* Right
) {
910 // FIXME: Correct comparison
911 std::string NanFunc
= "bool [mscorlib]System.Double::IsNaN(float64)";
913 case FCmpInst::FCMP_UGT
:
914 // X > Y || llvm_fcmp_uno(X, Y)
915 printBinaryInstruction("cgt",Left
,Right
);
916 printFCmpInstruction(FCmpInst::FCMP_UNO
,Left
,Right
);
917 printSimpleInstruction("or");
919 case FCmpInst::FCMP_OGT
:
921 printBinaryInstruction("cgt",Left
,Right
);
923 case FCmpInst::FCMP_UGE
:
924 // X >= Y || llvm_fcmp_uno(X, Y)
925 printBinaryInstruction("ceq",Left
,Right
);
926 printBinaryInstruction("cgt",Left
,Right
);
927 printSimpleInstruction("or");
928 printFCmpInstruction(FCmpInst::FCMP_UNO
,Left
,Right
);
929 printSimpleInstruction("or");
931 case FCmpInst::FCMP_OGE
:
933 printBinaryInstruction("ceq",Left
,Right
);
934 printBinaryInstruction("cgt",Left
,Right
);
935 printSimpleInstruction("or");
937 case FCmpInst::FCMP_ULT
:
938 // X < Y || llvm_fcmp_uno(X, Y)
939 printBinaryInstruction("clt",Left
,Right
);
940 printFCmpInstruction(FCmpInst::FCMP_UNO
,Left
,Right
);
941 printSimpleInstruction("or");
943 case FCmpInst::FCMP_OLT
:
945 printBinaryInstruction("clt",Left
,Right
);
947 case FCmpInst::FCMP_ULE
:
948 // X <= Y || llvm_fcmp_uno(X, Y)
949 printBinaryInstruction("ceq",Left
,Right
);
950 printBinaryInstruction("clt",Left
,Right
);
951 printSimpleInstruction("or");
952 printFCmpInstruction(FCmpInst::FCMP_UNO
,Left
,Right
);
953 printSimpleInstruction("or");
955 case FCmpInst::FCMP_OLE
:
957 printBinaryInstruction("ceq",Left
,Right
);
958 printBinaryInstruction("clt",Left
,Right
);
959 printSimpleInstruction("or");
961 case FCmpInst::FCMP_UEQ
:
962 // X == Y || llvm_fcmp_uno(X, Y)
963 printBinaryInstruction("ceq",Left
,Right
);
964 printFCmpInstruction(FCmpInst::FCMP_UNO
,Left
,Right
);
965 printSimpleInstruction("or");
967 case FCmpInst::FCMP_OEQ
:
969 printBinaryInstruction("ceq",Left
,Right
);
971 case FCmpInst::FCMP_UNE
:
973 printBinaryInstruction("ceq",Left
,Right
);
974 printSimpleInstruction("neg");
975 printSimpleInstruction("not");
977 case FCmpInst::FCMP_ONE
:
978 // X != Y && llvm_fcmp_ord(X, Y)
979 printBinaryInstruction("ceq",Left
,Right
);
980 printSimpleInstruction("not");
982 case FCmpInst::FCMP_ORD
:
983 // return X == X && Y == Y
984 printBinaryInstruction("ceq",Left
,Left
);
985 printBinaryInstruction("ceq",Right
,Right
);
986 printSimpleInstruction("or");
988 case FCmpInst::FCMP_UNO
:
990 printBinaryInstruction("ceq",Left
,Left
);
991 printSimpleInstruction("not");
992 printBinaryInstruction("ceq",Right
,Right
);
993 printSimpleInstruction("not");
994 printSimpleInstruction("or");
997 llvm_unreachable("Illegal FCmp predicate");
1002 void MSILWriter::printInvokeInstruction(const InvokeInst
* Inst
) {
1003 std::string Label
= "leave$normal_"+utostr(getUniqID());
1006 for (int I
= 3, E
= Inst
->getNumOperands(); I
!=E
; ++I
)
1007 printValueLoad(Inst
->getOperand(I
));
1008 // Print call instruction
1009 printFunctionCall(Inst
->getOperand(0),Inst
);
1010 // Save function result and leave "try" block
1011 printValueSave(Inst
);
1012 printSimpleInstruction("leave",Label
.c_str());
1014 Out
<< "catch [mscorlib]System.Exception {\n";
1015 // Redirect to unwind block
1016 printSimpleInstruction("pop");
1017 printBranchToBlock(Inst
->getParent(),NULL
,Inst
->getUnwindDest());
1018 Out
<< "}\n" << Label
<< ":\n";
1019 // Redirect to continue block
1020 printBranchToBlock(Inst
->getParent(),NULL
,Inst
->getNormalDest());
1024 void MSILWriter::printSwitchInstruction(const SwitchInst
* Inst
) {
1025 // FIXME: Emulate with IL "switch" instruction
1026 // Emulate = if () else if () else if () else ...
1027 for (unsigned int I
= 1, E
= Inst
->getNumCases(); I
!=E
; ++I
) {
1028 printValueLoad(Inst
->getCondition());
1029 printValueLoad(Inst
->getCaseValue(I
));
1030 printSimpleInstruction("ceq");
1031 // Condition jump to successor block
1032 printBranchToBlock(Inst
->getParent(),Inst
->getSuccessor(I
),NULL
);
1034 // Jump to default block
1035 printBranchToBlock(Inst
->getParent(),NULL
,Inst
->getDefaultDest());
1039 void MSILWriter::printVAArgInstruction(const VAArgInst
* Inst
) {
1040 printIndirectLoad(Inst
->getOperand(0));
1041 printSimpleInstruction("call",
1042 "instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
1043 printSimpleInstruction("refanyval","void*");
1045 "ldind."+getTypePostfix(PointerType::getUnqual(
1046 IntegerType::get(Inst
->getContext(), 8)),false);
1047 printSimpleInstruction(Name
.c_str());
1051 void MSILWriter::printAllocaInstruction(const AllocaInst
* Inst
) {
1052 uint64_t Size
= TD
->getTypeAllocSize(Inst
->getAllocatedType());
1053 // Constant optimization.
1054 if (const ConstantInt
* CInt
= dyn_cast
<ConstantInt
>(Inst
->getOperand(0))) {
1055 printPtrLoad(CInt
->getZExtValue()*Size
);
1058 printValueLoad(Inst
->getOperand(0));
1059 printSimpleInstruction("mul");
1061 printSimpleInstruction("localloc");
1065 void MSILWriter::printInstruction(const Instruction
* Inst
) {
1066 const Value
*Left
= 0, *Right
= 0;
1067 if (Inst
->getNumOperands()>=1) Left
= Inst
->getOperand(0);
1068 if (Inst
->getNumOperands()>=2) Right
= Inst
->getOperand(1);
1069 // Print instruction
1070 // FIXME: "ShuffleVector","ExtractElement","InsertElement" support.
1071 switch (Inst
->getOpcode()) {
1073 case Instruction::Ret
:
1074 if (Inst
->getNumOperands()) {
1075 printValueLoad(Left
);
1076 printSimpleInstruction("ret");
1078 printSimpleInstruction("ret");
1080 case Instruction::Br
:
1081 printBranchInstruction(cast
<BranchInst
>(Inst
));
1084 case Instruction::Add
:
1085 case Instruction::FAdd
:
1086 printBinaryInstruction("add",Left
,Right
);
1088 case Instruction::Sub
:
1089 case Instruction::FSub
:
1090 printBinaryInstruction("sub",Left
,Right
);
1092 case Instruction::Mul
:
1093 case Instruction::FMul
:
1094 printBinaryInstruction("mul",Left
,Right
);
1096 case Instruction::UDiv
:
1097 printBinaryInstruction("div.un",Left
,Right
);
1099 case Instruction::SDiv
:
1100 case Instruction::FDiv
:
1101 printBinaryInstruction("div",Left
,Right
);
1103 case Instruction::URem
:
1104 printBinaryInstruction("rem.un",Left
,Right
);
1106 case Instruction::SRem
:
1107 case Instruction::FRem
:
1108 printBinaryInstruction("rem",Left
,Right
);
1111 case Instruction::ICmp
:
1112 printICmpInstruction(cast
<ICmpInst
>(Inst
)->getPredicate(),Left
,Right
);
1114 case Instruction::FCmp
:
1115 printFCmpInstruction(cast
<FCmpInst
>(Inst
)->getPredicate(),Left
,Right
);
1118 case Instruction::And
:
1119 printBinaryInstruction("and",Left
,Right
);
1121 case Instruction::Or
:
1122 printBinaryInstruction("or",Left
,Right
);
1124 case Instruction::Xor
:
1125 printBinaryInstruction("xor",Left
,Right
);
1127 case Instruction::Shl
:
1128 printValueLoad(Left
);
1129 printValueLoad(Right
);
1130 printSimpleInstruction("conv.i4");
1131 printSimpleInstruction("shl");
1133 case Instruction::LShr
:
1134 printValueLoad(Left
);
1135 printValueLoad(Right
);
1136 printSimpleInstruction("conv.i4");
1137 printSimpleInstruction("shr.un");
1139 case Instruction::AShr
:
1140 printValueLoad(Left
);
1141 printValueLoad(Right
);
1142 printSimpleInstruction("conv.i4");
1143 printSimpleInstruction("shr");
1145 case Instruction::Select
:
1146 printSelectInstruction(Inst
->getOperand(0),Inst
->getOperand(1),Inst
->getOperand(2));
1148 case Instruction::Load
:
1149 printIndirectLoad(Inst
->getOperand(0));
1151 case Instruction::Store
:
1152 printIndirectSave(Inst
->getOperand(1), Inst
->getOperand(0));
1154 case Instruction::SExt
:
1155 printCastInstruction(Inst
->getOpcode(),Left
,
1156 cast
<CastInst
>(Inst
)->getDestTy(),
1157 cast
<CastInst
>(Inst
)->getSrcTy());
1159 case Instruction::Trunc
:
1160 case Instruction::ZExt
:
1161 case Instruction::FPTrunc
:
1162 case Instruction::FPExt
:
1163 case Instruction::UIToFP
:
1164 case Instruction::SIToFP
:
1165 case Instruction::FPToUI
:
1166 case Instruction::FPToSI
:
1167 case Instruction::PtrToInt
:
1168 case Instruction::IntToPtr
:
1169 case Instruction::BitCast
:
1170 printCastInstruction(Inst
->getOpcode(),Left
,
1171 cast
<CastInst
>(Inst
)->getDestTy());
1173 case Instruction::GetElementPtr
:
1174 printGepInstruction(Inst
->getOperand(0),gep_type_begin(Inst
),
1175 gep_type_end(Inst
));
1177 case Instruction::Call
:
1178 printCallInstruction(cast
<CallInst
>(Inst
));
1180 case Instruction::Invoke
:
1181 printInvokeInstruction(cast
<InvokeInst
>(Inst
));
1183 case Instruction::Unwind
:
1184 printSimpleInstruction("newobj",
1185 "instance void [mscorlib]System.Exception::.ctor()");
1186 printSimpleInstruction("throw");
1188 case Instruction::Switch
:
1189 printSwitchInstruction(cast
<SwitchInst
>(Inst
));
1191 case Instruction::Alloca
:
1192 printAllocaInstruction(cast
<AllocaInst
>(Inst
));
1194 case Instruction::Malloc
:
1195 llvm_unreachable("LowerAllocationsPass used");
1197 case Instruction::Free
:
1198 llvm_unreachable("LowerAllocationsPass used");
1200 case Instruction::Unreachable
:
1201 printSimpleInstruction("ldstr", "\"Unreachable instruction\"");
1202 printSimpleInstruction("newobj",
1203 "instance void [mscorlib]System.Exception::.ctor(string)");
1204 printSimpleInstruction("throw");
1206 case Instruction::VAArg
:
1207 printVAArgInstruction(cast
<VAArgInst
>(Inst
));
1210 errs() << "Instruction = " << Inst
->getName() << '\n';
1211 llvm_unreachable("Unsupported instruction");
1216 void MSILWriter::printLoop(const Loop
* L
) {
1217 Out
<< getLabelName(L
->getHeader()->getName()) << ":\n";
1218 const std::vector
<BasicBlock
*>& blocks
= L
->getBlocks();
1219 for (unsigned I
= 0, E
= blocks
.size(); I
!=E
; I
++) {
1220 BasicBlock
* BB
= blocks
[I
];
1221 Loop
* BBLoop
= LInfo
->getLoopFor(BB
);
1223 printBasicBlock(BB
);
1224 else if (BB
==BBLoop
->getHeader() && BBLoop
->getParentLoop()==L
)
1227 printSimpleInstruction("br",getLabelName(L
->getHeader()->getName()).c_str());
1231 void MSILWriter::printBasicBlock(const BasicBlock
* BB
) {
1232 Out
<< getLabelName(BB
) << ":\n";
1233 for (BasicBlock::const_iterator I
= BB
->begin(), E
= BB
->end(); I
!=E
; ++I
) {
1234 const Instruction
* Inst
= I
;
1235 // Comment llvm original instruction
1236 // Out << "\n//" << *Inst << "\n";
1237 // Do not handle PHI instruction in current block
1238 if (Inst
->getOpcode()==Instruction::PHI
) continue;
1239 // Print instruction
1240 printInstruction(Inst
);
1242 if (Inst
->getType()!=Type::getVoidTy(BB
->getContext())) {
1243 // Do not save value after invoke, it done in "try" block
1244 if (Inst
->getOpcode()==Instruction::Invoke
) continue;
1245 printValueSave(Inst
);
1251 void MSILWriter::printLocalVariables(const Function
& F
) {
1253 const Type
* Ty
= NULL
;
1254 std::set
<const Value
*> Printed
;
1255 const Value
* VaList
= NULL
;
1256 unsigned StackDepth
= 8;
1257 // Find local variables
1258 for (const_inst_iterator I
= inst_begin(&F
), E
= inst_end(&F
); I
!=E
; ++I
) {
1259 if (I
->getOpcode()==Instruction::Call
||
1260 I
->getOpcode()==Instruction::Invoke
) {
1261 // Test stack depth.
1262 if (StackDepth
<I
->getNumOperands())
1263 StackDepth
= I
->getNumOperands();
1265 const AllocaInst
* AI
= dyn_cast
<AllocaInst
>(&*I
);
1266 if (AI
&& !isa
<GlobalVariable
>(AI
)) {
1267 // Local variable allocation.
1268 Ty
= PointerType::getUnqual(AI
->getAllocatedType());
1269 Name
= getValueName(AI
);
1270 Out
<< "\t.locals (" << getTypeName(Ty
) << Name
<< ")\n";
1271 } else if (I
->getType()!=Type::getVoidTy(F
.getContext())) {
1272 // Operation result.
1274 Name
= getValueName(&*I
);
1275 Out
<< "\t.locals (" << getTypeName(Ty
) << Name
<< ")\n";
1277 // Test on 'va_list' variable
1278 bool isVaList
= false;
1279 if (const VAArgInst
* VaInst
= dyn_cast
<VAArgInst
>(&*I
)) {
1280 // "va_list" as "va_arg" instruction operand.
1282 VaList
= VaInst
->getOperand(0);
1283 } else if (const IntrinsicInst
* Inst
= dyn_cast
<IntrinsicInst
>(&*I
)) {
1284 // "va_list" as intrinsic function operand.
1285 switch (Inst
->getIntrinsicID()) {
1286 case Intrinsic::vastart
:
1287 case Intrinsic::vaend
:
1288 case Intrinsic::vacopy
:
1290 VaList
= Inst
->getOperand(1);
1296 // Print "va_list" variable.
1297 if (isVaList
&& Printed
.insert(VaList
).second
) {
1298 Name
= getValueName(VaList
);
1299 Name
.insert(Name
.length()-1,"$valist");
1300 Out
<< "\t.locals (valuetype [mscorlib]System.ArgIterator "
1304 printSimpleInstruction(".maxstack",utostr(StackDepth
*2).c_str());
1308 void MSILWriter::printFunctionBody(const Function
& F
) {
1310 for (Function::const_iterator I
= F
.begin(), E
= F
.end(); I
!=E
; ++I
) {
1311 if (Loop
*L
= LInfo
->getLoopFor(I
)) {
1312 if (L
->getHeader()==I
&& L
->getParentLoop()==0)
1321 void MSILWriter::printConstantExpr(const ConstantExpr
* CE
) {
1322 const Value
*left
= 0, *right
= 0;
1323 if (CE
->getNumOperands()>=1) left
= CE
->getOperand(0);
1324 if (CE
->getNumOperands()>=2) right
= CE
->getOperand(1);
1325 // Print instruction
1326 switch (CE
->getOpcode()) {
1327 case Instruction::Trunc
:
1328 case Instruction::ZExt
:
1329 case Instruction::SExt
:
1330 case Instruction::FPTrunc
:
1331 case Instruction::FPExt
:
1332 case Instruction::UIToFP
:
1333 case Instruction::SIToFP
:
1334 case Instruction::FPToUI
:
1335 case Instruction::FPToSI
:
1336 case Instruction::PtrToInt
:
1337 case Instruction::IntToPtr
:
1338 case Instruction::BitCast
:
1339 printCastInstruction(CE
->getOpcode(),left
,CE
->getType());
1341 case Instruction::GetElementPtr
:
1342 printGepInstruction(CE
->getOperand(0),gep_type_begin(CE
),gep_type_end(CE
));
1344 case Instruction::ICmp
:
1345 printICmpInstruction(CE
->getPredicate(),left
,right
);
1347 case Instruction::FCmp
:
1348 printFCmpInstruction(CE
->getPredicate(),left
,right
);
1350 case Instruction::Select
:
1351 printSelectInstruction(CE
->getOperand(0),CE
->getOperand(1),CE
->getOperand(2));
1353 case Instruction::Add
:
1354 case Instruction::FAdd
:
1355 printBinaryInstruction("add",left
,right
);
1357 case Instruction::Sub
:
1358 case Instruction::FSub
:
1359 printBinaryInstruction("sub",left
,right
);
1361 case Instruction::Mul
:
1362 case Instruction::FMul
:
1363 printBinaryInstruction("mul",left
,right
);
1365 case Instruction::UDiv
:
1366 printBinaryInstruction("div.un",left
,right
);
1368 case Instruction::SDiv
:
1369 case Instruction::FDiv
:
1370 printBinaryInstruction("div",left
,right
);
1372 case Instruction::URem
:
1373 printBinaryInstruction("rem.un",left
,right
);
1375 case Instruction::SRem
:
1376 case Instruction::FRem
:
1377 printBinaryInstruction("rem",left
,right
);
1379 case Instruction::And
:
1380 printBinaryInstruction("and",left
,right
);
1382 case Instruction::Or
:
1383 printBinaryInstruction("or",left
,right
);
1385 case Instruction::Xor
:
1386 printBinaryInstruction("xor",left
,right
);
1388 case Instruction::Shl
:
1389 printBinaryInstruction("shl",left
,right
);
1391 case Instruction::LShr
:
1392 printBinaryInstruction("shr.un",left
,right
);
1394 case Instruction::AShr
:
1395 printBinaryInstruction("shr",left
,right
);
1398 errs() << "Expression = " << *CE
<< "\n";
1399 llvm_unreachable("Invalid constant expression");
1404 void MSILWriter::printStaticInitializerList() {
1405 // List of global variables with uninitialized fields.
1406 for (std::map
<const GlobalVariable
*,std::vector
<StaticInitializer
> >::iterator
1407 VarI
= StaticInitList
.begin(), VarE
= StaticInitList
.end(); VarI
!=VarE
;
1409 const std::vector
<StaticInitializer
>& InitList
= VarI
->second
;
1410 if (InitList
.empty()) continue;
1411 // For each uninitialized field.
1412 for (std::vector
<StaticInitializer
>::const_iterator I
= InitList
.begin(),
1413 E
= InitList
.end(); I
!=E
; ++I
) {
1414 if (const ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(I
->constant
)) {
1415 // Out << "\n// Init " << getValueName(VarI->first) << ", offset " <<
1416 // utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n";
1417 // Load variable address
1418 printValueLoad(VarI
->first
);
1421 printPtrLoad(I
->offset
);
1422 printSimpleInstruction("add");
1425 printConstantExpr(CE
);
1426 // Save result at offset
1427 std::string postfix
= getTypePostfix(CE
->getType(),true);
1428 if (*postfix
.begin()=='u') *postfix
.begin() = 'i';
1429 postfix
= "stind."+postfix
;
1430 printSimpleInstruction(postfix
.c_str());
1432 errs() << "Constant = " << *I
->constant
<< '\n';
1433 llvm_unreachable("Invalid static initializer");
1440 void MSILWriter::printFunction(const Function
& F
) {
1441 bool isSigned
= F
.paramHasAttr(0, Attribute::SExt
);
1442 Out
<< "\n.method static ";
1443 Out
<< (F
.hasLocalLinkage() ? "private " : "public ");
1444 if (F
.isVarArg()) Out
<< "vararg ";
1445 Out
<< getTypeName(F
.getReturnType(),isSigned
) <<
1446 getConvModopt(F
.getCallingConv()) << getValueName(&F
) << '\n';
1449 unsigned ArgIdx
= 1;
1450 for (Function::const_arg_iterator I
= F
.arg_begin(), E
= F
.arg_end(); I
!=E
;
1452 isSigned
= F
.paramHasAttr(ArgIdx
, Attribute::SExt
);
1453 if (I
!=F
.arg_begin()) Out
<< ", ";
1454 Out
<< getTypeName(I
->getType(),isSigned
) << getValueName(I
);
1456 Out
<< ") cil managed\n";
1459 printLocalVariables(F
);
1460 printFunctionBody(F
);
1465 void MSILWriter::printDeclarations(const TypeSymbolTable
& ST
) {
1467 std::set
<const Type
*> Printed
;
1468 for (std::set
<const Type
*>::const_iterator
1469 UI
= UsedTypes
->begin(), UE
= UsedTypes
->end(); UI
!=UE
; ++UI
) {
1470 const Type
* Ty
= *UI
;
1471 if (isa
<ArrayType
>(Ty
) || isa
<VectorType
>(Ty
) || isa
<StructType
>(Ty
))
1472 Name
= getTypeName(Ty
, false, true);
1473 // Type with no need to declare.
1475 // Print not duplicated type
1476 if (Printed
.insert(Ty
).second
) {
1477 Out
<< ".class value explicit ansi sealed '" << Name
<< "'";
1478 Out
<< " { .pack " << 1 << " .size " << TD
->getTypeAllocSize(Ty
);
1485 unsigned int MSILWriter::getBitWidth(const Type
* Ty
) {
1486 unsigned int N
= Ty
->getPrimitiveSizeInBits();
1487 assert(N
!=0 && "Invalid type in getBitWidth()");
1496 errs() << "Bits = " << N
<< '\n';
1497 llvm_unreachable("Unsupported integer width");
1499 return 0; // Not reached
1503 void MSILWriter::printStaticConstant(const Constant
* C
, uint64_t& Offset
) {
1504 uint64_t TySize
= 0;
1505 const Type
* Ty
= C
->getType();
1506 // Print zero initialized constant.
1507 if (isa
<ConstantAggregateZero
>(C
) || C
->isNullValue()) {
1508 TySize
= TD
->getTypeAllocSize(C
->getType());
1510 Out
<< "int8 (0) [" << TySize
<< "]";
1513 // Print constant initializer
1514 switch (Ty
->getTypeID()) {
1515 case Type::IntegerTyID
: {
1516 TySize
= TD
->getTypeAllocSize(Ty
);
1517 const ConstantInt
* Int
= cast
<ConstantInt
>(C
);
1518 Out
<< getPrimitiveTypeName(Ty
,true) << "(" << Int
->getSExtValue() << ")";
1521 case Type::FloatTyID
:
1522 case Type::DoubleTyID
: {
1523 TySize
= TD
->getTypeAllocSize(Ty
);
1524 const ConstantFP
* FP
= cast
<ConstantFP
>(C
);
1525 if (Ty
->getTypeID() == Type::FloatTyID
)
1527 (uint32_t)FP
->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
1530 FP
->getValueAPF().bitcastToAPInt().getZExtValue() << ')';
1533 case Type::ArrayTyID
:
1534 case Type::VectorTyID
:
1535 case Type::StructTyID
:
1536 for (unsigned I
= 0, E
= C
->getNumOperands(); I
<E
; I
++) {
1537 if (I
!=0) Out
<< ",\n";
1538 printStaticConstant(C
->getOperand(I
),Offset
);
1541 case Type::PointerTyID
:
1542 TySize
= TD
->getTypeAllocSize(C
->getType());
1543 // Initialize with global variable address
1544 if (const GlobalVariable
*G
= dyn_cast
<GlobalVariable
>(C
)) {
1545 std::string name
= getValueName(G
);
1546 Out
<< "&(" << name
.insert(name
.length()-1,"$data") << ")";
1548 // Dynamic initialization
1549 if (!isa
<ConstantPointerNull
>(C
) && !C
->isNullValue())
1550 InitListPtr
->push_back(StaticInitializer(C
,Offset
));
1551 // Null pointer initialization
1552 if (TySize
==4) Out
<< "int32 (0)";
1553 else if (TySize
==8) Out
<< "int64 (0)";
1554 else llvm_unreachable("Invalid pointer size");
1558 errs() << "TypeID = " << Ty
->getTypeID() << '\n';
1559 llvm_unreachable("Invalid type in printStaticConstant()");
1566 void MSILWriter::printStaticInitializer(const Constant
* C
,
1567 const std::string
& Name
) {
1568 switch (C
->getType()->getTypeID()) {
1569 case Type::IntegerTyID
:
1570 case Type::FloatTyID
:
1571 case Type::DoubleTyID
:
1572 Out
<< getPrimitiveTypeName(C
->getType(), false);
1574 case Type::ArrayTyID
:
1575 case Type::VectorTyID
:
1576 case Type::StructTyID
:
1577 case Type::PointerTyID
:
1578 Out
<< getTypeName(C
->getType());
1581 errs() << "Type = " << *C
<< "\n";
1582 llvm_unreachable("Invalid constant type");
1584 // Print initializer
1585 std::string label
= Name
;
1586 label
.insert(label
.length()-1,"$data");
1587 Out
<< Name
<< " at " << label
<< '\n';
1588 Out
<< ".data " << label
<< " = {\n";
1589 uint64_t offset
= 0;
1590 printStaticConstant(C
,offset
);
1595 void MSILWriter::printVariableDefinition(const GlobalVariable
* G
) {
1596 const Constant
* C
= G
->getInitializer();
1597 if (C
->isNullValue() || isa
<ConstantAggregateZero
>(C
) || isa
<UndefValue
>(C
))
1600 InitListPtr
= &StaticInitList
[G
];
1601 printStaticInitializer(C
,getValueName(G
));
1605 void MSILWriter::printGlobalVariables() {
1606 if (ModulePtr
->global_empty()) return;
1607 Module::global_iterator I
,E
;
1608 for (I
= ModulePtr
->global_begin(), E
= ModulePtr
->global_end(); I
!=E
; ++I
) {
1609 // Variable definition
1610 Out
<< ".field static " << (I
->isDeclaration() ? "public " :
1612 if (I
->isDeclaration()) {
1613 Out
<< getTypeName(I
->getType()) << getValueName(&*I
) << "\n\n";
1615 printVariableDefinition(&*I
);
1620 const char* MSILWriter::getLibraryName(const Function
* F
) {
1621 return getLibraryForSymbol(F
->getName(), true, F
->getCallingConv());
1625 const char* MSILWriter::getLibraryName(const GlobalVariable
* GV
) {
1626 return getLibraryForSymbol(Mang
->getMangledName(GV
), false, CallingConv::C
);
1630 const char* MSILWriter::getLibraryForSymbol(const StringRef
&Name
,
1632 CallingConv::ID CallingConv
) {
1633 // TODO: Read *.def file with function and libraries definitions.
1634 return "MSVCRT.DLL";
1638 void MSILWriter::printExternals() {
1639 Module::const_iterator I
,E
;
1641 for (I
=ModulePtr
->begin(),E
=ModulePtr
->end(); I
!=E
; ++I
) {
1643 if (I
->isIntrinsic()) continue;
1644 if (I
->isDeclaration()) {
1645 const Function
* F
= I
;
1646 std::string Name
= getConvModopt(F
->getCallingConv())+getValueName(F
);
1648 getCallSignature(cast
<FunctionType
>(F
->getFunctionType()), NULL
, Name
);
1649 Out
<< ".method static hidebysig pinvokeimpl(\""
1650 << getLibraryName(F
) << "\")\n\t" << Sig
<< " preservesig {}\n\n";
1653 // External variables and static initialization.
1655 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1656 " native int LoadLibrary(string) preservesig {}\n"
1657 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1658 " native int GetProcAddress(native int, string) preservesig {}\n";
1660 ".method private static void* $MSIL_Import(string lib,string sym)\n"
1663 "\tcall\tnative int LoadLibrary(string)\n"
1665 "\tcall\tnative int GetProcAddress(native int,string)\n"
1668 "\tldstr\t\"Can no import variable\"\n"
1669 "\tnewobj\tinstance void [mscorlib]System.Exception::.ctor(string)\n"
1674 ".method static private void $MSIL_Init() managed cil\n{\n";
1675 printStaticInitializerList();
1676 // Foreach global variable.
1677 for (Module::global_iterator I
= ModulePtr
->global_begin(),
1678 E
= ModulePtr
->global_end(); I
!=E
; ++I
) {
1679 if (!I
->isDeclaration() || !I
->hasDLLImportLinkage()) continue;
1680 // Use "LoadLibrary"/"GetProcAddress" to recive variable address.
1681 std::string Tmp
= getTypeName(I
->getType())+getValueName(&*I
);
1682 printSimpleInstruction("ldsflda",Tmp
.c_str());
1683 Out
<< "\tldstr\t\"" << getLibraryName(&*I
) << "\"\n";
1684 Out
<< "\tldstr\t\"" << Mang
->getMangledName(&*I
) << "\"\n";
1685 printSimpleInstruction("call","void* $MSIL_Import(string,string)");
1686 printIndirectSave(I
->getType());
1688 printSimpleInstruction("ret");
1693 //===----------------------------------------------------------------------===//
1694 // External Interface declaration
1695 //===----------------------------------------------------------------------===//
1697 bool MSILTarget::addPassesToEmitWholeFile(PassManager
&PM
,
1698 formatted_raw_ostream
&o
,
1699 CodeGenFileType FileType
,
1700 CodeGenOpt::Level OptLevel
)
1702 if (FileType
!= TargetMachine::AssemblyFile
) return true;
1703 MSILWriter
* Writer
= new MSILWriter(o
);
1704 PM
.add(createGCLoweringPass());
1705 PM
.add(createLowerAllocationsPass(true));
1706 // FIXME: Handle switch trougth native IL instruction "switch"
1707 PM
.add(createLowerSwitchPass());
1708 PM
.add(createCFGSimplificationPass());
1709 PM
.add(new MSILModule(Writer
->UsedTypes
,Writer
->TD
));
1711 PM
.add(createGCInfoDeleter());