Added support for tuple return with __asmtuple!(int,int) etc.

This commit is contained in:
Tomas Lindquist Olsen
2009-03-28 08:25:58 +01:00
parent 1809214995
commit e61562033d
3 changed files with 53 additions and 8 deletions

View File

@@ -376,17 +376,36 @@ DValue * DtoInlineAsmExpr(Loc loc, FuncDeclaration * fd, Expressions * arguments
}
// 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);
}

View File

@@ -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, ...);
}
}

22
tests/mini/__asm1.d Normal file
View File

@@ -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);
}
}