4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
22 #pragma ident "%Z%%M% %I% %E% SMI"
25 * Copyright (c) 1987 by Sun Microsystems, Inc.
28 /* Swap handler for SIGFPE codes. */
32 #include <floatingpoint.h>
34 #ifndef FPE_INTDIV_TRAP
35 #define FPE_INTDIV_TRAP 0x14 /* integer divide by zero */
37 #ifndef FPE_CHKINST_TRAP
38 #define FPE_CHKINST_TRAP 0x18 /* CHK [CHK2] instruction */
40 #ifndef FPE_TRAPV_TRAP
41 #define FPE_TRAPV_TRAP 0x1c /* TRAPV [cpTRAPcc TRAPcc] instr */
43 #ifndef FPE_FLTBSUN_TRAP
44 #define FPE_FLTBSUN_TRAP 0xc0 /* [branch or set on unordered cond] */
46 #ifndef FPE_FLTINEX_TRAP
47 #define FPE_FLTINEX_TRAP 0xc4 /* [floating inexact result] */
49 #ifndef FPE_FLTDIV_TRAP
50 #define FPE_FLTDIV_TRAP 0xc8 /* [floating divide by zero] */
52 #ifndef FPE_FLTUND_TRAP
53 #define FPE_FLTUND_TRAP 0xcc /* [floating underflow] */
55 #ifndef FPE_FLTOPERR_TRAP
56 #define FPE_FLTOPERR_TRAP 0xd0 /* [floating operand error] */
58 #ifndef FPE_FLTOVF_TRAP
59 #define FPE_FLTOVF_TRAP 0xd4 /* [floating overflow] */
61 #ifndef FPE_FLTNAN_TRAP
62 #define FPE_FLTNAN_TRAP 0xd8 /* [floating Not-A-Number] */
64 #ifndef FPE_FPA_ENABLE
65 #define FPE_FPA_ENABLE 0x400 /* [FPA not enabled] */
68 #define FPE_FPA_ERROR 0x404 /* [FPA arithmetic exception] */
71 #define N_SIGFPE_CODE 13
73 /* Array of SIGFPE codes. */
75 static sigfpe_code_type sigfpe_codes
[N_SIGFPE_CODE
] = {
90 /* Array of handlers. */
92 static sigfpe_handler_type sigfpe_handlers
[N_SIGFPE_CODE
];
94 static int _sigfpe_master_enabled
;
95 /* Originally zero, set to 1 by _enable_sigfpe_master. */
98 _sigfpe_master(sig
, code
, scp
, addr
)
100 sigfpe_code_type code
;
101 struct sigcontext
*scp
;
105 enum fp_exception_type exception
;
107 for (i
= 0; (i
< N_SIGFPE_CODE
) && (code
!= sigfpe_codes
[i
]); i
++);
108 /* Find index of handler. */
109 if (i
>= N_SIGFPE_CODE
)
110 i
= N_SIGFPE_CODE
- 1;
111 switch ((unsigned int)sigfpe_handlers
[i
]) {
112 case (unsigned int)SIGFPE_DEFAULT
:
114 case FPE_FLTBSUN_TRAP
:
115 case FPE_FLTOPERR_TRAP
:
116 case FPE_FLTNAN_TRAP
:
117 exception
= fp_invalid
;
119 case FPE_FLTINEX_TRAP
:
120 exception
= fp_inexact
;
122 case FPE_FLTDIV_TRAP
:
123 exception
= fp_division
;
125 case FPE_FLTUND_TRAP
:
126 exception
= fp_underflow
;
128 case FPE_FLTOVF_TRAP
:
129 exception
= fp_overflow
;
131 default: /* The common default treatment is to abort. */
134 case (unsigned int)SIGFPE_ABORT
:
136 case (unsigned int)SIGFPE_IGNORE
:
138 default: /* User-defined not SIGFPE_DEFAULT or
140 (sigfpe_handlers
[i
]) (sig
, code
, scp
, addr
);
144 switch ((unsigned int)ieee_handlers
[(int) exception
]) {
145 case (unsigned int)SIGFPE_DEFAULT
:
146 /* Error condition but ignore it. */
147 case (unsigned int)SIGFPE_IGNORE
:
148 /* Error condition but ignore it. */
150 case (unsigned int)SIGFPE_ABORT
:
153 (ieee_handlers
[(int) exception
]) (sig
, code
, scp
, addr
);
159 _enable_sigfpe_master()
161 /* Enable the sigfpe master handler always. */
162 struct sigvec newsigvec
, oldsigvec
;
164 newsigvec
.sv_handler
= _sigfpe_master
;
165 newsigvec
.sv_mask
= 0;
166 newsigvec
.sv_onstack
= 0;
167 _sigfpe_master_enabled
= 1;
168 return sigvec(SIGFPE
, &newsigvec
, &oldsigvec
);
172 _test_sigfpe_master()
175 * Enable the sigfpe master handler if it's never been enabled
179 if (_sigfpe_master_enabled
== 0)
180 return _enable_sigfpe_master();
182 return _sigfpe_master_enabled
;
187 sigfpe_code_type code
;
188 sigfpe_handler_type hdl
;
190 sigfpe_handler_type oldhdl
;
193 _test_sigfpe_master();
194 for (i
= 0; (i
< N_SIGFPE_CODE
) && (code
!= sigfpe_codes
[i
]); i
++);
195 /* Find index of handler. */
196 if (i
>= N_SIGFPE_CODE
) {
198 return (sigfpe_handler_type
) BADSIG
;/* Not 0 or SIGFPE code */
200 oldhdl
= sigfpe_handlers
[i
];
201 sigfpe_handlers
[i
] = hdl
;