Mercurial > projects > ldc
comparison 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 |
comparison
equal
deleted
inserted
replaced
719:7261ff0f95ff | 720:e177ae483f8e |
---|---|
169 | 169 |
170 // construct function type | 170 // construct function type |
171 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; | 171 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; |
172 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); | 172 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); |
173 | 173 |
174 // tell first param to be passed in a register if we can | |
175 // ONLY extern(D) functions ! | |
176 if ((n > 0 || usesthis || usesnest) && f->linkage == LINKd) | |
177 { | |
178 // FIXME: Only x86 right now ... | |
179 if (global.params.cpu == ARCHx86) | |
180 { | |
181 // pass first param in EAX if it fits, is not floating point and is not a 3 byte struct. | |
182 // FIXME: struct are not passed in EAX yet | |
183 | |
184 // if there is a implicit context parameter, pass it in EAX | |
185 if (usesthis || usesnest) | |
186 { | |
187 f->thisAttrs |= llvm::Attribute::InReg; | |
188 } | |
189 // otherwise check the first formal parameter | |
190 else | |
191 { | |
192 Argument* arg = Argument::getNth(f->parameters, 0); | |
193 Type* t = arg->type->toBasetype(); | |
194 | |
195 // 32bit ints, pointers, classes and static arrays are candidate for being passed in EAX | |
196 if ((arg->storageClass & STCin) && | |
197 ((t->isscalar() && !t->isfloating()) || t->ty == Tclass || t->ty == Tsarray) && | |
198 (t->size() <= PTRSIZE)) | |
199 { | |
200 arg->llvmAttrs |= llvm::Attribute::InReg; | |
201 } | |
202 } | |
203 } | |
204 } | |
205 | |
206 // done | |
174 f->retInPtr = retinptr; | 207 f->retInPtr = retinptr; |
175 f->usesThis = usesthis; | 208 f->usesThis = usesthis; |
176 f->usesNest = usesnest; | 209 f->usesNest = usesnest; |
177 | 210 |
178 f->ir.type = new llvm::PATypeHolder(functype); | 211 f->ir.type = new llvm::PATypeHolder(functype); |
345 // set sret param | 378 // set sret param |
346 if (f->retInPtr) | 379 if (f->retInPtr) |
347 { | 380 { |
348 PAWI.Index = 1; | 381 PAWI.Index = 1; |
349 PAWI.Attrs = llvm::Attribute::StructRet; | 382 PAWI.Attrs = llvm::Attribute::StructRet; |
383 attrs.push_back(PAWI); | |
384 } | |
385 | |
386 // set this/nest param attrs | |
387 if (f->thisAttrs) | |
388 { | |
389 PAWI.Index = f->retInPtr ? 2 : 1; | |
390 PAWI.Attrs = f->thisAttrs; | |
350 attrs.push_back(PAWI); | 391 attrs.push_back(PAWI); |
351 } | 392 } |
352 | 393 |
353 // set attrs on the rest of the arguments | 394 // set attrs on the rest of the arguments |
354 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) | 395 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) |