1baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com/*
2baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * Copyright (c) 2013 Miodrag Vallat.  <miod@openbsd.org>
3baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *
4baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * Permission is hereby granted, free of charge, to any person obtaining
5baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * a copy of this software and associated documentation files (the
6baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * ``Software''), to deal in the Software without restriction, including
7baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * without limitation the rights to use, copy, modify, merge, publish,
8baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * distribute, sublicense, and/or sell copies of the Software, and to
9baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * permit persons to whom the Software is furnished to do so, subject to
10baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * the following conditions:
11baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *
12baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * The above copyright notice and this permission notice shall be included
13baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * in all copies or substantial portions of the Software.
14baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *
15baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
16baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com */
23baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
24baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com/*
25baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * vax Foreign Function Interface
26baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com */
27baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
28baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com#define LIBFFI_ASM
29baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com#include <fficonfig.h>
30baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com#include <ffi.h>
31baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
32baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.text
33baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
34baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com/*
35baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * void *					%r0
36baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * ffi_call_elfbsd(extended_cif *ecif,		4(%ap)
37baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *		   unsigned bytes,		8(%ap)
38baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *		   unsigned flags,		12(%ap)
39baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *		   void *rvalue,		16(%ap)
40baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *		   void (*fn)());		20(%ap)
41baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com */
42baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.globl	ffi_call_elfbsd
43baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.type	ffi_call_elfbsd,@function
44baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.align	2
45baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.comffi_call_elfbsd:
46baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.word	0x00c		# save R2 and R3
47baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
48baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Allocate stack space for the args
49baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	subl2	8(%ap), %sp
50baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
51baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Call ffi_prep_args
52baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%sp
53baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	4(%ap)
54baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	calls	$2, ffi_prep_args
55baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
56baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Get function pointer
57baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	20(%ap), %r1
58baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
59baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Build a CALLS frame
60baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	ashl	$-2, 8(%ap), %r0
61baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r0		# argument stack usage
62baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%sp, %r0	# future %ap
63baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# saved registers
64baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bbc	$11, 0(%r1), 1f
65baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r11
66baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$10, 0(%r1), 1f
67baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r10
68baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$9, 0(%r1), 1f
69baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r9
70baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$8, 0(%r1), 1f
71baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r8
72baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$7, 0(%r1), 1f
73baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r7
74baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$6, 0(%r1), 1f
75baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r6
76baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$5, 0(%r1), 1f
77baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r5
78baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$4, 0(%r1), 1f
79baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r4
80baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$3, 0(%r1), 1f
81baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r3
82baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:	bbc	$2, 0(%r1), 1f
83baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r2
84baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
85baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushal	9f
86baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%fp
87baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%ap
88baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	16(%ap), %r3	# struct return address, if needed
89baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%r0, %ap
90baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movzwl	4(%fp), %r0	# previous PSW, without the saved registers mask
91baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bisl2	$0x20000000, %r0 # calls frame
92baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movzwl	0(%r1), %r2
93baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bicw2	$0xf003, %r2	# only keep R11-R2
94baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	ashl	$16, %r2, %r2
95baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bisl2	%r2, %r0	# saved register mask of the called function
96baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r0
97baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	$0
98baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%sp, %fp
99baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
100baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Invoke the function
101baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushal	2(%r1)		# skip procedure entry mask
102baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%r3, %r1
103baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bicpsw	$0x000f
104baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	rsb
105baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
106baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com9:
107baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Copy return value if necessary
108baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	tstl	16(%ap)
109baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	jeql	9f
110baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	16(%ap), %r2
111baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
112baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bbc	$0, 12(%ap), 1f	# CIF_FLAGS_CHAR
113baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movb	%r0, 0(%r2)
114baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
115baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
116baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bbc	$1, 12(%ap), 1f	# CIF_FLAGS_SHORT
117baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movw	%r0, 0(%r2)
118baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
119baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
120baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bbc	$2, 12(%ap), 1f	# CIF_FLAGS_INT
121baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%r0, 0(%r2)
122baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
123baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
124baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bbc	$3, 12(%ap), 1f	# CIF_FLAGS_DINT
125baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movq	%r0, 0(%r2)
126baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
127baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
128baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	%r1, %r0	# might have been a struct
129baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	#brb	9f
130baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
131baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com9:
132baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	ret
133baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
134baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com/*
135baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * ffi_closure_elfbsd(void);
136baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * invoked with	%r0: ffi_closure *closure
137baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com */
138baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.globl	ffi_closure_elfbsd
139baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.type	ffi_closure_elfbsd, @function
140baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.align	2
141baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.comffi_closure_elfbsd:
142baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.word	0
143baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
144baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Allocate room on stack for return value
145baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	subl2	$8, %sp
146baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
147baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Invoke the closure function
148baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushal	4(%ap)		# calling stack
149baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushal	4(%sp)		# return value
150baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r0		# closure
151baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	calls	$3, ffi_closure_elfbsd_inner
152baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
153baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Copy return value if necessary
154baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bitb	$1, %r0		# CIF_FLAGS_CHAR
155baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	beql	1f
156baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movb	0(%sp), %r0
157baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
158baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
159baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bitb	$2, %r0		# CIF_FLAGS_SHORT
160baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	beql	1f
161baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movw	0(%sp), %r0
162baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
163baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
164baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bitb	$4, %r0		# CIF_FLAGS_INT
165baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	beql	1f
166baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movl	0(%sp), %r0
167baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	brb	9f
168baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
169baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	bitb	$8, %r0		# CIF_FLAGS_DINT
170baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	beql	1f
171baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	movq	0(%sp), %r0
172baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	#brb	9f
173baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com1:
174baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
175baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com9:
176baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	ret
177baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
178baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com/*
179baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * ffi_closure_struct_elfbsd(void);
180baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com * invoked with	%r0: ffi_closure *closure
181baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com *		%r1: struct return address
182baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com */
183baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.globl	ffi_closure_struct_elfbsd
184baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.type	ffi_closure_struct_elfbsd, @function
185baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.align	2
186baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.comffi_closure_struct_elfbsd:
187baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	.word	0
188baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
189baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	# Invoke the closure function
190baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushal	4(%ap)		# calling stack
191baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r1		# return value
192baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	pushl	%r0		# closure
193baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	calls	$3, ffi_closure_elfbsd_inner
194baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com
195baa84b827b80380ff181757e2997e5648e69b1e4doko@ubuntu.com	ret
196