Print this page
11210 libm should be cstyle(1ONBLD) clean

*** 20,29 **** --- 20,30 ---- */ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ + /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */
*** 43,97 **** #include "fenv_inlines.h" #include "libm_inlines.h" #ifdef __sparcv9 - #define FPreg(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X] ! #define FPREG(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_dregs[(X>>1)| \ ! ((X&1)<<4)] ! #else - #include <sys/procfs.h> ! #define FPxreg(X) &((prxregset_t*)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.pr_v8p.pr_xfr.pr_regs[X] ! #define FPreg(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X] ! ! #define FPREG(X) ((X & 1)? FPxreg(X - 1) : FPreg(X)) #endif /* __sparcv9 */ #include "fex_handler.h" /* avoid dependence on libsunmath */ static enum fp_class_type my_fp_classl(long double *a) { ! int msw = *(int*)a & ~0x80000000; if (msw >= 0x7fff0000) { ! if (((msw & 0xffff) | *(1+(int*)a) | *(2+(int*)a) | *(3+(int*)a)) == 0) ! return fp_infinity; else if (msw & 0x8000) ! return fp_quiet; else ! return fp_signaling; } else if (msw < 0x10000) { ! if ((msw | *(1+(int*)a) | *(2+(int*)a) | *(3+(int*)a)) == 0) ! return fp_zero; else ! return fp_subnormal; ! } else ! return fp_normal; } /* ! * Determine which type of invalid operation exception occurred ! */ enum fex_exception __fex_get_invalid_type(siginfo_t *sip, ucontext_t *uap) { unsigned instr, opf, rs1, rs2; enum fp_class_type t1, t2; --- 44,99 ---- #include "fenv_inlines.h" #include "libm_inlines.h" #ifdef __sparcv9 #define FPreg(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X] ! #define FPREG(X) &uap->uc_mcontext.fpregs.fpu_fr.fpu_dregs[(X >> 1) | \ ! ((X & 1) << 4)] #else #include <sys/procfs.h> ! #define FPxreg(X) & \ ! ((prxregset_t *)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.pr_v8p.pr_xfr. \ ! pr_regs[X] ! #define FPreg(X) & uap->uc_mcontext.fpregs.fpu_fr.fpu_regs[X] + #define FPREG(X) ((X & 1) ? FPxreg(X - 1) : FPreg(X)) #endif /* __sparcv9 */ #include "fex_handler.h" /* avoid dependence on libsunmath */ static enum fp_class_type my_fp_classl(long double *a) { ! int msw = *(int *)a & ~0x80000000; if (msw >= 0x7fff0000) { ! if (((msw & 0xffff) | *(1 + (int *)a) | *(2 + (int *)a) | *(3 + ! (int *)a)) == 0) ! return (fp_infinity); else if (msw & 0x8000) ! return (fp_quiet); else ! return (fp_signaling); } else if (msw < 0x10000) { ! if ((msw | *(1 + (int *)a) | *(2 + (int *)a) | *(3 + ! (int *)a)) == 0) ! return (fp_zero); else ! return (fp_subnormal); ! } else { ! return (fp_normal); ! } } /* ! * Determine which type of invalid operation exception occurred ! */ enum fex_exception __fex_get_invalid_type(siginfo_t *sip, ucontext_t *uap) { unsigned instr, opf, rs1, rs2; enum fp_class_type t1, t2;
*** 103,190 **** rs2 = instr & 0x1f; /* determine the classes of the operands */ switch (opf & 3) { case 1: /* single */ ! t1 = fp_classf(*(float*)FPreg(rs1)); ! t2 = fp_classf(*(float*)FPreg(rs2)); break; case 2: /* double */ ! t1 = fp_class(*(double*)FPREG(rs1)); ! t2 = fp_class(*(double*)FPREG(rs2)); break; case 3: /* quad */ ! t1 = my_fp_classl((long double*)FPREG(rs1)); ! t2 = my_fp_classl((long double*)FPREG(rs2)); break; default: /* integer operands never cause an invalid operation */ ! return (enum fex_exception) -1; } /* if rs2 is snan, return immediately */ if (t2 == fp_signaling) ! return fex_inv_snan; /* determine the type of operation */ switch ((instr >> 19) & 0x183f) { case 0x1034: /* add, subtract, multiply, divide, square root, convert */ switch (opf & 0x1fc) { case 0x40: case 0x44: /* add or subtract */ if (t1 == fp_signaling) ! return fex_inv_snan; else ! return fex_inv_isi; case 0x48: case 0x68: case 0x6c: /* multiply */ if (t1 == fp_signaling) ! return fex_inv_snan; else ! return fex_inv_zmi; case 0x4c: /* divide */ if (t1 == fp_signaling) ! return fex_inv_snan; else if (t1 == fp_zero) ! return fex_inv_zdz; else ! return fex_inv_idi; case 0x28: /* square root */ ! return fex_inv_sqrt; case 0x80: case 0xd0: /* convert to integer */ ! return fex_inv_int; } break; case 0x1035: /* compare */ if (t1 == fp_signaling) ! return fex_inv_snan; else ! return fex_inv_cmp; } ! return (enum fex_exception) -1; } #ifdef __sparcv9 extern void _Qp_sqrt(long double *, const long double *); #else extern long double _Q_sqrt(long double); #endif /* ! * Get the operands, generate the default untrapped result with ! * exceptions, and set a code indicating the type of operation ! */ void __fex_get_op(siginfo_t *sip, ucontext_t *uap, fex_info_t *info) { unsigned long fsr; unsigned instr, opf, rs1, rs2; --- 105,198 ---- rs2 = instr & 0x1f; /* determine the classes of the operands */ switch (opf & 3) { case 1: /* single */ ! t1 = fp_classf(*(float *)FPreg(rs1)); ! t2 = fp_classf(*(float *)FPreg(rs2)); break; case 2: /* double */ ! t1 = fp_class(*(double *)FPREG(rs1)); ! t2 = fp_class(*(double *)FPREG(rs2)); break; case 3: /* quad */ ! t1 = my_fp_classl((long double *)FPREG(rs1)); ! t2 = my_fp_classl((long double *)FPREG(rs2)); break; default: /* integer operands never cause an invalid operation */ ! return ((enum fex_exception)-1); } /* if rs2 is snan, return immediately */ if (t2 == fp_signaling) ! return (fex_inv_snan); /* determine the type of operation */ switch ((instr >> 19) & 0x183f) { case 0x1034: /* add, subtract, multiply, divide, square root, convert */ + switch (opf & 0x1fc) { case 0x40: case 0x44: /* add or subtract */ + if (t1 == fp_signaling) ! return (fex_inv_snan); else ! return (fex_inv_isi); case 0x48: case 0x68: case 0x6c: /* multiply */ + if (t1 == fp_signaling) ! return (fex_inv_snan); else ! return (fex_inv_zmi); case 0x4c: /* divide */ + if (t1 == fp_signaling) ! return (fex_inv_snan); else if (t1 == fp_zero) ! return (fex_inv_zdz); else ! return (fex_inv_idi); case 0x28: /* square root */ ! return (fex_inv_sqrt); case 0x80: case 0xd0: /* convert to integer */ ! return (fex_inv_int); } + break; case 0x1035: /* compare */ + if (t1 == fp_signaling) ! return (fex_inv_snan); else ! return (fex_inv_cmp); } ! return ((enum fex_exception)-1); } #ifdef __sparcv9 extern void _Qp_sqrt(long double *, const long double *); #else extern long double _Q_sqrt(long double); #endif /* ! * Get the operands, generate the default untrapped result with ! * exceptions, and set a code indicating the type of operation ! */ void __fex_get_op(siginfo_t *sip, ucontext_t *uap, fex_info_t *info) { unsigned long fsr; unsigned instr, opf, rs1, rs2;
*** 198,244 **** /* get the operands */ switch (opf & 3) { case 0: /* integer */ info->op1.type = fex_nodata; if (opf & 0x40) { info->op2.type = fex_int; ! info->op2.val.i = *(int*)FPreg(rs2); ! } ! else { info->op2.type = fex_llong; ! info->op2.val.l = *(long long*)FPREG(rs2); } break; case 1: /* single */ info->op1.type = info->op2.type = fex_float; ! info->op1.val.f = *(float*)FPreg(rs1); ! info->op2.val.f = *(float*)FPreg(rs2); break; case 2: /* double */ info->op1.type = info->op2.type = fex_double; ! info->op1.val.d = *(double*)FPREG(rs1); ! info->op2.val.d = *(double*)FPREG(rs2); break; case 3: /* quad */ info->op1.type = info->op2.type = fex_ldouble; ! info->op1.val.q = *(long double*)FPREG(rs1); ! info->op2.val.q = *(long double*)FPREG(rs2); break; } ! /* initialize res to the default untrapped result and ex to the ! corresponding flags (assume trapping is disabled and flags ! are clear) */ info->op = fex_other; info->res.type = fex_nodata; switch ((instr >> 19) & 0x183f) { case 0x1035: /* compare */ info->op = fex_cmp; switch (opf) { case 0x51: /* compare single */ c = (info->op1.val.f == info->op2.val.f); break; --- 206,257 ---- /* get the operands */ switch (opf & 3) { case 0: /* integer */ info->op1.type = fex_nodata; + if (opf & 0x40) { info->op2.type = fex_int; ! info->op2.val.i = *(int *)FPreg(rs2); ! } else { info->op2.type = fex_llong; ! info->op2.val.l = *(long long *)FPREG(rs2); } + break; case 1: /* single */ info->op1.type = info->op2.type = fex_float; ! info->op1.val.f = *(float *)FPreg(rs1); ! info->op2.val.f = *(float *)FPreg(rs2); break; case 2: /* double */ info->op1.type = info->op2.type = fex_double; ! info->op1.val.d = *(double *)FPREG(rs1); ! info->op2.val.d = *(double *)FPREG(rs2); break; case 3: /* quad */ info->op1.type = info->op2.type = fex_ldouble; ! info->op1.val.q = *(long double *)FPREG(rs1); ! info->op2.val.q = *(long double *)FPREG(rs2); break; } ! /* ! * initialize res to the default untrapped result and ex to the ! * corresponding flags (assume trapping is disabled and flags are ! * clear) ! */ info->op = fex_other; info->res.type = fex_nodata; + switch ((instr >> 19) & 0x183f) { case 0x1035: /* compare */ info->op = fex_cmp; + switch (opf) { case 0x51: /* compare single */ c = (info->op1.val.f == info->op2.val.f); break;
*** 260,272 **** --- 273,287 ---- case 0x57: /* compare quad with exception */ c = (info->op1.val.q < info->op2.val.q); break; } + break; case 0x1034: /* add, subtract, multiply, divide, square root, convert */ + switch (opf) { case 0x41: /* add single */ info->op = fex_add; info->res.type = fex_float; info->res.val.f = info->op1.val.f + info->op2.val.f;
*** 321,338 **** break; case 0x69: /* fsmuld */ info->op = fex_mul; info->res.type = fex_double; ! info->res.val.d = (double)info->op1.val.f * (double)info->op2.val.f; break; case 0x6e: /* fdmulq */ info->op = fex_mul; info->res.type = fex_ldouble; ! info->res.val.q = (long double)info->op1.val.d * ! (long double)info->op2.val.d; break; case 0x4d: /* divide single */ info->op = fex_div; info->res.type = fex_float; --- 336,354 ---- break; case 0x69: /* fsmuld */ info->op = fex_mul; info->res.type = fex_double; ! info->res.val.d = (double)info->op1.val.f * ! (double)info->op2.val.f; break; case 0x6e: /* fdmulq */ info->op = fex_mul; info->res.type = fex_ldouble; ! info->res.val.q = (long double)info->op1.val.d * (long ! double)info->op2.val.d; break; case 0x4d: /* divide single */ info->op = fex_div; info->res.type = fex_float;
*** 381,479 **** default: /* conversions */ info->op = fex_cnvt; info->op1 = info->op2; info->op2.type = fex_nodata; switch (opf) { case 0xd1: /* convert single to int */ info->res.type = fex_int; ! info->res.val.i = (int) info->op1.val.f; break; case 0xd2: /* convert double to int */ info->res.type = fex_int; ! info->res.val.i = (int) info->op1.val.d; break; case 0xd3: /* convert quad to int */ info->res.type = fex_int; ! info->res.val.i = (int) info->op1.val.q; break; case 0x81: /* convert single to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long) info->op1.val.f; break; case 0x82: /* convert double to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long) info->op1.val.d; break; case 0x83: /* convert quad to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long) info->op1.val.q; break; case 0xc4: /* convert int to single */ info->res.type = fex_float; ! info->res.val.f = (float) info->op1.val.i; break; case 0x84: /* convert long long to single */ info->res.type = fex_float; ! info->res.val.f = (float) info->op1.val.l; break; case 0x88: /* convert long long to double */ info->res.type = fex_double; ! info->res.val.d = (double) info->op1.val.l; break; case 0xc6: /* convert double to single */ info->res.type = fex_float; ! info->res.val.f = (float) info->op1.val.d; break; case 0xc7: /* convert quad to single */ info->res.type = fex_float; ! info->res.val.f = (float) info->op1.val.q; break; case 0xc9: /* convert single to double */ info->res.type = fex_double; ! info->res.val.d = (double) info->op1.val.f; break; case 0xcb: /* convert quad to double */ info->res.type = fex_double; ! info->res.val.d = (double) info->op1.val.q; break; case 0xcd: /* convert single to quad */ info->res.type = fex_ldouble; ! info->res.val.q = (long double) info->op1.val.f; break; case 0xce: /* convert double to quad */ info->res.type = fex_ldouble; ! info->res.val.q = (long double) info->op1.val.d; break; } } break; } __fenv_getfsr(&fsr); info->flags = (int)__fenv_get_ex(fsr); __fenv_set_ex(fsr, 0); __fenv_setfsr(&fsr); } /* ! * Store the specified result; if no result is given but the exception ! * is underflow or overflow, supply the default trapped result ! */ void __fex_st_result(siginfo_t *sip, ucontext_t *uap, fex_info_t *info) { unsigned instr, opf, rs1, rs2, rd; long double qscl; --- 397,498 ---- default: /* conversions */ info->op = fex_cnvt; info->op1 = info->op2; info->op2.type = fex_nodata; + switch (opf) { case 0xd1: /* convert single to int */ info->res.type = fex_int; ! info->res.val.i = (int)info->op1.val.f; break; case 0xd2: /* convert double to int */ info->res.type = fex_int; ! info->res.val.i = (int)info->op1.val.d; break; case 0xd3: /* convert quad to int */ info->res.type = fex_int; ! info->res.val.i = (int)info->op1.val.q; break; case 0x81: /* convert single to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long)info->op1.val.f; break; case 0x82: /* convert double to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long)info->op1.val.d; break; case 0x83: /* convert quad to long long */ info->res.type = fex_llong; ! info->res.val.l = (long long)info->op1.val.q; break; case 0xc4: /* convert int to single */ info->res.type = fex_float; ! info->res.val.f = (float)info->op1.val.i; break; case 0x84: /* convert long long to single */ info->res.type = fex_float; ! info->res.val.f = (float)info->op1.val.l; break; case 0x88: /* convert long long to double */ info->res.type = fex_double; ! info->res.val.d = (double)info->op1.val.l; break; case 0xc6: /* convert double to single */ info->res.type = fex_float; ! info->res.val.f = (float)info->op1.val.d; break; case 0xc7: /* convert quad to single */ info->res.type = fex_float; ! info->res.val.f = (float)info->op1.val.q; break; case 0xc9: /* convert single to double */ info->res.type = fex_double; ! info->res.val.d = (double)info->op1.val.f; break; case 0xcb: /* convert quad to double */ info->res.type = fex_double; ! info->res.val.d = (double)info->op1.val.q; break; case 0xcd: /* convert single to quad */ info->res.type = fex_ldouble; ! info->res.val.q = (long double)info->op1.val.f; break; case 0xce: /* convert double to quad */ info->res.type = fex_ldouble; ! info->res.val.q = (long double)info->op1.val.d; break; } } + break; } + __fenv_getfsr(&fsr); info->flags = (int)__fenv_get_ex(fsr); __fenv_set_ex(fsr, 0); __fenv_setfsr(&fsr); } /* ! * Store the specified result; if no result is given but the exception ! * is underflow or overflow, supply the default trapped result ! */ void __fex_st_result(siginfo_t *sip, ucontext_t *uap, fex_info_t *info) { unsigned instr, opf, rs1, rs2, rd; long double qscl;
*** 487,550 **** rs2 = instr & 0x1f; rd = (instr >> 25) & 0x1f; /* if the instruction is a compare, just set fcc to unordered */ if (((instr >> 19) & 0x183f) == 0x1035) { ! if (rd == 0) uap->uc_mcontext.fpregs.fpu_fsr |= 0xc00; ! else { #ifdef __sparcv9 ! uap->uc_mcontext.fpregs.fpu_fsr |= (3l << ((rd << 1) + 30)); #else ! ((prxregset_t*)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.pr_v8p.pr_xfsr |= (3 << ((rd - 1) << 1)); #endif } return; } ! /* if there is no result available, try to generate the untrapped ! default */ if (info->res.type == fex_nodata) { /* set scale factors for exponent wrapping */ switch (sip->si_code) { case FPE_FLTOVF: ! fscl = 1.262177448e-29f; /* 2^-96 */ ! dscl = 6.441148769597133308e-232; /* 2^-768 */ ! qscl = 8.778357852076208839765066529179033145e-3700l;/* 2^-12288 */ break; case FPE_FLTUND: ! fscl = 7.922816251e+28f; /* 2^96 */ ! dscl = 1.552518092300708935e+231; /* 2^768 */ ! qscl = 1.139165225263043370845938579315932009e+3699l;/* 2^12288 */ break; default: ! /* user may have blown away the default result by mistake, ! so try to regenerate it */ (void) __fex_get_op(sip, uap, info); if (info->res.type != fex_nodata) goto stuff; /* couldn't do it */ return; } /* get the operands */ switch (opf & 3) { case 1: /* single */ ! info->op1.val.f = *(float*)FPreg(rs1); ! info->op2.val.f = *(float*)FPreg(rs2); break; case 2: /* double */ ! info->op1.val.d = *(double*)FPREG(rs1); ! info->op2.val.d = *(double*)FPREG(rs2); break; case 3: /* quad */ ! info->op1.val.q = *(long double*)FPREG(rs1); ! info->op2.val.q = *(long double*)FPREG(rs2); break; } /* generate the wrapped result */ switch (opf) { --- 506,585 ---- rs2 = instr & 0x1f; rd = (instr >> 25) & 0x1f; /* if the instruction is a compare, just set fcc to unordered */ if (((instr >> 19) & 0x183f) == 0x1035) { ! if (rd == 0) { uap->uc_mcontext.fpregs.fpu_fsr |= 0xc00; ! } else { #ifdef __sparcv9 ! uap->uc_mcontext.fpregs.fpu_fsr |= (3l << ((rd << 1) + ! 30)); #else ! ((prxregset_t *)uap->uc_mcontext.xrs.xrs_ptr)->pr_un. ! pr_v8p.pr_xfsr |= (3 << ((rd - 1) << 1)); #endif } + return; } ! /* ! * if there is no result available, try to generate the untrapped ! * default ! */ if (info->res.type == fex_nodata) { /* set scale factors for exponent wrapping */ switch (sip->si_code) { case FPE_FLTOVF: ! /* 2^-96 */ ! fscl = 1.262177448e-29f; ! /* 2^-768 */ ! dscl = 6.441148769597133308e-232; ! /* 2^-12288 */ ! qscl = 8.778357852076208839765066529179033145e-3700l; break; case FPE_FLTUND: ! /* 2^96 */ ! fscl = 7.922816251e+28f; ! /* 2^768 */ ! dscl = 1.552518092300708935e+231; ! /* 2^12288 */ ! qscl = 1.139165225263043370845938579315932009e+3699l; break; default: ! ! /* ! * user may have blown away the default result by ! * mistake, so try to regenerate it ! */ (void) __fex_get_op(sip, uap, info); + if (info->res.type != fex_nodata) goto stuff; + /* couldn't do it */ return; } /* get the operands */ switch (opf & 3) { case 1: /* single */ ! info->op1.val.f = *(float *)FPreg(rs1); ! info->op2.val.f = *(float *)FPreg(rs2); break; case 2: /* double */ ! info->op1.val.d = *(double *)FPREG(rs1); ! info->op2.val.d = *(double *)FPREG(rs2); break; case 3: /* quad */ ! info->op1.val.q = *(long double *)FPREG(rs1); ! info->op2.val.q = *(long double *)FPREG(rs2); break; } /* generate the wrapped result */ switch (opf) {
*** 584,607 **** qscl * info->op2.val.q); break; case 0x49: /* multiply single */ info->res.type = fex_float; ! info->res.val.f = (fscl * info->op1.val.f) * ! (fscl * info->op2.val.f); break; case 0x4a: /* multiply double */ info->res.type = fex_double; ! info->res.val.d = (dscl * info->op1.val.d) * ! (dscl * info->op2.val.d); break; case 0x4b: /* multiply quad */ info->res.type = fex_ldouble; ! info->res.val.q = (qscl * info->op1.val.q) * ! (qscl * info->op2.val.q); break; case 0x4d: /* divide single */ info->res.type = fex_float; info->res.val.f = (fscl * info->op1.val.f) / --- 619,642 ---- qscl * info->op2.val.q); break; case 0x49: /* multiply single */ info->res.type = fex_float; ! info->res.val.f = (fscl * info->op1.val.f) * (fscl * ! info->op2.val.f); break; case 0x4a: /* multiply double */ info->res.type = fex_double; ! info->res.val.d = (dscl * info->op1.val.d) * (dscl * ! info->op2.val.d); break; case 0x4b: /* multiply quad */ info->res.type = fex_ldouble; ! info->res.val.q = (qscl * info->op1.val.q) * (qscl * ! info->op2.val.q); break; case 0x4d: /* divide single */ info->res.type = fex_float; info->res.val.f = (fscl * info->op1.val.f) /
*** 620,640 **** (info->op2.val.q / qscl); break; case 0xc6: /* convert double to single */ info->res.type = fex_float; ! info->res.val.f = (float) (fscl * (fscl * info->op1.val.d)); break; case 0xc7: /* convert quad to single */ info->res.type = fex_float; ! info->res.val.f = (float) (fscl * (fscl * info->op1.val.q)); break; case 0xcb: /* convert quad to double */ info->res.type = fex_double; ! info->res.val.d = (double) (dscl * (dscl * info->op1.val.q)); break; } if (info->res.type == fex_nodata) /* couldn't do it */ --- 655,678 ---- (info->op2.val.q / qscl); break; case 0xc6: /* convert double to single */ info->res.type = fex_float; ! info->res.val.f = (float)(fscl * (fscl * ! info->op1.val.d)); break; case 0xc7: /* convert quad to single */ info->res.type = fex_float; ! info->res.val.f = (float)(fscl * (fscl * ! info->op1.val.q)); break; case 0xcb: /* convert quad to double */ info->res.type = fex_double; ! info->res.val.d = (double)(dscl * (dscl * ! info->op1.val.q)); break; } if (info->res.type == fex_nodata) /* couldn't do it */
*** 645,899 **** /* stick the result in the destination */ if (opf & 0x80) { /* conversion */ if (opf & 0x10) { /* result is an int */ switch (info->res.type) { case fex_llong: ! info->res.val.i = (int) info->res.val.l; break; case fex_float: ! info->res.val.i = (int) info->res.val.f; break; case fex_double: ! info->res.val.i = (int) info->res.val.d; break; case fex_ldouble: ! info->res.val.i = (int) info->res.val.q; break; default: break; } ! *(int*)FPreg(rd) = info->res.val.i; return; } switch (opf & 0xc) { case 0: /* result is long long */ switch (info->res.type) { case fex_int: ! info->res.val.l = (long long) info->res.val.i; break; case fex_float: ! info->res.val.l = (long long) info->res.val.f; break; case fex_double: ! info->res.val.l = (long long) info->res.val.d; break; case fex_ldouble: ! info->res.val.l = (long long) info->res.val.q; break; default: break; } ! *(long long*)FPREG(rd) = info->res.val.l; break; case 0x4: /* result is float */ switch (info->res.type) { case fex_int: ! info->res.val.f = (float) info->res.val.i; break; case fex_llong: ! info->res.val.f = (float) info->res.val.l; break; case fex_double: ! info->res.val.f = (float) info->res.val.d; break; case fex_ldouble: ! info->res.val.f = (float) info->res.val.q; break; default: break; } ! *(float*)FPreg(rd) = info->res.val.f; break; case 0x8: /* result is double */ switch (info->res.type) { case fex_int: ! info->res.val.d = (double) info->res.val.i; break; case fex_llong: ! info->res.val.d = (double) info->res.val.l; break; case fex_float: ! info->res.val.d = (double) info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double) info->res.val.q; break; default: break; } ! *(double*)FPREG(rd) = info->res.val.d; break; case 0xc: /* result is long double */ switch (info->res.type) { case fex_int: ! info->res.val.q = (long double) info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double) info->res.val.l; break; case fex_float: ! info->res.val.q = (long double) info->res.val.f; break; case fex_double: ! info->res.val.q = (long double) info->res.val.d; break; default: break; } ! *(long double*)FPREG(rd) = info->res.val.q; break; } return; } if ((opf & 0xf0) == 0x60) { /* fsmuld, fdmulq */ switch (opf & 0xc0) { case 0x8: /* result is double */ switch (info->res.type) { case fex_int: ! info->res.val.d = (double) info->res.val.i; break; case fex_llong: ! info->res.val.d = (double) info->res.val.l; break; case fex_float: ! info->res.val.d = (double) info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double) info->res.val.q; break; default: break; } ! *(double*)FPREG(rd) = info->res.val.d; break; case 0xc: /* result is long double */ switch (info->res.type) { case fex_int: ! info->res.val.q = (long double) info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double) info->res.val.l; break; case fex_float: ! info->res.val.q = (long double) info->res.val.f; break; case fex_double: ! info->res.val.q = (long double) info->res.val.d; break; default: break; } ! *(long double*)FPREG(rd) = info->res.val.q; break; } return; } switch (opf & 3) { /* other arithmetic op */ case 1: /* result is float */ switch (info->res.type) { case fex_int: ! info->res.val.f = (float) info->res.val.i; break; case fex_llong: ! info->res.val.f = (float) info->res.val.l; break; case fex_double: ! info->res.val.f = (float) info->res.val.d; break; case fex_ldouble: ! info->res.val.f = (float) info->res.val.q; break; default: break; } ! *(float*)FPreg(rd) = info->res.val.f; break; case 2: /* result is double */ switch (info->res.type) { case fex_int: ! info->res.val.d = (double) info->res.val.i; break; case fex_llong: ! info->res.val.d = (double) info->res.val.l; break; case fex_float: ! info->res.val.d = (double) info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double) info->res.val.q; break; default: break; } ! *(double*)FPREG(rd) = info->res.val.d; break; case 3: /* result is long double */ switch (info->res.type) { case fex_int: ! info->res.val.q = (long double) info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double) info->res.val.l; break; case fex_float: ! info->res.val.q = (long double) info->res.val.f; break; case fex_double: ! info->res.val.q = (long double) info->res.val.d; break; default: break; } ! *(long double*)FPREG(rd) = info->res.val.q; break; } } #endif /* defined(__sparc) */ --- 683,958 ---- /* stick the result in the destination */ if (opf & 0x80) { /* conversion */ if (opf & 0x10) { /* result is an int */ switch (info->res.type) { case fex_llong: ! info->res.val.i = (int)info->res.val.l; break; case fex_float: ! info->res.val.i = (int)info->res.val.f; break; case fex_double: ! info->res.val.i = (int)info->res.val.d; break; case fex_ldouble: ! info->res.val.i = (int)info->res.val.q; break; default: break; } ! ! *(int *)FPreg(rd) = info->res.val.i; return; } switch (opf & 0xc) { case 0: /* result is long long */ + switch (info->res.type) { case fex_int: ! info->res.val.l = (long long)info->res.val.i; break; case fex_float: ! info->res.val.l = (long long)info->res.val.f; break; case fex_double: ! info->res.val.l = (long long)info->res.val.d; break; case fex_ldouble: ! info->res.val.l = (long long)info->res.val.q; break; default: break; } ! ! *(long long *)FPREG(rd) = info->res.val.l; break; case 0x4: /* result is float */ + switch (info->res.type) { case fex_int: ! info->res.val.f = (float)info->res.val.i; break; case fex_llong: ! info->res.val.f = (float)info->res.val.l; break; case fex_double: ! info->res.val.f = (float)info->res.val.d; break; case fex_ldouble: ! info->res.val.f = (float)info->res.val.q; break; default: break; } ! ! *(float *)FPreg(rd) = info->res.val.f; break; case 0x8: /* result is double */ + switch (info->res.type) { case fex_int: ! info->res.val.d = (double)info->res.val.i; break; case fex_llong: ! info->res.val.d = (double)info->res.val.l; break; case fex_float: ! info->res.val.d = (double)info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double)info->res.val.q; break; default: break; } ! ! *(double *)FPREG(rd) = info->res.val.d; break; case 0xc: /* result is long double */ + switch (info->res.type) { case fex_int: ! info->res.val.q = (long double)info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double)info->res.val.l; break; case fex_float: ! info->res.val.q = (long double)info->res.val.f; break; case fex_double: ! info->res.val.q = (long double)info->res.val.d; break; default: break; } ! ! *(long double *)FPREG(rd) = info->res.val.q; break; } + return; } if ((opf & 0xf0) == 0x60) { /* fsmuld, fdmulq */ switch (opf & 0xc0) { case 0x8: /* result is double */ + switch (info->res.type) { case fex_int: ! info->res.val.d = (double)info->res.val.i; break; case fex_llong: ! info->res.val.d = (double)info->res.val.l; break; case fex_float: ! info->res.val.d = (double)info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double)info->res.val.q; break; default: break; } ! ! *(double *)FPREG(rd) = info->res.val.d; break; case 0xc: /* result is long double */ + switch (info->res.type) { case fex_int: ! info->res.val.q = (long double)info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double)info->res.val.l; break; case fex_float: ! info->res.val.q = (long double)info->res.val.f; break; case fex_double: ! info->res.val.q = (long double)info->res.val.d; break; default: break; } ! ! *(long double *)FPREG(rd) = info->res.val.q; break; } + return; } switch (opf & 3) { /* other arithmetic op */ case 1: /* result is float */ + switch (info->res.type) { case fex_int: ! info->res.val.f = (float)info->res.val.i; break; case fex_llong: ! info->res.val.f = (float)info->res.val.l; break; case fex_double: ! info->res.val.f = (float)info->res.val.d; break; case fex_ldouble: ! info->res.val.f = (float)info->res.val.q; break; default: break; } ! ! *(float *)FPreg(rd) = info->res.val.f; break; case 2: /* result is double */ + switch (info->res.type) { case fex_int: ! info->res.val.d = (double)info->res.val.i; break; case fex_llong: ! info->res.val.d = (double)info->res.val.l; break; case fex_float: ! info->res.val.d = (double)info->res.val.f; break; case fex_ldouble: ! info->res.val.d = (double)info->res.val.q; break; default: break; } ! ! *(double *)FPREG(rd) = info->res.val.d; break; case 3: /* result is long double */ + switch (info->res.type) { case fex_int: ! info->res.val.q = (long double)info->res.val.i; break; case fex_llong: ! info->res.val.q = (long double)info->res.val.l; break; case fex_float: ! info->res.val.q = (long double)info->res.val.f; break; case fex_double: ! info->res.val.q = (long double)info->res.val.d; break; default: break; } ! ! *(long double *)FPREG(rd) = info->res.val.q; break; } } #endif /* defined(__sparc) */