This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH/RFC] Enable java on sh64-linux (Take 2)
- From: Kaz Kojima <kkojima at rr dot iij4u dot or dot jp>
- To: java-patches at gcc dot gnu dot org
- Cc: gcc-patches at gcc dot gnu dot org, joern dot rennecke at superh dot com, aoliva at redhat dot com
- Date: Thu, 30 Sep 2004 23:22:23 +0900 (JST)
- Subject: [PATCH/RFC] Enable java on sh64-linux (Take 2)
Hi,
SH custom sh-signal.h gets rid of the libjava Array_3 test failure.
Thanks again for suggestions.
The attached patch is the revised part. New sh-signal.h is also
used for non SH-5 cpus and MD_FALLBACK_FRAME_STATE_FOR for them
is changed not to fixup pc there. The patch is tested for non
SH-5 case with bootstrap and regtests on sh4-unknown-linux-gnu.
Now the result of libjava test for sh64-unknown-linux-gnu is:
FAIL: ArrayStore execution - gij test
FAIL: ArrayStore execution - gij test
FAIL: Divide_1 execution - gij test
FAIL: Divide_1 execution - gij test
FAIL: FileHandleGcTest execution - gij test
FAIL: FileHandleGcTest execution - gij test
FAIL: LargeFile execution - source compiled test
FAIL: LargeFile execution - gij test
FAIL: LargeFile execution - bytecode->native test
FAIL: LargeFile -O3 execution - source compiled test
FAIL: LargeFile execution - gij test
FAIL: LargeFile -O3 execution - bytecode->native test
FAIL: PR3096 -O3 execution - source compiled test
FAIL: Process_2 output - source compiled test
FAIL: Process_2 output - gij test
FAIL: Process_2 output - bytecode->native test
FAIL: Process_2 -O3 output - source compiled test
FAIL: Process_2 output - gij test
FAIL: Process_2 -O3 output - bytecode->native test
FAIL: Serialization execution - gij test
FAIL: Serialization execution - gij test
FAIL: String_overflow output - gij test
FAIL: String_overflow output - gij test
FAIL: Thread_Interrupt execution - gij test
FAIL: Thread_Interrupt execution - gij test
FAIL: Thread_Join execution - gij test
FAIL: Thread_Join execution - gij test
FAIL: Thread_Wait_2 -O3 execution - source compiled test
FAIL: Thread_Wait_2 -O3 execution - bytecode->native test
FAIL: Thread_Wait_Interrupt execution - gij test
FAIL: Thread_Wait_Interrupt -O3 execution - source compiled test
FAIL: Thread_Wait_Interrupt execution - gij test
FAIL: Thread_Wait_Interrupt -O3 execution - bytecode->native test
FAIL: negzero execution - gij test
FAIL: negzero execution - gij test
FAIL: pr6388 output - gij test
FAIL: pr6388 output - gij test
FAIL: pr83 -O3 output - source compiled test
FAIL: pr83 -O3 output - bytecode->native test
=== libjava Summary ===
# of expected passes 2814
# of unexpected failures 39
# of expected failures 10
# of untested testcases 35
Regards,
kaz
--
2004-09-30 Kaz Kojima <kkojima@gcc.gnu.org>
[gcc]
* config/sh/linux-unwind.h (SH_DWARF_FRAME_XD0): Remove for SH5.
(SH_DWARF_FRAME_PR, SH_DWARF_FRAME_GBR, SH_DWARF_FRAME_MACL)
(SH_DWARF_FRAME_MACH, SH_DWARF_FRAME_PC, SH_DWARF_FRAME_FPUL):
Likewise.
(SH_DWARF_FRAME_FP0, SH_DWARF_FRAME_FPSCR): Define to the correct
dwarf register number for SHmedia.
(shmedia_fallback_frame_state): New.
(MD_FALLBACK_FRAME_STATE_FOR): Define to it for SH5.
(sh_fallback_frame_state): Don't fixup PC here.
[libjava]
* configure.ac (SIGNAL_HANDLER): Set to include/sh-signal.h
for all sh*-*-linux* targets.
* configure: Regenerate.
* configure.host: Add sh64-* and sh5*-*. Set can_unwind_signal
for all sh*-linux* targets.
* include/sh-signal.h: New file.
* sysdep/sh64/locks.h: New file.
diff -u3prN ORIG/gcc/gcc/config/sh/linux-unwind.h LOCAL/gcc/gcc/config/sh/linux-unwind.h
--- ORIG/gcc/gcc/config/sh/linux-unwind.h Wed Sep 8 09:17:18 2004
+++ LOCAL/gcc/gcc/config/sh/linux-unwind.h Tue Sep 28 18:34:55 2004
@@ -27,18 +27,11 @@ Boston, MA 02111-1307, USA. */
# if defined (__SH5__)
#define SH_DWARF_FRAME_GP0 0
-#define SH_DWARF_FRAME_FP0 (__SH5__ == 32 ? 245 : 77)
-#define SH_DWARF_FRAME_XD0 289
+#define SH_DWARF_FRAME_FP0 77
#define SH_DWARF_FRAME_BT0 68
-#define SH_DWARF_FRAME_PR 241
#define SH_DWARF_FRAME_PR_MEDIA 18
-#define SH_DWARF_FRAME_GBR 238
-#define SH_DWARF_FRAME_MACH 239
-#define SH_DWARF_FRAME_MACL 240
-#define SH_DWARF_FRAME_PC 64
#define SH_DWARF_FRAME_SR 65
-#define SH_DWARF_FRAME_FPUL 244
-#define SH_DWARF_FRAME_FPSCR 243
+#define SH_DWARF_FRAME_FPSCR 76
#else
#define SH_DWARF_FRAME_GP0 0
#define SH_DWARF_FRAME_FP0 25
@@ -54,7 +47,88 @@ Boston, MA 02111-1307, USA. */
#endif /* defined (__SH5__) */
#if defined (__SH5__)
-/* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA. */
+
+#define MD_FALLBACK_FRAME_STATE_FOR shmedia_fallback_frame_state
+
+static _Unwind_Reason_Code
+shmedia_fallback_frame_state (struct _Unwind_Context *context,
+ _Unwind_FrameState *fs)
+{
+ unsigned char *pc = context->ra;
+ struct sigcontext *sc;
+ long new_cfa;
+ int i, r;
+
+ /* movi 0x10,r9; shori 0x77,r9; trapa r9; nop (sigreturn) */
+ /* movi 0x10,r9; shori 0xad,r9; trapa r9; nop (rt_sigreturn) */
+ if ((*(unsigned long *) (pc-1) == 0xcc004090)
+ && (*(unsigned long *) (pc+3) == 0xc801dc90)
+ && (*(unsigned long *) (pc+7) == 0x6c91fff0)
+ && (*(unsigned long *) (pc+11) == 0x6ff0fff0))
+ sc = context->cfa;
+ else if ((*(unsigned long *) (pc-1) == 0xcc004090)
+ && (*(unsigned long *) (pc+3) == 0xc802b490)
+ && (*(unsigned long *) (pc+7) == 0x6c91fff0)
+ && (*(unsigned long *) (pc+11) == 0x6ff0fff0))
+ {
+ struct rt_sigframe {
+ struct siginfo *pinfo;
+ void *puc;
+ struct siginfo info;
+ struct ucontext uc;
+ } *rt_ = context->cfa;
+ sc = (struct sigcontext *) &rt_->uc.uc_mcontext;
+ }
+ else
+ return _URC_END_OF_STACK;
+
+ new_cfa = sc->sc_regs[15];
+ fs->cfa_how = CFA_REG_OFFSET;
+ fs->cfa_reg = 15;
+ fs->cfa_offset = new_cfa - (long) context->cfa;
+
+ for (i = 0; i < 63; i++)
+ {
+ if (i == 15)
+ continue;
+
+ fs->regs.reg[i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[i].loc.offset
+ = (long)&(sc->sc_regs[i]) - new_cfa;
+ }
+
+ fs->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;
+ fs->regs.reg[SH_DWARF_FRAME_SR].loc.offset
+ = (long)&(sc->sc_sr) - new_cfa;
+
+ r = SH_DWARF_FRAME_BT0;
+ for (i = 0; i < 8; i++)
+ {
+ fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[r+i].loc.offset
+ = (long)&(sc->sc_tregs[i]) - new_cfa;
+ }
+
+ r = SH_DWARF_FRAME_FP0;
+ for (i = 0; i < 32; i++)
+ {
+ fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[r+i].loc.offset
+ = (long)&(sc->sc_fpregs[i]) - new_cfa;
+ }
+
+ fs->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;
+ fs->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset
+ = (long)&(sc->sc_fpscr) - new_cfa;
+
+ /* We use the slot for the zero register to save return address. */
+ fs->regs.reg[63].how = REG_SAVED_OFFSET;
+ fs->regs.reg[63].loc.offset
+ = (long)&(sc->sc_pc) - new_cfa;
+ fs->retaddr_column = 63;
+ return _URC_NO_REASON;
+}
+
#else /* defined (__SH5__) */
#define MD_FALLBACK_FRAME_STATE_FOR sh_fallback_frame_state
@@ -154,10 +228,6 @@ sh_fallback_frame_state (struct _Unwind_
= (long)&(sc->sc_fpscr) - new_cfa;
#endif
- /* The unwinder expects the PC to point to the following insn,
- whereas the kernel returns the address of the actual
- faulting insn. */
- sc->sc_pc += 2;
fs->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;
fs->regs.reg[SH_DWARF_FRAME_PC].loc.offset
= (long)&(sc->sc_pc) - new_cfa;
diff -u3prN ORIG/gcc/libjava/configure.ac LOCAL/gcc/libjava/configure.ac
--- ORIG/gcc/libjava/configure.ac Thu Sep 9 09:16:31 2004
+++ LOCAL/gcc/libjava/configure.ac Wed Sep 29 12:27:11 2004
@@ -1308,8 +1308,8 @@ case "${host}" in
sparc*-*-linux*)
SIGNAL_HANDLER=include/dwarf2-signal.h
;;
- sh-*-linux* | sh[[34]]*-*-linux*)
- SIGNAL_HANDLER=include/dwarf2-signal.h
+ sh*-*-linux*)
+ SIGNAL_HANDLER=include/sh-signal.h
;;
*mingw*)
SIGNAL_HANDLER=include/win32-signal.h
diff -u3prN ORIG/gcc/libjava/configure.host LOCAL/gcc/libjava/configure.host
--- ORIG/gcc/libjava/configure.host Thu Sep 9 09:16:31 2004
+++ LOCAL/gcc/libjava/configure.host Sun Sep 26 17:04:38 2004
@@ -156,6 +156,12 @@ case "${host}" in
libgcj_interpreter=yes
enable_hash_synchronization_default=yes
;;
+ sh64-* | sh5*-*)
+ sysdeps_dir=sh64
+ libgcj_flags="${libgcj_flags} -mieee"
+ libgcj_interpreter=yes
+ enable_hash_synchronization_default=yes
+ ;;
esac
# This case statement supports generic port properties and may refine
@@ -171,7 +177,7 @@ case "${host}" in
ia64-* | \
x86_64*-linux* | \
hppa*-linux* | \
- sh-linux* | sh[34]*-linux*)
+ sh*-linux*)
can_unwind_signal=yes
if test x$slow_pthread_self = xyes \
&& test x$cross_compiling != xyes; then
diff -u3prN ORIG/gcc/libjava/include/sh-signal.h LOCAL/gcc/libjava/include/sh-signal.h
--- ORIG/gcc/libjava/include/sh-signal.h Thu Jan 1 09:00:00 1970
+++ LOCAL/gcc/libjava/include/sh-signal.h Tue Sep 28 15:21:05 2004
@@ -0,0 +1,94 @@
+// sh-signal.h - Catch runtime signals and turn them into exceptions
+// on a SuperH based Linux system.
+
+/* Copyright (C) 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+
+#ifndef JAVA_SIGNAL_H
+#define JAVA_SIGNAL_H 1
+
+#include <signal.h>
+#include <sys/syscall.h>
+
+#define HANDLE_SEGV 1
+#define HANDLE_FPE 1
+
+/* The third parameter to the signal handler points to something with
+ * this structure defined in asm/ucontext.h, but the name clashes with
+ * struct ucontext from sys/ucontext.h so this private copy is used. */
+typedef struct _sig_ucontext {
+ unsigned long uc_flags;
+ struct _sig_ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask;
+} sig_ucontext_t;
+
+#define SIGNAL_HANDLER(_name) \
+ static void _name (int , siginfo_t *, sig_ucontext_t *_uc)
+
+/* SH either leaves PC pointing at a faulting instruction or the
+ following instruction, depending on the signal. SEGV always does
+ the former, so we adjust the saved PC to point to the following
+ instruction. This is what the handler in libgcc expects. */
+
+#ifdef __SH5__
+#define MAKE_THROW_FRAME(_exception) \
+do \
+ { \
+ _uc->uc_mcontext.sc_pc += 4; \
+ } \
+while (0)
+#else
+#define MAKE_THROW_FRAME(_exception) \
+do \
+ { \
+ _uc->uc_mcontext.sc_pc += 2; \
+ } \
+while (0)
+#endif
+
+/* For an explanation why we cannot simply use sigaction to
+ install the handlers, see i386-signal.h. */
+
+/* We use kernel_old_sigaction here because we're calling the kernel
+ directly rather than via glibc. The sigaction structure that the
+ syscall uses is a different shape from the one in userland and not
+ visible to us in a header file so we define it here. */
+
+struct kernel_old_sigaction {
+ void (*k_sa_handler) (int, siginfo_t *, sig_ucontext_t *);
+ unsigned long k_sa_mask;
+ unsigned long k_sa_flags;
+ void (*k_sa_restorer) (void);
+};
+
+#define INIT_SEGV \
+do \
+ { \
+ struct kernel_old_sigaction kact; \
+ kact.k_sa_handler = catch_segv; \
+ kact.k_sa_mask = 0; \
+ kact.k_sa_flags = SA_SIGINFO | SA_NODEFER; \
+ syscall (SYS_sigaction, SIGSEGV, &kact, NULL); \
+ } \
+while (0)
+
+#define INIT_FPE \
+do \
+ { \
+ struct kernel_old_sigaction kact; \
+ kact.k_sa_handler = catch_fpe; \
+ kact.k_sa_mask = 0; \
+ kact.k_sa_flags = SA_SIGINFO | SA_NODEFER; \
+ syscall (SYS_sigaction, SIGFPE, &kact, NULL); \
+ } \
+while (0)
+
+#endif /* JAVA_SIGNAL_H */
diff -u3prN ORIG/gcc/libjava/sysdep/sh64/locks.h LOCAL/gcc/libjava/sysdep/sh64/locks.h
--- ORIG/gcc/libjava/sysdep/sh64/locks.h Thu Jan 1 09:00:00 1970
+++ LOCAL/gcc/libjava/sysdep/sh64/locks.h Sat Sep 25 11:27:39 2004
@@ -0,0 +1,72 @@
+// locks.h - Thread synchronization primitives. SuperH SHmedia implementation.
+
+/* Copyright (C) 2004 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+#ifndef __SYSDEP_LOCKS_H__
+#define __SYSDEP_LOCKS_H__
+
+typedef size_t obj_addr_t; /* Integer type big enough for object */
+ /* address. */
+
+static long long __cas_lock = 0;
+
+inline static void
+__cas_start_atomic (void)
+{
+ long long val;
+
+ do
+ __asm__ __volatile__ ("swap.q %1,r63,%0"
+ : "=&r" (val)
+ : "r" (&__cas_lock), "0" (1LL)
+ : "memory");
+ while (val == 1);
+}
+
+inline static void
+__cas_end_atomic (void)
+{
+ __asm__ __volatile__ (" " : : : "memory");
+ __cas_lock = 0;
+}
+
+inline static bool
+compare_and_swap (volatile obj_addr_t *addr, obj_addr_t old,
+ obj_addr_t new_val)
+{
+ bool ret;
+
+ __cas_start_atomic ();
+ if (*addr != old)
+ ret = false;
+ else
+ {
+ *addr = new_val;
+ ret = true;
+ }
+ __cas_end_atomic ();
+
+ return ret;
+}
+
+inline static void
+release_set (volatile obj_addr_t *addr, obj_addr_t new_val)
+{
+ __asm__ __volatile__ (" " : : : "memory");
+ *(addr) = new_val;
+}
+
+inline static bool
+compare_and_swap_release (volatile obj_addr_t *addr, obj_addr_t old,
+ obj_addr_t new_val)
+{
+ return compare_and_swap (addr, old, new_val);
+}
+
+#endif /* ! __SYSDEP_LOCKS_H__ */