summaryrefslogtreecommitdiff
path: root/ext/ffi_c/libffi/src/vax/elfbsd.S
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi_c/libffi/src/vax/elfbsd.S')
-rw-r--r--ext/ffi_c/libffi/src/vax/elfbsd.S195
1 files changed, 195 insertions, 0 deletions
diff --git a/ext/ffi_c/libffi/src/vax/elfbsd.S b/ext/ffi_c/libffi/src/vax/elfbsd.S
new file mode 100644
index 0000000..01ca313
--- /dev/null
+++ b/ext/ffi_c/libffi/src/vax/elfbsd.S
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2013 Miodrag Vallat. <miod@openbsd.org>
+ *
+ * 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.
+ */
+
+/*
+ * vax Foreign Function Interface
+ */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+ .text
+
+/*
+ * void * %r0
+ * ffi_call_elfbsd(extended_cif *ecif, 4(%ap)
+ * unsigned bytes, 8(%ap)
+ * unsigned flags, 12(%ap)
+ * void *rvalue, 16(%ap)
+ * void (*fn)()); 20(%ap)
+ */
+ .globl ffi_call_elfbsd
+ .type ffi_call_elfbsd,@function
+ .align 2
+ffi_call_elfbsd:
+ .word 0x00c # save R2 and R3
+
+ # Allocate stack space for the args
+ subl2 8(%ap), %sp
+
+ # Call ffi_prep_args
+ pushl %sp
+ pushl 4(%ap)
+ calls $2, ffi_prep_args
+
+ # Get function pointer
+ movl 20(%ap), %r1
+
+ # Build a CALLS frame
+ ashl $-2, 8(%ap), %r0
+ pushl %r0 # argument stack usage
+ movl %sp, %r0 # future %ap
+ # saved registers
+ bbc $11, 0(%r1), 1f
+ pushl %r11
+1: bbc $10, 0(%r1), 1f
+ pushl %r10
+1: bbc $9, 0(%r1), 1f
+ pushl %r9
+1: bbc $8, 0(%r1), 1f
+ pushl %r8
+1: bbc $7, 0(%r1), 1f
+ pushl %r7
+1: bbc $6, 0(%r1), 1f
+ pushl %r6
+1: bbc $5, 0(%r1), 1f
+ pushl %r5
+1: bbc $4, 0(%r1), 1f
+ pushl %r4
+1: bbc $3, 0(%r1), 1f
+ pushl %r3
+1: bbc $2, 0(%r1), 1f
+ pushl %r2
+1:
+ pushal 9f
+ pushl %fp
+ pushl %ap
+ movl 16(%ap), %r3 # struct return address, if needed
+ movl %r0, %ap
+ movzwl 4(%fp), %r0 # previous PSW, without the saved registers mask
+ bisl2 $0x20000000, %r0 # calls frame
+ movzwl 0(%r1), %r2
+ bicw2 $0xf003, %r2 # only keep R11-R2
+ ashl $16, %r2, %r2
+ bisl2 %r2, %r0 # saved register mask of the called function
+ pushl %r0
+ pushl $0
+ movl %sp, %fp
+
+ # Invoke the function
+ pushal 2(%r1) # skip procedure entry mask
+ movl %r3, %r1
+ bicpsw $0x000f
+ rsb
+
+9:
+ # Copy return value if necessary
+ tstl 16(%ap)
+ jeql 9f
+ movl 16(%ap), %r2
+
+ bbc $0, 12(%ap), 1f # CIF_FLAGS_CHAR
+ movb %r0, 0(%r2)
+ brb 9f
+1:
+ bbc $1, 12(%ap), 1f # CIF_FLAGS_SHORT
+ movw %r0, 0(%r2)
+ brb 9f
+1:
+ bbc $2, 12(%ap), 1f # CIF_FLAGS_INT
+ movl %r0, 0(%r2)
+ brb 9f
+1:
+ bbc $3, 12(%ap), 1f # CIF_FLAGS_DINT
+ movq %r0, 0(%r2)
+ brb 9f
+1:
+ movl %r1, %r0 # might have been a struct
+ #brb 9f
+
+9:
+ ret
+
+/*
+ * ffi_closure_elfbsd(void);
+ * invoked with %r0: ffi_closure *closure
+ */
+ .globl ffi_closure_elfbsd
+ .type ffi_closure_elfbsd, @function
+ .align 2
+ffi_closure_elfbsd:
+ .word 0
+
+ # Allocate room on stack for return value
+ subl2 $8, %sp
+
+ # Invoke the closure function
+ pushal 4(%ap) # calling stack
+ pushal 4(%sp) # return value
+ pushl %r0 # closure
+ calls $3, ffi_closure_elfbsd_inner
+
+ # Copy return value if necessary
+ bitb $1, %r0 # CIF_FLAGS_CHAR
+ beql 1f
+ movb 0(%sp), %r0
+ brb 9f
+1:
+ bitb $2, %r0 # CIF_FLAGS_SHORT
+ beql 1f
+ movw 0(%sp), %r0
+ brb 9f
+1:
+ bitb $4, %r0 # CIF_FLAGS_INT
+ beql 1f
+ movl 0(%sp), %r0
+ brb 9f
+1:
+ bitb $8, %r0 # CIF_FLAGS_DINT
+ beql 1f
+ movq 0(%sp), %r0
+ #brb 9f
+1:
+
+9:
+ ret
+
+/*
+ * ffi_closure_struct_elfbsd(void);
+ * invoked with %r0: ffi_closure *closure
+ * %r1: struct return address
+ */
+ .globl ffi_closure_struct_elfbsd
+ .type ffi_closure_struct_elfbsd, @function
+ .align 2
+ffi_closure_struct_elfbsd:
+ .word 0
+
+ # Invoke the closure function
+ pushal 4(%ap) # calling stack
+ pushl %r1 # return value
+ pushl %r0 # closure
+ calls $3, ffi_closure_elfbsd_inner
+
+ ret