summaryrefslogtreecommitdiff
path: root/usr/src/lib/libm/common/m9x/fex_handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libm/common/m9x/fex_handler.h')
-rw-r--r--usr/src/lib/libm/common/m9x/fex_handler.h217
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 */