Print this page
11210 libm should be cstyle(1ONBLD) clean
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/m9x/__fex_i386.c
+++ new/usr/src/lib/libm/common/m9x/__fex_i386.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 +
25 26 /*
26 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 28 * Use is subject to license terms.
28 29 */
29 30
30 31 #include <stdio.h>
31 32 #include <unistd.h>
32 33 #include <stdlib.h>
33 34 #include <string.h>
34 35 #include <signal.h>
35 36 #include <siginfo.h>
36 37 #include <ucontext.h>
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
37 38 #include <thread.h>
38 39 #include <math.h>
39 40 #if defined(__SUNPRO_C)
40 41 #include <sunmath.h>
41 42 #endif
42 43 #include <fenv.h>
43 44 #include "fex_handler.h"
44 45 #include "fenv_inlines.h"
45 46
46 47 #if defined(__amd64)
47 -#define test_sse_hw 1
48 +#define test_sse_hw 1
48 49 #else
49 50 /*
50 51 * The following variable lives in libc on Solaris 10, where it
51 52 * gets set to a nonzero value at startup time on systems with SSE.
52 53 */
53 54 extern int _sse_hw;
54 -#define test_sse_hw _sse_hw
55 +
56 +#define test_sse_hw _sse_hw
55 57 #endif
56 58
57 59 static int accrued = 0;
58 60 static thread_key_t accrued_key;
59 61 static mutex_t accrued_key_lock = DEFAULTMUTEX;
60 -
61 62 int *
62 63 __fex_accrued()
63 64 {
64 - int *p;
65 + int *p;
65 66
66 - if (thr_main())
67 - return &accrued;
68 - else {
67 + if (thr_main()) {
68 + return (&accrued);
69 + } else {
69 70 p = NULL;
70 71 mutex_lock(&accrued_key_lock);
72 +
71 73 if (thr_getspecific(accrued_key, (void **)&p) != 0 &&
72 - thr_keycreate(&accrued_key, free) != 0) {
74 + thr_keycreate(&accrued_key, free) != 0) {
73 75 mutex_unlock(&accrued_key_lock);
74 - return NULL;
76 + return (NULL);
75 77 }
78 +
76 79 mutex_unlock(&accrued_key_lock);
80 +
77 81 if (!p) {
78 - if ((p = (int*) malloc(sizeof(int))) == NULL)
79 - return NULL;
82 + if ((p = (int *)malloc(sizeof (int))) == NULL)
83 + return (NULL);
84 +
80 85 if (thr_setspecific(accrued_key, (void *)p) != 0) {
81 - (void)free(p);
82 - return NULL;
86 + (void) free(p);
87 + return (NULL);
83 88 }
89 +
84 90 *p = 0;
85 91 }
86 - return p;
92 +
93 + return (p);
87 94 }
88 95 }
89 96
90 97 void
91 98 __fenv_getfsr(unsigned long *fsr)
92 99 {
93 - unsigned int cwsw, mxcsr;
100 + unsigned int cwsw, mxcsr;
94 101
95 102 __fenv_getcwsw(&cwsw);
96 103 /* clear reserved bits for no particularly good reason */
97 104 cwsw &= ~0xe0c00000u;
105 +
98 106 if (test_sse_hw) {
99 - /* pick up exception flags (excluding denormal operand
100 - flag) from mxcsr */
107 + /*
108 + * pick up exception flags (excluding denormal operand flag)
109 + * from mxcsr
110 + */
101 111 __fenv_getmxcsr(&mxcsr);
102 112 cwsw |= (mxcsr & 0x3d);
103 113 }
114 +
104 115 cwsw |= *__fex_accrued();
105 116 *fsr = cwsw ^ 0x003f0000u;
106 117 }
107 118
108 119 void
109 120 __fenv_setfsr(const unsigned long *fsr)
110 121 {
111 - unsigned int cwsw, mxcsr;
112 - int te;
122 + unsigned int cwsw, mxcsr;
123 + int te;
113 124
114 125 /* save accrued exception flags corresponding to enabled exceptions */
115 126 cwsw = (unsigned int)*fsr;
116 127 te = __fenv_get_te(cwsw);
117 128 *__fex_accrued() = cwsw & te;
118 129 cwsw = (cwsw & ~te) ^ 0x003f0000;
130 +
119 131 if (test_sse_hw) {
120 - /* propagate rounding direction, masks, and exception flags
121 - (excluding denormal operand mask and flag) to mxcsr */
132 + /*
133 + * propagate rounding direction, masks, and exception flags
134 + * (excluding denormal operand mask and flag) to mxcsr
135 + */
122 136 __fenv_getmxcsr(&mxcsr);
123 - mxcsr = (mxcsr & ~0x7ebd) | ((cwsw >> 13) & 0x6000) |
124 - ((cwsw >> 9) & 0x1e80) | (cwsw & 0x3d);
137 + mxcsr = (mxcsr & ~0x7ebd) | ((cwsw >> 13) & 0x6000) | ((cwsw >>
138 + 9) & 0x1e80) | (cwsw & 0x3d);
125 139 __fenv_setmxcsr(&mxcsr);
126 140 }
141 +
127 142 __fenv_setcwsw(&cwsw);
128 143 }
129 144
130 145 /* Offsets into the fp environment save area (assumes 32-bit protected mode) */
131 -#define CW 0 /* control word */
132 -#define SW 1 /* status word */
133 -#define TW 2 /* tag word */
134 -#define IP 3 /* instruction pointer */
135 -#define OP 4 /* opcode */
136 -#define EA 5 /* operand address */
146 +#define CW 0 /* control word */
147 +#define SW 1 /* status word */
148 +#define TW 2 /* tag word */
149 +#define IP 3 /* instruction pointer */
150 +#define OP 4 /* opcode */
151 +#define EA 5 /* operand address */
137 152
138 153 /* macro for accessing fp registers in the save area */
139 154 #if defined(__amd64)
140 -#define fpreg(u,x) *(long double *)(10*(x)+(char*)&(u)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.st)
155 +#define fpreg(u, x) *(long double *)(10 * (x) + \
156 + (char *)&(u)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.st)
141 157 #else
142 -#define fpreg(u,x) *(long double *)(10*(x)+(char*)&(u)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[7])
158 +#define fpreg(u, x) *(long double *)(10 * (x) + \
159 + (char *)&(u)->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[7])
143 160 #endif
144 161
145 162 /*
146 -* Fix sip->si_code; the Solaris x86 kernel can get it wrong
147 -*/
163 + * Fix sip->si_code; the Solaris x86 kernel can get it wrong
164 + */
148 165 void
149 166 __fex_get_x86_exc(siginfo_t *sip, ucontext_t *uap)
150 167 {
151 - unsigned sw, cw;
168 + unsigned sw, cw;
152 169
153 170 sw = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status;
154 171 #if defined(__amd64)
155 172 cw = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw;
156 173 #else
157 174 cw = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[CW];
158 175 #endif
176 +
159 177 if ((sw & FE_INVALID) && !(cw & (1 << fp_trap_invalid)))
160 178 /* store 0 for stack fault, FPE_FLTINV for IEEE invalid op */
161 - sip->si_code = ((sw & 0x40)? 0 : FPE_FLTINV);
179 + sip->si_code = ((sw & 0x40) ? 0 : FPE_FLTINV);
162 180 else if ((sw & FE_DIVBYZERO) && !(cw & (1 << fp_trap_division)))
163 181 sip->si_code = FPE_FLTDIV;
164 182 else if ((sw & FE_OVERFLOW) && !(cw & (1 << fp_trap_overflow)))
165 183 sip->si_code = FPE_FLTOVF;
166 184 else if ((sw & FE_UNDERFLOW) && !(cw & (1 << fp_trap_underflow)))
167 185 sip->si_code = FPE_FLTUND;
168 186 else if ((sw & FE_INEXACT) && !(cw & (1 << fp_trap_inexact)))
169 187 sip->si_code = FPE_FLTRES;
170 188 else
171 189 sip->si_code = 0;
172 190 }
173 191
174 192 static enum fp_class_type
175 193 my_fp_classf(float *x)
176 194 {
177 - int i = *(int*)x & ~0x80000000;
195 + int i = *(int *)x & ~0x80000000;
178 196
179 197 if (i < 0x7f800000) {
180 198 if (i < 0x00800000)
181 - return ((i == 0)? fp_zero : fp_subnormal);
182 - return fp_normal;
199 + return ((i == 0) ? fp_zero : fp_subnormal);
200 +
201 + return (fp_normal);
202 + } else if (i == 0x7f800000) {
203 + return (fp_infinity);
204 + } else if (i & 0x400000) {
205 + return (fp_quiet);
206 + } else {
207 + return (fp_signaling);
183 208 }
184 - else if (i == 0x7f800000)
185 - return fp_infinity;
186 - else if (i & 0x400000)
187 - return fp_quiet;
188 - else
189 - return fp_signaling;
190 209 }
191 210
192 211 static enum fp_class_type
193 212 my_fp_class(double *x)
194 213 {
195 - int i = *(1+(int*)x) & ~0x80000000;
214 + int i = *(1 + (int *)x) & ~0x80000000;
196 215
197 216 if (i < 0x7ff00000) {
198 217 if (i < 0x00100000)
199 - return (((i | *(int*)x) == 0)? fp_zero : fp_subnormal);
200 - return fp_normal;
218 + return (((i | *(int *)x) == 0) ? fp_zero :
219 + fp_subnormal);
220 +
221 + return (fp_normal);
222 + } else if (i == 0x7ff00000 && *(int *)x == 0) {
223 + return (fp_infinity);
224 + } else if (i & 0x80000) {
225 + return (fp_quiet);
226 + } else {
227 + return (fp_signaling);
201 228 }
202 - else if (i == 0x7ff00000 && *(int*)x == 0)
203 - return fp_infinity;
204 - else if (i & 0x80000)
205 - return fp_quiet;
206 - else
207 - return fp_signaling;
208 229 }
209 230
210 231 static enum fp_class_type
211 232 my_fp_classl(long double *x)
212 233 {
213 - int i = *(2+(int*)x) & 0x7fff;
234 + int i = *(2 + (int *)x) & 0x7fff;
214 235
215 236 if (i < 0x7fff) {
216 237 if (i < 1) {
217 - if (*(1+(int*)x) < 0) return fp_normal; /* pseudo-denormal */
218 - return (((*(1+(int*)x) | *(int*)x) == 0)?
219 - fp_zero : fp_subnormal);
238 + if (*(1 + (int *)x) < 0)
239 + return (fp_normal); /* pseudo-denormal */
240 +
241 + return (((*(1 + (int *)x) | *(int *)x) == 0) ? fp_zero :
242 + fp_subnormal);
220 243 }
221 - return ((*(1+(int*)x) < 0)? fp_normal :
222 - (enum fp_class_type) -1); /* unsupported format */
244 +
245 + return ((*(1 + (int *)x) < 0) ? fp_normal :
246 + (enum fp_class_type)-1); /* unsupported format */
247 + } else if (*(1 + (int *)x) == 0x80000000 && *(int *)x == 0) {
248 + return (fp_infinity);
249 + } else if (*(1 + (unsigned *)x) >= 0xc0000000) {
250 + return (fp_quiet);
251 + } else if (*(1 + (int *)x) < 0) {
252 + return (fp_signaling);
253 + } else {
254 + return ((enum fp_class_type)-1); /* unsupported format */
223 255 }
224 - else if (*(1+(int*)x) == 0x80000000 && *(int*)x == 0)
225 - return fp_infinity;
226 - else if (*(1+(unsigned*)x) >= 0xc0000000)
227 - return fp_quiet;
228 - else if (*(1+(int*)x) < 0)
229 - return fp_signaling;
230 - else
231 - return (enum fp_class_type) -1; /* unsupported format */
232 256 }
233 257
234 258 /*
235 -* Determine which type of invalid operation exception occurred
236 -*/
259 + * Determine which type of invalid operation exception occurred
260 + */
237 261 enum fex_exception
238 262 __fex_get_invalid_type(siginfo_t *sip, ucontext_t *uap)
239 263 {
240 - unsigned op;
241 - unsigned long ea;
242 - enum fp_class_type t1, t2;
264 + unsigned op;
265 + unsigned long ea;
266 + enum fp_class_type t1, t2;
243 267
244 268 /* get the opcode and data address */
245 269 #if defined(__amd64)
246 270 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.fop >> 16;
247 271 ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.rdp;
248 272 #else
249 273 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[OP] >> 16;
250 274 ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[EA];
251 275 #endif
252 276
253 - /* if the instruction is fld, the source must be snan (it can't be
254 - an unsupported format, since fldt doesn't raise any exceptions) */
277 + /*
278 + * if the instruction is fld, the source must be snan (it can't be
279 + * an unsupported format, since fldt doesn't raise any exceptions)
280 + */
255 281 switch (op & 0x7f8) {
256 282 case 0x100:
257 283 case 0x140:
258 284 case 0x180:
259 285 case 0x500:
260 286 case 0x540:
261 287 case 0x580:
262 - return fex_inv_snan;
288 + return (fex_inv_snan);
263 289 }
264 290
265 291 /* otherwise st is one of the operands; see if it's snan */
266 292 t1 = my_fp_classl(&fpreg(uap, 0));
293 +
267 294 if (t1 == fp_signaling)
268 - return fex_inv_snan;
269 - else if (t1 == (enum fp_class_type) -1)
270 - return (enum fex_exception) -1;
295 + return (fex_inv_snan);
296 + else if (t1 == (enum fp_class_type)-1)
297 + return ((enum fex_exception)-1);
271 298
272 299 /* determine the class of the second operand if there is one */
273 300 t2 = fp_normal;
301 +
274 302 switch (op & 0x7e0) {
275 303 case 0x600:
276 304 case 0x620:
277 305 case 0x640:
278 306 case 0x660:
279 307 case 0x680:
280 308 case 0x6a0:
309 +
281 310 /* short memory operand */
282 311 if (!ea)
283 - return (enum fex_exception) -1;
312 + return ((enum fex_exception)-1);
313 +
284 314 if (*(short *)ea == 0)
285 315 t2 = fp_zero;
316 +
286 317 break;
287 318
288 319 case 0x200:
289 320 case 0x220:
290 321 case 0x240:
291 322 case 0x260:
292 323 case 0x280:
293 324 case 0x2a0:
325 +
294 326 /* int memory operand */
295 327 if (!ea)
296 - return (enum fex_exception) -1;
328 + return ((enum fex_exception)-1);
329 +
297 330 if (*(int *)ea == 0)
298 331 t2 = fp_zero;
332 +
299 333 break;
300 334
301 335 case 0x000:
302 336 case 0x020:
303 337 case 0x040:
304 338 case 0x060:
305 339 case 0x080:
306 340 case 0x0a0:
341 +
307 342 /* single precision memory operand */
308 343 if (!ea)
309 - return (enum fex_exception) -1;
344 + return ((enum fex_exception)-1);
345 +
310 346 t2 = my_fp_classf((float *)ea);
311 347 break;
312 348
313 349 case 0x400:
314 350 case 0x420:
315 351 case 0x440:
316 352 case 0x460:
317 353 case 0x480:
318 354 case 0x4a0:
355 +
319 356 /* double precision memory operand */
320 357 if (!ea)
321 - return (enum fex_exception) -1;
358 + return ((enum fex_exception)-1);
359 +
322 360 t2 = my_fp_class((double *)ea);
323 361 break;
324 362
325 363 case 0x0c0:
326 364 case 0x0e0:
327 365 case 0x3e0:
328 366 case 0x4c0:
329 367 case 0x4e0:
330 368 case 0x5e0:
331 369 case 0x6c0:
332 370 case 0x6e0:
333 371 case 0x7e0:
372 +
334 373 /* register operand determined by opcode */
335 374 switch (op & 0x7f8) {
336 375 case 0x3e0:
337 376 case 0x3f8:
338 377 case 0x5f0:
339 378 case 0x5f8:
340 379 case 0x7e0:
341 380 case 0x7f8:
342 381 /* weed out nonexistent opcodes */
343 382 break;
344 383
345 384 default:
346 385 t2 = my_fp_classl(&fpreg(uap, op & 7));
347 386 }
387 +
348 388 break;
349 389
350 390 case 0x1e0:
351 391 case 0x2e0:
392 +
352 393 /* special forms */
353 394 switch (op) {
354 - case 0x1f1: /* fyl2x */
355 - case 0x1f3: /* fpatan */
356 - case 0x1f5: /* fprem1 */
357 - case 0x1f8: /* fprem */
358 - case 0x1f9: /* fyl2xp1 */
359 - case 0x1fd: /* fscale */
360 - case 0x2e9: /* fucompp */
395 + case 0x1f1: /* fyl2x */
396 + case 0x1f3: /* fpatan */
397 + case 0x1f5: /* fprem1 */
398 + case 0x1f8: /* fprem */
399 + case 0x1f9: /* fyl2xp1 */
400 + case 0x1fd: /* fscale */
401 + case 0x2e9: /* fucompp */
361 402 t2 = my_fp_classl(&fpreg(uap, 1));
362 403 break;
363 404 }
405 +
364 406 break;
365 407 }
366 408
367 409 /* see if the second op is snan */
368 410 if (t2 == fp_signaling)
369 - return fex_inv_snan;
370 - else if (t2 == (enum fp_class_type) -1)
371 - return (enum fex_exception) -1;
411 + return (fex_inv_snan);
412 + else if (t2 == (enum fp_class_type)-1)
413 + return ((enum fex_exception)-1);
372 414
373 415 /* determine the type of operation */
374 416 switch (op & 0x7f8) {
375 417 case 0x000:
376 418 case 0x020:
377 419 case 0x028:
378 420 case 0x040:
379 421 case 0x060:
380 422 case 0x068:
381 423 case 0x080:
382 424 case 0x0a0:
383 425 case 0x0a8:
384 426 case 0x0c0:
385 427 case 0x0e0:
386 428 case 0x0e8:
387 429 case 0x400:
388 430 case 0x420:
389 431 case 0x428:
390 432 case 0x440:
391 433 case 0x460:
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
392 434 case 0x468:
393 435 case 0x480:
394 436 case 0x4a0:
395 437 case 0x4a8:
396 438 case 0x4c0:
397 439 case 0x4e0:
398 440 case 0x4e8:
399 441 case 0x6c0:
400 442 case 0x6e0:
401 443 case 0x6e8:
444 +
402 445 /* fadd, fsub, fsubr */
403 446 if (t1 == fp_infinity && t2 == fp_infinity)
404 - return fex_inv_isi;
447 + return (fex_inv_isi);
448 +
405 449 break;
406 450
407 451 case 0x008:
408 452 case 0x048:
409 453 case 0x088:
410 454 case 0x0c8:
411 455 case 0x208:
412 456 case 0x248:
413 457 case 0x288:
414 458 case 0x408:
415 459 case 0x448:
416 460 case 0x488:
417 461 case 0x4c8:
418 462 case 0x608:
419 463 case 0x648:
420 464 case 0x688:
421 465 case 0x6c8:
466 +
422 467 /* fmul */
423 468 if ((t1 == fp_zero && t2 == fp_infinity) || (t2 == fp_zero &&
424 - t1 == fp_infinity))
425 - return fex_inv_zmi;
469 + t1 == fp_infinity))
470 + return (fex_inv_zmi);
471 +
426 472 break;
427 473
428 474 case 0x030:
429 475 case 0x038:
430 476 case 0x070:
431 477 case 0x078:
432 478 case 0x0b0:
433 479 case 0x0b8:
434 480 case 0x0f0:
435 481 case 0x0f8:
436 482 case 0x230:
437 483 case 0x238:
438 484 case 0x270:
439 485 case 0x278:
440 486 case 0x2b0:
441 487 case 0x2b8:
442 488 case 0x430:
443 489 case 0x438:
444 490 case 0x470:
445 491 case 0x478:
446 492 case 0x4b0:
447 493 case 0x4b8:
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
448 494 case 0x4f0:
449 495 case 0x4f8:
450 496 case 0x630:
451 497 case 0x638:
452 498 case 0x670:
453 499 case 0x678:
454 500 case 0x6b0:
455 501 case 0x6b8:
456 502 case 0x6f0:
457 503 case 0x6f8:
504 +
458 505 /* fdiv */
459 506 if (t1 == fp_zero && t2 == fp_zero)
460 - return fex_inv_zdz;
507 + return (fex_inv_zdz);
461 508 else if (t1 == fp_infinity && t2 == fp_infinity)
462 - return fex_inv_idi;
509 + return (fex_inv_idi);
510 +
463 511 break;
464 512
465 513 case 0x1f0:
466 514 case 0x1f8:
467 515 /* fsqrt, other special ops */
468 - return fex_inv_sqrt;
516 + return (fex_inv_sqrt);
469 517
470 518 case 0x010:
471 519 case 0x018:
472 520 case 0x050:
473 521 case 0x058:
474 522 case 0x090:
475 523 case 0x098:
476 524 case 0x0d0:
477 525 case 0x0d8:
478 526 case 0x210:
479 527 case 0x218:
480 528 case 0x250:
481 529 case 0x258:
482 530 case 0x290:
483 531 case 0x298:
484 532 case 0x2e8:
485 533 case 0x3f0:
486 534 case 0x410:
487 535 case 0x418:
488 536 case 0x450:
489 537 case 0x458:
490 538 case 0x490:
491 539 case 0x498:
492 540 case 0x4d0:
493 541 case 0x4d8:
494 542 case 0x5e0:
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
495 543 case 0x5e8:
496 544 case 0x610:
497 545 case 0x618:
498 546 case 0x650:
499 547 case 0x658:
500 548 case 0x690:
501 549 case 0x698:
502 550 case 0x6d0:
503 551 case 0x6d8:
504 552 case 0x7f0:
553 +
505 554 /* fcom */
506 555 if (t1 == fp_quiet || t2 == fp_quiet)
507 - return fex_inv_cmp;
556 + return (fex_inv_cmp);
557 +
508 558 break;
509 559
510 560 case 0x1e0:
561 +
511 562 /* ftst */
512 563 if (op == 0x1e4 && t1 == fp_quiet)
513 - return fex_inv_cmp;
564 + return (fex_inv_cmp);
565 +
514 566 break;
515 567
516 568 case 0x310:
517 569 case 0x318:
518 570 case 0x350:
519 571 case 0x358:
520 572 case 0x390:
521 573 case 0x398:
522 574 case 0x710:
523 575 case 0x718:
524 576 case 0x730:
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
525 577 case 0x738:
526 578 case 0x750:
527 579 case 0x758:
528 580 case 0x770:
529 581 case 0x778:
530 582 case 0x790:
531 583 case 0x798:
532 584 case 0x7b0:
533 585 case 0x7b8:
534 586 /* fist, fbst */
535 - return fex_inv_int;
587 + return (fex_inv_int);
536 588 }
537 589
538 - return (enum fex_exception) -1;
590 + return ((enum fex_exception)-1);
539 591 }
540 592
541 593 /* scale factors for exponent unwrapping */
594 +/* 2^12288 */
595 +static const long double
596 + two12288 = 1.139165225263043370845938579315932009e+3699l;
597 +/* 2^-12288 */
542 598 static const long double
543 - two12288 = 1.139165225263043370845938579315932009e+3699l, /* 2^12288 */
544 - twom12288 = 8.778357852076208839765066529179033145e-3700l, /* 2^-12288 */
545 - twom12288mulp = 8.778357852076208839289190796475222545e-3700l;
546 - /* (")*(1-2^-64) */
599 + twom12288 = 8.778357852076208839765066529179033145e-3700l;
600 +/* (")*(1-2^-64) */
601 +static const long double
602 + twom12288mulp = 8.778357852076208839289190796475222545e-3700l;
547 603
548 604 /* inline templates */
549 605 extern long double f2xm1(long double);
550 606 extern long double fyl2x(long double, long double);
551 607 extern long double fptan(long double);
552 608 extern long double fpatan(long double, long double);
553 609 extern long double fxtract(long double);
554 610 extern long double fprem1(long double, long double);
555 611 extern long double fprem(long double, long double);
556 612 extern long double fyl2xp1(long double, long double);
557 613 extern long double fsqrt(long double);
558 614 extern long double fsincos(long double);
559 615 extern long double frndint(long double);
560 616 extern long double fscale(long double, long double);
561 617 extern long double fsin(long double);
562 618 extern long double fcos(long double);
563 619
564 620 /*
565 -* Get the operands, generate the default untrapped result with
566 -* exceptions, and set a code indicating the type of operation
567 -*/
621 + * Get the operands, generate the default untrapped result with
622 + * exceptions, and set a code indicating the type of operation
623 + */
568 624 void
569 625 __fex_get_op(siginfo_t *sip, ucontext_t *uap, fex_info_t *info)
570 626 {
571 - fex_numeric_t t;
572 - long double op2v, x;
573 - unsigned int cwsw, ex, sw, op;
574 - unsigned long ea;
575 - volatile int c __unused;
627 + fex_numeric_t t;
628 + long double op2v, x;
629 + unsigned int cwsw, ex, sw, op;
630 + unsigned long ea;
631 + volatile int c __unused;
576 632
577 633 /* get the exception type, status word, opcode, and data address */
578 634 ex = sip->si_code;
579 635 sw = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status;
580 636 #if defined(__amd64)
581 637 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.fop >> 16;
582 638 ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.rdp;
583 639 #else
584 640 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[OP] >> 16;
585 641 ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[EA];
586 642 #endif
587 643
588 - /* initialize res to the default untrapped result and ex to the
589 - corresponding flags (assume trapping is disabled and flags
590 - are clear) */
644 + /*
645 + * initialize res to the default untrapped result and ex to the
646 + * corresponding flags (assume trapping is disabled and flags are
647 + * clear)
648 + */
591 649
592 650 /* single operand instructions */
593 651 info->op = fex_cnvt;
594 652 info->op2.type = fex_nodata;
653 +
595 654 switch (op & 0x7f8) {
596 655 /* load instructions */
597 656 case 0x100:
598 657 case 0x140:
599 658 case 0x180:
659 +
600 660 if (!ea) {
601 661 info->op = fex_other;
602 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
662 + info->op1.type = info->op2.type = info->res.type =
663 + fex_nodata;
603 664 info->flags = 0;
604 665 return;
605 666 }
667 +
606 668 info->op1.type = fex_float;
607 669 info->op1.val.f = *(float *)ea;
608 670 info->res.type = fex_ldouble;
609 - info->res.val.q = (long double) info->op1.val.f;
671 + info->res.val.q = (long double)info->op1.val.f;
610 672 goto done;
611 673
612 674 case 0x500:
613 675 case 0x540:
614 676 case 0x580:
677 +
615 678 if (!ea) {
616 679 info->op = fex_other;
617 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
680 + info->op1.type = info->op2.type = info->res.type =
681 + fex_nodata;
618 682 info->flags = 0;
619 683 return;
620 684 }
685 +
621 686 info->op1.type = fex_double;
622 687 info->op1.val.d = *(double *)ea;
623 688 info->res.type = fex_ldouble;
624 - info->res.val.q = (long double) info->op1.val.d;
689 + info->res.val.q = (long double)info->op1.val.d;
625 690 goto done;
626 691
627 692 /* store instructions */
628 693 case 0x110:
629 694 case 0x118:
630 695 case 0x150:
631 696 case 0x158:
632 697 case 0x190:
633 698 case 0x198:
634 699 info->res.type = fex_float;
700 +
635 701 if (ex == FPE_FLTRES && (op & 8) != 0) {
636 702 /* inexact, stack popped */
637 703 if (!ea) {
638 704 info->op = fex_other;
639 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
705 + info->op1.type = info->op2.type =
706 + info->res.type = fex_nodata;
640 707 info->flags = 0;
641 708 return;
642 709 }
710 +
643 711 info->op1.type = fex_nodata;
644 712 info->res.val.f = *(float *)ea;
645 713 info->flags = FE_INEXACT;
646 714 return;
647 715 }
716 +
648 717 info->op1.type = fex_ldouble;
649 718 info->op1.val.q = fpreg(uap, 0);
650 - info->res.val.f = (float) info->op1.val.q;
719 + info->res.val.f = (float)info->op1.val.q;
651 720 goto done;
652 721
653 722 case 0x310:
654 723 case 0x318:
655 724 case 0x350:
656 725 case 0x358:
657 726 case 0x390:
658 727 case 0x398:
659 728 info->res.type = fex_int;
729 +
660 730 if (ex == FPE_FLTRES && (op & 8) != 0) {
661 731 /* inexact, stack popped */
662 732 if (!ea) {
663 733 info->op = fex_other;
664 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
734 + info->op1.type = info->op2.type =
735 + info->res.type = fex_nodata;
665 736 info->flags = 0;
666 737 return;
667 738 }
739 +
668 740 info->op1.type = fex_nodata;
669 741 info->res.val.i = *(int *)ea;
670 742 info->flags = FE_INEXACT;
671 743 return;
672 744 }
745 +
673 746 info->op1.type = fex_ldouble;
674 747 info->op1.val.q = fpreg(uap, 0);
675 - info->res.val.i = (int) info->op1.val.q;
748 + info->res.val.i = (int)info->op1.val.q;
676 749 goto done;
677 750
678 751 case 0x510:
679 752 case 0x518:
680 753 case 0x550:
681 754 case 0x558:
682 755 case 0x590:
683 756 case 0x598:
684 757 info->res.type = fex_double;
758 +
685 759 if (ex == FPE_FLTRES && (op & 8) != 0) {
686 760 /* inexact, stack popped */
687 761 if (!ea) {
688 762 info->op = fex_other;
689 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
763 + info->op1.type = info->op2.type =
764 + info->res.type = fex_nodata;
690 765 info->flags = 0;
691 766 return;
692 767 }
768 +
693 769 info->op1.type = fex_nodata;
694 770 info->res.val.d = *(double *)ea;
695 771 info->flags = FE_INEXACT;
696 772 return;
697 773 }
774 +
698 775 info->op1.type = fex_ldouble;
699 776 info->op1.val.q = fpreg(uap, 0);
700 - info->res.val.d = (double) info->op1.val.q;
777 + info->res.val.d = (double)info->op1.val.q;
701 778 goto done;
702 779
703 780 case 0x710:
704 781 case 0x718:
705 782 case 0x750:
706 783 case 0x758:
707 784 case 0x790:
708 785 case 0x798:
709 786 info->res.type = fex_int;
787 +
710 788 if (ex == FPE_FLTRES && (op & 8) != 0) {
711 789 /* inexact, stack popped */
712 790 if (!ea) {
713 791 info->op = fex_other;
714 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
792 + info->op1.type = info->op2.type =
793 + info->res.type = fex_nodata;
715 794 info->flags = 0;
716 795 return;
717 796 }
797 +
718 798 info->op1.type = fex_nodata;
719 799 info->res.val.i = *(short *)ea;
720 800 info->flags = FE_INEXACT;
721 801 return;
722 802 }
803 +
723 804 info->op1.type = fex_ldouble;
724 805 info->op1.val.q = fpreg(uap, 0);
725 - info->res.val.i = (short) info->op1.val.q;
806 + info->res.val.i = (short)info->op1.val.q;
726 807 goto done;
727 808
728 809 case 0x730:
729 810 case 0x770:
730 811 case 0x7b0:
731 812 /* fbstp; don't bother */
732 813 info->op = fex_other;
733 814 info->op1.type = info->res.type = fex_nodata;
734 815 info->flags = 0;
735 816 return;
736 817
737 818 case 0x738:
738 819 case 0x778:
739 820 case 0x7b8:
740 821 info->res.type = fex_llong;
822 +
741 823 if (ex == FPE_FLTRES) {
742 824 /* inexact, stack popped */
743 825 if (!ea) {
744 826 info->op = fex_other;
745 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
827 + info->op1.type = info->op2.type =
828 + info->res.type = fex_nodata;
746 829 info->flags = 0;
747 830 return;
748 831 }
832 +
749 833 info->op1.type = fex_nodata;
750 834 info->res.val.l = *(long long *)ea;
751 835 info->flags = FE_INEXACT;
752 836 return;
753 837 }
838 +
754 839 info->op1.type = fex_ldouble;
755 840 info->op1.val.q = fpreg(uap, 0);
756 - info->res.val.l = (long long) info->op1.val.q;
841 + info->res.val.l = (long long)info->op1.val.q;
757 842 goto done;
758 843 }
759 844
760 - /* all other ops (except compares) have destinations on the stack
761 - so overflow, underflow, and inexact will stomp their operands */
845 + /*
846 + * all other ops (except compares) have destinations on the stack so
847 + * overflow, underflow, and inexact will stomp their operands
848 + */
762 849 if (ex == FPE_FLTOVF || ex == FPE_FLTUND || ex == FPE_FLTRES) {
763 850 /* find the trapped result */
764 851 info->op1.type = info->op2.type = fex_nodata;
765 852 info->res.type = fex_ldouble;
853 +
766 854 switch (op & 0x7f8) {
767 855 case 0x1f0:
768 856 /* fptan pushes 1.0 afterward, so result is in st(1) */
769 - info->res.val.q = ((op == 0x1f2)? fpreg(uap, 1) :
770 - fpreg(uap, 0));
857 + info->res.val.q = ((op == 0x1f2) ? fpreg(uap, 1) :
858 + fpreg(uap, 0));
771 859 break;
772 860
773 861 case 0x4c0:
774 862 case 0x4c8:
775 863 case 0x4e0:
776 864 case 0x4e8:
777 865 case 0x4f0:
778 866 case 0x4f8:
779 867 info->res.val.q = fpreg(uap, op & 7);
780 868 break;
781 869
782 870 case 0x6c0:
783 871 case 0x6c8:
784 872 case 0x6e0:
785 873 case 0x6e8:
786 874 case 0x6f0:
787 875 case 0x6f8:
788 876 /* stack was popped afterward */
789 877 info->res.val.q = fpreg(uap, (op - 1) & 7);
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
790 878 break;
791 879
792 880 default:
793 881 info->res.val.q = fpreg(uap, 0);
794 882 }
795 883
796 884 /* reconstruct default untrapped result */
797 885 if (ex == FPE_FLTOVF) {
798 886 /* generate an overflow with the sign of the result */
799 887 x = two12288;
800 - *(4+(short*)&x) |= (*(4+(short*)&info->res.val.q) & 0x8000);
888 + *(4 + (short *)&x) |= (*(4 +
889 + (short *)&info->res.val.q) & 0x8000);
801 890 info->res.val.q = x * two12288;
802 891 info->flags = FE_OVERFLOW | FE_INEXACT;
803 892 __fenv_getcwsw(&cwsw);
804 893 cwsw &= ~FE_ALL_EXCEPT;
805 894 __fenv_setcwsw(&cwsw);
806 - }
807 - else if (ex == FPE_FLTUND) {
808 - /* undo the scaling; we can't distinguish a chopped result
809 - from an exact one without futzing around to trap all in-
810 - exact exceptions so as to keep the flag clear, so we just
811 - punt */
812 - if (sw & 0x200) /* result was rounded up */
813 - info->res.val.q = (info->res.val.q * twom12288) * twom12288mulp;
895 + } else if (ex == FPE_FLTUND) {
896 + /*
897 + * undo the scaling; we can't distinguish a chopped
898 + * result from an exact one without futzing around to
899 + * trap all in- exact exceptions so as to keep the
900 + * flag clear, so we just punt
901 + */
902 + if (sw & 0x200) /* result was rounded up */
903 + info->res.val.q = (info->res.val.q *
904 + twom12288) * twom12288mulp;
814 905 else
815 - info->res.val.q = (info->res.val.q * twom12288) * twom12288;
906 + info->res.val.q = (info->res.val.q *
907 + twom12288) * twom12288;
908 +
816 909 __fenv_getcwsw(&cwsw);
817 910 info->flags = (cwsw & FE_INEXACT) | FE_UNDERFLOW;
818 911 cwsw &= ~FE_ALL_EXCEPT;
819 912 __fenv_setcwsw(&cwsw);
820 - }
821 - else
913 + } else {
822 914 info->flags = FE_INEXACT;
915 + }
823 916
824 917 /* determine the operation code */
825 918 switch (op) {
826 - case 0x1f0: /* f2xm1 */
827 - case 0x1f1: /* fyl2x */
828 - case 0x1f2: /* fptan */
829 - case 0x1f3: /* fpatan */
830 - case 0x1f5: /* fprem1 */
831 - case 0x1f8: /* fprem */
832 - case 0x1f9: /* fyl2xp1 */
833 - case 0x1fb: /* fsincos */
834 - case 0x1fc: /* frndint */
835 - case 0x1fd: /* fscale */
836 - case 0x1fe: /* fsin */
837 - case 0x1ff: /* fcos */
919 + case 0x1f0: /* f2xm1 */
920 + case 0x1f1: /* fyl2x */
921 + case 0x1f2: /* fptan */
922 + case 0x1f3: /* fpatan */
923 + case 0x1f5: /* fprem1 */
924 + case 0x1f8: /* fprem */
925 + case 0x1f9: /* fyl2xp1 */
926 + case 0x1fb: /* fsincos */
927 + case 0x1fc: /* frndint */
928 + case 0x1fd: /* fscale */
929 + case 0x1fe: /* fsin */
930 + case 0x1ff: /* fcos */
838 931 info->op = fex_other;
839 932 return;
840 933
841 - case 0x1fa: /* fsqrt */
934 + case 0x1fa: /* fsqrt */
842 935 info->op = fex_sqrt;
843 936 return;
844 937 }
845 938
846 939 info->op = fex_other;
940 +
847 941 switch (op & 0x7c0) {
848 942 case 0x000:
849 943 case 0x040:
850 944 case 0x080:
851 945 case 0x0c0:
852 946 case 0x200:
853 947 case 0x240:
854 948 case 0x280:
855 949 case 0x400:
856 950 case 0x440:
857 951 case 0x480:
858 952 case 0x4c0:
859 953 case 0x600:
860 954 case 0x640:
861 955 case 0x680:
862 956 case 0x6c0:
957 +
863 958 switch (op & 0x38) {
864 959 case 0x00:
865 960 info->op = fex_add;
866 961 break;
867 962
868 963 case 0x08:
869 964 info->op = fex_mul;
870 965 break;
871 966
872 967 case 0x20:
873 968 case 0x28:
874 969 info->op = fex_sub;
875 970 break;
876 971
877 972 case 0x30:
878 973 case 0x38:
879 974 info->op = fex_div;
880 975 break;
881 976 }
882 977 }
978 +
883 979 return;
884 980 }
885 981
886 - /* for other exceptions, the operands are preserved, so we can
887 - just emulate the operation with traps disabled */
982 + /*
983 + * for other exceptions, the operands are preserved, so we can just
984 + * emulate the operation with traps disabled
985 + */
888 986
889 987 /* one operand is always in st */
890 988 info->op1.type = fex_ldouble;
891 989 info->op1.val.q = fpreg(uap, 0);
892 990
893 991 /* oddball instructions */
894 992 info->op = fex_other;
993 +
895 994 switch (op) {
896 - case 0x1e4: /* ftst */
995 + case 0x1e4: /* ftst */
897 996 info->op = fex_cmp;
898 997 info->op2.type = fex_ldouble;
899 998 info->op2.val.q = 0.0l;
900 999 info->res.type = fex_nodata;
901 1000 c = (info->op1.val.q < info->op2.val.q);
902 1001 goto done;
903 1002
904 - case 0x1f0: /* f2xm1 */
1003 + case 0x1f0: /* f2xm1 */
905 1004 info->res.type = fex_ldouble;
906 1005 info->res.val.q = f2xm1(info->op1.val.q);
907 1006 goto done;
908 1007
909 - case 0x1f1: /* fyl2x */
1008 + case 0x1f1: /* fyl2x */
910 1009 info->op2.type = fex_ldouble;
911 1010 info->op2.val.q = fpreg(uap, 1);
912 1011 info->res.type = fex_ldouble;
913 1012 info->res.val.q = fyl2x(info->op1.val.q, info->op2.val.q);
914 1013 goto done;
915 1014
916 - case 0x1f2: /* fptan */
1015 + case 0x1f2: /* fptan */
917 1016 info->res.type = fex_ldouble;
918 1017 info->res.val.q = fptan(info->op1.val.q);
919 1018 goto done;
920 1019
921 - case 0x1f3: /* fpatan */
1020 + case 0x1f3: /* fpatan */
922 1021 info->op2.type = fex_ldouble;
923 1022 info->op2.val.q = fpreg(uap, 1);
924 1023 info->res.type = fex_ldouble;
925 1024 info->res.val.q = fpatan(info->op1.val.q, info->op2.val.q);
926 1025 goto done;
927 1026
928 - case 0x1f4: /* fxtract */
1027 + case 0x1f4: /* fxtract */
929 1028 info->res.type = fex_ldouble;
930 1029 info->res.val.q = fxtract(info->op1.val.q);
931 1030 goto done;
932 1031
933 - case 0x1f5: /* fprem1 */
1032 + case 0x1f5: /* fprem1 */
934 1033 info->op2.type = fex_ldouble;
935 1034 info->op2.val.q = fpreg(uap, 1);
936 1035 info->res.type = fex_ldouble;
937 1036 info->res.val.q = fprem1(info->op1.val.q, info->op2.val.q);
938 1037 goto done;
939 1038
940 - case 0x1f8: /* fprem */
1039 + case 0x1f8: /* fprem */
941 1040 info->op2.type = fex_ldouble;
942 1041 info->op2.val.q = fpreg(uap, 1);
943 1042 info->res.type = fex_ldouble;
944 1043 info->res.val.q = fprem(info->op1.val.q, info->op2.val.q);
945 1044 goto done;
946 1045
947 - case 0x1f9: /* fyl2xp1 */
1046 + case 0x1f9: /* fyl2xp1 */
948 1047 info->op2.type = fex_ldouble;
949 1048 info->op2.val.q = fpreg(uap, 1);
950 1049 info->res.type = fex_ldouble;
951 1050 info->res.val.q = fyl2xp1(info->op1.val.q, info->op2.val.q);
952 1051 goto done;
953 1052
954 - case 0x1fa: /* fsqrt */
1053 + case 0x1fa: /* fsqrt */
955 1054 info->op = fex_sqrt;
956 1055 info->res.type = fex_ldouble;
957 1056 info->res.val.q = fsqrt(info->op1.val.q);
958 1057 goto done;
959 1058
960 - case 0x1fb: /* fsincos */
1059 + case 0x1fb: /* fsincos */
961 1060 info->res.type = fex_ldouble;
962 1061 info->res.val.q = fsincos(info->op1.val.q);
963 1062 goto done;
964 1063
965 - case 0x1fc: /* frndint */
1064 + case 0x1fc: /* frndint */
966 1065 info->res.type = fex_ldouble;
967 1066 info->res.val.q = frndint(info->op1.val.q);
968 1067 goto done;
969 1068
970 - case 0x1fd: /* fscale */
1069 + case 0x1fd: /* fscale */
971 1070 info->op2.type = fex_ldouble;
972 1071 info->op2.val.q = fpreg(uap, 1);
973 1072 info->res.type = fex_ldouble;
974 1073 info->res.val.q = fscale(info->op1.val.q, info->op2.val.q);
975 1074 goto done;
976 1075
977 - case 0x1fe: /* fsin */
1076 + case 0x1fe: /* fsin */
978 1077 info->res.type = fex_ldouble;
979 1078 info->res.val.q = fsin(info->op1.val.q);
980 1079 goto done;
981 1080
982 - case 0x1ff: /* fcos */
1081 + case 0x1ff: /* fcos */
983 1082 info->res.type = fex_ldouble;
984 1083 info->res.val.q = fcos(info->op1.val.q);
985 1084 goto done;
986 1085
987 - case 0x2e9: /* fucompp */
1086 + case 0x2e9: /* fucompp */
988 1087 info->op = fex_cmp;
989 1088 info->op2.type = fex_ldouble;
990 1089 info->op2.val.q = fpreg(uap, 1);
991 1090 info->res.type = fex_nodata;
992 1091 c = (info->op1.val.q == info->op2.val.q);
993 1092 goto done;
994 1093 }
995 1094
996 1095 /* fucom[p], fcomi[p], fucomi[p] */
997 1096 switch (op & 0x7f8) {
998 1097 case 0x3e8:
999 1098 case 0x5e0:
1000 1099 case 0x5e8:
1001 - case 0x7e8: /* unordered compares */
1100 + case 0x7e8: /* unordered compares */
1002 1101 info->op = fex_cmp;
1003 1102 info->op2.type = fex_ldouble;
1004 1103 info->op2.val.q = fpreg(uap, op & 7);
1005 1104 info->res.type = fex_nodata;
1006 1105 c = (info->op1.val.q == info->op2.val.q);
1007 1106 goto done;
1008 1107
1009 1108 case 0x3f0:
1010 - case 0x7f0: /* ordered compares */
1109 + case 0x7f0: /* ordered compares */
1011 1110 info->op = fex_cmp;
1012 1111 info->op2.type = fex_ldouble;
1013 1112 info->op2.val.q = fpreg(uap, op & 7);
1014 1113 info->res.type = fex_nodata;
1015 1114 c = (info->op1.val.q < info->op2.val.q);
1016 1115 goto done;
1017 1116 }
1018 1117
1019 - /* all other instructions come in groups of the form
1020 - fadd, fmul, fcom, fcomp, fsub, fsubr, fdiv, fdivr */
1118 + /*
1119 + * all other instructions come in groups of the form
1120 + * fadd, fmul, fcom, fcomp, fsub, fsubr, fdiv, fdivr
1121 + */
1021 1122
1022 1123 /* get the second operand */
1023 1124 switch (op & 0x7c0) {
1024 1125 case 0x000:
1025 1126 case 0x040:
1026 1127 case 0x080:
1128 +
1027 1129 if (!ea) {
1028 1130 info->op = fex_other;
1029 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
1131 + info->op1.type = info->op2.type = info->res.type =
1132 + fex_nodata;
1030 1133 info->flags = 0;
1031 1134 return;
1032 1135 }
1136 +
1033 1137 info->op2.type = fex_float;
1034 1138 info->op2.val.f = *(float *)ea;
1035 - op2v = (long double) info->op2.val.f;
1139 + op2v = (long double)info->op2.val.f;
1036 1140 break;
1037 1141
1038 1142 case 0x0c0:
1039 1143 info->op2.type = fex_ldouble;
1040 1144 op2v = info->op2.val.q = fpreg(uap, op & 7);
1041 1145 break;
1042 1146
1043 1147 case 0x200:
1044 1148 case 0x240:
1045 1149 case 0x280:
1150 +
1046 1151 if (!ea) {
1047 1152 info->op = fex_other;
1048 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
1153 + info->op1.type = info->op2.type = info->res.type =
1154 + fex_nodata;
1049 1155 info->flags = 0;
1050 1156 return;
1051 1157 }
1158 +
1052 1159 info->op2.type = fex_int;
1053 1160 info->op2.val.i = *(int *)ea;
1054 - op2v = (long double) info->op2.val.i;
1161 + op2v = (long double)info->op2.val.i;
1055 1162 break;
1056 1163
1057 1164 case 0x400:
1058 1165 case 0x440:
1059 1166 case 0x480:
1167 +
1060 1168 if (!ea) {
1061 1169 info->op = fex_other;
1062 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
1170 + info->op1.type = info->op2.type = info->res.type =
1171 + fex_nodata;
1063 1172 info->flags = 0;
1064 1173 return;
1065 1174 }
1175 +
1066 1176 info->op2.type = fex_double;
1067 1177 info->op2.val.d = *(double *)ea;
1068 - op2v = (long double) info->op2.val.d;
1178 + op2v = (long double)info->op2.val.d;
1069 1179 break;
1070 1180
1071 1181 case 0x4c0:
1072 1182 case 0x6c0:
1073 1183 info->op2.type = fex_ldouble;
1074 1184 info->op2.val.q = fpreg(uap, op & 7);
1075 1185 t = info->op1;
1076 1186 info->op1 = info->op2;
1077 1187 info->op2 = t;
1078 1188 op2v = info->op2.val.q;
1079 1189 break;
1080 1190
1081 1191 case 0x600:
1082 1192 case 0x640:
1083 1193 case 0x680:
1194 +
1084 1195 if (!ea) {
1085 1196 info->op = fex_other;
1086 - info->op1.type = info->op2.type = info->res.type = fex_nodata;
1197 + info->op1.type = info->op2.type = info->res.type =
1198 + fex_nodata;
1087 1199 info->flags = 0;
1088 1200 return;
1089 1201 }
1202 +
1090 1203 info->op2.type = fex_int;
1091 1204 info->op2.val.i = *(short *)ea;
1092 - op2v = (long double) info->op2.val.i;
1205 + op2v = (long double)info->op2.val.i;
1093 1206 break;
1094 1207
1095 1208 default:
1096 1209 info->op = fex_other;
1097 1210 info->op1.type = info->op2.type = info->res.type = fex_nodata;
1098 1211 info->flags = 0;
1099 1212 return;
1100 1213 }
1101 1214
1102 1215 /* distinguish different operations in the group */
1103 1216 info->res.type = fex_ldouble;
1217 +
1104 1218 switch (op & 0x38) {
1105 1219 case 0x00:
1106 1220 info->op = fex_add;
1107 1221 info->res.val.q = info->op1.val.q + op2v;
1108 1222 break;
1109 1223
1110 1224 case 0x08:
1111 1225 info->op = fex_mul;
1112 1226 info->res.val.q = info->op1.val.q * op2v;
1113 1227 break;
1114 1228
1115 1229 case 0x10:
1116 1230 case 0x18:
1117 1231 info->op = fex_cmp;
1118 1232 info->res.type = fex_nodata;
1119 1233 c = (info->op1.val.q < op2v);
1120 1234 break;
1121 1235
1122 1236 case 0x20:
1123 1237 info->op = fex_sub;
1124 1238 info->res.val.q = info->op1.val.q - op2v;
1125 1239 break;
1126 1240
1127 1241 case 0x28:
1128 1242 info->op = fex_sub;
1129 1243 info->res.val.q = op2v - info->op1.val.q;
1130 1244 t = info->op1;
1131 1245 info->op1 = info->op2;
1132 1246 info->op2 = t;
1133 1247 break;
1134 1248
1135 1249 case 0x30:
1136 1250 info->op = fex_div;
1137 1251 info->res.val.q = info->op1.val.q / op2v;
1138 1252 break;
1139 1253
1140 1254 case 0x38:
1141 1255 info->op = fex_div;
1142 1256 info->res.val.q = op2v / info->op1.val.q;
1143 1257 t = info->op1;
1144 1258 info->op1 = info->op2;
1145 1259 info->op2 = t;
1146 1260 break;
1147 1261
1148 1262 default:
1149 1263 info->op = fex_other;
1150 1264 info->op1.type = info->op2.type = info->res.type = fex_nodata;
1151 1265 info->flags = 0;
1152 1266 return;
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
1153 1267 }
1154 1268
1155 1269 done:
1156 1270 __fenv_getcwsw(&cwsw);
1157 1271 info->flags = cwsw & FE_ALL_EXCEPT;
1158 1272 cwsw &= ~FE_ALL_EXCEPT;
1159 1273 __fenv_setcwsw(&cwsw);
1160 1274 }
1161 1275
1162 1276 /* pop the saved stack */
1163 -static void pop(ucontext_t *uap)
1277 +static void
1278 +pop(ucontext_t *uap)
1164 1279 {
1165 1280 unsigned top;
1166 1281
1167 1282 fpreg(uap, 0) = fpreg(uap, 1);
1168 1283 fpreg(uap, 1) = fpreg(uap, 2);
1169 1284 fpreg(uap, 2) = fpreg(uap, 3);
1170 1285 fpreg(uap, 3) = fpreg(uap, 4);
1171 1286 fpreg(uap, 4) = fpreg(uap, 5);
1172 1287 fpreg(uap, 5) = fpreg(uap, 6);
1173 1288 fpreg(uap, 6) = fpreg(uap, 7);
1174 1289 #if defined(__amd64)
1175 - top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw >> 10)
1176 - & 0xe;
1290 + top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw >> 10) & 0xe;
1177 1291 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.fctw |= (3 << top);
1178 1292 top = (top + 2) & 0xe;
1179 1293 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw =
1180 - (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw & ~0x3800)
1181 - | (top << 10);
1294 + (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw & ~0x3800) |
1295 + (top << 10);
1182 1296 #else
1183 - top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] >> 10)
1184 - & 0xe;
1297 + top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] >>
1298 + 10) & 0xe;
1185 1299 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[TW] |= (3 << top);
1186 1300 top = (top + 2) & 0xe;
1187 1301 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] =
1188 - (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] & ~0x3800)
1189 - | (top << 10);
1302 + (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] &
1303 + ~0x3800) | (top << 10);
1190 1304 #endif
1191 1305 }
1192 1306
1193 1307 /* push x onto the saved stack */
1194 -static void push(long double x, ucontext_t *uap)
1308 +static void
1309 +push(long double x, ucontext_t *uap)
1195 1310 {
1196 1311 unsigned top;
1197 1312
1198 1313 fpreg(uap, 7) = fpreg(uap, 6);
1199 1314 fpreg(uap, 6) = fpreg(uap, 5);
1200 1315 fpreg(uap, 5) = fpreg(uap, 4);
1201 1316 fpreg(uap, 4) = fpreg(uap, 3);
1202 1317 fpreg(uap, 3) = fpreg(uap, 2);
1203 1318 fpreg(uap, 2) = fpreg(uap, 1);
1204 1319 fpreg(uap, 1) = fpreg(uap, 0);
1205 1320 fpreg(uap, 0) = x;
1206 1321 #if defined(__amd64)
1207 - top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw >> 10)
1208 - & 0xe;
1322 + top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw >> 10) & 0xe;
1209 1323 top = (top - 2) & 0xe;
1210 1324 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.fctw &= ~(3 << top);
1211 1325 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw =
1212 - (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw & ~0x3800)
1213 - | (top << 10);
1326 + (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw & ~0x3800) |
1327 + (top << 10);
1214 1328 #else
1215 - top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] >> 10)
1216 - & 0xe;
1329 + top = (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] >>
1330 + 10) & 0xe;
1217 1331 top = (top - 2) & 0xe;
1218 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[TW] &= ~(3 << top);
1332 + uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[TW] &= ~(3 <<
1333 + top);
1219 1334 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] =
1220 - (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] & ~0x3800)
1221 - | (top << 10);
1335 + (uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] &
1336 + ~0x3800) | (top << 10);
1222 1337 #endif
1223 1338 }
1224 1339
1225 1340 /* scale factors for exponent wrapping */
1226 -static const float
1227 - fun = 7.922816251e+28f, /* 2^96 */
1228 - fov = 1.262177448e-29f; /* 2^-96 */
1229 -static const double
1230 - dun = 1.552518092300708935e+231, /* 2^768 */
1231 - dov = 6.441148769597133308e-232; /* 2^-768 */
1341 +static const float fun = 7.922816251e+28f, /* 2^96 */
1342 + fov = 1.262177448e-29f; /* 2^-96 */
1343 +static const double dun = 1.552518092300708935e+231, /* 2^768 */
1344 + dov = 6.441148769597133308e-232; /* 2^-768 */
1232 1345
1233 1346 /*
1234 -* Store the specified result; if no result is given but the exception
1235 -* is underflow or overflow, use the default trapped result
1236 -*/
1347 + * Store the specified result; if no result is given but the exception
1348 + * is underflow or overflow, use the default trapped result
1349 + */
1237 1350 void
1238 1351 __fex_st_result(siginfo_t *sip, ucontext_t *uap, fex_info_t *info)
1239 1352 {
1240 - fex_numeric_t r;
1241 - unsigned long ex, op, ea, stack;
1353 + fex_numeric_t r;
1354 + unsigned long ex, op, ea, stack;
1242 1355
1243 1356 /* get the exception type, opcode, and data address */
1244 1357 ex = sip->si_code;
1245 1358 #if defined(__amd64)
1246 1359 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.fop >> 16;
1247 - ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.rdp; /*???*/
1360 + ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.rdp; /* ??? */
1248 1361 #else
1249 1362 op = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[OP] >> 16;
1250 1363 ea = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[EA];
1251 1364 #endif
1252 1365
1253 - /* if the instruction is a compare, set the condition codes
1254 - to unordered and update the stack */
1366 + /*
1367 + * if the instruction is a compare, set the condition codes
1368 + * to unordered and update the stack
1369 + */
1255 1370 switch (op & 0x7f8) {
1256 1371 case 0x010:
1257 1372 case 0x050:
1258 1373 case 0x090:
1259 1374 case 0x0d0:
1260 1375 case 0x210:
1261 1376 case 0x250:
1262 1377 case 0x290:
1263 1378 case 0x410:
1264 1379 case 0x450:
1265 1380 case 0x490:
1266 1381 case 0x4d0:
1267 1382 case 0x5e0:
1268 1383 case 0x610:
1269 1384 case 0x650:
1270 1385 case 0x690:
1271 1386 /* f[u]com */
1272 1387 #if defined(__amd64)
1273 1388 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= 0x4500;
1274 1389 #else
1275 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |= 0x4500;
1390 + uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |=
1391 + 0x4500;
1276 1392 #endif
1277 1393 return;
1278 1394
1279 1395 case 0x018:
1280 1396 case 0x058:
1281 1397 case 0x098:
1282 1398 case 0x0d8:
1283 1399 case 0x218:
1284 1400 case 0x258:
1285 1401 case 0x298:
1286 1402 case 0x418:
1287 1403 case 0x458:
1288 1404 case 0x498:
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1289 1405 case 0x4d8:
1290 1406 case 0x5e8:
1291 1407 case 0x618:
1292 1408 case 0x658:
1293 1409 case 0x698:
1294 1410 case 0x6d0:
1295 1411 /* f[u]comp */
1296 1412 #if defined(__amd64)
1297 1413 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= 0x4500;
1298 1414 #else
1299 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |= 0x4500;
1415 + uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |=
1416 + 0x4500;
1300 1417 #endif
1301 1418 pop(uap);
1302 1419 return;
1303 1420
1304 1421 case 0x2e8:
1305 1422 case 0x6d8:
1306 1423 /* f[u]compp */
1307 1424 #if defined(__amd64)
1308 1425 uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= 0x4500;
1309 1426 #else
1310 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |= 0x4500;
1427 + uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |=
1428 + 0x4500;
1311 1429 #endif
1312 1430 pop(uap);
1313 1431 pop(uap);
1314 1432 return;
1315 1433
1316 1434 case 0x1e0:
1317 - if (op == 0x1e4) { /* ftst */
1435 +
1436 + if (op == 0x1e4) { /* ftst */
1318 1437 #if defined(__amd64)
1319 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= 0x4500;
1438 + uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |=
1439 + 0x4500;
1320 1440 #else
1321 - uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[SW] |= 0x4500;
1441 + uap->uc_mcontext.fpregs.fp_reg_set.
1442 + fpchip_state.state[SW] |= 0x4500;
1322 1443 #endif
1323 1444 return;
1324 1445 }
1446 +
1325 1447 break;
1326 1448
1327 1449 case 0x3e8:
1328 1450 case 0x3f0:
1329 1451 /* f[u]comi */
1330 1452 #if defined(__amd64)
1331 1453 uap->uc_mcontext.gregs[REG_PS] |= 0x45;
1332 1454 #else
1333 1455 uap->uc_mcontext.gregs[EFL] |= 0x45;
1334 1456 #endif
1335 1457 return;
1336 1458
1337 1459 case 0x7e8:
1338 1460 case 0x7f0:
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1339 1461 /* f[u]comip */
1340 1462 #if defined(__amd64)
1341 1463 uap->uc_mcontext.gregs[REG_PS] |= 0x45;
1342 1464 #else
1343 1465 uap->uc_mcontext.gregs[EFL] |= 0x45;
1344 1466 #endif
1345 1467 pop(uap);
1346 1468 return;
1347 1469 }
1348 1470
1349 - /* if there is no result available and the exception is overflow
1350 - or underflow, use the wrapped result */
1471 + /*
1472 + * if there is no result available and the exception is overflow
1473 + * or underflow, use the wrapped result
1474 + */
1351 1475 r = info->res;
1476 +
1352 1477 if (r.type == fex_nodata) {
1353 1478 if (ex == FPE_FLTOVF || ex == FPE_FLTUND) {
1354 1479 /* for store instructions, do the scaling and store */
1355 1480 switch (op & 0x7f8) {
1356 1481 case 0x110:
1357 1482 case 0x118:
1358 1483 case 0x150:
1359 1484 case 0x158:
1360 1485 case 0x190:
1361 1486 case 0x198:
1487 +
1362 1488 if (!ea)
1363 1489 return;
1490 +
1364 1491 if (ex == FPE_FLTOVF)
1365 - *(float *)ea = (fpreg(uap, 0) * fov) * fov;
1492 + *(float *)ea = (fpreg(uap, 0) * fov) *
1493 + fov;
1366 1494 else
1367 - *(float *)ea = (fpreg(uap, 0) * fun) * fun;
1495 + *(float *)ea = (fpreg(uap, 0) * fun) *
1496 + fun;
1497 +
1368 1498 if ((op & 8) != 0)
1369 1499 pop(uap);
1500 +
1370 1501 break;
1371 1502
1372 1503 case 0x510:
1373 1504 case 0x518:
1374 1505 case 0x550:
1375 1506 case 0x558:
1376 1507 case 0x590:
1377 1508 case 0x598:
1509 +
1378 1510 if (!ea)
1379 1511 return;
1512 +
1380 1513 if (ex == FPE_FLTOVF)
1381 - *(double *)ea = (fpreg(uap, 0) * dov) * dov;
1514 + *(double *)ea = (fpreg(uap, 0) * dov) *
1515 + dov;
1382 1516 else
1383 - *(double *)ea = (fpreg(uap, 0) * dun) * dun;
1517 + *(double *)ea = (fpreg(uap, 0) * dun) *
1518 + dun;
1519 +
1384 1520 if ((op & 8) != 0)
1385 1521 pop(uap);
1522 +
1386 1523 break;
1387 1524 }
1388 1525 }
1526 +
1389 1527 #ifdef DEBUG
1390 - else if (ex != FPE_FLTRES)
1528 + else if (ex != FPE_FLTRES) {
1391 1529 printf("No result supplied, stack may be hosed\n");
1530 + }
1392 1531 #endif
1393 1532 return;
1394 1533 }
1395 1534
1396 - /* otherwise convert the supplied result to the correct type,
1397 - put it in the destination, and update the stack as need be */
1535 + /*
1536 + * otherwise convert the supplied result to the correct type, put it
1537 + * in the destination, and update the stack as need be
1538 + */
1398 1539
1399 1540 /* store instructions */
1400 1541 switch (op & 0x7f8) {
1401 1542 case 0x110:
1402 1543 case 0x118:
1403 1544 case 0x150:
1404 1545 case 0x158:
1405 1546 case 0x190:
1406 1547 case 0x198:
1548 +
1407 1549 if (!ea)
1408 1550 return;
1551 +
1409 1552 switch (r.type) {
1410 1553 case fex_int:
1411 - *(float *)ea = (float) r.val.i;
1554 + *(float *)ea = (float)r.val.i;
1412 1555 break;
1413 1556
1414 1557 case fex_llong:
1415 - *(float *)ea = (float) r.val.l;
1558 + *(float *)ea = (float)r.val.l;
1416 1559 break;
1417 1560
1418 1561 case fex_float:
1419 1562 *(float *)ea = r.val.f;
1420 1563 break;
1421 1564
1422 1565 case fex_double:
1423 - *(float *)ea = (float) r.val.d;
1566 + *(float *)ea = (float)r.val.d;
1424 1567 break;
1425 1568
1426 1569 case fex_ldouble:
1427 - *(float *)ea = (float) r.val.q;
1570 + *(float *)ea = (float)r.val.q;
1428 1571 break;
1429 1572
1430 1573 default:
1431 1574 break;
1432 1575 }
1576 +
1433 1577 if (ex != FPE_FLTRES && (op & 8) != 0)
1434 1578 pop(uap);
1579 +
1435 1580 return;
1436 1581
1437 1582 case 0x310:
1438 1583 case 0x318:
1439 1584 case 0x350:
1440 1585 case 0x358:
1441 1586 case 0x390:
1442 1587 case 0x398:
1588 +
1443 1589 if (!ea)
1444 1590 return;
1591 +
1445 1592 switch (r.type) {
1446 1593 case fex_int:
1447 1594 *(int *)ea = r.val.i;
1448 1595 break;
1449 1596
1450 1597 case fex_llong:
1451 - *(int *)ea = (int) r.val.l;
1598 + *(int *)ea = (int)r.val.l;
1452 1599 break;
1453 1600
1454 1601 case fex_float:
1455 - *(int *)ea = (int) r.val.f;
1602 + *(int *)ea = (int)r.val.f;
1456 1603 break;
1457 1604
1458 1605 case fex_double:
1459 - *(int *)ea = (int) r.val.d;
1606 + *(int *)ea = (int)r.val.d;
1460 1607 break;
1461 1608
1462 1609 case fex_ldouble:
1463 - *(int *)ea = (int) r.val.q;
1610 + *(int *)ea = (int)r.val.q;
1464 1611 break;
1465 1612
1466 1613 default:
1467 1614 break;
1468 1615 }
1616 +
1469 1617 if (ex != FPE_FLTRES && (op & 8) != 0)
1470 1618 pop(uap);
1619 +
1471 1620 return;
1472 1621
1473 1622 case 0x510:
1474 1623 case 0x518:
1475 1624 case 0x550:
1476 1625 case 0x558:
1477 1626 case 0x590:
1478 1627 case 0x598:
1628 +
1479 1629 if (!ea)
1480 1630 return;
1631 +
1481 1632 switch (r.type) {
1482 1633 case fex_int:
1483 - *(double *)ea = (double) r.val.i;
1634 + *(double *)ea = (double)r.val.i;
1484 1635 break;
1485 1636
1486 1637 case fex_llong:
1487 - *(double *)ea = (double) r.val.l;
1638 + *(double *)ea = (double)r.val.l;
1488 1639 break;
1489 1640
1490 1641 case fex_float:
1491 - *(double *)ea = (double) r.val.f;
1642 + *(double *)ea = (double)r.val.f;
1492 1643 break;
1493 1644
1494 1645 case fex_double:
1495 1646 *(double *)ea = r.val.d;
1496 1647 break;
1497 1648
1498 1649 case fex_ldouble:
1499 - *(double *)ea = (double) r.val.q;
1650 + *(double *)ea = (double)r.val.q;
1500 1651 break;
1501 1652
1502 1653 default:
1503 1654 break;
1504 1655 }
1656 +
1505 1657 if (ex != FPE_FLTRES && (op & 8) != 0)
1506 1658 pop(uap);
1659 +
1507 1660 return;
1508 1661
1509 1662 case 0x710:
1510 1663 case 0x718:
1511 1664 case 0x750:
1512 1665 case 0x758:
1513 1666 case 0x790:
1514 1667 case 0x798:
1668 +
1515 1669 if (!ea)
1516 1670 return;
1671 +
1517 1672 switch (r.type) {
1518 1673 case fex_int:
1519 - *(short *)ea = (short) r.val.i;
1674 + *(short *)ea = (short)r.val.i;
1520 1675 break;
1521 1676
1522 1677 case fex_llong:
1523 - *(short *)ea = (short) r.val.l;
1678 + *(short *)ea = (short)r.val.l;
1524 1679 break;
1525 1680
1526 1681 case fex_float:
1527 - *(short *)ea = (short) r.val.f;
1682 + *(short *)ea = (short)r.val.f;
1528 1683 break;
1529 1684
1530 1685 case fex_double:
1531 - *(short *)ea = (short) r.val.d;
1686 + *(short *)ea = (short)r.val.d;
1532 1687 break;
1533 1688
1534 1689 case fex_ldouble:
1535 - *(short *)ea = (short) r.val.q;
1690 + *(short *)ea = (short)r.val.q;
1536 1691 break;
1537 1692
1538 1693 default:
1539 1694 break;
1540 1695 }
1696 +
1541 1697 if (ex != FPE_FLTRES && (op & 8) != 0)
1542 1698 pop(uap);
1699 +
1543 1700 return;
1544 1701
1545 1702 case 0x730:
1546 1703 case 0x770:
1547 1704 case 0x7b0:
1705 +
1548 1706 /* fbstp; don't bother */
1549 1707 if (ea && ex != FPE_FLTRES)
1550 1708 pop(uap);
1709 +
1551 1710 return;
1552 1711
1553 1712 case 0x738:
1554 1713 case 0x778:
1555 1714 case 0x7b8:
1715 +
1556 1716 if (!ea)
1557 1717 return;
1718 +
1558 1719 switch (r.type) {
1559 1720 case fex_int:
1560 - *(long long *)ea = (long long) r.val.i;
1721 + *(long long *)ea = (long long)r.val.i;
1561 1722 break;
1562 1723
1563 1724 case fex_llong:
1564 1725 *(long long *)ea = r.val.l;
1565 1726 break;
1566 1727
1567 1728 case fex_float:
1568 - *(long long *)ea = (long long) r.val.f;
1729 + *(long long *)ea = (long long)r.val.f;
1569 1730 break;
1570 1731
1571 1732 case fex_double:
1572 - *(long long *)ea = (long long) r.val.d;
1733 + *(long long *)ea = (long long)r.val.d;
1573 1734 break;
1574 1735
1575 1736 case fex_ldouble:
1576 - *(long long *)ea = (long long) r.val.q;
1737 + *(long long *)ea = (long long)r.val.q;
1577 1738 break;
1578 1739
1579 1740 default:
1580 1741 break;
1581 1742 }
1743 +
1582 1744 if (ex != FPE_FLTRES)
1583 1745 pop(uap);
1746 +
1584 1747 return;
1585 1748 }
1586 1749
1587 1750 /* for all other instructions, the result goes into a register */
1588 1751 switch (r.type) {
1589 1752 case fex_int:
1590 - r.val.q = (long double) r.val.i;
1753 + r.val.q = (long double)r.val.i;
1591 1754 break;
1592 1755
1593 1756 case fex_llong:
1594 - r.val.q = (long double) r.val.l;
1757 + r.val.q = (long double)r.val.l;
1595 1758 break;
1596 1759
1597 1760 case fex_float:
1598 - r.val.q = (long double) r.val.f;
1761 + r.val.q = (long double)r.val.f;
1599 1762 break;
1600 1763
1601 1764 case fex_double:
1602 - r.val.q = (long double) r.val.d;
1765 + r.val.q = (long double)r.val.d;
1603 1766 break;
1604 1767
1605 1768 default:
1606 1769 break;
1607 1770 }
1608 1771
1609 1772 /* for load instructions, push the result onto the stack */
1610 1773 switch (op & 0x7f8) {
1611 1774 case 0x100:
1612 1775 case 0x140:
1613 1776 case 0x180:
1614 1777 case 0x500:
1615 1778 case 0x540:
1616 1779 case 0x580:
1780 +
1617 1781 if (ea)
1618 1782 push(r.val.q, uap);
1783 +
1619 1784 return;
1620 1785 }
1621 1786
1622 - /* for all other instructions, if the exception is overflow,
1623 - underflow, or inexact, the stack has already been updated */
1787 + /*
1788 + * for all other instructions, if the exception is overflow,
1789 + * underflow, or inexact, the stack has already been updated
1790 + */
1624 1791 stack = (ex == FPE_FLTOVF || ex == FPE_FLTUND || ex == FPE_FLTRES);
1792 +
1625 1793 switch (op & 0x7f8) {
1626 - case 0x1f0: /* oddballs */
1794 + case 0x1f0: /* oddballs */
1795 +
1627 1796 switch (op) {
1628 - case 0x1f1: /* fyl2x */
1629 - case 0x1f3: /* fpatan */
1630 - case 0x1f9: /* fyl2xp1 */
1797 + case 0x1f1: /* fyl2x */
1798 + case 0x1f3: /* fpatan */
1799 + case 0x1f9: /* fyl2xp1 */
1800 +
1631 1801 /* pop the stack, leaving the result in st */
1632 1802 if (!stack)
1633 1803 pop(uap);
1804 +
1634 1805 fpreg(uap, 0) = r.val.q;
1635 1806 return;
1636 1807
1637 - case 0x1f2: /* fpatan */
1808 + case 0x1f2: /* fpatan */
1809 +
1638 1810 /* fptan pushes 1.0 afterward */
1639 - if (stack)
1811 + if (stack) {
1640 1812 fpreg(uap, 1) = r.val.q;
1641 - else {
1813 + } else {
1642 1814 fpreg(uap, 0) = r.val.q;
1643 1815 push(1.0L, uap);
1644 1816 }
1817 +
1645 1818 return;
1646 1819
1647 - case 0x1f4: /* fxtract */
1648 - case 0x1fb: /* fsincos */
1820 + case 0x1f4: /* fxtract */
1821 + case 0x1fb: /* fsincos */
1822 +
1649 1823 /* leave the supplied result in st */
1650 - if (stack)
1824 + if (stack) {
1651 1825 fpreg(uap, 0) = r.val.q;
1652 - else {
1653 - fpreg(uap, 0) = 0.0; /* punt */
1826 + } else {
1827 + fpreg(uap, 0) = 0.0; /* punt */
1654 1828 push(r.val.q, uap);
1655 1829 }
1830 +
1656 1831 return;
1657 1832 }
1658 1833
1659 1834 /* all others leave the stack alone and the result in st */
1660 1835 fpreg(uap, 0) = r.val.q;
1661 1836 return;
1662 1837
1663 1838 case 0x4c0:
1664 1839 case 0x4c8:
1665 1840 case 0x4e0:
1666 1841 case 0x4e8:
1667 1842 case 0x4f0:
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
1668 1843 case 0x4f8:
1669 1844 fpreg(uap, op & 7) = r.val.q;
1670 1845 return;
1671 1846
1672 1847 case 0x6c0:
1673 1848 case 0x6c8:
1674 1849 case 0x6e0:
1675 1850 case 0x6e8:
1676 1851 case 0x6f0:
1677 1852 case 0x6f8:
1853 +
1678 1854 /* stack is popped afterward */
1679 - if (stack)
1855 + if (stack) {
1680 1856 fpreg(uap, (op - 1) & 7) = r.val.q;
1681 - else {
1857 + } else {
1682 1858 fpreg(uap, op & 7) = r.val.q;
1683 1859 pop(uap);
1684 1860 }
1861 +
1685 1862 return;
1686 1863
1687 1864 default:
1688 1865 fpreg(uap, 0) = r.val.q;
1689 1866 return;
1690 1867 }
1691 1868 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX