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