Mercurial > projects > ldc
comparison gen/functions.cpp @ 920:545f54041d91
Implemented proper support for naked asm using llvm module level asm. Still not 100% complete, but already 1000 times better that what we had before. Don's BignumX86 implementation from Tango (when turned into a standalone unittest) seems to fully work with no changes, and great performance :)
Fixed align N; in asm blocks.
Fixed inreg parameter passing on x86 for ref/out params.
Removed support for lazy initialization of function local static variables, I have no idea why I ever implemented this, it's not in the D spec, and DMD doesn't support it :P
Some of the global variable related changes might cause minor regressions, but they should be easily fixable.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Tue, 03 Feb 2009 08:54:57 +0100 |
parents | 94ba810ea2b0 |
children | 7985bb036db4 |
comparison
equal
deleted
inserted
replaced
919:c76f74d09fb1 | 920:545f54041d91 |
---|---|
207 // otherwise check the first formal parameter | 207 // otherwise check the first formal parameter |
208 else | 208 else |
209 { | 209 { |
210 Type* t = arg->type->toBasetype(); | 210 Type* t = arg->type->toBasetype(); |
211 | 211 |
212 // 32bit ints, pointers, classes, static arrays and AAs | 212 // 32bit ints, pointers, classes, static arrays, AAs, ref and out params |
213 // are candidate for being passed in EAX | 213 // are candidate for being passed in EAX |
214 if ((arg->storageClass & STCin) && | 214 if ( |
215 ((t->isscalar() && !t->isfloating()) || | 215 (arg->storageClass & (STCref|STCout)) |
216 || | |
217 ((arg->storageClass & STCin) && | |
218 ((t->isscalar() && !t->isfloating()) || | |
216 t->ty == Tclass || t->ty == Tsarray || t->ty == Taarray) && | 219 t->ty == Tclass || t->ty == Tsarray || t->ty == Taarray) && |
217 (t->size() <= PTRSIZE)) | 220 (t->size() <= PTRSIZE)) |
221 ) | |
218 { | 222 { |
219 arg->llvmAttrs |= llvm::Attribute::InReg; | 223 arg->llvmAttrs |= llvm::Attribute::InReg; |
220 assert((f->thisAttrs & llvm::Attribute::InReg) == 0 && "can't have two inreg args!"); | 224 assert((f->thisAttrs & llvm::Attribute::InReg) == 0 && "can't have two inreg args!"); |
221 } | 225 } |
222 } | 226 } |
616 Logger::cout() << "func decl: " << *func << '\n'; | 620 Logger::cout() << "func decl: " << *func << '\n'; |
617 } | 621 } |
618 | 622 |
619 ////////////////////////////////////////////////////////////////////////////////////////// | 623 ////////////////////////////////////////////////////////////////////////////////////////// |
620 | 624 |
621 void DtoDefineFunc(FuncDeclaration* fd) | 625 void DtoDefineFunction(FuncDeclaration* fd) |
622 { | 626 { |
623 if (fd->ir.defined) return; | 627 if (fd->ir.defined) return; |
624 fd->ir.defined = true; | 628 fd->ir.defined = true; |
625 | 629 |
626 assert(fd->ir.declared); | 630 assert(fd->ir.declared); |
627 | 631 |
628 Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); | 632 Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars()); |
629 LOG_SCOPE; | 633 LOG_SCOPE; |
634 | |
635 // if this function is naked, we take over right away! no standard processing! | |
636 if (fd->naked) | |
637 { | |
638 DtoDefineNakedFunction(fd); | |
639 return; | |
640 } | |
630 | 641 |
631 // debug info | 642 // debug info |
632 if (global.params.symdebug) { | 643 if (global.params.symdebug) { |
633 Module* mo = fd->getModule(); | 644 Module* mo = fd->getModule(); |
634 fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd); | 645 fd->ir.irFunc->dwarfSubProg = DtoDwarfSubProgram(fd); |
682 fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), "function_vresult"); | 693 fd->vresult->ir.irLocal->value = DtoAlloca(DtoType(fd->vresult->type), "function_vresult"); |
683 } | 694 } |
684 | 695 |
685 // this hack makes sure the frame pointer elimination optimization is disabled. | 696 // this hack makes sure the frame pointer elimination optimization is disabled. |
686 // this this eliminates a bunch of inline asm related issues. | 697 // this this eliminates a bunch of inline asm related issues. |
687 // naked must always eliminate the framepointer however... | 698 if (fd->inlineAsm) |
688 if (fd->inlineAsm && !fd->naked) | |
689 { | 699 { |
690 // emit a call to llvm_eh_unwind_init | 700 // emit a call to llvm_eh_unwind_init |
691 LLFunction* hack = GET_INTRINSIC_DECL(eh_unwind_init); | 701 LLFunction* hack = GET_INTRINSIC_DECL(eh_unwind_init); |
692 gIR->ir->CreateCall(hack, ""); | 702 gIR->ir->CreateCall(hack, ""); |
693 } | 703 } |