LLVM API Documentation
00001 //===-- MSILWriter.cpp - Library for converting LLVM code to MSIL ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This library converts LLVM code to MSIL code. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "MSILWriter.h" 00015 #include "llvm/CallingConv.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/Intrinsics.h" 00018 #include "llvm/IntrinsicInst.h" 00019 #include "llvm/TypeSymbolTable.h" 00020 #include "llvm/Analysis/ConstantsScanner.h" 00021 #include "llvm/Support/CallSite.h" 00022 #include "llvm/Support/InstVisitor.h" 00023 #include "llvm/Support/MathExtras.h" 00024 #include "llvm/Transforms/Scalar.h" 00025 #include "llvm/ADT/StringExtras.h" 00026 #include "llvm/CodeGen/Passes.h" 00027 00028 namespace { 00029 // TargetMachine for the MSIL 00030 struct VISIBILITY_HIDDEN MSILTarget : public TargetMachine { 00031 const TargetData DataLayout; // Calculates type size & alignment 00032 00033 MSILTarget(const Module &M, const std::string &FS) 00034 : DataLayout(&M) {} 00035 00036 virtual bool WantsWholeFile() const { return true; } 00037 virtual bool addPassesToEmitWholeFile(PassManager &PM, raw_ostream &Out, 00038 CodeGenFileType FileType, bool Fast); 00039 00040 // This class always works, but shouldn't be the default in most cases. 00041 static unsigned getModuleMatchQuality(const Module &M) { return 1; } 00042 00043 virtual const TargetData *getTargetData() const { return &DataLayout; } 00044 }; 00045 } 00046 00047 /// MSILTargetMachineModule - Note that this is used on hosts that 00048 /// cannot link in a library unless there are references into the 00049 /// library. In particular, it seems that it is not possible to get 00050 /// things to work on Win32 without this. Though it is unused, do not 00051 /// remove it. 00052 extern "C" int MSILTargetMachineModule; 00053 int MSILTargetMachineModule = 0; 00054 00055 static RegisterTarget<MSILTarget> X("msil", "MSIL backend"); 00056 00057 bool MSILModule::runOnModule(Module &M) { 00058 ModulePtr = &M; 00059 TD = &getAnalysis<TargetData>(); 00060 bool Changed = false; 00061 // Find named types. 00062 TypeSymbolTable& Table = M.getTypeSymbolTable(); 00063 std::set<const Type *> Types = getAnalysis<FindUsedTypes>().getTypes(); 00064 for (TypeSymbolTable::iterator I = Table.begin(), E = Table.end(); I!=E; ) { 00065 if (!isa<StructType>(I->second) && !isa<OpaqueType>(I->second)) 00066 Table.remove(I++); 00067 else { 00068 std::set<const Type *>::iterator T = Types.find(I->second); 00069 if (T==Types.end()) 00070 Table.remove(I++); 00071 else { 00072 Types.erase(T); 00073 ++I; 00074 } 00075 } 00076 } 00077 // Find unnamed types. 00078 unsigned RenameCounter = 0; 00079 for (std::set<const Type *>::const_iterator I = Types.begin(), 00080 E = Types.end(); I!=E; ++I) 00081 if (const StructType *STy = dyn_cast<StructType>(*I)) { 00082 while (ModulePtr->addTypeName("unnamed$"+utostr(RenameCounter), STy)) 00083 ++RenameCounter; 00084 Changed = true; 00085 } 00086 // Pointer for FunctionPass. 00087 UsedTypes = &getAnalysis<FindUsedTypes>().getTypes(); 00088 return Changed; 00089 } 00090 00091 char MSILModule::ID = 0; 00092 char MSILWriter::ID = 0; 00093 00094 bool MSILWriter::runOnFunction(Function &F) { 00095 if (F.isDeclaration()) return false; 00096 LInfo = &getAnalysis<LoopInfo>(); 00097 printFunction(F); 00098 return false; 00099 } 00100 00101 00102 bool MSILWriter::doInitialization(Module &M) { 00103 ModulePtr = &M; 00104 Mang = new Mangler(M); 00105 Out << ".assembly extern mscorlib {}\n"; 00106 Out << ".assembly MSIL {}\n\n"; 00107 Out << "// External\n"; 00108 printExternals(); 00109 Out << "// Declarations\n"; 00110 printDeclarations(M.getTypeSymbolTable()); 00111 Out << "// Definitions\n"; 00112 printGlobalVariables(); 00113 Out << "// Startup code\n"; 00114 printModuleStartup(); 00115 return false; 00116 } 00117 00118 00119 bool MSILWriter::doFinalization(Module &M) { 00120 delete Mang; 00121 return false; 00122 } 00123 00124 00125 void MSILWriter::printModuleStartup() { 00126 Out << 00127 ".method static public int32 $MSIL_Startup() {\n" 00128 "\t.entrypoint\n" 00129 "\t.locals (native int i)\n" 00130 "\t.locals (native int argc)\n" 00131 "\t.locals (native int ptr)\n" 00132 "\t.locals (void* argv)\n" 00133 "\t.locals (string[] args)\n" 00134 "\tcall\tstring[] [mscorlib]System.Environment::GetCommandLineArgs()\n" 00135 "\tdup\n" 00136 "\tstloc\targs\n" 00137 "\tldlen\n" 00138 "\tconv.i4\n" 00139 "\tdup\n" 00140 "\tstloc\targc\n"; 00141 printPtrLoad(TD->getPointerSize()); 00142 Out << 00143 "\tmul\n" 00144 "\tlocalloc\n" 00145 "\tstloc\targv\n" 00146 "\tldc.i4.0\n" 00147 "\tstloc\ti\n" 00148 "L_01:\n" 00149 "\tldloc\ti\n" 00150 "\tldloc\targc\n" 00151 "\tceq\n" 00152 "\tbrtrue\tL_02\n" 00153 "\tldloc\targs\n" 00154 "\tldloc\ti\n" 00155 "\tldelem.ref\n" 00156 "\tcall\tnative int [mscorlib]System.Runtime.InteropServices.Marshal::" 00157 "StringToHGlobalAnsi(string)\n" 00158 "\tstloc\tptr\n" 00159 "\tldloc\targv\n" 00160 "\tldloc\ti\n"; 00161 printPtrLoad(TD->getPointerSize()); 00162 Out << 00163 "\tmul\n" 00164 "\tadd\n" 00165 "\tldloc\tptr\n" 00166 "\tstind.i\n" 00167 "\tldloc\ti\n" 00168 "\tldc.i4.1\n" 00169 "\tadd\n" 00170 "\tstloc\ti\n" 00171 "\tbr\tL_01\n" 00172 "L_02:\n" 00173 "\tcall void $MSIL_Init()\n"; 00174 00175 // Call user 'main' function. 00176 const Function* F = ModulePtr->getFunction("main"); 00177 if (!F || F->isDeclaration()) { 00178 Out << "\tldc.i4.0\n\tret\n}\n"; 00179 return; 00180 } 00181 bool BadSig = true;; 00182 std::string Args(""); 00183 Function::const_arg_iterator Arg1,Arg2; 00184 00185 switch (F->arg_size()) { 00186 case 0: 00187 BadSig = false; 00188 break; 00189 case 1: 00190 Arg1 = F->arg_begin(); 00191 if (Arg1->getType()->isInteger()) { 00192 Out << "\tldloc\targc\n"; 00193 Args = getTypeName(Arg1->getType()); 00194 BadSig = false; 00195 } 00196 break; 00197 case 2: 00198 Arg1 = Arg2 = F->arg_begin(); ++Arg2; 00199 if (Arg1->getType()->isInteger() && 00200 Arg2->getType()->getTypeID() == Type::PointerTyID) { 00201 Out << "\tldloc\targc\n\tldloc\targv\n"; 00202 Args = getTypeName(Arg1->getType())+","+getTypeName(Arg2->getType()); 00203 BadSig = false; 00204 } 00205 break; 00206 default: 00207 BadSig = true; 00208 } 00209 00210 bool RetVoid = (F->getReturnType()->getTypeID() == Type::VoidTyID); 00211 if (BadSig || (!F->getReturnType()->isInteger() && !RetVoid)) { 00212 Out << "\tldc.i4.0\n"; 00213 } else { 00214 Out << "\tcall\t" << getTypeName(F->getReturnType()) << 00215 getConvModopt(F->getCallingConv()) << "main(" << Args << ")\n"; 00216 if (RetVoid) 00217 Out << "\tldc.i4.0\n"; 00218 else 00219 Out << "\tconv.i4\n"; 00220 } 00221 Out << "\tret\n}\n"; 00222 } 00223 00224 bool MSILWriter::isZeroValue(const Value* V) { 00225 if (const Constant *C = dyn_cast<Constant>(V)) 00226 return C->isNullValue(); 00227 return false; 00228 } 00229 00230 00231 std::string MSILWriter::getValueName(const Value* V) { 00232 // Name into the quotes allow control and space characters. 00233 return "'"+Mang->getValueName(V)+"'"; 00234 } 00235 00236 00237 std::string MSILWriter::getLabelName(const std::string& Name) { 00238 if (Name.find('.')!=std::string::npos) { 00239 std::string Tmp(Name); 00240 // Replace unaccepable characters in the label name. 00241 for (std::string::iterator I = Tmp.begin(), E = Tmp.end(); I!=E; ++I) 00242 if (*I=='.') *I = '@'; 00243 return Tmp; 00244 } 00245 return Name; 00246 } 00247 00248 00249 std::string MSILWriter::getLabelName(const Value* V) { 00250 return getLabelName(Mang->getValueName(V)); 00251 } 00252 00253 00254 std::string MSILWriter::getConvModopt(unsigned CallingConvID) { 00255 switch (CallingConvID) { 00256 case CallingConv::C: 00257 case CallingConv::Cold: 00258 case CallingConv::Fast: 00259 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) "; 00260 case CallingConv::X86_FastCall: 00261 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvFastcall) "; 00262 case CallingConv::X86_StdCall: 00263 return "modopt([mscorlib]System.Runtime.CompilerServices.CallConvStdcall) "; 00264 default: 00265 cerr << "CallingConvID = " << CallingConvID << '\n'; 00266 assert(0 && "Unsupported calling convention"); 00267 } 00268 return ""; // Not reached 00269 } 00270 00271 00272 std::string MSILWriter::getArrayTypeName(Type::TypeID TyID, const Type* Ty) { 00273 std::string Tmp = ""; 00274 const Type* ElemTy = Ty; 00275 assert(Ty->getTypeID()==TyID && "Invalid type passed"); 00276 // Walk trought array element types. 00277 for (;;) { 00278 // Multidimensional array. 00279 if (ElemTy->getTypeID()==TyID) { 00280 if (const ArrayType* ATy = dyn_cast<ArrayType>(ElemTy)) 00281 Tmp += utostr(ATy->getNumElements()); 00282 else if (const VectorType* VTy = dyn_cast<VectorType>(ElemTy)) 00283 Tmp += utostr(VTy->getNumElements()); 00284 ElemTy = cast<SequentialType>(ElemTy)->getElementType(); 00285 } 00286 // Base element type found. 00287 if (ElemTy->getTypeID()!=TyID) break; 00288 Tmp += ","; 00289 } 00290 return getTypeName(ElemTy, false, true)+"["+Tmp+"]"; 00291 } 00292 00293 00294 std::string MSILWriter::getPrimitiveTypeName(const Type* Ty, bool isSigned) { 00295 unsigned NumBits = 0; 00296 switch (Ty->getTypeID()) { 00297 case Type::VoidTyID: 00298 return "void "; 00299 case Type::IntegerTyID: 00300 NumBits = getBitWidth(Ty); 00301 if(NumBits==1) 00302 return "bool "; 00303 if (!isSigned) 00304 return "unsigned int"+utostr(NumBits)+" "; 00305 return "int"+utostr(NumBits)+" "; 00306 case Type::FloatTyID: 00307 return "float32 "; 00308 case Type::DoubleTyID: 00309 return "float64 "; 00310 default: 00311 cerr << "Type = " << *Ty << '\n'; 00312 assert(0 && "Invalid primitive type"); 00313 } 00314 return ""; // Not reached 00315 } 00316 00317 00318 std::string MSILWriter::getTypeName(const Type* Ty, bool isSigned, 00319 bool isNested) { 00320 if (Ty->isPrimitiveType() || Ty->isInteger()) 00321 return getPrimitiveTypeName(Ty,isSigned); 00322 // FIXME: "OpaqueType" support 00323 switch (Ty->getTypeID()) { 00324 case Type::PointerTyID: 00325 return "void* "; 00326 case Type::StructTyID: 00327 if (isNested) 00328 return ModulePtr->getTypeName(Ty); 00329 return "valuetype '"+ModulePtr->getTypeName(Ty)+"' "; 00330 case Type::ArrayTyID: 00331 if (isNested) 00332 return getArrayTypeName(Ty->getTypeID(),Ty); 00333 return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' "; 00334 case Type::VectorTyID: 00335 if (isNested) 00336 return getArrayTypeName(Ty->getTypeID(),Ty); 00337 return "valuetype '"+getArrayTypeName(Ty->getTypeID(),Ty)+"' "; 00338 default: 00339 cerr << "Type = " << *Ty << '\n'; 00340 assert(0 && "Invalid type in getTypeName()"); 00341 } 00342 return ""; // Not reached 00343 } 00344 00345 00346 MSILWriter::ValueType MSILWriter::getValueLocation(const Value* V) { 00347 // Function argument 00348 if (isa<Argument>(V)) 00349 return ArgumentVT; 00350 // Function 00351 else if (const Function* F = dyn_cast<Function>(V)) 00352 return F->hasLocalLinkage() ? InternalVT : GlobalVT; 00353 // Variable 00354 else if (const GlobalVariable* G = dyn_cast<GlobalVariable>(V)) 00355 return G->hasLocalLinkage() ? InternalVT : GlobalVT; 00356 // Constant 00357 else if (isa<Constant>(V)) 00358 return isa<ConstantExpr>(V) ? ConstExprVT : ConstVT; 00359 // Local variable 00360 return LocalVT; 00361 } 00362 00363 00364 std::string MSILWriter::getTypePostfix(const Type* Ty, bool Expand, 00365 bool isSigned) { 00366 unsigned NumBits = 0; 00367 switch (Ty->getTypeID()) { 00368 // Integer constant, expanding for stack operations. 00369 case Type::IntegerTyID: 00370 NumBits = getBitWidth(Ty); 00371 // Expand integer value to "int32" or "int64". 00372 if (Expand) return (NumBits<=32 ? "i4" : "i8"); 00373 if (NumBits==1) return "i1"; 00374 return (isSigned ? "i" : "u")+utostr(NumBits/8); 00375 // Float constant. 00376 case Type::FloatTyID: 00377 return "r4"; 00378 case Type::DoubleTyID: 00379 return "r8"; 00380 case Type::PointerTyID: 00381 return "i"+utostr(TD->getTypePaddedSize(Ty)); 00382 default: 00383 cerr << "TypeID = " << Ty->getTypeID() << '\n'; 00384 assert(0 && "Invalid type in TypeToPostfix()"); 00385 } 00386 return ""; // Not reached 00387 } 00388 00389 00390 void MSILWriter::printConvToPtr() { 00391 switch (ModulePtr->getPointerSize()) { 00392 case Module::Pointer32: 00393 printSimpleInstruction("conv.u4"); 00394 break; 00395 case Module::Pointer64: 00396 printSimpleInstruction("conv.u8"); 00397 break; 00398 default: 00399 assert(0 && "Module use not supporting pointer size"); 00400 } 00401 } 00402 00403 00404 void MSILWriter::printPtrLoad(uint64_t N) { 00405 switch (ModulePtr->getPointerSize()) { 00406 case Module::Pointer32: 00407 printSimpleInstruction("ldc.i4",utostr(N).c_str()); 00408 // FIXME: Need overflow test? 00409 if (!isUInt32(N)) { 00410 cerr << "Value = " << utostr(N) << '\n'; 00411 assert(0 && "32-bit pointer overflowed"); 00412 } 00413 break; 00414 case Module::Pointer64: 00415 printSimpleInstruction("ldc.i8",utostr(N).c_str()); 00416 break; 00417 default: 00418 assert(0 && "Module use not supporting pointer size"); 00419 } 00420 } 00421 00422 00423 void MSILWriter::printValuePtrLoad(const Value* V) { 00424 printValueLoad(V); 00425 printConvToPtr(); 00426 } 00427 00428 00429 void MSILWriter::printConstLoad(const Constant* C) { 00430 if (const ConstantInt* CInt = dyn_cast<ConstantInt>(C)) { 00431 // Integer constant 00432 Out << "\tldc." << getTypePostfix(C->getType(),true) << '\t'; 00433 if (CInt->isMinValue(true)) 00434 Out << CInt->getSExtValue(); 00435 else 00436 Out << CInt->getZExtValue(); 00437 } else if (const ConstantFP* FP = dyn_cast<ConstantFP>(C)) { 00438 // Float constant 00439 uint64_t X; 00440 unsigned Size; 00441 if (FP->getType()->getTypeID()==Type::FloatTyID) { 00442 X = (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue(); 00443 Size = 4; 00444 } else { 00445 X = FP->getValueAPF().bitcastToAPInt().getZExtValue(); 00446 Size = 8; 00447 } 00448 Out << "\tldc.r" << Size << "\t( " << utohexstr(X) << ')'; 00449 } else if (isa<UndefValue>(C)) { 00450 // Undefined constant value = NULL. 00451 printPtrLoad(0); 00452 } else { 00453 cerr << "Constant = " << *C << '\n'; 00454 assert(0 && "Invalid constant value"); 00455 } 00456 Out << '\n'; 00457 } 00458 00459 00460 void MSILWriter::printValueLoad(const Value* V) { 00461 MSILWriter::ValueType Location = getValueLocation(V); 00462 switch (Location) { 00463 // Global variable or function address. 00464 case GlobalVT: 00465 case InternalVT: 00466 if (const Function* F = dyn_cast<Function>(V)) { 00467 std::string Name = getConvModopt(F->getCallingConv())+getValueName(F); 00468 printSimpleInstruction("ldftn", 00469 getCallSignature(F->getFunctionType(),NULL,Name).c_str()); 00470 } else { 00471 std::string Tmp; 00472 const Type* ElemTy = cast<PointerType>(V->getType())->getElementType(); 00473 if (Location==GlobalVT && cast<GlobalVariable>(V)->hasDLLImportLinkage()) { 00474 Tmp = "void* "+getValueName(V); 00475 printSimpleInstruction("ldsfld",Tmp.c_str()); 00476 } else { 00477 Tmp = getTypeName(ElemTy)+getValueName(V); 00478 printSimpleInstruction("ldsflda",Tmp.c_str()); 00479 } 00480 } 00481 break; 00482 // Function argument. 00483 case ArgumentVT: 00484 printSimpleInstruction("ldarg",getValueName(V).c_str()); 00485 break; 00486 // Local function variable. 00487 case LocalVT: 00488 printSimpleInstruction("ldloc",getValueName(V).c_str()); 00489 break; 00490 // Constant value. 00491 case ConstVT: 00492 if (isa<ConstantPointerNull>(V)) 00493 printPtrLoad(0); 00494 else 00495 printConstLoad(cast<Constant>(V)); 00496 break; 00497 // Constant expression. 00498 case ConstExprVT: 00499 printConstantExpr(cast<ConstantExpr>(V)); 00500 break; 00501 default: 00502 cerr << "Value = " << *V << '\n'; 00503 assert(0 && "Invalid value location"); 00504 } 00505 } 00506 00507 00508 void MSILWriter::printValueSave(const Value* V) { 00509 switch (getValueLocation(V)) { 00510 case ArgumentVT: 00511 printSimpleInstruction("starg",getValueName(V).c_str()); 00512 break; 00513 case LocalVT: 00514 printSimpleInstruction("stloc",getValueName(V).c_str()); 00515 break; 00516 default: 00517 cerr << "Value = " << *V << '\n'; 00518 assert(0 && "Invalid value location"); 00519 } 00520 } 00521 00522 00523 void MSILWriter::printBinaryInstruction(const char* Name, const Value* Left, 00524 const Value* Right) { 00525 printValueLoad(Left); 00526 printValueLoad(Right); 00527 Out << '\t' << Name << '\n'; 00528 } 00529 00530 00531 void MSILWriter::printSimpleInstruction(const char* Inst, const char* Operand) { 00532 if(Operand) 00533 Out << '\t' << Inst << '\t' << Operand << '\n'; 00534 else 00535 Out << '\t' << Inst << '\n'; 00536 } 00537 00538 00539 void MSILWriter::printPHICopy(const BasicBlock* Src, const BasicBlock* Dst) { 00540 for (BasicBlock::const_iterator I = Dst->begin(), E = Dst->end(); 00541 isa<PHINode>(I); ++I) { 00542 const PHINode* Phi = cast<PHINode>(I); 00543 const Value* Val = Phi->getIncomingValueForBlock(Src); 00544 if (isa<UndefValue>(Val)) continue; 00545 printValueLoad(Val); 00546 printValueSave(Phi); 00547 } 00548 } 00549 00550 00551 void MSILWriter::printBranchToBlock(const BasicBlock* CurrBB, 00552 const BasicBlock* TrueBB, 00553 const BasicBlock* FalseBB) { 00554 if (TrueBB==FalseBB) { 00555 // "TrueBB" and "FalseBB" destination equals 00556 printPHICopy(CurrBB,TrueBB); 00557 printSimpleInstruction("pop"); 00558 printSimpleInstruction("br",getLabelName(TrueBB).c_str()); 00559 } else if (FalseBB==NULL) { 00560 // If "FalseBB" not used the jump have condition 00561 printPHICopy(CurrBB,TrueBB); 00562 printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str()); 00563 } else if (TrueBB==NULL) { 00564 // If "TrueBB" not used the jump is unconditional 00565 printPHICopy(CurrBB,FalseBB); 00566 printSimpleInstruction("br",getLabelName(FalseBB).c_str()); 00567 } else { 00568 // Copy PHI instructions for each block 00569 std::string TmpLabel; 00570 // Print PHI instructions for "TrueBB" 00571 if (isa<PHINode>(TrueBB->begin())) { 00572 TmpLabel = getLabelName(TrueBB)+"$phi_"+utostr(getUniqID()); 00573 printSimpleInstruction("brtrue",TmpLabel.c_str()); 00574 } else { 00575 printSimpleInstruction("brtrue",getLabelName(TrueBB).c_str()); 00576 } 00577 // Print PHI instructions for "FalseBB" 00578 if (isa<PHINode>(FalseBB->begin())) { 00579 printPHICopy(CurrBB,FalseBB); 00580 printSimpleInstruction("br",getLabelName(FalseBB).c_str()); 00581 } else { 00582 printSimpleInstruction("br",getLabelName(FalseBB).c_str()); 00583 } 00584 if (isa<PHINode>(TrueBB->begin())) { 00585 // Handle "TrueBB" PHI Copy 00586 Out << TmpLabel << ":\n"; 00587 printPHICopy(CurrBB,TrueBB); 00588 printSimpleInstruction("br",getLabelName(TrueBB).c_str()); 00589 } 00590 } 00591 } 00592 00593 00594 void MSILWriter::printBranchInstruction(const BranchInst* Inst) { 00595 if (Inst->isUnconditional()) { 00596 printBranchToBlock(Inst->getParent(),NULL,Inst->getSuccessor(0)); 00597 } else { 00598 printValueLoad(Inst->getCondition()); 00599 printBranchToBlock(Inst->getParent(),Inst->getSuccessor(0), 00600 Inst->getSuccessor(1)); 00601 } 00602 } 00603 00604 00605 void MSILWriter::printSelectInstruction(const Value* Cond, const Value* VTrue, 00606 const Value* VFalse) { 00607 std::string TmpLabel = std::string("select$true_")+utostr(getUniqID()); 00608 printValueLoad(VTrue); 00609 printValueLoad(Cond); 00610 printSimpleInstruction("brtrue",TmpLabel.c_str()); 00611 printSimpleInstruction("pop"); 00612 printValueLoad(VFalse); 00613 Out << TmpLabel << ":\n"; 00614 } 00615 00616 00617 void MSILWriter::printIndirectLoad(const Value* V) { 00618 const Type* Ty = V->getType(); 00619 printValueLoad(V); 00620 if (const PointerType* P = dyn_cast<PointerType>(Ty)) 00621 Ty = P->getElementType(); 00622 std::string Tmp = "ldind."+getTypePostfix(Ty, false); 00623 printSimpleInstruction(Tmp.c_str()); 00624 } 00625 00626 00627 void MSILWriter::printIndirectSave(const Value* Ptr, const Value* Val) { 00628 printValueLoad(Ptr); 00629 printValueLoad(Val); 00630 printIndirectSave(Val->getType()); 00631 } 00632 00633 00634 void MSILWriter::printIndirectSave(const Type* Ty) { 00635 // Instruction need signed postfix for any type. 00636 std::string postfix = getTypePostfix(Ty, false); 00637 if (*postfix.begin()=='u') *postfix.begin() = 'i'; 00638 postfix = "stind."+postfix; 00639 printSimpleInstruction(postfix.c_str()); 00640 } 00641 00642 00643 void MSILWriter::printCastInstruction(unsigned int Op, const Value* V, 00644 const Type* Ty) { 00645 std::string Tmp(""); 00646 printValueLoad(V); 00647 switch (Op) { 00648 // Signed 00649 case Instruction::SExt: 00650 case Instruction::SIToFP: 00651 case Instruction::FPToSI: 00652 Tmp = "conv."+getTypePostfix(Ty,false,true); 00653 printSimpleInstruction(Tmp.c_str()); 00654 break; 00655 // Unsigned 00656 case Instruction::FPTrunc: 00657 case Instruction::FPExt: 00658 case Instruction::UIToFP: 00659 case Instruction::Trunc: 00660 case Instruction::ZExt: 00661 case Instruction::FPToUI: 00662 case Instruction::PtrToInt: 00663 case Instruction::IntToPtr: 00664 Tmp = "conv."+getTypePostfix(Ty,false); 00665 printSimpleInstruction(Tmp.c_str()); 00666 break; 00667 // Do nothing 00668 case Instruction::BitCast: 00669 // FIXME: meaning that ld*/st* instruction do not change data format. 00670 break; 00671 default: 00672 cerr << "Opcode = " << Op << '\n'; 00673 assert(0 && "Invalid conversion instruction"); 00674 } 00675 } 00676 00677 00678 void MSILWriter::printGepInstruction(const Value* V, gep_type_iterator I, 00679 gep_type_iterator E) { 00680 unsigned Size; 00681 // Load address 00682 printValuePtrLoad(V); 00683 // Calculate element offset. 00684 for (; I!=E; ++I){ 00685 Size = 0; 00686 const Value* IndexValue = I.getOperand(); 00687 if (const StructType* StrucTy = dyn_cast<StructType>(*I)) { 00688 uint64_t FieldIndex = cast<ConstantInt>(IndexValue)->getZExtValue(); 00689 // Offset is the sum of all previous structure fields. 00690 for (uint64_t F = 0; F<FieldIndex; ++F) 00691 Size += TD->getTypePaddedSize(StrucTy->getContainedType((unsigned)F)); 00692 printPtrLoad(Size); 00693 printSimpleInstruction("add"); 00694 continue; 00695 } else if (const SequentialType* SeqTy = dyn_cast<SequentialType>(*I)) { 00696 Size = TD->getTypePaddedSize(SeqTy->getElementType()); 00697 } else { 00698 Size = TD->getTypePaddedSize(*I); 00699 } 00700 // Add offset of current element to stack top. 00701 if (!isZeroValue(IndexValue)) { 00702 // Constant optimization. 00703 if (const ConstantInt* C = dyn_cast<ConstantInt>(IndexValue)) { 00704 if (C->getValue().isNegative()) { 00705 printPtrLoad(C->getValue().abs().getZExtValue()*Size); 00706 printSimpleInstruction("sub"); 00707 continue; 00708 } else 00709 printPtrLoad(C->getZExtValue()*Size); 00710 } else { 00711 printPtrLoad(Size); 00712 printValuePtrLoad(IndexValue); 00713 printSimpleInstruction("mul"); 00714 } 00715 printSimpleInstruction("add"); 00716 } 00717 } 00718 } 00719 00720 00721 std::string MSILWriter::getCallSignature(const FunctionType* Ty, 00722 const Instruction* Inst, 00723 std::string Name) { 00724 std::string Tmp(""); 00725 if (Ty->isVarArg()) Tmp += "vararg "; 00726 // Name and return type. 00727 Tmp += getTypeName(Ty->getReturnType())+Name+"("; 00728 // Function argument type list. 00729 unsigned NumParams = Ty->getNumParams(); 00730 for (unsigned I = 0; I!=NumParams; ++I) { 00731 if (I!=0) Tmp += ","; 00732 Tmp += getTypeName(Ty->getParamType(I)); 00733 } 00734 // CLR needs to know the exact amount of parameters received by vararg 00735 // function, because caller cleans the stack. 00736 if (Ty->isVarArg() && Inst) { 00737 // Origin to function arguments in "CallInst" or "InvokeInst". 00738 unsigned Org = isa<InvokeInst>(Inst) ? 3 : 1; 00739 // Print variable argument types. 00740 unsigned NumOperands = Inst->getNumOperands()-Org; 00741 if (NumParams<NumOperands) { 00742 if (NumParams!=0) Tmp += ", "; 00743 Tmp += "... , "; 00744 for (unsigned J = NumParams; J!=NumOperands; ++J) { 00745 if (J!=NumParams) Tmp += ", "; 00746 Tmp += getTypeName(Inst->getOperand(J+Org)->getType()); 00747 } 00748 } 00749 } 00750 return Tmp+")"; 00751 } 00752 00753 00754 void MSILWriter::printFunctionCall(const Value* FnVal, 00755 const Instruction* Inst) { 00756 // Get function calling convention. 00757 std::string Name = ""; 00758 if (const CallInst* Call = dyn_cast<CallInst>(Inst)) 00759 Name = getConvModopt(Call->getCallingConv()); 00760 else if (const InvokeInst* Invoke = dyn_cast<InvokeInst>(Inst)) 00761 Name = getConvModopt(Invoke->getCallingConv()); 00762 else { 00763 cerr << "Instruction = " << Inst->getName() << '\n'; 00764 assert(0 && "Need \"Invoke\" or \"Call\" instruction only"); 00765 } 00766 if (const Function* F = dyn_cast<Function>(FnVal)) { 00767 // Direct call. 00768 Name += getValueName(F); 00769 printSimpleInstruction("call", 00770 getCallSignature(F->getFunctionType(),Inst,Name).c_str()); 00771 } else { 00772 // Indirect function call. 00773 const PointerType* PTy = cast<PointerType>(FnVal->getType()); 00774 const FunctionType* FTy = cast<FunctionType>(PTy->getElementType()); 00775 // Load function address. 00776 printValueLoad(FnVal); 00777 printSimpleInstruction("calli",getCallSignature(FTy,Inst,Name).c_str()); 00778 } 00779 } 00780 00781 00782 void MSILWriter::printIntrinsicCall(const IntrinsicInst* Inst) { 00783 std::string Name; 00784 switch (Inst->getIntrinsicID()) { 00785 case Intrinsic::vastart: 00786 Name = getValueName(Inst->getOperand(1)); 00787 Name.insert(Name.length()-1,"$valist"); 00788 // Obtain the argument handle. 00789 printSimpleInstruction("ldloca",Name.c_str()); 00790 printSimpleInstruction("arglist"); 00791 printSimpleInstruction("call", 00792 "instance void [mscorlib]System.ArgIterator::.ctor" 00793 "(valuetype [mscorlib]System.RuntimeArgumentHandle)"); 00794 // Save as pointer type "void*" 00795 printValueLoad(Inst->getOperand(1)); 00796 printSimpleInstruction("ldloca",Name.c_str()); 00797 printIndirectSave(PointerType::getUnqual(IntegerType::get(8))); 00798 break; 00799 case Intrinsic::vaend: 00800 // Close argument list handle. 00801 printIndirectLoad(Inst->getOperand(1)); 00802 printSimpleInstruction("call","instance void [mscorlib]System.ArgIterator::End()"); 00803 break; 00804 case Intrinsic::vacopy: 00805 // Copy "ArgIterator" valuetype. 00806 printIndirectLoad(Inst->getOperand(1)); 00807 printIndirectLoad(Inst->getOperand(2)); 00808 printSimpleInstruction("cpobj","[mscorlib]System.ArgIterator"); 00809 break; 00810 default: 00811 cerr << "Intrinsic ID = " << Inst->getIntrinsicID() << '\n'; 00812 assert(0 && "Invalid intrinsic function"); 00813 } 00814 } 00815 00816 00817 void MSILWriter::printCallInstruction(const Instruction* Inst) { 00818 if (isa<IntrinsicInst>(Inst)) { 00819 // Handle intrinsic function. 00820 printIntrinsicCall(cast<IntrinsicInst>(Inst)); 00821 } else { 00822 // Load arguments to stack and call function. 00823 for (int I = 1, E = Inst->getNumOperands(); I!=E; ++I) 00824 printValueLoad(Inst->getOperand(I)); 00825 printFunctionCall(Inst->getOperand(0),Inst); 00826 } 00827 } 00828 00829 00830 void MSILWriter::printICmpInstruction(unsigned Predicate, const Value* Left, 00831 const Value* Right) { 00832 switch (Predicate) { 00833 case ICmpInst::ICMP_EQ: 00834 printBinaryInstruction("ceq",Left,Right); 00835 break; 00836 case ICmpInst::ICMP_NE: 00837 // Emulate = not neg (Op1 eq Op2) 00838 printBinaryInstruction("ceq",Left,Right); 00839 printSimpleInstruction("neg"); 00840 printSimpleInstruction("not"); 00841 break; 00842 case ICmpInst::ICMP_ULE: 00843 case ICmpInst::ICMP_SLE: 00844 // Emulate = (Op1 eq Op2) or (Op1 lt Op2) 00845 printBinaryInstruction("ceq",Left,Right); 00846 if (Predicate==ICmpInst::ICMP_ULE) 00847 printBinaryInstruction("clt.un",Left,Right); 00848 else 00849 printBinaryInstruction("clt",Left,Right); 00850 printSimpleInstruction("or"); 00851 break; 00852 case ICmpInst::ICMP_UGE: 00853 case ICmpInst::ICMP_SGE: 00854 // Emulate = (Op1 eq Op2) or (Op1 gt Op2) 00855 printBinaryInstruction("ceq",Left,Right); 00856 if (Predicate==ICmpInst::ICMP_UGE) 00857 printBinaryInstruction("cgt.un",Left,Right); 00858 else 00859 printBinaryInstruction("cgt",Left,Right); 00860 printSimpleInstruction("or"); 00861 break; 00862 case ICmpInst::ICMP_ULT: 00863 printBinaryInstruction("clt.un",Left,Right); 00864 break; 00865 case ICmpInst::ICMP_SLT: 00866 printBinaryInstruction("clt",Left,Right); 00867 break; 00868 case ICmpInst::ICMP_UGT: 00869 printBinaryInstruction("cgt.un",Left,Right); 00870 case ICmpInst::ICMP_SGT: 00871 printBinaryInstruction("cgt",Left,Right); 00872 break; 00873 default: 00874 cerr << "Predicate = " << Predicate << '\n'; 00875 assert(0 && "Invalid icmp predicate"); 00876 } 00877 } 00878 00879 00880 void MSILWriter::printFCmpInstruction(unsigned Predicate, const Value* Left, 00881 const Value* Right) { 00882 // FIXME: Correct comparison 00883 std::string NanFunc = "bool [mscorlib]System.Double::IsNaN(float64)"; 00884 switch (Predicate) { 00885 case FCmpInst::FCMP_UGT: 00886 // X > Y || llvm_fcmp_uno(X, Y) 00887 printBinaryInstruction("cgt",Left,Right); 00888 printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right); 00889 printSimpleInstruction("or"); 00890 break; 00891 case FCmpInst::FCMP_OGT: 00892 // X > Y 00893 printBinaryInstruction("cgt",Left,Right); 00894 break; 00895 case FCmpInst::FCMP_UGE: 00896 // X >= Y || llvm_fcmp_uno(X, Y) 00897 printBinaryInstruction("ceq",Left,Right); 00898 printBinaryInstruction("cgt",Left,Right); 00899 printSimpleInstruction("or"); 00900 printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right); 00901 printSimpleInstruction("or"); 00902 break; 00903 case FCmpInst::FCMP_OGE: 00904 // X >= Y 00905 printBinaryInstruction("ceq",Left,Right); 00906 printBinaryInstruction("cgt",Left,Right); 00907 printSimpleInstruction("or"); 00908 break; 00909 case FCmpInst::FCMP_ULT: 00910 // X < Y || llvm_fcmp_uno(X, Y) 00911 printBinaryInstruction("clt",Left,Right); 00912 printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right); 00913 printSimpleInstruction("or"); 00914 break; 00915 case FCmpInst::FCMP_OLT: 00916 // X < Y 00917 printBinaryInstruction("clt",Left,Right); 00918 break; 00919 case FCmpInst::FCMP_ULE: 00920 // X <= Y || llvm_fcmp_uno(X, Y) 00921 printBinaryInstruction("ceq",Left,Right); 00922 printBinaryInstruction("clt",Left,Right); 00923 printSimpleInstruction("or"); 00924 printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right); 00925 printSimpleInstruction("or"); 00926 break; 00927 case FCmpInst::FCMP_OLE: 00928 // X <= Y 00929 printBinaryInstruction("ceq",Left,Right); 00930 printBinaryInstruction("clt",Left,Right); 00931 printSimpleInstruction("or"); 00932 break; 00933 case FCmpInst::FCMP_UEQ: 00934 // X == Y || llvm_fcmp_uno(X, Y) 00935 printBinaryInstruction("ceq",Left,Right); 00936 printFCmpInstruction(FCmpInst::FCMP_UNO,Left,Right); 00937 printSimpleInstruction("or"); 00938 break; 00939 case FCmpInst::FCMP_OEQ: 00940 // X == Y 00941 printBinaryInstruction("ceq",Left,Right); 00942 break; 00943 case FCmpInst::FCMP_UNE: 00944 // X != Y 00945 printBinaryInstruction("ceq",Left,Right); 00946 printSimpleInstruction("neg"); 00947 printSimpleInstruction("not"); 00948 break; 00949 case FCmpInst::FCMP_ONE: 00950 // X != Y && llvm_fcmp_ord(X, Y) 00951 printBinaryInstruction("ceq",Left,Right); 00952 printSimpleInstruction("not"); 00953 break; 00954 case FCmpInst::FCMP_ORD: 00955 // return X == X && Y == Y 00956 printBinaryInstruction("ceq",Left,Left); 00957 printBinaryInstruction("ceq",Right,Right); 00958 printSimpleInstruction("or"); 00959 break; 00960 case FCmpInst::FCMP_UNO: 00961 // X != X || Y != Y 00962 printBinaryInstruction("ceq",Left,Left); 00963 printSimpleInstruction("not"); 00964 printBinaryInstruction("ceq",Right,Right); 00965 printSimpleInstruction("not"); 00966 printSimpleInstruction("or"); 00967 break; 00968 default: 00969 assert(0 && "Illegal FCmp predicate"); 00970 } 00971 } 00972 00973 00974 void MSILWriter::printInvokeInstruction(const InvokeInst* Inst) { 00975 std::string Label = "leave$normal_"+utostr(getUniqID()); 00976 Out << ".try {\n"; 00977 // Load arguments 00978 for (int I = 3, E = Inst->getNumOperands(); I!=E; ++I) 00979 printValueLoad(Inst->getOperand(I)); 00980 // Print call instruction 00981 printFunctionCall(Inst->getOperand(0),Inst); 00982 // Save function result and leave "try" block 00983 printValueSave(Inst); 00984 printSimpleInstruction("leave",Label.c_str()); 00985 Out << "}\n"; 00986 Out << "catch [mscorlib]System.Exception {\n"; 00987 // Redirect to unwind block 00988 printSimpleInstruction("pop"); 00989 printBranchToBlock(Inst->getParent(),NULL,Inst->getUnwindDest()); 00990 Out << "}\n" << Label << ":\n"; 00991 // Redirect to continue block 00992 printBranchToBlock(Inst->getParent(),NULL,Inst->getNormalDest()); 00993 } 00994 00995 00996 void MSILWriter::printSwitchInstruction(const SwitchInst* Inst) { 00997 // FIXME: Emulate with IL "switch" instruction 00998 // Emulate = if () else if () else if () else ... 00999 for (unsigned int I = 1, E = Inst->getNumCases(); I!=E; ++I) { 01000 printValueLoad(Inst->getCondition()); 01001 printValueLoad(Inst->getCaseValue(I)); 01002 printSimpleInstruction("ceq"); 01003 // Condition jump to successor block 01004 printBranchToBlock(Inst->getParent(),Inst->getSuccessor(I),NULL); 01005 } 01006 // Jump to default block 01007 printBranchToBlock(Inst->getParent(),NULL,Inst->getDefaultDest()); 01008 } 01009 01010 01011 void MSILWriter::printVAArgInstruction(const VAArgInst* Inst) { 01012 printIndirectLoad(Inst->getOperand(0)); 01013 printSimpleInstruction("call", 01014 "instance typedref [mscorlib]System.ArgIterator::GetNextArg()"); 01015 printSimpleInstruction("refanyval","void*"); 01016 std::string Name = 01017 "ldind."+getTypePostfix(PointerType::getUnqual(IntegerType::get(8)),false); 01018 printSimpleInstruction(Name.c_str()); 01019 } 01020 01021 01022 void MSILWriter::printAllocaInstruction(const AllocaInst* Inst) { 01023 uint64_t Size = TD->getTypePaddedSize(Inst->getAllocatedType()); 01024 // Constant optimization. 01025 if (const ConstantInt* CInt = dyn_cast<ConstantInt>(Inst->getOperand(0))) { 01026 printPtrLoad(CInt->getZExtValue()*Size); 01027 } else { 01028 printPtrLoad(Size); 01029 printValueLoad(Inst->getOperand(0)); 01030 printSimpleInstruction("mul"); 01031 } 01032 printSimpleInstruction("localloc"); 01033 } 01034 01035 01036 void MSILWriter::printInstruction(const Instruction* Inst) { 01037 const Value *Left = 0, *Right = 0; 01038 if (Inst->getNumOperands()>=1) Left = Inst->getOperand(0); 01039 if (Inst->getNumOperands()>=2) Right = Inst->getOperand(1); 01040 // Print instruction 01041 // FIXME: "ShuffleVector","ExtractElement","InsertElement" support. 01042 switch (Inst->getOpcode()) { 01043 // Terminator 01044 case Instruction::Ret: 01045 if (Inst->getNumOperands()) { 01046 printValueLoad(Left); 01047 printSimpleInstruction("ret"); 01048 } else 01049 printSimpleInstruction("ret"); 01050 break; 01051 case Instruction::Br: 01052 printBranchInstruction(cast<BranchInst>(Inst)); 01053 break; 01054 // Binary 01055 case Instruction::Add: 01056 printBinaryInstruction("add",Left,Right); 01057 break; 01058 case Instruction::Sub: 01059 printBinaryInstruction("sub",Left,Right); 01060 break; 01061 case Instruction::Mul: 01062 printBinaryInstruction("mul",Left,Right); 01063 break; 01064 case Instruction::UDiv: 01065 printBinaryInstruction("div.un",Left,Right); 01066 break; 01067 case Instruction::SDiv: 01068 case Instruction::FDiv: 01069 printBinaryInstruction("div",Left,Right); 01070 break; 01071 case Instruction::URem: 01072 printBinaryInstruction("rem.un",Left,Right); 01073 break; 01074 case Instruction::SRem: 01075 case Instruction::FRem: 01076 printBinaryInstruction("rem",Left,Right); 01077 break; 01078 // Binary Condition 01079 case Instruction::ICmp: 01080 printICmpInstruction(cast<ICmpInst>(Inst)->getPredicate(),Left,Right); 01081 break; 01082 case Instruction::FCmp: 01083 printFCmpInstruction(cast<FCmpInst>(Inst)->getPredicate(),Left,Right); 01084 break; 01085 // Bitwise Binary 01086 case Instruction::And: 01087 printBinaryInstruction("and",Left,Right); 01088 break; 01089 case Instruction::Or: 01090 printBinaryInstruction("or",Left,Right); 01091 break; 01092 case Instruction::Xor: 01093 printBinaryInstruction("xor",Left,Right); 01094 break; 01095 case Instruction::Shl: 01096 printValueLoad(Left); 01097 printValueLoad(Right); 01098 printSimpleInstruction("conv.i4"); 01099 printSimpleInstruction("shl"); 01100 break; 01101 case Instruction::LShr: 01102 printValueLoad(Left); 01103 printValueLoad(Right); 01104 printSimpleInstruction("conv.i4"); 01105 printSimpleInstruction("shr.un"); 01106 break; 01107 case Instruction::AShr: 01108 printValueLoad(Left); 01109 printValueLoad(Right); 01110 printSimpleInstruction("conv.i4"); 01111 printSimpleInstruction("shr"); 01112 break; 01113 case Instruction::Select: 01114 printSelectInstruction(Inst->getOperand(0),Inst->getOperand(1),Inst->getOperand(2)); 01115 break; 01116 case Instruction::Load: 01117 printIndirectLoad(Inst->getOperand(0)); 01118 break; 01119 case Instruction::Store: 01120 printIndirectSave(Inst->getOperand(1), Inst->getOperand(0)); 01121 break; 01122 case Instruction::Trunc: 01123 case Instruction::ZExt: 01124 case Instruction::SExt: 01125 case Instruction::FPTrunc: 01126 case Instruction::FPExt: 01127 case Instruction::UIToFP: 01128 case Instruction::SIToFP: 01129 case Instruction::FPToUI: 01130 case Instruction::FPToSI: 01131 case Instruction::PtrToInt: 01132 case Instruction::IntToPtr: 01133 case Instruction::BitCast: 01134 printCastInstruction(Inst->getOpcode(),Left, 01135 cast<CastInst>(Inst)->getDestTy()); 01136 break; 01137 case Instruction::GetElementPtr: 01138 printGepInstruction(Inst->getOperand(0),gep_type_begin(Inst), 01139 gep_type_end(Inst)); 01140 break; 01141 case Instruction::Call: 01142 printCallInstruction(cast<CallInst>(Inst)); 01143 break; 01144 case Instruction::Invoke: 01145 printInvokeInstruction(cast<InvokeInst>(Inst)); 01146 break; 01147 case Instruction::Unwind: 01148 printSimpleInstruction("newobj", 01149 "instance void [mscorlib]System.Exception::.ctor()"); 01150 printSimpleInstruction("throw"); 01151 break; 01152 case Instruction::Switch: 01153 printSwitchInstruction(cast<SwitchInst>(Inst)); 01154 break; 01155 case Instruction::Alloca: 01156 printAllocaInstruction(cast<AllocaInst>(Inst)); 01157 break; 01158 case Instruction::Malloc: 01159 assert(0 && "LowerAllocationsPass used"); 01160 break; 01161 case Instruction::Free: 01162 assert(0 && "LowerAllocationsPass used"); 01163 break; 01164 case Instruction::Unreachable: 01165 printSimpleInstruction("ldstr", "\"Unreachable instruction\""); 01166 printSimpleInstruction("newobj", 01167 "instance void [mscorlib]System.Exception::.ctor(string)"); 01168 printSimpleInstruction("throw"); 01169 break; 01170 case Instruction::VAArg: 01171 printVAArgInstruction(cast<VAArgInst>(Inst)); 01172 break; 01173 default: 01174 cerr << "Instruction = " << Inst->getName() << '\n'; 01175 assert(0 && "Unsupported instruction"); 01176 } 01177 } 01178 01179 01180 void MSILWriter::printLoop(const Loop* L) { 01181 Out << getLabelName(L->getHeader()->getName()) << ":\n"; 01182 const std::vector<BasicBlock*>& blocks = L->getBlocks(); 01183 for (unsigned I = 0, E = blocks.size(); I!=E; I++) { 01184 BasicBlock* BB = blocks[I]; 01185 Loop* BBLoop = LInfo->getLoopFor(BB); 01186 if (BBLoop == L) 01187 printBasicBlock(BB); 01188 else if (BB==BBLoop->getHeader() && BBLoop->getParentLoop()==L) 01189 printLoop(BBLoop); 01190 } 01191 printSimpleInstruction("br",getLabelName(L->getHeader()->getName()).c_str()); 01192 } 01193 01194 01195 void MSILWriter::printBasicBlock(const BasicBlock* BB) { 01196 Out << getLabelName(BB) << ":\n"; 01197 for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { 01198 const Instruction* Inst = I; 01199 // Comment llvm original instruction 01200 // Out << "\n//" << *Inst << "\n"; 01201 // Do not handle PHI instruction in current block 01202 if (Inst->getOpcode()==Instruction::PHI) continue; 01203 // Print instruction 01204 printInstruction(Inst); 01205 // Save result 01206 if (Inst->getType()!=Type::VoidTy) { 01207 // Do not save value after invoke, it done in "try" block 01208 if (Inst->getOpcode()==Instruction::Invoke) continue; 01209 printValueSave(Inst); 01210 } 01211 } 01212 } 01213 01214 01215 void MSILWriter::printLocalVariables(const Function& F) { 01216 std::string Name; 01217 const Type* Ty = NULL; 01218 std::set<const Value*> Printed; 01219 const Value* VaList = NULL; 01220 unsigned StackDepth = 8; 01221 // Find local variables 01222 for (const_inst_iterator I = inst_begin(&F), E = inst_end(&F); I!=E; ++I) { 01223 if (I->getOpcode()==Instruction::Call || 01224 I->getOpcode()==Instruction::Invoke) { 01225 // Test stack depth. 01226 if (StackDepth<I->getNumOperands()) 01227 StackDepth = I->getNumOperands(); 01228 } 01229 const AllocaInst* AI = dyn_cast<AllocaInst>(&*I); 01230 if (AI && !isa<GlobalVariable>(AI)) { 01231 // Local variable allocation. 01232 Ty = PointerType::getUnqual(AI->getAllocatedType()); 01233 Name = getValueName(AI); 01234 Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n"; 01235 } else if (I->getType()!=Type::VoidTy) { 01236 // Operation result. 01237 Ty = I->getType(); 01238 Name = getValueName(&*I); 01239 Out << "\t.locals (" << getTypeName(Ty) << Name << ")\n"; 01240 } 01241 // Test on 'va_list' variable 01242 bool isVaList = false; 01243 if (const VAArgInst* VaInst = dyn_cast<VAArgInst>(&*I)) { 01244 // "va_list" as "va_arg" instruction operand. 01245 isVaList = true; 01246 VaList = VaInst->getOperand(0); 01247 } else if (const IntrinsicInst* Inst = dyn_cast<IntrinsicInst>(&*I)) { 01248 // "va_list" as intrinsic function operand. 01249 switch (Inst->getIntrinsicID()) { 01250 case Intrinsic::vastart: 01251 case Intrinsic::vaend: 01252 case Intrinsic::vacopy: 01253 isVaList = true; 01254 VaList = Inst->getOperand(1); 01255 break; 01256 default: 01257 isVaList = false; 01258 } 01259 } 01260 // Print "va_list" variable. 01261 if (isVaList && Printed.insert(VaList).second) { 01262 Name = getValueName(VaList); 01263 Name.insert(Name.length()-1,"$valist"); 01264 Out << "\t.locals (valuetype [mscorlib]System.ArgIterator " 01265 << Name << ")\n"; 01266 } 01267 } 01268 printSimpleInstruction(".maxstack",utostr(StackDepth*2).c_str()); 01269 } 01270 01271 01272 void MSILWriter::printFunctionBody(const Function& F) { 01273 // Print body 01274 for (Function::const_iterator I = F.begin(), E = F.end(); I!=E; ++I) { 01275 if (Loop *L = LInfo->getLoopFor(I)) { 01276 if (L->getHeader()==I && L->getParentLoop()==0) 01277 printLoop(L); 01278 } else { 01279 printBasicBlock(I); 01280 } 01281 } 01282 } 01283 01284 01285 void MSILWriter::printConstantExpr(const ConstantExpr* CE) { 01286 const Value *left = 0, *right = 0; 01287 if (CE->getNumOperands()>=1) left = CE->getOperand(0); 01288 if (CE->getNumOperands()>=2) right = CE->getOperand(1); 01289 // Print instruction 01290 switch (CE->getOpcode()) { 01291 case Instruction::Trunc: 01292 case Instruction::ZExt: 01293 case Instruction::SExt: 01294 case Instruction::FPTrunc: 01295 case Instruction::FPExt: 01296 case Instruction::UIToFP: 01297 case Instruction::SIToFP: 01298 case Instruction::FPToUI: 01299 case Instruction::FPToSI: 01300 case Instruction::PtrToInt: 01301 case Instruction::IntToPtr: 01302 case Instruction::BitCast: 01303 printCastInstruction(CE->getOpcode(),left,CE->getType()); 01304 break; 01305 case Instruction::GetElementPtr: 01306 printGepInstruction(CE->getOperand(0),gep_type_begin(CE),gep_type_end(CE)); 01307 break; 01308 case Instruction::ICmp: 01309 printICmpInstruction(CE->getPredicate(),left,right); 01310 break; 01311 case Instruction::FCmp: 01312 printFCmpInstruction(CE->getPredicate(),left,right); 01313 break; 01314 case Instruction::Select: 01315 printSelectInstruction(CE->getOperand(0),CE->getOperand(1),CE->getOperand(2)); 01316 break; 01317 case Instruction::Add: 01318 printBinaryInstruction("add",left,right); 01319 break; 01320 case Instruction::Sub: 01321 printBinaryInstruction("sub",left,right); 01322 break; 01323 case Instruction::Mul: 01324 printBinaryInstruction("mul",left,right); 01325 break; 01326 case Instruction::UDiv: 01327 printBinaryInstruction("div.un",left,right); 01328 break; 01329 case Instruction::SDiv: 01330 case Instruction::FDiv: 01331 printBinaryInstruction("div",left,right); 01332 break; 01333 case Instruction::URem: 01334 printBinaryInstruction("rem.un",left,right); 01335 break; 01336 case Instruction::SRem: 01337 case Instruction::FRem: 01338 printBinaryInstruction("rem",left,right); 01339 break; 01340 case Instruction::And: 01341 printBinaryInstruction("and",left,right); 01342 break; 01343 case Instruction::Or: 01344 printBinaryInstruction("or",left,right); 01345 break; 01346 case Instruction::Xor: 01347 printBinaryInstruction("xor",left,right); 01348 break; 01349 case Instruction::Shl: 01350 printBinaryInstruction("shl",left,right); 01351 break; 01352 case Instruction::LShr: 01353 printBinaryInstruction("shr.un",left,right); 01354 break; 01355 case Instruction::AShr: 01356 printBinaryInstruction("shr",left,right); 01357 break; 01358 default: 01359 cerr << "Expression = " << *CE << "\n"; 01360 assert(0 && "Invalid constant expression"); 01361 } 01362 } 01363 01364 01365 void MSILWriter::printStaticInitializerList() { 01366 // List of global variables with uninitialized fields. 01367 for (std::map<const GlobalVariable*,std::vector<StaticInitializer> >::iterator 01368 VarI = StaticInitList.begin(), VarE = StaticInitList.end(); VarI!=VarE; 01369 ++VarI) { 01370 const std::vector<StaticInitializer>& InitList = VarI->second; 01371 if (InitList.empty()) continue; 01372 // For each uninitialized field. 01373 for (std::vector<StaticInitializer>::const_iterator I = InitList.begin(), 01374 E = InitList.end(); I!=E; ++I) { 01375 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(I->constant)) { 01376 // Out << "\n// Init " << getValueName(VarI->first) << ", offset " << 01377 // utostr(I->offset) << ", type "<< *I->constant->getType() << "\n\n"; 01378 // Load variable address 01379 printValueLoad(VarI->first); 01380 // Add offset 01381 if (I->offset!=0) { 01382 printPtrLoad(I->offset); 01383 printSimpleInstruction("add"); 01384 } 01385 // Load value 01386 printConstantExpr(CE); 01387 // Save result at offset 01388 std::string postfix = getTypePostfix(CE->getType(),true); 01389 if (*postfix.begin()=='u') *postfix.begin() = 'i'; 01390 postfix = "stind."+postfix; 01391 printSimpleInstruction(postfix.c_str()); 01392 } else { 01393 cerr << "Constant = " << *I->constant << '\n'; 01394 assert(0 && "Invalid static initializer"); 01395 } 01396 } 01397 } 01398 } 01399 01400 01401 void MSILWriter::printFunction(const Function& F) { 01402 bool isSigned = F.paramHasAttr(0, Attribute::SExt); 01403 Out << "\n.method static "; 01404 Out << (F.hasLocalLinkage() ? "private " : "public "); 01405 if (F.isVarArg()) Out << "vararg "; 01406 Out << getTypeName(F.getReturnType(),isSigned) << 01407 getConvModopt(F.getCallingConv()) << getValueName(&F) << '\n'; 01408 // Arguments 01409 Out << "\t("; 01410 unsigned ArgIdx = 1; 01411 for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); I!=E; 01412 ++I, ++ArgIdx) { 01413 isSigned = F.paramHasAttr(ArgIdx, Attribute::SExt); 01414 if (I!=F.arg_begin()) Out << ", "; 01415 Out << getTypeName(I->getType(),isSigned) << getValueName(I); 01416 } 01417 Out << ") cil managed\n"; 01418 // Body 01419 Out << "{\n"; 01420 printLocalVariables(F); 01421 printFunctionBody(F); 01422 Out << "}\n"; 01423 } 01424 01425 01426 void MSILWriter::printDeclarations(const TypeSymbolTable& ST) { 01427 std::string Name; 01428 std::set<const Type*> Printed; 01429 for (std::set<const Type*>::const_iterator 01430 UI = UsedTypes->begin(), UE = UsedTypes->end(); UI!=UE; ++UI) { 01431 const Type* Ty = *UI; 01432 if (isa<ArrayType>(Ty) || isa<VectorType>(Ty) || isa<StructType>(Ty)) 01433 Name = getTypeName(Ty, false, true); 01434 // Type with no need to declare. 01435 else continue; 01436 // Print not duplicated type 01437 if (Printed.insert(Ty).second) { 01438 Out << ".class value explicit ansi sealed '" << Name << "'"; 01439 Out << " { .pack " << 1 << " .size " << TD->getTypePaddedSize(Ty); 01440 Out << " }\n\n"; 01441 } 01442 } 01443 } 01444 01445 01446 unsigned int MSILWriter::getBitWidth(const Type* Ty) { 01447 unsigned int N = Ty->getPrimitiveSizeInBits(); 01448 assert(N!=0 && "Invalid type in getBitWidth()"); 01449 switch (N) { 01450 case 1: 01451 case 8: 01452 case 16: 01453 case 32: 01454 case 64: 01455 return N; 01456 default: 01457 cerr << "Bits = " << N << '\n'; 01458 assert(0 && "Unsupported integer width"); 01459 } 01460 return 0; // Not reached 01461 } 01462 01463 01464 void MSILWriter::printStaticConstant(const Constant* C, uint64_t& Offset) { 01465 uint64_t TySize = 0; 01466 const Type* Ty = C->getType(); 01467 // Print zero initialized constant. 01468 if (isa<ConstantAggregateZero>(C) || C->isNullValue()) { 01469 TySize = TD->getTypePaddedSize(C->getType()); 01470 Offset += TySize; 01471 Out << "int8 (0) [" << TySize << "]"; 01472 return; 01473 } 01474 // Print constant initializer 01475 switch (Ty->getTypeID()) { 01476 case Type::IntegerTyID: { 01477 TySize = TD->getTypePaddedSize(Ty); 01478 const ConstantInt* Int = cast<ConstantInt>(C); 01479 Out << getPrimitiveTypeName(Ty,true) << "(" << Int->getSExtValue() << ")"; 01480 break; 01481 } 01482 case Type::FloatTyID: 01483 case Type::DoubleTyID: { 01484 TySize = TD->getTypePaddedSize(Ty); 01485 const ConstantFP* FP = cast<ConstantFP>(C); 01486 if (Ty->getTypeID() == Type::FloatTyID) 01487 Out << "int32 (" << 01488 (uint32_t)FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')'; 01489 else 01490 Out << "int64 (" << 01491 FP->getValueAPF().bitcastToAPInt().getZExtValue() << ')'; 01492 break; 01493 } 01494 case Type::ArrayTyID: 01495 case Type::VectorTyID: 01496 case Type::StructTyID: 01497 for (unsigned I = 0, E = C->getNumOperands(); I<E; I++) { 01498 if (I!=0) Out << ",\n"; 01499 printStaticConstant(C->getOperand(I),Offset); 01500 } 01501 break; 01502 case Type::PointerTyID: 01503 TySize = TD->getTypePaddedSize(C->getType()); 01504 // Initialize with global variable address 01505 if (const GlobalVariable *G = dyn_cast<GlobalVariable>(C)) { 01506 std::string name = getValueName(G); 01507 Out << "&(" << name.insert(name.length()-1,"$data") << ")"; 01508 } else { 01509 // Dynamic initialization 01510 if (!isa<ConstantPointerNull>(C) && !C->isNullValue()) 01511 InitListPtr->push_back(StaticInitializer(C,Offset)); 01512 // Null pointer initialization 01513 if (TySize==4) Out << "int32 (0)"; 01514 else if (TySize==8) Out << "int64 (0)"; 01515 else assert(0 && "Invalid pointer size"); 01516 } 01517 break; 01518 default: 01519 cerr << "TypeID = " << Ty->getTypeID() << '\n'; 01520 assert(0 && "Invalid type in printStaticConstant()"); 01521 } 01522 // Increase offset. 01523 Offset += TySize; 01524 } 01525 01526 01527 void MSILWriter::printStaticInitializer(const Constant* C, 01528 const std::string& Name) { 01529 switch (C->getType()->getTypeID()) { 01530 case Type::IntegerTyID: 01531 case Type::FloatTyID: 01532 case Type::DoubleTyID: 01533 Out << getPrimitiveTypeName(C->getType(), false); 01534 break; 01535 case Type::ArrayTyID: 01536 case Type::VectorTyID: 01537 case Type::StructTyID: 01538 case Type::PointerTyID: 01539 Out << getTypeName(C->getType()); 01540 break; 01541 default: 01542 cerr << "Type = " << *C << "\n"; 01543 assert(0 && "Invalid constant type"); 01544 } 01545 // Print initializer 01546 std::string label = Name; 01547 label.insert(label.length()-1,"$data"); 01548 Out << Name << " at " << label << '\n'; 01549 Out << ".data " << label << " = {\n"; 01550 uint64_t offset = 0; 01551 printStaticConstant(C,offset); 01552 Out << "\n}\n\n"; 01553 } 01554 01555 01556 void MSILWriter::printVariableDefinition(const GlobalVariable* G) { 01557 const Constant* C = G->getInitializer(); 01558 if (C->isNullValue() || isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) 01559 InitListPtr = 0; 01560 else 01561 InitListPtr = &StaticInitList[G]; 01562 printStaticInitializer(C,getValueName(G)); 01563 } 01564 01565 01566 void MSILWriter::printGlobalVariables() { 01567 if (ModulePtr->global_empty()) return; 01568 Module::global_iterator I,E; 01569 for (I = ModulePtr->global_begin(), E = ModulePtr->global_end(); I!=E; ++I) { 01570 // Variable definition 01571 Out << ".field static " << (I->isDeclaration() ? "public " : 01572 "private "); 01573 if (I->isDeclaration()) { 01574 Out << getTypeName(I->getType()) << getValueName(&*I) << "\n\n"; 01575 } else 01576 printVariableDefinition(&*I); 01577 } 01578 } 01579 01580 01581 const char* MSILWriter::getLibraryName(const Function* F) { 01582 return getLibraryForSymbol(F->getName().c_str(), true, F->getCallingConv()); 01583 } 01584 01585 01586 const char* MSILWriter::getLibraryName(const GlobalVariable* GV) { 01587 return getLibraryForSymbol(Mang->getValueName(GV).c_str(), false, 0); 01588 } 01589 01590 01591 const char* MSILWriter::getLibraryForSymbol(const char* Name, bool isFunction, 01592 unsigned CallingConv) { 01593 // TODO: Read *.def file with function and libraries definitions. 01594 return "MSVCRT.DLL"; 01595 } 01596 01597 01598 void MSILWriter::printExternals() { 01599 Module::const_iterator I,E; 01600 // Functions. 01601 for (I=ModulePtr->begin(),E=ModulePtr->end(); I!=E; ++I) { 01602 // Skip intrisics 01603 if (I->isIntrinsic()) continue; 01604 if (I->isDeclaration()) { 01605 const Function* F = I; 01606 std::string Name = getConvModopt(F->getCallingConv())+getValueName(F); 01607 std::string Sig = 01608 getCallSignature(cast<FunctionType>(F->getFunctionType()), NULL, Name); 01609 Out << ".method static hidebysig pinvokeimpl(\"" 01610 << getLibraryName(F) << "\")\n\t" << Sig << " preservesig {}\n\n"; 01611 } 01612 } 01613 // External variables and static initialization. 01614 Out << 01615 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)" 01616 " native int LoadLibrary(string) preservesig {}\n" 01617 ".method public hidebysig static pinvokeimpl(\"KERNEL32.DLL\" ansi winapi)" 01618 " native int GetProcAddress(native int, string) preservesig {}\n"; 01619 Out << 01620 ".method private static void* $MSIL_Import(string lib,string sym)\n" 01621 " managed cil\n{\n" 01622 "\tldarg\tlib\n" 01623 "\tcall\tnative int LoadLibrary(string)\n" 01624 "\tldarg\tsym\n" 01625 "\tcall\tnative int GetProcAddress(native int,string)\n" 01626 "\tdup\n" 01627 "\tbrtrue\tL_01\n" 01628 "\tldstr\t\"Can no import variable\"\n" 01629 "\tnewobj\tinstance void [mscorlib]System.Exception::.ctor(string)\n" 01630 "\tthrow\n" 01631 "L_01:\n" 01632 "\tret\n" 01633 "}\n\n" 01634 ".method static private void $MSIL_Init() managed cil\n{\n"; 01635 printStaticInitializerList(); 01636 // Foreach global variable. 01637 for (Module::global_iterator I = ModulePtr->global_begin(), 01638 E = ModulePtr->global_end(); I!=E; ++I) { 01639 if (!I->isDeclaration() || !I->hasDLLImportLinkage()) continue; 01640 // Use "LoadLibrary"/"GetProcAddress" to recive variable address. 01641 std::string Label = "not_null$_"+utostr(getUniqID()); 01642 std::string Tmp = getTypeName(I->getType())+getValueName(&*I); 01643 printSimpleInstruction("ldsflda",Tmp.c_str()); 01644 Out << "\tldstr\t\"" << getLibraryName(&*I) << "\"\n"; 01645 Out << "\tldstr\t\"" << Mang->getValueName(&*I) << "\"\n"; 01646 printSimpleInstruction("call","void* $MSIL_Import(string,string)"); 01647 printIndirectSave(I->getType()); 01648 } 01649 printSimpleInstruction("ret"); 01650 Out << "}\n\n"; 01651 } 01652 01653 01654 //===----------------------------------------------------------------------===// 01655 // External Interface declaration 01656 //===----------------------------------------------------------------------===// 01657 01658 bool MSILTarget::addPassesToEmitWholeFile(PassManager &PM, raw_ostream &o, 01659 CodeGenFileType FileType, bool Fast) 01660 { 01661 if (FileType != TargetMachine::AssemblyFile) return true; 01662 MSILWriter* Writer = new MSILWriter(o); 01663 PM.add(createGCLoweringPass()); 01664 PM.add(createLowerAllocationsPass(true)); 01665 // FIXME: Handle switch trougth native IL instruction "switch" 01666 PM.add(createLowerSwitchPass()); 01667 PM.add(createCFGSimplificationPass()); 01668 PM.add(new MSILModule(Writer->UsedTypes,Writer->TD)); 01669 PM.add(Writer); 01670 PM.add(createGCInfoDeleter()); 01671 return false; 01672 }