From 181d8ded82d49d0133d9d6fd1631d9816c970bfa Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Sat, 26 Jan 2008 12:06:34 +0100 Subject: Import libffi from PyObjC 1.3.7. darcs-hash:129bccb59266f997deac9b0353aea2d2d4049f92 --- libffi/src/powerpc/ppc_closure.S | 250 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 libffi/src/powerpc/ppc_closure.S (limited to 'libffi/src/powerpc/ppc_closure.S') diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S new file mode 100644 index 0000000..dce9dab --- /dev/null +++ b/libffi/src/powerpc/ppc_closure.S @@ -0,0 +1,250 @@ +#define LIBFFI_ASM +#include +#include +#include + + .file "ppc_closure.S" + +#ifndef __powerpc64__ + +ENTRY(ffi_closure_SYSV) +.LFB1: + stwu %r1,-144(%r1) +.LCFI0: + mflr %r0 +.LCFI1: + 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 + bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR + mflr %r4 # move to r4 + slwi %r3,%r3,4 # now multiply return type by 16 + add %r3,%r3,%r4 # add contents of table to table address + mtctr %r3 + bctr # jump to it +.LFE1: + +# Each of the ret_typeX code fragments has to be exactly 16 bytes long +# (4 instructions). For cache effectiveness we align to a 16 byte boundary +# first. + .align 4 + + nop + nop + nop +.Lget_ret_type0_addr: + blrl + +# case FFI_TYPE_VOID +.Lret_type0: + b .Lfinish + nop + nop + nop + +# case FFI_TYPE_INT +.Lret_type1: + lwz %r3,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_FLOAT +.Lret_type2: + lfs %f1,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_DOUBLE +.Lret_type3: + lfd %f1,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_LONGDOUBLE +.Lret_type4: + lfd %f1,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_UINT8 +.Lret_type5: + lbz %r3,3(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_SINT8 +.Lret_type6: + lbz %r3,3(%r5) + extsb %r3,%r3 + b .Lfinish + nop + +# case FFI_TYPE_UINT16 +.Lret_type7: + lhz %r3,2(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_SINT16 +.Lret_type8: + lha %r3,2(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_UINT32 +.Lret_type9: + lwz %r3,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_SINT32 +.Lret_type10: + lwz %r3,0(%r5) + b .Lfinish + nop + nop + +# case FFI_TYPE_UINT64 +.Lret_type11: + lwz %r3,0(%r5) + lwz %r4,4(%r5) + b .Lfinish + nop + +# case FFI_TYPE_SINT64 +.Lret_type12: + lwz %r3,0(%r5) + lwz %r4,4(%r5) + b .Lfinish + nop + +# case FFI_TYPE_STRUCT +.Lret_type13: + b .Lfinish + nop + nop + nop + +# case FFI_TYPE_POINTER +.Lret_type14: + lwz %r3,0(%r5) + b .Lfinish + nop + nop + +# case done +.Lfinish: + + lwz %r0,148(%r1) + mtlr %r0 + addi %r1,%r1,144 + blr +END(ffi_closure_SYSV) + + .section ".eh_frame",EH_FRAME_FLAGS,@progbits +.Lframe1: + .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry +.LSCIE1: + .4byte 0x0 # CIE Identifier Tag + .byte 0x1 # CIE Version +#if defined _RELOCATABLE || defined __PIC__ + .ascii "zR\0" # CIE Augmentation +#else + .ascii "\0" # CIE Augmentation +#endif + .uleb128 0x1 # CIE Code Alignment Factor + .sleb128 -4 # CIE Data Alignment Factor + .byte 0x41 # CIE RA Column +#if defined _RELOCATABLE || defined __PIC__ + .uleb128 0x1 # Augmentation size + .byte 0x1b # FDE Encoding (pcrel sdata4) +#endif + .byte 0xc # DW_CFA_def_cfa + .uleb128 0x1 + .uleb128 0x0 + .align 2 +.LECIE1: +.LSFDE1: + .4byte .LEFDE1-.LASFDE1 # FDE Length +.LASFDE1: + .4byte .LASFDE1-.Lframe1 # FDE CIE offset +#if defined _RELOCATABLE || defined __PIC__ + .4byte .LFB1-. # FDE initial location +#else + .4byte .LFB1 # FDE initial location +#endif + .4byte .LFE1-.LFB1 # FDE address range +#if defined _RELOCATABLE || defined __PIC__ + .uleb128 0x0 # Augmentation size +#endif + .byte 0x4 # DW_CFA_advance_loc4 + .4byte .LCFI0-.LFB1 + .byte 0xe # DW_CFA_def_cfa_offset + .uleb128 144 + .byte 0x4 # DW_CFA_advance_loc4 + .4byte .LCFI1-.LCFI0 + .byte 0x2f # DW_CFA_GNU_negative_offset_extended + .uleb128 0x41 + .uleb128 0x1 + .align 2 +.LEFDE1: + +#endif -- cgit v1.2.3