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 }