unsigned EMUSHORT *a, *b, *c;
{
unsigned EMUSHORT ai[NI], bi[NI];
- int i;
+ int i, sign;
EMULONG lt, lta, ltb;
+/* IEEE says if result is not a NaN, the sign is "-" if and only if
+ operands have opposite signs -- but flush -0 to 0 later if not IEEE. */
+ sign = eisneg(a) ^ eisneg(b);
+
#ifdef NANS
/* Return any NaN input. */
if (eisnan (a))
|| (eisinf (a) && eisinf (b)))
{
mtherr ("ediv", INVALID);
- enan (c, eisneg (a) ^ eisneg (b));
+ enan (c, sign);
return;
}
#endif
#ifdef INFINITY
if (eisinf (b))
{
- if (eisneg (a) ^ eisneg (b))
- *(c + (NE - 1)) = 0x8000;
- else
- *(c + (NE - 1)) = 0;
einfin (c);
- return;
+ goto divsign;
}
/* Anything else over infinity is zero. */
if (eisinf (a))
{
eclear (c);
- return;
+ goto divsign;
}
#endif
emovi (a, ai);
}
}
eclear (c);
- return;
+ goto divsign;
}
dnzro1:
goto dnzro2;
}
}
- if (ai[0] == bi[0])
- *(c + (NE - 1)) = 0;
- else
- *(c + (NE - 1)) = 0x8000;
/* Divide by zero is not an invalid operation.
It is a divide-by-zero operation! */
einfin (c);
mtherr ("ediv", SING);
- return;
+ goto divsign;
}
dnzro2:
/* calculate exponent */
lt = ltb - lta + EXONE;
emdnorm (bi, i, 0, lt, 64);
- /* set the sign */
- if (ai[0] == bi[0])
- bi[0] = 0;
- else
- bi[0] = 0Xffff;
emovo (bi, c);
+
+ divsign:
+
+ if (sign
+#ifndef IEEE
+ && (ecmp (c, ezero) != 0)
+#endif
+ )
+ *(c+(NE-1)) |= 0x8000;
+ else
+ *(c+(NE-1)) &= ~0x8000;
}
/* Multiply e-types A and B, return e-type product C. */
unsigned EMUSHORT *a, *b, *c;
{
unsigned EMUSHORT ai[NI], bi[NI];
- int i, j;
+ int i, j, sign;
EMULONG lt, lta, ltb;
+/* IEEE says if result is not a NaN, the sign is "-" if and only if
+ operands have opposite signs -- but flush -0 to 0 later if not IEEE. */
+ sign = eisneg(a) ^ eisneg(b);
+
#ifdef NANS
/* NaN times anything is the same NaN. */
if (eisnan (a))
|| (eisinf (b) && (ecmp (a, ezero) == 0)))
{
mtherr ("emul", INVALID);
- enan (c, eisneg (a) ^ eisneg (b));
+ enan (c, sign);
return;
}
#endif
#ifdef INFINITY
if (eisinf (a) || eisinf (b))
{
- if (eisneg (a) ^ eisneg (b))
- *(c + (NE - 1)) = 0x8000;
- else
- *(c + (NE - 1)) = 0;
einfin (c);
- return;
+ goto mulsign;
}
#endif
emovi (a, ai);
}
}
eclear (c);
- return;
+ goto mulsign;
}
mnzer1:
}
}
eclear (c);
- return;
+ goto mulsign;
}
mnzer2:
/* calculate exponent */
lt = lta + ltb - (EXONE - 1);
emdnorm (bi, j, 0, lt, 64);
- /* calculate sign of product */
- if (ai[0] == bi[0])
- bi[0] = 0;
- else
- bi[0] = 0xffff;
emovo (bi, c);
+
+ mulsign:
+
+ if (sign
+#ifndef IEEE
+ && (ecmp (c, ezero) != 0)
+#endif
+ )
+ *(c+(NE-1)) |= 0x8000;
+ else
+ *(c+(NE-1)) &= ~0x8000;
}
/* Convert double precision PE to e-type Y. */