llvm.org GIT mirror llvm / f13090c
Update MSIL BE. This patch fixes most weird glitches outlined in README.txt. Patch by Roman Samoilov! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36890 91177308-0d34-0410-b5e6-96231b3b80d8 Anton Korobeynikov 13 years ago
3 changed file(s) with 451 addition(s) and 150 deletion(s). Raw diff Collapse all Expand all
None //===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===//
1 //
2 // The LLVM Compiler Infrastructure
1 // The LLVM Compiler Infrastructure
32 //
43 // This file was developed by Roman Samoilov and is distributed under
54 // the University of Illinois Open Source License. See LICENSE.TXT for details.
2019 #include "llvm/Analysis/ConstantsScanner.h"
2120 #include "llvm/Support/CallSite.h"
2221 #include "llvm/Support/InstVisitor.h"
22 #include "llvm/Support/MathExtras.h"
2323 #include "llvm/Transforms/Scalar.h"
2424 #include "llvm/ADT/StringExtras.h"
2525
9292
9393 bool MSILWriter::doInitialization(Module &M) {
9494 ModulePtr = &M;
95 Mang = new Mangler(M);
95 Mang = new Mangler(M);
9696 Out << ".assembly extern mscorlib {}\n";
9797 Out << ".assembly MSIL {}\n\n";
9898 Out << "// External\n";
101101 printDeclarations(M.getTypeSymbolTable());
102102 Out << "// Definitions\n";
103103 printGlobalVariables();
104 Out << "// Startup code\n";
105 printModuleStartup();
104106 return false;
105107 }
106108
110112 return false;
111113 }
112114
115
116 void MSILWriter::printModuleStartup() {
117 Out <<
118 ".method static public int32 $MSIL_Startup() {\n"
119 "\t.entrypoint\n"
120 "\t.locals (native int i)\n"
121 "\t.locals (native int argc)\n"
122 "\t.locals (native int ptr)\n"
123 "\t.locals (void* argv)\n"
124 "\t.locals (string[] args)\n"
125 "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n"
126 "\tdup\n"
127 "\tstloc\targs\n"
128 "\tldlen\n"
129 "\tconv.i4\n"
130 "\tdup\n"
131 "\tstloc\targc\n";
132 printPtrLoad(TD->getPointerSize());
133 Out <<
134 "\tmul\n"
135 "\tlocalloc\n"
136 "\tstloc\targv\n"
137 "\tldc.i4.0\n"
138 "\tstloc\ti\n"
139 "L_01:\n"
140 "\tldloc\ti\n"
141 "\tldloc\targc\n"
142 "\tceq\n"
143 "\tbrtrue\tL_02\n"
144 "\tldloc\targs\n"
145 "\tldloc\ti\n"
146 "\tldelem.ref\n"
147 "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::"
148 "StringToHGlobalAnsi(string)\n"
149 "\tstloc\tptr\n"
150 "\tldloc\targv\n"
151 "\tldloc\ti\n";
152 printPtrLoad(TD->getPointerSize());
153 Out <<
154 "\tmul\n"
155 "\tadd\n"
156 "\tldloc\tptr\n"
157 "\tstind.i\n"
158 "\tldloc\ti\n"
159 "\tldc.i4.1\n"
160 "\tadd\n"
161 "\tstloc\ti\n"
162 "\tbr\tL_01\n"
163 "L_02:\n"
164 "\tcall void $MSIL_Init()\n";
165
166 // Call user 'main' function.
167 const Function* F = ModulePtr->getFunction("main");
168 if (!F || F->isDeclaration()) {
169 Out << "\tldc.i4.0\n\tret\n}\n";
170 return;
171 }
172 bool BadSig = true;;
173 std::string Args("");
174 Function::const_arg_iterator Arg1,Arg2;
175
176 switch (F->arg_size()) {
177 case 0:
178 BadSig = false;
179 break;
180 case 1:
181 Arg1 = F->arg_begin();
182 if (Arg1->getType()->isInteger()) {
183 Out << "\tldloc\targc\n";
184 Args = getTypeName(Arg1->getType());
185 BadSig = false;
186 }
187 break;
188 case 2:
189 Arg1 = Arg2 = F->arg_begin(); ++Arg2;
190 if (Arg1->getType()->isInteger() &&
191 Arg2->getType()->getTypeID() == Type::PointerTyID) {
192 Out << "\tldloc\targc\n\tldloc\targv\n";
193 Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType());
194 BadSig = false;
195 }
196 break;
197 default:
198 BadSig = true;
199 }
200
201 bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID);
202 if (BadSig || !F->getReturnType()->isInteger() && !RetVoid) {
203 Out << "\tldc.i4.0\n";
204 } else {
205 Out << "\tcall\t" << getTypeName(F->getReturnType()) <<
206 getConvModopt(F->getCallingConv()) << "main(" << Args << ")\n";
207 if (RetVoid)
208 Out << "\tldc.i4.0\n";
209 else
210 Out << "\tconv.i4\n";
211 }
212 Out << "\tret\n}\n";
213 }
113214
114215 bool MSILWriter::isZeroValue(const Value* V) {
115216 if (const Constant *C = dyn_cast(V))
176277 if (ElemTy->getTypeID()!=TyID) break;
177278 Tmp += ",";
178279 }
179 return getTypeName(ElemTy)+"["+Tmp+"]";
280 return getTypeName(ElemTy, false, true)+"["+Tmp+"]";
180281 }
181282
182283
203304 }
204305
205306
206 std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned) {
307 std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned,
308 bool isNested) {
207309 if (Ty->isPrimitiveType() || Ty->isInteger())
208310 return getPrimitiveTypeName(Ty,isSigned);
209311 // FIXME: "OpaqueType" support
211313 case Type::PointerTyID:
212314 return "void* ";
213315 case Type::StructTyID:
316 if (isNested)
317 return ModulePtr->getTypeName(Ty);
214318 return "valuetype '"+ModulePtr->getTypeName(Ty)+"' ";
215319 case Type::ArrayTyID:
320 if (isNested)
321 return getArrayTypeName(Ty->getTypeID(),Ty);
216322 return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
217323 case Type::VectorTyID:
324 if (isNested)
325 return getArrayTypeName(Ty->getTypeID(),Ty);
218326 return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' ";
219327 default:
220328 cerr << "Type = " << *Ty << '\n';
266374 }
267375
268376
377 void MSILWriter::printConvToPtr() {
378 switch (ModulePtr->getPointerSize()) {
379 case Module::Pointer32:
380 printSimpleInstruction("conv.u4");
381 break;
382 case Module::Pointer64:
383 printSimpleInstruction("conv.u8");
384 break;
385 default:
386 assert(0 && "Module use not supporting pointer size");
387 }
388 }
389
390
269391 void MSILWriter::printPtrLoad(uint64_t N) {
270392 switch (ModulePtr->getPointerSize()) {
271393 case Module::Pointer32:
272394 printSimpleInstruction("ldc.i4",utostr(N).c_str());
273395 // FIXME: Need overflow test?
274 assert(N<0xFFFFFFFF && "32-bit pointer overflowed");
396 if (!isUInt32(N)) {
397 cerr << "Value = " << utostr(N) << '\n';
398 assert(0 && "32-bit pointer overflowed");
399 }
275400 break;
276401 case Module::Pointer64:
277402 printSimpleInstruction("ldc.i8",utostr(N).c_str());
279404 default:
280405 assert(0 && "Module use not supporting pointer size");
281406 }
407 }
408
409
410 void MSILWriter::printValuePtrLoad(const Value* V) {
411 printValueLoad(V);
412 printConvToPtr();
282413 }
283414
284415
290421 Out << CInt->getSExtValue();
291422 else
292423 Out << CInt->getZExtValue();
293 } else if (const ConstantFP* CFp = dyn_cast(C)) {
424 } else if (const ConstantFP* FP = dyn_cast(C)) {
294425 // Float constant
295 Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t' <<
296 CFp->getValue();
426 uint64_t X;
427 unsigned Size;
428 if (FP->getType()->getTypeID()==Type::FloatTyID) {
429 X = FloatToBits(FP->getValue());
430 Size = 4;
431 } else {
432 X = DoubleToBits(FP->getValue());
433 Size = 8;
434 }
435 Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')';
436 } else if (isa(C)) {
437 // Undefined constant value = NULL.
438 printPtrLoad(0);
297439 } else {
298440 cerr << "Constant = " << *C << '\n';
299441 assert(0 && "Invalid constant value");
303445
304446
305447 void MSILWriter::printValueLoad(const Value* V) {
306 switch (getValueLocation(V)) {
448 MSILWriter::ValueType Location = getValueLocation(V);
449 switch (Location) {
307450 // Global variable or function address.
308451 case GlobalVT:
309452 case InternalVT:
312455 printSimpleInstruction("ldftn",
313456 getCallSignature(F->getFunctionType(),NULL,Name).c_str());
314457 } else {
458 std::string Tmp;
315459 const Type* ElemTy = cast(V->getType())->getElementType();
316 std::string Tmp = getTypeName(ElemTy)+getValueName(V);
317 printSimpleInstruction("ldsflda",Tmp.c_str());
460 if (Location==GlobalVT && cast(V)->hasDLLImportLinkage()) {
461 Tmp = "void* "+getValueName(V);
462 printSimpleInstruction("ldsfld",Tmp.c_str());
463 } else {
464 Tmp = getTypeName(ElemTy)+getValueName(V);
465 printSimpleInstruction("ldsflda",Tmp.c_str());
466 }
318467 }
319468 break;
320469 // Function argument.
453602
454603
455604 void MSILWriter::printIndirectLoad(const Value* V) {
605 const Type* Ty = V->getType();
456606 printValueLoad(V);
457 std::string Tmp = "ldind."+getTypePostfix(V->getType(),false);
607 if (const PointerType* P = dyn_cast(Ty))
608 Ty = P->getElementType();
609 std::string Tmp = "ldind."+getTypePostfix(Ty, false);
458610 printSimpleInstruction(Tmp.c_str());
459611 }
460612
461613
462 void MSILWriter::printStoreInstruction(const Instruction* Inst) {
463 const Value* Val = Inst->getOperand(0);
464 const Value* Ptr = Inst->getOperand(1);
465 // Load destination address.
614 void MSILWriter::printIndirectSave(const Value* Ptr, const Value* Val) {
466615 printValueLoad(Ptr);
467 // Load value.
468616 printValueLoad(Val);
617 printIndirectSave(Val->getType());
618 }
619
620
621 void MSILWriter::printIndirectSave(const Type* Ty) {
469622 // Instruction need signed postfix for any type.
470 std::string postfix = getTypePostfix(Val->getType(),false);
623 std::string postfix = getTypePostfix(Ty, false);
471624 if (*postfix.begin()=='u') *postfix.begin() = 'i';
472625 postfix = "stind."+postfix;
473626 printSimpleInstruction(postfix.c_str());
511664
512665 void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I,
513666 gep_type_iterator E) {
667 unsigned Size;
514668 // Load address
515 printValueLoad(V);
669 printValuePtrLoad(V);
516670 // Calculate element offset.
517 unsigned TySize;
518 for (++I; I!=E; ++I){
519 const Type* Ty = I.getIndexedType();
520 const Value* Idx = I.getOperand();
521 // Get size of type.
522 switch (Ty->getTypeID()) {
523 case Type::IntegerTyID:
524 case Type::FloatTyID:
525 case Type::DoubleTyID:
526 case Type::PointerTyID:
527 TySize = TD->getTypeSize(Ty);
528 break;
529 case Type::StructTyID:
530 TySize = 0;
531 break;
532 case Type::ArrayTyID:
533 TySize = TD->getTypeSize(cast(Ty)->getElementType());
534 break;
535 case Type::VectorTyID:
536 TySize = TD->getTypeSize(cast(Ty)->getElementType());
537 break;
538 default:
539 cerr << "Type = " << *Ty << '\n';
540 assert(0 && "Invalid index type in printGepInstruction()");
541 }
542 // Calculate offset to structure field.
543 if (const StructType* STy = dyn_cast(Ty)) {
544 TySize = 0;
545 uint64_t FieldIdx = cast(Idx)->getZExtValue();
546 // Offset is the summ of all previous structure fields.
547 for (uint64_t F = 0; F
548 TySize += TD->getTypeSize(STy->getContainedType(unsigned(F)));
549 // Add field offset to stack top.
550 printPtrLoad(TySize);
671 for (; I!=E; ++I){
672 Size = 0;
673 const Value* IndexValue = I.getOperand();
674 if (const StructType* StrucTy = dyn_cast(*I)) {
675 uint64_t FieldIndex = cast(IndexValue)->getZExtValue();
676 // Offset is the sum of all previous structure fields.
677 for (uint64_t F = 0; F
678 Size += TD->getTypeSize(StrucTy->getContainedType((unsigned)F));
679 printPtrLoad(Size);
551680 printSimpleInstruction("add");
552681 continue;
682 } else if (const SequentialType* SeqTy = dyn_cast(*I)) {
683 Size = TD->getTypeSize(SeqTy->getElementType());
684 } else {
685 Size = TD->getTypeSize(*I);
553686 }
554687 // Add offset of current element to stack top.
555 if (!isZeroValue(Idx)) {
556 uint64_t TySize = TD->getTypeSize(I.getIndexedType());
557 // Constant optimization
558 if (const ConstantInt* CInt = dyn_cast(Idx)) {
559 printPtrLoad(CInt->getZExtValue()*TySize);
688 if (!isZeroValue(IndexValue)) {
689 // Constant optimization.
690 if (const ConstantInt* C = dyn_cast(IndexValue)) {
691 if (C->getValue().isNegative()) {
692 printPtrLoad(C->getValue().abs().getZExtValue()*Size);
693 printSimpleInstruction("sub");
694 continue;
695 } else
696 printPtrLoad(C->getZExtValue()*Size);
560697 } else {
561 printPtrLoad(TySize);
562 printValueLoad(Idx);
698 printPtrLoad(Size);
699 printValuePtrLoad(IndexValue);
563700 printSimpleInstruction("mul");
564701 }
565702 printSimpleInstruction("add");
571708 std::string MSILWriter::getCallSignature(const FunctionType* Ty,
572709 const Instruction* Inst,
573710 std::string Name) {
574 std::string Tmp = "";
711 std::string Tmp("");
575712 if (Ty->isVarArg()) Tmp += "vararg ";
576713 // Name and return type.
577714 Tmp += getTypeName(Ty->getReturnType())+Name+"(";
584721 // CLR needs to know the exact amount of parameters received by vararg
585722 // function, because caller cleans the stack.
586723 if (Ty->isVarArg() && Inst) {
587 // Origin to function arguments in "CallInst" or "InvokeInst"
724 // Origin to function arguments in "CallInst" or "InvokeInst".
588725 unsigned Org = isa(Inst) ? 3 : 1;
589726 // Print variable argument types.
590727 unsigned NumOperands = Inst->getNumOperands()-Org;
603740
604741 void MSILWriter::printFunctionCall(const Value* FnVal,
605742 const Instruction* Inst) {
606 // Get function calling convention
743 // Get function calling convention.
607744 std::string Name = "";
608745 if (const CallInst* Call = dyn_cast(Inst))
609746 Name = getConvModopt(Call->getCallingConv());
613750 cerr << "Instruction = " << Inst->getName() << '\n';
614751 assert(0 && "Need \"Invoke\" or \"Call\" instruction only");
615752 }
616
617753 if (const Function* F = dyn_cast(FnVal)) {
618 // Direct call
754 // Direct call.
619755 Name += getValueName(F);
620756 printSimpleInstruction("call",
621757 getCallSignature(F->getFunctionType(),Inst,Name).c_str());
622758 } else {
623 // Indirect function call
759 // Indirect function call.
624760 const PointerType* PTy = cast(FnVal->getType());
625761 const FunctionType* FTy = cast(PTy->getElementType());
626 // Load function address
762 // Load function address.
627763 printValueLoad(FnVal);
628764 printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str());
629765 }
630766 }
631767
632768
769 void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) {
770 std::string Name;
771 switch (Inst->getIntrinsicID()) {
772 case Intrinsic::vastart:
773 Name = getValueName(Inst->getOperand(1));
774 Name.insert(Name.length()-1,"$valist");
775 // Obtain the argument handle.
776 printSimpleInstruction("ldloca",Name.c_str());
777 printSimpleInstruction("arglist");
778 printSimpleInstruction("call",
779 "instance void [mscorlib]System.ArgIterator::.ctor"
780 "(valuetype [mscorlib]System.RuntimeArgumentHandle)");
781 // Save as pointer type "void*"
782 printValueLoad(Inst->getOperand(1));
783 printSimpleInstruction("ldloca",Name.c_str());
784 printIndirectSave(PointerType::get(IntegerType::get(8)));
785 break;
786 case Intrinsic::vaend:
787 // Close argument list handle.
788 printIndirectLoad(Inst->getOperand(1));
789 printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()");
790 break;
791 case Intrinsic::vacopy:
792 // Copy "ArgIterator" valuetype.
793 printIndirectLoad(Inst->getOperand(1));
794 printIndirectLoad(Inst->getOperand(2));
795 printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator");
796 break;
797 default:
798 cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n';
799 assert(0 && "Invalid intrinsic function");
800 }
801 }
802
803
633804 void MSILWriter::printCallInstruction(const Instruction* Inst) {
634 // Load arguments to stack
635 for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I)
636 printValueLoad(Inst->getOperand(I));
637 printFunctionCall(Inst->getOperand(0),Inst);
805 if (isa(Inst)) {
806 // Handle intrinsic function.
807 printIntrinsicCall(cast(Inst));
808 } else {
809 // Load arguments to stack and call function.
810 for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I)
811 printValueLoad(Inst->getOperand(I));
812 printFunctionCall(Inst->getOperand(0),Inst);
813 }
638814 }
639815
640816
645821 printBinaryInstruction("ceq",Left,Right);
646822 break;
647823 case ICmpInst::ICMP_NE:
648 // Emulate = not (Op1 eq Op2)
824 // Emulate = not neg (Op1 eq Op2)
649825 printBinaryInstruction("ceq",Left,Right);
826 printSimpleInstruction("neg");
650827 printSimpleInstruction("not");
651828 break;
652829 case ICmpInst::ICMP_ULE:
753930 case FCmpInst::FCMP_UNE:
754931 // X != Y
755932 printBinaryInstruction("ceq",Left,Right);
933 printSimpleInstruction("neg");
756934 printSimpleInstruction("not");
757935 break;
758936 case FCmpInst::FCMP_ONE:
817995 }
818996
819997
998 void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) {
999 printIndirectLoad(Inst->getOperand(0));
1000 printSimpleInstruction("call",
1001 "instance typedref [mscorlib]System.ArgIterator::GetNextArg()");
1002 printSimpleInstruction("refanyval","void*");
1003 std::string Name = "ldind."+getTypePostfix(PointerType::get(IntegerType::get(8)),false);
1004 printSimpleInstruction(Name.c_str());
1005 }
1006
1007
1008 void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) {
1009 uint64_t Size = TD->getTypeSize(Inst->getAllocatedType());
1010 // Constant optimization.
1011 if (const ConstantInt* CInt = dyn_cast(Inst->getOperand(0))) {
1012 printPtrLoad(CInt->getZExtValue()*Size);
1013 } else {
1014 printPtrLoad(Size);
1015 printValueLoad(Inst->getOperand(0));
1016 printSimpleInstruction("mul");
1017 }
1018 printSimpleInstruction("localloc");
1019 }
1020
1021
8201022 void MSILWriter::printInstruction(const Instruction* Inst) {
8211023 const Value *Left = 0, *Right = 0;
8221024 if (Inst->getNumOperands()>=1) Left = Inst->getOperand(0);
8231025 if (Inst->getNumOperands()>=2) Right = Inst->getOperand(1);
8241026 // Print instruction
825 // FIXME: "ShuffleVector","ExtractElement","InsertElement","VAArg" support.
1027 // FIXME: "ShuffleVector","ExtractElement","InsertElement" support.
8261028 switch (Inst->getOpcode()) {
8271029 // Terminator
8281030 case Instruction::Ret:
8771079 printBinaryInstruction("xor",Left,Right);
8781080 break;
8791081 case Instruction::Shl:
880 printBinaryInstruction("shl",Left,Right);
1082 printValueLoad(Left);
1083 printValueLoad(Right);
1084 printSimpleInstruction("conv.i4");
1085 printSimpleInstruction("shl");
8811086 break;
8821087 case Instruction::LShr:
883 printBinaryInstruction("shr.un",Left,Right);
1088 printValueLoad(Left);
1089 printValueLoad(Right);
1090 printSimpleInstruction("conv.i4");
1091 printSimpleInstruction("shr.un");
8841092 break;
8851093 case Instruction::AShr:
886 printBinaryInstruction("shr",Left,Right);
1094 printValueLoad(Left);
1095 printValueLoad(Right);
1096 printSimpleInstruction("conv.i4");
1097 printSimpleInstruction("shr");
8871098 break;
8881099 case Instruction::Select:
8891100 printSelectInstruction(Inst->getOperand(0),Inst->getOperand(1),Inst->getOperand(2));
8921103 printIndirectLoad(Inst->getOperand(0));
8931104 break;
8941105 case Instruction::Store:
895 printStoreInstruction(Inst);
1106 printIndirectSave(Inst->getOperand(1), Inst->getOperand(0));
8961107 break;
8971108 case Instruction::Trunc:
8981109 case Instruction::ZExt:
9191130 case Instruction::Invoke:
9201131 printInvokeInstruction(cast(Inst));
9211132 break;
922 case Instruction::Unwind: {
923 std::string Class = "instance void [mscorlib]System.Exception::.ctor()";
924 printSimpleInstruction("newobj",Class.c_str());
1133 case Instruction::Unwind:
1134 printSimpleInstruction("newobj",
1135 "instance void [mscorlib]System.Exception::.ctor()");
9251136 printSimpleInstruction("throw");
9261137 break;
927 }
9281138 case Instruction::Switch:
9291139 printSwitchInstruction(cast(Inst));
9301140 break;
9311141 case Instruction::Alloca:
932 printValueLoad(Inst->getOperand(0));
933 printSimpleInstruction("localloc");
1142 printAllocaInstruction(cast(Inst));
9341143 break;
9351144 case Instruction::Malloc:
9361145 assert(0 && "LowerAllocationsPass used");
9391148 assert(0 && "LowerAllocationsPass used");
9401149 break;
9411150 case Instruction::Unreachable:
942 printSimpleInstruction("ldnull");
1151 printSimpleInstruction("ldstr", "\"Unreachable instruction\"");
1152 printSimpleInstruction("newobj",
1153 "instance void [mscorlib]System.Exception::.ctor(string)");
9431154 printSimpleInstruction("throw");
1155 break;
1156 case Instruction::VAArg:
1157 printVAArgInstruction(cast(Inst));
9441158 break;
9451159 default:
9461160 cerr << "Instruction = " << Inst->getName() << '\n';
9871201 void MSILWriter::printLocalVariables(const Function& F) {
9881202 std::string Name;
9891203 const Type* Ty = NULL;
990 // Find variables
1204 std::set Printed;
1205 const Value* VaList = NULL;
1206 unsigned StackDepth = 8;
1207 // Find local variables
9911208 for (const_inst_iterator I = inst_begin(&F), E = inst_end(&F); I!=E; ++I) {
1209 if (I->getOpcode()==Instruction::Call ||
1210 I->getOpcode()==Instruction::Invoke) {
1211 // Test stack depth.
1212 if (StackDepthgetNumOperands())
1213 StackDepth = I->getNumOperands();
1214 }
9921215 const AllocaInst* AI = dyn_cast(&*I);
9931216 if (AI && !isa(AI)) {
1217 // Local variable allocation.
9941218 Ty = PointerType::get(AI->getAllocatedType());
9951219 Name = getValueName(AI);
1220 Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
9961221 } else if (I->getType()!=Type::VoidTy) {
1222 // Operation result.
9971223 Ty = I->getType();
9981224 Name = getValueName(&*I);
999 } else continue;
1000 Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
1001 }
1225 Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n";
1226 }
1227 // Test on 'va_list' variable
1228 bool isVaList = false;
1229 if (const VAArgInst* VaInst = dyn_cast(&*I)) {
1230 // "va_list" as "va_arg" instruction operand.
1231 isVaList = true;
1232 VaList = VaInst->getOperand(0);
1233 } else if (const IntrinsicInst* Inst = dyn_cast(&*I)) {
1234 // "va_list" as intrinsic function operand.
1235 switch (Inst->getIntrinsicID()) {
1236 case Intrinsic::vastart:
1237 case Intrinsic::vaend:
1238 case Intrinsic::vacopy:
1239 isVaList = true;
1240 VaList = Inst->getOperand(1);
1241 break;
1242 default:
1243 isVaList = false;
1244 }
1245 }
1246 // Print "va_list" variable.
1247 if (isVaList && Printed.insert(VaList).second) {
1248 Name = getValueName(VaList);
1249 Name.insert(Name.length()-1,"$valist");
1250 Out << "\t.locals (valuetype [mscorlib]System.ArgIterator "
1251 << Name << ")\n";
1252 }
1253 }
1254 printSimpleInstruction(".maxstack",utostr(StackDepth*2).c_str());
10021255 }
10031256
10041257
11521405 Out << ") cil managed\n";
11531406 // Body
11541407 Out << "{\n";
1155 // FIXME: Convert "string[]" to "argc,argv"
1156 if (F.getName()=="main") {
1157 printSimpleInstruction(".entrypoint");
1158 printLocalVariables(F);
1159 printStaticInitializerList();
1160 } else {
1161 printLocalVariables(F);
1162 }
1408 printLocalVariables(F);
11631409 printFunctionBody(F);
11641410 Out << "}\n";
11651411 }
11681414 void MSILWriter::printDeclarations(const TypeSymbolTable& ST) {
11691415 std::string Name;
11701416 std::set Printed;
1171 //cerr << "UsedTypes = " << UsedTypes << '\n';
11721417 for (std::set::const_iterator
11731418 UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) {
11741419 const Type* Ty = *UI;
1175 if (isa(Ty))
1176 Name = getArrayTypeName(Ty->getTypeID(),Ty);
1177 else if (isa(Ty))
1178 Name = getArrayTypeName(Ty->getTypeID(),Ty);
1179 else if (isa(Ty))
1180 Name = ModulePtr->getTypeName(Ty);
1420 if (isa(Ty) || isa(Ty) || isa(Ty))
1421 Name = getTypeName(Ty, false, true);
11811422 // Type with no need to declare.
11821423 else continue;
11831424 // Print not duplicated type
12271468 case Type::FloatTyID:
12281469 case Type::DoubleTyID: {
12291470 TySize = TD->getTypeSize(Ty);
1230 const ConstantFP* CFp = cast(C);
1231 Out << getPrimitiveTypeName(Ty,true) << "(" << CFp->getValue() << ")";
1471 const ConstantFP* FP = cast(C);
1472 if (Ty->getTypeID() == Type::FloatTyID)
1473 Out << "int32 (" << FloatToBits(FP->getValue()) << ')';
1474 else
1475 Out << "int64 (" << DoubleToBits(FP->getValue()) << ')';
12321476 break;
12331477 }
12341478 case Type::ArrayTyID:
12701514 case Type::IntegerTyID:
12711515 case Type::FloatTyID:
12721516 case Type::DoubleTyID:
1273 Out << getPrimitiveTypeName(C->getType(),true);
1517 Out << getPrimitiveTypeName(C->getType(), false);
12741518 break;
12751519 case Type::ArrayTyID:
12761520 case Type::VectorTyID:
13081552 Module::global_iterator I,E;
13091553 for (I = ModulePtr->global_begin(), E = ModulePtr->global_end(); I!=E; ++I) {
13101554 // Variable definition
1311 if (I->isDeclaration()) continue;
1312 Out << ".field static " << (I->hasExternalLinkage() ? "public " :
1313 "private ");
1314 printVariableDefinition(&*I);
1315 }
1555 Out << ".field static " << (I->isDeclaration() ? "public " :
1556 "private ");
1557 if (I->isDeclaration()) {
1558 Out << getTypeName(I->getType()) << getValueName(&*I) << "\n\n";
1559 } else
1560 printVariableDefinition(&*I);
1561 }
1562 }
1563
1564
1565 const char* MSILWriter::getLibraryName(const Function* F) {
1566 return getLibraryForSymbol(F->getName().c_str(), true, F->getCallingConv());
1567 }
1568
1569
1570 const char* MSILWriter::getLibraryName(const GlobalVariable* GV) {
1571 return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0);
1572 }
1573
1574
1575 const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction,
1576 unsigned CallingConv) {
1577 // TODO: Read *.def file with function and libraries definitions.
1578 return "MSVCRT.DLL";
13161579 }
13171580
13181581
13191582 void MSILWriter::printExternals() {
13201583 Module::const_iterator I,E;
1584 // Functions.
13211585 for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) {
13221586 // Skip intrisics
13231587 if (I->getIntrinsicID()) continue;
1324 // FIXME: Treat as standard library function
13251588 if (I->isDeclaration()) {
1326 const Function* F = &*I;
1327 const FunctionType* FTy = F->getFunctionType();
1589 const Function* F = I;
13281590 std::string Name = getConvModopt(F->getCallingConv())+getValueName(F);
1329 std::string Sig = getCallSignature(FTy,NULL,Name);
1330 Out << ".method static hidebysig pinvokeimpl(\"msvcrt.dll\" cdecl)\n\t"
1331 << Sig << " preservesig {}\n\n";
1332 }
1333 }
1334 }
1591 std::string Sig =
1592 getCallSignature(cast(F->getFunctionType()), NULL, Name);
1593 Out << ".method static hidebysig pinvokeimpl(\""
1594 << getLibraryName(F) << "\")\n\t" << Sig << " preservesig {}\n\n";
1595 }
1596 }
1597 // External variables and static initialization.
1598 Out <<
1599 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1600 " native int LoadLibrary(string) preservesig {}\n"
1601 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)"
1602 " native int GetProcAddress(native int, string) preservesig {}\n";
1603 Out <<
1604 ".method private static void* $MSIL_Import(string lib,string sym)\n"
1605 " managed cil\n{\n"
1606 "\tldarg\tlib\n"
1607 "\tcall\tnative int LoadLibrary(string)\n"
1608 "\tldarg\tsym\n"
1609 "\tcall\tnative int GetProcAddress(native int,string)\n"
1610 "\tdup\n"
1611 "\tbrtrue\tL_01\n"
1612 "\tldstr\t\"Can no import variable\"\n"
1613 "\tnewobj\tinstance void [mscorlib]System.Exception::.ctor(string)\n"
1614 "\tthrow\n"
1615 "L_01:\n"
1616 "\tret\n"
1617 "}\n\n"
1618 ".method static private void $MSIL_Init() managed cil\n{\n";
1619 printStaticInitializerList();
1620 // Foreach global variable.
1621 for (Module::global_iterator I = ModulePtr->global_begin(),
1622 E = ModulePtr->global_end(); I!=E; ++I) {
1623 if (!I->isDeclaration() || !I->hasDLLImportLinkage()) continue;
1624 // Use "LoadLibrary"/"GetProcAddress" to recive variable address.
1625 std::string Label = "not_null$_"+utostr(getUniqID());
1626 std::string Tmp = getTypeName(I->getType())+getValueName(&*I);
1627 printSimpleInstruction("ldsflda",Tmp.c_str());
1628 Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n";
1629 Out << "\tldstr\t\"" << Mang->getValueName(&*I) << "\"\n";
1630 printSimpleInstruction("call","void* $MSIL_Import(string,string)");
1631 printIndirectSave(I->getType());
1632 }
1633 printSimpleInstruction("ret");
1634 Out << "}\n\n";
1635 }
1636
13351637
13361638 //===----------------------------------------------------------------------===//
1337 // External Interface declaration
1639 // External Interface declaration
13381640 //===----------------------------------------------------------------------===//
13391641
13401642 bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, std::ostream &o,
1515 #include "llvm/Constants.h"
1616 #include "llvm/Module.h"
1717 #include "llvm/Instructions.h"
18 #include "llvm/IntrinsicInst.h"
1819 #include "llvm/Pass.h"
1920 #include "llvm/PassManager.h"
2021 #include "llvm/Analysis/FindUsedTypes.h"
6667 : constant(_constant), offset(_offset) {}
6768 };
6869
69 uint64_t UniqID;
70 uint64_t UniqID;
7071
7172 uint64_t getUniqID() {
7273 return ++UniqID;
118119
119120 virtual bool doFinalization(Module &M);
120121
122 void printModuleStartup();
123
121124 bool isZeroValue(const Value* V);
122125
123126 std::string getValueName(const Value* V);
136139
137140 std::string getPointerTypeName(const Type* Ty);
138141
139 std::string getTypeName(const Type* Ty, bool isSigned = false);
142 std::string getTypeName(const Type* Ty, bool isSigned = false,
143 bool isNested = false);
140144
141145 ValueType getValueLocation(const Value* V);
142146
143147 std::string getTypePostfix(const Type* Ty, bool Expand,
144148 bool isSigned = false);
145149
150 void printConvToPtr();
151
146152 void printPtrLoad(uint64_t N);
153
154 void printValuePtrLoad(const Value* V);
147155
148156 void printConstLoad(const Constant* C);
149157
169177
170178 void printIndirectLoad(const Value* V);
171179
172 void printStoreInstruction(const Instruction* Inst);
180 void printIndirectSave(const Value* Ptr, const Value* Val);
181
182 void printIndirectSave(const Type* Ty);
173183
174184 void printCastInstruction(unsigned int Op, const Value* V,
175185 const Type* Ty);
183193
184194 void printFunctionCall(const Value* FnVal, const Instruction* Inst);
185195
196 void printIntrinsicCall(const IntrinsicInst* Inst);
197
186198 void printCallInstruction(const Instruction* Inst);
187199
188200 void printICmpInstruction(unsigned Predicate, const Value* Left,
194206 void printInvokeInstruction(const InvokeInst* Inst);
195207
196208 void printSwitchInstruction(const SwitchInst* Inst);
209
210 void printVAArgInstruction(const VAArgInst* Inst);
211
212 void printAllocaInstruction(const AllocaInst* Inst);
197213
198214 void printInstruction(const Instruction* Inst);
199215
223239
224240 void printGlobalVariables();
225241
242 const char* getLibraryName(const Function* F);
243
244 const char* getLibraryName(const GlobalVariable* GV);
245
246 const char* getLibraryForSymbol(const char* Name, bool isFunction,
247 unsigned CallingConv);
248
226249 void printExternals();
227250 };
228251 }
229252
230253 #endif
254
1111
1212 //===---------------------------------------------------------------------===//
1313
14 Variable argument functions support, "VAArg" instruction and some intrinsics.
15 CLI instruction "arglist" can get argument list descriptor for current function
16 that can be passed to other functions.
17
18 va_arg = Function "System.ArgIterator::GetNextArg()"
19 va_list = Class "System.ArgIterator"
20 va_start = Instruction "arglist"
21 va_end = Do nothing
22
23 //===---------------------------------------------------------------------===//
24
25 If possible get used types inside of "MSILWriter" class, do not pass trougth
26 "MSILModule" class.
27
28 getAnalysis().getTypes()
29
30 //===---------------------------------------------------------------------===//
31
3214 "switch" instruction emulation with CLI "switch" instruction.
3315
3416 //===---------------------------------------------------------------------===//
3921 .method static hidebysig pinvokeimpl("msvcrt.dll" cdecl)
4022 void free(void*) preservesig {}
4123
42 //===---------------------------------------------------------------------===//
43
44 DLLImport'ed variables support with the help of win32 envoronment.
45
46 "LoadLibrary" - to load dynamic library into address space.
47 "GetProcAddress" - to recive variable address by name.
4824
4925
50