mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
Added support for tuple return with __asmtuple!(int,int) etc.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
22
tests/mini/__asm1.d
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user