struct fp_ext * fp_fsglmul(struct fp_ext *dest, struct fp_ext *src) { int exp; dprint(PINSTR, "fsglmul\n"); fp_dyadic_check(dest, src); /* calculate the correct sign now, as it's necessary for infinities */ dest->sign = src->sign ^ dest->sign; /* Handle infinities */ if (IS_INF(dest)) { if (IS_ZERO(src)) fp_set_nan(dest); return dest; } if (IS_INF(src)) { if (IS_ZERO(dest)) fp_set_nan(dest); else fp_copy_ext(dest, src); return dest; } /* Of course, as we all know, zero * anything = zero. You may not have known that it might be a positive or negative zero... */ if (IS_ZERO(dest) || IS_ZERO(src)) { dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } exp = dest->exp + src->exp - 0x3ffe; /* do a 32-bit multiply */ fp_mul64(dest->mant.m32[0], dest->mant.m32[1], dest->mant.m32[0] & 0xffffff00, src->mant.m32[0] & 0xffffff00); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }
struct fp_ext * fp_fsglmul(struct fp_ext *dest, struct fp_ext *src) { int exp; dprint(PINSTR, "fsglmul\n"); fp_dyadic_check(dest, src); /* */ dest->sign = src->sign ^ dest->sign; /* */ if (IS_INF(dest)) { if (IS_ZERO(src)) fp_set_nan(dest); return dest; } if (IS_INF(src)) { if (IS_ZERO(dest)) fp_set_nan(dest); else fp_copy_ext(dest, src); return dest; } /* */ if (IS_ZERO(dest) || IS_ZERO(src)) { dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } exp = dest->exp + src->exp - 0x3ffe; /* */ fp_mul64(dest->mant.m32[0], dest->mant.m32[1], dest->mant.m32[0] & 0xffffff00, src->mant.m32[0] & 0xffffff00); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }
struct fp_ext * fp_fdiv(struct fp_ext *dest, struct fp_ext *src) { union fp_mant128 temp; int exp; dprint(PINSTR, "fdiv\n"); fp_dyadic_check(dest, src); /* calculate the correct sign now, as it's necessary for infinities */ dest->sign = src->sign ^ dest->sign; /* Handle infinities */ if (IS_INF(dest)) { /* infinity / infinity = NaN (quiet, as always) */ if (IS_INF(src)) fp_set_nan(dest); /* infinity / anything else = infinity (with approprate sign) */ return dest; } if (IS_INF(src)) { /* anything / infinity = zero (with appropriate sign) */ dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } /* zeroes */ if (IS_ZERO(dest)) { /* zero / zero = NaN */ if (IS_ZERO(src)) fp_set_nan(dest); /* zero / anything else = zero */ return dest; } if (IS_ZERO(src)) { /* anything / zero = infinity (with appropriate sign) */ fp_set_sr(FPSR_EXC_DZ); dest->exp = 0x7fff; dest->mant.m64 = 0; return dest; } exp = dest->exp - src->exp + 0x3fff; /* shift up the mantissa for denormalized numbers, so that the highest bit is set, this makes lots of things below easier */ if ((long)dest->mant.m32[0] >= 0) exp -= fp_overnormalize(dest); if ((long)src->mant.m32[0] >= 0) exp -= fp_overnormalize(src); /* now, do the 64-bit divide */ fp_dividemant(&temp, dest, src); /* normalize it back to 64 bits and stuff it back into the destination struct */ if (!temp.m32[0]) { exp--; fp_putmant128(dest, &temp, 32); } else fp_putmant128(dest, &temp, 31); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }
struct fp_ext * fp_fmul(struct fp_ext *dest, struct fp_ext *src) { union fp_mant128 temp; int exp; dprint(PINSTR, "fmul\n"); fp_dyadic_check(dest, src); /* calculate the correct sign now, as it's necessary for infinities */ dest->sign = src->sign ^ dest->sign; /* Handle infinities */ if (IS_INF(dest)) { if (IS_ZERO(src)) fp_set_nan(dest); return dest; } if (IS_INF(src)) { if (IS_ZERO(dest)) fp_set_nan(dest); else fp_copy_ext(dest, src); return dest; } /* Of course, as we all know, zero * anything = zero. You may not have known that it might be a positive or negative zero... */ if (IS_ZERO(dest) || IS_ZERO(src)) { dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } exp = dest->exp + src->exp - 0x3ffe; /* shift up the mantissa for denormalized numbers, so that the highest bit is set, this makes the shift of the result below easier */ if ((long)dest->mant.m32[0] >= 0) exp -= fp_overnormalize(dest); if ((long)src->mant.m32[0] >= 0) exp -= fp_overnormalize(src); /* now, do a 64-bit multiply with expansion */ fp_multiplymant(&temp, dest, src); /* normalize it back to 64 bits and stuff it back into the destination struct */ if ((long)temp.m32[0] > 0) { exp--; fp_putmant128(dest, &temp, 1); } else fp_putmant128(dest, &temp, 0); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }
struct fp_ext * fp_fdiv(struct fp_ext *dest, struct fp_ext *src) { union fp_mant128 temp; int exp; dprint(PINSTR, "fdiv\n"); fp_dyadic_check(dest, src); /* */ dest->sign = src->sign ^ dest->sign; /* */ if (IS_INF(dest)) { /* */ if (IS_INF(src)) fp_set_nan(dest); /* */ return dest; } if (IS_INF(src)) { /* */ dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } /* */ if (IS_ZERO(dest)) { /* */ if (IS_ZERO(src)) fp_set_nan(dest); /* */ return dest; } if (IS_ZERO(src)) { /* */ fp_set_sr(FPSR_EXC_DZ); dest->exp = 0x7fff; dest->mant.m64 = 0; return dest; } exp = dest->exp - src->exp + 0x3fff; /* */ if ((long)dest->mant.m32[0] >= 0) exp -= fp_overnormalize(dest); if ((long)src->mant.m32[0] >= 0) exp -= fp_overnormalize(src); /* */ fp_dividemant(&temp, dest, src); /* */ if (!temp.m32[0]) { exp--; fp_putmant128(dest, &temp, 32); } else fp_putmant128(dest, &temp, 31); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }
struct fp_ext * fp_fmul(struct fp_ext *dest, struct fp_ext *src) { union fp_mant128 temp; int exp; dprint(PINSTR, "fmul\n"); fp_dyadic_check(dest, src); /* */ dest->sign = src->sign ^ dest->sign; /* */ if (IS_INF(dest)) { if (IS_ZERO(src)) fp_set_nan(dest); return dest; } if (IS_INF(src)) { if (IS_ZERO(dest)) fp_set_nan(dest); else fp_copy_ext(dest, src); return dest; } /* */ if (IS_ZERO(dest) || IS_ZERO(src)) { dest->exp = 0; dest->mant.m64 = 0; dest->lowmant = 0; return dest; } exp = dest->exp + src->exp - 0x3ffe; /* */ if ((long)dest->mant.m32[0] >= 0) exp -= fp_overnormalize(dest); if ((long)src->mant.m32[0] >= 0) exp -= fp_overnormalize(src); /* */ fp_multiplymant(&temp, dest, src); /* */ if ((long)temp.m32[0] > 0) { exp--; fp_putmant128(dest, &temp, 1); } else fp_putmant128(dest, &temp, 0); if (exp >= 0x7fff) { fp_set_ovrflw(dest); return dest; } dest->exp = exp; if (exp < 0) { fp_set_sr(FPSR_EXC_UNFL); fp_denormalize(dest, -exp); } return dest; }