OSDN Git Service

* configure.ac: Tidy target case.
[pf3gnuchains/gcc-fork.git] / libffi / src / alpha / osf.S
index 2078683..aba6782 100644 (file)
@@ -1,10 +1,8 @@
 /* -----------------------------------------------------------------------
-   osf.S - Copyright (c) 1998 Cygnus Solutions
+   osf.S - Copyright (c) 1998, 2001, 2007 Red Hat
    
    Alpha/OSF Foreign Function Interface 
 
-   $Id: osf.S,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
-
    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
    ----------------------------------------------------------------------- */
 
 #define LIBFFI_ASM     
+#include <fficonfig.h>
 #include <ffi.h>
 
-#define callback $16
-#define ecifp   $17
-#define bytes   $18
-#define flags   $19
-#define raddr    $20
-#define fn       $21
+       .arch ev6
+       .text
 
-#define flags_ofs      16
-#define raddr_ofs      24
-#define fn_ofs         32
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+                void *raddr, void (*fnaddr)());
 
-#define SIZEOF_FRAME   (6*8)
+   Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+   for this function.  This has been allocated by ffi_call.  We also
+   deallocate some of the stack that has been alloca'd.  */
 
-       .text
-       .align  4
+       .align  3
        .globl  ffi_call_osf
        .ent    ffi_call_osf
-       
+       FFI_HIDDEN(ffi_call_osf)
+
 ffi_call_osf:
-       lda     $30, -SIZEOF_FRAME($30)
-       stq     $26, 0($30)
-       stq     $15, 8($30)
-       stq     flags, flags_ofs($30)
-       stq     raddr, raddr_ofs($30)
-       stq     fn, fn_ofs($30)
-       mov     $30, $15
-       .frame  $15, SIZEOF_FRAME, $26, 0
-        .mask   0x4008000, -SIZEOF_FRAME
+       .frame  $15, 32, $26, 0
+       .mask   0x4008000, -32
+$LFB1:
+       addq    $16,$17,$1
+       mov     $16, $30
+       stq     $26, 0($1)
+       stq     $15, 8($1)
+       stq     $18, 16($1)
+       mov     $1, $15
+$LCFI1:
        .prologue 0
 
-       mov     callback, $27           # mov callback into place
-       subq    $30, bytes, $30         # allocate stack space
-       
-       # Call ffi_prep_args; ecif, bytes and flags are already in place.
-       mov     $30, $16                # push stack arg
-       jsr     $26, ($27), 0
+       stq     $19, 24($1)
+       mov     $20, $27
 
        # Load up all of the (potential) argument registers.
+       ldq     $16, 0($30)
        ldt     $f16, 0($30)
        ldt     $f17, 8($30)
+       ldq     $17, 8($30)
        ldt     $f18, 16($30)
+       ldq     $18, 16($30)
        ldt     $f19, 24($30)
+       ldq     $19, 24($30)
        ldt     $f20, 32($30)
+       ldq     $20, 32($30)
        ldt     $f21, 40($30)
-       ldq     $16, 48($30)
-       ldq     $17, 56($30)
-       ldq     $18, 64($30)
-       ldq     $19, 72($30)
-       ldq     $20, 80($30)
-       ldq     $21, 88($30)
-
-       # Get rid of the arg reg temp space and call the function.
-       ldq     $27, fn_ofs($15)
-       lda     $30, 12*8($30)
+       ldq     $21, 40($30)
+
+       # Deallocate the register argument area.
+       lda     $30, 48($30)
+
        jsr     $26, ($27), 0
+       ldgp    $29, 0($26)
 
        # If the return value pointer is NULL, assume no return value.
-       ldq     raddr, raddr_ofs($15)
-       beq     raddr, $noretval
+       ldq     $19, 24($15)
+       ldq     $18, 16($15)
+       ldq     $26, 0($15)
+$LCFI2:
+       beq     $19, $noretval
 
-       ldq     flags, flags_ofs($15)
-       cmpeq   flags, FFI_TYPE_INT, $1
+       # Store the return value out in the proper type.
+       cmpeq   $18, FFI_TYPE_INT, $1
        bne     $1, $retint
-       cmpeq   flags, FFI_TYPE_FLOAT, $2
+       cmpeq   $18, FFI_TYPE_FLOAT, $2
        bne     $2, $retfloat
-       cmpeq   flags, FFI_TYPE_DOUBLE, $3
+       cmpeq   $18, FFI_TYPE_DOUBLE, $3
        bne     $3, $retdouble
-       br      $retstruct
-       
-       .align 3
+
+       .align  3
+$noretval:
+       ldq     $15, 8($15)
+       ret
+
+       .align  4
 $retint:
-       stq     $0, 0(raddr)
-       br      $noretval
+       stq     $0, 0($19)
+       nop
+       ldq     $15, 8($15)
+       ret
+
+       .align  4
 $retfloat:
-       sts     $f0, 0(raddr)
-       br      $noretval
-$retdouble:
-       stt     $f0, 0(raddr)
+       sts     $f0, 0($19)
+       nop
+       ldq     $15, 8($15)
+       ret
 
-$retstruct:
-$noretval:
-       mov     $15, $30
-       ldq     $26, 0($15)
+       .align  4
+$retdouble:
+       stt     $f0, 0($19)
+       nop
        ldq     $15, 8($15)
-       lda     $30, SIZEOF_FRAME($30)
        ret
+$LFE1:
 
        .end    ffi_call_osf
+
+/* ffi_closure_osf(...)
+
+   Receives the closure argument in $1.   */
+
+       .align  3
+       .globl  ffi_closure_osf
+       .ent    ffi_closure_osf
+       FFI_HIDDEN(ffi_closure_osf)
+
+ffi_closure_osf:
+       .frame  $30, 16*8, $26, 0
+       .mask   0x4000000, -16*8
+$LFB2:
+       ldgp    $29, 0($27)
+       subq    $30, 16*8, $30
+$LCFI5:
+       stq     $26, 0($30)
+$LCFI6:
+       .prologue 1
+
+       # Store all of the potential argument registers in va_list format.
+       stt     $f16, 4*8($30)
+       stt     $f17, 5*8($30)
+       stt     $f18, 6*8($30)
+       stt     $f19, 7*8($30)
+       stt     $f20, 8*8($30)
+       stt     $f21, 9*8($30)
+       stq     $16, 10*8($30)
+       stq     $17, 11*8($30)
+       stq     $18, 12*8($30)
+       stq     $19, 13*8($30)
+       stq     $20, 14*8($30)
+       stq     $21, 15*8($30)
+
+       # Call ffi_closure_osf_inner to do the bulk of the work.
+       mov     $1, $16
+       lda     $17, 2*8($30)
+       lda     $18, 10*8($30)
+       jsr     $26, ffi_closure_osf_inner
+       ldgp    $29, 0($26)
+       ldq     $26, 0($30)
+
+       # Load up the return value in the proper type.
+       lda     $1, $load_table
+       s4addq  $0, $1, $1
+       ldl     $1, 0($1)
+       addq    $1, $29, $1
+       jmp     $31, ($1), $load_32
+
+       .align 4
+$load_none:
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_float:
+       lds     $f0, 16($30)
+       nop
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_double:
+       ldt     $f0, 16($30)
+       nop
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_u8:
+#ifdef __alpha_bwx__
+       ldbu    $0, 16($30)
+       nop
+#else
+       ldq     $0, 16($30)
+       and     $0, 255, $0
+#endif
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_s8:
+#ifdef __alpha_bwx__
+       ldbu    $0, 16($30)
+       sextb   $0, $0
+#else
+       ldq     $0, 16($30)
+       sll     $0, 56, $0
+       sra     $0, 56, $0
+#endif
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_u16:
+#ifdef __alpha_bwx__
+       ldwu    $0, 16($30)
+       nop
+#else
+       ldq     $0, 16($30)
+       zapnot  $0, 3, $0
+#endif
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_s16:
+#ifdef __alpha_bwx__
+       ldwu    $0, 16($30)
+       sextw   $0, $0
+#else
+       ldq     $0, 16($30)
+       sll     $0, 48, $0
+       sra     $0, 48, $0
+#endif
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_32:
+       ldl     $0, 16($30)
+       nop
+       addq    $30, 16*8, $30
+       ret
+
+       .align 4
+$load_64:
+       ldq     $0, 16($30)
+       nop
+       addq    $30, 16*8, $30
+       ret
+$LFE2:
+
+       .end    ffi_closure_osf
+
+#ifdef __ELF__
+.section .rodata
+#else
+.rdata
+#endif
+$load_table:
+       .gprel32 $load_none     # FFI_TYPE_VOID
+       .gprel32 $load_32       # FFI_TYPE_INT
+       .gprel32 $load_float    # FFI_TYPE_FLOAT
+       .gprel32 $load_double   # FFI_TYPE_DOUBLE
+       .gprel32 $load_none     # FFI_TYPE_LONGDOUBLE
+       .gprel32 $load_u8       # FFI_TYPE_UINT8
+       .gprel32 $load_s8       # FFI_TYPE_SINT8
+       .gprel32 $load_u16      # FFI_TYPE_UINT16
+       .gprel32 $load_s16      # FFI_TYPE_SINT16
+       .gprel32 $load_32       # FFI_TYPE_UINT32
+       .gprel32 $load_32       # FFI_TYPE_SINT32
+       .gprel32 $load_64       # FFI_TYPE_UINT64
+       .gprel32 $load_64       # FFI_TYPE_SINT64
+       .gprel32 $load_none     # FFI_TYPE_STRUCT
+       .gprel32 $load_64       # FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h.  */
+
+#if       FFI_TYPE_FLOAT != 2          \
+       || FFI_TYPE_DOUBLE != 3         \
+       || FFI_TYPE_UINT8 != 5          \
+       || FFI_TYPE_SINT8 != 6          \
+       || FFI_TYPE_UINT16 != 7         \
+       || FFI_TYPE_SINT16 != 8         \
+       || FFI_TYPE_UINT32 != 9         \
+       || FFI_TYPE_SINT32 != 10        \
+       || FFI_TYPE_UINT64 != 11        \
+       || FFI_TYPE_SINT64 != 12        \
+       || FFI_TYPE_STRUCT != 13        \
+       || FFI_TYPE_POINTER != 14       \
+       || FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
+
+#ifdef __ELF__
+       .section        .eh_frame,EH_FRAME_FLAGS,@progbits
+__FRAME_BEGIN__:
+       .4byte  $LECIE1-$LSCIE1 # Length of Common Information Entry
+$LSCIE1:
+       .4byte  0x0             # CIE Identifier Tag
+       .byte   0x1             # CIE Version
+       .ascii "zR\0"           # CIE Augmentation
+       .byte   0x1             # uleb128 0x1; CIE Code Alignment Factor
+       .byte   0x78            # sleb128 -8; CIE Data Alignment Factor
+       .byte   26              # CIE RA Column
+       .byte   0x1             # uleb128 0x1; Augmentation size
+       .byte   0x1b            # FDE Encoding (pcrel sdata4)
+       .byte   0xc             # DW_CFA_def_cfa
+       .byte   30              # uleb128 column 30
+       .byte   0               # uleb128 offset 0
+       .align 3
+$LECIE1:
+$LSFDE1:
+       .4byte  $LEFDE1-$LASFDE1                # FDE Length
+$LASFDE1:
+       .4byte  $LASFDE1-__FRAME_BEGIN__        # FDE CIE offset
+       .4byte  $LFB1-.         # FDE initial location
+       .4byte  $LFE1-$LFB1     # FDE address range
+       .byte   0x0             # uleb128 0x0; Augmentation size
+
+       .byte   0x4             # DW_CFA_advance_loc4
+       .4byte  $LCFI1-$LFB1
+       .byte   0x9a            # DW_CFA_offset, column 26
+       .byte   4               # uleb128 4*-8
+       .byte   0x8f            # DW_CFA_offset, column 15
+       .byte   0x3             # uleb128 3*-8
+       .byte   0xc             # DW_CFA_def_cfa
+       .byte   15              # uleb128 column 15
+       .byte   32              # uleb128 offset 32
+
+       .byte   0x4             # DW_CFA_advance_loc4
+       .4byte  $LCFI2-$LCFI1
+       .byte   0xda            # DW_CFA_restore, column 26
+       .align 3
+$LEFDE1:
+
+$LSFDE3:
+       .4byte  $LEFDE3-$LASFDE3                # FDE Length
+$LASFDE3:
+       .4byte  $LASFDE3-__FRAME_BEGIN__        # FDE CIE offset
+       .4byte  $LFB2-.         # FDE initial location
+       .4byte  $LFE2-$LFB2     # FDE address range
+       .byte   0x0             # uleb128 0x0; Augmentation size
+
+       .byte   0x4             # DW_CFA_advance_loc4
+       .4byte  $LCFI5-$LFB2
+       .byte   0xe             # DW_CFA_def_cfa_offset
+       .byte   0x80,0x1        # uleb128 128
+
+       .byte   0x4             # DW_CFA_advance_loc4
+       .4byte  $LCFI6-$LCFI5
+       .byte   0x9a            # DW_CFA_offset, column 26
+       .byte   16              # uleb128 offset 16*-8
+       .align 3
+$LEFDE3:
+#endif