SysV/m68k, which NetBSD and OpenBSD follow). Add m88k/ELF support. Add vax/a.out support. All tests from the libffi.call dejagnu testsuite pass on these three platforms. ok jasper@
210 lines
4.8 KiB
ArmAsm
210 lines
4.8 KiB
ArmAsm
/*
|
|
* Copyright (c) 2013 Miodrag Vallat.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* m88k Foreign Function Interface
|
|
*/
|
|
|
|
#define LIBFFI_ASM
|
|
#include <fficonfig.h>
|
|
#include <ffi.h>
|
|
|
|
.text
|
|
|
|
/*
|
|
* ffi_cacheflush_OBSD(unsigned int addr, %r2
|
|
* unsigned int size); %r3
|
|
*/
|
|
.align 4
|
|
.globl ffi_cacheflush_OBSD
|
|
.type ffi_cacheflush_OBSD,@function
|
|
ffi_cacheflush_OBSD:
|
|
tb0 0, %r0, 451
|
|
or %r0, %r0, %r0
|
|
jmp %r1
|
|
.size ffi_cacheflush_OBSD, . - ffi_cacheflush_OBSD
|
|
|
|
/*
|
|
* ffi_call_OBSD(unsigned bytes, %r2
|
|
* extended_cif *ecif, %r3
|
|
* unsigned flags, %r4
|
|
* void *rvalue, %r5
|
|
* void (*fn)()); %r6
|
|
*/
|
|
.align 4
|
|
.globl ffi_call_OBSD
|
|
.type ffi_call_OBSD,@function
|
|
ffi_call_OBSD:
|
|
subu %r31, %r31, 32
|
|
st %r30, %r31, 4
|
|
st %r1, %r31, 0
|
|
addu %r30, %r31, 32
|
|
|
|
| Save the few arguments we'll need after ffi_prep_args()
|
|
st.d %r4, %r31, 8
|
|
st %r6, %r31, 16
|
|
|
|
| Allocate room for the image of r2-r9, and the stack space for
|
|
| the args (rounded to a 16-byte boundary)
|
|
addu %r2, %r2, (8 * 4) + 15
|
|
clr %r2, %r2, 4<0>
|
|
subu %r31, %r31, %r2
|
|
|
|
| Fill register and stack image
|
|
or %r2, %r31, %r0
|
|
#ifdef PIC
|
|
bsr ffi_prep_args#plt
|
|
#else
|
|
bsr ffi_prep_args
|
|
#endif
|
|
|
|
| Save pointer to return struct address, if any
|
|
or %r12, %r2, %r0
|
|
|
|
| Get function pointer
|
|
subu %r4, %r30, 32
|
|
ld %r1, %r4, 16
|
|
|
|
| Fetch the register arguments
|
|
ld.d %r2, %r31, (0 * 4)
|
|
ld.d %r4, %r31, (2 * 4)
|
|
ld.d %r6, %r31, (4 * 4)
|
|
ld.d %r8, %r31, (6 * 4)
|
|
addu %r31, %r31, (8 * 4)
|
|
|
|
| Invoke the function
|
|
jsr %r1
|
|
|
|
| Restore stack now that we don't need the args anymore
|
|
subu %r31, %r30, 32
|
|
|
|
| Figure out what to return as the function's return value
|
|
ld %r5, %r31, 12 | rvalue
|
|
ld %r4, %r31, 8 | flags
|
|
|
|
bcnd eq0, %r5, 9f
|
|
|
|
bb0 0, %r4, 1f | CIF_FLAGS_INT
|
|
st %r2, %r5, 0
|
|
br 9f
|
|
|
|
1:
|
|
bb0 1, %r4, 1f | CIF_FLAGS_DINT
|
|
st.d %r2, %r5, 0
|
|
br 9f
|
|
|
|
1:
|
|
9:
|
|
ld %r1, %r31, 0
|
|
ld %r30, %r31, 4
|
|
jmp.n %r1
|
|
addu %r31, %r31, 32
|
|
.size ffi_call_OBSD, . - ffi_call_OBSD
|
|
|
|
/*
|
|
* ffi_closure_OBSD(ffi_closure *closure); %r13
|
|
*/
|
|
.align 4
|
|
.globl ffi_closure_OBSD
|
|
.type ffi_closure_OBSD, @function
|
|
ffi_closure_OBSD:
|
|
subu %r31, %r31, 16
|
|
st %r30, %r31, 4
|
|
st %r1, %r31, 0
|
|
addu %r30, %r31, 16
|
|
|
|
| Make room on the stack for saved register arguments and return
|
|
| value
|
|
subu %r31, %r31, (8 * 4) + (2 * 4)
|
|
st.d %r2, %r31, (0 * 4)
|
|
st.d %r4, %r31, (2 * 4)
|
|
st.d %r6, %r31, (4 * 4)
|
|
st.d %r8, %r31, (6 * 4)
|
|
|
|
| Invoke the closure function
|
|
or %r5, %r30, 0 | calling stack
|
|
addu %r4, %r31, 0 | saved registers
|
|
addu %r3, %r31, (8 * 4) | return value
|
|
or %r2, %r13, %r0 | closure
|
|
#ifdef PIC
|
|
bsr ffi_closure_OBSD_inner#plt
|
|
#else
|
|
bsr ffi_closure_OBSD_inner
|
|
#endif
|
|
|
|
| Figure out what to return as the function's return value
|
|
bb0 0, %r2, 1f | CIF_FLAGS_INT
|
|
ld %r2, %r31, (8 * 4)
|
|
br 9f
|
|
|
|
1:
|
|
bb0 1, %r2, 1f | CIF_FLAGS_DINT
|
|
ld.d %r2, %r31, (8 * 4)
|
|
br 9f
|
|
|
|
1:
|
|
9:
|
|
subu %r31, %r30, 16
|
|
ld %r1, %r31, 0
|
|
ld %r30, %r31, 4
|
|
jmp.n %r1
|
|
addu %r31, %r31, 16
|
|
.size ffi_closure_OBSD,.-ffi_closure_OBSD
|
|
|
|
/*
|
|
* ffi_closure_struct_OBSD(ffi_closure *closure); %r13
|
|
*/
|
|
.align 4
|
|
.globl ffi_closure_struct_OBSD
|
|
.type ffi_closure_struct_OBSD, @function
|
|
ffi_closure_struct_OBSD:
|
|
subu %r31, %r31, 16
|
|
st %r30, %r31, 4
|
|
st %r1, %r31, 0
|
|
addu %r30, %r31, 16
|
|
|
|
| Make room on the stack for saved register arguments
|
|
subu %r31, %r31, (8 * 4)
|
|
st.d %r2, %r31, (0 * 4)
|
|
st.d %r4, %r31, (2 * 4)
|
|
st.d %r6, %r31, (4 * 4)
|
|
st.d %r8, %r31, (6 * 4)
|
|
|
|
| Invoke the closure function
|
|
or %r5, %r30, 0 | calling stack
|
|
addu %r4, %r31, 0 | saved registers
|
|
or %r3, %r12, 0 | return value
|
|
or %r2, %r13, %r0 | closure
|
|
#ifdef PIC
|
|
bsr ffi_closure_OBSD_inner#plt
|
|
#else
|
|
bsr ffi_closure_OBSD_inner
|
|
#endif
|
|
|
|
subu %r31, %r30, 16
|
|
ld %r1, %r31, 0
|
|
ld %r30, %r31, 4
|
|
jmp.n %r1
|
|
addu %r31, %r31, 16
|
|
.size ffi_closure_struct_OBSD,.-ffi_closure_struct_OBSD
|