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