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 #include <sys/isa_defs.h> 34 35 /* the following enums must match the bit positions in fenv.h */ 36 enum fex_exception { 37 fex_inexact = 0, 38 fex_division = 1, 39 fex_underflow = 2, 40 fex_overflow = 3, 41 fex_inv_zdz = 4, 42 fex_inv_idi = 5, 43 fex_inv_isi = 6, 44 fex_inv_zmi = 7, 45 fex_inv_sqrt = 8, 46 fex_inv_snan = 9, 47 fex_inv_int = 10, 48 fex_inv_cmp = 11 49 }; 50 51 52 /* auxiliary functions in __fex_hdlr.c */ 53 extern struct fex_handler_data *__fex_get_thr_handlers(void); 54 extern void __fex_update_te(void); 55 56 /* auxiliary functions in __traceback.o */ 57 extern char *convert_address_to_symbol (char *address); 58 59 /* auxiliary functions in fex_log.c */ 60 extern void __fex_mklog(ucontext_t *, char *, int, enum fex_exception, 61 int, void *); 62 63 /* system-dependent auxiliary functions */ 64 extern enum fex_exception __fex_get_invalid_type(siginfo_t *, ucontext_t *); 65 extern void __fex_get_op(siginfo_t *, ucontext_t *, fex_info_t *); 66 extern void __fex_st_result(siginfo_t *, ucontext_t *, fex_info_t *); 67 68 /* inline templates and macros for accessing fp state */ 69 extern void __fenv_getfsr(unsigned long *); 70 extern void __fenv_setfsr(const unsigned long *); 71 72 #if defined(__sparc) 73 74 #define __fenv_get_rd(X) ((X>>30)&0x3) 75 #define __fenv_set_rd(X,Y) X=(X&~0xc0000000ul)|((Y)<<30) 76 77 #define __fenv_get_te(X) ((X>>23)&0x1f) 78 #define __fenv_set_te(X,Y) X=(X&~0x0f800000ul)|((Y)<<23) 79 80 #define __fenv_get_ex(X) ((X>>5)&0x1f) 81 #define __fenv_set_ex(X,Y) X=(X&~0x000003e0ul)|((Y)<<5) 82 83 #elif defined(__x86) 84 85 extern void __fenv_getcwsw(unsigned int *); 86 extern void __fenv_setcwsw(const unsigned int *); 87 88 extern void __fenv_getmxcsr(unsigned int *); 89 extern void __fenv_setmxcsr(const unsigned int *); 90 91 #define __fenv_get_rd(X) ((X>>26)&3) 92 #define __fenv_set_rd(X,Y) X=(X&~0x0c000000)|((Y)<<26) 93 94 #define __fenv_get_rp(X) ((X>>24)&3) 95 #define __fenv_set_rp(X,Y) X=(X&~0x03000000)|((Y)<<24) 96 97 #define __fenv_get_te(X) ((X>>16)&0x3d) 98 #define __fenv_set_te(X,Y) X=(X&~0x003d0000)|((Y)<<16) 99 100 #define __fenv_get_ex(X) (X&0x3d) 101 #define __fenv_set_ex(X,Y) X=(X&~0x0000003d)|(Y) 102 103 /* 104 * These macros define some useful distinctions between various 105 * SSE instructions. In some cases, distinctions are made for 106 * the purpose of simplifying the decoding of instructions, while 107 * in other cases, they are made for the purpose of simplying the 108 * emulation. Note that these values serve as bit flags within 109 * the enum values in sseinst_t. 110 */ 111 #define DOUBLE 0x100 112 #define SIMD 0x080 113 #define INTREG 0x040 114 115 typedef union { 116 double d[2]; 117 long long l[2]; 118 float f[4]; 119 int i[4]; 120 } sseoperand_t; 121 122 /* structure to hold a decoded SSE instruction */ 123 typedef struct { 124 enum { 125 /* single precision scalar instructions */ 126 cmpss = 0, 127 minss = 1, 128 maxss = 2, 129 addss = 3, 130 subss = 4, 131 mulss = 5, 132 divss = 6, 133 sqrtss = 7, 134 ucomiss = 16, 135 comiss = 17, 136 cvtss2sd = 32, 137 cvtsi2ss = INTREG + 0, 138 cvttss2si = INTREG + 1, 139 cvtss2si = INTREG + 2, 140 cvtsi2ssq = INTREG + 8, 141 cvttss2siq = INTREG + 9, 142 cvtss2siq = INTREG + 10, 143 144 /* single precision SIMD instructions */ 145 cmpps = SIMD + 0, 146 minps = SIMD + 1, 147 maxps = SIMD + 2, 148 addps = SIMD + 3, 149 subps = SIMD + 4, 150 mulps = SIMD + 5, 151 divps = SIMD + 6, 152 sqrtps = SIMD + 7, 153 cvtps2pd = SIMD + 32, 154 cvtdq2ps = SIMD + 34, 155 cvttps2dq = SIMD + 35, 156 cvtps2dq = SIMD + 36, 157 cvtpi2ps = SIMD + INTREG + 0, 158 cvttps2pi = SIMD + INTREG + 1, 159 cvtps2pi = SIMD + INTREG + 2, 160 161 /* double precision scalar instructions */ 162 cmpsd = DOUBLE + 0, 163 minsd = DOUBLE + 1, 164 maxsd = DOUBLE + 2, 165 addsd = DOUBLE + 3, 166 subsd = DOUBLE + 4, 167 mulsd = DOUBLE + 5, 168 divsd = DOUBLE + 6, 169 sqrtsd = DOUBLE + 7, 170 ucomisd = DOUBLE + 16, 171 comisd = DOUBLE + 17, 172 cvtsd2ss = DOUBLE + 32, 173 cvtsi2sd = DOUBLE + INTREG + 0, 174 cvttsd2si = DOUBLE + INTREG + 1, 175 cvtsd2si = DOUBLE + INTREG + 2, 176 cvtsi2sdq = DOUBLE + INTREG + 8, 177 cvttsd2siq = DOUBLE + INTREG + 9, 178 cvtsd2siq = DOUBLE + INTREG + 10, 179 180 /* double precision SIMD instructions */ 181 cmppd = DOUBLE + SIMD + 0, 182 minpd = DOUBLE + SIMD + 1, 183 maxpd = DOUBLE + SIMD + 2, 184 addpd = DOUBLE + SIMD + 3, 185 subpd = DOUBLE + SIMD + 4, 186 mulpd = DOUBLE + SIMD + 5, 187 divpd = DOUBLE + SIMD + 6, 188 sqrtpd = DOUBLE + SIMD + 7, 189 cvtpd2ps = DOUBLE + SIMD + 32, 190 cvtdq2pd = DOUBLE + SIMD + 34, 191 cvttpd2dq = DOUBLE + SIMD + 35, 192 cvtpd2dq = DOUBLE + SIMD + 36, 193 cvtpi2pd = DOUBLE + SIMD + INTREG + 0, 194 cvttpd2pi = DOUBLE + SIMD + INTREG + 1, 195 cvtpd2pi = DOUBLE + SIMD + INTREG + 2, 196 } op; 197 int imm; 198 sseoperand_t *op1, *op2; 199 } sseinst_t; 200 201 /* x86-specific auxiliary functions */ 202 extern int *__fex_accrued(void); 203 extern void __fex_get_x86_exc(siginfo_t *, ucontext_t *); 204 extern int __fex_parse_sse(ucontext_t *, sseinst_t *); 205 extern enum fex_exception __fex_get_sse_op(ucontext_t *, sseinst_t *, 206 fex_info_t *); 207 extern void __fex_get_simd_op(ucontext_t *, sseinst_t *, 208 enum fex_exception *, fex_info_t *); 209 extern void __fex_st_sse_result(ucontext_t *, sseinst_t *, 210 enum fex_exception, fex_info_t *); 211 extern void __fex_st_simd_result(ucontext_t *, sseinst_t *, 212 enum fex_exception *, fex_info_t *); 213 214 #else 215 #error Unknown architecture 216 #endif 217 218 #endif /* _M9X_FEX_HANDLER_H */ 219