PATCH: Fix libffi for ia64

H. J. Lu hjl@lucon.org
Tue May 4 16:15:00 GMT 2004


Here is an updated patch for mainline since

http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00666.html

fixed other problems. BTW, should we back port mine and Andreas's
patch to gcc 3.4?


H.J.
-------------- next part --------------
2004-05-04  H.J. Lu  <hongjiu.lu@intel.com>

	* src/ia64/ffi.c (is_homogeneous_fp_aggregate): Fix the
	recursive call.
	(ffi_closure_UNIX_inner): Handle HFA return.
	(ffi_prep_incoming_args_UNIX): Fix structure argument.

	* libffi/src/ia64/unix.S (ffi_call_unix): Add a stop bit
	between read and write. Don't override the structure return
	address. Use stfs to load float.

--- libffi/src/ia64/ffi.c.ia64	2004-03-30 09:27:41.000000000 -0800
+++ libffi/src/ia64/ffi.c	2004-05-04 08:12:00.000000000 -0700
@@ -104,7 +104,7 @@ static bool is_homogeneous_fp_aggregate(
 	  element = FFI_TYPE_DOUBLE;
 	  break;
 	case FFI_TYPE_STRUCT:
-	  if (!is_homogeneous_fp_aggregate(type, n, &struct_element))
+	  if (!is_homogeneous_fp_aggregate(*ptr, n, &struct_element))
 	      return false;
 	  if (type_set && struct_element != element) return false;
 	  n -= (type -> size)/float_type_size(element);
@@ -533,6 +533,56 @@ ffi_closure_UNIX_inner (ffi_closure *clo
 		    : : "r" (resp), "r" (resp+8), "r" (resp+16), "r" (resp+24)
 		    : "r8","r9","r10","r11");
     }
+  else if ((rtype & FFI_IS_DOUBLE_FP_AGGREGATE) == FFI_IS_DOUBLE_FP_AGGREGATE)
+    {
+      switch (rtype & ~FFI_IS_DOUBLE_FP_AGGREGATE)
+	{
+	case 8:
+	  asm volatile ("ldfd f15=[%0]" : : "r" (resp + 56) : "f15");
+	case 7:
+	  asm volatile ("ldfd f14=[%0]" : : "r" (resp + 48) : "f14");
+	case 6:
+	  asm volatile ("ldfd f13=[%0]" : : "r" (resp + 40) : "f13");
+	case 5:
+	  asm volatile ("ldfd f12=[%0]" : : "r" (resp + 32) : "f12");
+	case 4:
+	  asm volatile ("ldfd f11=[%0]" : : "r" (resp + 24) : "f11");
+	case 3:
+	  asm volatile ("ldfd f10=[%0]" : : "r" (resp + 16) : "f10");
+	case 2:
+	  asm volatile ("ldfd f9=[%0]" : : "r" (resp + 8) : "f9");
+	case 1:
+	  asm volatile ("ldfd f8=[%0]" : : "r" (resp) : "f8");
+	  break;
+	default:
+	  abort ();
+	}
+    }
+  else if ((rtype & FFI_IS_FLOAT_FP_AGGREGATE) == FFI_IS_FLOAT_FP_AGGREGATE)
+    {
+      switch (rtype & ~FFI_IS_FLOAT_FP_AGGREGATE)
+	{
+	case 8:
+	  asm volatile ("ldfs f15=[%0]" : : "r" (resp + 56) : "f15");
+	case 7:
+	  asm volatile ("ldfs f14=[%0]" : : "r" (resp + 48) : "f14");
+	case 6:
+	  asm volatile ("ldfs f13=[%0]" : : "r" (resp + 40) : "f13");
+	case 5:
+	  asm volatile ("ldfs f12=[%0]" : : "r" (resp + 32) : "f12");
+	case 4:
+	  asm volatile ("ldfs f11=[%0]" : : "r" (resp + 24) : "f11");
+	case 3:
+	  asm volatile ("ldfs f10=[%0]" : : "r" (resp + 16) : "f10");
+	case 2:
+	  asm volatile ("ldfs f9=[%0]" : : "r" (resp + 8) : "f9");
+	case 1:
+	  asm volatile ("ldfs f8=[%0]" : : "r" (resp) : "f8");
+	  break;
+	default:
+	  abort ();
+	}
+    }
   else if (rtype != FFI_TYPE_VOID && rtype != FFI_TYPE_STRUCT)
     {
       /* Can only happen for homogeneous FP aggregates?	*/
@@ -619,6 +669,7 @@ ffi_prep_incoming_args_UNIX(struct ia64_
 		}
 		abort();  /* Other fp types NYI */
 	      }
+	      *p_argv = (void *) argp;
 	  }
 	  break;
 
--- libffi/src/ia64/unix.S.ia64	2003-10-21 17:01:04.000000000 -0700
+++ libffi/src/ia64/unix.S	2004-05-04 08:12:00.000000000 -0700
@@ -91,6 +91,7 @@ ffi_call_unix:
 	;;
 	ldfd	f14=[loc2],2*FLOAT_SZ
 	ldfd	f15=[loc3]
+	;;
 fp_done:
 	add	r9=16,sp	/* Pointer to r8_contents	*/
 	/* loc2 points at first integer register value.  */
@@ -112,10 +113,10 @@ fp_done:
         /* is the value currently in loc2.                              */
 	mov	sp=loc2
 	
-	ld8 	r8=[fn],8
+	ld8 	r2=[fn],8
 	;;
 	ld8	r1=[fn]		/* Set up gp */
-	mov	b6=r8;;
+	mov	b6=r2;;
 	br.call.sptk.many b0 = b6	/* call fn	*/
 	
 	/* Handle return value. */
@@ -234,26 +235,26 @@ handle_float_hfa:
 (p11)	br.cond.dptk.few	shfa7
 shfa8:	add 	loc3=7*4,raddr
 	;;
-	stfd	[loc3]=f15
+	stfs	[loc3]=f15
 shfa7:	add 	loc3=6*4,raddr
 	;;
-	stfd	[loc3]=f14
+	stfs	[loc3]=f14
 shfa6:	add 	loc3=5*4,raddr
 	;;
-	stfd	[loc3]=f13
+	stfs	[loc3]=f13
 shfa5:	add 	loc3=4*4,raddr
 	;;
-	stfd	[loc3]=f12
+	stfs	[loc3]=f12
 shfa4:	add 	loc3=3*4,raddr
 	;;
-	stfd	[loc3]=f11
+	stfs	[loc3]=f11
 shfa3:	add 	loc3=2*4,raddr
 	;;
-	stfd	[loc3]=f10
+	stfs	[loc3]=f10
 shfa2:	add 	loc3=1*4,raddr
 	;;
-	stfd	[loc3]=f9
-	stfd	[raddr]=f8
+	stfs	[loc3]=f9
+	stfs	[raddr]=f8
 	br	done
 
         .endp ffi_call_unix
@@ -277,7 +278,7 @@ ffi_closure_UNIX:
 	add	gp=16,gp
 	;;
 	ld8	gp=[gp]
-	/* Reserve a structia64_args on the stack such that arguments	*/
+	/* Reserve a struct ia64_args on the stack such that arguments	*/
 	/* past the first 8 are automatically placed in the right	*/
 	/* slot.  Note that when we start the sp points at 2 8-byte	*/
 	/* scratch words, followed by the extra arguments.		*/


More information about the Gcc-patches mailing list