diff options
Diffstat (limited to 'usr/src/lib/libm/common/m9x/fex_handler.h')
-rw-r--r-- | usr/src/lib/libm/common/m9x/fex_handler.h | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/usr/src/lib/libm/common/m9x/fex_handler.h b/usr/src/lib/libm/common/m9x/fex_handler.h new file mode 100644 index 0000000000..45f2d0713f --- /dev/null +++ b/usr/src/lib/libm/common/m9x/fex_handler.h @@ -0,0 +1,217 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _M9X_FEX_HANDLER_H +#define _M9X_FEX_HANDLER_H + +/* the following enums must match the bit positions in fenv.h */ +enum fex_exception { + fex_inexact = 0, + fex_division = 1, + fex_underflow = 2, + fex_overflow = 3, + fex_inv_zdz = 4, + fex_inv_idi = 5, + fex_inv_isi = 6, + fex_inv_zmi = 7, + fex_inv_sqrt = 8, + fex_inv_snan = 9, + fex_inv_int = 10, + fex_inv_cmp = 11 +}; + + +/* auxiliary functions in __fex_hdlr.c */ +extern struct fex_handler_data *__fex_get_thr_handlers(void); +extern void __fex_update_te(void); + +/* auxiliary functions in __fex_sym.c */ +extern void __fex_sym_init(void); +extern char *__fex_sym(char *, char **); + +/* auxiliary functions in fex_log.c */ +extern void __fex_mklog(ucontext_t *, char *, int, enum fex_exception, + int, void *); + +/* system-dependent auxiliary functions */ +extern enum fex_exception __fex_get_invalid_type(siginfo_t *, ucontext_t *); +extern void __fex_get_op(siginfo_t *, ucontext_t *, fex_info_t *); +extern void __fex_st_result(siginfo_t *, ucontext_t *, fex_info_t *); + +/* inline templates and macros for accessing fp state */ +extern void __fenv_getfsr(unsigned long *); +extern void __fenv_setfsr(const unsigned long *); + +#if defined(__sparc) + +#define __fenv_get_rd(X) ((X>>30)&0x3) +#define __fenv_set_rd(X,Y) X=(X&~0xc0000000ul)|((Y)<<30) + +#define __fenv_get_te(X) ((X>>23)&0x1f) +#define __fenv_set_te(X,Y) X=(X&~0x0f800000ul)|((Y)<<23) + +#define __fenv_get_ex(X) ((X>>5)&0x1f) +#define __fenv_set_ex(X,Y) X=(X&~0x000003e0ul)|((Y)<<5) + +#elif defined(__x86) + +extern void __fenv_getcwsw(unsigned int *); +extern void __fenv_setcwsw(const unsigned int *); + +extern void __fenv_getmxcsr(unsigned int *); +extern void __fenv_setmxcsr(const unsigned int *); + +#define __fenv_get_rd(X) ((X>>26)&3) +#define __fenv_set_rd(X,Y) X=(X&~0x0c000000)|((Y)<<26) + +#define __fenv_get_rp(X) ((X>>24)&3) +#define __fenv_set_rp(X,Y) X=(X&~0x03000000)|((Y)<<24) + +#define __fenv_get_te(X) ((X>>16)&0x3d) +#define __fenv_set_te(X,Y) X=(X&~0x003d0000)|((Y)<<16) + +#define __fenv_get_ex(X) (X&0x3d) +#define __fenv_set_ex(X,Y) X=(X&~0x0000003d)|(Y) + +/* + * These macros define some useful distinctions between various + * SSE instructions. In some cases, distinctions are made for + * the purpose of simplifying the decoding of instructions, while + * in other cases, they are made for the purpose of simplying the + * emulation. Note that these values serve as bit flags within + * the enum values in sseinst_t. + */ +#define DOUBLE 0x100 +#define SIMD 0x080 +#define INTREG 0x040 + +typedef union { + double d[2]; + long long l[2]; + float f[4]; + int i[4]; +} sseoperand_t; + +/* structure to hold a decoded SSE instruction */ +typedef struct { + enum { + /* single precision scalar instructions */ + cmpss = 0, + minss = 1, + maxss = 2, + addss = 3, + subss = 4, + mulss = 5, + divss = 6, + sqrtss = 7, + ucomiss = 16, + comiss = 17, + cvtss2sd = 32, + cvtsi2ss = INTREG + 0, + cvttss2si = INTREG + 1, + cvtss2si = INTREG + 2, + cvtsi2ssq = INTREG + 8, + cvttss2siq = INTREG + 9, + cvtss2siq = INTREG + 10, + + /* single precision SIMD instructions */ + cmpps = SIMD + 0, + minps = SIMD + 1, + maxps = SIMD + 2, + addps = SIMD + 3, + subps = SIMD + 4, + mulps = SIMD + 5, + divps = SIMD + 6, + sqrtps = SIMD + 7, + cvtps2pd = SIMD + 32, + cvtdq2ps = SIMD + 34, + cvttps2dq = SIMD + 35, + cvtps2dq = SIMD + 36, + cvtpi2ps = SIMD + INTREG + 0, + cvttps2pi = SIMD + INTREG + 1, + cvtps2pi = SIMD + INTREG + 2, + + /* double precision scalar instructions */ + cmpsd = DOUBLE + 0, + minsd = DOUBLE + 1, + maxsd = DOUBLE + 2, + addsd = DOUBLE + 3, + subsd = DOUBLE + 4, + mulsd = DOUBLE + 5, + divsd = DOUBLE + 6, + sqrtsd = DOUBLE + 7, + ucomisd = DOUBLE + 16, + comisd = DOUBLE + 17, + cvtsd2ss = DOUBLE + 32, + cvtsi2sd = DOUBLE + INTREG + 0, + cvttsd2si = DOUBLE + INTREG + 1, + cvtsd2si = DOUBLE + INTREG + 2, + cvtsi2sdq = DOUBLE + INTREG + 8, + cvttsd2siq = DOUBLE + INTREG + 9, + cvtsd2siq = DOUBLE + INTREG + 10, + + /* double precision SIMD instructions */ + cmppd = DOUBLE + SIMD + 0, + minpd = DOUBLE + SIMD + 1, + maxpd = DOUBLE + SIMD + 2, + addpd = DOUBLE + SIMD + 3, + subpd = DOUBLE + SIMD + 4, + mulpd = DOUBLE + SIMD + 5, + divpd = DOUBLE + SIMD + 6, + sqrtpd = DOUBLE + SIMD + 7, + cvtpd2ps = DOUBLE + SIMD + 32, + cvtdq2pd = DOUBLE + SIMD + 34, + cvttpd2dq = DOUBLE + SIMD + 35, + cvtpd2dq = DOUBLE + SIMD + 36, + cvtpi2pd = DOUBLE + SIMD + INTREG + 0, + cvttpd2pi = DOUBLE + SIMD + INTREG + 1, + cvtpd2pi = DOUBLE + SIMD + INTREG + 2, + } op; + int imm; + sseoperand_t *op1, *op2; +} sseinst_t; + +/* x86-specific auxiliary functions */ +extern int *__fex_accrued(void); +extern void __fex_get_x86_exc(siginfo_t *, ucontext_t *); +extern int __fex_parse_sse(ucontext_t *, sseinst_t *); +extern enum fex_exception __fex_get_sse_op(ucontext_t *, sseinst_t *, + fex_info_t *); +extern void __fex_get_simd_op(ucontext_t *, sseinst_t *, + enum fex_exception *, fex_info_t *); +extern void __fex_st_sse_result(ucontext_t *, sseinst_t *, + enum fex_exception, fex_info_t *); +extern void __fex_st_simd_result(ucontext_t *, sseinst_t *, + enum fex_exception *, fex_info_t *); + +#else +#error Unknown architecture +#endif + +#endif /* _M9X_FEX_HANDLER_H */ |