xref: /titanic_51/usr/src/lib/libm/common/m9x/fex_handler.h (revision 25c28e83beb90e7c80452a7c818c5e6f73a07dc8)
1*25c28e83SPiotr Jasiukajtis /*
2*25c28e83SPiotr Jasiukajtis  * CDDL HEADER START
3*25c28e83SPiotr Jasiukajtis  *
4*25c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
5*25c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
6*25c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
7*25c28e83SPiotr Jasiukajtis  *
8*25c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*25c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
10*25c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
11*25c28e83SPiotr Jasiukajtis  * and limitations under the License.
12*25c28e83SPiotr Jasiukajtis  *
13*25c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
14*25c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*25c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
16*25c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
17*25c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
18*25c28e83SPiotr Jasiukajtis  *
19*25c28e83SPiotr Jasiukajtis  * CDDL HEADER END
20*25c28e83SPiotr Jasiukajtis  */
21*25c28e83SPiotr Jasiukajtis 
22*25c28e83SPiotr Jasiukajtis /*
23*25c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24*25c28e83SPiotr Jasiukajtis  */
25*25c28e83SPiotr Jasiukajtis /*
26*25c28e83SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27*25c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
28*25c28e83SPiotr Jasiukajtis  */
29*25c28e83SPiotr Jasiukajtis 
30*25c28e83SPiotr Jasiukajtis #ifndef	_M9X_FEX_HANDLER_H
31*25c28e83SPiotr Jasiukajtis #define	_M9X_FEX_HANDLER_H
32*25c28e83SPiotr Jasiukajtis 
33*25c28e83SPiotr Jasiukajtis /* the following enums must match the bit positions in fenv.h */
34*25c28e83SPiotr Jasiukajtis enum fex_exception {
35*25c28e83SPiotr Jasiukajtis 	fex_inexact		= 0,
36*25c28e83SPiotr Jasiukajtis 	fex_division	= 1,
37*25c28e83SPiotr Jasiukajtis 	fex_underflow	= 2,
38*25c28e83SPiotr Jasiukajtis 	fex_overflow	= 3,
39*25c28e83SPiotr Jasiukajtis 	fex_inv_zdz		= 4,
40*25c28e83SPiotr Jasiukajtis 	fex_inv_idi		= 5,
41*25c28e83SPiotr Jasiukajtis 	fex_inv_isi		= 6,
42*25c28e83SPiotr Jasiukajtis 	fex_inv_zmi		= 7,
43*25c28e83SPiotr Jasiukajtis 	fex_inv_sqrt	= 8,
44*25c28e83SPiotr Jasiukajtis 	fex_inv_snan	= 9,
45*25c28e83SPiotr Jasiukajtis 	fex_inv_int		= 10,
46*25c28e83SPiotr Jasiukajtis 	fex_inv_cmp		= 11
47*25c28e83SPiotr Jasiukajtis };
48*25c28e83SPiotr Jasiukajtis 
49*25c28e83SPiotr Jasiukajtis 
50*25c28e83SPiotr Jasiukajtis /* auxiliary functions in __fex_hdlr.c */
51*25c28e83SPiotr Jasiukajtis extern struct fex_handler_data *__fex_get_thr_handlers(void);
52*25c28e83SPiotr Jasiukajtis extern void __fex_update_te(void);
53*25c28e83SPiotr Jasiukajtis 
54*25c28e83SPiotr Jasiukajtis /* auxiliary functions in __fex_sym.c */
55*25c28e83SPiotr Jasiukajtis extern void __fex_sym_init(void);
56*25c28e83SPiotr Jasiukajtis extern char *__fex_sym(char *, char **);
57*25c28e83SPiotr Jasiukajtis 
58*25c28e83SPiotr Jasiukajtis /* auxiliary functions in fex_log.c */
59*25c28e83SPiotr Jasiukajtis extern void __fex_mklog(ucontext_t *, char *, int, enum fex_exception,
60*25c28e83SPiotr Jasiukajtis 	int, void *);
61*25c28e83SPiotr Jasiukajtis 
62*25c28e83SPiotr Jasiukajtis /* system-dependent auxiliary functions */
63*25c28e83SPiotr Jasiukajtis extern enum fex_exception __fex_get_invalid_type(siginfo_t *, ucontext_t *);
64*25c28e83SPiotr Jasiukajtis extern void __fex_get_op(siginfo_t *, ucontext_t *, fex_info_t *);
65*25c28e83SPiotr Jasiukajtis extern void __fex_st_result(siginfo_t *, ucontext_t *, fex_info_t *);
66*25c28e83SPiotr Jasiukajtis 
67*25c28e83SPiotr Jasiukajtis /* inline templates and macros for accessing fp state */
68*25c28e83SPiotr Jasiukajtis extern void __fenv_getfsr(unsigned long *);
69*25c28e83SPiotr Jasiukajtis extern void __fenv_setfsr(const unsigned long *);
70*25c28e83SPiotr Jasiukajtis 
71*25c28e83SPiotr Jasiukajtis #if defined(__sparc)
72*25c28e83SPiotr Jasiukajtis 
73*25c28e83SPiotr Jasiukajtis #define __fenv_get_rd(X)	((X>>30)&0x3)
74*25c28e83SPiotr Jasiukajtis #define __fenv_set_rd(X,Y)	X=(X&~0xc0000000ul)|((Y)<<30)
75*25c28e83SPiotr Jasiukajtis 
76*25c28e83SPiotr Jasiukajtis #define __fenv_get_te(X)	((X>>23)&0x1f)
77*25c28e83SPiotr Jasiukajtis #define __fenv_set_te(X,Y)	X=(X&~0x0f800000ul)|((Y)<<23)
78*25c28e83SPiotr Jasiukajtis 
79*25c28e83SPiotr Jasiukajtis #define __fenv_get_ex(X)	((X>>5)&0x1f)
80*25c28e83SPiotr Jasiukajtis #define __fenv_set_ex(X,Y)	X=(X&~0x000003e0ul)|((Y)<<5)
81*25c28e83SPiotr Jasiukajtis 
82*25c28e83SPiotr Jasiukajtis #elif defined(__x86)
83*25c28e83SPiotr Jasiukajtis 
84*25c28e83SPiotr Jasiukajtis extern void __fenv_getcwsw(unsigned int *);
85*25c28e83SPiotr Jasiukajtis extern void __fenv_setcwsw(const unsigned int *);
86*25c28e83SPiotr Jasiukajtis 
87*25c28e83SPiotr Jasiukajtis extern void __fenv_getmxcsr(unsigned int *);
88*25c28e83SPiotr Jasiukajtis extern void __fenv_setmxcsr(const unsigned int *);
89*25c28e83SPiotr Jasiukajtis 
90*25c28e83SPiotr Jasiukajtis #define __fenv_get_rd(X)	((X>>26)&3)
91*25c28e83SPiotr Jasiukajtis #define __fenv_set_rd(X,Y)	X=(X&~0x0c000000)|((Y)<<26)
92*25c28e83SPiotr Jasiukajtis 
93*25c28e83SPiotr Jasiukajtis #define __fenv_get_rp(X)	((X>>24)&3)
94*25c28e83SPiotr Jasiukajtis #define __fenv_set_rp(X,Y)	X=(X&~0x03000000)|((Y)<<24)
95*25c28e83SPiotr Jasiukajtis 
96*25c28e83SPiotr Jasiukajtis #define __fenv_get_te(X)	((X>>16)&0x3d)
97*25c28e83SPiotr Jasiukajtis #define __fenv_set_te(X,Y)	X=(X&~0x003d0000)|((Y)<<16)
98*25c28e83SPiotr Jasiukajtis 
99*25c28e83SPiotr Jasiukajtis #define __fenv_get_ex(X)	(X&0x3d)
100*25c28e83SPiotr Jasiukajtis #define __fenv_set_ex(X,Y)	X=(X&~0x0000003d)|(Y)
101*25c28e83SPiotr Jasiukajtis 
102*25c28e83SPiotr Jasiukajtis /*
103*25c28e83SPiotr Jasiukajtis  * These macros define some useful distinctions between various
104*25c28e83SPiotr Jasiukajtis  * SSE instructions.  In some cases, distinctions are made for
105*25c28e83SPiotr Jasiukajtis  * the purpose of simplifying the decoding of instructions, while
106*25c28e83SPiotr Jasiukajtis  * in other cases, they are made for the purpose of simplying the
107*25c28e83SPiotr Jasiukajtis  * emulation.  Note that these values serve as bit flags within
108*25c28e83SPiotr Jasiukajtis  * the enum values in sseinst_t.
109*25c28e83SPiotr Jasiukajtis  */
110*25c28e83SPiotr Jasiukajtis #define DOUBLE		0x100
111*25c28e83SPiotr Jasiukajtis #define SIMD		0x080
112*25c28e83SPiotr Jasiukajtis #define INTREG		0x040
113*25c28e83SPiotr Jasiukajtis 
114*25c28e83SPiotr Jasiukajtis typedef union {
115*25c28e83SPiotr Jasiukajtis 	double		d[2];
116*25c28e83SPiotr Jasiukajtis 	long long	l[2];
117*25c28e83SPiotr Jasiukajtis 	float		f[4];
118*25c28e83SPiotr Jasiukajtis 	int		i[4];
119*25c28e83SPiotr Jasiukajtis } sseoperand_t;
120*25c28e83SPiotr Jasiukajtis 
121*25c28e83SPiotr Jasiukajtis /* structure to hold a decoded SSE instruction */
122*25c28e83SPiotr Jasiukajtis typedef struct {
123*25c28e83SPiotr Jasiukajtis 	enum {
124*25c28e83SPiotr Jasiukajtis 		/* single precision scalar instructions */
125*25c28e83SPiotr Jasiukajtis 		cmpss		= 0,
126*25c28e83SPiotr Jasiukajtis 		minss		= 1,
127*25c28e83SPiotr Jasiukajtis 		maxss		= 2,
128*25c28e83SPiotr Jasiukajtis 		addss		= 3,
129*25c28e83SPiotr Jasiukajtis 		subss		= 4,
130*25c28e83SPiotr Jasiukajtis 		mulss		= 5,
131*25c28e83SPiotr Jasiukajtis 		divss		= 6,
132*25c28e83SPiotr Jasiukajtis 		sqrtss		= 7,
133*25c28e83SPiotr Jasiukajtis 		ucomiss		= 16,
134*25c28e83SPiotr Jasiukajtis 		comiss		= 17,
135*25c28e83SPiotr Jasiukajtis 		cvtss2sd	= 32,
136*25c28e83SPiotr Jasiukajtis 		cvtsi2ss	= INTREG + 0,
137*25c28e83SPiotr Jasiukajtis 		cvttss2si	= INTREG + 1,
138*25c28e83SPiotr Jasiukajtis 		cvtss2si	= INTREG + 2,
139*25c28e83SPiotr Jasiukajtis 		cvtsi2ssq	= INTREG + 8,
140*25c28e83SPiotr Jasiukajtis 		cvttss2siq	= INTREG + 9,
141*25c28e83SPiotr Jasiukajtis 		cvtss2siq	= INTREG + 10,
142*25c28e83SPiotr Jasiukajtis 
143*25c28e83SPiotr Jasiukajtis 		/* single precision SIMD instructions */
144*25c28e83SPiotr Jasiukajtis 		cmpps		= SIMD + 0,
145*25c28e83SPiotr Jasiukajtis 		minps		= SIMD + 1,
146*25c28e83SPiotr Jasiukajtis 		maxps		= SIMD + 2,
147*25c28e83SPiotr Jasiukajtis 		addps		= SIMD + 3,
148*25c28e83SPiotr Jasiukajtis 		subps		= SIMD + 4,
149*25c28e83SPiotr Jasiukajtis 		mulps		= SIMD + 5,
150*25c28e83SPiotr Jasiukajtis 		divps		= SIMD + 6,
151*25c28e83SPiotr Jasiukajtis 		sqrtps		= SIMD + 7,
152*25c28e83SPiotr Jasiukajtis 		cvtps2pd	= SIMD + 32,
153*25c28e83SPiotr Jasiukajtis 		cvtdq2ps	= SIMD + 34,
154*25c28e83SPiotr Jasiukajtis 		cvttps2dq	= SIMD + 35,
155*25c28e83SPiotr Jasiukajtis 		cvtps2dq	= SIMD + 36,
156*25c28e83SPiotr Jasiukajtis 		cvtpi2ps	= SIMD + INTREG + 0,
157*25c28e83SPiotr Jasiukajtis 		cvttps2pi	= SIMD + INTREG + 1,
158*25c28e83SPiotr Jasiukajtis 		cvtps2pi	= SIMD + INTREG + 2,
159*25c28e83SPiotr Jasiukajtis 
160*25c28e83SPiotr Jasiukajtis 		/* double precision scalar instructions */
161*25c28e83SPiotr Jasiukajtis 		cmpsd		= DOUBLE + 0,
162*25c28e83SPiotr Jasiukajtis 		minsd		= DOUBLE + 1,
163*25c28e83SPiotr Jasiukajtis 		maxsd		= DOUBLE + 2,
164*25c28e83SPiotr Jasiukajtis 		addsd		= DOUBLE + 3,
165*25c28e83SPiotr Jasiukajtis 		subsd		= DOUBLE + 4,
166*25c28e83SPiotr Jasiukajtis 		mulsd		= DOUBLE + 5,
167*25c28e83SPiotr Jasiukajtis 		divsd		= DOUBLE + 6,
168*25c28e83SPiotr Jasiukajtis 		sqrtsd		= DOUBLE + 7,
169*25c28e83SPiotr Jasiukajtis 		ucomisd		= DOUBLE + 16,
170*25c28e83SPiotr Jasiukajtis 		comisd		= DOUBLE + 17,
171*25c28e83SPiotr Jasiukajtis 		cvtsd2ss	= DOUBLE + 32,
172*25c28e83SPiotr Jasiukajtis 		cvtsi2sd	= DOUBLE + INTREG + 0,
173*25c28e83SPiotr Jasiukajtis 		cvttsd2si	= DOUBLE + INTREG + 1,
174*25c28e83SPiotr Jasiukajtis 		cvtsd2si	= DOUBLE + INTREG + 2,
175*25c28e83SPiotr Jasiukajtis 		cvtsi2sdq	= DOUBLE + INTREG + 8,
176*25c28e83SPiotr Jasiukajtis 		cvttsd2siq	= DOUBLE + INTREG + 9,
177*25c28e83SPiotr Jasiukajtis 		cvtsd2siq	= DOUBLE + INTREG + 10,
178*25c28e83SPiotr Jasiukajtis 
179*25c28e83SPiotr Jasiukajtis 		/* double precision SIMD instructions */
180*25c28e83SPiotr Jasiukajtis 		cmppd		= DOUBLE + SIMD + 0,
181*25c28e83SPiotr Jasiukajtis 		minpd		= DOUBLE + SIMD + 1,
182*25c28e83SPiotr Jasiukajtis 		maxpd		= DOUBLE + SIMD + 2,
183*25c28e83SPiotr Jasiukajtis 		addpd		= DOUBLE + SIMD + 3,
184*25c28e83SPiotr Jasiukajtis 		subpd		= DOUBLE + SIMD + 4,
185*25c28e83SPiotr Jasiukajtis 		mulpd		= DOUBLE + SIMD + 5,
186*25c28e83SPiotr Jasiukajtis 		divpd		= DOUBLE + SIMD + 6,
187*25c28e83SPiotr Jasiukajtis 		sqrtpd		= DOUBLE + SIMD + 7,
188*25c28e83SPiotr Jasiukajtis 		cvtpd2ps	= DOUBLE + SIMD + 32,
189*25c28e83SPiotr Jasiukajtis 		cvtdq2pd	= DOUBLE + SIMD + 34,
190*25c28e83SPiotr Jasiukajtis 		cvttpd2dq	= DOUBLE + SIMD + 35,
191*25c28e83SPiotr Jasiukajtis 		cvtpd2dq	= DOUBLE + SIMD + 36,
192*25c28e83SPiotr Jasiukajtis 		cvtpi2pd	= DOUBLE + SIMD + INTREG + 0,
193*25c28e83SPiotr Jasiukajtis 		cvttpd2pi	= DOUBLE + SIMD + INTREG + 1,
194*25c28e83SPiotr Jasiukajtis 		cvtpd2pi	= DOUBLE + SIMD + INTREG + 2,
195*25c28e83SPiotr Jasiukajtis 	} op;
196*25c28e83SPiotr Jasiukajtis 	int		imm;
197*25c28e83SPiotr Jasiukajtis 	sseoperand_t	*op1, *op2;
198*25c28e83SPiotr Jasiukajtis } sseinst_t;
199*25c28e83SPiotr Jasiukajtis 
200*25c28e83SPiotr Jasiukajtis /* x86-specific auxiliary functions */
201*25c28e83SPiotr Jasiukajtis extern int *__fex_accrued(void);
202*25c28e83SPiotr Jasiukajtis extern void __fex_get_x86_exc(siginfo_t *, ucontext_t *);
203*25c28e83SPiotr Jasiukajtis extern int __fex_parse_sse(ucontext_t *, sseinst_t *);
204*25c28e83SPiotr Jasiukajtis extern enum fex_exception __fex_get_sse_op(ucontext_t *, sseinst_t *,
205*25c28e83SPiotr Jasiukajtis 	fex_info_t *);
206*25c28e83SPiotr Jasiukajtis extern void __fex_get_simd_op(ucontext_t *, sseinst_t *,
207*25c28e83SPiotr Jasiukajtis 	enum fex_exception *, fex_info_t *);
208*25c28e83SPiotr Jasiukajtis extern void __fex_st_sse_result(ucontext_t *, sseinst_t *,
209*25c28e83SPiotr Jasiukajtis 	enum fex_exception, fex_info_t *);
210*25c28e83SPiotr Jasiukajtis extern void __fex_st_simd_result(ucontext_t *, sseinst_t *,
211*25c28e83SPiotr Jasiukajtis 	enum fex_exception *, fex_info_t *);
212*25c28e83SPiotr Jasiukajtis 
213*25c28e83SPiotr Jasiukajtis #else
214*25c28e83SPiotr Jasiukajtis #error Unknown architecture
215*25c28e83SPiotr Jasiukajtis #endif
216*25c28e83SPiotr Jasiukajtis 
217*25c28e83SPiotr Jasiukajtis #endif	/* _M9X_FEX_HANDLER_H */
218