Edit

kc3-lang/libffi/src/vax/elfbsd.S

Branch :

  • Show log

    Commit

  • Author : Anthony Green
    Date : 2013-10-08 06:27:46
    Hash : d2fcbcdf
    Message : Add m88k and VAX support. Update some configury bits.

  • src/vax/elfbsd.S
  • /*
     * 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