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