1*25c28e83SPiotr Jasiukajtis /*
2*25c28e83SPiotr Jasiukajtis  * CDDL HEADER START
3*25c28e83SPiotr Jasiukajtis  *
4*25c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
5*25c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
6*25c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
7*25c28e83SPiotr Jasiukajtis  *
8*25c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*25c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
10*25c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
11*25c28e83SPiotr Jasiukajtis  * and limitations under the License.
12*25c28e83SPiotr Jasiukajtis  *
13*25c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
14*25c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*25c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
16*25c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
17*25c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
18*25c28e83SPiotr Jasiukajtis  *
19*25c28e83SPiotr Jasiukajtis  * CDDL HEADER END
20*25c28e83SPiotr Jasiukajtis  */
21*25c28e83SPiotr Jasiukajtis 
22*25c28e83SPiotr Jasiukajtis /*
23*25c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
24*25c28e83SPiotr Jasiukajtis  */
25*25c28e83SPiotr Jasiukajtis /*
26*25c28e83SPiotr Jasiukajtis  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27*25c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
28*25c28e83SPiotr Jasiukajtis  */
29*25c28e83SPiotr Jasiukajtis 
30*25c28e83SPiotr Jasiukajtis #include <ucontext.h>
31*25c28e83SPiotr Jasiukajtis #include <fenv.h>
32*25c28e83SPiotr Jasiukajtis #if defined(__SUNPRO_C)
33*25c28e83SPiotr Jasiukajtis #include <sunmath.h>
34*25c28e83SPiotr Jasiukajtis #else
35*25c28e83SPiotr Jasiukajtis #include <sys/ieeefp.h>
36*25c28e83SPiotr Jasiukajtis #endif
37*25c28e83SPiotr Jasiukajtis #include "fex_handler.h"
38*25c28e83SPiotr Jasiukajtis #include "fenv_inlines.h"
39*25c28e83SPiotr Jasiukajtis 
40*25c28e83SPiotr Jasiukajtis #if !defined(REG_PC)
41*25c28e83SPiotr Jasiukajtis #define REG_PC	EIP
42*25c28e83SPiotr Jasiukajtis #endif
43*25c28e83SPiotr Jasiukajtis 
44*25c28e83SPiotr Jasiukajtis #if !defined(REG_PS)
45*25c28e83SPiotr Jasiukajtis #define REG_PS	EFL
46*25c28e83SPiotr Jasiukajtis #endif
47*25c28e83SPiotr Jasiukajtis 
48*25c28e83SPiotr Jasiukajtis #ifdef __amd64
49*25c28e83SPiotr Jasiukajtis #define regno(X)	((X < 4)? REG_RAX - X : \
50*25c28e83SPiotr Jasiukajtis 			((X > 4)? REG_RAX + 1 - X : REG_RSP))
51*25c28e83SPiotr Jasiukajtis #else
52*25c28e83SPiotr Jasiukajtis #define regno(X)	(EAX - X)
53*25c28e83SPiotr Jasiukajtis #endif
54*25c28e83SPiotr Jasiukajtis 
55*25c28e83SPiotr Jasiukajtis /*
56*25c28e83SPiotr Jasiukajtis  * Support for SSE instructions
57*25c28e83SPiotr Jasiukajtis  */
58*25c28e83SPiotr Jasiukajtis 
59*25c28e83SPiotr Jasiukajtis /*
60*25c28e83SPiotr Jasiukajtis  * Decode an SSE instruction.  Fill in *inst and return the length of the
61*25c28e83SPiotr Jasiukajtis  * instruction in bytes.  Return 0 if the instruction is not recognized.
62*25c28e83SPiotr Jasiukajtis  */
63*25c28e83SPiotr Jasiukajtis int
__fex_parse_sse(ucontext_t * uap,sseinst_t * inst)64*25c28e83SPiotr Jasiukajtis __fex_parse_sse(ucontext_t *uap, sseinst_t *inst)
65*25c28e83SPiotr Jasiukajtis {
66*25c28e83SPiotr Jasiukajtis 	unsigned char	*ip;
67*25c28e83SPiotr Jasiukajtis 	char		*addr;
68*25c28e83SPiotr Jasiukajtis 	int		i, dbl, simd, rex, modrm, sib, r;
69*25c28e83SPiotr Jasiukajtis 
70*25c28e83SPiotr Jasiukajtis 	i = 0;
71*25c28e83SPiotr Jasiukajtis 	ip = (unsigned char *)uap->uc_mcontext.gregs[REG_PC];
72*25c28e83SPiotr Jasiukajtis 
73*25c28e83SPiotr Jasiukajtis 	/* look for pseudo-prefixes */
74*25c28e83SPiotr Jasiukajtis 	dbl = 0;
75*25c28e83SPiotr Jasiukajtis 	simd = SIMD;
76*25c28e83SPiotr Jasiukajtis 	if (ip[i] == 0xF3) {
77*25c28e83SPiotr Jasiukajtis 		simd = 0;
78*25c28e83SPiotr Jasiukajtis 		i++;
79*25c28e83SPiotr Jasiukajtis 	} else if (ip[i] == 0x66) {
80*25c28e83SPiotr Jasiukajtis 		dbl = DOUBLE;
81*25c28e83SPiotr Jasiukajtis 		i++;
82*25c28e83SPiotr Jasiukajtis 	} else if (ip[i] == 0xF2) {
83*25c28e83SPiotr Jasiukajtis 		dbl = DOUBLE;
84*25c28e83SPiotr Jasiukajtis 		simd = 0;
85*25c28e83SPiotr Jasiukajtis 		i++;
86*25c28e83SPiotr Jasiukajtis 	}
87*25c28e83SPiotr Jasiukajtis 
88*25c28e83SPiotr Jasiukajtis 	/* look for AMD64 REX prefix */
89*25c28e83SPiotr Jasiukajtis 	rex = 0;
90*25c28e83SPiotr Jasiukajtis 	if (ip[i] >= 0x40 && ip[i] <= 0x4F) {
91*25c28e83SPiotr Jasiukajtis 		rex = ip[i];
92*25c28e83SPiotr Jasiukajtis 		i++;
93*25c28e83SPiotr Jasiukajtis 	}
94*25c28e83SPiotr Jasiukajtis 
95*25c28e83SPiotr Jasiukajtis 	/* parse opcode */
96*25c28e83SPiotr Jasiukajtis 	if (ip[i++] != 0x0F)
97*25c28e83SPiotr Jasiukajtis 		return 0;
98*25c28e83SPiotr Jasiukajtis 	switch (ip[i++]) {
99*25c28e83SPiotr Jasiukajtis 	case 0x2A:
100*25c28e83SPiotr Jasiukajtis 		inst->op = (int)cvtsi2ss + simd + dbl;
101*25c28e83SPiotr Jasiukajtis 		if (!simd)
102*25c28e83SPiotr Jasiukajtis 			inst->op = (int)inst->op + (rex & 8);
103*25c28e83SPiotr Jasiukajtis 		break;
104*25c28e83SPiotr Jasiukajtis 
105*25c28e83SPiotr Jasiukajtis 	case 0x2C:
106*25c28e83SPiotr Jasiukajtis 		inst->op = (int)cvttss2si + simd + dbl;
107*25c28e83SPiotr Jasiukajtis 		if (!simd)
108*25c28e83SPiotr Jasiukajtis 			inst->op = (int)inst->op + (rex & 8);
109*25c28e83SPiotr Jasiukajtis 		break;
110*25c28e83SPiotr Jasiukajtis 
111*25c28e83SPiotr Jasiukajtis 	case 0x2D:
112*25c28e83SPiotr Jasiukajtis 		inst->op = (int)cvtss2si + simd + dbl;
113*25c28e83SPiotr Jasiukajtis 		if (!simd)
114*25c28e83SPiotr Jasiukajtis 			inst->op = (int)inst->op + (rex & 8);
115*25c28e83SPiotr Jasiukajtis 		break;
116*25c28e83SPiotr Jasiukajtis 
117*25c28e83SPiotr Jasiukajtis 	case 0x2E:
118*25c28e83SPiotr Jasiukajtis 		/* oddball: scalar instruction in a SIMD opcode group */
119*25c28e83SPiotr Jasiukajtis 		if (!simd)
120*25c28e83SPiotr Jasiukajtis 			return 0;
121*25c28e83SPiotr Jasiukajtis 		inst->op = (int)ucomiss + dbl;
122*25c28e83SPiotr Jasiukajtis 		break;
123*25c28e83SPiotr Jasiukajtis 
124*25c28e83SPiotr Jasiukajtis 	case 0x2F:
125*25c28e83SPiotr Jasiukajtis 		/* oddball: scalar instruction in a SIMD opcode group */
126*25c28e83SPiotr Jasiukajtis 		if (!simd)
127*25c28e83SPiotr Jasiukajtis 			return 0;
128*25c28e83SPiotr Jasiukajtis 		inst->op = (int)comiss + dbl;
129*25c28e83SPiotr Jasiukajtis 		break;
130*25c28e83SPiotr Jasiukajtis 
131*25c28e83SPiotr Jasiukajtis 	case 0x51:
132*25c28e83SPiotr Jasiukajtis 		inst->op = (int)sqrtss + simd + dbl;
133*25c28e83SPiotr Jasiukajtis 		break;
134*25c28e83SPiotr Jasiukajtis 
135*25c28e83SPiotr Jasiukajtis 	case 0x58:
136*25c28e83SPiotr Jasiukajtis 		inst->op = (int)addss + simd + dbl;
137*25c28e83SPiotr Jasiukajtis 		break;
138*25c28e83SPiotr Jasiukajtis 
139*25c28e83SPiotr Jasiukajtis 	case 0x59:
140*25c28e83SPiotr Jasiukajtis 		inst->op = (int)mulss + simd + dbl;
141*25c28e83SPiotr Jasiukajtis 		break;
142*25c28e83SPiotr Jasiukajtis 
143*25c28e83SPiotr Jasiukajtis 	case 0x5A:
144*25c28e83SPiotr Jasiukajtis 		inst->op = (int)cvtss2sd + simd + dbl;
145*25c28e83SPiotr Jasiukajtis 		break;
146*25c28e83SPiotr Jasiukajtis 
147*25c28e83SPiotr Jasiukajtis 	case 0x5B:
148*25c28e83SPiotr Jasiukajtis 		if (dbl) {
149*25c28e83SPiotr Jasiukajtis 			if (simd)
150*25c28e83SPiotr Jasiukajtis 				inst->op = cvtps2dq;
151*25c28e83SPiotr Jasiukajtis 			else
152*25c28e83SPiotr Jasiukajtis 				return 0;
153*25c28e83SPiotr Jasiukajtis 		} else {
154*25c28e83SPiotr Jasiukajtis 			inst->op = (simd)? cvtdq2ps : cvttps2dq;
155*25c28e83SPiotr Jasiukajtis 		}
156*25c28e83SPiotr Jasiukajtis 		break;
157*25c28e83SPiotr Jasiukajtis 
158*25c28e83SPiotr Jasiukajtis 	case 0x5C:
159*25c28e83SPiotr Jasiukajtis 		inst->op = (int)subss + simd + dbl;
160*25c28e83SPiotr Jasiukajtis 		break;
161*25c28e83SPiotr Jasiukajtis 
162*25c28e83SPiotr Jasiukajtis 	case 0x5D:
163*25c28e83SPiotr Jasiukajtis 		inst->op = (int)minss + simd + dbl;
164*25c28e83SPiotr Jasiukajtis 		break;
165*25c28e83SPiotr Jasiukajtis 
166*25c28e83SPiotr Jasiukajtis 	case 0x5E:
167*25c28e83SPiotr Jasiukajtis 		inst->op = (int)divss + simd + dbl;
168*25c28e83SPiotr Jasiukajtis 		break;
169*25c28e83SPiotr Jasiukajtis 
170*25c28e83SPiotr Jasiukajtis 	case 0x5F:
171*25c28e83SPiotr Jasiukajtis 		inst->op = (int)maxss + simd + dbl;
172*25c28e83SPiotr Jasiukajtis 		break;
173*25c28e83SPiotr Jasiukajtis 
174*25c28e83SPiotr Jasiukajtis 	case 0xC2:
175*25c28e83SPiotr Jasiukajtis 		inst->op = (int)cmpss + simd + dbl;
176*25c28e83SPiotr Jasiukajtis 		break;
177*25c28e83SPiotr Jasiukajtis 
178*25c28e83SPiotr Jasiukajtis 	case 0xE6:
179*25c28e83SPiotr Jasiukajtis 		if (simd) {
180*25c28e83SPiotr Jasiukajtis 			if (dbl)
181*25c28e83SPiotr Jasiukajtis 				inst->op = cvttpd2dq;
182*25c28e83SPiotr Jasiukajtis 			else
183*25c28e83SPiotr Jasiukajtis 				return 0;
184*25c28e83SPiotr Jasiukajtis 		} else {
185*25c28e83SPiotr Jasiukajtis 			inst->op = (dbl)? cvtpd2dq : cvtdq2pd;
186*25c28e83SPiotr Jasiukajtis 		}
187*25c28e83SPiotr Jasiukajtis 		break;
188*25c28e83SPiotr Jasiukajtis 
189*25c28e83SPiotr Jasiukajtis 	default:
190*25c28e83SPiotr Jasiukajtis 		return 0;
191*25c28e83SPiotr Jasiukajtis 	}
192*25c28e83SPiotr Jasiukajtis 
193*25c28e83SPiotr Jasiukajtis 	/* locate operands */
194*25c28e83SPiotr Jasiukajtis 	modrm = ip[i++];
195*25c28e83SPiotr Jasiukajtis 
196*25c28e83SPiotr Jasiukajtis 	if (inst->op == cvtss2si || inst->op == cvttss2si ||
197*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtsd2si || inst->op == cvttsd2si ||
198*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtss2siq || inst->op == cvttss2siq ||
199*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtsd2siq || inst->op == cvttsd2siq) {
200*25c28e83SPiotr Jasiukajtis 		/* op1 is a gp register */
201*25c28e83SPiotr Jasiukajtis 		r = ((rex & 4) << 1) | ((modrm >> 3) & 7);
202*25c28e83SPiotr Jasiukajtis 		inst->op1 = (sseoperand_t *)&uap->uc_mcontext.gregs[regno(r)];
203*25c28e83SPiotr Jasiukajtis 	} else if (inst->op == cvtps2pi || inst->op == cvttps2pi ||
204*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtpd2pi || inst->op == cvttpd2pi) {
205*25c28e83SPiotr Jasiukajtis 		/* op1 is a mmx register */
206*25c28e83SPiotr Jasiukajtis #ifdef __amd64
207*25c28e83SPiotr Jasiukajtis 		inst->op1 = (sseoperand_t *)&uap->uc_mcontext.fpregs.fp_reg_set.
208*25c28e83SPiotr Jasiukajtis 		    fpchip_state.st[(modrm >> 3) & 7];
209*25c28e83SPiotr Jasiukajtis #else
210*25c28e83SPiotr Jasiukajtis 		inst->op1 = (sseoperand_t *)(10 * ((modrm >> 3) & 7) +
211*25c28e83SPiotr Jasiukajtis 		    (char *)&uap->uc_mcontext.fpregs.fp_reg_set.
212*25c28e83SPiotr Jasiukajtis 		    fpchip_state.state[7]);
213*25c28e83SPiotr Jasiukajtis #endif
214*25c28e83SPiotr Jasiukajtis 	} else {
215*25c28e83SPiotr Jasiukajtis 		/* op1 is a xmm register */
216*25c28e83SPiotr Jasiukajtis 		r = ((rex & 4) << 1) | ((modrm >> 3) & 7);
217*25c28e83SPiotr Jasiukajtis 		inst->op1 = (sseoperand_t *)&uap->uc_mcontext.fpregs.
218*25c28e83SPiotr Jasiukajtis 		    fp_reg_set.fpchip_state.xmm[r];
219*25c28e83SPiotr Jasiukajtis 	}
220*25c28e83SPiotr Jasiukajtis 
221*25c28e83SPiotr Jasiukajtis 	if ((modrm >> 6) == 3) {
222*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvtsi2ss || inst->op == cvtsi2sd ||
223*25c28e83SPiotr Jasiukajtis 		    inst->op == cvtsi2ssq || inst->op == cvtsi2sdq) {
224*25c28e83SPiotr Jasiukajtis 			/* op2 is a gp register */
225*25c28e83SPiotr Jasiukajtis 			r = ((rex & 1) << 3) | (modrm & 7);
226*25c28e83SPiotr Jasiukajtis 			inst->op2 = (sseoperand_t *)&uap->uc_mcontext.
227*25c28e83SPiotr Jasiukajtis 			    gregs[regno(r)];
228*25c28e83SPiotr Jasiukajtis 		} else if (inst->op == cvtpi2ps || inst->op == cvtpi2pd) {
229*25c28e83SPiotr Jasiukajtis 			/* op2 is a mmx register */
230*25c28e83SPiotr Jasiukajtis #ifdef __amd64
231*25c28e83SPiotr Jasiukajtis 			inst->op2 = (sseoperand_t *)&uap->uc_mcontext.fpregs.
232*25c28e83SPiotr Jasiukajtis 			    fp_reg_set.fpchip_state.st[modrm & 7];
233*25c28e83SPiotr Jasiukajtis #else
234*25c28e83SPiotr Jasiukajtis 			inst->op2 = (sseoperand_t *)(10 * (modrm & 7) +
235*25c28e83SPiotr Jasiukajtis 			    (char *)&uap->uc_mcontext.fpregs.fp_reg_set.
236*25c28e83SPiotr Jasiukajtis 			    fpchip_state.state[7]);
237*25c28e83SPiotr Jasiukajtis #endif
238*25c28e83SPiotr Jasiukajtis 		} else {
239*25c28e83SPiotr Jasiukajtis 			/* op2 is a xmm register */
240*25c28e83SPiotr Jasiukajtis 			r = ((rex & 1) << 3) | (modrm & 7);
241*25c28e83SPiotr Jasiukajtis 			inst->op2 = (sseoperand_t *)&uap->uc_mcontext.fpregs.
242*25c28e83SPiotr Jasiukajtis 			    fp_reg_set.fpchip_state.xmm[r];
243*25c28e83SPiotr Jasiukajtis 		}
244*25c28e83SPiotr Jasiukajtis 	} else if ((modrm & 0xc7) == 0x05) {
245*25c28e83SPiotr Jasiukajtis #ifdef __amd64
246*25c28e83SPiotr Jasiukajtis 		/* address of next instruction + offset */
247*25c28e83SPiotr Jasiukajtis 		r = i + 4;
248*25c28e83SPiotr Jasiukajtis 		if (inst->op == cmpss || inst->op == cmpps ||
249*25c28e83SPiotr Jasiukajtis 		    inst->op == cmpsd || inst->op == cmppd)
250*25c28e83SPiotr Jasiukajtis 			r++;
251*25c28e83SPiotr Jasiukajtis 		inst->op2 = (sseoperand_t *)(ip + r + *(int *)(ip + i));
252*25c28e83SPiotr Jasiukajtis #else
253*25c28e83SPiotr Jasiukajtis 		/* absolute address */
254*25c28e83SPiotr Jasiukajtis 		inst->op2 = (sseoperand_t *)(*(int *)(ip + i));
255*25c28e83SPiotr Jasiukajtis #endif
256*25c28e83SPiotr Jasiukajtis 		i += 4;
257*25c28e83SPiotr Jasiukajtis 	} else {
258*25c28e83SPiotr Jasiukajtis 		/* complex address */
259*25c28e83SPiotr Jasiukajtis 		if ((modrm & 7) == 4) {
260*25c28e83SPiotr Jasiukajtis 			/* parse sib byte */
261*25c28e83SPiotr Jasiukajtis 			sib = ip[i++];
262*25c28e83SPiotr Jasiukajtis 			if ((sib & 7) == 5 && (modrm >> 6) == 0) {
263*25c28e83SPiotr Jasiukajtis 				/* start with absolute address */
264*25c28e83SPiotr Jasiukajtis 				addr = (char *)(uintptr_t)(*(int *)(ip + i));
265*25c28e83SPiotr Jasiukajtis 				i += 4;
266*25c28e83SPiotr Jasiukajtis 			} else {
267*25c28e83SPiotr Jasiukajtis 				/* start with base */
268*25c28e83SPiotr Jasiukajtis 				r = ((rex & 1) << 3) | (sib & 7);
269*25c28e83SPiotr Jasiukajtis 				addr = (char *)uap->uc_mcontext.gregs[regno(r)];
270*25c28e83SPiotr Jasiukajtis 			}
271*25c28e83SPiotr Jasiukajtis 			r = ((rex & 2) << 2) | ((sib >> 3) & 7);
272*25c28e83SPiotr Jasiukajtis 			if (r != 4) {
273*25c28e83SPiotr Jasiukajtis 				/* add scaled index */
274*25c28e83SPiotr Jasiukajtis 				addr += uap->uc_mcontext.gregs[regno(r)]
275*25c28e83SPiotr Jasiukajtis 				    << (sib >> 6);
276*25c28e83SPiotr Jasiukajtis 			}
277*25c28e83SPiotr Jasiukajtis 		} else {
278*25c28e83SPiotr Jasiukajtis 			r = ((rex & 1) << 3) | (modrm & 7);
279*25c28e83SPiotr Jasiukajtis 			addr = (char *)uap->uc_mcontext.gregs[regno(r)];
280*25c28e83SPiotr Jasiukajtis 		}
281*25c28e83SPiotr Jasiukajtis 
282*25c28e83SPiotr Jasiukajtis 		/* add displacement, if any */
283*25c28e83SPiotr Jasiukajtis 		if ((modrm >> 6) == 1) {
284*25c28e83SPiotr Jasiukajtis 			addr += (char)ip[i++];
285*25c28e83SPiotr Jasiukajtis 		} else if ((modrm >> 6) == 2) {
286*25c28e83SPiotr Jasiukajtis 			addr += *(int *)(ip + i);
287*25c28e83SPiotr Jasiukajtis 			i += 4;
288*25c28e83SPiotr Jasiukajtis 		}
289*25c28e83SPiotr Jasiukajtis 		inst->op2 = (sseoperand_t *)addr;
290*25c28e83SPiotr Jasiukajtis 	}
291*25c28e83SPiotr Jasiukajtis 
292*25c28e83SPiotr Jasiukajtis 	if (inst->op == cmpss || inst->op == cmpps || inst->op == cmpsd ||
293*25c28e83SPiotr Jasiukajtis 	    inst->op == cmppd) {
294*25c28e83SPiotr Jasiukajtis 		/* get the immediate operand */
295*25c28e83SPiotr Jasiukajtis 		inst->imm = ip[i++];
296*25c28e83SPiotr Jasiukajtis 	}
297*25c28e83SPiotr Jasiukajtis 
298*25c28e83SPiotr Jasiukajtis 	return i;
299*25c28e83SPiotr Jasiukajtis }
300*25c28e83SPiotr Jasiukajtis 
301*25c28e83SPiotr Jasiukajtis static enum fp_class_type
my_fp_classf(float * x)302*25c28e83SPiotr Jasiukajtis my_fp_classf(float *x)
303*25c28e83SPiotr Jasiukajtis {
304*25c28e83SPiotr Jasiukajtis 	int	i = *(int *)x & ~0x80000000;
305*25c28e83SPiotr Jasiukajtis 
306*25c28e83SPiotr Jasiukajtis 	if (i < 0x7f800000) {
307*25c28e83SPiotr Jasiukajtis 		if (i < 0x00800000)
308*25c28e83SPiotr Jasiukajtis 			return ((i == 0)? fp_zero : fp_subnormal);
309*25c28e83SPiotr Jasiukajtis 		return fp_normal;
310*25c28e83SPiotr Jasiukajtis 	}
311*25c28e83SPiotr Jasiukajtis 	else if (i == 0x7f800000)
312*25c28e83SPiotr Jasiukajtis 		return fp_infinity;
313*25c28e83SPiotr Jasiukajtis 	else if (i & 0x400000)
314*25c28e83SPiotr Jasiukajtis 		return fp_quiet;
315*25c28e83SPiotr Jasiukajtis 	else
316*25c28e83SPiotr Jasiukajtis 		return fp_signaling;
317*25c28e83SPiotr Jasiukajtis }
318*25c28e83SPiotr Jasiukajtis 
319*25c28e83SPiotr Jasiukajtis static enum fp_class_type
my_fp_class(double * x)320*25c28e83SPiotr Jasiukajtis my_fp_class(double *x)
321*25c28e83SPiotr Jasiukajtis {
322*25c28e83SPiotr Jasiukajtis 	int	i = *(1+(int *)x) & ~0x80000000;
323*25c28e83SPiotr Jasiukajtis 
324*25c28e83SPiotr Jasiukajtis 	if (i < 0x7ff00000) {
325*25c28e83SPiotr Jasiukajtis 		if (i < 0x00100000)
326*25c28e83SPiotr Jasiukajtis 			return (((i | *(int *)x) == 0)? fp_zero : fp_subnormal);
327*25c28e83SPiotr Jasiukajtis 		return fp_normal;
328*25c28e83SPiotr Jasiukajtis 	}
329*25c28e83SPiotr Jasiukajtis 	else if (i == 0x7ff00000 && *(int *)x == 0)
330*25c28e83SPiotr Jasiukajtis 		return fp_infinity;
331*25c28e83SPiotr Jasiukajtis 	else if (i & 0x80000)
332*25c28e83SPiotr Jasiukajtis 		return fp_quiet;
333*25c28e83SPiotr Jasiukajtis 	else
334*25c28e83SPiotr Jasiukajtis 		return fp_signaling;
335*25c28e83SPiotr Jasiukajtis }
336*25c28e83SPiotr Jasiukajtis 
337*25c28e83SPiotr Jasiukajtis /*
338*25c28e83SPiotr Jasiukajtis  * Inspect a scalar SSE instruction that incurred an invalid operation
339*25c28e83SPiotr Jasiukajtis  * exception to determine which type of exception it was.
340*25c28e83SPiotr Jasiukajtis  */
341*25c28e83SPiotr Jasiukajtis static enum fex_exception
__fex_get_sse_invalid_type(sseinst_t * inst)342*25c28e83SPiotr Jasiukajtis __fex_get_sse_invalid_type(sseinst_t *inst)
343*25c28e83SPiotr Jasiukajtis {
344*25c28e83SPiotr Jasiukajtis 	enum fp_class_type	t1, t2;
345*25c28e83SPiotr Jasiukajtis 
346*25c28e83SPiotr Jasiukajtis 	/* check op2 for signaling nan */
347*25c28e83SPiotr Jasiukajtis 	t2 = ((int)inst->op & DOUBLE)? my_fp_class(&inst->op2->d[0]) :
348*25c28e83SPiotr Jasiukajtis 	    my_fp_classf(&inst->op2->f[0]);
349*25c28e83SPiotr Jasiukajtis 	if (t2 == fp_signaling)
350*25c28e83SPiotr Jasiukajtis 		return fex_inv_snan;
351*25c28e83SPiotr Jasiukajtis 
352*25c28e83SPiotr Jasiukajtis 	/* eliminate all single-operand instructions */
353*25c28e83SPiotr Jasiukajtis 	switch (inst->op) {
354*25c28e83SPiotr Jasiukajtis 	case cvtsd2ss:
355*25c28e83SPiotr Jasiukajtis 	case cvtss2sd:
356*25c28e83SPiotr Jasiukajtis 		/* hmm, this shouldn't have happened */
357*25c28e83SPiotr Jasiukajtis 		return (enum fex_exception) -1;
358*25c28e83SPiotr Jasiukajtis 
359*25c28e83SPiotr Jasiukajtis 	case sqrtss:
360*25c28e83SPiotr Jasiukajtis 	case sqrtsd:
361*25c28e83SPiotr Jasiukajtis 		return fex_inv_sqrt;
362*25c28e83SPiotr Jasiukajtis 
363*25c28e83SPiotr Jasiukajtis 	case cvtss2si:
364*25c28e83SPiotr Jasiukajtis 	case cvtsd2si:
365*25c28e83SPiotr Jasiukajtis 	case cvttss2si:
366*25c28e83SPiotr Jasiukajtis 	case cvttsd2si:
367*25c28e83SPiotr Jasiukajtis 	case cvtss2siq:
368*25c28e83SPiotr Jasiukajtis 	case cvtsd2siq:
369*25c28e83SPiotr Jasiukajtis 	case cvttss2siq:
370*25c28e83SPiotr Jasiukajtis 	case cvttsd2siq:
371*25c28e83SPiotr Jasiukajtis 		return fex_inv_int;
372*25c28e83SPiotr Jasiukajtis 	default:
373*25c28e83SPiotr Jasiukajtis 		break;
374*25c28e83SPiotr Jasiukajtis 	}
375*25c28e83SPiotr Jasiukajtis 
376*25c28e83SPiotr Jasiukajtis 	/* check op1 for signaling nan */
377*25c28e83SPiotr Jasiukajtis 	t1 = ((int)inst->op & DOUBLE)? my_fp_class(&inst->op1->d[0]) :
378*25c28e83SPiotr Jasiukajtis 	    my_fp_classf(&inst->op1->f[0]);
379*25c28e83SPiotr Jasiukajtis 	if (t1 == fp_signaling)
380*25c28e83SPiotr Jasiukajtis 		return fex_inv_snan;
381*25c28e83SPiotr Jasiukajtis 
382*25c28e83SPiotr Jasiukajtis 	/* check two-operand instructions for other cases */
383*25c28e83SPiotr Jasiukajtis 	switch (inst->op) {
384*25c28e83SPiotr Jasiukajtis 	case cmpss:
385*25c28e83SPiotr Jasiukajtis 	case cmpsd:
386*25c28e83SPiotr Jasiukajtis 	case minss:
387*25c28e83SPiotr Jasiukajtis 	case minsd:
388*25c28e83SPiotr Jasiukajtis 	case maxss:
389*25c28e83SPiotr Jasiukajtis 	case maxsd:
390*25c28e83SPiotr Jasiukajtis 	case comiss:
391*25c28e83SPiotr Jasiukajtis 	case comisd:
392*25c28e83SPiotr Jasiukajtis 		return fex_inv_cmp;
393*25c28e83SPiotr Jasiukajtis 
394*25c28e83SPiotr Jasiukajtis 	case addss:
395*25c28e83SPiotr Jasiukajtis 	case addsd:
396*25c28e83SPiotr Jasiukajtis 	case subss:
397*25c28e83SPiotr Jasiukajtis 	case subsd:
398*25c28e83SPiotr Jasiukajtis 		if (t1 == fp_infinity && t2 == fp_infinity)
399*25c28e83SPiotr Jasiukajtis 			return fex_inv_isi;
400*25c28e83SPiotr Jasiukajtis 		break;
401*25c28e83SPiotr Jasiukajtis 
402*25c28e83SPiotr Jasiukajtis 	case mulss:
403*25c28e83SPiotr Jasiukajtis 	case mulsd:
404*25c28e83SPiotr Jasiukajtis 		if ((t1 == fp_zero && t2 == fp_infinity) ||
405*25c28e83SPiotr Jasiukajtis 		    (t2 == fp_zero && t1 == fp_infinity))
406*25c28e83SPiotr Jasiukajtis 			return fex_inv_zmi;
407*25c28e83SPiotr Jasiukajtis 		break;
408*25c28e83SPiotr Jasiukajtis 
409*25c28e83SPiotr Jasiukajtis 	case divss:
410*25c28e83SPiotr Jasiukajtis 	case divsd:
411*25c28e83SPiotr Jasiukajtis 		if (t1 == fp_zero && t2 == fp_zero)
412*25c28e83SPiotr Jasiukajtis 			return fex_inv_zdz;
413*25c28e83SPiotr Jasiukajtis 		if (t1 == fp_infinity && t2 == fp_infinity)
414*25c28e83SPiotr Jasiukajtis 			return fex_inv_idi;
415*25c28e83SPiotr Jasiukajtis 	default:
416*25c28e83SPiotr Jasiukajtis 		break;
417*25c28e83SPiotr Jasiukajtis 	}
418*25c28e83SPiotr Jasiukajtis 
419*25c28e83SPiotr Jasiukajtis 	return (enum fex_exception)-1;
420*25c28e83SPiotr Jasiukajtis }
421*25c28e83SPiotr Jasiukajtis 
422*25c28e83SPiotr Jasiukajtis /* inline templates */
423*25c28e83SPiotr Jasiukajtis extern void sse_cmpeqss(float *, float *, int *);
424*25c28e83SPiotr Jasiukajtis extern void sse_cmpltss(float *, float *, int *);
425*25c28e83SPiotr Jasiukajtis extern void sse_cmpless(float *, float *, int *);
426*25c28e83SPiotr Jasiukajtis extern void sse_cmpunordss(float *, float *, int *);
427*25c28e83SPiotr Jasiukajtis extern void sse_minss(float *, float *, float *);
428*25c28e83SPiotr Jasiukajtis extern void sse_maxss(float *, float *, float *);
429*25c28e83SPiotr Jasiukajtis extern void sse_addss(float *, float *, float *);
430*25c28e83SPiotr Jasiukajtis extern void sse_subss(float *, float *, float *);
431*25c28e83SPiotr Jasiukajtis extern void sse_mulss(float *, float *, float *);
432*25c28e83SPiotr Jasiukajtis extern void sse_divss(float *, float *, float *);
433*25c28e83SPiotr Jasiukajtis extern void sse_sqrtss(float *, float *);
434*25c28e83SPiotr Jasiukajtis extern void sse_ucomiss(float *, float *);
435*25c28e83SPiotr Jasiukajtis extern void sse_comiss(float *, float *);
436*25c28e83SPiotr Jasiukajtis extern void sse_cvtss2sd(float *, double *);
437*25c28e83SPiotr Jasiukajtis extern void sse_cvtsi2ss(int *, float *);
438*25c28e83SPiotr Jasiukajtis extern void sse_cvttss2si(float *, int *);
439*25c28e83SPiotr Jasiukajtis extern void sse_cvtss2si(float *, int *);
440*25c28e83SPiotr Jasiukajtis #ifdef __amd64
441*25c28e83SPiotr Jasiukajtis extern void sse_cvtsi2ssq(long long *, float *);
442*25c28e83SPiotr Jasiukajtis extern void sse_cvttss2siq(float *, long long *);
443*25c28e83SPiotr Jasiukajtis extern void sse_cvtss2siq(float *, long long *);
444*25c28e83SPiotr Jasiukajtis #endif
445*25c28e83SPiotr Jasiukajtis extern void sse_cmpeqsd(double *, double *, long long *);
446*25c28e83SPiotr Jasiukajtis extern void sse_cmpltsd(double *, double *, long long *);
447*25c28e83SPiotr Jasiukajtis extern void sse_cmplesd(double *, double *, long long *);
448*25c28e83SPiotr Jasiukajtis extern void sse_cmpunordsd(double *, double *, long long *);
449*25c28e83SPiotr Jasiukajtis extern void sse_minsd(double *, double *, double *);
450*25c28e83SPiotr Jasiukajtis extern void sse_maxsd(double *, double *, double *);
451*25c28e83SPiotr Jasiukajtis extern void sse_addsd(double *, double *, double *);
452*25c28e83SPiotr Jasiukajtis extern void sse_subsd(double *, double *, double *);
453*25c28e83SPiotr Jasiukajtis extern void sse_mulsd(double *, double *, double *);
454*25c28e83SPiotr Jasiukajtis extern void sse_divsd(double *, double *, double *);
455*25c28e83SPiotr Jasiukajtis extern void sse_sqrtsd(double *, double *);
456*25c28e83SPiotr Jasiukajtis extern void sse_ucomisd(double *, double *);
457*25c28e83SPiotr Jasiukajtis extern void sse_comisd(double *, double *);
458*25c28e83SPiotr Jasiukajtis extern void sse_cvtsd2ss(double *, float *);
459*25c28e83SPiotr Jasiukajtis extern void sse_cvtsi2sd(int *, double *);
460*25c28e83SPiotr Jasiukajtis extern void sse_cvttsd2si(double *, int *);
461*25c28e83SPiotr Jasiukajtis extern void sse_cvtsd2si(double *, int *);
462*25c28e83SPiotr Jasiukajtis #ifdef __amd64
463*25c28e83SPiotr Jasiukajtis extern void sse_cvtsi2sdq(long long *, double *);
464*25c28e83SPiotr Jasiukajtis extern void sse_cvttsd2siq(double *, long long *);
465*25c28e83SPiotr Jasiukajtis extern void sse_cvtsd2siq(double *, long long *);
466*25c28e83SPiotr Jasiukajtis #endif
467*25c28e83SPiotr Jasiukajtis 
468*25c28e83SPiotr Jasiukajtis /*
469*25c28e83SPiotr Jasiukajtis  * Fill in *info with the operands, default untrapped result, and
470*25c28e83SPiotr Jasiukajtis  * flags produced by a scalar SSE instruction, and return the type
471*25c28e83SPiotr Jasiukajtis  * of trapped exception (if any).  On entry, the mxcsr must have
472*25c28e83SPiotr Jasiukajtis  * all exceptions masked and all flags clear.  The same conditions
473*25c28e83SPiotr Jasiukajtis  * will hold on exit.
474*25c28e83SPiotr Jasiukajtis  *
475*25c28e83SPiotr Jasiukajtis  * This routine does not work if the instruction specified by *inst
476*25c28e83SPiotr Jasiukajtis  * is not a scalar instruction.
477*25c28e83SPiotr Jasiukajtis  */
478*25c28e83SPiotr Jasiukajtis enum fex_exception
__fex_get_sse_op(ucontext_t * uap,sseinst_t * inst,fex_info_t * info)479*25c28e83SPiotr Jasiukajtis __fex_get_sse_op(ucontext_t *uap, sseinst_t *inst, fex_info_t *info)
480*25c28e83SPiotr Jasiukajtis {
481*25c28e83SPiotr Jasiukajtis 	unsigned int	e, te, mxcsr, oldmxcsr, subnorm;
482*25c28e83SPiotr Jasiukajtis 
483*25c28e83SPiotr Jasiukajtis 	/*
484*25c28e83SPiotr Jasiukajtis 	 * Perform the operation with traps disabled and check the
485*25c28e83SPiotr Jasiukajtis 	 * exception flags.  If the underflow trap was enabled, also
486*25c28e83SPiotr Jasiukajtis 	 * check for an exact subnormal result.
487*25c28e83SPiotr Jasiukajtis 	 */
488*25c28e83SPiotr Jasiukajtis 	__fenv_getmxcsr(&oldmxcsr);
489*25c28e83SPiotr Jasiukajtis 	subnorm = 0;
490*25c28e83SPiotr Jasiukajtis 	if ((int)inst->op & DOUBLE) {
491*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvtsi2sd) {
492*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_int;
493*25c28e83SPiotr Jasiukajtis 			info->op1.val.i = inst->op2->i[0];
494*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
495*25c28e83SPiotr Jasiukajtis 		} else if (inst->op == cvtsi2sdq) {
496*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_llong;
497*25c28e83SPiotr Jasiukajtis 			info->op1.val.l = inst->op2->l[0];
498*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
499*25c28e83SPiotr Jasiukajtis 		} else if (inst->op == sqrtsd || inst->op == cvtsd2ss ||
500*25c28e83SPiotr Jasiukajtis 		    inst->op == cvttsd2si || inst->op == cvtsd2si ||
501*25c28e83SPiotr Jasiukajtis 		    inst->op == cvttsd2siq || inst->op == cvtsd2siq) {
502*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_double;
503*25c28e83SPiotr Jasiukajtis 			info->op1.val.d = inst->op2->d[0];
504*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
505*25c28e83SPiotr Jasiukajtis 		} else {
506*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_double;
507*25c28e83SPiotr Jasiukajtis 			info->op1.val.d = inst->op1->d[0];
508*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_double;
509*25c28e83SPiotr Jasiukajtis 			info->op2.val.d = inst->op2->d[0];
510*25c28e83SPiotr Jasiukajtis 		}
511*25c28e83SPiotr Jasiukajtis 		info->res.type = fex_double;
512*25c28e83SPiotr Jasiukajtis 		switch (inst->op) {
513*25c28e83SPiotr Jasiukajtis 		case cmpsd:
514*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
515*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_llong;
516*25c28e83SPiotr Jasiukajtis 			switch (inst->imm & 3) {
517*25c28e83SPiotr Jasiukajtis 			case 0:
518*25c28e83SPiotr Jasiukajtis 				sse_cmpeqsd(&info->op1.val.d, &info->op2.val.d,
519*25c28e83SPiotr Jasiukajtis 				    &info->res.val.l);
520*25c28e83SPiotr Jasiukajtis 				break;
521*25c28e83SPiotr Jasiukajtis 
522*25c28e83SPiotr Jasiukajtis 			case 1:
523*25c28e83SPiotr Jasiukajtis 				sse_cmpltsd(&info->op1.val.d, &info->op2.val.d,
524*25c28e83SPiotr Jasiukajtis 				    &info->res.val.l);
525*25c28e83SPiotr Jasiukajtis 				break;
526*25c28e83SPiotr Jasiukajtis 
527*25c28e83SPiotr Jasiukajtis 			case 2:
528*25c28e83SPiotr Jasiukajtis 				sse_cmplesd(&info->op1.val.d, &info->op2.val.d,
529*25c28e83SPiotr Jasiukajtis 				    &info->res.val.l);
530*25c28e83SPiotr Jasiukajtis 				break;
531*25c28e83SPiotr Jasiukajtis 
532*25c28e83SPiotr Jasiukajtis 			case 3:
533*25c28e83SPiotr Jasiukajtis 				sse_cmpunordsd(&info->op1.val.d,
534*25c28e83SPiotr Jasiukajtis 				    &info->op2.val.d, &info->res.val.l);
535*25c28e83SPiotr Jasiukajtis 			}
536*25c28e83SPiotr Jasiukajtis 			if (inst->imm & 4)
537*25c28e83SPiotr Jasiukajtis 				info->res.val.l ^= 0xffffffffffffffffull;
538*25c28e83SPiotr Jasiukajtis 			break;
539*25c28e83SPiotr Jasiukajtis 
540*25c28e83SPiotr Jasiukajtis 		case minsd:
541*25c28e83SPiotr Jasiukajtis 			info->op = fex_other;
542*25c28e83SPiotr Jasiukajtis 			sse_minsd(&info->op1.val.d, &info->op2.val.d,
543*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
544*25c28e83SPiotr Jasiukajtis 			break;
545*25c28e83SPiotr Jasiukajtis 
546*25c28e83SPiotr Jasiukajtis 		case maxsd:
547*25c28e83SPiotr Jasiukajtis 			info->op = fex_other;
548*25c28e83SPiotr Jasiukajtis 			sse_maxsd(&info->op1.val.d, &info->op2.val.d,
549*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
550*25c28e83SPiotr Jasiukajtis 			break;
551*25c28e83SPiotr Jasiukajtis 
552*25c28e83SPiotr Jasiukajtis 		case addsd:
553*25c28e83SPiotr Jasiukajtis 			info->op = fex_add;
554*25c28e83SPiotr Jasiukajtis 			sse_addsd(&info->op1.val.d, &info->op2.val.d,
555*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
556*25c28e83SPiotr Jasiukajtis 			if (my_fp_class(&info->res.val.d) == fp_subnormal)
557*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
558*25c28e83SPiotr Jasiukajtis 			break;
559*25c28e83SPiotr Jasiukajtis 
560*25c28e83SPiotr Jasiukajtis 		case subsd:
561*25c28e83SPiotr Jasiukajtis 			info->op = fex_sub;
562*25c28e83SPiotr Jasiukajtis 			sse_subsd(&info->op1.val.d, &info->op2.val.d,
563*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
564*25c28e83SPiotr Jasiukajtis 			if (my_fp_class(&info->res.val.d) == fp_subnormal)
565*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
566*25c28e83SPiotr Jasiukajtis 			break;
567*25c28e83SPiotr Jasiukajtis 
568*25c28e83SPiotr Jasiukajtis 		case mulsd:
569*25c28e83SPiotr Jasiukajtis 			info->op = fex_mul;
570*25c28e83SPiotr Jasiukajtis 			sse_mulsd(&info->op1.val.d, &info->op2.val.d,
571*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
572*25c28e83SPiotr Jasiukajtis 			if (my_fp_class(&info->res.val.d) == fp_subnormal)
573*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
574*25c28e83SPiotr Jasiukajtis 			break;
575*25c28e83SPiotr Jasiukajtis 
576*25c28e83SPiotr Jasiukajtis 		case divsd:
577*25c28e83SPiotr Jasiukajtis 			info->op = fex_div;
578*25c28e83SPiotr Jasiukajtis 			sse_divsd(&info->op1.val.d, &info->op2.val.d,
579*25c28e83SPiotr Jasiukajtis 			    &info->res.val.d);
580*25c28e83SPiotr Jasiukajtis 			if (my_fp_class(&info->res.val.d) == fp_subnormal)
581*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
582*25c28e83SPiotr Jasiukajtis 			break;
583*25c28e83SPiotr Jasiukajtis 
584*25c28e83SPiotr Jasiukajtis 		case sqrtsd:
585*25c28e83SPiotr Jasiukajtis 			info->op = fex_sqrt;
586*25c28e83SPiotr Jasiukajtis 			sse_sqrtsd(&info->op1.val.d, &info->res.val.d);
587*25c28e83SPiotr Jasiukajtis 			break;
588*25c28e83SPiotr Jasiukajtis 
589*25c28e83SPiotr Jasiukajtis 		case cvtsd2ss:
590*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
591*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_float;
592*25c28e83SPiotr Jasiukajtis 			sse_cvtsd2ss(&info->op1.val.d, &info->res.val.f);
593*25c28e83SPiotr Jasiukajtis 			if (my_fp_classf(&info->res.val.f) == fp_subnormal)
594*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
595*25c28e83SPiotr Jasiukajtis 			break;
596*25c28e83SPiotr Jasiukajtis 
597*25c28e83SPiotr Jasiukajtis 		case cvtsi2sd:
598*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
599*25c28e83SPiotr Jasiukajtis 			sse_cvtsi2sd(&info->op1.val.i, &info->res.val.d);
600*25c28e83SPiotr Jasiukajtis 			break;
601*25c28e83SPiotr Jasiukajtis 
602*25c28e83SPiotr Jasiukajtis 		case cvttsd2si:
603*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
604*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_int;
605*25c28e83SPiotr Jasiukajtis 			sse_cvttsd2si(&info->op1.val.d, &info->res.val.i);
606*25c28e83SPiotr Jasiukajtis 			break;
607*25c28e83SPiotr Jasiukajtis 
608*25c28e83SPiotr Jasiukajtis 		case cvtsd2si:
609*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
610*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_int;
611*25c28e83SPiotr Jasiukajtis 			sse_cvtsd2si(&info->op1.val.d, &info->res.val.i);
612*25c28e83SPiotr Jasiukajtis 			break;
613*25c28e83SPiotr Jasiukajtis 
614*25c28e83SPiotr Jasiukajtis #ifdef __amd64
615*25c28e83SPiotr Jasiukajtis 		case cvtsi2sdq:
616*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
617*25c28e83SPiotr Jasiukajtis 			sse_cvtsi2sdq(&info->op1.val.l, &info->res.val.d);
618*25c28e83SPiotr Jasiukajtis 			break;
619*25c28e83SPiotr Jasiukajtis 
620*25c28e83SPiotr Jasiukajtis 		case cvttsd2siq:
621*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
622*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_llong;
623*25c28e83SPiotr Jasiukajtis 			sse_cvttsd2siq(&info->op1.val.d, &info->res.val.l);
624*25c28e83SPiotr Jasiukajtis 			break;
625*25c28e83SPiotr Jasiukajtis 
626*25c28e83SPiotr Jasiukajtis 		case cvtsd2siq:
627*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
628*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_llong;
629*25c28e83SPiotr Jasiukajtis 			sse_cvtsd2siq(&info->op1.val.d, &info->res.val.l);
630*25c28e83SPiotr Jasiukajtis 			break;
631*25c28e83SPiotr Jasiukajtis #endif
632*25c28e83SPiotr Jasiukajtis 
633*25c28e83SPiotr Jasiukajtis 		case ucomisd:
634*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
635*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_nodata;
636*25c28e83SPiotr Jasiukajtis 			sse_ucomisd(&info->op1.val.d, &info->op2.val.d);
637*25c28e83SPiotr Jasiukajtis 			break;
638*25c28e83SPiotr Jasiukajtis 
639*25c28e83SPiotr Jasiukajtis 		case comisd:
640*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
641*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_nodata;
642*25c28e83SPiotr Jasiukajtis 			sse_comisd(&info->op1.val.d, &info->op2.val.d);
643*25c28e83SPiotr Jasiukajtis 			break;
644*25c28e83SPiotr Jasiukajtis 		default:
645*25c28e83SPiotr Jasiukajtis 			break;
646*25c28e83SPiotr Jasiukajtis 		}
647*25c28e83SPiotr Jasiukajtis 	} else {
648*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvtsi2ss) {
649*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_int;
650*25c28e83SPiotr Jasiukajtis 			info->op1.val.i = inst->op2->i[0];
651*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
652*25c28e83SPiotr Jasiukajtis 		} else if (inst->op == cvtsi2ssq) {
653*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_llong;
654*25c28e83SPiotr Jasiukajtis 			info->op1.val.l = inst->op2->l[0];
655*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
656*25c28e83SPiotr Jasiukajtis 		} else if (inst->op == sqrtss || inst->op == cvtss2sd ||
657*25c28e83SPiotr Jasiukajtis 		    inst->op == cvttss2si || inst->op == cvtss2si ||
658*25c28e83SPiotr Jasiukajtis 		    inst->op == cvttss2siq || inst->op == cvtss2siq) {
659*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_float;
660*25c28e83SPiotr Jasiukajtis 			info->op1.val.f = inst->op2->f[0];
661*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
662*25c28e83SPiotr Jasiukajtis 		} else {
663*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_float;
664*25c28e83SPiotr Jasiukajtis 			info->op1.val.f = inst->op1->f[0];
665*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_float;
666*25c28e83SPiotr Jasiukajtis 			info->op2.val.f = inst->op2->f[0];
667*25c28e83SPiotr Jasiukajtis 		}
668*25c28e83SPiotr Jasiukajtis 		info->res.type = fex_float;
669*25c28e83SPiotr Jasiukajtis 		switch (inst->op) {
670*25c28e83SPiotr Jasiukajtis 		case cmpss:
671*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
672*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_int;
673*25c28e83SPiotr Jasiukajtis 			switch (inst->imm & 3) {
674*25c28e83SPiotr Jasiukajtis 			case 0:
675*25c28e83SPiotr Jasiukajtis 				sse_cmpeqss(&info->op1.val.f, &info->op2.val.f,
676*25c28e83SPiotr Jasiukajtis 				    &info->res.val.i);
677*25c28e83SPiotr Jasiukajtis 				break;
678*25c28e83SPiotr Jasiukajtis 
679*25c28e83SPiotr Jasiukajtis 			case 1:
680*25c28e83SPiotr Jasiukajtis 				sse_cmpltss(&info->op1.val.f, &info->op2.val.f,
681*25c28e83SPiotr Jasiukajtis 				    &info->res.val.i);
682*25c28e83SPiotr Jasiukajtis 				break;
683*25c28e83SPiotr Jasiukajtis 
684*25c28e83SPiotr Jasiukajtis 			case 2:
685*25c28e83SPiotr Jasiukajtis 				sse_cmpless(&info->op1.val.f, &info->op2.val.f,
686*25c28e83SPiotr Jasiukajtis 				    &info->res.val.i);
687*25c28e83SPiotr Jasiukajtis 				break;
688*25c28e83SPiotr Jasiukajtis 
689*25c28e83SPiotr Jasiukajtis 			case 3:
690*25c28e83SPiotr Jasiukajtis 				sse_cmpunordss(&info->op1.val.f,
691*25c28e83SPiotr Jasiukajtis 				    &info->op2.val.f, &info->res.val.i);
692*25c28e83SPiotr Jasiukajtis 			}
693*25c28e83SPiotr Jasiukajtis 			if (inst->imm & 4)
694*25c28e83SPiotr Jasiukajtis 				info->res.val.i ^= 0xffffffffu;
695*25c28e83SPiotr Jasiukajtis 			break;
696*25c28e83SPiotr Jasiukajtis 
697*25c28e83SPiotr Jasiukajtis 		case minss:
698*25c28e83SPiotr Jasiukajtis 			info->op = fex_other;
699*25c28e83SPiotr Jasiukajtis 			sse_minss(&info->op1.val.f, &info->op2.val.f,
700*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
701*25c28e83SPiotr Jasiukajtis 			break;
702*25c28e83SPiotr Jasiukajtis 
703*25c28e83SPiotr Jasiukajtis 		case maxss:
704*25c28e83SPiotr Jasiukajtis 			info->op = fex_other;
705*25c28e83SPiotr Jasiukajtis 			sse_maxss(&info->op1.val.f, &info->op2.val.f,
706*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
707*25c28e83SPiotr Jasiukajtis 			break;
708*25c28e83SPiotr Jasiukajtis 
709*25c28e83SPiotr Jasiukajtis 		case addss:
710*25c28e83SPiotr Jasiukajtis 			info->op = fex_add;
711*25c28e83SPiotr Jasiukajtis 			sse_addss(&info->op1.val.f, &info->op2.val.f,
712*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
713*25c28e83SPiotr Jasiukajtis 			if (my_fp_classf(&info->res.val.f) == fp_subnormal)
714*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
715*25c28e83SPiotr Jasiukajtis 			break;
716*25c28e83SPiotr Jasiukajtis 
717*25c28e83SPiotr Jasiukajtis 		case subss:
718*25c28e83SPiotr Jasiukajtis 			info->op = fex_sub;
719*25c28e83SPiotr Jasiukajtis 			sse_subss(&info->op1.val.f, &info->op2.val.f,
720*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
721*25c28e83SPiotr Jasiukajtis 			if (my_fp_classf(&info->res.val.f) == fp_subnormal)
722*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
723*25c28e83SPiotr Jasiukajtis 			break;
724*25c28e83SPiotr Jasiukajtis 
725*25c28e83SPiotr Jasiukajtis 		case mulss:
726*25c28e83SPiotr Jasiukajtis 			info->op = fex_mul;
727*25c28e83SPiotr Jasiukajtis 			sse_mulss(&info->op1.val.f, &info->op2.val.f,
728*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
729*25c28e83SPiotr Jasiukajtis 			if (my_fp_classf(&info->res.val.f) == fp_subnormal)
730*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
731*25c28e83SPiotr Jasiukajtis 			break;
732*25c28e83SPiotr Jasiukajtis 
733*25c28e83SPiotr Jasiukajtis 		case divss:
734*25c28e83SPiotr Jasiukajtis 			info->op = fex_div;
735*25c28e83SPiotr Jasiukajtis 			sse_divss(&info->op1.val.f, &info->op2.val.f,
736*25c28e83SPiotr Jasiukajtis 			    &info->res.val.f);
737*25c28e83SPiotr Jasiukajtis 			if (my_fp_classf(&info->res.val.f) == fp_subnormal)
738*25c28e83SPiotr Jasiukajtis 				subnorm = 1;
739*25c28e83SPiotr Jasiukajtis 			break;
740*25c28e83SPiotr Jasiukajtis 
741*25c28e83SPiotr Jasiukajtis 		case sqrtss:
742*25c28e83SPiotr Jasiukajtis 			info->op = fex_sqrt;
743*25c28e83SPiotr Jasiukajtis 			sse_sqrtss(&info->op1.val.f, &info->res.val.f);
744*25c28e83SPiotr Jasiukajtis 			break;
745*25c28e83SPiotr Jasiukajtis 
746*25c28e83SPiotr Jasiukajtis 		case cvtss2sd:
747*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
748*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_double;
749*25c28e83SPiotr Jasiukajtis 			sse_cvtss2sd(&info->op1.val.f, &info->res.val.d);
750*25c28e83SPiotr Jasiukajtis 			break;
751*25c28e83SPiotr Jasiukajtis 
752*25c28e83SPiotr Jasiukajtis 		case cvtsi2ss:
753*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
754*25c28e83SPiotr Jasiukajtis 			sse_cvtsi2ss(&info->op1.val.i, &info->res.val.f);
755*25c28e83SPiotr Jasiukajtis 			break;
756*25c28e83SPiotr Jasiukajtis 
757*25c28e83SPiotr Jasiukajtis 		case cvttss2si:
758*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
759*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_int;
760*25c28e83SPiotr Jasiukajtis 			sse_cvttss2si(&info->op1.val.f, &info->res.val.i);
761*25c28e83SPiotr Jasiukajtis 			break;
762*25c28e83SPiotr Jasiukajtis 
763*25c28e83SPiotr Jasiukajtis 		case cvtss2si:
764*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
765*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_int;
766*25c28e83SPiotr Jasiukajtis 			sse_cvtss2si(&info->op1.val.f, &info->res.val.i);
767*25c28e83SPiotr Jasiukajtis 			break;
768*25c28e83SPiotr Jasiukajtis 
769*25c28e83SPiotr Jasiukajtis #ifdef __amd64
770*25c28e83SPiotr Jasiukajtis 		case cvtsi2ssq:
771*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
772*25c28e83SPiotr Jasiukajtis 			sse_cvtsi2ssq(&info->op1.val.l, &info->res.val.f);
773*25c28e83SPiotr Jasiukajtis 			break;
774*25c28e83SPiotr Jasiukajtis 
775*25c28e83SPiotr Jasiukajtis 		case cvttss2siq:
776*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
777*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_llong;
778*25c28e83SPiotr Jasiukajtis 			sse_cvttss2siq(&info->op1.val.f, &info->res.val.l);
779*25c28e83SPiotr Jasiukajtis 			break;
780*25c28e83SPiotr Jasiukajtis 
781*25c28e83SPiotr Jasiukajtis 		case cvtss2siq:
782*25c28e83SPiotr Jasiukajtis 			info->op = fex_cnvt;
783*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_llong;
784*25c28e83SPiotr Jasiukajtis 			sse_cvtss2siq(&info->op1.val.f, &info->res.val.l);
785*25c28e83SPiotr Jasiukajtis 			break;
786*25c28e83SPiotr Jasiukajtis #endif
787*25c28e83SPiotr Jasiukajtis 
788*25c28e83SPiotr Jasiukajtis 		case ucomiss:
789*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
790*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_nodata;
791*25c28e83SPiotr Jasiukajtis 			sse_ucomiss(&info->op1.val.f, &info->op2.val.f);
792*25c28e83SPiotr Jasiukajtis 			break;
793*25c28e83SPiotr Jasiukajtis 
794*25c28e83SPiotr Jasiukajtis 		case comiss:
795*25c28e83SPiotr Jasiukajtis 			info->op = fex_cmp;
796*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_nodata;
797*25c28e83SPiotr Jasiukajtis 			sse_comiss(&info->op1.val.f, &info->op2.val.f);
798*25c28e83SPiotr Jasiukajtis 			break;
799*25c28e83SPiotr Jasiukajtis 		default:
800*25c28e83SPiotr Jasiukajtis 			break;
801*25c28e83SPiotr Jasiukajtis 		}
802*25c28e83SPiotr Jasiukajtis 	}
803*25c28e83SPiotr Jasiukajtis 	__fenv_getmxcsr(&mxcsr);
804*25c28e83SPiotr Jasiukajtis 	info->flags = mxcsr & 0x3d;
805*25c28e83SPiotr Jasiukajtis 	__fenv_setmxcsr(&oldmxcsr);
806*25c28e83SPiotr Jasiukajtis 
807*25c28e83SPiotr Jasiukajtis 	/* determine which exception would have been trapped */
808*25c28e83SPiotr Jasiukajtis 	te = ~(uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr
809*25c28e83SPiotr Jasiukajtis 	    >> 7) & 0x3d;
810*25c28e83SPiotr Jasiukajtis 	e = mxcsr & te;
811*25c28e83SPiotr Jasiukajtis 	if (e & FE_INVALID)
812*25c28e83SPiotr Jasiukajtis 		return __fex_get_sse_invalid_type(inst);
813*25c28e83SPiotr Jasiukajtis 	if (e & FE_DIVBYZERO)
814*25c28e83SPiotr Jasiukajtis 		return fex_division;
815*25c28e83SPiotr Jasiukajtis 	if (e & FE_OVERFLOW)
816*25c28e83SPiotr Jasiukajtis 		return fex_overflow;
817*25c28e83SPiotr Jasiukajtis 	if ((e & FE_UNDERFLOW) || (subnorm && (te & FE_UNDERFLOW)))
818*25c28e83SPiotr Jasiukajtis 		return fex_underflow;
819*25c28e83SPiotr Jasiukajtis 	if (e & FE_INEXACT)
820*25c28e83SPiotr Jasiukajtis 		return fex_inexact;
821*25c28e83SPiotr Jasiukajtis 	return (enum fex_exception)-1;
822*25c28e83SPiotr Jasiukajtis }
823*25c28e83SPiotr Jasiukajtis 
824*25c28e83SPiotr Jasiukajtis /*
825*25c28e83SPiotr Jasiukajtis  * Emulate a SIMD SSE instruction to determine which exceptions occur
826*25c28e83SPiotr Jasiukajtis  * in each part.  For i = 0, 1, 2, and 3, set e[i] to indicate the
827*25c28e83SPiotr Jasiukajtis  * trapped exception that would occur if the i-th part of the SIMD
828*25c28e83SPiotr Jasiukajtis  * instruction were executed in isolation; set e[i] to -1 if no
829*25c28e83SPiotr Jasiukajtis  * trapped exception would occur in this part.  Also fill in info[i]
830*25c28e83SPiotr Jasiukajtis  * with the corresponding operands, default untrapped result, and
831*25c28e83SPiotr Jasiukajtis  * flags.
832*25c28e83SPiotr Jasiukajtis  *
833*25c28e83SPiotr Jasiukajtis  * This routine does not work if the instruction specified by *inst
834*25c28e83SPiotr Jasiukajtis  * is not a SIMD instruction.
835*25c28e83SPiotr Jasiukajtis  */
836*25c28e83SPiotr Jasiukajtis void
__fex_get_simd_op(ucontext_t * uap,sseinst_t * inst,enum fex_exception * e,fex_info_t * info)837*25c28e83SPiotr Jasiukajtis __fex_get_simd_op(ucontext_t *uap, sseinst_t *inst, enum fex_exception *e,
838*25c28e83SPiotr Jasiukajtis     fex_info_t *info)
839*25c28e83SPiotr Jasiukajtis {
840*25c28e83SPiotr Jasiukajtis 	sseinst_t	dummy;
841*25c28e83SPiotr Jasiukajtis 	int		i;
842*25c28e83SPiotr Jasiukajtis 
843*25c28e83SPiotr Jasiukajtis 	e[0] = e[1] = e[2] = e[3] = -1;
844*25c28e83SPiotr Jasiukajtis 
845*25c28e83SPiotr Jasiukajtis 	/* perform each part of the SIMD operation */
846*25c28e83SPiotr Jasiukajtis 	switch (inst->op) {
847*25c28e83SPiotr Jasiukajtis 	case cmpps:
848*25c28e83SPiotr Jasiukajtis 		dummy.op = cmpss;
849*25c28e83SPiotr Jasiukajtis 		dummy.imm = inst->imm;
850*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
851*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
852*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
853*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
854*25c28e83SPiotr Jasiukajtis 		}
855*25c28e83SPiotr Jasiukajtis 		break;
856*25c28e83SPiotr Jasiukajtis 
857*25c28e83SPiotr Jasiukajtis 	case minps:
858*25c28e83SPiotr Jasiukajtis 		dummy.op = minss;
859*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
860*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
861*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
862*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
863*25c28e83SPiotr Jasiukajtis 		}
864*25c28e83SPiotr Jasiukajtis 		break;
865*25c28e83SPiotr Jasiukajtis 
866*25c28e83SPiotr Jasiukajtis 	case maxps:
867*25c28e83SPiotr Jasiukajtis 		dummy.op = maxss;
868*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
869*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
870*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
871*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
872*25c28e83SPiotr Jasiukajtis 		}
873*25c28e83SPiotr Jasiukajtis 		break;
874*25c28e83SPiotr Jasiukajtis 
875*25c28e83SPiotr Jasiukajtis 	case addps:
876*25c28e83SPiotr Jasiukajtis 		dummy.op = addss;
877*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
878*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
879*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
880*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
881*25c28e83SPiotr Jasiukajtis 		}
882*25c28e83SPiotr Jasiukajtis 		break;
883*25c28e83SPiotr Jasiukajtis 
884*25c28e83SPiotr Jasiukajtis 	case subps:
885*25c28e83SPiotr Jasiukajtis 		dummy.op = subss;
886*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
887*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
888*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
889*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
890*25c28e83SPiotr Jasiukajtis 		}
891*25c28e83SPiotr Jasiukajtis 		break;
892*25c28e83SPiotr Jasiukajtis 
893*25c28e83SPiotr Jasiukajtis 	case mulps:
894*25c28e83SPiotr Jasiukajtis 		dummy.op = mulss;
895*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
896*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
897*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
898*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
899*25c28e83SPiotr Jasiukajtis 		}
900*25c28e83SPiotr Jasiukajtis 		break;
901*25c28e83SPiotr Jasiukajtis 
902*25c28e83SPiotr Jasiukajtis 	case divps:
903*25c28e83SPiotr Jasiukajtis 		dummy.op = divss;
904*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
905*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
906*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
907*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
908*25c28e83SPiotr Jasiukajtis 		}
909*25c28e83SPiotr Jasiukajtis 		break;
910*25c28e83SPiotr Jasiukajtis 
911*25c28e83SPiotr Jasiukajtis 	case sqrtps:
912*25c28e83SPiotr Jasiukajtis 		dummy.op = sqrtss;
913*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
914*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
915*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
916*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
917*25c28e83SPiotr Jasiukajtis 		}
918*25c28e83SPiotr Jasiukajtis 		break;
919*25c28e83SPiotr Jasiukajtis 
920*25c28e83SPiotr Jasiukajtis 	case cvtdq2ps:
921*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2ss;
922*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
923*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
924*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
925*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
926*25c28e83SPiotr Jasiukajtis 		}
927*25c28e83SPiotr Jasiukajtis 		break;
928*25c28e83SPiotr Jasiukajtis 
929*25c28e83SPiotr Jasiukajtis 	case cvttps2dq:
930*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttss2si;
931*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
932*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
933*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
934*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
935*25c28e83SPiotr Jasiukajtis 		}
936*25c28e83SPiotr Jasiukajtis 		break;
937*25c28e83SPiotr Jasiukajtis 
938*25c28e83SPiotr Jasiukajtis 	case cvtps2dq:
939*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2si;
940*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
941*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
942*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
943*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
944*25c28e83SPiotr Jasiukajtis 		}
945*25c28e83SPiotr Jasiukajtis 		break;
946*25c28e83SPiotr Jasiukajtis 
947*25c28e83SPiotr Jasiukajtis 	case cvtpi2ps:
948*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2ss;
949*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
950*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
951*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
952*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
953*25c28e83SPiotr Jasiukajtis 		}
954*25c28e83SPiotr Jasiukajtis 		break;
955*25c28e83SPiotr Jasiukajtis 
956*25c28e83SPiotr Jasiukajtis 	case cvttps2pi:
957*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttss2si;
958*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
959*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
960*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
961*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
962*25c28e83SPiotr Jasiukajtis 		}
963*25c28e83SPiotr Jasiukajtis 		break;
964*25c28e83SPiotr Jasiukajtis 
965*25c28e83SPiotr Jasiukajtis 	case cvtps2pi:
966*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2si;
967*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
968*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
969*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
970*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
971*25c28e83SPiotr Jasiukajtis 		}
972*25c28e83SPiotr Jasiukajtis 		break;
973*25c28e83SPiotr Jasiukajtis 
974*25c28e83SPiotr Jasiukajtis 	case cmppd:
975*25c28e83SPiotr Jasiukajtis 		dummy.op = cmpsd;
976*25c28e83SPiotr Jasiukajtis 		dummy.imm = inst->imm;
977*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
978*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
979*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
980*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
981*25c28e83SPiotr Jasiukajtis 		}
982*25c28e83SPiotr Jasiukajtis 		break;
983*25c28e83SPiotr Jasiukajtis 
984*25c28e83SPiotr Jasiukajtis 	case minpd:
985*25c28e83SPiotr Jasiukajtis 		dummy.op = minsd;
986*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
987*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
988*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
989*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
990*25c28e83SPiotr Jasiukajtis 		}
991*25c28e83SPiotr Jasiukajtis 		break;
992*25c28e83SPiotr Jasiukajtis 
993*25c28e83SPiotr Jasiukajtis 	case maxpd:
994*25c28e83SPiotr Jasiukajtis 		dummy.op = maxsd;
995*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
996*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
997*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
998*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
999*25c28e83SPiotr Jasiukajtis 		}
1000*25c28e83SPiotr Jasiukajtis 		break;
1001*25c28e83SPiotr Jasiukajtis 
1002*25c28e83SPiotr Jasiukajtis 	case addpd:
1003*25c28e83SPiotr Jasiukajtis 		dummy.op = addsd;
1004*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1005*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1006*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1007*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1008*25c28e83SPiotr Jasiukajtis 		}
1009*25c28e83SPiotr Jasiukajtis 		break;
1010*25c28e83SPiotr Jasiukajtis 
1011*25c28e83SPiotr Jasiukajtis 	case subpd:
1012*25c28e83SPiotr Jasiukajtis 		dummy.op = subsd;
1013*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1014*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1015*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1016*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1017*25c28e83SPiotr Jasiukajtis 		}
1018*25c28e83SPiotr Jasiukajtis 		break;
1019*25c28e83SPiotr Jasiukajtis 
1020*25c28e83SPiotr Jasiukajtis 	case mulpd:
1021*25c28e83SPiotr Jasiukajtis 		dummy.op = mulsd;
1022*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1023*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1024*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1025*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1026*25c28e83SPiotr Jasiukajtis 		}
1027*25c28e83SPiotr Jasiukajtis 		break;
1028*25c28e83SPiotr Jasiukajtis 
1029*25c28e83SPiotr Jasiukajtis 	case divpd:
1030*25c28e83SPiotr Jasiukajtis 		dummy.op = divsd;
1031*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1032*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1033*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1034*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1035*25c28e83SPiotr Jasiukajtis 		}
1036*25c28e83SPiotr Jasiukajtis 		break;
1037*25c28e83SPiotr Jasiukajtis 
1038*25c28e83SPiotr Jasiukajtis 	case sqrtpd:
1039*25c28e83SPiotr Jasiukajtis 		dummy.op = sqrtsd;
1040*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1041*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1042*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1043*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1044*25c28e83SPiotr Jasiukajtis 		}
1045*25c28e83SPiotr Jasiukajtis 		break;
1046*25c28e83SPiotr Jasiukajtis 
1047*25c28e83SPiotr Jasiukajtis 	case cvtpi2pd:
1048*25c28e83SPiotr Jasiukajtis 	case cvtdq2pd:
1049*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2sd;
1050*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1051*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1052*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
1053*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1054*25c28e83SPiotr Jasiukajtis 		}
1055*25c28e83SPiotr Jasiukajtis 		break;
1056*25c28e83SPiotr Jasiukajtis 
1057*25c28e83SPiotr Jasiukajtis 	case cvttpd2pi:
1058*25c28e83SPiotr Jasiukajtis 	case cvttpd2dq:
1059*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttsd2si;
1060*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1061*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1062*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1063*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1064*25c28e83SPiotr Jasiukajtis 		}
1065*25c28e83SPiotr Jasiukajtis 		break;
1066*25c28e83SPiotr Jasiukajtis 
1067*25c28e83SPiotr Jasiukajtis 	case cvtpd2pi:
1068*25c28e83SPiotr Jasiukajtis 	case cvtpd2dq:
1069*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsd2si;
1070*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1071*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1072*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1073*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1074*25c28e83SPiotr Jasiukajtis 		}
1075*25c28e83SPiotr Jasiukajtis 		break;
1076*25c28e83SPiotr Jasiukajtis 
1077*25c28e83SPiotr Jasiukajtis 	case cvtps2pd:
1078*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2sd;
1079*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1080*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1081*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1082*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1083*25c28e83SPiotr Jasiukajtis 		}
1084*25c28e83SPiotr Jasiukajtis 		break;
1085*25c28e83SPiotr Jasiukajtis 
1086*25c28e83SPiotr Jasiukajtis 	case cvtpd2ps:
1087*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsd2ss;
1088*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1089*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1090*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1091*25c28e83SPiotr Jasiukajtis 			e[i] = __fex_get_sse_op(uap, &dummy, &info[i]);
1092*25c28e83SPiotr Jasiukajtis 		}
1093*25c28e83SPiotr Jasiukajtis 	default:
1094*25c28e83SPiotr Jasiukajtis 		break;
1095*25c28e83SPiotr Jasiukajtis 	}
1096*25c28e83SPiotr Jasiukajtis }
1097*25c28e83SPiotr Jasiukajtis 
1098*25c28e83SPiotr Jasiukajtis /*
1099*25c28e83SPiotr Jasiukajtis  * Store the result value from *info in the destination of the scalar
1100*25c28e83SPiotr Jasiukajtis  * SSE instruction specified by *inst.  If no result is given but the
1101*25c28e83SPiotr Jasiukajtis  * exception is underflow or overflow, supply the default trapped result.
1102*25c28e83SPiotr Jasiukajtis  *
1103*25c28e83SPiotr Jasiukajtis  * This routine does not work if the instruction specified by *inst
1104*25c28e83SPiotr Jasiukajtis  * is not a scalar instruction.
1105*25c28e83SPiotr Jasiukajtis  */
1106*25c28e83SPiotr Jasiukajtis void
__fex_st_sse_result(ucontext_t * uap,sseinst_t * inst,enum fex_exception e,fex_info_t * info)1107*25c28e83SPiotr Jasiukajtis __fex_st_sse_result(ucontext_t *uap, sseinst_t *inst, enum fex_exception e,
1108*25c28e83SPiotr Jasiukajtis     fex_info_t *info)
1109*25c28e83SPiotr Jasiukajtis {
1110*25c28e83SPiotr Jasiukajtis 	int		i = 0;
1111*25c28e83SPiotr Jasiukajtis 	long long	l = 0L;;
1112*25c28e83SPiotr Jasiukajtis 	float		f = 0.0, fscl;
1113*25c28e83SPiotr Jasiukajtis 	double		d = 0.0L, dscl;
1114*25c28e83SPiotr Jasiukajtis 
1115*25c28e83SPiotr Jasiukajtis 	/* for compares that write eflags, just set the flags
1116*25c28e83SPiotr Jasiukajtis 	   to indicate "unordered" */
1117*25c28e83SPiotr Jasiukajtis 	if (inst->op == ucomiss || inst->op == comiss ||
1118*25c28e83SPiotr Jasiukajtis 	    inst->op == ucomisd || inst->op == comisd) {
1119*25c28e83SPiotr Jasiukajtis 		uap->uc_mcontext.gregs[REG_PS] |= 0x45;
1120*25c28e83SPiotr Jasiukajtis 		return;
1121*25c28e83SPiotr Jasiukajtis 	}
1122*25c28e83SPiotr Jasiukajtis 
1123*25c28e83SPiotr Jasiukajtis 	/* if info doesn't specify a result value, try to generate
1124*25c28e83SPiotr Jasiukajtis 	   the default trapped result */
1125*25c28e83SPiotr Jasiukajtis 	if (info->res.type == fex_nodata) {
1126*25c28e83SPiotr Jasiukajtis 		/* set scale factors for exponent wrapping */
1127*25c28e83SPiotr Jasiukajtis 		switch (e) {
1128*25c28e83SPiotr Jasiukajtis 		case fex_overflow:
1129*25c28e83SPiotr Jasiukajtis 			fscl = 1.262177448e-29f; /* 2^-96 */
1130*25c28e83SPiotr Jasiukajtis 			dscl = 6.441148769597133308e-232; /* 2^-768 */
1131*25c28e83SPiotr Jasiukajtis 			break;
1132*25c28e83SPiotr Jasiukajtis 
1133*25c28e83SPiotr Jasiukajtis 		case fex_underflow:
1134*25c28e83SPiotr Jasiukajtis 			fscl = 7.922816251e+28f; /* 2^96 */
1135*25c28e83SPiotr Jasiukajtis 			dscl = 1.552518092300708935e+231; /* 2^768 */
1136*25c28e83SPiotr Jasiukajtis 			break;
1137*25c28e83SPiotr Jasiukajtis 
1138*25c28e83SPiotr Jasiukajtis 		default:
1139*25c28e83SPiotr Jasiukajtis 			(void) __fex_get_sse_op(uap, inst, info);
1140*25c28e83SPiotr Jasiukajtis 			if (info->res.type == fex_nodata)
1141*25c28e83SPiotr Jasiukajtis 				return;
1142*25c28e83SPiotr Jasiukajtis 			goto stuff;
1143*25c28e83SPiotr Jasiukajtis 		}
1144*25c28e83SPiotr Jasiukajtis 
1145*25c28e83SPiotr Jasiukajtis 		/* generate the wrapped result */
1146*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvtsd2ss) {
1147*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_double;
1148*25c28e83SPiotr Jasiukajtis 			info->op1.val.d = inst->op2->d[0];
1149*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_nodata;
1150*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_float;
1151*25c28e83SPiotr Jasiukajtis 			info->res.val.f = (float)(fscl * (fscl *
1152*25c28e83SPiotr Jasiukajtis 			    info->op1.val.d));
1153*25c28e83SPiotr Jasiukajtis 		} else if ((int)inst->op & DOUBLE) {
1154*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_double;
1155*25c28e83SPiotr Jasiukajtis 			info->op1.val.d = inst->op1->d[0];
1156*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_double;
1157*25c28e83SPiotr Jasiukajtis 			info->op2.val.d = inst->op2->d[0];
1158*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_double;
1159*25c28e83SPiotr Jasiukajtis 			switch (inst->op) {
1160*25c28e83SPiotr Jasiukajtis 			case addsd:
1161*25c28e83SPiotr Jasiukajtis 				info->res.val.d = dscl * (dscl *
1162*25c28e83SPiotr Jasiukajtis 				    info->op1.val.d + dscl * info->op2.val.d);
1163*25c28e83SPiotr Jasiukajtis 				break;
1164*25c28e83SPiotr Jasiukajtis 
1165*25c28e83SPiotr Jasiukajtis 			case subsd:
1166*25c28e83SPiotr Jasiukajtis 				info->res.val.d = dscl * (dscl *
1167*25c28e83SPiotr Jasiukajtis 				    info->op1.val.d - dscl * info->op2.val.d);
1168*25c28e83SPiotr Jasiukajtis 				break;
1169*25c28e83SPiotr Jasiukajtis 
1170*25c28e83SPiotr Jasiukajtis 			case mulsd:
1171*25c28e83SPiotr Jasiukajtis 				info->res.val.d = (dscl * info->op1.val.d) *
1172*25c28e83SPiotr Jasiukajtis 				    (dscl * info->op2.val.d);
1173*25c28e83SPiotr Jasiukajtis 				break;
1174*25c28e83SPiotr Jasiukajtis 
1175*25c28e83SPiotr Jasiukajtis 			case divsd:
1176*25c28e83SPiotr Jasiukajtis 				info->res.val.d = (dscl * info->op1.val.d) /
1177*25c28e83SPiotr Jasiukajtis 				    (info->op2.val.d / dscl);
1178*25c28e83SPiotr Jasiukajtis 				break;
1179*25c28e83SPiotr Jasiukajtis 
1180*25c28e83SPiotr Jasiukajtis 			default:
1181*25c28e83SPiotr Jasiukajtis 				return;
1182*25c28e83SPiotr Jasiukajtis 			}
1183*25c28e83SPiotr Jasiukajtis 		} else {
1184*25c28e83SPiotr Jasiukajtis 			info->op1.type = fex_float;
1185*25c28e83SPiotr Jasiukajtis 			info->op1.val.f = inst->op1->f[0];
1186*25c28e83SPiotr Jasiukajtis 			info->op2.type = fex_float;
1187*25c28e83SPiotr Jasiukajtis 			info->op2.val.f = inst->op2->f[0];
1188*25c28e83SPiotr Jasiukajtis 			info->res.type = fex_float;
1189*25c28e83SPiotr Jasiukajtis 			switch (inst->op) {
1190*25c28e83SPiotr Jasiukajtis 			case addss:
1191*25c28e83SPiotr Jasiukajtis 				info->res.val.f = fscl * (fscl *
1192*25c28e83SPiotr Jasiukajtis 				    info->op1.val.f + fscl * info->op2.val.f);
1193*25c28e83SPiotr Jasiukajtis 				break;
1194*25c28e83SPiotr Jasiukajtis 
1195*25c28e83SPiotr Jasiukajtis 			case subss:
1196*25c28e83SPiotr Jasiukajtis 				info->res.val.f = fscl * (fscl *
1197*25c28e83SPiotr Jasiukajtis 				    info->op1.val.f - fscl * info->op2.val.f);
1198*25c28e83SPiotr Jasiukajtis 				break;
1199*25c28e83SPiotr Jasiukajtis 
1200*25c28e83SPiotr Jasiukajtis 			case mulss:
1201*25c28e83SPiotr Jasiukajtis 				info->res.val.f = (fscl * info->op1.val.f) *
1202*25c28e83SPiotr Jasiukajtis 				    (fscl * info->op2.val.f);
1203*25c28e83SPiotr Jasiukajtis 				break;
1204*25c28e83SPiotr Jasiukajtis 
1205*25c28e83SPiotr Jasiukajtis 			case divss:
1206*25c28e83SPiotr Jasiukajtis 				info->res.val.f = (fscl * info->op1.val.f) /
1207*25c28e83SPiotr Jasiukajtis 				    (info->op2.val.f / fscl);
1208*25c28e83SPiotr Jasiukajtis 				break;
1209*25c28e83SPiotr Jasiukajtis 
1210*25c28e83SPiotr Jasiukajtis 			default:
1211*25c28e83SPiotr Jasiukajtis 				return;
1212*25c28e83SPiotr Jasiukajtis 			}
1213*25c28e83SPiotr Jasiukajtis 		}
1214*25c28e83SPiotr Jasiukajtis 	}
1215*25c28e83SPiotr Jasiukajtis 
1216*25c28e83SPiotr Jasiukajtis 	/* put the result in the destination */
1217*25c28e83SPiotr Jasiukajtis stuff:
1218*25c28e83SPiotr Jasiukajtis 	if (inst->op == cmpss || inst->op == cvttss2si || inst->op == cvtss2si
1219*25c28e83SPiotr Jasiukajtis 	    || inst->op == cvttsd2si || inst->op == cvtsd2si) {
1220*25c28e83SPiotr Jasiukajtis 		switch (info->res.type) {
1221*25c28e83SPiotr Jasiukajtis 		case fex_int:
1222*25c28e83SPiotr Jasiukajtis 			i = info->res.val.i;
1223*25c28e83SPiotr Jasiukajtis 			break;
1224*25c28e83SPiotr Jasiukajtis 
1225*25c28e83SPiotr Jasiukajtis 		case fex_llong:
1226*25c28e83SPiotr Jasiukajtis 			i = info->res.val.l;
1227*25c28e83SPiotr Jasiukajtis 			break;
1228*25c28e83SPiotr Jasiukajtis 
1229*25c28e83SPiotr Jasiukajtis 		case fex_float:
1230*25c28e83SPiotr Jasiukajtis 			i = info->res.val.f;
1231*25c28e83SPiotr Jasiukajtis 			break;
1232*25c28e83SPiotr Jasiukajtis 
1233*25c28e83SPiotr Jasiukajtis 		case fex_double:
1234*25c28e83SPiotr Jasiukajtis 			i = info->res.val.d;
1235*25c28e83SPiotr Jasiukajtis 			break;
1236*25c28e83SPiotr Jasiukajtis 
1237*25c28e83SPiotr Jasiukajtis 		case fex_ldouble:
1238*25c28e83SPiotr Jasiukajtis 			i = info->res.val.q;
1239*25c28e83SPiotr Jasiukajtis 			break;
1240*25c28e83SPiotr Jasiukajtis 
1241*25c28e83SPiotr Jasiukajtis 		default:
1242*25c28e83SPiotr Jasiukajtis 			break;
1243*25c28e83SPiotr Jasiukajtis 		}
1244*25c28e83SPiotr Jasiukajtis 		inst->op1->i[0] = i;
1245*25c28e83SPiotr Jasiukajtis 	} else if (inst->op == cmpsd || inst->op == cvttss2siq ||
1246*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtss2siq || inst->op == cvttsd2siq ||
1247*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtsd2siq) {
1248*25c28e83SPiotr Jasiukajtis 		switch (info->res.type) {
1249*25c28e83SPiotr Jasiukajtis 		case fex_int:
1250*25c28e83SPiotr Jasiukajtis 			l = info->res.val.i;
1251*25c28e83SPiotr Jasiukajtis 			break;
1252*25c28e83SPiotr Jasiukajtis 
1253*25c28e83SPiotr Jasiukajtis 		case fex_llong:
1254*25c28e83SPiotr Jasiukajtis 			l = info->res.val.l;
1255*25c28e83SPiotr Jasiukajtis 			break;
1256*25c28e83SPiotr Jasiukajtis 
1257*25c28e83SPiotr Jasiukajtis 		case fex_float:
1258*25c28e83SPiotr Jasiukajtis 			l = info->res.val.f;
1259*25c28e83SPiotr Jasiukajtis 			break;
1260*25c28e83SPiotr Jasiukajtis 
1261*25c28e83SPiotr Jasiukajtis 		case fex_double:
1262*25c28e83SPiotr Jasiukajtis 			l = info->res.val.d;
1263*25c28e83SPiotr Jasiukajtis 			break;
1264*25c28e83SPiotr Jasiukajtis 
1265*25c28e83SPiotr Jasiukajtis 		case fex_ldouble:
1266*25c28e83SPiotr Jasiukajtis 			l = info->res.val.q;
1267*25c28e83SPiotr Jasiukajtis 			break;
1268*25c28e83SPiotr Jasiukajtis 
1269*25c28e83SPiotr Jasiukajtis 		default:
1270*25c28e83SPiotr Jasiukajtis 			break;
1271*25c28e83SPiotr Jasiukajtis 		}
1272*25c28e83SPiotr Jasiukajtis 		inst->op1->l[0] = l;
1273*25c28e83SPiotr Jasiukajtis 	} else if ((((int)inst->op & DOUBLE) && inst->op != cvtsd2ss) ||
1274*25c28e83SPiotr Jasiukajtis 	    inst->op == cvtss2sd) {
1275*25c28e83SPiotr Jasiukajtis 		switch (info->res.type) {
1276*25c28e83SPiotr Jasiukajtis 		case fex_int:
1277*25c28e83SPiotr Jasiukajtis 			d = info->res.val.i;
1278*25c28e83SPiotr Jasiukajtis 			break;
1279*25c28e83SPiotr Jasiukajtis 
1280*25c28e83SPiotr Jasiukajtis 		case fex_llong:
1281*25c28e83SPiotr Jasiukajtis 			d = info->res.val.l;
1282*25c28e83SPiotr Jasiukajtis 			break;
1283*25c28e83SPiotr Jasiukajtis 
1284*25c28e83SPiotr Jasiukajtis 		case fex_float:
1285*25c28e83SPiotr Jasiukajtis 			d = info->res.val.f;
1286*25c28e83SPiotr Jasiukajtis 			break;
1287*25c28e83SPiotr Jasiukajtis 
1288*25c28e83SPiotr Jasiukajtis 		case fex_double:
1289*25c28e83SPiotr Jasiukajtis 			d = info->res.val.d;
1290*25c28e83SPiotr Jasiukajtis 			break;
1291*25c28e83SPiotr Jasiukajtis 
1292*25c28e83SPiotr Jasiukajtis 		case fex_ldouble:
1293*25c28e83SPiotr Jasiukajtis 			d = info->res.val.q;
1294*25c28e83SPiotr Jasiukajtis 			break;
1295*25c28e83SPiotr Jasiukajtis 
1296*25c28e83SPiotr Jasiukajtis 		default:
1297*25c28e83SPiotr Jasiukajtis 			break;
1298*25c28e83SPiotr Jasiukajtis 		}
1299*25c28e83SPiotr Jasiukajtis 		inst->op1->d[0] = d;
1300*25c28e83SPiotr Jasiukajtis 	} else {
1301*25c28e83SPiotr Jasiukajtis 		switch (info->res.type) {
1302*25c28e83SPiotr Jasiukajtis 		case fex_int:
1303*25c28e83SPiotr Jasiukajtis 			f = info->res.val.i;
1304*25c28e83SPiotr Jasiukajtis 			break;
1305*25c28e83SPiotr Jasiukajtis 
1306*25c28e83SPiotr Jasiukajtis 		case fex_llong:
1307*25c28e83SPiotr Jasiukajtis 			f = info->res.val.l;
1308*25c28e83SPiotr Jasiukajtis 			break;
1309*25c28e83SPiotr Jasiukajtis 
1310*25c28e83SPiotr Jasiukajtis 		case fex_float:
1311*25c28e83SPiotr Jasiukajtis 			f = info->res.val.f;
1312*25c28e83SPiotr Jasiukajtis 			break;
1313*25c28e83SPiotr Jasiukajtis 
1314*25c28e83SPiotr Jasiukajtis 		case fex_double:
1315*25c28e83SPiotr Jasiukajtis 			f = info->res.val.d;
1316*25c28e83SPiotr Jasiukajtis 			break;
1317*25c28e83SPiotr Jasiukajtis 
1318*25c28e83SPiotr Jasiukajtis 		case fex_ldouble:
1319*25c28e83SPiotr Jasiukajtis 			f = info->res.val.q;
1320*25c28e83SPiotr Jasiukajtis 			break;
1321*25c28e83SPiotr Jasiukajtis 
1322*25c28e83SPiotr Jasiukajtis 		default:
1323*25c28e83SPiotr Jasiukajtis 			break;
1324*25c28e83SPiotr Jasiukajtis 		}
1325*25c28e83SPiotr Jasiukajtis 		inst->op1->f[0] = f;
1326*25c28e83SPiotr Jasiukajtis 	}
1327*25c28e83SPiotr Jasiukajtis }
1328*25c28e83SPiotr Jasiukajtis 
1329*25c28e83SPiotr Jasiukajtis /*
1330*25c28e83SPiotr Jasiukajtis  * Store the results from a SIMD instruction.  For each i, store
1331*25c28e83SPiotr Jasiukajtis  * the result value from info[i] in the i-th part of the destination
1332*25c28e83SPiotr Jasiukajtis  * of the SIMD SSE instruction specified by *inst.  If no result
1333*25c28e83SPiotr Jasiukajtis  * is given but the exception indicated by e[i] is underflow or
1334*25c28e83SPiotr Jasiukajtis  * overflow, supply the default trapped result.
1335*25c28e83SPiotr Jasiukajtis  *
1336*25c28e83SPiotr Jasiukajtis  * This routine does not work if the instruction specified by *inst
1337*25c28e83SPiotr Jasiukajtis  * is not a SIMD instruction.
1338*25c28e83SPiotr Jasiukajtis  */
1339*25c28e83SPiotr Jasiukajtis void
__fex_st_simd_result(ucontext_t * uap,sseinst_t * inst,enum fex_exception * e,fex_info_t * info)1340*25c28e83SPiotr Jasiukajtis __fex_st_simd_result(ucontext_t *uap, sseinst_t *inst, enum fex_exception *e,
1341*25c28e83SPiotr Jasiukajtis     fex_info_t *info)
1342*25c28e83SPiotr Jasiukajtis {
1343*25c28e83SPiotr Jasiukajtis 	sseinst_t	dummy;
1344*25c28e83SPiotr Jasiukajtis 	int		i;
1345*25c28e83SPiotr Jasiukajtis 
1346*25c28e83SPiotr Jasiukajtis 	/* store each part */
1347*25c28e83SPiotr Jasiukajtis 	switch (inst->op) {
1348*25c28e83SPiotr Jasiukajtis 	case cmpps:
1349*25c28e83SPiotr Jasiukajtis 		dummy.op = cmpss;
1350*25c28e83SPiotr Jasiukajtis 		dummy.imm = inst->imm;
1351*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1352*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1353*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1354*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1355*25c28e83SPiotr Jasiukajtis 		}
1356*25c28e83SPiotr Jasiukajtis 		break;
1357*25c28e83SPiotr Jasiukajtis 
1358*25c28e83SPiotr Jasiukajtis 	case minps:
1359*25c28e83SPiotr Jasiukajtis 		dummy.op = minss;
1360*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1361*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1362*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1363*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1364*25c28e83SPiotr Jasiukajtis 		}
1365*25c28e83SPiotr Jasiukajtis 		break;
1366*25c28e83SPiotr Jasiukajtis 
1367*25c28e83SPiotr Jasiukajtis 	case maxps:
1368*25c28e83SPiotr Jasiukajtis 		dummy.op = maxss;
1369*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1370*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1371*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1372*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1373*25c28e83SPiotr Jasiukajtis 		}
1374*25c28e83SPiotr Jasiukajtis 		break;
1375*25c28e83SPiotr Jasiukajtis 
1376*25c28e83SPiotr Jasiukajtis 	case addps:
1377*25c28e83SPiotr Jasiukajtis 		dummy.op = addss;
1378*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1379*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1380*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1381*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1382*25c28e83SPiotr Jasiukajtis 		}
1383*25c28e83SPiotr Jasiukajtis 		break;
1384*25c28e83SPiotr Jasiukajtis 
1385*25c28e83SPiotr Jasiukajtis 	case subps:
1386*25c28e83SPiotr Jasiukajtis 		dummy.op = subss;
1387*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1388*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1389*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1390*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1391*25c28e83SPiotr Jasiukajtis 		}
1392*25c28e83SPiotr Jasiukajtis 		break;
1393*25c28e83SPiotr Jasiukajtis 
1394*25c28e83SPiotr Jasiukajtis 	case mulps:
1395*25c28e83SPiotr Jasiukajtis 		dummy.op = mulss;
1396*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1397*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1398*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1399*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1400*25c28e83SPiotr Jasiukajtis 		}
1401*25c28e83SPiotr Jasiukajtis 		break;
1402*25c28e83SPiotr Jasiukajtis 
1403*25c28e83SPiotr Jasiukajtis 	case divps:
1404*25c28e83SPiotr Jasiukajtis 		dummy.op = divss;
1405*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1406*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1407*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1408*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1409*25c28e83SPiotr Jasiukajtis 		}
1410*25c28e83SPiotr Jasiukajtis 		break;
1411*25c28e83SPiotr Jasiukajtis 
1412*25c28e83SPiotr Jasiukajtis 	case sqrtps:
1413*25c28e83SPiotr Jasiukajtis 		dummy.op = sqrtss;
1414*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1415*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1416*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1417*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1418*25c28e83SPiotr Jasiukajtis 		}
1419*25c28e83SPiotr Jasiukajtis 		break;
1420*25c28e83SPiotr Jasiukajtis 
1421*25c28e83SPiotr Jasiukajtis 	case cvtdq2ps:
1422*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2ss;
1423*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1424*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1425*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
1426*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1427*25c28e83SPiotr Jasiukajtis 		}
1428*25c28e83SPiotr Jasiukajtis 		break;
1429*25c28e83SPiotr Jasiukajtis 
1430*25c28e83SPiotr Jasiukajtis 	case cvttps2dq:
1431*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttss2si;
1432*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1433*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1434*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1435*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1436*25c28e83SPiotr Jasiukajtis 		}
1437*25c28e83SPiotr Jasiukajtis 		break;
1438*25c28e83SPiotr Jasiukajtis 
1439*25c28e83SPiotr Jasiukajtis 	case cvtps2dq:
1440*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2si;
1441*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 4; i++) {
1442*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1443*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1444*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1445*25c28e83SPiotr Jasiukajtis 		}
1446*25c28e83SPiotr Jasiukajtis 		break;
1447*25c28e83SPiotr Jasiukajtis 
1448*25c28e83SPiotr Jasiukajtis 	case cvtpi2ps:
1449*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2ss;
1450*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1451*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1452*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
1453*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1454*25c28e83SPiotr Jasiukajtis 		}
1455*25c28e83SPiotr Jasiukajtis 		break;
1456*25c28e83SPiotr Jasiukajtis 
1457*25c28e83SPiotr Jasiukajtis 	case cvttps2pi:
1458*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttss2si;
1459*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1460*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1461*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1462*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1463*25c28e83SPiotr Jasiukajtis 		}
1464*25c28e83SPiotr Jasiukajtis 		break;
1465*25c28e83SPiotr Jasiukajtis 
1466*25c28e83SPiotr Jasiukajtis 	case cvtps2pi:
1467*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2si;
1468*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1469*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1470*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1471*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1472*25c28e83SPiotr Jasiukajtis 		}
1473*25c28e83SPiotr Jasiukajtis 		break;
1474*25c28e83SPiotr Jasiukajtis 
1475*25c28e83SPiotr Jasiukajtis 	case cmppd:
1476*25c28e83SPiotr Jasiukajtis 		dummy.op = cmpsd;
1477*25c28e83SPiotr Jasiukajtis 		dummy.imm = inst->imm;
1478*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1479*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1480*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1481*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1482*25c28e83SPiotr Jasiukajtis 		}
1483*25c28e83SPiotr Jasiukajtis 		break;
1484*25c28e83SPiotr Jasiukajtis 
1485*25c28e83SPiotr Jasiukajtis 	case minpd:
1486*25c28e83SPiotr Jasiukajtis 		dummy.op = minsd;
1487*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1488*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1489*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1490*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1491*25c28e83SPiotr Jasiukajtis 		}
1492*25c28e83SPiotr Jasiukajtis 		break;
1493*25c28e83SPiotr Jasiukajtis 
1494*25c28e83SPiotr Jasiukajtis 	case maxpd:
1495*25c28e83SPiotr Jasiukajtis 		dummy.op = maxsd;
1496*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1497*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1498*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1499*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1500*25c28e83SPiotr Jasiukajtis 		}
1501*25c28e83SPiotr Jasiukajtis 		break;
1502*25c28e83SPiotr Jasiukajtis 
1503*25c28e83SPiotr Jasiukajtis 	case addpd:
1504*25c28e83SPiotr Jasiukajtis 		dummy.op = addsd;
1505*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1506*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1507*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1508*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1509*25c28e83SPiotr Jasiukajtis 		}
1510*25c28e83SPiotr Jasiukajtis 		break;
1511*25c28e83SPiotr Jasiukajtis 
1512*25c28e83SPiotr Jasiukajtis 	case subpd:
1513*25c28e83SPiotr Jasiukajtis 		dummy.op = subsd;
1514*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1515*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1516*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1517*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1518*25c28e83SPiotr Jasiukajtis 		}
1519*25c28e83SPiotr Jasiukajtis 		break;
1520*25c28e83SPiotr Jasiukajtis 
1521*25c28e83SPiotr Jasiukajtis 	case mulpd:
1522*25c28e83SPiotr Jasiukajtis 		dummy.op = mulsd;
1523*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1524*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1525*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1526*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1527*25c28e83SPiotr Jasiukajtis 		}
1528*25c28e83SPiotr Jasiukajtis 		break;
1529*25c28e83SPiotr Jasiukajtis 
1530*25c28e83SPiotr Jasiukajtis 	case divpd:
1531*25c28e83SPiotr Jasiukajtis 		dummy.op = divsd;
1532*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1533*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1534*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1535*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1536*25c28e83SPiotr Jasiukajtis 		}
1537*25c28e83SPiotr Jasiukajtis 		break;
1538*25c28e83SPiotr Jasiukajtis 
1539*25c28e83SPiotr Jasiukajtis 	case sqrtpd:
1540*25c28e83SPiotr Jasiukajtis 		dummy.op = sqrtsd;
1541*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1542*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1543*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1544*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1545*25c28e83SPiotr Jasiukajtis 		}
1546*25c28e83SPiotr Jasiukajtis 		break;
1547*25c28e83SPiotr Jasiukajtis 
1548*25c28e83SPiotr Jasiukajtis 	case cvtpi2pd:
1549*25c28e83SPiotr Jasiukajtis 	case cvtdq2pd:
1550*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsi2sd;
1551*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1552*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1553*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->i[i];
1554*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1555*25c28e83SPiotr Jasiukajtis 		}
1556*25c28e83SPiotr Jasiukajtis 		break;
1557*25c28e83SPiotr Jasiukajtis 
1558*25c28e83SPiotr Jasiukajtis 	case cvttpd2pi:
1559*25c28e83SPiotr Jasiukajtis 	case cvttpd2dq:
1560*25c28e83SPiotr Jasiukajtis 		dummy.op = cvttsd2si;
1561*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1562*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1563*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1564*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1565*25c28e83SPiotr Jasiukajtis 		}
1566*25c28e83SPiotr Jasiukajtis 		/* for cvttpd2dq, zero the high 64 bits of the destination */
1567*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvttpd2dq)
1568*25c28e83SPiotr Jasiukajtis 			inst->op1->l[1] = 0ll;
1569*25c28e83SPiotr Jasiukajtis 		break;
1570*25c28e83SPiotr Jasiukajtis 
1571*25c28e83SPiotr Jasiukajtis 	case cvtpd2pi:
1572*25c28e83SPiotr Jasiukajtis 	case cvtpd2dq:
1573*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsd2si;
1574*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1575*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->i[i];
1576*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1577*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1578*25c28e83SPiotr Jasiukajtis 		}
1579*25c28e83SPiotr Jasiukajtis 		/* for cvtpd2dq, zero the high 64 bits of the destination */
1580*25c28e83SPiotr Jasiukajtis 		if (inst->op == cvtpd2dq)
1581*25c28e83SPiotr Jasiukajtis 			inst->op1->l[1] = 0ll;
1582*25c28e83SPiotr Jasiukajtis 		break;
1583*25c28e83SPiotr Jasiukajtis 
1584*25c28e83SPiotr Jasiukajtis 	case cvtps2pd:
1585*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtss2sd;
1586*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1587*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->d[i];
1588*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->f[i];
1589*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1590*25c28e83SPiotr Jasiukajtis 		}
1591*25c28e83SPiotr Jasiukajtis 		break;
1592*25c28e83SPiotr Jasiukajtis 
1593*25c28e83SPiotr Jasiukajtis 	case cvtpd2ps:
1594*25c28e83SPiotr Jasiukajtis 		dummy.op = cvtsd2ss;
1595*25c28e83SPiotr Jasiukajtis 		for (i = 0; i < 2; i++) {
1596*25c28e83SPiotr Jasiukajtis 			dummy.op1 = (sseoperand_t *)&inst->op1->f[i];
1597*25c28e83SPiotr Jasiukajtis 			dummy.op2 = (sseoperand_t *)&inst->op2->d[i];
1598*25c28e83SPiotr Jasiukajtis 			__fex_st_sse_result(uap, &dummy, e[i], &info[i]);
1599*25c28e83SPiotr Jasiukajtis 		}
1600*25c28e83SPiotr Jasiukajtis 		/* zero the high 64 bits of the destination */
1601*25c28e83SPiotr Jasiukajtis 		inst->op1->l[1] = 0ll;
1602*25c28e83SPiotr Jasiukajtis 
1603*25c28e83SPiotr Jasiukajtis 	default:
1604*25c28e83SPiotr Jasiukajtis 		break;
1605*25c28e83SPiotr Jasiukajtis 	}
1606*25c28e83SPiotr Jasiukajtis }
1607*25c28e83SPiotr Jasiukajtis 
1608