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