OSDN Git Service

Richards changes to the closure code for alpha
authorgreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2000 07:13:18 +0000 (07:13 +0000)
committergreen <green@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 10 Dec 2000 07:13:18 +0000 (07:13 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38169 138bc75d-0d04-0410-961f-82ee72b054a4

libffi/ChangeLog
libffi/src/alpha/ffi.c
libffi/src/alpha/osf.S

index 71dad41..bd2e83c 100644 (file)
@@ -1,4 +1,12 @@
-2000-12-07 Dec  8 11:23:29 2000  Richard Henderson  <rth@redhat.com>
+2000-12-09  Richard Henderson  <rth@redhat.com>
+
+       * src/alpha/ffi.c (ffi_call): Simplify struct return test.
+       (ffi_closure_osf_inner): Index rather than increment avalue
+       and arg_types.  Give ffi_closure_osf the raw return value type.
+       * src/alpha/osf.S (ffi_closure_osf): Handle return value type
+       promotion.
+
+2000-12-07  Richard Henderson  <rth@redhat.com>
 
        * src/raw_api.c (ffi_translate_args): Fix typo.
        (ffi_prep_closure): Likewise.
index 84ee849..29292e6 100644 (file)
@@ -70,7 +70,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
 
   /* If the return value is a struct and we don't have a return
      value address then we need to make one.  */
-  if (rvalue == NULL && cif->rtype->type == FFI_TYPE_STRUCT)
+  if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
     rvalue = alloca(cif->rtype->size);
 
   /* Allocate the space for the arguments, plus 4 words of temp
@@ -202,7 +202,7 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
   /* Grab the addresses of the arguments from the stack frame.  */
   while (i < avn)
     {
-      switch ((*arg_types)->type)
+      switch (arg_types[i]->type)
        {
        case FFI_TYPE_SINT8:
        case FFI_TYPE_UINT8:
@@ -214,7 +214,7 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
        case FFI_TYPE_UINT64:
        case FFI_TYPE_POINTER:
        case FFI_TYPE_STRUCT:
-         *avalue = &argp[argn];
+         avalue[i] = &argp[argn];
          break;
 
        case FFI_TYPE_FLOAT:
@@ -223,27 +223,27 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
              /* Floats coming from registers need conversion from double
                 back to float format.  */
              *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
-             *avalue = &argp[argn - 6];
+             avalue[i] = &argp[argn - 6];
            }
          else
-           *avalue = &argp[argn];
+           avalue[i] = &argp[argn];
          break;
 
        case FFI_TYPE_DOUBLE:
-         *avalue = &argp[argn - (argn < 6 ? 6 : 0)];
+         avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
          break;
 
        default:
          FFI_ASSERT(0);
        }
 
-      argn += ALIGN((*arg_types)->size, SIZEOF_ARG) / SIZEOF_ARG;
-      i++, arg_types++, avalue++;
+      argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+      i++;
     }
 
   /* Invoke the closure.  */
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
-  /* Tell ffi_closure_osf what register to put the return value in.  */
-  return cif->flags;
+  /* Tell ffi_closure_osf how to perform return type promotions.  */
+  return cif->rtype->type;
 }
index 9ed37cb..fce089a 100644 (file)
@@ -28,6 +28,7 @@
 #define LIBFFI_ASM     
 #include <ffi.h>
 
+       .arch ev6
        .text
 
 /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
@@ -121,9 +122,9 @@ $retdouble:
        .ent    ffi_closure_osf
 ffi_closure_osf:
        .frame  $30, 16*8, $26, 0
-       .mask   0x4000000, -14*8
+       .mask   0x4000000, -16*8
        ldgp    $29, 0($27)
-       subq    $30, 14*8, $30
+       subq    $30, 16*8, $30
        stq     $26, 0($30)
        .prologue 1
 
@@ -150,33 +151,129 @@ ffi_closure_osf:
        ldq     $26, 0($30)
 
        # Load up the return value in the proper type.
-       cmpeq   $0, FFI_TYPE_INT, $1
-       bne     $1, $loadint
-       cmpeq   $0, FFI_TYPE_FLOAT, $2
-       bne     $2, $loadfloat
-       cmpeq   $18, FFI_TYPE_DOUBLE, $3
-       bne     $3, $loaddouble
+       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 3
-$loadint:
+       .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
 
-$loadfloat:
-       lds     $f0, 16($30)
+       .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
 
-$loaddouble:
-       ldt     $f0, 16($30)
+       .align 4
+$load_64:
+       ldq     $0, 16($30)
        nop
        addq    $30, 16*8, $30
        ret
 
        .end    ffi_closure_osf
+
+.section .rodata
+$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_double   # 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