mirror of git://gcc.gnu.org/git/gcc.git
[multiple changes]
2007-09-04 <aph@redhat.com> * src/arm/sysv.S (UNWIND): New. (Whole file): Conditionally compile unwinder directives. * src/arm/sysv.S: Add unwinder directives. * src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes. Only treat r0 as a struct address if we're actually returning a struct by address. Only copy the bytes that are actually within a struct. (ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes is returned in r0, not passed by address. (ffi_call): Allocate a word-sized temporary for the case where a composite is returned in r0. (ffi_prep_incoming_args_SYSV): Align as necessary. 2007-08-05 Steven Newbury <s_j_newbury@yahoo.co.uk> * src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of directly using the sys_cacheflush syscall. 2007-07-27 Andrew Haley <aph@redhat.com> * src/arm/sysv.S (ffi_closure_SYSV): Add soft-float. From-SVN: r128093
This commit is contained in:
parent
4d4b8cb9c0
commit
cb642590f3
|
|
@ -1,3 +1,28 @@
|
||||||
|
2007-09-04 <aph@redhat.com>
|
||||||
|
|
||||||
|
* src/arm/sysv.S (UNWIND): New.
|
||||||
|
(Whole file): Conditionally compile unwinder directives.
|
||||||
|
* src/arm/sysv.S: Add unwinder directives.
|
||||||
|
|
||||||
|
* src/arm/ffi.c (ffi_prep_args): Align structs by at least 4 bytes.
|
||||||
|
Only treat r0 as a struct address if we're actually returning a
|
||||||
|
struct by address.
|
||||||
|
Only copy the bytes that are actually within a struct.
|
||||||
|
(ffi_prep_cif_machdep): A Composite Type not larger than 4 bytes
|
||||||
|
is returned in r0, not passed by address.
|
||||||
|
(ffi_call): Allocate a word-sized temporary for the case where
|
||||||
|
a composite is returned in r0.
|
||||||
|
(ffi_prep_incoming_args_SYSV): Align as necessary.
|
||||||
|
|
||||||
|
2007-08-05 Steven Newbury <s_j_newbury@yahoo.co.uk>
|
||||||
|
|
||||||
|
* src/arm/ffi.c (FFI_INIT_TRAMPOLINE): Use __clear_cache instead of
|
||||||
|
directly using the sys_cacheflush syscall.
|
||||||
|
|
||||||
|
2007-07-27 Andrew Haley <aph@redhat.com>
|
||||||
|
|
||||||
|
* src/arm/sysv.S (ffi_closure_SYSV): Add soft-float.
|
||||||
|
|
||||||
2007-09-03 Maciej W. Rozycki <macro@linux-mips.org>
|
2007-09-03 Maciej W. Rozycki <macro@linux-mips.org>
|
||||||
|
|
||||||
* Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
|
* Makefile.am: Unify MIPS_IRIX and MIPS_LINUX into MIPS.
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||||
|
|
||||||
argp = stack;
|
argp = stack;
|
||||||
|
|
||||||
if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
|
if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
|
||||||
*(void **) argp = ecif->rvalue;
|
*(void **) argp = ecif->rvalue;
|
||||||
argp += 4;
|
argp += 4;
|
||||||
}
|
}
|
||||||
|
|
@ -58,6 +58,9 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||||
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
|
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((*p_arg)->type == FFI_TYPE_STRUCT)
|
||||||
|
argp = (char *) ALIGN(argp, 4);
|
||||||
|
|
||||||
z = (*p_arg)->size;
|
z = (*p_arg)->size;
|
||||||
if (z < sizeof(int))
|
if (z < sizeof(int))
|
||||||
{
|
{
|
||||||
|
|
@ -81,7 +84,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FFI_TYPE_STRUCT:
|
case FFI_TYPE_STRUCT:
|
||||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
memcpy(argp, *p_argv, (*p_arg)->size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -115,7 +118,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
switch (cif->rtype->type)
|
switch (cif->rtype->type)
|
||||||
{
|
{
|
||||||
case FFI_TYPE_VOID:
|
case FFI_TYPE_VOID:
|
||||||
case FFI_TYPE_STRUCT:
|
|
||||||
case FFI_TYPE_FLOAT:
|
case FFI_TYPE_FLOAT:
|
||||||
case FFI_TYPE_DOUBLE:
|
case FFI_TYPE_DOUBLE:
|
||||||
cif->flags = (unsigned) cif->rtype->type;
|
cif->flags = (unsigned) cif->rtype->type;
|
||||||
|
|
@ -126,6 +128,17 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||||
cif->flags = (unsigned) FFI_TYPE_SINT64;
|
cif->flags = (unsigned) FFI_TYPE_SINT64;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_STRUCT:
|
||||||
|
if (cif->rtype->size <= 4)
|
||||||
|
/* A Composite Type not larger than 4 bytes is returned in r0. */
|
||||||
|
cif->flags = (unsigned)FFI_TYPE_INT;
|
||||||
|
else
|
||||||
|
/* A Composite Type larger than 4 bytes, or whose size cannot
|
||||||
|
be determined statically ... is stored in memory at an
|
||||||
|
address passed [in r0]. */
|
||||||
|
cif->flags = (unsigned)FFI_TYPE_STRUCT;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cif->flags = FFI_TYPE_INT;
|
cif->flags = FFI_TYPE_INT;
|
||||||
break;
|
break;
|
||||||
|
|
@ -141,21 +154,27 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
|
||||||
{
|
{
|
||||||
extended_cif ecif;
|
extended_cif ecif;
|
||||||
|
|
||||||
|
int small_struct = (cif->flags == FFI_TYPE_INT
|
||||||
|
&& cif->rtype->type == FFI_TYPE_STRUCT);
|
||||||
|
|
||||||
ecif.cif = cif;
|
ecif.cif = cif;
|
||||||
ecif.avalue = avalue;
|
ecif.avalue = avalue;
|
||||||
|
|
||||||
|
unsigned int temp;
|
||||||
|
|
||||||
/* If the return value is a struct and we don't have a return */
|
/* If the return value is a struct and we don't have a return */
|
||||||
/* value address then we need to make one */
|
/* value address then we need to make one */
|
||||||
|
|
||||||
if ((rvalue == NULL) &&
|
if ((rvalue == NULL) &&
|
||||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
(cif->flags == FFI_TYPE_STRUCT))
|
||||||
{
|
{
|
||||||
ecif.rvalue = alloca(cif->rtype->size);
|
ecif.rvalue = alloca(cif->rtype->size);
|
||||||
}
|
}
|
||||||
|
else if (small_struct)
|
||||||
|
ecif.rvalue = &temp;
|
||||||
else
|
else
|
||||||
ecif.rvalue = rvalue;
|
ecif.rvalue = rvalue;
|
||||||
|
|
||||||
|
|
||||||
switch (cif->abi)
|
switch (cif->abi)
|
||||||
{
|
{
|
||||||
case FFI_SYSV:
|
case FFI_SYSV:
|
||||||
|
|
@ -167,6 +186,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
|
||||||
FFI_ASSERT(0);
|
FFI_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (small_struct)
|
||||||
|
memcpy (rvalue, &temp, cif->rtype->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** private members **/
|
/** private members **/
|
||||||
|
|
@ -228,9 +249,12 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||||
{
|
{
|
||||||
size_t z;
|
size_t z;
|
||||||
|
|
||||||
|
size_t alignment = (*p_arg)->alignment;
|
||||||
|
if (alignment < 4)
|
||||||
|
alignment = 4;
|
||||||
/* Align if necessary */
|
/* Align if necessary */
|
||||||
if ((sizeof(int) - 1) & (unsigned) argp) {
|
if ((alignment - 1) & (unsigned) argp) {
|
||||||
argp = (char *) ALIGN(argp, sizeof(int));
|
argp = (char *) ALIGN(argp, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
z = (*p_arg)->size;
|
z = (*p_arg)->size;
|
||||||
|
|
@ -248,21 +272,16 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
|
||||||
|
|
||||||
/* How to make a trampoline. */
|
/* How to make a trampoline. */
|
||||||
|
|
||||||
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
|
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
|
||||||
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
|
||||||
unsigned int __fun = (unsigned int)(FUN); \
|
unsigned int __fun = (unsigned int)(FUN); \
|
||||||
unsigned int __ctx = (unsigned int)(CTX); \
|
unsigned int __ctx = (unsigned int)(CTX); \
|
||||||
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
|
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
|
||||||
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
|
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
|
||||||
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
|
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
|
||||||
*(unsigned int*) &__tramp[12] = __ctx; \
|
*(unsigned int*) &__tramp[12] = __ctx; \
|
||||||
*(unsigned int*) &__tramp[16] = __fun; \
|
*(unsigned int*) &__tramp[16] = __fun; \
|
||||||
register unsigned long _beg __asm ("a1") = (unsigned long) (&__tramp[0]); \
|
__clear_cache((&__tramp[0]), (&__tramp[19])); \
|
||||||
register unsigned long _end __asm ("a2") = (unsigned long) (&__tramp[19]); \
|
|
||||||
register unsigned long _flg __asm ("a3") = 0; \
|
|
||||||
__asm __volatile ("swi 0x9f0002 @ sys_cacheflush" \
|
|
||||||
: "=r" (_beg) \
|
|
||||||
: "0" (_beg), "r" (_end), "r" (_flg)); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,14 @@
|
||||||
# define call_reg(x) mov lr, pc ; mov pc, x
|
# define call_reg(x) mov lr, pc ; mov pc, x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Conditionally compile unwinder directives. */
|
||||||
|
#ifdef __ARM_EABI__
|
||||||
|
#define UNWIND
|
||||||
|
#else
|
||||||
|
#define UNWIND @
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
|
||||||
.macro ARM_FUNC_START name
|
.macro ARM_FUNC_START name
|
||||||
.text
|
.text
|
||||||
|
|
@ -92,6 +100,7 @@
|
||||||
bx pc
|
bx pc
|
||||||
nop
|
nop
|
||||||
.arm
|
.arm
|
||||||
|
UNWIND .fnstart
|
||||||
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
/* A hook to tell gdb that we've switched to ARM mode. Also used to call
|
||||||
directly from other local arm routines. */
|
directly from other local arm routines. */
|
||||||
_L__\name:
|
_L__\name:
|
||||||
|
|
@ -102,6 +111,7 @@ _L__\name:
|
||||||
.align 0
|
.align 0
|
||||||
.arm
|
.arm
|
||||||
ENTRY(\name)
|
ENTRY(\name)
|
||||||
|
UNWIND .fnstart
|
||||||
.endm
|
.endm
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -134,8 +144,11 @@ _L__\name:
|
||||||
ARM_FUNC_START ffi_call_SYSV
|
ARM_FUNC_START ffi_call_SYSV
|
||||||
@ Save registers
|
@ Save registers
|
||||||
stmfd sp!, {r0-r3, fp, lr}
|
stmfd sp!, {r0-r3, fp, lr}
|
||||||
|
UNWIND .save {r0-r3, fp, lr}
|
||||||
mov fp, sp
|
mov fp, sp
|
||||||
|
|
||||||
|
UNWIND .setfp fp, sp
|
||||||
|
|
||||||
@ Make room for all of the new args.
|
@ Make room for all of the new args.
|
||||||
sub sp, fp, r2
|
sub sp, fp, r2
|
||||||
|
|
||||||
|
|
@ -205,6 +218,7 @@ LSYM(Lepilogue):
|
||||||
RETLDM "r0-r3,fp"
|
RETLDM "r0-r3,fp"
|
||||||
|
|
||||||
.ffi_call_SYSV_end:
|
.ffi_call_SYSV_end:
|
||||||
|
UNWIND .fnend
|
||||||
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
|
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -216,21 +230,40 @@ LSYM(Lepilogue):
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ARM_FUNC_START ffi_closure_SYSV
|
ARM_FUNC_START ffi_closure_SYSV
|
||||||
|
UNWIND .pad #16
|
||||||
add ip, sp, #16
|
add ip, sp, #16
|
||||||
stmfd sp!, {ip, lr}
|
stmfd sp!, {ip, lr}
|
||||||
|
UNWIND .save {r0, lr}
|
||||||
add r2, sp, #8
|
add r2, sp, #8
|
||||||
|
.pad #16
|
||||||
sub sp, sp, #16
|
sub sp, sp, #16
|
||||||
str sp, [sp, #8]
|
str sp, [sp, #8]
|
||||||
add r1, sp, #8
|
add r1, sp, #8
|
||||||
bl ffi_closure_SYSV_inner
|
bl ffi_closure_SYSV_inner
|
||||||
cmp r0, #FFI_TYPE_INT
|
cmp r0, #FFI_TYPE_INT
|
||||||
beq .Lretint
|
beq .Lretint
|
||||||
|
|
||||||
cmp r0, #FFI_TYPE_FLOAT
|
cmp r0, #FFI_TYPE_FLOAT
|
||||||
|
#ifdef __SOFTFP__
|
||||||
|
beq .Lretint
|
||||||
|
#else
|
||||||
beq .Lretfloat
|
beq .Lretfloat
|
||||||
|
#endif
|
||||||
|
|
||||||
cmp r0, #FFI_TYPE_DOUBLE
|
cmp r0, #FFI_TYPE_DOUBLE
|
||||||
|
#ifdef __SOFTFP__
|
||||||
|
beq .Lretlonglong
|
||||||
|
#else
|
||||||
beq .Lretdouble
|
beq .Lretdouble
|
||||||
|
#endif
|
||||||
|
|
||||||
cmp r0, #FFI_TYPE_LONGDOUBLE
|
cmp r0, #FFI_TYPE_LONGDOUBLE
|
||||||
|
#ifdef __SOFTFP__
|
||||||
|
beq .Lretlonglong
|
||||||
|
#else
|
||||||
beq .Lretlongdouble
|
beq .Lretlongdouble
|
||||||
|
#endif
|
||||||
|
|
||||||
cmp r0, #FFI_TYPE_SINT64
|
cmp r0, #FFI_TYPE_SINT64
|
||||||
beq .Lretlonglong
|
beq .Lretlonglong
|
||||||
.Lclosure_epilogue:
|
.Lclosure_epilogue:
|
||||||
|
|
@ -243,6 +276,8 @@ ARM_FUNC_START ffi_closure_SYSV
|
||||||
ldr r0, [sp]
|
ldr r0, [sp]
|
||||||
ldr r1, [sp, #4]
|
ldr r1, [sp, #4]
|
||||||
b .Lclosure_epilogue
|
b .Lclosure_epilogue
|
||||||
|
|
||||||
|
#ifndef __SOFTFP__
|
||||||
.Lretfloat:
|
.Lretfloat:
|
||||||
ldfs f0, [sp]
|
ldfs f0, [sp]
|
||||||
b .Lclosure_epilogue
|
b .Lclosure_epilogue
|
||||||
|
|
@ -252,6 +287,9 @@ ARM_FUNC_START ffi_closure_SYSV
|
||||||
.Lretlongdouble:
|
.Lretlongdouble:
|
||||||
ldfd f0, [sp]
|
ldfd f0, [sp]
|
||||||
b .Lclosure_epilogue
|
b .Lclosure_epilogue
|
||||||
|
#endif
|
||||||
|
|
||||||
.ffi_closure_SYSV_end:
|
.ffi_closure_SYSV_end:
|
||||||
|
UNWIND .fnend
|
||||||
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue