OSDN Git Service

Initial revision
[pf3gnuchains/gcc-fork.git] / libffi / src / alpha / osf.S
diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S
new file mode 100644 (file)
index 0000000..2078683
--- /dev/null
@@ -0,0 +1,118 @@
+/* -----------------------------------------------------------------------
+   osf.S - Copyright (c) 1998 Cygnus Solutions
+   
+   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
+   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 CYGNUS SOLUTIONS 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 <ffi.h>
+
+#define callback $16
+#define ecifp   $17
+#define bytes   $18
+#define flags   $19
+#define raddr    $20
+#define fn       $21
+
+#define flags_ofs      16
+#define raddr_ofs      24
+#define fn_ofs         32
+
+#define SIZEOF_FRAME   (6*8)
+
+       .text
+       .align  4
+       .globl  ffi_call_osf
+       .ent    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
+       .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
+
+       # Load up all of the (potential) argument registers.
+       ldt     $f16, 0($30)
+       ldt     $f17, 8($30)
+       ldt     $f18, 16($30)
+       ldt     $f19, 24($30)
+       ldt     $f20, 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)
+       jsr     $26, ($27), 0
+
+       # If the return value pointer is NULL, assume no return value.
+       ldq     raddr, raddr_ofs($15)
+       beq     raddr, $noretval
+
+       ldq     flags, flags_ofs($15)
+       cmpeq   flags, FFI_TYPE_INT, $1
+       bne     $1, $retint
+       cmpeq   flags, FFI_TYPE_FLOAT, $2
+       bne     $2, $retfloat
+       cmpeq   flags, FFI_TYPE_DOUBLE, $3
+       bne     $3, $retdouble
+       br      $retstruct
+       
+       .align 3
+$retint:
+       stq     $0, 0(raddr)
+       br      $noretval
+$retfloat:
+       sts     $f0, 0(raddr)
+       br      $noretval
+$retdouble:
+       stt     $f0, 0(raddr)
+
+$retstruct:
+$noretval:
+       mov     $15, $30
+       ldq     $26, 0($15)
+       ldq     $15, 8($15)
+       lda     $30, SIZEOF_FRAME($30)
+       ret
+
+       .end    ffi_call_osf