alpha: Reorganize cif flags
authorRichard Henderson <rth@twiddle.net>
Fri, 17 Oct 2014 19:33:53 +0000 (12:33 -0700)
committerRichard Henderson <rth@twiddle.net>
Wed, 12 Nov 2014 08:30:59 +0000 (09:30 +0100)
Unties the backend from changes to FFI_TYPE_* constants, and allows
compilation to succeed after the addition of FFI_TYPE_COMPLEX.

Delete the hand-written unwind info.

src/alpha/ffi.c
src/alpha/internal.h [new file with mode: 0644]
src/alpha/osf.S

index 192f691..519bd2c 100644 (file)
@@ -28,6 +28,7 @@
 #include <ffi.h>
 #include <ffi_common.h>
 #include <stdlib.h>
+#include "internal.h"
 
 /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
    all further uses in this file will refer to the 128-bit type.  */
@@ -48,6 +49,8 @@ extern void ffi_closure_osf(void) FFI_HIDDEN;
 ffi_status
 ffi_prep_cif_machdep(ffi_cif *cif)
 {
+  int flags;
+
   /* Adjust cif->bytes to represent a minimum 6 words for the temporary
      register argument loading area.  */
   if (cif->bytes < 6*FFI_SIZEOF_ARG)
@@ -56,21 +59,46 @@ ffi_prep_cif_machdep(ffi_cif *cif)
   /* Set the return type flag */
   switch (cif->rtype->type)
     {
-    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_VOID:
+      flags = ALPHA_FLAGS(ALPHA_ST_VOID, ALPHA_LD_VOID);
+      break;
+    case FFI_TYPE_INT:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT32);
+      break;
     case FFI_TYPE_FLOAT:
+      flags = ALPHA_FLAGS(ALPHA_ST_FLOAT, ALPHA_LD_FLOAT);
+      break;
     case FFI_TYPE_DOUBLE:
-      cif->flags = cif->rtype->type;
+      flags = ALPHA_FLAGS(ALPHA_ST_DOUBLE, ALPHA_LD_DOUBLE);
+      break;
+    case FFI_TYPE_UINT8:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT8);
+      break;
+    case FFI_TYPE_SINT8:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT8);
+      break;
+    case FFI_TYPE_UINT16:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_UINT16);
+      break;
+    case FFI_TYPE_SINT16:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_SINT16);
+      break;
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_POINTER:
+      flags = ALPHA_FLAGS(ALPHA_ST_INT, ALPHA_LD_INT64);
       break;
-
     case FFI_TYPE_LONGDOUBLE:
-      /* 128-bit long double is returned in memory, like a struct.  */
-      cif->flags = FFI_TYPE_STRUCT;
+    case FFI_TYPE_STRUCT:
+      /* Passed in memory, with a hidden pointer.  */
+      flags = ALPHA_RET_IN_MEM;
       break;
-
     default:
-      cif->flags = FFI_TYPE_INT;
-      break;
+      abort();
     }
+  cif->flags = flags;
   
   return FFI_OK;
 }
@@ -80,20 +108,20 @@ void
 ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
 {
   unsigned long *stack, *argp;
-  long i, avn;
+  long i, avn, flags = cif->flags;
   ffi_type **arg_types;
   
   /* 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->flags == FFI_TYPE_STRUCT)
+  if (rvalue == NULL && flags == ALPHA_RET_IN_MEM)
     rvalue = alloca(cif->rtype->size);
 
   /* Allocate the space for the arguments, plus 4 words of temp
      space for ffi_call_osf.  */
   argp = stack = alloca(cif->bytes + 4*FFI_SIZEOF_ARG);
 
-  if (cif->flags == FFI_TYPE_STRUCT)
-    *(void **) argp++ = rvalue;
+  if (flags == ALPHA_RET_IN_MEM)
+    *argp++ = (unsigned long)rvalue;
 
   i = 0;
   avn = cif->nargs;
@@ -166,7 +194,8 @@ ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
       i++, arg_types++, avalue++;
     }
 
-  ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
+  flags = (flags >> ALPHA_ST_SHIFT) & 0xff;
+  ffi_call_osf(stack, cif->bytes, flags, rvalue, fn);
 }
 
 
@@ -211,16 +240,16 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
   ffi_cif *cif;
   void **avalue;
   ffi_type **arg_types;
-  long i, avn, argn;
+  long i, avn, argn, flags;
 
   cif = closure->cif;
   avalue = alloca(cif->nargs * sizeof(void *));
-
+  flags = cif->flags;
   argn = 0;
 
   /* Copy the caller's structure return address to that the closure
      returns the data directly to the caller.  */
-  if (cif->flags == FFI_TYPE_STRUCT)
+  if (flags == ALPHA_RET_IN_MEM)
     {
       rvalue = (void *) argp[0];
       argn = 1;
@@ -284,5 +313,5 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
   closure->fun (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_osf how to perform return type promotions.  */
-  return cif->rtype->type;
+  return (flags >> ALPHA_LD_SHIFT) & 0xff;
 }
diff --git a/src/alpha/internal.h b/src/alpha/internal.h
new file mode 100644 (file)
index 0000000..664a2a6
--- /dev/null
@@ -0,0 +1,19 @@
+#define ALPHA_ST_VOID  0
+#define ALPHA_ST_INT   1
+#define ALPHA_ST_FLOAT 2
+#define ALPHA_ST_DOUBLE        3
+
+#define ALPHA_LD_VOID  0
+#define ALPHA_LD_INT64 1
+#define ALPHA_LD_INT32 2
+#define ALPHA_LD_UINT16        3
+#define ALPHA_LD_SINT16        4
+#define ALPHA_LD_UINT8 5
+#define ALPHA_LD_SINT8 6
+#define ALPHA_LD_FLOAT 7
+#define ALPHA_LD_DOUBLE        8
+
+#define ALPHA_ST_SHIFT         0
+#define ALPHA_LD_SHIFT         8
+#define ALPHA_RET_IN_MEM       0x10000
+#define ALPHA_FLAGS(S, L)      (((L) << ALPHA_LD_SHIFT) | (S))
index 6b9f4df..fb9c595 100644 (file)
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
-   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011 Red Hat
-   
-   Alpha/OSF Foreign Function Interface 
+   osf.S - Copyright (c) 1998, 2001, 2007, 2008, 2011, 2014 Red Hat
+
+   Alpha/OSF Foreign Function Interface
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
    DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
-#define LIBFFI_ASM     
+#define LIBFFI_ASM
 #include <fficonfig.h>
 #include <ffi.h>
+#include <ffi_cfi.h>
+#include "internal.h"
 
        .arch ev6
        .text
 
+/* Aid in building a direct addressed jump table, 4 insns per entry.  */
+.macro E index
+       .align  4
+       .org    99b + \index * 16
+.endm
+
 /* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
                 void *raddr, void (*fnaddr)(void));
 
@@ -38,7 +46,7 @@
    for this function.  This has been allocated by ffi_call.  We also
    deallocate some of the stack that has been alloca'd.  */
 
-       .align  3
+       .align  4
        .globl  ffi_call_osf
        .ent    ffi_call_osf
        FFI_HIDDEN(ffi_call_osf)
 ffi_call_osf:
        .frame  $15, 32, $26, 0
        .mask   0x4008000, -32
-$LFB1:
+       cfi_startproc
        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
+       cfi_def_cfa($15, 32)
+       cfi_rel_offset($26, 0)
+       cfi_rel_offset($15, 8)
 
        stq     $19, 24($1)
        mov     $20, $27
@@ -77,71 +87,61 @@ $LCFI1:
        lda     $30, 48($30)
 
        jsr     $26, ($27), 0
-       ldgp    $29, 0($26)
-
-       # If the return value pointer is NULL, assume no return value.
-       ldq     $19, 24($15)
-       ldq     $18, 16($15)
+0:
+       ldah    $29, 0($26)             !gpdisp!1
+       ldq     $2, 24($15)
+       lda     $29, 0($29)             !gpdisp!1
+       ldq     $3, 16($15)
+       lda     $1, 99f-0b($26)
        ldq     $26, 0($15)
-$LCFI2:
-       beq     $19, $noretval
-
-       # Store the return value out in the proper type.
-       cmpeq   $18, FFI_TYPE_INT, $1
-       bne     $1, $retint
-       cmpeq   $18, FFI_TYPE_FLOAT, $2
-       bne     $2, $retfloat
-       cmpeq   $18, FFI_TYPE_DOUBLE, $3
-       bne     $3, $retdouble
-
-       .align  3
-$noretval:
        ldq     $15, 8($15)
-       ret
+       cfi_restore($26)
+       cfi_restore($15)
+       cfi_def_cfa($sp, 0)
+       cmoveq  $2, ALPHA_ST_VOID, $3   # mash null return to void
+       addq    $3, $3, $3
+       s8addq  $3, $1, $1              # 99f + stcode * 16
+       jmp     $31, ($1), $st_int
 
        .align  4
-$retint:
-       stq     $0, 0($19)
-       nop
-       ldq     $15, 8($15)
+99:
+E ALPHA_ST_VOID
        ret
-
-       .align  4
-$retfloat:
-       sts     $f0, 0($19)
-       nop
-       ldq     $15, 8($15)
+E ALPHA_ST_INT
+$st_int:
+       stq     $0, 0($2)
        ret
-
-       .align  4
-$retdouble:
-       stt     $f0, 0($19)
-       nop
-       ldq     $15, 8($15)
+E ALPHA_ST_FLOAT
+       sts     $f0, 0($2)
+       ret
+E ALPHA_ST_DOUBLE
+       stt     $f0, 0($2)
        ret
-$LFE1:
 
+       cfi_endproc
        .end    ffi_call_osf
 
 /* ffi_closure_osf(...)
 
    Receives the closure argument in $1.   */
 
-       .align  3
+#define CLOSURE_FS     (16*8)
+
+       .align  4
        .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:
+       .frame  $30, CLOSURE_FS, $26, 0
+       .mask   0x4000000, -CLOSURE_FS
+       cfi_startproc
        ldgp    $29, 0($27)
-       subq    $30, 16*8, $30
-$LCFI5:
+       subq    $30, CLOSURE_FS, $30
+       cfi_adjust_cfa_offset(CLOSURE_FS)
        stq     $26, 0($30)
-$LCFI6:
        .prologue 1
+       cfi_rel_offset($26, 0)
 
        # Store all of the potential argument registers in va_list format.
        stt     $f16, 4*8($30)
@@ -162,225 +162,74 @@ $LCFI6:
        lda     $17, 2*8($30)
        lda     $18, 10*8($30)
        jsr     $26, ffi_closure_osf_inner
-       ldgp    $29, 0($26)
+0:
+       ldah    $29, 0($26)                     !gpdisp!2
+       lda     $2, 99f-0b($26)
+       s4addq  $0, 0, $1                       # ldcode * 4
+       ldq     $0, 16($30)                     # preload return value
+       s4addq  $1, $2, $1                      # 99f + ldcode * 16
+       lda     $29, 0($29)                     !gpdisp!2
        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
+       cfi_restore($26)
        jmp     $31, ($1), $load_32
 
-       .align 4
-$load_none:
-       addq    $30, 16*8, $30
+.macro epilogue
+       addq    $30, CLOSURE_FS, $30
+       cfi_adjust_cfa_offset(-CLOSURE_FS)
        ret
+       .align  4
+       cfi_adjust_cfa_offset(CLOSURE_FS)
+.endm
 
        .align 4
-$load_float:
-       lds     $f0, 16($30)
-       nop
-       addq    $30, 16*8, $30
-       ret
+99:
+E ALPHA_LD_VOID
+       epilogue
 
-       .align 4
-$load_double:
-       ldt     $f0, 16($30)
-       nop
-       addq    $30, 16*8, $30
-       ret
+E ALPHA_LD_INT64
+       epilogue
 
-       .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
+E ALPHA_LD_INT32
+$load_32:
+       sextl   $0, $0
+       epilogue
 
-       .align 4
-$load_u16:
-#ifdef __alpha_bwx__
-       ldwu    $0, 16($30)
-       nop
-#else
-       ldq     $0, 16($30)
+E ALPHA_LD_UINT16
        zapnot  $0, 3, $0
-#endif
-       addq    $30, 16*8, $30
-       ret
+       epilogue
 
-       .align 4
-$load_s16:
+E ALPHA_LD_SINT16
 #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
+       epilogue
 
-       .align 4
-$load_32:
-       ldl     $0, 16($30)
-       nop
-       addq    $30, 16*8, $30
-       ret
+E ALPHA_LD_UINT8
+       and     $0, 0xff, $0
+       epilogue
 
-       .align 4
-$load_64:
-       ldq     $0, 16($30)
-       nop
-       addq    $30, 16*8, $30
-       ret
-$LFE2:
-
-       .end    ffi_closure_osf
-
-#ifdef __ELF__
-.section .rodata
+E ALPHA_LD_SINT8
+#ifdef __alpha_bwx__
+       sextb   $0, $0
 #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"
+       sll     $0, 56, $0
+       sra     $0, 56, $0
 #endif
+       epilogue
 
-#ifdef __ELF__
-# define UA_SI         .4byte
-# define FDE_ENCODING  0x1b    /* pcrel sdata4 */
-# define FDE_ENCODE(X) .4byte X-.
-# define FDE_ARANGE(X) .4byte X
-#elif defined __osf__
-# define UA_SI         .align 0; .long
-# define FDE_ENCODING  0x50    /* aligned absolute */
-# define FDE_ENCODE(X) .align 3; .quad X
-# define FDE_ARANGE(X) .align 0; .quad X
-#endif
+E ALPHA_LD_FLOAT
+       lds     $f0, 16($sp)
+       epilogue
 
-#ifdef __ELF__
-       .section        .eh_frame,EH_FRAME_FLAGS,@progbits
-#elif defined __osf__
-       .data
-       .align 3
-       .globl _GLOBAL__F_ffi_call_osf
-_GLOBAL__F_ffi_call_osf:
-#endif
-__FRAME_BEGIN__:
-       UA_SI   $LECIE1-$LSCIE1 # Length of Common Information Entry
-$LSCIE1:
-       UA_SI   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   FDE_ENCODING    # FDE Encoding
-       .byte   0xc             # DW_CFA_def_cfa
-       .byte   30              # uleb128 column 30
-       .byte   0               # uleb128 offset 0
-       .align 3
-$LECIE1:
-$LSFDE1:
-       UA_SI   $LEFDE1-$LASFDE1                # FDE Length
-$LASFDE1:
-       UA_SI   $LASFDE1-__FRAME_BEGIN__        # FDE CIE offset
-       FDE_ENCODE($LFB1)                       # FDE initial location
-       FDE_ARANGE($LFE1-$LFB1)                 # FDE address range
-       .byte   0x0             # uleb128 0x0; Augmentation size
-
-       .byte   0x4             # DW_CFA_advance_loc4
-       UA_SI   $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
-       UA_SI   $LCFI2-$LCFI1
-       .byte   0xda            # DW_CFA_restore, column 26
-       .align 3
-$LEFDE1:
-
-$LSFDE3:
-       UA_SI   $LEFDE3-$LASFDE3                # FDE Length
-$LASFDE3:
-       UA_SI   $LASFDE3-__FRAME_BEGIN__        # FDE CIE offset
-       FDE_ENCODE($LFB2)                       # FDE initial location
-       FDE_ARANGE($LFE2-$LFB2)                 # FDE address range
-       .byte   0x0             # uleb128 0x0; Augmentation size
-
-       .byte   0x4             # DW_CFA_advance_loc4
-       UA_SI   $LCFI5-$LFB2
-       .byte   0xe             # DW_CFA_def_cfa_offset
-       .byte   0x80,0x1        # uleb128 128
-
-       .byte   0x4             # DW_CFA_advance_loc4
-       UA_SI   $LCFI6-$LCFI5
-       .byte   0x9a            # DW_CFA_offset, column 26
-       .byte   16              # uleb128 offset 16*-8
-       .align 3
-$LEFDE3:
-#if defined __osf__
-       .align 0
-       .long   0               # End of Table
-#endif
+E ALPHA_LD_DOUBLE
+       ldt     $f0, 16($sp)
+       epilogue
+
+       cfi_endproc
+       .end    ffi_closure_osf
 
 #if defined __ELF__ && defined __linux__
        .section        .note.GNU-stack,"",@progbits