Commits

Ronald Oussoren  committed da4afd7

Libffi tests now pass on powerpc, except for cls_align_longdouble (and all
regular tests still pass to)

  • Participants
  • Parent commits 616f363
  • Branches pyobjc-ancient

Comments (0)

Files changed (4)

File libffi-src/src/powerpc/ffi_darwin.c

 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
 	  break;
 
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+	case FFI_TYPE_LONGDOUBLE:
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS-1) {
+	    ((double *)next_arg)[0] = ((double *)*p_argv)[0];
+	    ((double *)next_arg)[1] = ((double *)*p_argv)[0];
+	  } else {
+	    *fpr_base++ = ((double *)*p_argv)[0];
+	    *fpr_base++ = ((double *)*p_argv)[1];
+	  }
+	  next_arg += 2;
+
+	  fparg_count += 2;
+
+	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+	  break;
+#endif
+
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_SINT64:
 	  *(long long *)next_arg = *(long long *)*p_argv;
 
 	case FFI_TYPE_STRUCT:
 
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
-	case FFI_TYPE_LONGDOUBLE:
-#endif
 	  dest_cpy = (char *) next_arg;
 
 	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
 	  /* If the first member of the struct is a double, then align
 	     the struct to double-word.
 	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
-	  if ((*ptr)->elements[0]->type == 3)
+	  if ((*ptr)->elements && (*ptr)->elements[0]->type == 3)
 	    size_al = ALIGN((*ptr)->size, 8);
-	  if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
+	  if (size_al < 3 && (ecif->cif == NULL ||  ecif->cif->abi == FFI_DARWIN))
+	    /* XXX: for some reason ecif->cif is NULL at times */
 	    dest_cpy += 4 - size_al;
 
 	  memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
 	  /* If the first member of the struct is a double, then align
 	     the struct to double-word.
 	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
-	  if ((*ptr)->elements[0]->type == 3)
+	  if ((*ptr)->elements && (*ptr)->elements[0]->type == 3)
 	    size_al = ALIGN((*ptr)->size, 8);
 	  intarg_count += (size_al + 3) / 4;
 	  break;

File libffi-src/src/prep_cif.c

       /* Perform a sanity check on the argument type */
       FFI_ASSERT_VALID_TYPE(*ptr);
 
+#ifdef POWERPC_DARWIN
+      {
+      int curalign;
+
+      curalign = (*ptr)->alignment;
+      if (ptr != &(arg->elements[0])) {
+	      if (curalign > 4) {
+		      curalign = 4;
+	      }
+      }
+
+      arg->size = ALIGN(arg->size, curalign);
+      arg->size += (*ptr)->size;
+
+      arg->alignment = (arg->alignment > curalign) ? 
+	arg->alignment : curalign;
+      }
+#else
+      int curalign;
+
       arg->size = ALIGN(arg->size, (*ptr)->alignment);
       arg->size += (*ptr)->size;
 
       arg->alignment = (arg->alignment > (*ptr)->alignment) ? 
 	arg->alignment : (*ptr)->alignment;
+#endif
 
       ptr++;
     }

File libffi-src/src/types.c

 
 #endif
 
-#if defined X86 || defined ARM || defined M68K || defined(POWERPC_DARWIN) || defined(X86_DARWIN)
+#if defined X86 || defined ARM || defined M68K || defined(X86_DARWIN)
 
 FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
 FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
 
+#elif defined(POWERPC_DARWIN)
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
+
 #elif defined SH
 
 FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
 FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
 #endif
 
-#elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN
+#elif defined ARM || defined SH || defined POWERPC_AIX 
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
 FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
 
+#elif defined POWERPC_DARWIN
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+
+#if __GNUC__ >= 4
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+#else
+#error "don't use this"
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
+#endif
+
 #elif defined SPARC
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);

File libffi-src/testsuite/libffi.call/float.c

 {
   int i;
 
+  printf("%d\n", e);
+  printf("a:%d b:%f c:%f d:%llf e:%d\n", a, b, c, d, e);
   i = (int) ((float)a/b + ((float)c/(float)d));
 
   return i;
 
   floating (si1, f, d, ld, si2);
 
+  printf("calling through ffi %d\n", si2);
   ffi_call(&cif, FFI_FN(floating), &rint, values);
 
   printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));