Mercurial > projects > ldc
diff gen/functions.cpp @ 720:e177ae483f8e
Added inreg attribute where appropriate on x86 to follow ABI docs.
Removed now unnecessary temporary variable in StringExp.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Thu, 23 Oct 2008 00:34:46 +0200 |
parents | 7261ff0f95ff |
children | 55f6c2e454d7 |
line wrap: on
line diff
--- a/gen/functions.cpp Wed Oct 22 21:50:08 2008 +0200 +++ b/gen/functions.cpp Thu Oct 23 00:34:46 2008 +0200 @@ -171,6 +171,39 @@ bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); + // tell first param to be passed in a register if we can + // ONLY extern(D) functions ! + if ((n > 0 || usesthis || usesnest) && f->linkage == LINKd) + { + // FIXME: Only x86 right now ... + if (global.params.cpu == ARCHx86) + { + // pass first param in EAX if it fits, is not floating point and is not a 3 byte struct. + // FIXME: struct are not passed in EAX yet + + // if there is a implicit context parameter, pass it in EAX + if (usesthis || usesnest) + { + f->thisAttrs |= llvm::Attribute::InReg; + } + // otherwise check the first formal parameter + else + { + Argument* arg = Argument::getNth(f->parameters, 0); + Type* t = arg->type->toBasetype(); + + // 32bit ints, pointers, classes and static arrays are candidate for being passed in EAX + if ((arg->storageClass & STCin) && + ((t->isscalar() && !t->isfloating()) || t->ty == Tclass || t->ty == Tsarray) && + (t->size() <= PTRSIZE)) + { + arg->llvmAttrs |= llvm::Attribute::InReg; + } + } + } + } + + // done f->retInPtr = retinptr; f->usesThis = usesthis; f->usesNest = usesnest; @@ -350,6 +383,14 @@ attrs.push_back(PAWI); } + // set this/nest param attrs + if (f->thisAttrs) + { + PAWI.Index = f->retInPtr ? 2 : 1; + PAWI.Attrs = f->thisAttrs; + attrs.push_back(PAWI); + } + // set attrs on the rest of the arguments for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) {