tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Can someone affirm the attached patch working on non-aix/power64 machines?



Hi all,

to get python running on AIX I first needed to patch libffi.
Can please someone try the attached patch on power64 architectures and tell
me whether it breaks them or not?

Thanks in advance,
Jens
Index: devel/libffi/distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/devel/libffi/distinfo,v
retrieving revision 1.14
diff -u -r1.14 distinfo
--- devel/libffi/distinfo       21 Sep 2009 00:33:51 -0000      1.14
+++ devel/libffi/distinfo       22 Nov 2009 20:51:50 -0000
@@ -13,3 +13,7 @@
 SHA1 (patch-ah) = e9580069ede90cd616da7bc230b28acbf5d204a6
 SHA1 (patch-ai) = f9a81054764fd15bcd2e4743c90e425e844b0825
 SHA1 (patch-aj) = 6fa0cff1b0e764fe0311d87365b85d2318814a2d
+SHA1 (patch-ak) = 93b438e4488e09544973501ed3027d4fa49756b6
+SHA1 (patch-al) = 985a5ddbfd629257c2faf42dd5bf87db51e30db0
+SHA1 (patch-am) = f9df8105ce084eced4db2e53203734b18335548c
+SHA1 (patch-an) = c7a3ec30a46e716049eb230fcdc759fcdd9a43a2
Index: devel/libffi/patches/patch-ak
===================================================================
RCS file: devel/libffi/patches/patch-ak
diff -N devel/libffi/patches/patch-ak
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ devel/libffi/patches/patch-ak       22 Nov 2009 20:51:50 -0000
@@ -0,0 +1,164 @@
+--- src/powerpc/aix.S.orig     2009-09-24 15:29:59.000000000 +0200
++++ src/powerpc/aix.S  2009-09-24 15:30:09.000000000 +0200
+@@ -88,10 +88,140 @@
+       .toc
+       .csect .text[PR]
+       .align 2
+-.globl ffi_prep_args
+ 
+ .csect .text[PR]
+       .align 2
++#ifdef __64BIT__
++      /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
++       *                   unsigned int flags, unsigned int *rvalue,
++       *                   void (*fn)(),
++       *                   void (*prep_args)(extended_cif*, unsigned *const));
++       * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args
++       */
++
++      .globl ffi_call_AIX
++      .globl .ffi_call_AIX
++.csect ffi_call_AIX[DS]
++ffi_call_AIX:
++      .llong .ffi_call_AIX, TOC[tc0], 0
++      .csect .text[PR]
++.ffi_call_AIX:
++        // We only need r12 until the call, so it doesn't have to be saved...
++
++      mr      r12,r8                  /* r8 is prep_args() */
++
++      /* Save the old stack pointer as AP.  */
++
++      mr      r8,r1
++
++      /* Allocate the stack space we need.  */
++
++      stdux   r1,r1,r4                /* r4 is -cif->bytes */
++
++      /* Save registers we use.  */
++
++      mflr    r9                      /* r9 becomes return address */
++
++      std     r28,-32(r8)
++      std     r29,-24(r8)
++      std     r30,-16(r8)
++      std     r31, -8(r8)
++
++      std     r9, 16(r8)              /* save return address */
++      std     r2, 40(r1)              /* save TOC pointer */
++
++      /* Save arguments over call...  */
++      mr      r31,r5  /* flags, */
++      mr      r30,r6  /* rvalue, */
++      mr      r29,r7  /* fn() */
++      mr      r28,r8  /* our AP. */
++
++      /* Call ffi_prep_args.  */
++      /* r3 is already &ecif */
++      mr      r4,r1           /* r4 becomes stack pointer */
++      li      r9,0
++
++      ld      r2,8(r12)       /* TOC of prep_args() */
++      ld      r12,0(r12)      /* trampoline */
++      mtctr   r12             /* r12 holds address of prep_args() */
++      bctrl
++      ld     r2,40(r1)        /* restore TOC */
++
++      /* Now do the call.  */
++
++      ld      r12,0(r29)      /* r29 is fn(), r12 its trampoline */
++      /* Set up cr1 with bits 4-7 of the flags.  */
++      mtcrf   0x40,r31        /* r31 is cif->flags */
++      std     r2,40(r1)       /* save current TOC */
++      mtctr   r12             /* load ctr with fn() pointer */
++      ld      r2,8(r29)       /* r2 is TOC of fn() */
++      /* Load all those argument registers.  */
++      // We have set up a nice stack frame, just load it into registers.
++      ld      r3, 40+(1*8)(r1)
++      ld      r4, 40+(2*8)(r1)
++      ld      r5, 40+(3*8)(r1)
++      ld      r6, 40+(4*8)(r1)
++      nop
++      ld      r7, 40+(5*8)(r1)
++      ld      r8, 40+(6*8)(r1)
++      ld      r9, 40+(7*8)(r1)
++      ld      r10,40+(8*8)(r1)
++
++L1:
++      /* Load all the FP registers.  */
++      bf      6,L2 // 2f + 0x18
++      lfd     f1,-32-(13*8)(r28)
++      lfd     f2,-32-(12*8)(r28)
++      lfd     f3,-32-(11*8)(r28)
++      lfd     f4,-32-(10*8)(r28)
++      nop
++      lfd     f5,-32-(9*8)(r28)
++      lfd     f6,-32-(8*8)(r28)
++      lfd     f7,-32-(7*8)(r28)
++      lfd     f8,-32-(6*8)(r28)
++      nop
++      lfd     f9,-32-(5*8)(r28)
++      lfd     f10,-32-(4*8)(r28)
++      lfd     f11,-32-(3*8)(r28)
++      lfd     f12,-32-(2*8)(r28)
++      nop
++      lfd     f13,-32-(1*8)(r28)
++
++L2:
++      /* Make the call.  */
++      bctrl
++      ld r2,40(r1)    /* restore TOC */
++
++      /* Now, deal with the return value.  */
++      mtcrf   0x1,r31
++
++      bt      30,L(done_return_value)
++      bt      29,L(fp_return_value)
++      std     r3,0(r30)
++
++      /* Fall through...  */
++
++L(done_return_value):
++      /* Restore the registers we used and return.  */
++      ld      r9,   16(r28)
++      ld      r31,  -8(r28)
++      mtlr    r9
++      ld      r30, -16(r28)
++      ld      r29,-24(r28)
++      ld      r28,-32(r28)
++      ld      r1,0(r1)
++      blr
++
++L(fp_return_value):
++      bf      28,L(float_return_value)
++      stfd    f1,0(r30)
++      b       L(done_return_value)
++L(float_return_value):
++      stfs    f1,0(r30)
++      b       L(done_return_value)
++      .long 0
++      .byte 0,0,0,1,128,4,0,0
++#else /* ! __64BIT__ */
+       .globl ffi_call_AIX
+       .globl .ffi_call_AIX
+ .csect ffi_call_AIX[DS]
+@@ -208,6 +338,7 @@
+       b       L(done_return_value)
+       .long 0
+       .byte 0,0,0,1,128,4,0,0
++#endif /* ! __64BIT__ */
+ //END(ffi_call_AIX)
+ 
+ .csect .text[PR]
+@@ -216,7 +347,11 @@
+       .globl .ffi_call_DARWIN
+ .csect ffi_call_DARWIN[DS]
+ ffi_call_DARWIN:
++#ifdef __64BIT__
++      .llong .ffi_call_DARWIN, TOC[tc0], 0
++#else
+       .long .ffi_call_DARWIN, TOC[tc0], 0
++#endif
+       .csect .text[PR]
+ .ffi_call_DARWIN:
+       blr
Index: devel/libffi/patches/patch-al
===================================================================
RCS file: devel/libffi/patches/patch-al
diff -N devel/libffi/patches/patch-al
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ devel/libffi/patches/patch-al       22 Nov 2009 20:51:50 -0000
@@ -0,0 +1,203 @@
+--- src/powerpc/aix_closure.S.orig     2006-12-25 00:12:13.000000000 +0100
++++ src/powerpc/aix_closure.S  2009-09-24 15:44:23.000000000 +0200
+@@ -84,6 +84,7 @@
+ #define L(x) x
+       .file "aix_closure.S"
+       .toc
++      .extern .ffi_closure_helper_DARWIN
+ LC..60:
+       .tc L..60[TC],L..60
+       .csect .text[PR]
+@@ -91,6 +92,174 @@
+ 
+ .csect .text[PR]
+       .align 2
++#ifdef __64BIT__
++      .globl ffi_closure_ASM
++      .globl .ffi_closure_ASM
++.csect ffi_closure_ASM[DS]
++
++
++ffi_closure_ASM:
++      .llong .ffi_closure_ASM, TOC[tc0], 0
++      .csect .text[PR]
++.ffi_closure_ASM:
++
++      mflr r0                 /* extract return address */
++      std r0, 16(r1)          /* save the return address */
++
++      /* 48 Bytes (Linkage Area) */
++      /* 64 Bytes (output params 8*8) */
++      /* 104 Bytes (13*8 from FPR) */
++      /* 32 Bytes (result) */
++      /* 248 Bytes */
++
++      stdu r1,-248(r1)        /* skip over caller save area */
++
++      /* we want to build up an area for the parameters passed
++       * in registers (both floating point and integer) */
++
++      /* 256 bytes (callee stack frame aligned to 32
++       * 48 bytes (caller linkage area)
++       * 304 (start of caller parameter aligned to 8
++       */
++
++
++      /* we store gpr 3 to gpr 10 in the parents outgoing area  */
++
++      std   r3,  (248+48+0*8)(r1)
++      std   r4,  (248+48+1*8)(r1)
++      std   r5,  (248+48+2*8)(r1)
++      std   r6,  (248+48+3*8)(r1)
++      std   r7,  (248+48+4*8)(r1)
++      std   r8,  (248+48+5*8)(r1)
++      std   r9,  (248+48+6*8)(r1)
++      std   r10, (248+48+7*8)(r1)
++
++      /* next save fpr 1 to fpr 13 */
++
++      stfd  f1,  (112+0*8)(r1)
++      stfd  f2,  (112+1*8)(r1)
++      stfd  f3,  (112+2*8)(r1)
++      stfd  f4,  (112+3*8)(r1)
++      stfd  f5,  (112+4*8)(r1)
++      stfd  f6,  (112+5*8)(r1)
++      stfd  f7,  (112+6*8)(r1)
++      stfd  f8,  (112+7*8)(r1)
++      stfd  f9,  (112+8*8)(r1)
++      stfd  f10, (112+9*8)(r1)
++      stfd  f11, (112+10*8)(r1)
++      stfd  f12, (112+11*8)(r1)
++      stfd  f13, (112+12*8)(r1)
++
++      /* set up registers for the routine that actually does the work
++       * get the context pointer from the trampoline
++       */
++      mr r3,r11
++
++      /* now load up the pointer to the result storage
++       * current stack frame size - ((8 * 4) + saved registers)
++       */
++      addi r4,r1,216
++
++      /* now load up the pointer to the saved gpr registers */
++      addi r5,r1,248+48
++
++      /* now load up the pointer to the saved fpr registers */
++      addi r6,r1,112
++
++      /* make the call
++       * int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
++       *                                unsigned long * pgr, ffi_dblfl * pfr)
++       */
++
++      bl .ffi_closure_helper_DARWIN
++      nop
++
++      /* now r3 contains the return type */
++      /* so use it to look up in a table */
++      /* so we know how to deal with each type */
++
++      /* look up the proper starting point in table  */
++      /* by using return type as offset */
++      addi r5,r1,216  /* get pointer to results area */
++      ld   r4,LC..60(r2)      /* get address of jump table */
++      sldi r3,r3,2            /* now multiply return type by 4 */
++      lwzx r3,r4,r3           /* get the contents of that table value */
++      add r3,r3,r4            /* add contents of table to table address */
++      mtctr r3
++      bctr                    /* jump to it */
++
++L..60:
++      .long L..44-L..60    /* FFI_TYPE_VOID */
++      .long L..50-L..60    /* FFI_TYPE_INT */
++      .long L..47-L..60    /* FFI_TYPE_FLOAT */
++      .long L..46-L..60    /* FFI_TYPE_DOUBLE */
++      .long L..62-L..60    /* FFI_TYPE_LONGDOUBLE */
++      .long L..56-L..60    /* FFI_TYPE_UINT8 */
++      .long L..55-L..60    /* FFI_TYPE_SINT8 */
++      .long L..58-L..60    /* FFI_TYPE_UINT16 */
++      .long L..57-L..60    /* FFI_TYPE_SINT16 */
++      .long L..50-L..60    /* FFI_TYPE_UINT32 */
++      .long L..50-L..60    /* FFI_TYPE_SINT32 */
++      .long L..48-L..60    /* FFI_TYPE_UINT64 */
++      .long L..48-L..60    /* FFI_TYPE_SINT64 */
++      .long L..44-L..60    /* FFI_TYPE_STRUCT */
++      .long L..48-L..60    /* FFI_TYPE_POINTER */
++
++
++/* case double */
++L..46:
++      lfd f1,0(r5)
++      b L..44
++
++/* case long double */
++L..62:
++      lfd f1,0(r5)
++      lfd f2,8(r5)
++      b L..44
++
++/* case float */
++L..47:
++      lfs f1,0(r5)
++      b L..44
++
++/* case long long */
++L..48:
++      ld r3,0(r5)
++      b L..44
++
++/* case int / int32 / uint32*/
++L..50:
++      lwz r3,4(r5)
++      b L..44
++
++/* case signed int8    */
++L..55:
++      lbz r3,7(r5)
++      extsb r3,r3
++      b L..44
++
++/* case unsigned int8  */
++L..56:
++      lbz r3,7(r5)
++      b L..44
++
++/* case signed int16 */
++L..57:
++      lha r3,6(r5)
++      b L..44
++
++/* case unsigned int16 */
++L..58:
++      lhz r3,6(r5)
++      b L..44
++
++/* case void / done    */
++L..44:
++      addi r1,r1,248          /* restore stack pointer */
++      ld r0,16(r1)            /* get return address */
++      mtlr r0                 /* reset link register */
++      blr
++#else /* ! __64BIT__ */
+       .globl ffi_closure_ASM
+       .globl .ffi_closure_ASM
+ .csect ffi_closure_ASM[DS]
+@@ -106,8 +275,8 @@
+       /* 24 Bytes (Linkage Area) */
+       /* 32 Bytes (params) */
+       /* 104 Bytes (13*8 from FPR) */
+-      /* 8 Bytes (result) */
+-      /* 168 Bytes */
++      /* 16 Bytes (result) */
++      /* 176 Bytes */
+ 
+       stwu r1,-176(r1)        /* skip over caller save area
+                               keep stack aligned to 16  */
+@@ -243,5 +412,6 @@
+       lwz r0,8(r1)            /* get return address */
+       mtlr r0                 /* reset link register */
+       blr
++#endif        /* __64BIT__ */
+ 
+ /* END(ffi_closure_ASM) */
Index: devel/libffi/patches/patch-am
===================================================================
RCS file: devel/libffi/patches/patch-am
diff -N devel/libffi/patches/patch-am
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ devel/libffi/patches/patch-am       22 Nov 2009 20:51:50 -0000
@@ -0,0 +1,396 @@
+--- src/powerpc/ffi_darwin.c.orig      2009-09-24 15:31:53.000000000 +0200
++++ src/powerpc/ffi_darwin.c   2009-09-24 15:32:07.000000000 +0200
+@@ -80,34 +80,37 @@
+ 
+    */
+ 
+-void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
++void ffi_prep_args(extended_cif *ecif, unsigned long *const stack)
+ {
+   const unsigned bytes = ecif->cif->bytes;
+   const unsigned flags = ecif->cif->flags;
+ 
+   /* 'stacktop' points at the previous backchain pointer.  */
+-  unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
++  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
+ 
+   /* 'fpr_base' points at the space for fpr1, and grows upwards as
+      we use FPR registers.  */
+-  double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - 
NUM_FPR_ARG_REGISTERS;
++  double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) -
++                                                      NUM_FPR_ARG_REGISTERS;
+   int fparg_count = 0;
+ 
+ 
+   /* 'next_arg' grows up as we put parameters in it.  */
+-  unsigned *next_arg = stack + 6; /* 6 reserved positions.  */
++  unsigned long *next_arg = stack + 6; /* 6 reserved positions.  */
+ 
+   int i = ecif->cif->nargs;
++  ffi_abi abi = ecif->cif->abi;
+   double double_tmp;
+   void **p_argv = ecif->avalue;
+-  unsigned gprvalue;
++  unsigned long gprvalue;
+   ffi_type** ptr = ecif->cif->arg_types;
+   char *dest_cpy;
+   unsigned size_al = 0;
+ 
++
+   /* Check that everything starts aligned properly.  */
+-  FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
+-  FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
++  FFI_ASSERT(((unsigned long)(char *)stack & 0xF) == 0);
++  FFI_ASSERT(((unsigned long)(char *)stacktop & 0xF) == 0);
+   FFI_ASSERT((bytes & 0xF) == 0);
+ 
+   /* Deal with return values that are actually pass-by-reference.
+@@ -115,12 +118,10 @@
+      Return values are referenced by r3, so r4 is the first parameter.  */
+ 
+   if (flags & FLAG_RETVAL_REFERENCE)
+-    *next_arg++ = (unsigned)(char *)ecif->rvalue;
++    *next_arg++ = (unsigned long)(char *)ecif->rvalue;/* this overwrites ecif 
*/
+ 
+   /* Now for the arguments.  */
+-  for (;
+-       i > 0;
+-       i--, ptr++, p_argv++)
++  for (; i > 0; i--, ptr++, p_argv++)
+     {
+       switch ((*ptr)->type)
+       {
+@@ -140,11 +141,14 @@
+ 
+       case FFI_TYPE_DOUBLE:
+         double_tmp = *(double *)*p_argv;
+-        if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+-          *(double *)next_arg = double_tmp;
+-        else
++        if (fparg_count < NUM_FPR_ARG_REGISTERS)
+           *fpr_base++ = double_tmp;
++        *(double *)next_arg = double_tmp;
++#if defined(POWERPC64)
++        next_arg++;
++#else
+         next_arg += 2;
++#endif
+         fparg_count++;
+         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         break;
+@@ -152,28 +156,45 @@
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ 
+       case FFI_TYPE_LONGDOUBLE:
+-        double_tmp = ((double *)*p_argv)[0];
+-        if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+-          *(double *)next_arg = double_tmp;
+-        else
+-          *fpr_base++ = double_tmp;
++#ifdef POWERPC64
++        if (fparg_count < NUM_FPR_ARG_REGISTERS) {
++          *(long double*)fpr_base = *(long double*)*p_argv;
++          fpr_base += 2;
++        } else
++          *(long double *)next_arg = *(long double*)*p_argv;
+         next_arg += 2;
+-        fparg_count++;
+-        double_tmp = ((double *)*p_argv)[1];
+-        if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+-          *(double *)next_arg = double_tmp;
++        fparg_count += 2;
++#else
++        double_tmp = *(double *)*p_argv;
++        if (fparg_count < NUM_FPR_ARG_REGISTERS)
++          *fpr_base++ = double_tmp;
+         else
++          *(double *)next_arg = double_tmp;
++
++        double_tmp = ((double *)*p_argv)[1];
++        if (fparg_count < NUM_FPR_ARG_REGISTERS)
+           *fpr_base++ = double_tmp;
+-        next_arg += 2;
+-        fparg_count++;
++        else
++          *(double *)next_arg = double_tmp;
++        next_arg += 4;
++        fparg_count += 2;
++#endif
+         FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+         break;
+ #endif
+       case FFI_TYPE_UINT64:
+       case FFI_TYPE_SINT64:
++#ifdef POWERPC64
++        gprvalue =  *(long long *)*p_argv;
++        goto putgpr;
++#else
+         *(long long *)next_arg = *(long long *)*p_argv;
+         next_arg+=2;
++#endif
+         break;
++      case FFI_TYPE_POINTER:
++        gprvalue =  *(unsigned long *)*p_argv;
++        goto putgpr;
+       case FFI_TYPE_UINT8:
+         gprvalue = *(unsigned char *)*p_argv;
+         goto putgpr;
+@@ -188,6 +209,17 @@
+         goto putgpr;
+ 
+       case FFI_TYPE_STRUCT:
++#ifdef POWERPC64
++        dest_cpy = (char *) next_arg;
++        size_al = (*ptr)->size;
++        if ((*ptr)->elements[0]->type == 3)
++          size_al = ALIGN((*ptr)->size, 8);
++        if (size_al < 3 && abi == FFI_DARWIN)
++          dest_cpy += 4 - size_al;
++
++        memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
++        next_arg += (size_al + 7) / 8;
++#else
+         dest_cpy = (char *) next_arg;
+ 
+         /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+@@ -199,17 +231,17 @@
+            Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
+         if ((*ptr)->elements[0]->type == 3)
+           size_al = ALIGN((*ptr)->size, 8);
+-        if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
++        if (size_al < 3 && abi == FFI_DARWIN)
+           dest_cpy += 4 - size_al;
+ 
+         memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
+         next_arg += (size_al + 3) / 4;
++#endif
+         break;
+ 
+       case FFI_TYPE_INT:
+       case FFI_TYPE_UINT32:
+       case FFI_TYPE_SINT32:
+-      case FFI_TYPE_POINTER:
+         gprvalue = *(unsigned *)*p_argv;
+       putgpr:
+         *next_arg++ = gprvalue;
+@@ -220,10 +252,10 @@
+     }
+ 
+   /* Check that we didn't overrun the stack...  */
+-  //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(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
++  FFI_ASSERT((unsigned long*)fpr_base
++           <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
++  FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+ }
+ 
+ /* Adjust the size of S to be correct for Darwin.
+@@ -278,7 +310,6 @@
+   int fparg_count = 0, intarg_count = 0;
+   unsigned flags = 0;
+   unsigned size_al = 0;
+-
+   /* All the machine-independent calculation of cif->bytes will be wrong.
+      All the calculation of structure sizes will also be wrong.
+      Redo the calculation for DARWIN.  */
+@@ -322,6 +353,9 @@
+       flags |= FLAG_RETURNS_FP;
+       break;
+ 
++#ifdef POWERPC64
++    case FFI_TYPE_POINTER:
++#endif
+     case FFI_TYPE_UINT64:
+     case FFI_TYPE_SINT64:
+       flags |= FLAG_RETURNS_64BITS;
+@@ -391,7 +425,11 @@
+            Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
+         if ((*ptr)->elements[0]->type == 3)
+           size_al = ALIGN((*ptr)->size, 8);
++#ifdef POWERPC64
++        intarg_count += (size_al + 7) / 8;
++#else
+         intarg_count += (size_al + 3) / 4;
++#endif
+         break;
+ 
+       default:
+@@ -410,13 +448,22 @@
+     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+ 
+   /* Stack space.  */
++#ifdef POWERPC64
++  if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
++    bytes += (intarg_count + fparg_count) * sizeof(long);
++#else
+   if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
+     bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
++#endif
+   else
+     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
+ 
+   /* The stack space allocated needs to be a multiple of 16 bytes.  */
++#ifdef POWERPC64
++  bytes = (bytes + 31) & ~0x1F;
++#else
+   bytes = (bytes + 15) & ~0xF;
++#endif
+ 
+   cif->flags = flags;
+   cif->bytes = bytes;
+@@ -424,10 +471,10 @@
+   return FFI_OK;
+ }
+ 
+-extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
+-                       void (*fn)(void), void (*fn2)(void));
+-extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
+-                          void (*fn)(void), void (*fn2)(void));
++extern void ffi_call_AIX(extended_cif *, unsigned long, unsigned, unsigned *,
++              void (*fn)(), void (*fn2)(extended_cif*, unsigned long *const));
++extern void ffi_call_DARWIN(extended_cif *, unsigned long, unsigned, unsigned 
*,
++              void (*fn)(), void (*fn2)(extended_cif*, unsigned long *const));
+ 
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
+ {
+@@ -450,11 +497,11 @@
+   switch (cif->abi)
+     {
+     case FFI_AIX:
+-      ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
++      ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
+                  ffi_prep_args);
+       break;
+     case FFI_DARWIN:
+-      ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
++      ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
+                     ffi_prep_args);
+       break;
+     default:
+@@ -650,7 +697,6 @@
+   ffi_cif *        cif;
+   double           temp;
+   unsigned         size_al;
+-  union ldu        temp_ld;
+ 
+   cif = closure->cif;
+   avalue = alloca(cif->nargs * sizeof(void *));
+@@ -678,34 +724,56 @@
+       {
+       case FFI_TYPE_SINT8:
+       case FFI_TYPE_UINT8:
++#ifdef POWERPC64
++        avalue[i] = (char *) pgr + 7;
++#else
+         avalue[i] = (char *) pgr + 3;
++#endif
+         ng++;
+         pgr++;
+         break;
+ 
+       case FFI_TYPE_SINT16:
+       case FFI_TYPE_UINT16:
++#ifdef POWERPC64
++        avalue[i] = (char *) pgr + 6;
++#else
+         avalue[i] = (char *) pgr + 2;
++#endif
+         ng++;
+         pgr++;
+         break;
+ 
+       case FFI_TYPE_SINT32:
+       case FFI_TYPE_UINT32:
++#ifdef POWERPC64
++        avalue[i] = (char*)pgr + 4;
++#else
+       case FFI_TYPE_POINTER:
+         avalue[i] = pgr;
++#endif
+         ng++;
+         pgr++;
+         break;
+ 
+       case FFI_TYPE_STRUCT:
++#ifdef POWERPC64
++        size_al = arg_types[i]->size;
++        if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
++          size_al = ALIGN(arg_types[i]->size, 8);
++        if (size_al < 3 && cif->abi == FFI_DARWIN)
++          avalue[i] = (void*) pgr + 8 - size_al;
++        else
++          avalue[i] = (void*) pgr;
++        ng += (size_al + 7) / 8;
++        pgr += (size_al + 7) / 8;
++#else
+         /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
+            SI 4 bytes) are aligned as if they were those modes.  */
+         size_al = arg_types[i]->size;
+         /* 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 (arg_types[i]->elements[0]->type == 3)
++           the struct to double-word. */
++        if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
+           size_al = ALIGN(arg_types[i]->size, 8);
+         if (size_al < 3 && cif->abi == FFI_DARWIN)
+           avalue[i] = (void*) pgr + 4 - size_al;
+@@ -713,15 +781,24 @@
+           avalue[i] = (void*) pgr;
+         ng += (size_al + 3) / 4;
+         pgr += (size_al + 3) / 4;
++#endif
+         break;
+ 
+       case FFI_TYPE_SINT64:
+       case FFI_TYPE_UINT64:
++#ifdef POWERPC64
++      case FFI_TYPE_POINTER:
++        avalue[i] = pgr;
++        ng += 1;
++        pgr += 1;
++        break;
++#else
+         /* Long long ints are passed in two gpr's.  */
+         avalue[i] = pgr;
+         ng += 2;
+         pgr += 2;
+         break;
++#endif
+ 
+       case FFI_TYPE_FLOAT:
+         /* A float value consumes a GPR.
+@@ -743,7 +820,7 @@
+         break;
+ 
+       case FFI_TYPE_DOUBLE:
+-        /* A double value consumes two GPRs.
++        /* A double value consumes one or two GPRs.
+            There are 13 64bit floating point registers.  */
+         if (nf < NUM_FPR_ARG_REGISTERS)
+           {
+@@ -755,8 +832,13 @@
+             avalue[i] = pgr;
+           }
+         nf++;
++#if defined (POWERPC64)
++        ng++;
++        pgr++;
++#else
+         ng += 2;
+         pgr += 2;
++#endif
+         break;
+ 
+ #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+@@ -774,6 +856,7 @@
+            We use a union to pass the long double to avalue[i].  */
+         else if (nf == NUM_FPR_ARG_REGISTERS - 1)
+           {
++            union ldu temp_ld;
+             memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
+             memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
+             avalue[i] = &temp_ld.ld;
Index: devel/libffi/patches/patch-an
===================================================================
RCS file: devel/libffi/patches/patch-an
diff -N devel/libffi/patches/patch-an
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ devel/libffi/patches/patch-an       22 Nov 2009 20:51:50 -0000
@@ -0,0 +1,15 @@
+--- src/powerpc/ffitarget.h.orig       2009-09-24 15:33:27.000000000 +0200
++++ src/powerpc/ffitarget.h    2009-09-24 15:33:39.000000000 +0200
+@@ -30,7 +30,11 @@
+ 
+ /* ---- System specific configurations ----------------------------------- */
+ 
+-#if defined (POWERPC) && defined (__powerpc64__)
++#if defined (POWERPC) && defined (__powerpc64__)      /* linux64 */
++#define POWERPC64
++#elif defined(POWERPC_DARWIN) && defined (__ppc64__)  /* Darwin */
++#define POWERPC64
++#elif defined(POWERPC_AIX) && defined (__64BIT__)     /* AIX */
+ #define POWERPC64
+ #endif
+ 


Home | Main Index | Thread Index | Old Index