summaryrefslogtreecommitdiff
path: root/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie
diff options
context:
space:
mode:
Diffstat (limited to 'jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie')
-rw-r--r--jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/eabi.S101
-rw-r--r--jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffi.c272
-rw-r--r--jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffitarget.h52
3 files changed, 425 insertions, 0 deletions
diff --git a/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/eabi.S b/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/eabi.S
new file mode 100644
index 0000000..ac7aceb
--- /dev/null
+++ b/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/eabi.S
@@ -0,0 +1,101 @@
+/* -----------------------------------------------------------------------
+ eabi.S - Copyright (c) 2012, 2013 Anthony Green
+
+ Moxie Assembly glue.
+
+ 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 AUTHOR 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .globl ffi_prep_args_EABI
+
+ .text
+ .p2align 4
+ .globl ffi_call_EABI
+ .type ffi_call_EABI, @function
+
+ # $r0 : ffi_prep_args
+ # $r1 : &ecif
+ # $r2 : cif->bytes
+ # $r3 : fig->flags
+ # $r4 : ecif.rvalue
+ # $r5 : fn
+
+ffi_call_EABI:
+ push $sp, $r6
+ push $sp, $r7
+ push $sp, $r8
+ dec $sp, 24
+
+ /* 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. */
+ 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
+
+ /* 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. */
+ jsr $r7
+
+ ldi.l $r7, 0xffffffff
+ cmp $r8, $r7
+ beq retstruct
+
+ ldi.l $r7, 4
+ cmp $r8, $r7
+ bgt ret2reg
+
+ st.l ($r6), $r0
+ jmpa retdone
+
+ret2reg:
+ st.l ($r6), $r0
+ sto.l 4($r6), $r1
+
+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/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffi.c b/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffi.c
new file mode 100644
index 0000000..540a042
--- /dev/null
+++ b/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffi.c
@@ -0,0 +1,272 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (C) 2012, 2013 Anthony Green
+
+ Moxie Foreign Function Interface
+
+ 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+void *ffi_prep_args(char *stack, extended_cif *ecif)
+{
+ register unsigned int i;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+ register int count = 0;
+
+ 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++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+
+ if ((*p_arg)->type == FFI_TYPE_STRUCT)
+ {
+ z = sizeof(void*);
+ *(void **) argp = *p_argv;
+ }
+ else if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ count += z;
+ }
+
+ return (stack + ((count > 24) ? 24 : ALIGN_DOWN(count, 8)));
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ cif->flags = -1;
+ else
+ cif->flags = cif->rtype->size;
+
+ cif->bytes = ALIGN (cif->bytes, 8);
+
+ return FFI_OK;
+}
+
+extern void ffi_call_EABI(void *(*)(char *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned,
+ unsigned *,
+ void (*fn)(void));
+
+void ffi_call(ffi_cif *cif,
+ void (*fn)(void),
+ void *rvalue,
+ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = 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))
+ {
+ ecif.rvalue = alloca(cif->rtype->size);
+ }
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_EABI:
+ ffi_call_EABI(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+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 $r7. We must save this
+ pointer in a place that will persist while we do our work. */
+ 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");
+
+ /* 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;
+ void **avalue = alloca (cif->nargs * sizeof(void *));
+ 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 *)&register_args[1];
+ }
+
+ /* Find the address of each argument. */
+ for (i = 0; i < cif->nargs; i++)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ avalue[i] = ptr + 3;
+ break;
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ avalue[i] = ptr + 2;
+ break;
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_POINTER:
+ avalue[i] = ptr;
+ break;
+ case FFI_TYPE_STRUCT:
+ avalue[i] = *(void**)ptr;
+ break;
+ default:
+ /* This is an 8-byte value. */
+ avalue[i] = ptr;
+ ptr += 4;
+ break;
+ }
+ ptr += 4;
+
+ /* If we've handled more arguments than fit in registers,
+ start looking at the those passed on the stack. */
+ if (ptr == &register_args[6])
+ ptr = stack_args;
+ }
+
+ /* Invoke the closure. */
+ if (cif->rtype && (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ (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);
+ asm ("mov $r12, %0\n ld.l $r0, ($r12)\n ldo.l $r1, 4($r12)" : : "r" (&rvalue));
+ }
+}
+
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data,
+ void *codeloc)
+{
+ unsigned short *tramp = (unsigned short *) &closure->tramp[0];
+ unsigned long fn = (long) ffi_closure_eabi;
+ unsigned long cls = (long) codeloc;
+
+ if (cif->abi != FFI_EABI)
+ return FFI_BAD_ABI;
+
+ fn = (unsigned long) ffi_closure_eabi;
+
+ 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;
+
+ return FFI_OK;
+}
diff --git a/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffitarget.h b/jni/ruby/ext/fiddle/libffi-3.2.1/src/moxie/ffitarget.h
new file mode 100644
index 0000000..623e3ec
--- /dev/null
+++ b/jni/ruby/ext/fiddle/libffi-3.2.1/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