This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] powerpc libffi Net/FreeBSD


Hello,

I'd like to commit the attached patch to gcc-head.

The patch comes from:
http://sourceware.org/ml/libffi-discuss/2009/msg00069.html

I tested the patch on gcc-head, FreeBSD:

http://gcc.gnu.org/ml/gcc-testresults/2009-06/msg00132.html

I also tested it on ppc-linux to see that there is no impact on non BSD targets.

Ok for trunk?

Andrew, I will wait until you did the merge.

Thanks,

Andreas

2009-06-02 Wim Lewis <wiml@hhhh.org>

	* src/powerpc/ffi.c: Avoid clobbering cr3 and cr4, which are
	supposed to be callee-saved.
	* src/powerpc/sysv.S (small_struct_return_value): Fix overrun of
	return buffer for odd-size structs.
Index: src/powerpc/ffi.c
===================================================================
--- src/powerpc/ffi.c	(revision 148063)
+++ src/powerpc/ffi.c	(working copy)
@@ -42,11 +42,12 @@
   FLAG_RETURNS_64BITS   = 1 << (31-28),
 
   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
-
-  FLAG_SYSV_SMST_R4     = 1 << (31-16), /* cr4, use r4 for FFI_SYSV 8 byte
+  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
 					   structs.  */
-  FLAG_SYSV_SMST_R3     = 1 << (31-15), /* cr3, use r3 for FFI_SYSV 4 byte
+  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
 					   structs.  */
+  /* Bits (31-24) through (31-19) store shift value for SMST */
+
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
@@ -684,14 +685,14 @@
 	      if (size <= 4)
 		{
 		  flags |= FLAG_SYSV_SMST_R3;
-		  flags |= 8 * (4 - size) << 4;
+		  flags |= 8 * (4 - size) << 8;
 		  break;
 		}
 	      /* These structs are returned in r3 and r4. See above.   */
 	      if  (size <= 8)
 		{
-		  flags |= FLAG_SYSV_SMST_R4;
-		  flags |= 8 * (8 - size) << 4;
+		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
+		  flags |= 8 * (8 - size) << 8;
 		  break;
 		}
 	    }
Index: src/powerpc/sysv.S
===================================================================
--- src/powerpc/sysv.S	(revision 148063)
+++ src/powerpc/sysv.S	(working copy)
@@ -135,30 +135,19 @@
 	b	L(done_return_value)
 
 L(small_struct_return_value):
-	mtcrf	0x10,%r31	/* cr3  */
-	bt-	15,L(smst_one_register)
-	mtcrf	0x08,%r31	/* cr4  */
-	bt-	16,L(smst_two_register)
-	b       L(done_return_value)
-
-L(smst_one_register):
-	rlwinm  %r5,%r31,5+23,32-5,31 /* Extract the value to shift.  */
-	slw	%r3,%r3,%r5
-	stw	%r3,0(%r30)
+	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
+	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
+	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
+	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
+	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
+/* smst_one_register: */
+	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
+	mtxer	%r6                   /* move byte count to XER ... */
+	stswx	%r3,0,%r30            /* ... and store that many bytes */
+	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
+	add	%r6,%r6,%r30          /* adjust pointer */
+	stswi	%r4,%r6,4             /* store last four bytes */
 	b	L(done_return_value)
-L(smst_two_register):
-	rlwinm  %r5,%r31,5+23,32-5,31 /* Extract the value to shift.  */
-	cmpwi	%r5,0
-	subfic	%r9,%r5,32
-	slw	%r29,%r3,%r5
-	srw	%r9,%r4,%r9
-	beq-	L(smst_8byte)
-	or	%r3,%r9,%r29
-	slw	%r4,%r4,%r5
-L(smst_8byte):
-	stw	%r3,0(%r30)
-	stw	%r4,4(%r30)
-	b	L(done_return_value)
 
 .LFE1:
 END(ffi_call_SYSV)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]