This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java 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]

Re: [PATCH/RFC] Enable java on sh64-linux (Take 2)


Andrew Haley <aph@redhat.com> wrote:
>> BTW, it's surprising that no testcase could detect the above problem,
>> isn't it?  How about the testcase below?  It caught this mistake.
> 
> That's good.  The libffi testsuite is far from complete.
> 
> I'm betting on libffi mistakes for the rest of the gij failures, too.

There are 4 gij failures remained:

FAIL: ArrayStore execution - gij test
FAIL: FileHandleGcTest execution - gij test
FAIL: LargeFile execution - gij test
FAIL: Process_2 output - gij test

The ArrayStore error is fairy unstable but tends to fail with broken
fields of jclass in _Jv_PrepareCLass after catching ArrayStoreException.
It went away even with a small change of _Jv_CheckArrayStore or with -O0
compilation of natClass.cc.  Perhaps ArrayStore failure is caused by
a more nasty thing than libffi mistakes.
Anyway, I've stumbled there and tried to make the native gdb work.  With
it, I've got

(gdb) r ArrayStore
Starting program: /home/kkojima/xsh-gcc/sh64-unknown-linux-gnu/libjava/.libs/gij ArrayStore
../../LOCAL/gdb-6.2/gdb/utils.c:1032: internal-error: virtual memory exhausted: can't allocate 29022014 bytes.

:-) and unfortunately it's hard to add memory or swap to my target board.
I'm stuck at the moment.  I'd like to attach my latest libffi sh5 specific
changes here because it fixes a failure for the new libffi test anyway.
The result of libffi test on sh64-unknown-linux-gnu is:

                === libffi Summary ===

# of expected passes            214
# of unsupported tests          2

Regards,
	kaz
--
	* src/sh64/ffi.c (simple_type): Remove.
	(return_type): Handle small structures correctly.
	(ffi_prep_args): Likewise.  Use sign extend when an FFI_TYPE_SINT32
	type argument is stored to the 64-bit slot.
	(ffi_closure_helper_SYSV): Handle small structures correctly.
	* src/sh64/sysv.S (ffi_call_SYSV): Handle 1, 2 and 4-byte return.
	Emit position independent code if PIC and remove wrong datalabel
	prefixes from EH data.

diff -u3pr ORIG/gcc/libffi/src/sh64/ffi.c LOCAL/gcc/libffi/src/sh64/ffi.c
--- ORIG/gcc/libffi/src/sh64/ffi.c	Fri Jun 13 11:23:26 2003
+++ LOCAL/gcc/libffi/src/sh64/ffi.c	Sun Oct  3 10:24:39 2004
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 2003 Kaz Kojima
+   ffi.c - Copyright (c) 2003, 2004 Kaz Kojima
    
    SuperH SHmedia Foreign Function Interface 
 
@@ -31,48 +31,21 @@
 #define NGREGARG 8
 #define NFREGARG 12
 
-/* If the structure has essentialy an unique element, return its type.  */
-static int
-simple_type (ffi_type *arg)
-{
-  if (arg->type != FFI_TYPE_STRUCT)
-    return arg->type;
-  else if (arg->elements[1])
-    return FFI_TYPE_STRUCT;
-
-  return simple_type (arg->elements[0]);
-}
-
 static int
 return_type (ffi_type *arg)
 {
-  unsigned short type;
 
   if (arg->type != FFI_TYPE_STRUCT)
     return arg->type;
 
-  type = simple_type (arg->elements[0]);
-  if (! arg->elements[1])
-    {
-      switch (type)
-	{
-	case FFI_TYPE_SINT8:
-	case FFI_TYPE_UINT8:
-	case FFI_TYPE_SINT16:
-	case FFI_TYPE_UINT16:
-	case FFI_TYPE_SINT32:
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT64:
-	case FFI_TYPE_UINT64:
-	  return FFI_TYPE_UINT64;
-
-	default:
-	  return type;
-	}
-    }
-
   /* gcc uses r2 if the result can be packed in on register.  */
-  if (arg->size <= sizeof (UINT64))
+  if (arg->size <= sizeof (UINT8))
+    return FFI_TYPE_UINT8;
+  else if (arg->size <= sizeof (UINT16))
+    return FFI_TYPE_UINT16;
+  else if (arg->size <= sizeof (UINT32))
+    return FFI_TYPE_UINT32;
+  else if (arg->size <= sizeof (UINT64))
     return FFI_TYPE_UINT64;
 
   return FFI_TYPE_STRUCT;
@@ -105,8 +78,10 @@ void ffi_prep_args(char *stack, extended
   for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
     {
       size_t z;
+      int align;
 
       z = (*p_arg)->size;
+      align = (*p_arg)->alignment;
       if (z < sizeof (UINT32))
 	{
 	  switch ((*p_arg)->type)
@@ -128,7 +103,7 @@ void ffi_prep_args(char *stack, extended
 	      break;
   
 	    case FFI_TYPE_STRUCT:
-	      *(UINT64 *) argp = (UINT64) *(UINT32 *)(*p_argv);
+	      memcpy (argp, *p_argv, z);
 	      break;
 
 	    default:
@@ -136,12 +111,31 @@ void ffi_prep_args(char *stack, extended
 	    }
 	  argp += sizeof (UINT64);
 	}
-      else if (z == sizeof (UINT32))
+      else if (z == sizeof (UINT32) && align == sizeof (UINT32))
 	{
-	  *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_SINT32:
+	      *(SINT64 *) argp = (SINT64) *(SINT32 *) (*p_argv);
+	      break;
+
+	    case FFI_TYPE_FLOAT:
+	    case FFI_TYPE_POINTER:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_STRUCT:
+	      *(UINT64 *) argp = (UINT64) *(UINT32 *) (*p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	      break;
+	    }
 	  argp += sizeof (UINT64);
 	}
-      else if (z == sizeof (UINT64))
+      else if (z == sizeof (UINT64)
+	       && align == sizeof (UINT64)
+	       && ((int) *p_argv & (sizeof (UINT64) - 1)) == 0)
 	{
 	  *(UINT64 *) argp = *(UINT64 *) (*p_argv);
 	  argp += sizeof (UINT64);
@@ -254,6 +248,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *c
 	      /*@dependent@*/ void **avalue)
 {
   extended_cif ecif;
+  UINT64 trvalue;
 
   ecif.cif = cif;
   ecif.avalue = avalue;
@@ -261,7 +256,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *c
   /* 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) && 
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    ecif.rvalue = &trvalue;
+  else if ((rvalue == NULL) && 
       (cif->rtype->type == FFI_TYPE_STRUCT))
     {
       /*@-sysunrecog@*/
@@ -283,6 +281,11 @@ void ffi_call(/*@dependent@*/ ffi_cif *c
       FFI_ASSERT(0);
       break;
     }
+
+  if (rvalue
+      && cif->rtype->type == FFI_TYPE_STRUCT
+      && return_type (cif->rtype) != FFI_TYPE_STRUCT)
+    memcpy (rvalue, &trvalue, cif->rtype->size);
 }
 
 extern void ffi_closure_SYSV (void);
@@ -353,7 +356,7 @@ ffi_closure_helper_SYSV (ffi_closure *cl
 
   /* Copy the caller's structure return value address so that the closure
      returns the data directly to the caller.  */
-  if (cif->rtype->type == FFI_TYPE_STRUCT)
+  if (return_type (cif->rtype) == FFI_TYPE_STRUCT)
     {
       rvalue = *pgr;
       greg = 1;
@@ -443,6 +446,6 @@ ffi_closure_helper_SYSV (ffi_closure *cl
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
 
   /* Tell ffi_closure_SYSV how to perform return type promotions.  */
-  return cif->rtype->type;
+  return return_type (cif->rtype);
 }
 
diff -u3pr ORIG/gcc/libffi/src/sh64/sysv.S LOCAL/gcc/libffi/src/sh64/sysv.S
--- ORIG/gcc/libffi/src/sh64/sysv.S	Wed Oct 22 04:01:58 2003
+++ LOCAL/gcc/libffi/src/sh64/sysv.S	Sun Oct  3 10:24:39 2004
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   sysv.S - Copyright (c) 2003 Kaz Kojima
+   sysv.S - Copyright (c) 2003, 2004 Kaz Kojima
    
    SuperH SHmedia Foreign Function Interface 
 
@@ -64,8 +64,9 @@ ENTRY(ffi_call_SYSV)
 	st.q	r15, 8, r28
 	st.l	r15, 4, r18
 	st.l	r15, 0, r14
-	add.l	r15, r63, r14
 .LCFI1:
+	add.l	r15, r63, r14
+.LCFI2:
 #	add	r4, r63, r28
 	add	r5, r63, r29
 	add	r6, r63, r30
@@ -252,10 +253,17 @@ ENTRY(ffi_call_SYSV)
 	pt/l	.L_epilogue, tr4
 
 	beqi/l	r29, FFI_TYPE_INT, tr0
+	beqi/l	r29, FFI_TYPE_UINT32, tr0
 	beqi/l	r29, FFI_TYPE_SINT64, tr1
 	beqi/l	r29, FFI_TYPE_UINT64, tr1
 	beqi/l	r29, FFI_TYPE_DOUBLE, tr2
 	beqi/l	r29, FFI_TYPE_FLOAT, tr3
+
+	pt/l	.L_ret_q, tr0
+	pt/l	.L_ret_h, tr1
+
+	beqi/l	r29, FFI_TYPE_UINT8, tr0
+	beqi/l	r29, FFI_TYPE_UINT16, tr1
 	blink	tr4, r63
 
 .L_ret_d:
@@ -270,6 +278,14 @@ ENTRY(ffi_call_SYSV)
 	fst.s	r31, OFS_FLT, fr0
 	blink	tr4, r63
 
+.L_ret_q:
+	st.b	r31, 0, r2
+	blink	tr4, r63
+
+.L_ret_h:
+	st.w	r31, 0, r2
+	blink	tr4, r63
+
 .L_ret_i:
 	st.l	r31, 0, r2
 	# Fall
@@ -297,12 +313,13 @@ ENTRY(ffi_call_SYSV)
 ENTRY(ffi_closure_SYSV)
 .LFB2:
 	addi.l	r15, -136, r15
-.LCFI2:
+.LCFI3:
 	st.l	r15, 12, r18
 	st.l	r15, 8, r14
 	st.l	r15, 4, r12
+.LCFI4:
 	add	r15, r63, r14
-.LCFI3:
+.LCFI5:
 	/* Stack layout:	
 	   ...
 	   64 bytes (register parameters)
@@ -418,12 +435,18 @@ __FRAME_BEGIN__:
 .LSCIE1:
 	.4byte	0x0	/* CIE Identifier Tag */
 	.byte	0x1	/* CIE Version */
+#ifdef PIC
 	.ascii "zR\0"	/* CIE Augmentation */
+#else
+	.byte	0x0	/* CIE Augmentation */
+#endif
 	.uleb128 0x1	/* CIE Code Alignment Factor */
 	.sleb128 -4	/* CIE Data Alignment Factor */
 	.byte	0x12	/* CIE RA Column */
+#ifdef PIC
 	.uleb128 0x1	/* Augmentation size */
-	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
+	.byte	0x10	/* FDE Encoding (pcrel) */
+#endif
 	.byte	0xc	/* DW_CFA_def_cfa */
 	.uleb128 0xf
 	.uleb128 0x0
@@ -433,8 +456,15 @@ __FRAME_BEGIN__:
 	.4byte	datalabel .LEFDE1-datalabel .LASFDE1	/* FDE Length */
 .LASFDE1:
 	.4byte	datalabel .LASFDE1-datalabel __FRAME_BEGIN__
-	.4byte	datalabel .LFB1-.		/* FDE initial location */
+#ifdef PIC
+	.4byte	.LFB1-.	/* FDE initial location */
+#else
+	.4byte	.LFB1	/* FDE initial location */
+#endif
 	.4byte	datalabel .LFE1-datalabel .LFB1	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
 	.byte	0x4	/* DW_CFA_advance_loc4 */
 	.4byte	datalabel .LCFI0-datalabel .LFB1
 	.byte	0xe	/* DW_CFA_def_cfa_offset */
@@ -455,6 +485,8 @@ __FRAME_BEGIN__:
 	.uleb128 0x4
 	.byte   0xa0	/* DW_CFA_offset, column 0x20 */
 	.uleb128 0x2
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI2-datalabel .LCFI1
 	.byte	0xd	/* DW_CFA_def_cfa_register */
 	.uleb128 0xe
 	.align	2
@@ -464,20 +496,29 @@ __FRAME_BEGIN__:
 	.4byte	datalabel .LEFDE3-datalabel .LASFDE3	/* FDE Length */
 .LASFDE3:
 	.4byte	datalabel .LASFDE3-datalabel __FRAME_BEGIN__
-	.4byte	datalabel .LFB2-.		/* FDE initial location */
+#ifdef PIC
+	.4byte	.LFB2-.	/* FDE initial location */
+#else
+	.4byte	.LFB2	/* FDE initial location */
+#endif
 	.4byte	datalabel .LFE2-datalabel .LFB2	/* FDE address range */
+#ifdef PIC
+	.uleb128 0x0	/* Augmentation size */
+#endif
 	.byte	0x4	/* DW_CFA_advance_loc4 */
-	.4byte	datalabel .LCFI2-datalabel .LFB2
+	.4byte	datalabel .LCFI3-datalabel .LFB2
 	.byte	0xe	/* DW_CFA_def_cfa_offset */
 	.uleb128 0x88
 	.byte	0x4	/* DW_CFA_advance_loc4 */
-	.4byte	datalabel .LCFI3-datalabel .LCFI2
+	.4byte	datalabel .LCFI4-datalabel .LCFI3
 	.byte   0x8c	/* DW_CFA_offset, column 0xc */
 	.uleb128 0x21
 	.byte   0x8e	/* DW_CFA_offset, column 0xe */
 	.uleb128 0x20
 	.byte   0x92	/* DW_CFA_offset, column 0x12 */
 	.uleb128 0x1f
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	datalabel .LCFI5-datalabel .LCFI4
 	.byte	0xd	/* DW_CFA_def_cfa_register */
 	.uleb128 0xe
 	.align	2


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