Richards changes to the closure code for alpha

From-SVN: r38169
This commit is contained in:
Richard Henderson 2000-12-09 23:13:18 -08:00 committed by Anthony Green
parent bc38c78775
commit 3f67ba6e95
3 changed files with 133 additions and 28 deletions

View File

@ -1,4 +1,12 @@
2000-12-07 Dec 8 11:23:29 2000 Richard Henderson <rth@redhat.com>
2000-12-09 Richard Henderson <rth@redhat.com>
* src/alpha/ffi.c (ffi_call): Simplify struct return test.
(ffi_closure_osf_inner): Index rather than increment avalue
and arg_types. Give ffi_closure_osf the raw return value type.
* src/alpha/osf.S (ffi_closure_osf): Handle return value type
promotion.
2000-12-07 Richard Henderson <rth@redhat.com>
* src/raw_api.c (ffi_translate_args): Fix typo.
(ffi_prep_closure): Likewise.

View File

@ -70,7 +70,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
/* If the return value is a struct and we don't have a return
value address then we need to make one. */
if (rvalue == NULL && cif->rtype->type == FFI_TYPE_STRUCT)
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
rvalue = alloca(cif->rtype->size);
/* Allocate the space for the arguments, plus 4 words of temp
@ -202,7 +202,7 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
/* Grab the addresses of the arguments from the stack frame. */
while (i < avn)
{
switch ((*arg_types)->type)
switch (arg_types[i]->type)
{
case FFI_TYPE_SINT8:
case FFI_TYPE_UINT8:
@ -214,7 +214,7 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
case FFI_TYPE_UINT64:
case FFI_TYPE_POINTER:
case FFI_TYPE_STRUCT:
*avalue = &argp[argn];
avalue[i] = &argp[argn];
break;
case FFI_TYPE_FLOAT:
@ -223,27 +223,27 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
/* Floats coming from registers need conversion from double
back to float format. */
*(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
*avalue = &argp[argn - 6];
avalue[i] = &argp[argn - 6];
}
else
*avalue = &argp[argn];
avalue[i] = &argp[argn];
break;
case FFI_TYPE_DOUBLE:
*avalue = &argp[argn - (argn < 6 ? 6 : 0)];
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
break;
default:
FFI_ASSERT(0);
}
argn += ALIGN((*arg_types)->size, SIZEOF_ARG) / SIZEOF_ARG;
i++, arg_types++, avalue++;
argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
i++;
}
/* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_osf what register to put the return value in. */
return cif->flags;
/* Tell ffi_closure_osf how to perform return type promotions. */
return cif->rtype->type;
}

View File

@ -28,6 +28,7 @@
#define LIBFFI_ASM
#include <ffi.h>
.arch ev6
.text
/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
@ -121,9 +122,9 @@ $retdouble:
.ent ffi_closure_osf
ffi_closure_osf:
.frame $30, 16*8, $26, 0
.mask 0x4000000, -14*8
.mask 0x4000000, -16*8
ldgp $29, 0($27)
subq $30, 14*8, $30
subq $30, 16*8, $30
stq $26, 0($30)
.prologue 1
@ -150,33 +151,129 @@ ffi_closure_osf:
ldq $26, 0($30)
# Load up the return value in the proper type.
cmpeq $0, FFI_TYPE_INT, $1
bne $1, $loadint
cmpeq $0, FFI_TYPE_FLOAT, $2
bne $2, $loadfloat
cmpeq $18, FFI_TYPE_DOUBLE, $3
bne $3, $loaddouble
lda $1, $load_table
s4addq $0, $1, $1
ldl $1, 0($1)
addq $1, $29, $1
jmp $31, ($1), $load_32
.align 4
$load_none:
addq $30, 16*8, $30
ret
.align 3
$loadint:
ldq $0, 16($30)
nop
addq $30, 16*8, $30
ret
$loadfloat:
.align 4
$load_float:
lds $f0, 16($30)
nop
addq $30, 16*8, $30
ret
$loaddouble:
.align 4
$load_double:
ldt $f0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_u8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
nop
#else
ldq $0, 16($30)
and $0, 255, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s8:
#ifdef __alpha_bwx__
ldbu $0, 16($30)
sextb $0, $0
#else
ldq $0, 16($30)
sll $0, 56, $0
sra $0, 56, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_u16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
nop
#else
ldq $0, 16($30)
zapnot $0, 3, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_s16:
#ifdef __alpha_bwx__
ldwu $0, 16($30)
sextw $0, $0
#else
ldq $0, 16($30)
sll $0, 48, $0
sra $0, 48, $0
#endif
addq $30, 16*8, $30
ret
.align 4
$load_32:
ldl $0, 16($30)
nop
addq $30, 16*8, $30
ret
.align 4
$load_64:
ldq $0, 16($30)
nop
addq $30, 16*8, $30
ret
.end ffi_closure_osf
.section .rodata
$load_table:
.gprel32 $load_none # FFI_TYPE_VOID
.gprel32 $load_32 # FFI_TYPE_INT
.gprel32 $load_float # FFI_TYPE_FLOAT
.gprel32 $load_double # FFI_TYPE_DOUBLE
.gprel32 $load_double # FFI_TYPE_LONGDOUBLE
.gprel32 $load_u8 # FFI_TYPE_UINT8
.gprel32 $load_s8 # FFI_TYPE_SINT8
.gprel32 $load_u16 # FFI_TYPE_UINT16
.gprel32 $load_s16 # FFI_TYPE_SINT16
.gprel32 $load_32 # FFI_TYPE_UINT32
.gprel32 $load_32 # FFI_TYPE_SINT32
.gprel32 $load_64 # FFI_TYPE_UINT64
.gprel32 $load_64 # FFI_TYPE_SINT64
.gprel32 $load_none # FFI_TYPE_STRUCT
.gprel32 $load_64 # FFI_TYPE_POINTER
/* Assert that the table above is in sync with ffi.h. */
#if FFI_TYPE_FLOAT != 2 \
|| FFI_TYPE_DOUBLE != 3 \
|| FFI_TYPE_UINT8 != 5 \
|| FFI_TYPE_SINT8 != 6 \
|| FFI_TYPE_UINT16 != 7 \
|| FFI_TYPE_SINT16 != 8 \
|| FFI_TYPE_UINT32 != 9 \
|| FFI_TYPE_SINT32 != 10 \
|| FFI_TYPE_UINT64 != 11 \
|| FFI_TYPE_SINT64 != 12 \
|| FFI_TYPE_STRUCT != 13 \
|| FFI_TYPE_POINTER != 14 \
|| FFI_TYPE_LAST != 14
#error "osf.S out of sync with ffi.h"
#endif