OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [include/] [s390-signal.h] - Blame information for rev 821

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 757 jeremybenn
// s390-signal.h - Catch runtime signals and turn them into exceptions
2
// on an s390 based Linux system.
3
 
4
/* Copyright (C) 2002, 2010  Free Software Foundation
5
 
6
   This file is part of libgcj.
7
 
8
This software is copyrighted work licensed under the terms of the
9
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
10
details.  */
11
 
12
 
13
#ifndef JAVA_SIGNAL_H
14
#define JAVA_SIGNAL_H 1
15
 
16
#include <signal.h>
17
#include <sys/syscall.h>
18
#include <ucontext.h>
19
#include <limits.h>
20
 
21
#define HANDLE_SEGV 1
22
#define HANDLE_FPE 1
23
 
24
#define SIGNAL_HANDLER(_name)   \
25
static void _name (int, siginfo_t *_si __attribute__((unused)), \
26
                   ucontext_t *_uc __attribute__((unused)))
27
 
28
/* We no longer need to fiddle with the PSW address in the signal handler;
29
   this is now all handled correctly in MD_FALLBACK_FRAME_STATE_FOR.  */
30
#define MAKE_THROW_FRAME(_exception)
31
 
32
 
33
/* According to the JVM spec, "if the dividend is the negative integer
34
   of the smallest magnitude and the divisor is -1, then overflow occurs
35
   and the result is equal to the dividend.  Despite the overflow, no
36
   exception occurs".
37
 
38
   We handle this by inspecting the instruction which generated the signal,
39
   and if dividend and divisor are as above, we simply return from the signal
40
   handler.  This causes execution to continue after the instruction.
41
   Before returning, we the set result registers as expected.  */
42
#define UC_EXTENDED     0x00000001
43
 
44
#define HANDLE_DIVIDE_OVERFLOW                                          \
45
do                                                                      \
46
{                                                                       \
47
  unsigned char *_eip = (unsigned char *)                               \
48
    __builtin_extract_return_addr (_si->si_addr);                       \
49
  unsigned long *_regs = _uc->uc_mcontext.gregs;                        \
50
  int _r1, _r2, _d2, _x2, _b2;                                          \
51
  struct                                                                \
52
  {                                                                     \
53
    unsigned long int uc_flags;                                         \
54
    struct ucontext *uc_link;                                           \
55
    stack_t uc_stack;                                                   \
56
    mcontext_t uc_mcontext;                                             \
57
    unsigned long sigmask[2];                                           \
58
    unsigned long ext_regs[16];                                         \
59
  } *_uc_ext = (typeof(_uc_ext))_uc;                                    \
60
                                                                        \
61
  /* First, a couple of helper routines to decode instructions.  */     \
62
  struct _decode                                                        \
63
    {                                                                   \
64
      /* Decode RR instruction format.  */                              \
65
      static inline int _is_rr (unsigned char *_eip,                    \
66
                                unsigned char _op,                      \
67
                                int *_r1, int *_r2)                     \
68
      {                                                                 \
69
        if (_eip[0] == _op)                                              \
70
          {                                                             \
71
            *_r1 = _eip[1] >> 4;                                        \
72
            *_r2 = _eip[1] & 0xf;                                       \
73
            return 1;                                                   \
74
          }                                                             \
75
        return 0;                                                        \
76
      }                                                                 \
77
                                                                        \
78
      /* Decode RX instruction format.  */                              \
79
      static inline int _is_rx (unsigned char *_eip,                    \
80
                                unsigned char _op,                      \
81
                                int *_r1, int *_d2, int *_x2, int *_b2) \
82
      {                                                                 \
83
        if (_eip[0] == _op)                                              \
84
          {                                                             \
85
            *_r1 = _eip[1] >> 4;                                        \
86
            *_x2 = _eip[1] & 0xf;                                       \
87
            *_b2 = _eip[2] >> 4;                                        \
88
            *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3];                    \
89
            return 1;                                                   \
90
          }                                                             \
91
        return 0;                                                        \
92
      }                                                                 \
93
                                                                        \
94
      /* Decode RRE instruction format.  */                             \
95
      static inline int _is_rre (unsigned char *_eip,                   \
96
                                 unsigned char _op1, unsigned char _op2,\
97
                                 int *_r1, int *_r2)                    \
98
      {                                                                 \
99
        if (_eip[0] == _op1 && _eip[1] == _op2)                          \
100
          {                                                             \
101
            *_r1 = _eip[3] >> 4;                                        \
102
            *_r2 = _eip[3] & 0xf;                                       \
103
            return 1;                                                   \
104
          }                                                             \
105
        return 0;                                                        \
106
      }                                                                 \
107
                                                                        \
108
      /* Decode RXY instruction format.  */                             \
109
      static inline int _is_rxy (unsigned char *_eip,                   \
110
                                 unsigned char _op1, unsigned char _op2,\
111
                                 int *_r1, int *_d2, int *_x2, int *_b2)\
112
      {                                                                 \
113
        if (_eip[0] == _op1 && _eip[5] == _op2)                          \
114
          {                                                             \
115
            *_r1 = _eip[1] >> 4;                                        \
116
            *_x2 = _eip[1] & 0xf;                                       \
117
            *_b2 = _eip[2] >> 4;                                        \
118
            *_d2 = ((_eip[2] & 0xf) << 8) + _eip[3] + (_eip[4] << 12);  \
119
            /* We have a 20-bit signed displacement.  */                \
120
            *_d2 = (*_d2 ^ 0x80000) - 0x80000;                          \
121
            return 1;                                                   \
122
          }                                                             \
123
        return 0;                                                        \
124
      }                                                                 \
125
                                                                        \
126
      /* Compute effective address.  */                                 \
127
      static inline unsigned long _eff (unsigned long *_regs,           \
128
                                        long _d, int _x, int _b)        \
129
      {                                                                 \
130
        return _d + (_x? _regs[_x] : 0) + (_b? _regs[_b] : 0);            \
131
      }                                                                 \
132
                                                                        \
133
      static inline int is_long_long_min_p (unsigned long *_regs,       \
134
                                            unsigned long *_ext_regs,   \
135
                                            int _r)                     \
136
      {                                                                 \
137
        return ((long long)_regs[_r]                                    \
138
                | (long long)_ext_regs[_r] << 32) ==                    \
139
          LONG_LONG_MIN;                                                \
140
      }                                                                 \
141
  };                                                                    \
142
                                                                        \
143
  /* DR r1,r2 */                                                        \
144
  if (_decode::_is_rr (_eip, 0x1d, &_r1, &_r2)                          \
145
      && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN        \
146
      && (int) _regs[_r2] == -1)                                        \
147
    {                                                                   \
148
      _regs[_r1] &= ~0xffffffff;                                        \
149
      return;                                                           \
150
    }                                                                   \
151
                                                                        \
152
  /* D r1,d2(x2,b2) */                                                  \
153
  if (_decode::_is_rx (_eip, 0x5d, &_r1, &_d2, &_x2, &_b2)              \
154
      && (int) _regs[_r1] == -1 && (int) _regs[_r1+1] == INT_MIN        \
155
      && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1)           \
156
    {                                                                   \
157
      _regs[_r1] &= ~0xffffffff;                                        \
158
      return;                                                           \
159
    }                                                                   \
160
                                                                        \
161
  /* DSGR r1,r2 */                                                      \
162
  if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2)                   \
163
      && (long) _regs[_r1+1] == LONG_MIN                                \
164
      && (long) _regs[_r2] == -1L)                                      \
165
    {                                                                   \
166
      _regs[_r1] = 0;                                                    \
167
      return;                                                           \
168
    }                                                                   \
169
                                                                        \
170
  /* DSGFR r1,r2 */                                                     \
171
  if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2)                   \
172
      && (long) _regs[_r1+1] == LONG_MIN                                \
173
      && (int) _regs[_r2] == -1)                                        \
174
    {                                                                   \
175
      _regs[_r1] = 0;                                                    \
176
      return;                                                           \
177
    }                                                                   \
178
                                                                        \
179
  /* DSG r1,d2(x2,b2) */                                                \
180
  if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2)       \
181
      && (long) _regs[_r1+1] == LONG_MIN                                \
182
      && *(long *) _decode::_eff (_regs, _d2, _x2, _b2) == -1L)         \
183
    {                                                                   \
184
      _regs[_r1] = 0;                                                    \
185
      return;                                                           \
186
    }                                                                   \
187
                                                                        \
188
  /* DSGF r1,d2(x2,b2) */                                               \
189
  if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2)       \
190
      && (long) _regs[_r1+1] == LONG_MIN                                \
191
      && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1)           \
192
    {                                                                   \
193
      _regs[_r1] = 0;                                                    \
194
      return;                                                           \
195
    }                                                                   \
196
                                                                        \
197
  /* The extended ucontext contains the upper halfs of the 64bit        \
198
     registers in 31bit applications.  */                               \
199
  if (_uc->uc_flags & 1 == 1)                                           \
200
    {                                                                   \
201
      /* DSGR r1,r2 */                                                  \
202
      if (_decode::_is_rre (_eip, 0xb9, 0x0d, &_r1, &_r2)               \
203
          && (int) _regs[_r2] == -1                                     \
204
          && (int) _uc_ext->ext_regs[_r2] == -1                         \
205
          && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs,     \
206
                                          _r1 + 1))                     \
207
        {                                                               \
208
          _regs[_r1] = 0;                                                \
209
          _uc_ext->ext_regs[_r1] = 0;                                    \
210
          return;                                                       \
211
        }                                                               \
212
                                                                        \
213
      /* DSGFR r1,r2 */                                                 \
214
      if (_decode::_is_rre (_eip, 0xb9, 0x1d, &_r1, &_r2)               \
215
          && (int) _regs[_r2] == -1                                     \
216
          && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs,     \
217
                                          _r1 + 1))                     \
218
        {                                                               \
219
          _regs[_r1] = 0;                                                \
220
          _uc_ext->ext_regs[_r1] = 0;                                    \
221
          return;                                                       \
222
        }                                                               \
223
                                                                        \
224
      /* DSG r1,d2(x2,b2) */                                            \
225
      if (_decode::_is_rxy (_eip, 0xe3, 0x0d, &_r1, &_d2, &_x2, &_b2)   \
226
          && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1        \
227
          && *(int *) _decode::_eff (_regs, _d2 + 4, _x2, _b2) == -1    \
228
          && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs,     \
229
                                          _r1 + 1))                     \
230
        {                                                               \
231
          _regs[_r1] = 0;                                                \
232
          _uc_ext->ext_regs[_r1] = 0;                                    \
233
          return;                                                       \
234
        }                                                               \
235
                                                                        \
236
      /* DSGF r1,d2(x2,b2) */                                           \
237
      if (_decode::_is_rxy (_eip, 0xe3, 0x1d, &_r1, &_d2, &_x2, &_b2)   \
238
          && *(int *) _decode::_eff (_regs, _d2, _x2, _b2) == -1        \
239
          && _decode::is_long_long_min_p (_regs, _uc_ext->ext_regs,     \
240
                                          _r1 + 1))                     \
241
        {                                                               \
242
          _regs[_r1] = 0;                                                \
243
          _uc_ext->ext_regs[_r1] = 0;                                    \
244
          return;                                                       \
245
        }                                                               \
246
    }                                                                   \
247
 }                                                                      \
248
while (0)
249
 
250
/* For an explanation why we cannot simply use sigaction to
251
   install the handlers, see i386-signal.h.  */
252
 
253
/* We use old_kernel_sigaction here because we're calling the kernel
254
   directly rather than via glibc.  The sigaction structure that the
255
   syscall uses is a different shape from the one in userland and not
256
   visible to us in a header file so we define it here.  */
257
 
258
struct old_s390_kernel_sigaction {
259
        void (*k_sa_handler) (int, siginfo_t *, ucontext_t *);
260
        unsigned long k_sa_mask;
261
        unsigned long k_sa_flags;
262
        void (*sa_restorer) (void);
263
};
264
 
265
#define INIT_SEGV                                       \
266
do                                                      \
267
  {                                                     \
268
    struct old_s390_kernel_sigaction kact;              \
269
    kact.k_sa_handler = catch_segv;                     \
270
    kact.k_sa_mask = 0;                                  \
271
    kact.k_sa_flags = SA_SIGINFO;                       \
272
    syscall (SYS_sigaction, SIGSEGV, &kact, NULL);      \
273
  }                                                     \
274
while (0)
275
 
276
#define INIT_FPE                                                \
277
do                                                              \
278
  {                                                             \
279
    struct old_s390_kernel_sigaction kact;                      \
280
    kact.k_sa_handler = catch_fpe;                              \
281
    kact.k_sa_mask = 0;                                          \
282
    kact.k_sa_flags = SA_SIGINFO;                               \
283
    syscall (SYS_sigaction, SIGFPE, &kact, NULL);               \
284
  }                                                             \
285
while (0)
286
 
287
#endif /* JAVA_SIGNAL_H */
288
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.