diff options
Diffstat (limited to 'ext/ffi_c/libffi/src/moxie')
-rw-r--r-- | ext/ffi_c/libffi/src/moxie/eabi.S | 137 | ||||
-rw-r--r-- | ext/ffi_c/libffi/src/moxie/ffi.c | 82 | ||||
-rw-r--r-- | ext/ffi_c/libffi/src/moxie/ffitarget.h | 52 |
3 files changed, 146 insertions, 125 deletions
diff --git a/ext/ffi_c/libffi/src/moxie/eabi.S b/ext/ffi_c/libffi/src/moxie/eabi.S index 379ea4b..ac7aceb 100644 --- a/ext/ffi_c/libffi/src/moxie/eabi.S +++ b/ext/ffi_c/libffi/src/moxie/eabi.S @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- - eabi.S - Copyright (c) 2004 Anthony Green + eabi.S - Copyright (c) 2012, 2013 Anthony Green - FR-V Assembly glue. + Moxie Assembly glue. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -34,95 +34,68 @@ .globl ffi_call_EABI .type ffi_call_EABI, @function - # gr8 : ffi_prep_args - # gr9 : &ecif - # gr10: cif->bytes - # gr11: fig->flags - # gr12: ecif.rvalue - # gr13: fn + # $r0 : ffi_prep_args + # $r1 : &ecif + # $r2 : cif->bytes + # $r3 : fig->flags + # $r4 : ecif.rvalue + # $r5 : fn -ffi_call_EABI: - addi sp, #-80, sp - sti fp, @(sp, #24) - addi sp, #24, fp - movsg lr, gr5 +ffi_call_EABI: + push $sp, $r6 + push $sp, $r7 + push $sp, $r8 + dec $sp, 24 - /* Make room for the new arguments. */ - /* subi sp, fp, gr10 */ - - /* Store return address and incoming args on stack. */ - sti gr5, @(fp, #8) - sti gr8, @(fp, #-4) - sti gr9, @(fp, #-8) - sti gr10, @(fp, #-12) - sti gr11, @(fp, #-16) - sti gr12, @(fp, #-20) - sti gr13, @(fp, #-24) - - sub sp, gr10, sp + /* Store incoming args on stack. */ + sto.l 0($sp), $r0 /* ffi_prep_args */ + sto.l 4($sp), $r1 /* ecif */ + sto.l 8($sp), $r2 /* bytes */ + sto.l 12($sp), $r3 /* flags */ + sto.l 16($sp), $r4 /* &rvalue */ + sto.l 20($sp), $r5 /* fn */ /* Call ffi_prep_args. */ - ldi @(fp, #-4), gr4 - addi sp, #0, gr8 - ldi @(fp, #-8), gr9 -#ifdef __FRV_FDPIC__ - ldd @(gr4, gr0), gr14 - calll @(gr14, gr0) -#else - calll @(gr4, gr0) -#endif - - /* ffi_prep_args returns the new stack pointer. */ - mov gr8, gr4 - - ldi @(sp, #0), gr8 - ldi @(sp, #4), gr9 - ldi @(sp, #8), gr10 - ldi @(sp, #12), gr11 - ldi @(sp, #16), gr12 - ldi @(sp, #20), gr13 + mov $r6, $r4 /* Save result buffer */ + mov $r7, $r5 /* Save the target fn */ + mov $r8, $r3 /* Save the flags */ + sub.l $sp, $r2 /* Allocate stack space */ + mov $r0, $sp /* We can stomp over $r0 */ + /* $r1 is already set up */ + jsra ffi_prep_args - /* Always copy the return value pointer into the hidden - parameter register. This is only strictly necessary - when we're returning an aggregate type, but it doesn't - hurt to do this all the time, and it saves a branch. */ - ldi @(fp, #-20), gr3 - - /* Use the ffi_prep_args return value for the new sp. */ - mov gr4, sp + /* Load register arguments. */ + ldo.l $r0, 0($sp) + ldo.l $r1, 4($sp) + ldo.l $r2, 8($sp) + ldo.l $r3, 12($sp) + ldo.l $r4, 16($sp) + ldo.l $r5, 20($sp) /* Call the target function. */ - ldi @(fp, -24), gr4 -#ifdef __FRV_FDPIC__ - ldd @(gr4, gr0), gr14 - calll @(gr14, gr0) -#else - calll @(gr4, gr0) -#endif + jsr $r7 + + ldi.l $r7, 0xffffffff + cmp $r8, $r7 + beq retstruct + + ldi.l $r7, 4 + cmp $r8, $r7 + bgt ret2reg - /* Store the result. */ - ldi @(fp, #-16), gr10 /* fig->flags */ - ldi @(fp, #-20), gr4 /* ecif.rvalue */ + st.l ($r6), $r0 + jmpa retdone - /* Is the return value stored in two registers? */ - cmpi gr10, #8, icc0 - bne icc0, 0, .L2 - /* Yes, save them. */ - sti gr8, @(gr4, #0) - sti gr9, @(gr4, #4) - bra .L3 -.L2: - /* Is the return value a structure? */ - cmpi gr10, #-1, icc0 - beq icc0, 0, .L3 - /* No, save a 4 byte return value. */ - sti gr8, @(gr4, #0) -.L3: +ret2reg: + st.l ($r6), $r0 + sto.l 4($r6), $r1 - /* Restore the stack, and return. */ - ldi @(fp, 8), gr5 - ld @(fp, gr0), fp - addi sp,#80,sp - jmpl @(gr5,gr0) +retstruct: +retdone: + /* Return. */ + ldo.l $r6, -4($fp) + ldo.l $r7, -8($fp) + ldo.l $r8, -12($fp) + ret .size ffi_call_EABI, .-ffi_call_EABI diff --git a/ext/ffi_c/libffi/src/moxie/ffi.c b/ext/ffi_c/libffi/src/moxie/ffi.c index 54cbbb9..540a042 100644 --- a/ext/ffi_c/libffi/src/moxie/ffi.c +++ b/ext/ffi_c/libffi/src/moxie/ffi.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (C) 2009 Anthony Green + ffi.c - Copyright (C) 2012, 2013 Anthony Green Moxie Foreign Function Interface @@ -43,6 +43,12 @@ void *ffi_prep_args(char *stack, extended_cif *ecif) p_argv = ecif->avalue; argp = stack; + if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) + { + *(void **) argp = ecif->rvalue; + argp += 4; + } + for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; (i != 0); i--, p_arg++) @@ -56,17 +62,6 @@ void *ffi_prep_args(char *stack, extended_cif *ecif) z = sizeof(void*); *(void **) argp = *p_argv; } - /* if ((*p_arg)->type == FFI_TYPE_FLOAT) - { - if (count > 24) - { - // This is going on the stack. Turn it into a double. - *(double *) argp = (double) *(float*)(* p_argv); - z = sizeof(double); - } - else - *(void **) argp = *(void **)(* p_argv); - } */ else if (z < sizeof(int)) { z = sizeof(int); @@ -147,8 +142,7 @@ void ffi_call(ffi_cif *cif, } else ecif.rvalue = rvalue; - - + switch (cif->abi) { case FFI_EABI: @@ -165,19 +159,25 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, unsigned arg4, unsigned arg5, unsigned arg6) { /* This function is called by a trampoline. The trampoline stows a - pointer to the ffi_closure object in gr7. We must save this + pointer to the ffi_closure object in $r7. We must save this pointer in a place that will persist while we do our work. */ - register ffi_closure *creg __asm__ ("gr7"); + register ffi_closure *creg __asm__ ("$r12"); ffi_closure *closure = creg; /* Arguments that don't fit in registers are found on the stack at a fixed offset above the current frame pointer. */ - register char *frame_pointer __asm__ ("fp"); - char *stack_args = frame_pointer + 16; + register char *frame_pointer __asm__ ("$fp"); + + /* Pointer to a struct return value. */ + void *struct_rvalue = (void *) arg1; + + /* 6 words reserved for register args + 3 words from jsr */ + char *stack_args = frame_pointer + 9*4; /* Lay the register arguments down in a continuous chunk of memory. */ unsigned register_args[6] = { arg1, arg2, arg3, arg4, arg5, arg6 }; + char *register_args_ptr = (char *) register_args; ffi_cif *cif = closure->cif; ffi_type **arg_types = cif->arg_types; @@ -185,6 +185,12 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, char *ptr = (char *) register_args; int i; + /* preserve struct type return pointer passing */ + if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { + ptr += 4; + register_args_ptr = (char *)®ister_args[1]; + } + /* Find the address of each argument. */ for (i = 0; i < cif->nargs; i++) { @@ -201,6 +207,7 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, case FFI_TYPE_SINT32: case FFI_TYPE_UINT32: case FFI_TYPE_FLOAT: + case FFI_TYPE_POINTER: avalue[i] = ptr; break; case FFI_TYPE_STRUCT: @@ -216,30 +223,21 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3, /* If we've handled more arguments than fit in registers, start looking at the those passed on the stack. */ - if (ptr == ((char *)register_args + (6*4))) + if (ptr == ®ister_args[6]) ptr = stack_args; } /* Invoke the closure. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) + if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT)) { - /* The caller allocates space for the return structure, and - passes a pointer to this space in gr3. Use this value directly - as the return value. */ - register void *return_struct_ptr __asm__("gr3"); - (closure->fun) (cif, return_struct_ptr, avalue, closure->user_data); + (closure->fun) (cif, struct_rvalue, avalue, closure->user_data); } else { /* Allocate space for the return value and call the function. */ long long rvalue; (closure->fun) (cif, &rvalue, avalue, closure->user_data); - - /* Functions return 4-byte or smaller results in gr8. 8-byte - values also use gr9. We fill the both, even for small return - values, just to avoid a branch. */ - asm ("ldi @(%0, #0), gr8" : : "r" (&rvalue)); - asm ("ldi @(%0, #0), gr9" : : "r" (&((int *) &rvalue)[1])); + asm ("mov $r12, %0\n ld.l $r0, ($r12)\n ldo.l $r1, 4($r12)" : : "r" (&rvalue)); } } @@ -250,27 +248,25 @@ ffi_prep_closure_loc (ffi_closure* closure, void *user_data, void *codeloc) { - unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + unsigned short *tramp = (unsigned short *) &closure->tramp[0]; unsigned long fn = (long) ffi_closure_eabi; unsigned long cls = (long) codeloc; - int i; + + if (cif->abi != FFI_EABI) + return FFI_BAD_ABI; fn = (unsigned long) ffi_closure_eabi; - tramp[0] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ - tramp[1] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ - tramp[2] = 0x8cf80000 + (fn >> 16); /* sethi hi(fn), gr6 */ - tramp[3] = 0x8ef80000 + (cls >> 16); /* sethi hi(cls), gr7 */ - tramp[4] = 0x80300006; /* jmpl @(gr0, gr6) */ + tramp[0] = 0x01e0; /* ldi.l $r7, .... */ + tramp[1] = cls >> 16; + tramp[2] = cls & 0xffff; + tramp[3] = 0x1a00; /* jmpa .... */ + tramp[4] = fn >> 16; + tramp[5] = fn & 0xffff; closure->cif = cif; closure->fun = fun; closure->user_data = user_data; - /* Cache flushing. */ - for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) - __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i), - "r" (codeloc)); - return FFI_OK; } diff --git a/ext/ffi_c/libffi/src/moxie/ffitarget.h b/ext/ffi_c/libffi/src/moxie/ffitarget.h new file mode 100644 index 0000000..623e3ec --- /dev/null +++ b/ext/ffi_c/libffi/src/moxie/ffitarget.h @@ -0,0 +1,52 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - Copyright (c) 2012, 2013 Anthony Green + Target configuration macros for Moxie + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + ----------------------------------------------------------------------- */ + +#ifndef LIBFFI_TARGET_H +#define LIBFFI_TARGET_H + +/* ---- System specific configurations ----------------------------------- */ + +#ifndef LIBFFI_ASM +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + +typedef enum ffi_abi { + FFI_FIRST_ABI = 0, + FFI_EABI, + FFI_DEFAULT_ABI = FFI_EABI, + FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 +} ffi_abi; +#endif + +/* ---- Definitions for closures ----------------------------------------- */ + +#define FFI_CLOSURES 1 +#define FFI_NATIVE_RAW_API 0 + +/* Trampolines are 12-bytes long. See ffi_prep_closure_loc. */ +#define FFI_TRAMPOLINE_SIZE (12) + +#endif |