sparc: Add support for complex types
This commit is contained in:
@@ -90,6 +90,40 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
case FFI_TYPE_UINT64:
|
case FFI_TYPE_UINT64:
|
||||||
flags = SPARC_RET_INT64;
|
flags = SPARC_RET_INT64;
|
||||||
break;
|
break;
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
|
rtt = rtype->elements[0]->type;
|
||||||
|
switch (rtt)
|
||||||
|
{
|
||||||
|
case FFI_TYPE_FLOAT:
|
||||||
|
flags = SPARC_RET_F_2;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_DOUBLE:
|
||||||
|
flags = SPARC_RET_F_4;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
flags = SPARC_RET_F_8;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_SINT64:
|
||||||
|
case FFI_TYPE_UINT64:
|
||||||
|
flags = SPARC_RET_INT128;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_INT:
|
||||||
|
case FFI_TYPE_SINT32:
|
||||||
|
case FFI_TYPE_UINT32:
|
||||||
|
flags = SPARC_RET_INT64;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_SINT16:
|
||||||
|
case FFI_TYPE_UINT16:
|
||||||
|
flags = SP_V8_RET_CPLX16;
|
||||||
|
break;
|
||||||
|
case FFI_TYPE_SINT8:
|
||||||
|
case FFI_TYPE_UINT8:
|
||||||
|
flags = SP_V8_RET_CPLX8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@@ -102,11 +136,24 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
size_t z = ty->size;
|
size_t z = ty->size;
|
||||||
int tt = ty->type;
|
int tt = ty->type;
|
||||||
|
|
||||||
if (tt == FFI_TYPE_STRUCT || tt == FFI_TYPE_LONGDOUBLE)
|
switch (tt)
|
||||||
/* Passed by reference. */
|
{
|
||||||
z = 4;
|
case FFI_TYPE_STRUCT:
|
||||||
else
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
z = ALIGN(z, 4);
|
by_reference:
|
||||||
|
/* Passed by reference. */
|
||||||
|
z = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
|
tt = ty->elements[0]->type;
|
||||||
|
if (tt == FFI_TYPE_FLOAT || z > 8)
|
||||||
|
goto by_reference;
|
||||||
|
/* FALLTHRU */
|
||||||
|
|
||||||
|
default:
|
||||||
|
z = ALIGN(z, 4);
|
||||||
|
}
|
||||||
bytes += z;
|
bytes += z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,11 +216,14 @@ ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
|
|||||||
{
|
{
|
||||||
ffi_type *ty = p_arg[i];
|
ffi_type *ty = p_arg[i];
|
||||||
void *a = avalue[i];
|
void *a = avalue[i];
|
||||||
|
int tt = ty->type;
|
||||||
|
size_t z;
|
||||||
|
|
||||||
switch (ty->type)
|
switch (tt)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
by_reference:
|
||||||
*argp++ = (unsigned long)a;
|
*argp++ = (unsigned long)a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -205,6 +255,23 @@ ffi_prep_args_v8(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
|
|||||||
*argp++ = *(SINT16 *)a;
|
*argp++ = *(SINT16 *)a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
|
tt = ty->elements[0]->type;
|
||||||
|
z = ty->size;
|
||||||
|
if (tt == FFI_TYPE_FLOAT || z > 8)
|
||||||
|
goto by_reference;
|
||||||
|
if (z < 4)
|
||||||
|
{
|
||||||
|
memcpy((char *)argp + 4 - z, a, z);
|
||||||
|
argp++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(argp, a, z);
|
||||||
|
argp += z / 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@@ -299,11 +366,13 @@ ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
|
|||||||
ffi_type *ty = arg_types[i];
|
ffi_type *ty = arg_types[i];
|
||||||
int tt = ty->type;
|
int tt = ty->type;
|
||||||
void *a = argp;
|
void *a = argp;
|
||||||
|
size_t z;
|
||||||
|
|
||||||
switch (tt)
|
switch (tt)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
by_reference:
|
||||||
/* Straight copy of invisible reference. */
|
/* Straight copy of invisible reference. */
|
||||||
a = (void *)*argp;
|
a = (void *)*argp;
|
||||||
break;
|
break;
|
||||||
@@ -336,6 +405,17 @@ ffi_closure_sparc_inner_v8(ffi_closure *closure, void *rvalue,
|
|||||||
a += 3;
|
a += 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
|
tt = ty->elements[0]->type;
|
||||||
|
z = ty->size;
|
||||||
|
if (tt == FFI_TYPE_FLOAT || z > 8)
|
||||||
|
goto by_reference;
|
||||||
|
if (z < 4)
|
||||||
|
a += 4 - z;
|
||||||
|
else if (z > 4)
|
||||||
|
argp++;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,14 +52,28 @@
|
|||||||
and addition work correctly. The mask is placed in the second byte. */
|
and addition work correctly. The mask is placed in the second byte. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ffi_struct_float_mask (ffi_type *struct_type, int size_mask)
|
ffi_struct_float_mask (ffi_type *outer_type, int size_mask)
|
||||||
{
|
{
|
||||||
ffi_type **elts, *t;
|
ffi_type **elts;
|
||||||
|
ffi_type *t;
|
||||||
|
|
||||||
for (elts = struct_type->elements; (t = *elts) != NULL; elts++)
|
if (outer_type->type == FFI_TYPE_COMPLEX)
|
||||||
|
{
|
||||||
|
int m = 0, tt = outer_type->elements[0]->type;
|
||||||
|
size_t z = outer_type->size;
|
||||||
|
|
||||||
|
if (tt == FFI_TYPE_FLOAT
|
||||||
|
|| tt == FFI_TYPE_DOUBLE
|
||||||
|
|| tt == FFI_TYPE_LONGDOUBLE)
|
||||||
|
m = (1 << (z / 4)) - 1;
|
||||||
|
return (m << 8) | z;
|
||||||
|
}
|
||||||
|
FFI_ASSERT (outer_type->type == FFI_TYPE_STRUCT);
|
||||||
|
|
||||||
|
for (elts = outer_type->elements; (t = *elts) != NULL; elts++)
|
||||||
{
|
{
|
||||||
size_t z = t->size;
|
size_t z = t->size;
|
||||||
int o, m;
|
int o, m, tt;
|
||||||
|
|
||||||
size_mask = ALIGN(size_mask, t->alignment);
|
size_mask = ALIGN(size_mask, t->alignment);
|
||||||
switch (t->type)
|
switch (t->type)
|
||||||
@@ -67,6 +81,13 @@ ffi_struct_float_mask (ffi_type *struct_type, int size_mask)
|
|||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
size_mask = ffi_struct_float_mask (t, size_mask);
|
size_mask = ffi_struct_float_mask (t, size_mask);
|
||||||
continue;
|
continue;
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
|
tt = t->elements[0]->type;
|
||||||
|
if (tt != FFI_TYPE_FLOAT
|
||||||
|
&& tt != FFI_TYPE_DOUBLE
|
||||||
|
&& tt != FFI_TYPE_LONGDOUBLE)
|
||||||
|
break;
|
||||||
|
/* FALLTHRU */
|
||||||
case FFI_TYPE_FLOAT:
|
case FFI_TYPE_FLOAT:
|
||||||
case FFI_TYPE_DOUBLE:
|
case FFI_TYPE_DOUBLE:
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
@@ -78,8 +99,8 @@ ffi_struct_float_mask (ffi_type *struct_type, int size_mask)
|
|||||||
size_mask += z;
|
size_mask += z;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_mask = ALIGN(size_mask, struct_type->alignment);
|
size_mask = ALIGN(size_mask, outer_type->alignment);
|
||||||
FFI_ASSERT ((size_mask & 0xff) == struct_type->size);
|
FFI_ASSERT ((size_mask & 0xff) == outer_type->size);
|
||||||
|
|
||||||
return size_mask;
|
return size_mask;
|
||||||
}
|
}
|
||||||
@@ -162,6 +183,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
flags = SPARC_RET_F_4;
|
flags = SPARC_RET_F_4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
if (rtype->size > 32)
|
if (rtype->size > 32)
|
||||||
{
|
{
|
||||||
@@ -194,7 +216,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
{
|
{
|
||||||
case 1: flags = SPARC_RET_F_1; break;
|
case 1: flags = SPARC_RET_F_1; break;
|
||||||
case 2: flags = SPARC_RET_F_2; break;
|
case 2: flags = SPARC_RET_F_2; break;
|
||||||
case 3: flags = SPARC_RET_F_3; break;
|
case 3: flags = SP_V9_RET_F_3; break;
|
||||||
case 4: flags = SPARC_RET_F_4; break;
|
case 4: flags = SPARC_RET_F_4; break;
|
||||||
/* 5 word structures skipped; handled via RET_STRUCT. */
|
/* 5 word structures skipped; handled via RET_STRUCT. */
|
||||||
case 6: flags = SPARC_RET_F_6; break;
|
case 6: flags = SPARC_RET_F_6; break;
|
||||||
@@ -218,7 +240,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
break;
|
break;
|
||||||
case FFI_TYPE_INT:
|
case FFI_TYPE_INT:
|
||||||
case FFI_TYPE_SINT32:
|
case FFI_TYPE_SINT32:
|
||||||
flags = SPARC_RET_SINT32;
|
flags = SP_V9_RET_SINT32;
|
||||||
break;
|
break;
|
||||||
case FFI_TYPE_UINT32:
|
case FFI_TYPE_UINT32:
|
||||||
flags = SPARC_RET_UINT32;
|
flags = SPARC_RET_UINT32;
|
||||||
@@ -242,6 +264,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
|
|
||||||
switch (ty->type)
|
switch (ty->type)
|
||||||
{
|
{
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
/* Large structs passed by reference. */
|
/* Large structs passed by reference. */
|
||||||
if (z > 16)
|
if (z > 16)
|
||||||
@@ -249,7 +272,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
|
|||||||
a = z = 8;
|
a = z = 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* ??? FALLTHRU -- check for fp members in the struct. */
|
/* Small structs may be passed in integer or fp regs or both. */
|
||||||
|
if (bytes >= 16*8)
|
||||||
|
break;
|
||||||
|
if ((ffi_struct_float_mask (ty, 0) & 0xff00) == 0)
|
||||||
|
break;
|
||||||
|
/* FALLTHRU */
|
||||||
case FFI_TYPE_FLOAT:
|
case FFI_TYPE_FLOAT:
|
||||||
case FFI_TYPE_DOUBLE:
|
case FFI_TYPE_DOUBLE:
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
@@ -351,6 +379,7 @@ ffi_prep_args_v9(ffi_cif *cif, unsigned long *argp, void *rvalue, void **avalue)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
z = ty->size;
|
z = ty->size;
|
||||||
if (z > 16)
|
if (z > 16)
|
||||||
@@ -466,6 +495,7 @@ ffi_closure_sparc_inner_v9(ffi_closure *closure, void *rvalue,
|
|||||||
argx = argn + 1;
|
argx = argn + 1;
|
||||||
switch (ty->type)
|
switch (ty->type)
|
||||||
{
|
{
|
||||||
|
case FFI_TYPE_COMPLEX:
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
z = ty->size;
|
z = ty->size;
|
||||||
if (z > 16)
|
if (z > 16)
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ typedef enum ffi_abi {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
|
||||||
|
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||||
|
|
||||||
/* ---- Definitions for closures ----------------------------------------- */
|
/* ---- Definitions for closures ----------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,18 @@
|
|||||||
#define SPARC_RET_UINT16 4
|
#define SPARC_RET_UINT16 4
|
||||||
#define SPARC_RET_SINT16 5
|
#define SPARC_RET_SINT16 5
|
||||||
#define SPARC_RET_UINT32 6
|
#define SPARC_RET_UINT32 6
|
||||||
#define SPARC_RET_SINT32 7 /* v9 only */
|
#define SP_V9_RET_SINT32 7 /* v9 only */
|
||||||
|
#define SP_V8_RET_CPLX16 7 /* v8 only */
|
||||||
#define SPARC_RET_INT64 8
|
#define SPARC_RET_INT64 8
|
||||||
#define SPARC_RET_INT128 9 /* v9 only */
|
#define SPARC_RET_INT128 9
|
||||||
|
|
||||||
/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */
|
/* Note that F_7 is missing, and is handled by SPARC_RET_STRUCT. */
|
||||||
#define SPARC_RET_F_8 10
|
#define SPARC_RET_F_8 10
|
||||||
#define SPARC_RET_F_6 11 /* v9 only */
|
#define SPARC_RET_F_6 11
|
||||||
#define SPARC_RET_F_4 12
|
#define SPARC_RET_F_4 12
|
||||||
#define SPARC_RET_F_2 13
|
#define SPARC_RET_F_2 13
|
||||||
#define SPARC_RET_F_3 14 /* v9 only */
|
#define SP_V9_RET_F_3 14 /* v9 only */
|
||||||
|
#define SP_V8_RET_CPLX8 14 /* v8 only */
|
||||||
#define SPARC_RET_F_1 15
|
#define SPARC_RET_F_1 15
|
||||||
|
|
||||||
#define SPARC_FLAG_RET_MASK 15
|
#define SPARC_FLAG_RET_MASK 15
|
||||||
|
|||||||
136
src/sparc/v8.S
136
src/sparc/v8.S
@@ -1,8 +1,8 @@
|
|||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
v8.S - Copyright (c) 2013 The Written Word, Inc.
|
v8.S - Copyright (c) 2013 The Written Word, Inc.
|
||||||
Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
|
Copyright (c) 1996, 1997, 2003, 2004, 2008 Red Hat, Inc.
|
||||||
|
|
||||||
SPARC Foreign Function Interface
|
SPARC Foreign Function Interface
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
----------------------------------------------------------------------- */
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define LIBFFI_ASM
|
#define LIBFFI_ASM
|
||||||
#include <fficonfig.h>
|
#include <fficonfig.h>
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
#include <ffi_cfi.h>
|
#include <ffi_cfi.h>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
.align 8
|
.align 8
|
||||||
.globl C(ffi_flush_icache)
|
.globl C(ffi_flush_icache)
|
||||||
.type C(ffi_flush_icache),@function
|
.type C(ffi_flush_icache),@function
|
||||||
@@ -75,7 +75,7 @@ C(ffi_flush_icache):
|
|||||||
.globl C(ffi_call_v8)
|
.globl C(ffi_call_v8)
|
||||||
.type C(ffi_call_v8),@function
|
.type C(ffi_call_v8),@function
|
||||||
FFI_HIDDEN(C(ffi_call_v8))
|
FFI_HIDDEN(C(ffi_call_v8))
|
||||||
|
|
||||||
C(ffi_call_v8):
|
C(ffi_call_v8):
|
||||||
cfi_startproc
|
cfi_startproc
|
||||||
! Allocate a stack frame sized by ffi_call.
|
! Allocate a stack frame sized by ffi_call.
|
||||||
@@ -139,26 +139,44 @@ E SPARC_RET_UINT32
|
|||||||
7: st %o0, [%i2]
|
7: st %o0, [%i2]
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_SINT32
|
E SP_V8_RET_CPLX16
|
||||||
unimp
|
sth %o0, [%i2+2]
|
||||||
|
b 9f
|
||||||
|
srl %o0, 16, %o0
|
||||||
E SPARC_RET_INT64
|
E SPARC_RET_INT64
|
||||||
std %o0, [%i2]
|
st %o0, [%i2]
|
||||||
|
st %o1, [%i2+4]
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_INT128
|
E SPARC_RET_INT128
|
||||||
unimp
|
std %o0, [%i2]
|
||||||
E SPARC_RET_F_8
|
std %o2, [%i2+8]
|
||||||
unimp
|
|
||||||
E SPARC_RET_F_6
|
|
||||||
unimp
|
|
||||||
E SPARC_RET_F_4
|
|
||||||
unimp
|
|
||||||
E SPARC_RET_F_2
|
|
||||||
std %f0, [%i2]
|
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_F_3
|
E SPARC_RET_F_8
|
||||||
unimp
|
st %f7, [%i2+7*4]
|
||||||
|
nop
|
||||||
|
st %f6, [%i2+6*4]
|
||||||
|
nop
|
||||||
|
E SPARC_RET_F_6
|
||||||
|
st %f5, [%i2+5*4]
|
||||||
|
nop
|
||||||
|
st %f4, [%i2+4*4]
|
||||||
|
nop
|
||||||
|
E SPARC_RET_F_4
|
||||||
|
st %f3, [%i2+3*4]
|
||||||
|
nop
|
||||||
|
st %f2, [%i2+2*4]
|
||||||
|
nop
|
||||||
|
E SPARC_RET_F_2
|
||||||
|
st %f1, [%i2+4]
|
||||||
|
st %f0, [%i2]
|
||||||
|
ret
|
||||||
|
restore
|
||||||
|
E SP_V8_RET_CPLX8
|
||||||
|
stb %o0, [%i2+1]
|
||||||
|
b 10f
|
||||||
|
srl %o0, 8, %o0
|
||||||
E SPARC_RET_F_1
|
E SPARC_RET_F_1
|
||||||
st %f0, [%i2]
|
st %f0, [%i2]
|
||||||
ret
|
ret
|
||||||
@@ -172,16 +190,22 @@ E SPARC_RET_F_1
|
|||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
|
|
||||||
|
.align 8
|
||||||
|
9: sth %o0, [%i2]
|
||||||
|
ret
|
||||||
|
restore
|
||||||
|
.align 8
|
||||||
|
10: stb %o0, [%i2]
|
||||||
|
ret
|
||||||
|
restore
|
||||||
|
|
||||||
cfi_endproc
|
cfi_endproc
|
||||||
.size C(ffi_call_v8),. - C(ffi_call_v8)
|
.size C(ffi_call_v8),. - C(ffi_call_v8)
|
||||||
|
|
||||||
|
|
||||||
#undef STACKFRAME
|
/* 16*4 register window + 1*4 struct return + 6*4 args backing store
|
||||||
#define STACKFRAME 104 /* 16*4 register window +
|
+ 8*4 return storage + 1*4 alignment. */
|
||||||
1*4 struct return +
|
#define STACKFRAME (16*4 + 4 + 6*4 + 8*4 + 4)
|
||||||
6*4 args backing store +
|
|
||||||
2*4 return storage +
|
|
||||||
1*4 alignment */
|
|
||||||
|
|
||||||
/* ffi_closure_v8(...)
|
/* ffi_closure_v8(...)
|
||||||
|
|
||||||
@@ -211,7 +235,7 @@ C(ffi_closure_v8):
|
|||||||
|
|
||||||
! Call ffi_closure_sparc_inner to do the bulk of the work.
|
! Call ffi_closure_sparc_inner to do the bulk of the work.
|
||||||
mov %g2, %o0
|
mov %g2, %o0
|
||||||
add %fp, -8, %o1
|
add %fp, -8*4, %o1
|
||||||
call ffi_closure_sparc_inner_v8
|
call ffi_closure_sparc_inner_v8
|
||||||
add %fp, 64, %o2
|
add %fp, 64, %o2
|
||||||
|
|
||||||
@@ -220,8 +244,8 @@ C(ffi_closure_v8):
|
|||||||
1: sll %o0, 4, %o0 ! o0 = o0 * 16
|
1: sll %o0, 4, %o0 ! o0 = o0 * 16
|
||||||
add %o7, %o0, %o7 ! o7 = 0b + o0*16
|
add %o7, %o0, %o7 ! o7 = 0b + o0*16
|
||||||
jmp %o7+(2f-0b)
|
jmp %o7+(2f-0b)
|
||||||
nop
|
add %fp, -8*4, %i2
|
||||||
|
|
||||||
! Note that each entry is 4 insns, enforced by the E macro.
|
! Note that each entry is 4 insns, enforced by the E macro.
|
||||||
.align 16
|
.align 16
|
||||||
2:
|
2:
|
||||||
@@ -232,47 +256,63 @@ E SPARC_RET_STRUCT
|
|||||||
jmp %i7+12
|
jmp %i7+12
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_UINT8
|
E SPARC_RET_UINT8
|
||||||
ldub [%fp-8+3], %i0
|
ldub [%i2+3], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_SINT8
|
E SPARC_RET_SINT8
|
||||||
ldsb [%fp-8+3], %i0
|
ldsb [%i2+3], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_UINT16
|
E SPARC_RET_UINT16
|
||||||
lduh [%fp-8+2], %i0
|
lduh [%i2+2], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_SINT16
|
E SPARC_RET_SINT16
|
||||||
ldsh [%fp-8+2], %i0
|
ldsh [%i2+2], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_UINT32
|
E SPARC_RET_UINT32
|
||||||
ld [%fp-8], %i0
|
ld [%i2], %i0
|
||||||
|
ret
|
||||||
|
restore
|
||||||
|
E SP_V8_RET_CPLX16
|
||||||
|
ld [%i2], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_SINT32
|
|
||||||
unimp
|
|
||||||
E SPARC_RET_INT64
|
E SPARC_RET_INT64
|
||||||
ldd [%fp-8], %i0
|
ldd [%i2], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_INT128
|
E SPARC_RET_INT128
|
||||||
unimp
|
ldd [%i2], %i0
|
||||||
E SPARC_RET_F_8
|
ldd [%i2+8], %i2
|
||||||
unimp
|
ret
|
||||||
E SPARC_RET_F_6
|
restore
|
||||||
unimp
|
E SPARC_RET_F_8
|
||||||
E SPARC_RET_F_4
|
ld [%i2+7*4], %f7
|
||||||
unimp
|
nop
|
||||||
E SPARC_RET_F_2
|
ld [%i2+6*4], %f6
|
||||||
ldd [%fp-8], %f0
|
nop
|
||||||
|
E SPARC_RET_F_6
|
||||||
|
ld [%i2+5*4], %f5
|
||||||
|
nop
|
||||||
|
ld [%i2+4*4], %f4
|
||||||
|
nop
|
||||||
|
E SPARC_RET_F_4
|
||||||
|
ld [%i2+3*4], %f3
|
||||||
|
nop
|
||||||
|
ld [%i2+2*4], %f2
|
||||||
|
nop
|
||||||
|
E SPARC_RET_F_2
|
||||||
|
ldd [%i2], %f0
|
||||||
|
ret
|
||||||
|
restore
|
||||||
|
E SP_V8_RET_CPLX8
|
||||||
|
lduh [%i2], %i0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
E SPARC_RET_F_3
|
|
||||||
unimp
|
|
||||||
E SPARC_RET_F_1
|
E SPARC_RET_F_1
|
||||||
ld [%fp-8], %f0
|
ld [%i2], %f0
|
||||||
ret
|
ret
|
||||||
restore
|
restore
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ E SPARC_RET_UINT32
|
|||||||
srl %o0, 0, %i0
|
srl %o0, 0, %i0
|
||||||
return %i7+8
|
return %i7+8
|
||||||
stx %o0, [%o2]
|
stx %o0, [%o2]
|
||||||
E SPARC_RET_SINT32
|
E SP_V9_RET_SINT32
|
||||||
sra %o0, 0, %i0
|
sra %o0, 0, %i0
|
||||||
return %i7+8
|
return %i7+8
|
||||||
stx %o0, [%o2]
|
stx %o0, [%o2]
|
||||||
@@ -167,7 +167,7 @@ E SPARC_RET_F_4
|
|||||||
E SPARC_RET_F_2
|
E SPARC_RET_F_2
|
||||||
return %i7+8
|
return %i7+8
|
||||||
std %f0, [%o2]
|
std %f0, [%o2]
|
||||||
E SPARC_RET_F_3
|
E SP_V9_RET_F_3
|
||||||
st %f2, [%i2+2*4]
|
st %f2, [%i2+2*4]
|
||||||
nop
|
nop
|
||||||
st %f1, [%i2+1*4]
|
st %f1, [%i2+1*4]
|
||||||
@@ -294,7 +294,7 @@ E SPARC_RET_UINT32
|
|||||||
lduw [FP-160+4], %i0
|
lduw [FP-160+4], %i0
|
||||||
return %i7+8
|
return %i7+8
|
||||||
nop
|
nop
|
||||||
E SPARC_RET_SINT32
|
E SP_V9_RET_SINT32
|
||||||
ldsw [FP-160+4], %i0
|
ldsw [FP-160+4], %i0
|
||||||
return %i7+8
|
return %i7+8
|
||||||
nop
|
nop
|
||||||
@@ -326,7 +326,7 @@ E SPARC_RET_F_2
|
|||||||
ldd [FP-160], %f0
|
ldd [FP-160], %f0
|
||||||
return %i7+8
|
return %i7+8
|
||||||
nop
|
nop
|
||||||
E SPARC_RET_F_3
|
E SP_V9_RET_F_3
|
||||||
ld [FP-160+2*4], %f2
|
ld [FP-160+2*4], %f2
|
||||||
nop
|
nop
|
||||||
ld [FP-160+1*4], %f1
|
ld [FP-160+1*4], %f1
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ if { [istarget aarch64*]
|
|||||||
|| [istarget arm*]
|
|| [istarget arm*]
|
||||||
|| [istarget i?86*]
|
|| [istarget i?86*]
|
||||||
|| [istarget s390*]
|
|| [istarget s390*]
|
||||||
|
|| [istarget sparc*]
|
||||||
|| [istarget x86_64*] } {
|
|| [istarget x86_64*] } {
|
||||||
run-many-tests $ctlist ""
|
run-many-tests $ctlist ""
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
_Complex int f_complex(_Complex int c, int x, int *py)
|
_Complex int f_complex(_Complex int c, int x, int *py)
|
||||||
{
|
{
|
||||||
c = -(2 * creal (c)) + (cimag (c) + 1)* I;
|
__real__ c = -2 * __real__ c;
|
||||||
|
__imag__ c = __imag__ c + 1;
|
||||||
*py += x;
|
*py += x;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user