tree-ssa-pre.c (my_rev_post_order_compute): Remove set but not used count variable.
[gcc.git] / libjava / include / s390-signal.h
index 743c398830b110e6e6311eed8a312e5e961fdd74..fe965bd2b460f8aab713121d0a3b765a535c59c1 100644 (file)
@@ -15,18 +15,170 @@ details.  */
 
 #include <signal.h>
 #include <sys/syscall.h>
+#include <ucontext.h>
+#include <limits.h>
 
 #define HANDLE_SEGV 1
-#undef HANDLE_FPE
+#define HANDLE_FPE 1
 
 #define SIGNAL_HANDLER(_name)  \
-static void _name (int, siginfo_t *, void *)
+static void _name (int, siginfo_t *_si __attribute__((unused)), \
+                  ucontext_t *_uc __attribute__((unused)))
 
 /* We no longer need to fiddle with the PSW address in the signal handler;
    this is now all handled correctly in MD_FALLBACK_FRAME_STATE_FOR.  */
 #define MAKE_THROW_FRAME(_exception)
 
 
+/* According to the JVM spec, "if the dividend is the negative integer 
+   of the smallest magnitude and the divisor is -1, then overflow occurs 
+   and the result is equal to the dividend.  Despite the overflow, no 
+   exception occurs".
+
+   We handle this by inspecting the instruction which generated the signal,
+   and if dividend and divisor are as above, we simply return from the signal
+   handler.  This causes execution to continue after the instruction.  
+   Before returning, we the set result registers as expected.  */
+
+#define HANDLE_DIVIDE_OVERFLOW                                         \
+do                                                                     \
+{                                                                      \
+  unsigned char *_eip = (unsigned char *)                              \
+    __builtin_extract_return_addr (_si->si_addr);                      \
+  unsigned long *_regs = _uc->uc_mcontext.gregs;                       \
+  int _r1, _r2, _d2, _x2, _b2;                                         \
+                                                                       \
+  /* First, a couple of helper routines to decode instructions.  */    \
+  struct _decode                                                       \
+    {                                                                  \
+      /* Decode RR instruction format.  */                             \
+      static inline int _is_rr (unsigned char *_eip,                   \
+                               unsigned char _op,                      \
+                               int *_r1, int *_r2)                     \
+      {                                                                        \
+       if (_eip[0] == _op)                                             \
+         {                                                             \
+           *_r1 = _eip[1] >> 4;                                        \
+           *_r2 = _eip[1] & 0xf;                                       \
+           return 1;                                                   \
+         }                                                             \
+       return 0;                                                       \
+      }                                                                        \
+                                                                       \
+      /* Decode RX instruction format.  */                             \
+      static inline int _is_rx (unsigned char *_eip,                   \
+                               unsigned char _op,                      \
+                               int *_r1, int *_d2, int *_x2, int *_b2) \
+      {                                                                        \
+       if (_eip[0] == _op)                                             \
+         {                                                             \
+           *_r1 = _eip[1] >> 4;                                        \
+           *_x2 = _eip[1] & 0xf;                                       \
+           *_b2 = _eip[2] >> 4;                                        \
+           *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3];                    \
+           return 1;                                                   \
+         }                                                             \
+       return 0;                                                       \
+      }                                                                        \
+                                                                       \
+      /* Decode RRE instruction format.  */                            \
+      static inline int _is_rre (unsigned char *_eip,                  \
+                                unsigned char _op1, unsigned char _op2,\
+                                int *_r1, int *_r2)                    \
+      {                                                                        \
+       if (_eip[0] == _op1 && _eip[1] == _op2)                         \
+         {                                                             \
+           *_r1 = _eip[3] >> 4;                                        \
+           *_r2 = _eip[3] & 0xf;                                       \
+           return 1;                                                   \
+         }                                                             \
+       return 0;                                                       \
+      }                                                                        \
+                                                                       \
+      /* Decode RXY instruction format.  */                            \
+      static inline int _is_rxy (unsigned char *_eip,                  \
+                                unsigned char _op1, unsigned char _op2,\
+                                int *_r1, int *_d2, int *_x2, int *_b2)\
+      {                                                                        \
+       if (_eip[0] == _op1 && _eip[5] == _op2)                         \
+         {                                                             \
+           *_r1 = _eip[1] >> 4;                                        \
+           *_x2 = _eip[1] & 0xf;                                       \
+           *_b2 = _eip[2] >> 4;                                        \
+           *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3] + (_eip[4] << 12);  \
+           /* We have a 20-bit signed displacement.  */                \
+           *_d2 = (*_d2 ^ 0x80000) - 0x80000;                          \
+           return 1;                                                   \
+         }                                                             \
+       return 0;                                                       \
+      }                                                                        \
+                                                                       \
+      /* Compute effective address.  */                                        \
+      static inline unsigned long _eff (unsigned long *_regs,          \
+                                       long _d, int _x, int _b)        \
+      {                                                                        \
+       return _d + (_x? _regs[_x] : 0) + (_b? _regs[_b] : 0);          \
+      }                                                                        \
+    };                                                                 \
+                                                                       \
+                                                                       \
+  /* DR r1,r2 */                                                       \
+  if (_decode::_is_rr (_eip, 0x1d, &_r1, &_r2)                         \
+      && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN       \
+      && (int) _regs[_r2] == -1)                                       \
+    {                                                                  \
+      _regs[_r1] &= ~0xffffffff;                                       \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+  /* D r1,d2(x2,b2) */                                                 \
+  if (_decode::_is_rx (_eip, 0x5d, &_r1, &_d2, &_x2, &_b2)             \
+      && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN       \
+      && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1)          \
+    {                                                                  \
+      _regs[_r1] &= ~0xffffffff;                                       \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+  /* DSGR r1,r2 */                                                     \
+  if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2)                  \
+      && (long) _regs[_r1+1] == LONG_MIN                               \
+      && (long) _regs[_r2] == -1L)                                     \
+    {                                                                  \
+      _regs[_r1] = 0;                                                  \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+  /* DSGFR r1,r2 */                                                    \
+  if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2)                  \
+      && (long) _regs[_r1+1] == LONG_MIN                               \
+      && (int) _regs[_r2] == -1)                                       \
+    {                                                                  \
+      _regs[_r1] = 0;                                                  \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+  /* DSG r1,d2(x2,b2) */                                               \
+  if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2)      \
+      && (long) _regs[_r1+1] == LONG_MIN                               \
+      && *(long *) _decode::_eff (_regs, _d2, _x2, _b2) == -1L)                \
+    {                                                                  \
+      _regs[_r1] = 0;                                                  \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+  /* DSGF r1,d2(x2,b2) */                                              \
+  if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2)      \
+      && (long) _regs[_r1+1] == LONG_MIN                               \
+      && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1)          \
+    {                                                                  \
+      _regs[_r1] = 0;                                                  \
+      return;                                                          \
+    }                                                                  \
+                                                                       \
+}                                                                      \
+while (0)
+
 /* For an explanation why we cannot simply use sigaction to
    install the handlers, see i386-signal.h.  */
 
@@ -36,7 +188,7 @@ static void _name (int, siginfo_t *, void *)
    visible to us in a header file so we define it here.  */
 
 struct old_s390_kernel_sigaction {
-       void (*k_sa_handler) (int, siginfo_t *, void *);
+       void (*k_sa_handler) (int, siginfo_t *, ucontext_t *);
        unsigned long k_sa_mask;
        unsigned long k_sa_flags;
        void (*sa_restorer) (void);