diff options
Diffstat (limited to 'ext/ffi_c/libffi/src/m68k')
-rw-r--r-- | ext/ffi_c/libffi/src/m68k/ffi.c | 96 | ||||
-rw-r--r-- | ext/ffi_c/libffi/src/m68k/ffitarget.h | 7 | ||||
-rw-r--r-- | ext/ffi_c/libffi/src/m68k/sysv.S | 124 |
3 files changed, 183 insertions, 44 deletions
diff --git a/ext/ffi_c/libffi/src/m68k/ffi.c b/ext/ffi_c/libffi/src/m68k/ffi.c index 0d4df1e..0dee938 100644 --- a/ext/ffi_c/libffi/src/m68k/ffi.c +++ b/ext/ffi_c/libffi/src/m68k/ffi.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- ffi.c - - m68k Foreign Function Interface + + m68k Foreign Function Interface ----------------------------------------------------------------------- */ #include <ffi.h> @@ -13,8 +13,13 @@ void rtems_cache_flush_multiple_data_lines( const void *, size_t ); #else #include <sys/syscall.h> +#ifdef __MINT__ +#include <mint/mintbind.h> +#include <mint/ssystem.h> +#else #include <asm/cachectl.h> #endif +#endif void ffi_call_SYSV (extended_cif *, unsigned, unsigned, @@ -39,8 +44,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) argp = stack; - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT - && !ecif->cif->flags) + if ( +#ifdef __MINT__ + (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((ecif->cif->rtype->type == FFI_TYPE_STRUCT) + && !ecif->cif->flags))) struct_value_ptr = ecif->rvalue; else struct_value_ptr = NULL; @@ -51,12 +60,12 @@ ffi_prep_args (void *stack, extended_cif *ecif) i != 0; i--, p_arg++) { - size_t z; + size_t z = (*p_arg)->size; + int type = (*p_arg)->type; - z = (*p_arg)->size; if (z < sizeof (int)) { - switch ((*p_arg)->type) + switch (type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; @@ -75,7 +84,14 @@ ffi_prep_args (void *stack, extended_cif *ecif) break; case FFI_TYPE_STRUCT: +#ifdef __MINT__ + if (z == 1 || z == 2) + memcpy (argp + 2, *p_argv, z); + else + memcpy (argp, *p_argv, z); +#else memcpy (argp + sizeof (int) - z, *p_argv, z); +#endif break; default: @@ -107,6 +123,8 @@ ffi_prep_args (void *stack, extended_cif *ecif) #define CIF_FLAGS_POINTER 32 #define CIF_FLAGS_STRUCT1 64 #define CIF_FLAGS_STRUCT2 128 +#define CIF_FLAGS_SINT8 256 +#define CIF_FLAGS_SINT16 512 /* Perform machine dependent cif processing */ ffi_status @@ -120,17 +138,34 @@ ffi_prep_cif_machdep (ffi_cif *cif) break; case FFI_TYPE_STRUCT: + if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT && + cif->rtype->elements[1]) + { + cif->flags = 0; + break; + } + switch (cif->rtype->size) { case 1: +#ifdef __MINT__ + cif->flags = CIF_FLAGS_STRUCT2; +#else cif->flags = CIF_FLAGS_STRUCT1; +#endif break; case 2: cif->flags = CIF_FLAGS_STRUCT2; break; +#ifdef __MINT__ + case 3: +#endif case 4: cif->flags = CIF_FLAGS_INT; break; +#ifdef __MINT__ + case 7: +#endif case 8: cif->flags = CIF_FLAGS_DINT; break; @@ -150,7 +185,11 @@ ffi_prep_cif_machdep (ffi_cif *cif) #if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE) case FFI_TYPE_LONGDOUBLE: +#ifdef __MINT__ + cif->flags = 0; +#else cif->flags = CIF_FLAGS_LDOUBLE; +#endif break; #endif @@ -163,6 +202,14 @@ ffi_prep_cif_machdep (ffi_cif *cif) cif->flags = CIF_FLAGS_DINT; break; + case FFI_TYPE_SINT16: + cif->flags = CIF_FLAGS_SINT16; + break; + + case FFI_TYPE_SINT8: + cif->flags = CIF_FLAGS_SINT8; + break; + default: cif->flags = CIF_FLAGS_INT; break; @@ -218,6 +265,26 @@ ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif) size_t z; z = (*p_arg)->size; +#ifdef __MINT__ + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 1 || z == 2)) + { + *p_argv = (void *) (argp + 2); + + z = 4; + } + else + if (cif->flags && + cif->rtype->type == FFI_TYPE_STRUCT && + (z == 3 || z == 4)) + { + *p_argv = (void *) (argp); + + z = 4; + } + else +#endif if (z <= 4) { *p_argv = (void *) (argp + 4 - z); @@ -261,19 +328,27 @@ ffi_prep_closure_loc (ffi_closure* closure, void *user_data, void *codeloc) { - FFI_ASSERT (cif->abi == FFI_SYSV); + if (cif->abi != FFI_SYSV) + return FFI_BAD_ABI; *(unsigned short *)closure->tramp = 0x207c; *(void **)(closure->tramp + 2) = codeloc; *(unsigned short *)(closure->tramp + 6) = 0x4ef9; - if (cif->rtype->type == FFI_TYPE_STRUCT - && !cif->flags) + + if ( +#ifdef __MINT__ + (cif->rtype->type == FFI_TYPE_LONGDOUBLE) || +#endif + (((cif->rtype->type == FFI_TYPE_STRUCT) + && !cif->flags))) *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV; else *(void **)(closure->tramp + 8) = ffi_closure_SYSV; #ifdef __rtems__ rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE ); +#elif defined(__MINT__) + Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE); #else syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE, FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE); @@ -285,4 +360,3 @@ ffi_prep_closure_loc (ffi_closure* closure, return FFI_OK; } - diff --git a/ext/ffi_c/libffi/src/m68k/ffitarget.h b/ext/ffi_c/libffi/src/m68k/ffitarget.h index 3b777ed..e81dde2 100644 --- a/ext/ffi_c/libffi/src/m68k/ffitarget.h +++ b/ext/ffi_c/libffi/src/m68k/ffitarget.h @@ -1,5 +1,6 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. + ffitarget.h - Copyright (c) 2012 Anthony Green + Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for Motorola 68K. Permission is hereby granted, free of charge, to any person obtaining @@ -27,6 +28,10 @@ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H +#ifndef LIBFFI_H +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; diff --git a/ext/ffi_c/libffi/src/m68k/sysv.S b/ext/ffi_c/libffi/src/m68k/sysv.S index c782f51..ec2b14f 100644 --- a/ext/ffi_c/libffi/src/m68k/sysv.S +++ b/ext/ffi_c/libffi/src/m68k/sysv.S @@ -1,9 +1,11 @@ /* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1998 Andreas Schwab - Copyright (c) 2008 Red Hat, Inc. - - m68k Foreign Function Interface + sysv.S - Copyright (c) 2012 Alan Hourihane + Copyright (c) 1998, 2012 Andreas Schwab + Copyright (c) 2008 Red Hat, Inc. + Copyright (c) 2012 Thorsten Glaser + + m68k Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -42,13 +44,19 @@ #define CFI_ENDPROC() #endif +#ifdef __MINT__ +#define CALLFUNC(funcname) _ ## funcname +#else +#define CALLFUNC(funcname) funcname +#endif + .text - .globl ffi_call_SYSV - .type ffi_call_SYSV,@function + .globl CALLFUNC(ffi_call_SYSV) + .type CALLFUNC(ffi_call_SYSV),@function .align 4 -ffi_call_SYSV: +CALLFUNC(ffi_call_SYSV): CFI_STARTPROC() link %fp,#0 CFI_OFFSET(14,-8) @@ -63,14 +71,18 @@ ffi_call_SYSV: move.l 8(%fp),-(%sp) pea 4(%sp) #if !defined __PIC__ - jsr ffi_prep_args + jsr CALLFUNC(ffi_prep_args) #else - bsr.l ffi_prep_args@PLTPC + bsr.l CALLFUNC(ffi_prep_args@PLTPC) #endif addq.l #8,%sp | Pass pointer to struct value, if any +#ifdef __MINT__ + move.l %d0,%a1 +#else move.l %a0,%a1 +#endif | Call the function move.l 24(%fp),%a0 @@ -87,7 +99,7 @@ ffi_call_SYSV: | If the return value pointer is NULL, assume no return value. | NOTE: On the mc68000, tst on an address register is not supported. -#if defined(__mc68000__) && !defined(__mcoldfire__) +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) cmp.w #0, %a1 #else tst.l %a1 @@ -109,7 +121,7 @@ retlongint: retfloat: btst #2,%d2 jbeq retdouble -#if defined(__MC68881__) +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.s %fp0,(%a1) #else move.l %d0,(%a1) @@ -119,7 +131,7 @@ retfloat: retdouble: btst #3,%d2 jbeq retlongdouble -#if defined(__MC68881__) +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.d %fp0,(%a1) #else move.l %d0,(%a1)+ @@ -130,7 +142,7 @@ retdouble: retlongdouble: btst #4,%d2 jbeq retpointer -#if defined(__MC68881__) +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.x %fp0,(%a1) #else move.l %d0,(%a1)+ @@ -142,7 +154,11 @@ retlongdouble: retpointer: btst #5,%d2 jbeq retstruct1 +#ifdef __MINT__ + move.l %d0,(%a1) +#else move.l %a0,(%a1) +#endif jbra epilogue retstruct1: @@ -153,8 +169,28 @@ retstruct1: retstruct2: btst #7,%d2 - jbeq noretval + jbeq retsint8 move.w %d0,(%a1) + jbra epilogue + +retsint8: + btst #8,%d2 + jbeq retsint16 + | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32. +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) + ext.w %d0 + ext.l %d0 +#else + extb.l %d0 +#endif + move.l %d0,(%a1) + jbra epilogue + +retsint16: + btst #9,%d2 + jbeq noretval + ext.l %d0 + move.l %d0,(%a1) noretval: epilogue: @@ -162,13 +198,13 @@ epilogue: unlk %fp rts CFI_ENDPROC() - .size ffi_call_SYSV,.-ffi_call_SYSV + .size CALLFUNC(ffi_call_SYSV),.-CALLFUNC(ffi_call_SYSV) - .globl ffi_closure_SYSV - .type ffi_closure_SYSV, @function + .globl CALLFUNC(ffi_closure_SYSV) + .type CALLFUNC(ffi_closure_SYSV), @function .align 4 -ffi_closure_SYSV: +CALLFUNC(ffi_closure_SYSV): CFI_STARTPROC() link %fp,#-12 CFI_OFFSET(14,-8) @@ -178,16 +214,18 @@ ffi_closure_SYSV: pea -12(%fp) move.l %a0,-(%sp) #if !defined __PIC__ - jsr ffi_closure_SYSV_inner + jsr CALLFUNC(ffi_closure_SYSV_inner) #else - bsr.l ffi_closure_SYSV_inner@PLTPC + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) #endif lsr.l #1,%d0 jne 1f jcc .Lcls_epilogue + | CIF_FLAGS_INT move.l -12(%fp),%d0 .Lcls_epilogue: + | no CIF_FLAGS_* unlk %fp rts 1: @@ -195,11 +233,12 @@ ffi_closure_SYSV: lsr.l #2,%d0 jne 1f jcs .Lcls_ret_float + | CIF_FLAGS_DINT move.l (%a0)+,%d0 move.l (%a0),%d1 jra .Lcls_epilogue .Lcls_ret_float: -#if defined(__MC68881__) +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.s (%a0),%fp0 #else move.l (%a0),%d0 @@ -209,7 +248,8 @@ ffi_closure_SYSV: lsr.l #2,%d0 jne 1f jcs .Lcls_ret_ldouble -#if defined(__MC68881__) + | CIF_FLAGS_DOUBLE +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.d (%a0),%fp0 #else move.l (%a0)+,%d0 @@ -217,7 +257,7 @@ ffi_closure_SYSV: #endif jra .Lcls_epilogue .Lcls_ret_ldouble: -#if defined(__MC68881__) +#if defined(__MC68881__) || defined(__HAVE_68881__) fmove.x (%a0),%fp0 #else move.l (%a0)+,%d0 @@ -227,26 +267,46 @@ ffi_closure_SYSV: jra .Lcls_epilogue 1: lsr.l #2,%d0 - jne .Lcls_ret_struct2 + jne 1f jcs .Lcls_ret_struct1 + | CIF_FLAGS_POINTER move.l (%a0),%a0 move.l %a0,%d0 jra .Lcls_epilogue .Lcls_ret_struct1: move.b (%a0),%d0 jra .Lcls_epilogue -.Lcls_ret_struct2: +1: + lsr.l #2,%d0 + jne 1f + jcs .Lcls_ret_sint8 + | CIF_FLAGS_STRUCT2 move.w (%a0),%d0 jra .Lcls_epilogue +.Lcls_ret_sint8: + move.l (%a0),%d0 + | NOTE: On the mc68000, extb is not supported. 8->16, then 16->32. +#if !defined(__mc68020__) && !defined(__mc68030__) && !defined(__mc68040__) && !defined(__mc68060__) && !defined(__mcoldfire__) + ext.w %d0 + ext.l %d0 +#else + extb.l %d0 +#endif + jra .Lcls_epilogue +1: + | CIF_FLAGS_SINT16 + move.l (%a0),%d0 + ext.l %d0 + jra .Lcls_epilogue CFI_ENDPROC() - .size ffi_closure_SYSV,.-ffi_closure_SYSV + .size CALLFUNC(ffi_closure_SYSV),.-CALLFUNC(ffi_closure_SYSV) - .globl ffi_closure_struct_SYSV - .type ffi_closure_struct_SYSV, @function + .globl CALLFUNC(ffi_closure_struct_SYSV) + .type CALLFUNC(ffi_closure_struct_SYSV), @function .align 4 -ffi_closure_struct_SYSV: +CALLFUNC(ffi_closure_struct_SYSV): CFI_STARTPROC() link %fp,#0 CFI_OFFSET(14,-8) @@ -256,14 +316,14 @@ ffi_closure_struct_SYSV: move.l %a1,-(%sp) move.l %a0,-(%sp) #if !defined __PIC__ - jsr ffi_closure_SYSV_inner + jsr CALLFUNC(ffi_closure_SYSV_inner) #else - bsr.l ffi_closure_SYSV_inner@PLTPC + bsr.l CALLFUNC(ffi_closure_SYSV_inner@PLTPC) #endif unlk %fp rts CFI_ENDPROC() - .size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV + .size CALLFUNC(ffi_closure_struct_SYSV),.-CALLFUNC(ffi_closure_struct_SYSV) #if defined __ELF__ && defined __linux__ .section .note.GNU-stack,"",@progbits |