Commit cb642590 by Andrew Haley

[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
parent 4d4b8cb9
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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 @@ ...@@ -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: ...@@ -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: ...@@ -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): ...@@ -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): ...@@ -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 ...@@ -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 ...@@ -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)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment