149 lines
3.0 KiB
ArmAsm
149 lines
3.0 KiB
ArmAsm
#define LIBFFI_ASM
|
|
#include <powerpc/asm.h>
|
|
|
|
.globl ffi_closure_helper_SYSV
|
|
|
|
ENTRY(ffi_closure_SYSV)
|
|
stwu %r1,-144(%r1)
|
|
mflr %r0
|
|
stw %r31,140(%r1)
|
|
stw %r0,148(%r1)
|
|
|
|
# we want to build up an areas for the parameters passed
|
|
# in registers (both floating point and integer)
|
|
|
|
# so first save gpr 3 to gpr 10 (aligned to 4)
|
|
stw %r3, 16(%r1)
|
|
stw %r4, 20(%r1)
|
|
stw %r5, 24(%r1)
|
|
stw %r6, 28(%r1)
|
|
stw %r7, 32(%r1)
|
|
stw %r8, 36(%r1)
|
|
stw %r9, 40(%r1)
|
|
stw %r10,44(%r1)
|
|
|
|
# next save fpr 1 to fpr 8 (aligned to 8)
|
|
stfd %f1, 48(%r1)
|
|
stfd %f2, 56(%r1)
|
|
stfd %f3, 64(%r1)
|
|
stfd %f4, 72(%r1)
|
|
stfd %f5, 80(%r1)
|
|
stfd %f6, 88(%r1)
|
|
stfd %f7, 96(%r1)
|
|
stfd %f8, 104(%r1)
|
|
|
|
# set up registers for the routine that actually does the work
|
|
# get the context pointer from the trampoline
|
|
mr %r3,%r11
|
|
|
|
# now load up the pointer to the result storage
|
|
addi %r4,%r1,112
|
|
|
|
# now load up the pointer to the saved gpr registers
|
|
addi %r5,%r1,16
|
|
|
|
# now load up the pointer to the saved fpr registers */
|
|
addi %r6,%r1,48
|
|
|
|
# now load up the pointer to the outgoing parameter
|
|
# stack in the previous frame
|
|
# i.e. the previous frame pointer + 8
|
|
addi %r7,%r1,152
|
|
|
|
# make the call
|
|
bl JUMPTARGET(ffi_closure_helper_SYSV)
|
|
|
|
# now r3 contains the return type
|
|
# so use it to look up in a table
|
|
# so we know how to deal with each type
|
|
|
|
# look up the proper starting point in table
|
|
# by using return type as offset
|
|
addi %r5,%r1,112 # get pointer to results area
|
|
addis %r4,0,.L60@ha # get address of jump table
|
|
addi %r4,%r4,.L60@l
|
|
slwi %r3,%r3,2 # now multiply return type by 4
|
|
lwzx %r3,%r4,%r3 # get the contents of that table value
|
|
add %r3,%r3,%r4 # add contents of table to table address
|
|
mtctr %r3
|
|
bctr # jump to it
|
|
.align 2
|
|
.L60:
|
|
.long .L44-.L60 # FFI_TYPE_VOID
|
|
.long .L50-.L60 # FFI_TYPE_INT
|
|
.long .L47-.L60 # FFI_TYPE_FLOAT
|
|
.long .L46-.L60 # FFI_TYPE_DOUBLE
|
|
.long .L46-.L60 # FFI_TYPE_LONGDOUBLE
|
|
.long .L56-.L60 # FFI_TYPE_UINT8
|
|
.long .L55-.L60 # FFI_TYPE_SINT8
|
|
.long .L58-.L60 # FFI_TYPE_UINT16
|
|
.long .L57-.L60 # FFI_TYPE_SINT16
|
|
.long .L50-.L60 # FFI_TYPE_UINT32
|
|
.long .L50-.L60 # FFI_TYPE_SINT32
|
|
.long .L48-.L60 # FFI_TYPE_UINT64
|
|
.long .L48-.L60 # FFI_TYPE_SINT64
|
|
.long .L44-.L60 # FFI_TYPE_STRUCT
|
|
.long .L50-.L60 # FFI_TYPE_POINTER
|
|
|
|
|
|
# case double
|
|
.L46:
|
|
lfd %f1,0(%r5)
|
|
b .L44
|
|
|
|
# case float
|
|
.L47:
|
|
lfs %f1,0(%r5)
|
|
b .L44
|
|
|
|
# case long long
|
|
.L48:
|
|
lwz %r3,0(%r5)
|
|
lwz %r4,4(%r5)
|
|
b .L44
|
|
|
|
# case default / int32 / pointer
|
|
.L50:
|
|
lwz %r3,0(%r5)
|
|
b .L44
|
|
|
|
# case signed int8
|
|
.L55:
|
|
addi %r5,%r5,3
|
|
lbz %r3,0(%r5)
|
|
extsb %r3,%r3
|
|
b .L44
|
|
|
|
# case unsigned int8
|
|
.L56:
|
|
addi %r5,%r5,3
|
|
lbz %r3,0(%r5)
|
|
b .L44
|
|
|
|
# case signed int16
|
|
.L57:
|
|
addi %r5,%r5,2
|
|
lhz %r3,0(%r5)
|
|
extsh %r3,%r3
|
|
b .L44
|
|
|
|
#case unsigned int16
|
|
.L58:
|
|
addi %r5,%r5,2
|
|
lhz %r3,0(%r5)
|
|
|
|
# case void / done
|
|
.L44:
|
|
|
|
lwz %r11,0(%r1)
|
|
lwz %r0,4(%r11)
|
|
mtlr %r0
|
|
lwz %r31,-4(%r11)
|
|
mr %r1,%r11
|
|
blr
|
|
END(ffi_closure_SYSV)
|
|
|
|
|
|
|
|
|