comparison gen/tollvm.c @ 1:c53b6e3fe49a trunk

[svn r5] Initial commit. Most things are very rough.
author lindquist
date Sat, 01 Sep 2007 21:43:27 +0200
parents
children e116aa1488e6
comparison
equal deleted inserted replaced
0:a9e71648e74d 1:c53b6e3fe49a
1 #include <iostream>
2
3 #include "llvm/Constants.h"
4 #include "llvm/Type.h"
5 #include "llvm/DerivedTypes.h"
6 #include "llvm/GlobalValue.h"
7 #include "llvm/Instructions.h"
8 #include "llvm/CallingConv.h"
9
10 #include "mtype.h"
11 #include "dsymbol.h"
12 #include "aggregate.h"
13 #include "declaration.h"
14 #include "init.h"
15
16 #include "tollvm.h"
17 #include "irstate.h"
18 #include "logger.h"
19 #include "runtime.h"
20 #include "elem.h"
21
22 const llvm::Type* LLVM_DtoType(Type* t)
23 {
24 assert(t);
25 switch (t->ty)
26 {
27 // integers
28 case Tint8:
29 case Tuns8:
30 case Tchar:
31 return (const llvm::Type*)llvm::Type::Int8Ty;
32 case Tint16:
33 case Tuns16:
34 case Twchar:
35 return (const llvm::Type*)llvm::Type::Int16Ty;
36 case Tint32:
37 case Tuns32:
38 case Tdchar:
39 return (const llvm::Type*)llvm::Type::Int32Ty;
40 case Tint64:
41 case Tuns64:
42 return (const llvm::Type*)llvm::Type::Int64Ty;
43
44 case Tbool:
45 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType();
46
47 // floats
48 case Tfloat32:
49 return llvm::Type::FloatTy;
50 case Tfloat64:
51 case Tfloat80:
52 return llvm::Type::DoubleTy;
53
54 // pointers
55 case Tpointer: {
56 assert(t->next);
57 if (t->next->ty == Tvoid)
58 return (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
59 else
60 return (const llvm::Type*)llvm::PointerType::get(LLVM_DtoType(t->next));
61 }
62
63 // arrays
64 case Tarray:
65 return LLVM_DtoArrayType(t);
66 case Tsarray:
67 return LLVM_DtoStaticArrayType(t);
68
69 // void
70 case Tvoid:
71 return llvm::Type::VoidTy;
72
73 // aggregates
74 case Tstruct: {
75 if (t->llvmType == 0)
76 {
77 // recursive or cyclic declaration
78 if (!gIR->structs.empty())
79 {
80 IRStruct* found = 0;
81 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
82 {
83 if (t == i->type)
84 {
85 return i->recty.get();
86 }
87 }
88 }
89
90 // forward declaration
91 TypeStruct* ts = (TypeStruct*)t;
92 assert(ts->sym);
93 ts->sym->toObjFile();
94 }
95 return t->llvmType;
96 }
97
98 case Tclass: {
99 if (t->llvmType == 0)
100 {
101 TypeClass* tc = (TypeClass*)t;
102 assert(tc->sym);
103 if (!tc->sym->llvmInProgress) {
104 tc->sym->toObjFile();
105 }
106 else {
107 //assert(0 && "circular class referencing");
108 return llvm::OpaqueType::get();
109 }
110 }
111 return llvm::PointerType::get(t->llvmType);
112 }
113
114 // functions
115 case Tfunction:
116 {
117 if (t->llvmType == 0) {
118 return LLVM_DtoFunctionType(t);
119 }
120 else {
121 return t->llvmType;
122 }
123 }
124
125 // delegates
126 case Tdelegate:
127 {
128 if (t->llvmType == 0) {
129 return LLVM_DtoDelegateType(t);
130 }
131 else {
132 return t->llvmType;
133 }
134 }
135
136 // typedefs
137 case Ttypedef:
138 {
139 Type* bt = t->toBasetype();
140 assert(bt);
141 return LLVM_DtoType(bt);
142 }
143
144 default:
145 printf("trying to convert unknown type with value %d\n", t->ty);
146 assert(0);
147 }
148 return 0;
149 }
150
151 //////////////////////////////////////////////////////////////////////////////////////////
152
153 llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
154 {
155 TypeFunction* f = (TypeFunction*)t;
156
157 // parameter types
158 const llvm::Type* rettype;
159 std::vector<const llvm::Type*> paramvec;
160
161 TY retty = f->next->ty;
162
163 if (retty == Tstruct || retty == Tdelegate || retty == Tarray) {
164 rettype = llvm::PointerType::get(LLVM_DtoType(f->next));
165 paramvec.push_back(rettype);
166 rettype = llvm::Type::VoidTy;
167 }
168 else {
169 Type* rt = f->next;
170 if (rt)
171 rettype = LLVM_DtoType(rt);
172 else
173 assert(0);
174 }
175
176 if (thisparam) {
177 paramvec.push_back(thisparam);
178 }
179
180 size_t n = Argument::dim(f->parameters);
181 for (int i=0; i < n; ++i) {
182 Argument* arg = Argument::getNth(f->parameters, i);
183 // ensure scalar
184 Type* argT = arg->type;
185 assert(argT);
186 paramvec.push_back(LLVM_DtoType(argT));
187 }
188
189 Logger::cout() << "Return type: " << *rettype << '\n';
190
191 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, paramvec, f->varargs);
192 return functype;
193 }
194
195 //////////////////////////////////////////////////////////////////////////////////////////
196
197 llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
198 {
199 TypeFunction* f = (TypeFunction*)fdecl->type;
200 assert(f != 0);
201
202 // has already been pulled in by a reference to (
203 if (f->llvmType != 0) {
204 return llvm::cast<llvm::FunctionType>(f->llvmType);
205 }
206
207 // return value type
208 const llvm::Type* rettype;
209 const llvm::Type* actualRettype;
210 Type* rt = f->next;
211 bool retinptr = false;
212 bool usesthis = false;
213
214 if (fdecl->isMain()) {
215 rettype = llvm::Type::Int32Ty;
216 actualRettype = rettype;
217 }
218 else if (rt) {
219 if (rt->ty == Tstruct || rt->ty == Tdelegate || rt->ty == Tarray) {
220 rettype = llvm::PointerType::get(LLVM_DtoType(rt));
221 actualRettype = llvm::Type::VoidTy;
222 f->llvmRetInPtr = retinptr = true;
223 }
224 else {
225 rettype = LLVM_DtoType(rt);
226 actualRettype = rettype;
227 }
228 }
229 else {
230 assert(0);
231 }
232
233 // parameter types
234 std::vector<const llvm::Type*> paramvec;
235
236 if (retinptr) {
237 Logger::print("returning through pointer parameter\n");
238 paramvec.push_back(rettype);
239 }
240
241 if (fdecl->needThis() && fdecl->vthis) {
242 Logger::print("this is: %s\n", fdecl->vthis->type->toChars());
243 paramvec.push_back(LLVM_DtoType(fdecl->vthis->type));
244 usesthis = true;
245 }
246
247 size_t n = Argument::dim(f->parameters);
248 for (int i=0; i < n; ++i) {
249 Argument* arg = Argument::getNth(f->parameters, i);
250 // ensure scalar
251 Type* argT = arg->type;
252 assert(argT);
253
254 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) {
255 //assert(arg->vardecl);
256 //arg->vardecl->refparam = true;
257 }
258 else
259 arg->llvmCopy = true;
260
261 const llvm::Type* at = LLVM_DtoType(argT);
262 if (llvm::isa<llvm::StructType>(at)) {
263 Logger::println("struct param");
264 paramvec.push_back(llvm::PointerType::get(at));
265 }
266 else if (llvm::isa<llvm::ArrayType>(at)) {
267 Logger::println("sarray param");
268 assert(argT->ty == Tsarray);
269 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0)));
270 paramvec.push_back(llvm::PointerType::get(at));
271 }
272 else {
273 if (!arg->llvmCopy) {
274 Logger::println("ref param");
275 at = llvm::PointerType::get(at);
276 }
277 else {
278 Logger::println("in param");
279 }
280 paramvec.push_back(at);
281 }
282 }
283
284 // construct function type
285 bool isvararg = f->varargs;
286 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
287
288 f->llvmType = functype;
289 return functype;
290 }
291
292 //////////////////////////////////////////////////////////////////////////////////////////
293
294 llvm::StructType* LLVM_DtoDelegateType(Type* t)
295 {
296 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty);
297 const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr);
298 const llvm::Type* funcptr = llvm::PointerType::get(func);
299
300 std::vector<const llvm::Type*> types;
301 types.push_back(i8ptr);
302 types.push_back(funcptr);
303 return llvm::StructType::get(types);
304 }
305
306 //////////////////////////////////////////////////////////////////////////////////////////
307
308 llvm::Type* LLVM_DtoStructType(Type* t)
309 {
310 assert(0);
311 std::vector<const llvm::Type*> types;
312 return llvm::StructType::get(types);
313 }
314
315 //////////////////////////////////////////////////////////////////////////////////////////
316
317 llvm::StructType* LLVM_DtoArrayType(Type* t)
318 {
319 assert(t->next);
320 const llvm::Type* at = LLVM_DtoType(t->next);
321 const llvm::Type* arrty;
322
323 /*if (t->ty == Tsarray) {
324 TypeSArray* tsa = (TypeSArray*)t;
325 assert(tsa->dim->type->isintegral());
326 arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
327 }
328 else {
329 arrty = llvm::ArrayType::get(at,0);
330 }*/
331 if (at == llvm::Type::VoidTy) {
332 at = llvm::Type::Int8Ty;
333 }
334 arrty = llvm::PointerType::get(at);
335
336 std::vector<const llvm::Type*> members;
337 if (global.params.is64bit)
338 members.push_back(llvm::Type::Int64Ty);
339 else
340 members.push_back(llvm::Type::Int32Ty);
341
342 members.push_back(arrty);
343
344 return llvm::StructType::get(members);
345 }
346
347 //////////////////////////////////////////////////////////////////////////////////////////
348
349 llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
350 {
351 if (t->llvmType)
352 return llvm::cast<llvm::ArrayType>(t->llvmType);
353
354 assert(t->ty == Tsarray);
355 assert(t->next);
356
357 const llvm::Type* at = LLVM_DtoType(t->next);
358
359 TypeSArray* tsa = (TypeSArray*)t;
360 assert(tsa->dim->type->isintegral());
361 llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
362
363 tsa->llvmType = arrty;
364 return arrty;
365 }
366
367 //////////////////////////////////////////////////////////////////////////////////////////
368
369 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false)
370 {
371 assert(bits == 32 || bits == 64);
372 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty;
373 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty;
374 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty;
375 const llvm::Type* int8ptrty = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
376 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy;
377
378 assert(gIR);
379 assert(gIR->module);
380
381 // parameter types
382 std::vector<const llvm::Type*> pvec;
383 pvec.push_back(int8ptrty);
384 pvec.push_back(set?int8ty:int8ptrty);
385 pvec.push_back(bits==32?int32ty:int64ty);
386 pvec.push_back(int32ty);
387 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false);
388 return new llvm::Function(functype, llvm::GlobalValue::ExternalLinkage, name, gIR->module);
389 }
390
391 //////////////////////////////////////////////////////////////////////////////////////////
392
393 // llvm.memset.i32
394 static llvm::Function* LLVM_DeclareMemSet32()
395 {
396 static llvm::Function* _func = 0;
397 if (_func == 0) {
398 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true);
399 }
400 return _func;
401 }
402
403 //////////////////////////////////////////////////////////////////////////////////////////
404
405 static llvm::Function* LLVM_DeclareMemSet64()
406 {
407 static llvm::Function* _func = 0;
408 if (_func == 0) {
409 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true);
410 }
411 return _func;
412 }
413
414 //////////////////////////////////////////////////////////////////////////////////////////
415
416 // llvm.memcpy.i32
417 static llvm::Function* LLVM_DeclareMemCpy32()
418 {
419 static llvm::Function* _func = 0;
420 if (_func == 0) {
421 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32);
422 }
423 return _func;
424 }
425
426 //////////////////////////////////////////////////////////////////////////////////////////
427
428 // llvm.memcpy.i64
429 static llvm::Function* LLVM_DeclareMemCpy64()
430 {
431 static llvm::Function* _func = 0;
432 if (_func == 0) {
433 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64);
434 }
435 return _func;
436 }
437
438 //////////////////////////////////////////////////////////////////////////////////////////
439
440 llvm::Value* LLVM_DtoStructZeroInit(TypeStruct* t, llvm::Value* v)
441 {
442 assert(gIR);
443 uint64_t n = gTargetData->getTypeSize(t->llvmType);
444 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
445 llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty);
446
447 llvm::Value* sarr = new llvm::BitCastInst(v,sarrty,"tmp",gIR->scopebb());
448
449 llvm::Function* fn = LLVM_DeclareMemSet32();
450 std::vector<llvm::Value*> llargs;
451 llargs.resize(4);
452 llargs[0] = sarr;
453 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
454 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
455 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
456
457 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
458
459 return ret;
460 }
461
462 //////////////////////////////////////////////////////////////////////////////////////////
463
464 llvm::Value* LLVM_DtoStructCopy(TypeStruct* t, llvm::Value* dst, llvm::Value* src)
465 {
466 assert(dst->getType() == src->getType());
467 assert(gIR);
468
469 uint64_t n = gTargetData->getTypeSize(t->llvmType);
470 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n));
471 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
472
473 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
474 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
475
476 llvm::Function* fn = LLVM_DeclareMemCpy32();
477 std::vector<llvm::Value*> llargs;
478 llargs.resize(4);
479 llargs[0] = dstarr;
480 llargs[1] = srcarr;
481 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
482 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
483
484 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
485 }
486
487 //////////////////////////////////////////////////////////////////////////////////////////
488 llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si)
489 {
490 llvm::StructType* structtype = llvm::cast<llvm::StructType>(si->ad->llvmType);
491 size_t n = structtype->getNumElements();
492
493 assert(si->value.dim == si->vars.dim);
494
495 std::vector<llvm::Constant*> inits;
496 inits.resize(n, NULL);
497 for (int i = 0; i < si->value.dim; ++i)
498 {
499 Initializer* ini = (Initializer*)si->value.data[i];
500 assert(ini);
501
502 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
503 assert(vd);
504 Logger::println("vars[%d] = %s", i, vd->toChars());
505 unsigned idx = si->ad->offsetToIndex(vd->offset);
506
507 llvm::Constant* v = 0;
508
509 if (ExpInitializer* ex = ini->isExpInitializer())
510 {
511 elem* e = ex->exp->toElem(gIR);
512 v = llvm::cast<llvm::Constant>(e->val);
513 delete e;
514 }
515 else if (StructInitializer* si = ini->isStructInitializer())
516 {
517 v = LLVM_DtoStructInitializer(si);
518 }
519 else if (ArrayInitializer* ai = ini->isArrayInitializer())
520 {
521 v = LLVM_DtoArrayInitializer(ai);
522 }
523 else if (ini->isVoidInitializer())
524 {
525 v = llvm::UndefValue::get(structtype->getElementType(idx));
526 }
527 else
528 assert(v);
529
530 inits[idx] = v;
531 }
532
533 // fill out nulls
534 assert(si->ad->llvmInitZ);
535 if (si->ad->llvmInitZ->isNullValue())
536 {
537 for (int i = 0; i < n; ++i)
538 {
539 if (inits[i] == 0)
540 {
541 inits[i] = llvm::Constant::getNullValue(structtype->getElementType(i));
542 }
543 }
544 }
545 else
546 {
547 for (int i = 0; i < n; ++i)
548 {
549 if (inits[i] == 0)
550 {
551 inits[i] = si->ad->llvmInitZ->getOperand(i);
552 }
553 }
554 }
555
556 return llvm::ConstantStruct::get(structtype, inits);
557 }
558
559 //////////////////////////////////////////////////////////////////////////////////////////
560
561 llvm::Value* LLVM_DtoNullArray(llvm::Value* v)
562 {
563 assert(gIR);
564 d_uns64 n = (global.params.is64bit) ? 16 : 8;
565
566 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
567
568 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
569
570 llvm::Function* fn = LLVM_DeclareMemSet32();
571 std::vector<llvm::Value*> llargs;
572 llargs.resize(4);
573 llargs[0] = arr;
574 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
575 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
576 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
577
578 //Logger::cout() << *fn << '|' << *fn->getType() << '\n';
579 //Logger::cout() << "to null array call: " << *llargs[0] << '|' << *llargs[1] << '|' << *llargs[2] << '|' << *llargs[3] << '\n';
580
581 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
582
583 return ret;
584 }
585
586 //////////////////////////////////////////////////////////////////////////////////////////
587
588 llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v)
589 {
590 assert(gIR);
591 d_uns64 n = (global.params.is64bit) ? 16 : 8;
592
593 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty);
594
595 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb());
596
597 llvm::Function* fn = LLVM_DeclareMemSet32();
598 std::vector<llvm::Value*> llargs;
599 llargs.resize(4);
600 llargs[0] = arr;
601 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false);
602 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
603 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
604
605 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
606
607 return ret;
608 }
609
610 //////////////////////////////////////////////////////////////////////////////////////////
611
612 llvm::Value* LLVM_DtoDelegateCopy(llvm::Value* dst, llvm::Value* src)
613 {
614 assert(dst->getType() == src->getType());
615 assert(gIR);
616
617 d_uns64 n = (global.params.is64bit) ? 16 : 8;
618
619 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
620
621 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
622 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
623
624 llvm::Function* fn = LLVM_DeclareMemCpy32();
625 std::vector<llvm::Value*> llargs;
626 llargs.resize(4);
627 llargs[0] = dstarr;
628 llargs[1] = srcarr;
629 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
630 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
631
632 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
633 }
634
635 //////////////////////////////////////////////////////////////////////////////////////////
636
637 llvm::Value* LLVM_DtoArrayAssign(llvm::Value* dst, llvm::Value* src)
638 {
639 assert(gIR);
640 if (dst->getType() == src->getType())
641 {
642 d_uns64 n = (global.params.is64bit) ? 16 : 8;
643
644 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
645
646 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
647 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
648
649 llvm::Function* fn = LLVM_DeclareMemCpy32();
650 std::vector<llvm::Value*> llargs;
651 llargs.resize(4);
652 llargs[0] = dstarr;
653 llargs[1] = srcarr;
654 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
655 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
656
657 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
658 }
659 else
660 {
661 if (!llvm::isa<llvm::ArrayType>(src->getType()->getContainedType(0)))
662 {
663 Logger::cout() << "invalid: " << *src << '\n';
664 assert(0);
665 }
666 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(src->getType()->getContainedType(0));
667 llvm::Type* dstty = llvm::PointerType::get(arrty->getElementType());
668
669 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
670 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
671
672 llvm::Value* dstlen = new llvm::GetElementPtrInst(dst,zero,zero,"tmp",gIR->scopebb());
673 llvm::Value* srclen = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
674 new llvm::StoreInst(srclen, dstlen, gIR->scopebb());
675
676 llvm::Value* dstptr = new llvm::GetElementPtrInst(dst,zero,one,"tmp",gIR->scopebb());
677 llvm::Value* srcptr = new llvm::BitCastInst(src,dstty,"tmp",gIR->scopebb());
678 new llvm::StoreInst(srcptr, dstptr, gIR->scopebb());
679 }
680 }
681
682 //////////////////////////////////////////////////////////////////////////////////////////
683
684 void LLVM_DtoArrayInit(llvm::Value* l, llvm::Value* r)
685 {
686 const llvm::PointerType* ptrty = llvm::cast<llvm::PointerType>(l->getType());
687 if (llvm::isa<llvm::ArrayType>(ptrty->getContainedType(0)))
688 {
689 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(ptrty->getContainedType(0));
690 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
691
692 std::vector<llvm::Value*> args;
693 args.resize(3);
694 args[0] = new llvm::GetElementPtrInst(l,zero,zero,"tmp",gIR->scopebb());
695 args[1] = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
696 args[2] = r;
697
698 const char* funcname = NULL;
699
700 if (llvm::isa<llvm::PointerType>(arrty->getElementType())) {
701 funcname = "_d_array_init_pointer";
702
703 const llvm::Type* dstty = llvm::PointerType::get(llvm::PointerType::get(llvm::Type::Int8Ty));
704 if (args[0]->getType() != dstty)
705 args[0] = new llvm::BitCastInst(args[0],dstty,"tmp",gIR->scopebb());
706
707 const llvm::Type* valty = llvm::PointerType::get(llvm::Type::Int8Ty);
708 if (args[2]->getType() != valty)
709 args[2] = new llvm::BitCastInst(args[2],valty,"tmp",gIR->scopebb());
710 }
711 else if (r->getType() == llvm::Type::Int1Ty) {
712 funcname = "_d_array_init_i1";
713 }
714 else if (r->getType() == llvm::Type::Int8Ty) {
715 funcname = "_d_array_init_i8";
716 }
717 else if (r->getType() == llvm::Type::Int16Ty) {
718 funcname = "_d_array_init_i16";
719 }
720 else if (r->getType() == llvm::Type::Int32Ty) {
721 funcname = "_d_array_init_i32";
722 }
723 else if (r->getType() == llvm::Type::Int64Ty) {
724 funcname = "_d_array_init_i64";
725 }
726 else if (r->getType() == llvm::Type::FloatTy) {
727 funcname = "_d_array_init_float";
728 }
729 else if (r->getType() == llvm::Type::DoubleTy) {
730 funcname = "_d_array_init_double";
731 }
732 else {
733 assert(0);
734 }
735
736 Logger::cout() << *args[0] << '|' << *args[2] << '\n';
737
738 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
739 assert(fn);
740 llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
741 call->setCallingConv(llvm::CallingConv::C);
742
743 Logger::println("array init call ok");
744 }
745 else if (llvm::isa<llvm::StructType>(ptrty->getContainedType(0)))
746 {
747 assert(0 && "Only static arrays support initialisers atm");
748 }
749 else
750 assert(0);
751 }
752
753 //////////////////////////////////////////////////////////////////////////////////////////
754
755 void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr)
756 {
757 const llvm::StructType* st = llvm::cast<llvm::StructType>(arr->getType()->getContainedType(0));
758 //const llvm::PointerType* pt = llvm::cast<llvm::PointerType>(r->getType());
759
760 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
761 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
762
763 llvm::Value* arrdim = new llvm::GetElementPtrInst(arr,zero,zero,"tmp",gIR->scopebb());
764 new llvm::StoreInst(dim, arrdim, gIR->scopebb());
765
766 llvm::Value* arrptr = new llvm::GetElementPtrInst(arr,zero,one,"tmp",gIR->scopebb());
767 new llvm::StoreInst(ptr, arrptr, gIR->scopebb());
768 }
769
770 //////////////////////////////////////////////////////////////////////////////////////////
771 llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* arrinit)
772 {
773 Logger::println("arr init begin");
774 assert(arrinit->type->ty == Tsarray);
775 TypeSArray* t = (TypeSArray*)arrinit->type;
776 integer_t tdim = t->dim->toInteger();
777
778 std::vector<llvm::Constant*> inits(tdim, 0);
779
780 const llvm::Type* elemty = LLVM_DtoType(arrinit->type->next);
781
782 assert(arrinit->index.dim == arrinit->value.dim);
783 for (int i=0,j=0; i < tdim; ++i)
784 {
785 Initializer* init = 0;
786 Expression* idx = (Expression*)arrinit->index.data[j];
787
788 if (idx)
789 {
790 integer_t k = idx->toInteger();
791 if (i == k)
792 {
793 init = (Initializer*)arrinit->value.data[j];
794 assert(init);
795 ++j;
796 }
797 }
798 else
799 {
800 init = (Initializer*)arrinit->value.data[j];
801 ++j;
802 }
803
804 llvm::Constant* v = 0;
805
806 if (!init)
807 {
808 elem* e = t->next->defaultInit()->toElem(gIR);
809 v = llvm::cast<llvm::Constant>(e->val);
810 delete e;
811 }
812 else if (ExpInitializer* ex = init->isExpInitializer())
813 {
814 elem* e = ex->exp->toElem(gIR);
815 v = llvm::cast<llvm::Constant>(e->val);
816 delete e;
817 }
818 else if (StructInitializer* si = init->isStructInitializer())
819 {
820 v = LLVM_DtoStructInitializer(si);
821 }
822 else if (ArrayInitializer* ai = init->isArrayInitializer())
823 {
824 v = LLVM_DtoArrayInitializer(ai);
825 }
826 else if (init->isVoidInitializer())
827 {
828 v = llvm::UndefValue::get(elemty);
829 }
830 else
831 assert(v);
832
833 inits[i] = v;
834 }
835
836 llvm::ArrayType* arrty = LLVM_DtoStaticArrayType(t);
837 return llvm::ConstantArray::get(arrty, inits);
838 }
839
840 //////////////////////////////////////////////////////////////////////////////////////////
841 void LLVM_DtoArrayCopy(elem* dst, elem* src)
842 {
843 assert(0);
844 }
845
846 //////////////////////////////////////////////////////////////////////////////////////////
847
848 llvm::GlobalValue::LinkageTypes LLVM_DtoLinkage(PROT prot, uint stc)
849 {
850 switch(prot)
851 {
852 case PROTprivate:
853 return llvm::GlobalValue::InternalLinkage;
854
855 case PROTpublic:
856 case PROTpackage:
857 case PROTprotected:
858 case PROTexport:
859 return llvm::GlobalValue::ExternalLinkage;
860
861 case PROTundefined:
862 case PROTnone:
863 assert(0 && "Unsupported linkage type");
864 }
865 return llvm::GlobalValue::ExternalLinkage;
866
867 /* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage,
868 InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage,
869 GhostLinkage */
870 }
871
872 //////////////////////////////////////////////////////////////////////////////////////////
873
874 unsigned LLVM_DtoCallingConv(LINK l)
875 {
876 if (l == LINKc)
877 return llvm::CallingConv::C;
878 else if (l == LINKd || l == LINKdefault)
879 return llvm::CallingConv::Fast;
880 else if (l == LINKwindows)
881 return llvm::CallingConv::X86_StdCall;
882 else
883 assert(0 && "Unsupported calling convention");
884 }
885
886 //////////////////////////////////////////////////////////////////////////////////////////
887
888 llvm::Value* LLVM_DtoPointedType(llvm::Value* ptr, llvm::Value* val)
889 {
890 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0);
891 const llvm::Type* valTy = val->getType();
892 // ptr points to val's type
893 if (ptrTy == valTy)
894 {
895 return val;
896 }
897 // ptr is integer pointer
898 else if (ptrTy->isInteger())
899 {
900 // val is integer
901 assert(valTy->isInteger());
902 const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy);
903 const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy);
904 if (pt->getBitWidth() < vt->getBitWidth()) {
905 return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb());
906 }
907 else
908 assert(0);
909 }
910 // something else unsupported
911 else
912 {
913 Logger::cout() << *ptrTy << '|' << *valTy << '\n';
914 assert(0);
915 }
916 return 0;
917 }
918
919 //////////////////////////////////////////////////////////////////////////////////////////
920
921 llvm::Value* LLVM_DtoBoolean(llvm::Value* val)
922 {
923 const llvm::Type* t = val->getType();
924 if (t->isInteger())
925 {
926 if (t == llvm::Type::Int1Ty)
927 return val;
928 else {
929 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false);
930 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb());
931 }
932 }
933 else if (llvm::isa<llvm::PointerType>(t)) {
934 const llvm::Type* st = LLVM_DtoSize_t();
935 llvm::Value* ptrasint = new llvm::PtrToIntInst(val,st,"tmp",gIR->scopebb());
936 llvm::Value* zero = llvm::ConstantInt::get(st, 0, false);
937 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, ptrasint, zero, "tmp", gIR->scopebb());
938 }
939 else
940 {
941 Logger::cout() << *t << '\n';
942 }
943 assert(0);
944 return 0;
945 }
946
947 //////////////////////////////////////////////////////////////////////////////////////////
948
949 const llvm::Type* LLVM_DtoSize_t()
950 {
951 if (global.params.is64bit)
952 return llvm::Type::Int64Ty;
953 else
954 return llvm::Type::Int32Ty;
955 }
956
957 //////////////////////////////////////////////////////////////////////////////////////////
958
959 void LLVM_DtoMain()
960 {
961 // emit main function llvm style
962 // int main(int argc, char**argv, char**env);
963
964 assert(gIR != 0);
965 IRState& ir = *gIR;
966
967 assert(ir.emitMain && ir.mainFunc);
968
969 // parameter types
970 std::vector<const llvm::Type*> pvec;
971 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty);
972 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
973 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
974 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
975 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty;
976
977 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false);
978 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module);
979
980 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func);
981
982 // call static ctors
983 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors");
984 new llvm::CallInst(fn,"",bb);
985
986 // call user main function
987 llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb);
988 call->setCallingConv(ir.mainFunc->getCallingConv());
989
990 // call static dtors
991 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors");
992 new llvm::CallInst(fn,"",bb);
993
994 // return
995 new llvm::ReturnInst(call,bb);
996
997 /*
998 // return value type
999 const llvm::Type* rettype;
1000 Type* rt = f->next;
1001 if (rt) {
1002 rettype = LLVM_DtoType(rt);
1003 }
1004 else {
1005 assert(0);
1006 }
1007
1008 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, paramvec, false);
1009 */
1010 }
1011
1012 //////////////////////////////////////////////////////////////////////////////////////////
1013
1014 void LLVM_DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
1015 {
1016 Array* arr = &tc->sym->dtors;
1017 for (size_t i=0; i<arr->dim; i++)
1018 {
1019 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
1020 assert(fd->llvmValue);
1021 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
1022 }
1023 }
1024
1025 //////////////////////////////////////////////////////////////////////////////////////////
1026
1027 void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst)
1028 {
1029 assert(tc->llvmInit);
1030 assert(dst->getType() == tc->llvmInit->getType());
1031 assert(gIR);
1032
1033 assert(tc->llvmType);
1034 uint64_t n = gTargetData->getTypeSize(tc->llvmType);
1035 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
1036
1037 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
1038 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
1039
1040 llvm::Function* fn = LLVM_DeclareMemCpy32();
1041 std::vector<llvm::Value*> llargs;
1042 llargs.resize(4);
1043 llargs[0] = dstarr;
1044 llargs[1] = srcarr;
1045 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
1046 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
1047
1048 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
1049 }
1050
1051 //////////////////////////////////////////////////////////////////////////////////////////
1052
1053 llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
1054 {
1055 llvm::Constant* _init = 0;
1056 if (!init)
1057 {
1058 elem* e = type->defaultInit()->toElem(gIR);
1059 if (!e->inplace && !e->isNull()) {
1060 _init = llvm::cast<llvm::Constant>(e->getValue());
1061 }
1062 delete e;
1063 }
1064 else if (ExpInitializer* ex = init->isExpInitializer())
1065 {
1066 elem* e = ex->exp->toElem(gIR);
1067 if (!e->inplace && !e->isNull()) {
1068 _init = llvm::cast<llvm::Constant>(e->getValue());
1069 }
1070 delete e;
1071 }
1072 else if (StructInitializer* si = init->isStructInitializer())
1073 {
1074 _init = LLVM_DtoStructInitializer(si);
1075 }
1076 else if (ArrayInitializer* ai = init->isArrayInitializer())
1077 {
1078 _init = LLVM_DtoArrayInitializer(ai);
1079 }
1080 else if (init->isVoidInitializer())
1081 {
1082 const llvm::Type* ty = LLVM_DtoType(type);
1083 _init = llvm::Constant::getNullValue(ty);
1084 }
1085 else {
1086 Logger::println("unsupported initializer: %s", init->toChars());
1087 }
1088 return _init;
1089 }