201 lines
4.5 KiB
ArmAsm
201 lines
4.5 KiB
ArmAsm
$NetBSD: patch-src_m88k_elfbsd.S,v 1.1 2013/11/03 23:51:51 jklos Exp $
|
|
|
|
--- src/m88k/elfbsd.S.orig 2013-11-03 22:57:57.000000000 +0000
|
|
+++ src/m88k/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
|