summaryrefslogtreecommitdiff
path: root/js/src/ctypes/libffi/src/avr32/sysv.S
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/ctypes/libffi/src/avr32/sysv.S')
-rw-r--r--js/src/ctypes/libffi/src/avr32/sysv.S208
1 files changed, 208 insertions, 0 deletions
diff --git a/js/src/ctypes/libffi/src/avr32/sysv.S b/js/src/ctypes/libffi/src/avr32/sysv.S
new file mode 100644
index 0000000..a984b3c
--- /dev/null
+++ b/js/src/ctypes/libffi/src/avr32/sysv.S
@@ -0,0 +1,208 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2009 Bradley Smith <brad@brad-smith.co.uk>
+
+ AVR32 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.
+ --------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ /* r12: ffi_prep_args
+ * r11: &ecif
+ * r10: size
+ * r9: cif->flags
+ * r8: ecif.rvalue
+ * sp+0: cif->rstruct_flag
+ * sp+4: fn */
+
+ .text
+ .align 1
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV, @function
+ffi_call_SYSV:
+ stm --sp, r0,r1,lr
+ stm --sp, r8-r12
+ mov r0, sp
+
+ /* Make room for all of the new args. */
+ sub sp, r10
+ /* Pad to make way for potential skipped registers */
+ sub sp, 20
+
+ /* Call ffi_prep_args(stack, &ecif). */
+ /* r11 already set */
+ mov r1, r12
+ mov r12, sp
+ icall r1
+
+ /* Save new argument size */
+ mov r1, r12
+
+ /* Move first 5 parameters in registers. */
+ ldm sp++, r8-r12
+
+ /* call (fn) (...). */
+ ld.w r1, r0[36]
+ icall r1
+
+ /* Remove the space we pushed for the args. */
+ mov sp, r0
+
+ /* Load r1 with the rstruct flag. */
+ ld.w r1, sp[32]
+
+ /* Load r9 with the return type code. */
+ ld.w r9, sp[12]
+
+ /* Load r8 with the return value pointer. */
+ ld.w r8, sp[16]
+
+ /* If the return value pointer is NULL, assume no return value. */
+ cp.w r8, 0
+ breq .Lend
+
+ /* Check if return type is actually a struct */
+ cp.w r1, 0
+ breq 1f
+
+ /* Return 8bit */
+ cp.w r9, FFI_TYPE_UINT8
+ breq .Lstore8
+
+ /* Return 16bit */
+ cp.w r9, FFI_TYPE_UINT16
+ breq .Lstore16
+
+1:
+ /* Return 32bit */
+ cp.w r9, FFI_TYPE_UINT32
+ breq .Lstore32
+ cp.w r9, FFI_TYPE_UINT16
+ breq .Lstore32
+ cp.w r9, FFI_TYPE_UINT8
+ breq .Lstore32
+
+ /* Return 64bit */
+ cp.w r9, FFI_TYPE_UINT64
+ breq .Lstore64
+
+ /* Didn't match anything */
+ bral .Lend
+
+.Lstore64:
+ st.w r8[0], r11
+ st.w r8[4], r10
+ bral .Lend
+
+.Lstore32:
+ st.w r8[0], r12
+ bral .Lend
+
+.Lstore16:
+ st.h r8[0], r12
+ bral .Lend
+
+.Lstore8:
+ st.b r8[0], r12
+ bral .Lend
+
+.Lend:
+ sub sp, -20
+ ldm sp++, r0,r1,pc
+
+ .size ffi_call_SYSV, . - ffi_call_SYSV
+
+
+ /* r12: __ctx
+ * r11: __rstruct_flag
+ * r10: __inner */
+
+ .align 1
+ .globl ffi_closure_SYSV
+ .type ffi_closure_SYSV, @function
+ffi_closure_SYSV:
+ stm --sp, r0,lr
+ mov r0, r11
+ mov r8, r10
+ sub r10, sp, -8
+ sub sp, 12
+ st.w sp[8], sp
+ sub r11, sp, -8
+ icall r8
+
+ /* Check if return type is actually a struct */
+ cp.w r0, 0
+ breq 1f
+
+ /* Return 8bit */
+ cp.w r12, FFI_TYPE_UINT8
+ breq .Lget8
+
+ /* Return 16bit */
+ cp.w r12, FFI_TYPE_UINT16
+ breq .Lget16
+
+1:
+ /* Return 32bit */
+ cp.w r12, FFI_TYPE_UINT32
+ breq .Lget32
+ cp.w r12, FFI_TYPE_UINT16
+ breq .Lget32
+ cp.w r12, FFI_TYPE_UINT8
+ breq .Lget32
+
+ /* Return 64bit */
+ cp.w r12, FFI_TYPE_UINT64
+ breq .Lget64
+
+ /* Didn't match anything */
+ bral .Lclend
+
+.Lget64:
+ ld.w r11, sp[0]
+ ld.w r10, sp[4]
+ bral .Lclend
+
+.Lget32:
+ ld.w r12, sp[0]
+ bral .Lclend
+
+.Lget16:
+ ld.uh r12, sp[0]
+ bral .Lclend
+
+.Lget8:
+ ld.ub r12, sp[0]
+ bral .Lclend
+
+.Lclend:
+ sub sp, -12
+ ldm sp++, r0,lr
+ sub sp, -20
+ mov pc, lr
+
+ .size ffi_closure_SYSV, . - ffi_closure_SYSV
+
+#if defined __ELF__ && defined __linux__
+ .section .note.GNU-stack,"",@progbits
+#endif