/Modules/_ctypes/libffi/src/powerpc/sysv.S
http://unladen-swallow.googlecode.com/ · Assembly · 230 lines · 174 code · 16 blank · 40 comment · 5 complexity · 889b214acb97d36fa25441c00a9a0ea1 MD5 · raw file
- /* -----------------------------------------------------------------------
- sysv.S - Copyright (c) 1998 Geoffrey Keating
- Copyright (C) 2007 Free Software Foundation, Inc
- PowerPC Assembly glue.
- 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.
- ----------------------------------------------------------------------- */
- #define LIBFFI_ASM
- #include <fficonfig.h>
- #include <ffi.h>
- #include <powerpc/asm.h>
- #ifndef __powerpc64__
- .globl ffi_prep_args_SYSV
- ENTRY(ffi_call_SYSV)
- .LFB1:
- /* Save the old stack pointer as AP. */
- mr %r8,%r1
- .LCFI0:
- /* Allocate the stack space we need. */
- stwux %r1,%r1,%r4
- /* Save registers we use. */
- mflr %r9
- stw %r28,-16(%r8)
- .LCFI1:
- stw %r29,-12(%r8)
- .LCFI2:
- stw %r30, -8(%r8)
- .LCFI3:
- stw %r31, -4(%r8)
- .LCFI4:
- stw %r9, 4(%r8)
- .LCFI5:
- /* Save arguments over call... */
- mr %r31,%r5 /* flags, */
- mr %r30,%r6 /* rvalue, */
- mr %r29,%r7 /* function address, */
- mr %r28,%r8 /* our AP. */
- .LCFI6:
- /* Call ffi_prep_args_SYSV. */
- mr %r4,%r1
- bl ffi_prep_args_SYSV@local
- /* Now do the call. */
- /* Set up cr1 with bits 4-7 of the flags. */
- mtcrf 0x40,%r31
- /* Get the address to call into CTR. */
- mtctr %r29
- /* Load all those argument registers. */
- lwz %r3,-16-(8*4)(%r28)
- lwz %r4,-16-(7*4)(%r28)
- lwz %r5,-16-(6*4)(%r28)
- lwz %r6,-16-(5*4)(%r28)
- bf- 5,1f
- nop
- lwz %r7,-16-(4*4)(%r28)
- lwz %r8,-16-(3*4)(%r28)
- lwz %r9,-16-(2*4)(%r28)
- lwz %r10,-16-(1*4)(%r28)
- nop
- 1:
- /* Load all the FP registers. */
- bf- 6,2f
- lfd %f1,-16-(8*4)-(8*8)(%r28)
- lfd %f2,-16-(8*4)-(7*8)(%r28)
- lfd %f3,-16-(8*4)-(6*8)(%r28)
- lfd %f4,-16-(8*4)-(5*8)(%r28)
- nop
- lfd %f5,-16-(8*4)-(4*8)(%r28)
- lfd %f6,-16-(8*4)-(3*8)(%r28)
- lfd %f7,-16-(8*4)-(2*8)(%r28)
- lfd %f8,-16-(8*4)-(1*8)(%r28)
- 2:
- /* Make the call. */
- bctrl
- /* Now, deal with the return value. */
- mtcrf 0x01,%r31 /* cr7 */
- bt- 31,L(small_struct_return_value)
- bt- 30,L(done_return_value)
- bt- 29,L(fp_return_value)
- stw %r3,0(%r30)
- bf+ 28,L(done_return_value)
- stw %r4,4(%r30)
- mtcrf 0x02,%r31 /* cr6 */
- bf 27,L(done_return_value)
- stw %r5,8(%r30)
- stw %r6,12(%r30)
- /* Fall through... */
- L(done_return_value):
- /* Restore the registers we used and return. */
- lwz %r9, 4(%r28)
- lwz %r31, -4(%r28)
- mtlr %r9
- lwz %r30, -8(%r28)
- lwz %r29,-12(%r28)
- lwz %r28,-16(%r28)
- lwz %r1,0(%r1)
- blr
- L(fp_return_value):
- bf 28,L(float_return_value)
- stfd %f1,0(%r30)
- mtcrf 0x02,%r31 /* cr6 */
- bf 27,L(done_return_value)
- stfd %f2,8(%r30)
- b L(done_return_value)
- L(float_return_value):
- stfs %f1,0(%r30)
- b L(done_return_value)
- L(small_struct_return_value):
- mtcrf 0x10,%r31 /* cr3 */
- bt- 15,L(smst_one_register)
- mtcrf 0x08,%r31 /* cr4 */
- bt- 16,L(smst_two_register)
- b L(done_return_value)
- L(smst_one_register):
- rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
- slw %r3,%r3,%r5
- stw %r3,0(%r30)
- b L(done_return_value)
- L(smst_two_register):
- rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
- cmpwi %r5,0
- subfic %r9,%r5,32
- slw %r29,%r3,%r5
- srw %r9,%r4,%r9
- beq- L(smst_8byte)
- or %r3,%r9,%r29
- slw %r4,%r4,%r5
- L(smst_8byte):
- stw %r3,0(%r30)
- stw %r4,4(%r30)
- b L(done_return_value)
- .LFE1:
- END(ffi_call_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 0xd /* DW_CFA_def_cfa_register */
- .uleb128 0x08
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .4byte .LCFI5-.LCFI0
- .byte 0x11 /* DW_CFA_offset_extended_sf */
- .uleb128 0x41
- .sleb128 -1
- .byte 0x9f /* DW_CFA_offset, column 0x1f */
- .uleb128 0x1
- .byte 0x9e /* DW_CFA_offset, column 0x1e */
- .uleb128 0x2
- .byte 0x9d /* DW_CFA_offset, column 0x1d */
- .uleb128 0x3
- .byte 0x9c /* DW_CFA_offset, column 0x1c */
- .uleb128 0x4
- .byte 0x4 /* DW_CFA_advance_loc4 */
- .4byte .LCFI6-.LCFI5
- .byte 0xd /* DW_CFA_def_cfa_register */
- .uleb128 0x1c
- .align 2
- .LEFDE1:
- #endif
- #if defined __ELF__ && defined __linux__
- .section .note.GNU-stack,"",@progbits
- #endif