Mercurial > projects > ldc
changeset 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 | ba9d6292572a |
files | gen/naked.cpp runtime/import/ldc/llvmasm.di tests/mini/__asm1.d |
diffstat | 3 files changed, 53 insertions(+), 8 deletions(-) [+] |
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); }
--- a/runtime/import/ldc/llvmasm.di Sat Mar 28 07:24:53 2009 +0100 +++ b/runtime/import/ldc/llvmasm.di Sat Mar 28 08:25:58 2009 +0100 @@ -1,13 +1,17 @@ module ldc.llvmasm; -pragma(llvm_inline_asm) -template __asm() +struct __asmtuple_t(T...) { - void __asm(char[] asmcode, char[] constraints, ...); + T v; } pragma(llvm_inline_asm) -template __asm(T) { - T __asm(char[] asmcode, char[] constraints, ...); + void __asm( )(char[] asmcode, char[] constraints, ...); + T __asm(T)(char[] asmcode, char[] constraints, ...); + + template __asmtuple(T...) + { + __asmtuple_t!(T) __asmtuple(char[] asmcode, char[] constraints, ...); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/__asm1.d Sat Mar 28 08:25:58 2009 +0100 @@ -0,0 +1,22 @@ +import ldc.llvmasm; +void main() { + version(X86) + { + int i; + __asm("movl $1, $0", "=*m,i", &i, 42); + assert(i == 42); + + int j = __asm!(int)("movl $1, %eax", "={ax},i", 42); + assert(j == 42); + + auto k = __asmtuple!(int,int)("mov $2, %eax ; mov $3, %edx", "={ax},={dx},i,i", 10, 20); + assert(k.v[0] == 10); + assert(k.v[1] == 20); + } + else version(PPC) + { + int j = 42; + int i = __asm!(int)("li $1, $0", "=r,*m", &j); + assert(i == 42); + } +}