Mercurial > projects > ldc
diff gen/naked.cpp @ 1154:9279a9dc6df3
Added support for tuple return with __asmtuple!(int,int) etc.
author | Tomas Lindquist Olsen <tomas.l.olsen gmail.com> |
---|---|
date | Sat, 28 Mar 2009 08:25:58 +0100 |
parents | 4454126b4345 |
children | 204197eb9eb5 |
line wrap: on
line diff
--- a/gen/naked.cpp Sat Mar 28 07:24:53 2009 +0100 +++ b/gen/naked.cpp Sat Mar 28 08:25:58 2009 +0100 @@ -376,17 +376,36 @@ } // build asm function type - const llvm::Type* ret_type = DtoType(fd->type->nextOf()); + Type* type = fd->type->nextOf()->toBasetype(); + const llvm::Type* ret_type = DtoType(type); llvm::FunctionType* FT = llvm::FunctionType::get(ret_type, argtypes, false); // build asm call bool sideeffect = true; llvm::InlineAsm* ia = llvm::InlineAsm::get(FT, code, constraints, sideeffect); - llvm::Value* v = gIR->ir->CreateCall(ia, args.begin(), args.end(), ""); + llvm::Value* rv = gIR->ir->CreateCall(ia, args.begin(), args.end(), ""); + + // work around missing tuple support for users of the return value + if (type->ty == Tstruct) + { + // make a copy + llvm::Value* mem = DtoAlloca(ret_type, ".__asm_tuple_ret"); + + TypeStruct* ts = (TypeStruct*)type; + size_t n = ts->sym->fields.dim; + for (size_t i = 0; i < n; i++) + { + llvm::Value* v = gIR->ir->CreateExtractValue(rv, i, ""); + llvm::Value* gep = DtoGEPi(mem, 0, i); + DtoStore(v, gep); + } + + return new DVarValue(fd->type->nextOf(), mem); + } // return call as im value - return new DImValue(fd->type->nextOf(), v); + return new DImValue(fd->type->nextOf(), rv); }