ffi.c: Formatting.
authorAlan Modra <amodra@bigpond.net.au>
Sat, 3 Dec 2005 00:06:33 +0000 (00:06 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Sat, 3 Dec 2005 00:06:33 +0000 (10:36 +1030)
* src/powerpc/ffi.c: Formatting.
(ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
(ffi_prep_args64): Likewise.

From-SVN: r107963

libffi/ChangeLog
libffi/src/powerpc/ffi.c

index 7c9c97e..49ff74f 100644 (file)
@@ -1,3 +1,9 @@
+2005-12-03  Alan Modra  <amodra@bigpond.net.au>
+
+       * src/powerpc/ffi.c: Formatting.
+       (ffi_prep_args_SYSV): Avoid possible aliasing problems by using unions.
+       (ffi_prep_args64): Likewise.
+
 2005-09-30  Geoffrey Keating  <geoffk@apple.com>
 
        * testsuite/lib/libffi-dg.exp (libffi_target_compile): For
index 7d8bf3a..bfd7ab6 100644 (file)
@@ -30,8 +30,8 @@
 #include <stdio.h>
 
 
-extern void ffi_closure_SYSV(void);
-extern void FFI_HIDDEN ffi_closure_LINUX64(void);
+extern void ffi_closure_SYSV (void);
+extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
 
 enum {
   /* The assembly depends on these exact flags.  */
@@ -81,78 +81,104 @@ enum { ASM_NEEDS_REGISTERS = 4 };
 */
 
 /*@-exportheader@*/
-void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
+void
+ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
 /*@=exportheader@*/
 {
   const unsigned bytes = ecif->cif->bytes;
   const unsigned flags = ecif->cif->flags;
 
+  typedef union {
+    char *c;
+    unsigned *u;
+    long long *ll;
+    float *f;
+    double *d;
+  } valp;
+
   /* 'stacktop' points at the previous backchain pointer.  */
-  unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
+  valp stacktop;
 
   /* 'gpr_base' points at the space for gpr3, and grows upwards as
      we use GPR registers.  */
-  unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
-  int intarg_count = 0;
+  valp gpr_base;
+  int intarg_count;
 
   /* 'fpr_base' points at the space for fpr1, and grows upwards as
      we use FPR registers.  */
-  double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
-  int fparg_count = 0;
+  valp fpr_base;
+  int fparg_count;
 
   /* 'copy_space' grows down as we put structures in it.  It should
      stay 16-byte aligned.  */
-  char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
-                     ? (char *)fpr_base
-                     : (char *)gpr_base);
+  valp copy_space;
 
   /* 'next_arg' grows up as we put parameters in it.  */
-  unsigned *next_arg = stack + 2;
+  valp next_arg;
 
   int i;
   ffi_type **ptr;
   double double_tmp;
-  void **p_argv;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    unsigned int **ui;
+    long long **ll;
+    float **f;
+    double **d;
+  } p_argv;
   size_t struct_copy_size;
   unsigned gprvalue;
 
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+  intarg_count = 0;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
+  fparg_count = 0;
+  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
+  next_arg.u = stack + 2;
+
   /* Check that everything starts aligned properly.  */
-  FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
-  FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
-  FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
-  FFI_ASSERT((bytes & 0xF) == 0);
-  FFI_ASSERT(copy_space >= (char *)next_arg);
+  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
+  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
+  FFI_ASSERT (copy_space.c >= next_arg.c);
 
   /* Deal with return values that are actually pass-by-reference.  */
   if (flags & FLAG_RETVAL_REFERENCE)
     {
-      *gpr_base++ = (unsigned long)(char *)ecif->rvalue;
+      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
       intarg_count++;
     }
 
   /* Now for the arguments.  */
-  p_argv = ecif->avalue;
+  p_argv.v = ecif->avalue;
   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
        i > 0;
-       i--, ptr++, p_argv++)
+       i--, ptr++, p_argv.v++)
     {
       switch ((*ptr)->type)
        {
        case FFI_TYPE_FLOAT:
-         double_tmp = *(float *)*p_argv;
+         double_tmp = **p_argv.f;
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
            {
-             *(float *)next_arg = (float)double_tmp;
-             next_arg += 1;
+             *next_arg.f = (float) double_tmp;
+             next_arg.u += 1;
            }
          else
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
          break;
 
        case FFI_TYPE_DOUBLE:
-         double_tmp = *(double *)*p_argv;
+         double_tmp = **p_argv.d;
 
          if (fparg_count >= NUM_FPR_ARG_REGISTERS)
            {
@@ -160,15 +186,15 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
                  && intarg_count % 2 != 0)
                {
                  intarg_count++;
-                 next_arg++;
+                 next_arg.u++;
                }
-             *(double *)next_arg = double_tmp;
-             next_arg += 2;
+             *next_arg.d = double_tmp;
+             next_arg.u += 2;
            }
          else
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
          break;
 
        case FFI_TYPE_UINT64:
@@ -177,13 +203,13 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
            intarg_count++;
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
            {
-             if (intarg_count%2 != 0)
+             if (intarg_count % 2 != 0)
                {
                  intarg_count++;
-                 next_arg++;
+                 next_arg.u++;
                }
-             *(long long *)next_arg = *(long long *)*p_argv;
-             next_arg += 2;
+             *next_arg.ll = **p_argv.ll;
+             next_arg.u += 2;
            }
          else
            {
@@ -194,13 +220,12 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
               * not correct starting register of pair then skip
               * until the proper starting register
               */
-             if (intarg_count%2 != 0)
+             if (intarg_count % 2 != 0)
                {
                  intarg_count ++;
-                 gpr_base++;
+                 gpr_base.u++;
                }
-             *(long long *)gpr_base = *(long long *)*p_argv;
-             gpr_base += 2;
+             *gpr_base.ll++ = **p_argv.ll;
            }
          intarg_count += 2;
          break;
@@ -210,49 +235,50 @@ void ffi_prep_args_SYSV(extended_cif *ecif, unsigned *const stack)
        case FFI_TYPE_LONGDOUBLE:
 #endif
          struct_copy_size = ((*ptr)->size + 15) & ~0xF;
-         copy_space -= struct_copy_size;
-         memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
+         copy_space.c -= struct_copy_size;
+         memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
 
-         gprvalue = (unsigned long)copy_space;
+         gprvalue = (unsigned long) copy_space.c;
 
-         FFI_ASSERT(copy_space > (char *)next_arg);
-         FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
+         FFI_ASSERT (copy_space.c > next_arg.c);
+         FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
          goto putgpr;
 
        case FFI_TYPE_UINT8:
-         gprvalue = *(unsigned char *)*p_argv;
+         gprvalue = **p_argv.uc;
          goto putgpr;
        case FFI_TYPE_SINT8:
-         gprvalue = *(signed char *)*p_argv;
+         gprvalue = **p_argv.sc;
          goto putgpr;
        case FFI_TYPE_UINT16:
-         gprvalue = *(unsigned short *)*p_argv;
+         gprvalue = **p_argv.us;
          goto putgpr;
        case FFI_TYPE_SINT16:
-         gprvalue = *(signed short *)*p_argv;
+         gprvalue = **p_argv.ss;
          goto putgpr;
 
        case FFI_TYPE_INT:
        case FFI_TYPE_UINT32:
        case FFI_TYPE_SINT32:
        case FFI_TYPE_POINTER:
-         gprvalue = *(unsigned *)*p_argv;
+         gprvalue = **p_argv.ui;
+
        putgpr:
          if (intarg_count >= NUM_GPR_ARG_REGISTERS)
-           *next_arg++ = gprvalue;
+           *next_arg.u++ = gprvalue;
          else
-           *gpr_base++ = gprvalue;
+           *gpr_base.u++ = gprvalue;
          intarg_count++;
          break;
        }
     }
 
   /* Check that we didn't overrun the stack...  */
-  FFI_ASSERT(copy_space >= (char *)next_arg);
-  FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
-  FFI_ASSERT((unsigned *)fpr_base
-            <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
-  FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+  FFI_ASSERT (copy_space.c >= next_arg.c);
+  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
+  FFI_ASSERT (fpr_base.u
+             <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
 }
 
 /* About the LINUX64 ABI.  */
@@ -297,159 +323,187 @@ enum { ASM_NEEDS_REGISTERS64 = 4 };
 */
 
 /*@-exportheader@*/
-void FFI_HIDDEN ffi_prep_args64(extended_cif *ecif, unsigned long *const stack)
+void FFI_HIDDEN
+ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
 /*@=exportheader@*/
 {
   const unsigned long bytes = ecif->cif->bytes;
   const unsigned long flags = ecif->cif->flags;
 
+  typedef union {
+    char *c;
+    unsigned long *ul;
+    float *f;
+    double *d;
+  } valp;
+
   /* 'stacktop' points at the previous backchain pointer.  */
-  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
+  valp stacktop;
 
   /* 'next_arg' points at the space for gpr3, and grows upwards as
      we use GPR registers, then continues at rest.  */
-  unsigned long *const gpr_base = stacktop - ASM_NEEDS_REGISTERS64
-    - NUM_GPR_ARG_REGISTERS64;
-  unsigned long *const gpr_end = gpr_base + NUM_GPR_ARG_REGISTERS64;
-  unsigned long *const rest = stack + 6 + NUM_GPR_ARG_REGISTERS64;
-  unsigned long *next_arg = gpr_base;
+  valp gpr_base;
+  valp gpr_end;
+  valp rest;
+  valp next_arg;
 
   /* 'fpr_base' points at the space for fpr3, and grows upwards as
      we use FPR registers.  */
-  double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS64;
-  int fparg_count = 0;
+  valp fpr_base;
+  int fparg_count;
 
   int i, words;
   ffi_type **ptr;
   double double_tmp;
-  void **p_argv;
+  union {
+    void **v;
+    char **c;
+    signed char **sc;
+    unsigned char **uc;
+    signed short **ss;
+    unsigned short **us;
+    signed int **si;
+    unsigned int **ui;
+    unsigned long **ul;
+    float **f;
+    double **d;
+  } p_argv;
   unsigned long gprvalue;
 
+  stacktop.c = (char *) stack + bytes;
+  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
+  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
+  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
+  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
+  fparg_count = 0;
+  next_arg.ul = gpr_base.ul;
+
   /* Check that everything starts aligned properly.  */
-  FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
-  FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
-  FFI_ASSERT((bytes & 0xF) == 0);
+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
+  FFI_ASSERT ((bytes & 0xF) == 0);
 
   /* Deal with return values that are actually pass-by-reference.  */
   if (flags & FLAG_RETVAL_REFERENCE)
-    *next_arg++ = (unsigned long)(char *)ecif->rvalue;
+    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
 
   /* Now for the arguments.  */
-  p_argv = ecif->avalue;
+  p_argv.v = ecif->avalue;
   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
        i > 0;
-       i--, ptr++, p_argv++)
+       i--, ptr++, p_argv.v++)
     {
       switch ((*ptr)->type)
        {
        case FFI_TYPE_FLOAT:
-         double_tmp = *(float *)*p_argv;
-         *(float *)next_arg = (float)double_tmp;
-         if (++next_arg == gpr_end)
-           next_arg = rest;
+         double_tmp = **p_argv.f;
+         *next_arg.f = (float) double_tmp;
+         if (++next_arg.ul == gpr_end.ul)
+           next_arg.ul = rest.ul;
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
          break;
 
        case FFI_TYPE_DOUBLE:
-         double_tmp = *(double *)*p_argv;
-         *(double *)next_arg = double_tmp;
-         if (++next_arg == gpr_end)
-           next_arg = rest;
+         double_tmp = **p_argv.d;
+         *next_arg.d = double_tmp;
+         if (++next_arg.ul == gpr_end.ul)
+           next_arg.ul = rest.ul;
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
          break;
 
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
        case FFI_TYPE_LONGDOUBLE:
-         double_tmp = ((double *) *p_argv)[0];
-         *(double *) next_arg = double_tmp;
-         if (++next_arg == gpr_end)
-           next_arg = rest;
+         double_tmp = (*p_argv.d)[0];
+         *next_arg.d = double_tmp;
+         if (++next_arg.ul == gpr_end.ul)
+           next_arg.ul = rest.ul;
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         double_tmp = ((double *) *p_argv)[1];
-         *(double *) next_arg = double_tmp;
-         if (++next_arg == gpr_end)
-           next_arg = rest;
+         double_tmp = (*p_argv.d)[1];
+         *next_arg.d = double_tmp;
+         if (++next_arg.ul == gpr_end.ul)
+           next_arg.ul = rest.ul;
          if (fparg_count < NUM_FPR_ARG_REGISTERS64)
-           *fpr_base++ = double_tmp;
+           *fpr_base.d++ = double_tmp;
          fparg_count++;
-         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
          break;
 #endif
 
        case FFI_TYPE_STRUCT:
          words = ((*ptr)->size + 7) / 8;
-         if (next_arg >= gpr_base && next_arg + words > gpr_end)
+         if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
            {
-             size_t first = (char *) gpr_end - (char *) next_arg;
-             memcpy((char *) next_arg, (char *) *p_argv, first);
-             memcpy((char *) rest, (char *) *p_argv + first,
-                    (*ptr)->size - first);
-             next_arg = (unsigned long *) ((char *) rest + words * 8 - first);
+             size_t first = gpr_end.c - next_arg.c;
+             memcpy (next_arg.c, *p_argv.c, first);
+             memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
+             next_arg.c = rest.c + words * 8 - first;
            }
          else
            {
-             char *where = (char *) next_arg;
+             char *where = next_arg.c;
 
              /* Structures with size less than eight bytes are passed
                 left-padded.  */
              if ((*ptr)->size < 8)
                where += 8 - (*ptr)->size;
 
-             memcpy (where, (char *) *p_argv, (*ptr)->size);
-             next_arg += words;
-             if (next_arg == gpr_end)
-               next_arg = rest;
+             memcpy (where, *p_argv.c, (*ptr)->size);
+             next_arg.ul += words;
+             if (next_arg.ul == gpr_end.ul)
+               next_arg.ul = rest.ul;
            }
          break;
 
        case FFI_TYPE_UINT8:
-         gprvalue = *(unsigned char *)*p_argv;
+         gprvalue = **p_argv.uc;
          goto putgpr;
        case FFI_TYPE_SINT8:
-         gprvalue = *(signed char *)*p_argv;
+         gprvalue = **p_argv.sc;
          goto putgpr;
        case FFI_TYPE_UINT16:
-         gprvalue = *(unsigned short *)*p_argv;
+         gprvalue = **p_argv.us;
          goto putgpr;
        case FFI_TYPE_SINT16:
-         gprvalue = *(signed short *)*p_argv;
+         gprvalue = **p_argv.ss;
          goto putgpr;
        case FFI_TYPE_UINT32:
-         gprvalue = *(unsigned int *)*p_argv;
+         gprvalue = **p_argv.ui;
          goto putgpr;
        case FFI_TYPE_INT:
        case FFI_TYPE_SINT32:
-         gprvalue = *(signed int *)*p_argv;
+         gprvalue = **p_argv.si;
          goto putgpr;
 
        case FFI_TYPE_UINT64:
        case FFI_TYPE_SINT64:
        case FFI_TYPE_POINTER:
-         gprvalue = *(unsigned long *)*p_argv;
+         gprvalue = **p_argv.ul;
        putgpr:
-         *next_arg++ = gprvalue;
-         if (next_arg == gpr_end)
-           next_arg = rest;
+         *next_arg.ul++ = gprvalue;
+         if (next_arg.ul == gpr_end.ul)
+           next_arg.ul = rest.ul;
          break;
        }
     }
 
-  FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS
-            || (next_arg >= gpr_base && next_arg <= gpr_base + 4));
+  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
+             || (next_arg.ul >= gpr_base.ul
+                 && next_arg.ul <= gpr_base.ul + 4));
 }
 
 
 
 /* Perform machine dependent cif processing */
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
 {
   /* All this is for the SYSV and LINUX64 ABI.  */
   int i;
@@ -467,10 +521,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
         Redo the calculation for SYSV.  */
 
       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
-      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
+      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
 
       /* Space for the GPR registers.  */
-      bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
+      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
     }
   else
     {
@@ -478,10 +532,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
 
       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
         regs.  */
-      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof(long);
+      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
 
       /* Space for the mandatory parm save area and general registers.  */
-      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof(long);
+      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
 
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
       if (type == FFI_TYPE_LONGDOUBLE)
@@ -523,23 +577,26 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
             in memory.  */
 
          /* Treat structs with size <= 8 bytes.  */
-         if (size <= 8) {
-           flags |= FLAG_RETURNS_SMST;
-           /* These structs are returned in r3. We pack the type and the
-              precalculated shift value (needed in the sysv.S) into flags.
-              The same applies for the structs returned in r3/r4.  */
-           if (size <= 4) {
-             flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 )
-               | (8 * (4 - size) << 4);
-             break;
-           }
-           /* These structs are returned in r3 and r4. See above.   */
-           if  (size <= 8) {
-             flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 )
-               | (8 * (8 - size) << 4);
-           break;
+         if (size <= 8)
+           {
+             flags |= FLAG_RETURNS_SMST;
+             /* These structs are returned in r3. We pack the type and the
+                precalculated shift value (needed in the sysv.S) into flags.
+                The same applies for the structs returned in r3/r4.  */
+             if (size <= 4)
+               {
+                 flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
+                 flags |= 8 * (4 - size) << 4;
+                 break;
+               }
+             /* These structs are returned in r3 and r4. See above.   */
+             if  (size <= 8)
+               {
+                 flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
+                 flags |= 8 * (8 - size) << 4;
+                 break;
+               }
            }
-         }
        }
       /* else fall through.  */
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
@@ -600,7 +657,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
               (r7,r8), (r9,r10).
            */
            if (intarg_count == NUM_GPR_ARG_REGISTERS-1
-               || intarg_count%2 != 0)
+               || intarg_count % 2 != 0)
              intarg_count++;
            intarg_count += 2;
            break;
@@ -663,23 +720,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
     {
       /* Space for the FPR registers, if needed.  */
       if (fparg_count != 0)
-       bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+       bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
 
       /* Stack space.  */
       if (intarg_count > NUM_GPR_ARG_REGISTERS)
-       bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
+       bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
       if (fparg_count > NUM_FPR_ARG_REGISTERS)
-       bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
+       bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
     }
   else
     {
       /* Space for the FPR registers, if needed.  */
       if (fparg_count != 0)
-       bytes += NUM_FPR_ARG_REGISTERS64 * sizeof(double);
+       bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
 
       /* Stack space.  */
       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
-       bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof(long);
+       bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
     }
 
   /* The stack space allocated needs to be a multiple of 16 bytes.  */
@@ -707,10 +764,11 @@ extern void FFI_HIDDEN ffi_call_LINUX64(/*@out@*/ extended_cif *,
 /*@=declundef@*/
 /*@=exportheader@*/
 
-void ffi_call(/*@dependent@*/ ffi_cif *cif,
-             void (*fn)(),
-             /*@out@*/ void *rvalue,
-             /*@dependent@*/ void **avalue)
+void
+ffi_call(/*@dependent@*/ ffi_cif *cif,
+        void (*fn)(),
+        /*@out@*/ void *rvalue,
+        /*@dependent@*/ void **avalue)
 {
   extended_cif ecif;
 
@@ -720,8 +778,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
   /* 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->rtype->type == FFI_TYPE_STRUCT))
     {
       /*@-sysunrecog@*/
       ecif.rvalue = alloca(cif->rtype->size);
@@ -737,47 +794,47 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
     case FFI_SYSV:
     case FFI_GCC_SYSV:
       /*@-usedef@*/
-      ffi_call_SYSV(&ecif, -cif->bytes,
-                   cif->flags, ecif.rvalue, fn);
+      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
       break;
 #else
     case FFI_LINUX64:
       /*@-usedef@*/
-      ffi_call_LINUX64(&ecif, -(long) cif->bytes,
-                      cif->flags, ecif.rvalue, fn);
+      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
       break;
 #endif
     default:
-      FFI_ASSERT(0);
+      FFI_ASSERT (0);
       break;
     }
 }
 
 
 #ifndef POWERPC64
-static void flush_icache(char *, int);
-
 #define MIN_CACHE_LINE_SIZE 8
 
-static void flush_icache(char * addr1, int size)
+static void
+flush_icache (char *addr1, int size)
 {
   int i;
   char * addr;
-  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
-    addr = addr1 + i;
-    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
-  }
+  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
+    {
+      addr = addr1 + i;
+      __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;"
+                       : : "r" (addr) : "memory");
+    }
   addr = addr1 + size - 1;
-  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
+  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;"
+                   : : "r"(addr) : "memory");
 }
 #endif
 
 ffi_status
-ffi_prep_closure (ffi_closureclosure,
-                 ffi_cifcif,
-                 void (*fun)(ffi_cif*, void*, void**, void*),
+ffi_prep_closure (ffi_closure *closure,
+                 ffi_cif *cif,
+                 void (*fun) (ffi_cif *, void *, void **, void *),
                  void *user_data)
 {
 #ifdef POWERPC64
@@ -801,11 +858,11 @@ ffi_prep_closure (ffi_closure* closure,
   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
   tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
   tramp[9] = 0x4e800420;  /*   bctr */
-  *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
-  *(void **) &tramp[3] = (void *)closure;          /* context */
+  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
+  *(void **) &tramp[3] = (void *) closure;          /* context */
 
   /* Flush the icache.  */
-  flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+  flush_icache (&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
 #endif
 
   closure->cif = cif;
@@ -821,8 +878,8 @@ typedef union
   double d;
 } ffi_dblfl;
 
-int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
-                            ffi_dblfl*, unsigned long*);
+int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
+                            ffi_dblfl *, unsigned long *);
 
 /* Basically the trampoline invokes ffi_closure_SYSV, and on
  * entry, r11 holds the address of the closure.
@@ -833,9 +890,9 @@ int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
  */
 
 int
-ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
-                        unsigned long * pgr, ffi_dblfl * pfr,
-                        unsigned long * pst)
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
+                        unsigned long *pgr, ffi_dblfl *pfr,
+                        unsigned long *pst)
 {
   /* rvalue is the pointer to space for return value in closure assembly */
   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
@@ -852,7 +909,7 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
   unsigned         size;
 
   cif = closure->cif;
-  avalue = alloca(cif->nargs * sizeof(void *));
+  avalue = alloca (cif->nargs * sizeof (void *));
   size = cif->rtype->size;
 
   nf = 0;
@@ -865,11 +922,12 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
 
   if (cif->rtype->type == FFI_TYPE_STRUCT)
     {
-      if (!((cif->abi == FFI_SYSV) && (size <= 8))) {
-       rvalue = (void *) *pgr;
-       ng++;
-       pgr++;
-      }
+      if (!((cif->abi == FFI_SYSV) && (size <= 8)))
+       {
+         rvalue = (void *) *pgr;
+         ng++;
+         pgr++;
+       }
     }
 
   i = 0;
@@ -884,54 +942,66 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
        case FFI_TYPE_SINT8:
        case FFI_TYPE_UINT8:
          /* there are 8 gpr registers used to pass values */
-         if (ng < 8) {
-           avalue[i] = (((char *)pgr)+3);
-           ng++;
-           pgr++;
-         } else {
-           avalue[i] = (((char *)pst)+3);
-           pst++;
-         }
+         if (ng < 8)
+           {
+             avalue[i] = (char *) pgr + 3;
+             ng++;
+             pgr++;
+           }
+         else
+           {
+             avalue[i] = (char *) pst + 3;
+             pst++;
+           }
          break;
 
        case FFI_TYPE_SINT16:
        case FFI_TYPE_UINT16:
          /* there are 8 gpr registers used to pass values */
-         if (ng < 8) {
-           avalue[i] = (((char *)pgr)+2);
-           ng++;
-           pgr++;
-         } else {
-           avalue[i] = (((char *)pst)+2);
-           pst++;
-         }
+         if (ng < 8)
+           {
+             avalue[i] = (char *) pgr + 2;
+             ng++;
+             pgr++;
+           }
+         else
+           {
+             avalue[i] = (char *) pst + 2;
+             pst++;
+           }
          break;
 
        case FFI_TYPE_SINT32:
        case FFI_TYPE_UINT32:
        case FFI_TYPE_POINTER:
          /* there are 8 gpr registers used to pass values */
-         if (ng < 8) {
-           avalue[i] = pgr;
-           ng++;
-           pgr++;
-         } else {
-           avalue[i] = pst;
-           pst++;
-         }
+         if (ng < 8)
+           {
+             avalue[i] = pgr;
+             ng++;
+             pgr++;
+           }
+         else
+           {
+             avalue[i] = pst;
+             pst++;
+           }
          break;
 
        case FFI_TYPE_STRUCT:
          /* Structs are passed by reference. The address will appear in a
             gpr if it is one of the first 8 arguments.  */
-         if (ng < 8) {
-           avalue[i] = (void *) *pgr;
-           ng++;
-           pgr++;
-         } else {
-           avalue[i] = (void *) *pst;
-           pst++;
-         }
+         if (ng < 8)
+           {
+             avalue[i] = (void *) *pgr;
+             ng++;
+             pgr++;
+           }
+         else
+           {
+             avalue[i] = (void *) *pst;
+             pst++;
+           }
          break;
 
        case FFI_TYPE_SINT64:
@@ -945,20 +1015,25 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
           * or pst to find the correct address for this type
           * of parameter.
           */
-         if (ng < 7) {
-           if (ng & 0x01) {
-             /* skip r4, r6, r8 as starting points */
-             ng++;
-             pgr++;
+         if (ng < 7)
+           {
+             if (ng & 0x01)
+               {
+                 /* skip r4, r6, r8 as starting points */
+                 ng++;
+                 pgr++;
+               }
+             avalue[i] = pgr;
+             ng += 2;
+             pgr += 2;
+           }
+         else
+           {
+             if (((long) pst) & 4)
+               pst++;
+             avalue[i] = pst;
+             pst += 2;
            }
-           avalue[i] = pgr;
-           ng+=2;
-           pgr+=2;
-         } else {
-           if (((long)pst) & 4) pst++;
-           avalue[i] = pst;
-           pst+=2;
-         }
          break;
 
        case FFI_TYPE_FLOAT:
@@ -969,42 +1044,49 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
 
          /* there are 8 64bit floating point registers */
 
-         if (nf < 8) {
-           temp = pfr->d;
-           pfr->f = (float)temp;
-           avalue[i] = pfr;
-           nf++;
-           pfr++;
-         } else {
-           /* FIXME? here we are really changing the values
-            * stored in the original calling routines outgoing
-            * parameter stack.  This is probably a really
-            * naughty thing to do but...
-            */
-           avalue[i] = pst;
-           nf++;
-           pst+=1;
-         }
+         if (nf < 8)
+           {
+             temp = pfr->d;
+             pfr->f = (float) temp;
+             avalue[i] = pfr;
+             nf++;
+             pfr++;
+           }
+         else
+           {
+             /* FIXME? here we are really changing the values
+              * stored in the original calling routines outgoing
+              * parameter stack.  This is probably a really
+              * naughty thing to do but...
+              */
+             avalue[i] = pst;
+             nf++;
+             pst += 1;
+           }
          break;
 
        case FFI_TYPE_DOUBLE:
          /* On the outgoing stack all values are aligned to 8 */
          /* there are 8 64bit floating point registers */
 
-         if (nf < 8) {
-           avalue[i] = pfr;
-           nf++;
-           pfr++;
-         } else {
-           if (((long)pst) & 4) pst++;
-           avalue[i] = pst;
-           nf++;
-           pst+=2;
-         }
+         if (nf < 8)
+           {
+             avalue[i] = pfr;
+             nf++;
+             pfr++;
+           }
+         else
+           {
+             if (((long) pst) & 4)
+               pst++;
+             avalue[i] = pst;
+             nf++;
+             pst += 2;
+           }
          break;
 
        default:
-         FFI_ASSERT(0);
+         FFI_ASSERT (0);
        }
 
       i++;
@@ -1023,8 +1105,8 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
 
 }
 
-int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure*, void*, unsigned long*,
-                                          ffi_dblfl*);
+int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
+                                          unsigned long *, ffi_dblfl *);
 
 int FFI_HIDDEN
 ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
@@ -1153,7 +1235,7 @@ ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
 #endif
 
        default:
-         FFI_ASSERT(0);
+         FFI_ASSERT (0);
        }
 
       i++;