mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 03:30:29 +08:00
Richards changes to the closure code for alpha
From-SVN: r38169
This commit is contained in:
parent
bc38c78775
commit
3f67ba6e95
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user