--- /dev/null	Sat May 10 12:09:27 2014
+++ new/usr/src/lib/libm/common/m9x/fex_handler.h	Sat May 10 12:09:27 2014
@@ -0,0 +1,212 @@
+/*
+ * 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.
+ */
+
+/* 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
