OSDN Git Service

2002-04-19 David S. Miller <davem@redhat.com>
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Apr 2002 09:37:49 +0000 (09:37 +0000)
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 21 Apr 2002 09:37:49 +0000 (09:37 +0000)
* include/dwarf2-signal.h (SIGNAL_HANDLER): Name siginfo_t pointer
arg.
(MAKE_THROW_FRAME): Define for 32-bit and 64-bit sparc.
(INIT_SEGV, INIT_FPE): Use direct __libc_sigaction installation
on Sparc too.
* include/sparc-signal.h (FLUSH_REGISTER_WINDOWS): Define properly
for 64-bit sparc.
(MAKE_THROW_FRAME): Use long for sp/retaddr so 64-bit works.
* sysdeps/sparc/locks.h: New file.
* configure.in (SIGNAL_HANDLER): Set to include/sparc-signal.h
on all sparc Solaris configurations.  Set to
include/dwarf2-signal.h on sparc Linux.
* configure: Regenerate
* configure.host (can_unwind_signal): sparc*-linux* can do it now.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52575 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/configure
libjava/configure.host
libjava/configure.in
libjava/include/dwarf2-signal.h
libjava/include/sparc-signal.h
libjava/sysdep/sparc/locks.h [new file with mode: 0644]

index 33df075..7b889fe 100644 (file)
@@ -1,3 +1,20 @@
+2002-04-19  David S. Miller  <davem@redhat.com>
+
+       * include/dwarf2-signal.h (SIGNAL_HANDLER): Name siginfo_t pointer
+       arg.
+       (MAKE_THROW_FRAME): Define for 32-bit and 64-bit sparc.
+       (INIT_SEGV, INIT_FPE): Use direct __libc_sigaction installation
+       on Sparc too.
+       * include/sparc-signal.h (FLUSH_REGISTER_WINDOWS): Define properly
+       for 64-bit sparc.
+       (MAKE_THROW_FRAME): Use long for sp/retaddr so 64-bit works.
+       * sysdeps/sparc/locks.h: New file.
+       * configure.in (SIGNAL_HANDLER): Set to include/sparc-signal.h
+       on all sparc Solaris configurations.  Set to
+       include/dwarf2-signal.h on sparc Linux.
+       * configure: Regenerate
+       * configure.host (can_unwind_signal): sparc*-linux* can do it now.
+
 2002-04-19  Hans Boehm <Hans_Boehm@hp.com>
 
        * configure: Rebuilt.
index 52a6834..711f39e 100755 (executable)
@@ -6465,7 +6465,7 @@ case "${host}" in
  i?86-*-linux*)
     SIGNAL_HANDLER=include/i386-signal.h
     ;;
- sparc-sun-solaris*)
+ sparc*-sun-solaris*)
     SIGNAL_HANDLER=include/sparc-signal.h
     ;;
 # ia64-*)
@@ -6481,6 +6481,9 @@ case "${host}" in
  alpha*-*-linux*)
     SIGNAL_HANDLER=include/dwarf2-signal.h
     ;;
+sparc*-*-linux*)
+   SIGNAL_HANDLER=include/dwarf2-signal.h
+   ;;
  *mingw*)
     SIGNAL_HANDLER=include/win32-signal.h
     ;;
index 5eac4d3..16e4cd8 100644 (file)
@@ -125,6 +125,7 @@ case "${host}" in
   i[34567]86*-linux* | \
   powerpc*-linux* | \
   alpha*-linux* | \
+  sparc*-linux* | \
   ia64-*)
        can_unwind_signal=yes
        ;;
index 7dae1eb..14ff725 100644 (file)
@@ -867,7 +867,7 @@ case "${host}" in
  i?86-*-linux*)
     SIGNAL_HANDLER=include/i386-signal.h
     ;;
- sparc-sun-solaris*)
+ sparc*-sun-solaris*)
     SIGNAL_HANDLER=include/sparc-signal.h
     ;;
 # ia64-*)
@@ -883,6 +883,9 @@ case "${host}" in
  alpha*-*-linux*)
     SIGNAL_HANDLER=include/dwarf2-signal.h
     ;;
+ sparc*-*-linux*)
+    SIGNAL_HANDLER=include/dwarf2-signal.h
+    ;;
  *mingw*)
     SIGNAL_HANDLER=include/win32-signal.h
     ;;
index cde0fa9..0828705 100644 (file)
@@ -21,7 +21,7 @@ details.  */
 #undef HANDLE_FPE
 
 #define SIGNAL_HANDLER(_name)  \
-static void _Jv_##_name (int, siginfo_t *, void *_p)
+static void _Jv_##_name (int, siginfo_t *_sip, void *_p)
 
 class java::lang::Throwable;
 
@@ -58,6 +58,53 @@ do                                                                   \
   _sc->sc_ip++;                                                                \
 }                                                                      \
 while (0)
+#elif defined(__sparc__)
+/* We could do the unwind of the signal frame quickly by hand here like
+   sparc-signal.h does under Solaris, but that makes debugging unwind
+   failures almost impossible.  */
+#if !defined(__arch64__)
+#define MAKE_THROW_FRAME(_exception)                                   \
+do                                                                     \
+{                                                                      \
+  /* Sparc-32 leaves PC pointing at a faulting instruction             \
+   always.  So we adjust the saved PC to point to the following                \
+   instruction; this is what the handler in libgcc expects.  */                \
+  /* Note that we are lying to the unwinder here, which expects the    \
+   faulting pc, not pc+1.  But we claim the unwind information can't   \
+   be changed by such a ld or st instruction, so it doesn't matter. */ \
+  struct sig_regs {                                                    \
+    unsigned int psr, pc, npc, y, u_regs[16];                          \
+  } *regp;                                                             \
+  unsigned int insn;                                                   \
+  __asm__ __volatile__("ld [%%i7 + 8], %0" : "=r" (insn));             \
+  if (insn == 0x821020d8)                                              \
+    regp = (struct sig_regs *) _sip;                                   \
+  else                                                                 \
+    regp = (struct sig_regs *) (_sip + 1);                             \
+  regp->pc = regp->npc;                                                        \
+  regp->npc += 4;                                                      \
+}                                                                      \
+while (0)
+#else
+#define MAKE_THROW_FRAME(_exception)                                   \
+do                                                                     \
+{                                                                      \
+  /* Sparc-64 leaves PC pointing at a faulting instruction             \
+   always.  So we adjust the saved PC to point to the following                \
+   instruction; this is what the handler in libgcc expects.  */                \
+  /* Note that we are lying to the unwinder here, which expects the    \
+   faulting pc, not pc+1.  But we claim the unwind information can't   \
+   be changed by such a ld or st instruction, so it doesn't matter. */ \
+  struct pt_regs {                                                     \
+    unsigned long u_regs[16];                                          \
+    unsigned long tstate, tpc, tnpc;                                   \
+    unsigned int y, fprs;                                              \
+  } *regp = (struct pt_regs *) (_sip + 1);                             \
+  regp->tpc = regp->tnpc;                                              \
+  regp->tnpc += 4;                                                     \
+}                                                                      \
+while (0)
+#endif
 #else
 #define MAKE_THROW_FRAME(_exception)           \
 do                                             \
@@ -67,7 +114,7 @@ do                                           \
 while (0)
 #endif
 
-#ifndef __ia64__
+#if !(defined(__ia64__) || defined(__sparc__))
 #define INIT_SEGV                                              \
 do                                                             \
   {                                                            \
@@ -100,7 +147,7 @@ while (0)
  * go away once all systems have pthreads libraries that are
  * compiled with full unwind info.  */
 
-#else  /* __ia64__ */
+#else  /* __ia64__ || __sparc__ */
 
 // FIXME: We shouldn't be using libc_sigaction here, since it should
 // be glibc private.  But using syscall here would mean translating to
@@ -136,5 +183,5 @@ do                                                          \
     __libc_sigaction (SIGFPE, &act, NULL);                     \
   }                                                            \
 while (0)  
-#endif /* __ia64__ */
+#endif /* __ia64__ || __sparc__ */
 #endif /* JAVA_SIGNAL_H */
index 03538ec..8694fc5 100644 (file)
@@ -20,8 +20,13 @@ details.  */
 #define SIGNAL_HANDLER(_name)                                          \
 static void _name (int _dummy, siginfo_t *_info, void *arg)
 
+#ifdef __arch64__
+#define FLUSH_REGISTER_WINDOWS                                 \
+  asm volatile ("flushw");
+#else
 #define FLUSH_REGISTER_WINDOWS                                 \
   asm volatile ("ta 3");
+#endif
 
 #define MAKE_THROW_FRAME(_exception)                           \
 do                                                             \
@@ -29,8 +34,8 @@ do                                                            \
   ucontext_t *_context = (ucontext_t *) arg;                    \
   (void)_dummy;                                                        \
   (void)_info;                                                 \
-  register int sp = _context->uc_mcontext.gregs[REG_SP];       \
-  register int retaddr = _context->uc_mcontext.gregs[REG_O7];  \
+  register long sp = _context->uc_mcontext.gregs[REG_SP];      \
+  register long retaddr = _context->uc_mcontext.gregs[REG_O7]; \
   FLUSH_REGISTER_WINDOWS;                                      \
   asm volatile ("mov %0, %%i6; mov %1, %%i7"                   \
                : : "r"(sp), "r"(retaddr));                     \
diff --git a/libjava/sysdep/sparc/locks.h b/libjava/sysdep/sparc/locks.h
new file mode 100644 (file)
index 0000000..503417c
--- /dev/null
@@ -0,0 +1,120 @@
+// locks.h - Thread synchronization primitives. Sparc implementation.
+
+/* Copyright (C) 2002  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.                             */
+
+#ifdef __arch64__
+/* Sparc64 implementation, use cas instruction.  */
+inline static bool
+compare_and_swap(volatile obj_addr_t *addr,
+                obj_addr_t old,
+                obj_addr_t new_val)
+{
+  __asm__ __volatile__("casx [%2], %3, %0\n\t"
+                      "membar #StoreLoad | #StoreStore"
+                      : "=&r" (new_val)
+                      : "0" (new_val), "r" (addr), "r" (old)
+                      : "memory");
+
+  return (new_val == old) ? true : false;
+}
+
+inline static void
+release_set(volatile obj_addr_t *addr, obj_addr_t new_val)
+{
+  __asm__ __volatile__("membar #StoreStore | #LoadStore" : : : "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);
+}
+#else
+/* Sparc32 implementation, use a spinlock.  */
+static unsigned char __cas_lock = 0;
+
+inline static void
+__cas_start_atomic(void)
+{
+  unsigned int tmp;
+  __asm__ __volatile__(
+"1:    ldstub  [%1], %0\n"
+"      orcc    %0, 0x0, %g0\n"
+"      be      3f\n"
+"       nop\n"
+"2:    ldub    [%1], %0\n"
+"      orcc    %0, 0x0, %g0\n"
+"      bne     2b\n"
+"       nop\n"
+"3:"   : "=&r" (tmp)
+       : "r" (&__cas_lock)
+       : "memory", "cc");
+}
+
+inline static void
+__cas_end_atomic(void)
+{
+  __asm__ __volatile__(
+  "stb %%g0, [%0]"
+  : /* no outputs */
+  : "r" (&__cas_lock)
+  : "memory");
+}
+
+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)
+{
+  /* Technically stbar would be needed here but no sparc32
+     system actually requires it.  Also the stbar would mean
+     this code would not work on sparcv7 chips.  */
+  __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 /* __arch64__ */
+
+#endif /* ! __SYSDEP_LOCKS_H__ */