um: merge tls_{32,64}.h
[pandora-kernel.git] / arch / x86 / math-emu / fpu_trig.c
index 403cbde..ecd0668 100644 (file)
 #include "fpu_emu.h"
 #include "status_w.h"
 #include "control_w.h"
-#include "reg_constant.h"      
+#include "reg_constant.h"
 
 static void rem_kernel(unsigned long long st0, unsigned long long *y,
-                      unsigned long long st1,
-                      unsigned long long q, int n);
+                      unsigned long long st1, unsigned long long q, int n);
 
 #define BETTER_THAN_486
 
@@ -33,788 +32,706 @@ static void rem_kernel(unsigned long long st0, unsigned long long *y,
    precision of the result sometimes degrades to about 63.9 bits */
 static int trig_arg(FPU_REG *st0_ptr, int even)
 {
-  FPU_REG tmp;
-  u_char tmptag;
-  unsigned long long q;
-  int old_cw = control_word, saved_status = partial_status;
-  int tag, st0_tag = TAG_Valid;
-
-  if ( exponent(st0_ptr) >= 63 )
-    {
-      partial_status |= SW_C2;     /* Reduction incomplete. */
-      return -1;
-    }
-
-  control_word &= ~CW_RC;
-  control_word |= RC_CHOP;
-
-  setpositive(st0_ptr);
-  tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
-                 SIGN_POS);
-
-  FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't overflow
-                                  to 2^64 */
-  q = significand(&tmp);
-  if ( q )
-    {
-      rem_kernel(significand(st0_ptr),
-                &significand(&tmp),
-                significand(&CONST_PI2),
-                q, exponent(st0_ptr) - exponent(&CONST_PI2));
-      setexponent16(&tmp, exponent(&CONST_PI2));
-      st0_tag = FPU_normalize(&tmp);
-      FPU_copy_to_reg0(&tmp, st0_tag);
-    }
-
-  if ( (even && !(q & 1)) || (!even && (q & 1)) )
-    {
-      st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2, FULL_PRECISION);
+       FPU_REG tmp;
+       u_char tmptag;
+       unsigned long long q;
+       int old_cw = control_word, saved_status = partial_status;
+       int tag, st0_tag = TAG_Valid;
+
+       if (exponent(st0_ptr) >= 63) {
+               partial_status |= SW_C2;        /* Reduction incomplete. */
+               return -1;
+       }
 
-#ifdef BETTER_THAN_486
-      /* So far, the results are exact but based upon a 64 bit
-        precision approximation to pi/2. The technique used
-        now is equivalent to using an approximation to pi/2 which
-        is accurate to about 128 bits. */
-      if ( (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64) || (q > 1) )
-       {
-         /* This code gives the effect of having pi/2 to better than
-            128 bits precision. */
-
-         significand(&tmp) = q + 1;
-         setexponent16(&tmp, 63);
-         FPU_normalize(&tmp);
-         tmptag =
-           FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
-                     exponent(&CONST_PI2extra) + exponent(&tmp));
-         setsign(&tmp, getsign(&CONST_PI2extra));
-         st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
-         if ( signnegative(st0_ptr) )
-           {
-             /* CONST_PI2extra is negative, so the result of the addition
-                can be negative. This means that the argument is actually
-                in a different quadrant. The correction is always < pi/2,
-                so it can't overflow into yet another quadrant. */
-             setpositive(st0_ptr);
-             q++;
-           }
+       control_word &= ~CW_RC;
+       control_word |= RC_CHOP;
+
+       setpositive(st0_ptr);
+       tag = FPU_u_div(st0_ptr, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
+                       SIGN_POS);
+
+       FPU_round_to_int(&tmp, tag);    /* Fortunately, this can't overflow
+                                          to 2^64 */
+       q = significand(&tmp);
+       if (q) {
+               rem_kernel(significand(st0_ptr),
+                          &significand(&tmp),
+                          significand(&CONST_PI2),
+                          q, exponent(st0_ptr) - exponent(&CONST_PI2));
+               setexponent16(&tmp, exponent(&CONST_PI2));
+               st0_tag = FPU_normalize(&tmp);
+               FPU_copy_to_reg0(&tmp, st0_tag);
        }
+
+       if ((even && !(q & 1)) || (!even && (q & 1))) {
+               st0_tag =
+                   FPU_sub(REV | LOADED | TAG_Valid, (int)&CONST_PI2,
+                           FULL_PRECISION);
+
+#ifdef BETTER_THAN_486
+               /* So far, the results are exact but based upon a 64 bit
+                  precision approximation to pi/2. The technique used
+                  now is equivalent to using an approximation to pi/2 which
+                  is accurate to about 128 bits. */
+               if ((exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64)
+                   || (q > 1)) {
+                       /* This code gives the effect of having pi/2 to better than
+                          128 bits precision. */
+
+                       significand(&tmp) = q + 1;
+                       setexponent16(&tmp, 63);
+                       FPU_normalize(&tmp);
+                       tmptag =
+                           FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
+                                     FULL_PRECISION, SIGN_POS,
+                                     exponent(&CONST_PI2extra) +
+                                     exponent(&tmp));
+                       setsign(&tmp, getsign(&CONST_PI2extra));
+                       st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
+                       if (signnegative(st0_ptr)) {
+                               /* CONST_PI2extra is negative, so the result of the addition
+                                  can be negative. This means that the argument is actually
+                                  in a different quadrant. The correction is always < pi/2,
+                                  so it can't overflow into yet another quadrant. */
+                               setpositive(st0_ptr);
+                               q++;
+                       }
+               }
 #endif /* BETTER_THAN_486 */
-    }
+       }
 #ifdef BETTER_THAN_486
-  else
-    {
-      /* So far, the results are exact but based upon a 64 bit
-        precision approximation to pi/2. The technique used
-        now is equivalent to using an approximation to pi/2 which
-        is accurate to about 128 bits. */
-      if ( ((q > 0) && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
-          || (q > 1) )
-       {
-         /* This code gives the effect of having p/2 to better than
-            128 bits precision. */
-
-         significand(&tmp) = q;
-         setexponent16(&tmp, 63);
-         FPU_normalize(&tmp);         /* This must return TAG_Valid */
-         tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
-                            SIGN_POS,
-                            exponent(&CONST_PI2extra) + exponent(&tmp));
-         setsign(&tmp, getsign(&CONST_PI2extra));
-         st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp,
-                           FULL_PRECISION);
-         if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
-             ((st0_ptr->sigh > CONST_PI2.sigh)
-              || ((st0_ptr->sigh == CONST_PI2.sigh)
-                  && (st0_ptr->sigl > CONST_PI2.sigl))) )
-           {
-             /* CONST_PI2extra is negative, so the result of the
-                subtraction can be larger than pi/2. This means
-                that the argument is actually in a different quadrant.
-                The correction is always < pi/2, so it can't overflow
-                into yet another quadrant. */
-             st0_tag = FPU_sub(REV|LOADED|TAG_Valid, (int)&CONST_PI2,
-                               FULL_PRECISION);
-             q++;
-           }
+       else {
+               /* So far, the results are exact but based upon a 64 bit
+                  precision approximation to pi/2. The technique used
+                  now is equivalent to using an approximation to pi/2 which
+                  is accurate to about 128 bits. */
+               if (((q > 0)
+                    && (exponent(st0_ptr) <= exponent(&CONST_PI2extra) + 64))
+                   || (q > 1)) {
+                       /* This code gives the effect of having p/2 to better than
+                          128 bits precision. */
+
+                       significand(&tmp) = q;
+                       setexponent16(&tmp, 63);
+                       FPU_normalize(&tmp);    /* This must return TAG_Valid */
+                       tmptag =
+                           FPU_u_mul(&CONST_PI2extra, &tmp, &tmp,
+                                     FULL_PRECISION, SIGN_POS,
+                                     exponent(&CONST_PI2extra) +
+                                     exponent(&tmp));
+                       setsign(&tmp, getsign(&CONST_PI2extra));
+                       st0_tag = FPU_sub(LOADED | (tmptag & 0x0f), (int)&tmp,
+                                         FULL_PRECISION);
+                       if ((exponent(st0_ptr) == exponent(&CONST_PI2)) &&
+                           ((st0_ptr->sigh > CONST_PI2.sigh)
+                            || ((st0_ptr->sigh == CONST_PI2.sigh)
+                                && (st0_ptr->sigl > CONST_PI2.sigl)))) {
+                               /* CONST_PI2extra is negative, so the result of the
+                                  subtraction can be larger than pi/2. This means
+                                  that the argument is actually in a different quadrant.
+                                  The correction is always < pi/2, so it can't overflow
+                                  into yet another quadrant. */
+                               st0_tag =
+                                   FPU_sub(REV | LOADED | TAG_Valid,
+                                           (int)&CONST_PI2, FULL_PRECISION);
+                               q++;
+                       }
+               }
        }
-    }
 #endif /* BETTER_THAN_486 */
 
-  FPU_settag0(st0_tag);
-  control_word = old_cw;
-  partial_status = saved_status & ~SW_C2;     /* Reduction complete. */
+       FPU_settag0(st0_tag);
+       control_word = old_cw;
+       partial_status = saved_status & ~SW_C2; /* Reduction complete. */
 
-  return (q & 3) | even;
+       return (q & 3) | even;
 }
 
-
 /* Convert a long to register */
 static void convert_l2reg(long const *arg, int deststnr)
 {
-  int tag;
-  long num = *arg;
-  u_char sign;
-  FPU_REG *dest = &st(deststnr);
-
-  if (num == 0)
-    {
-      FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
-      return;
-    }
-
-  if (num > 0)
-    { sign = SIGN_POS; }
-  else
-    { num = -num; sign = SIGN_NEG; }
-
-  dest->sigh = num;
-  dest->sigl = 0;
-  setexponent16(dest, 31);
-  tag = FPU_normalize(dest);
-  FPU_settagi(deststnr, tag);
-  setsign(dest, sign);
-  return;
-}
+       int tag;
+       long num = *arg;
+       u_char sign;
+       FPU_REG *dest = &st(deststnr);
 
+       if (num == 0) {
+               FPU_copy_to_regi(&CONST_Z, TAG_Zero, deststnr);
+               return;
+       }
+
+       if (num > 0) {
+               sign = SIGN_POS;
+       } else {
+               num = -num;
+               sign = SIGN_NEG;
+       }
+
+       dest->sigh = num;
+       dest->sigl = 0;
+       setexponent16(dest, 31);
+       tag = FPU_normalize(dest);
+       FPU_settagi(deststnr, tag);
+       setsign(dest, sign);
+       return;
+}
 
 static void single_arg_error(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  if ( st0_tag == TAG_Empty )
-    FPU_stack_underflow();  /* Puts a QNaN in st(0) */
-  else if ( st0_tag == TW_NaN )
-    real_1op_NaN(st0_ptr);       /* return with a NaN in st(0) */
+       if (st0_tag == TAG_Empty)
+               FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+       else if (st0_tag == TW_NaN)
+               real_1op_NaN(st0_ptr);  /* return with a NaN in st(0) */
 #ifdef PARANOID
-  else
-    EXCEPTION(EX_INTERNAL|0x0112);
+       else
+               EXCEPTION(EX_INTERNAL | 0x0112);
 #endif /* PARANOID */
 }
 
-
 static void single_arg_2_error(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  int isNaN;
-
-  switch ( st0_tag )
-    {
-    case TW_NaN:
-      isNaN = (exponent(st0_ptr) == EXP_OVER) && (st0_ptr->sigh & 0x80000000);
-      if ( isNaN && !(st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
-       {
-         EXCEPTION(EX_Invalid);
-         if ( control_word & CW_Invalid )
-           {
-             /* The masked response */
-             /* Convert to a QNaN */
-             st0_ptr->sigh |= 0x40000000;
-             push();
-             FPU_copy_to_reg0(st0_ptr, TAG_Special);
-           }
-       }
-      else if ( isNaN )
-       {
-         /* A QNaN */
-         push();
-         FPU_copy_to_reg0(st0_ptr, TAG_Special);
-       }
-      else
-       {
-         /* pseudoNaN or other unsupported */
-         EXCEPTION(EX_Invalid);
-         if ( control_word & CW_Invalid )
-           {
-             /* The masked response */
-             FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
-             push();
-             FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
-           }
-       }
-      break;              /* return with a NaN in st(0) */
+       int isNaN;
+
+       switch (st0_tag) {
+       case TW_NaN:
+               isNaN = (exponent(st0_ptr) == EXP_OVER)
+                   && (st0_ptr->sigh & 0x80000000);
+               if (isNaN && !(st0_ptr->sigh & 0x40000000)) {   /* Signaling ? */
+                       EXCEPTION(EX_Invalid);
+                       if (control_word & CW_Invalid) {
+                               /* The masked response */
+                               /* Convert to a QNaN */
+                               st0_ptr->sigh |= 0x40000000;
+                               push();
+                               FPU_copy_to_reg0(st0_ptr, TAG_Special);
+                       }
+               } else if (isNaN) {
+                       /* A QNaN */
+                       push();
+                       FPU_copy_to_reg0(st0_ptr, TAG_Special);
+               } else {
+                       /* pseudoNaN or other unsupported */
+                       EXCEPTION(EX_Invalid);
+                       if (control_word & CW_Invalid) {
+                               /* The masked response */
+                               FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+                               push();
+                               FPU_copy_to_reg0(&CONST_QNaN, TAG_Special);
+                       }
+               }
+               break;          /* return with a NaN in st(0) */
 #ifdef PARANOID
-    default:
-      EXCEPTION(EX_INTERNAL|0x0112);
+       default:
+               EXCEPTION(EX_INTERNAL | 0x0112);
 #endif /* PARANOID */
-    }
+       }
 }
 
-
 /*---------------------------------------------------------------------------*/
 
 static void f2xm1(FPU_REG *st0_ptr, u_char tag)
 {
-  FPU_REG a;
+       FPU_REG a;
 
-  clear_C1();
+       clear_C1();
 
-  if ( tag == TAG_Valid )
-    {
-      /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
-      if ( exponent(st0_ptr) < 0 )
-       {
-       denormal_arg:
+       if (tag == TAG_Valid) {
+               /* For an 80486 FPU, the result is undefined if the arg is >= 1.0 */
+               if (exponent(st0_ptr) < 0) {
+                     denormal_arg:
 
-         FPU_to_exp16(st0_ptr, &a);
+                       FPU_to_exp16(st0_ptr, &a);
 
-         /* poly_2xm1(x) requires 0 < st(0) < 1. */
-         poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+                       /* poly_2xm1(x) requires 0 < st(0) < 1. */
+                       poly_2xm1(getsign(st0_ptr), &a, st0_ptr);
+               }
+               set_precision_flag_up();        /* 80486 appears to always do this */
+               return;
        }
-      set_precision_flag_up();   /* 80486 appears to always do this */
-      return;
-    }
 
-  if ( tag == TAG_Zero )
-    return;
+       if (tag == TAG_Zero)
+               return;
 
-  if ( tag == TAG_Special )
-    tag = FPU_Special(st0_ptr);
+       if (tag == TAG_Special)
+               tag = FPU_Special(st0_ptr);
 
-  switch ( tag )
-    {
-    case TW_Denormal:
-      if ( denormal_operand() < 0 )
-       return;
-      goto denormal_arg;
-    case TW_Infinity:
-      if ( signnegative(st0_ptr) )
-       {
-         /* -infinity gives -1 (p16-10) */
-         FPU_copy_to_reg0(&CONST_1, TAG_Valid);
-         setnegative(st0_ptr);
+       switch (tag) {
+       case TW_Denormal:
+               if (denormal_operand() < 0)
+                       return;
+               goto denormal_arg;
+       case TW_Infinity:
+               if (signnegative(st0_ptr)) {
+                       /* -infinity gives -1 (p16-10) */
+                       FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+                       setnegative(st0_ptr);
+               }
+               return;
+       default:
+               single_arg_error(st0_ptr, tag);
        }
-      return;
-    default:
-      single_arg_error(st0_ptr, tag);
-    }
 }
 
-
 static void fptan(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st_new_ptr;
-  int q;
-  u_char arg_sign = getsign(st0_ptr);
-
-  /* Stack underflow has higher priority */
-  if ( st0_tag == TAG_Empty )
-    {
-      FPU_stack_underflow();  /* Puts a QNaN in st(0) */
-      if ( control_word & CW_Invalid )
-       {
-         st_new_ptr = &st(-1);
-         push();
-         FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+       FPU_REG *st_new_ptr;
+       int q;
+       u_char arg_sign = getsign(st0_ptr);
+
+       /* Stack underflow has higher priority */
+       if (st0_tag == TAG_Empty) {
+               FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+               if (control_word & CW_Invalid) {
+                       st_new_ptr = &st(-1);
+                       push();
+                       FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+               }
+               return;
        }
-      return;
-    }
-
-  if ( STACK_OVERFLOW )
-    { FPU_stack_overflow(); return; }
-
-  if ( st0_tag == TAG_Valid )
-    {
-      if ( exponent(st0_ptr) > -40 )
-       {
-         if ( (q = trig_arg(st0_ptr, 0)) == -1 )
-           {
-             /* Operand is out of range */
-             return;
-           }
-
-         poly_tan(st0_ptr);
-         setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
-         set_precision_flag_up();  /* We do not really know if up or down */
+
+       if (STACK_OVERFLOW) {
+               FPU_stack_overflow();
+               return;
        }
-      else
-       {
-         /* For a small arg, the result == the argument */
-         /* Underflow may happen */
 
-       denormal_arg:
+       if (st0_tag == TAG_Valid) {
+               if (exponent(st0_ptr) > -40) {
+                       if ((q = trig_arg(st0_ptr, 0)) == -1) {
+                               /* Operand is out of range */
+                               return;
+                       }
+
+                       poly_tan(st0_ptr);
+                       setsign(st0_ptr, (q & 1) ^ (arg_sign != 0));
+                       set_precision_flag_up();        /* We do not really know if up or down */
+               } else {
+                       /* For a small arg, the result == the argument */
+                       /* Underflow may happen */
+
+                     denormal_arg:
+
+                       FPU_to_exp16(st0_ptr, st0_ptr);
 
-         FPU_to_exp16(st0_ptr, st0_ptr);
-      
-         st0_tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
-         FPU_settag0(st0_tag);
+                       st0_tag =
+                           FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+                       FPU_settag0(st0_tag);
+               }
+               push();
+               FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+               return;
        }
-      push();
-      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
-      return;
-    }
-
-  if ( st0_tag == TAG_Zero )
-    {
-      push();
-      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
-      setcc(0);
-      return;
-    }
-
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-
-  if ( st0_tag == TW_Denormal )
-    {
-      if ( denormal_operand() < 0 )
-       return;
 
-      goto denormal_arg;
-    }
-
-  if ( st0_tag == TW_Infinity )
-    {
-      /* The 80486 treats infinity as an invalid operand */
-      if ( arith_invalid(0) >= 0 )
-       {
-         st_new_ptr = &st(-1);
-         push();
-         arith_invalid(0);
+       if (st0_tag == TAG_Zero) {
+               push();
+               FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+               setcc(0);
+               return;
+       }
+
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+
+       if (st0_tag == TW_Denormal) {
+               if (denormal_operand() < 0)
+                       return;
+
+               goto denormal_arg;
        }
-      return;
-    }
 
-  single_arg_2_error(st0_ptr, st0_tag);
-}
+       if (st0_tag == TW_Infinity) {
+               /* The 80486 treats infinity as an invalid operand */
+               if (arith_invalid(0) >= 0) {
+                       st_new_ptr = &st(-1);
+                       push();
+                       arith_invalid(0);
+               }
+               return;
+       }
 
+       single_arg_2_error(st0_ptr, st0_tag);
+}
 
 static void fxtract(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st_new_ptr;
-  u_char sign;
-  register FPU_REG *st1_ptr = st0_ptr;  /* anticipate */
-
-  if ( STACK_OVERFLOW )
-    {  FPU_stack_overflow(); return; }
-
-  clear_C1();
-
-  if ( st0_tag == TAG_Valid )
-    {
-      long e;
-
-      push();
-      sign = getsign(st1_ptr);
-      reg_copy(st1_ptr, st_new_ptr);
-      setexponent16(st_new_ptr, exponent(st_new_ptr));
-
-    denormal_arg:
-
-      e = exponent16(st_new_ptr);
-      convert_l2reg(&e, 1);
-      setexponentpos(st_new_ptr, 0);
-      setsign(st_new_ptr, sign);
-      FPU_settag0(TAG_Valid);       /* Needed if arg was a denormal */
-      return;
-    }
-  else if ( st0_tag == TAG_Zero )
-    {
-      sign = getsign(st0_ptr);
-
-      if ( FPU_divide_by_zero(0, SIGN_NEG) < 0 )
-       return;
+       FPU_REG *st_new_ptr;
+       u_char sign;
+       register FPU_REG *st1_ptr = st0_ptr;    /* anticipate */
 
-      push();
-      FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
-      setsign(st_new_ptr, sign);
-      return;
-    }
+       if (STACK_OVERFLOW) {
+               FPU_stack_overflow();
+               return;
+       }
 
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
+       clear_C1();
 
-  if ( st0_tag == TW_Denormal )
-    {
-      if (denormal_operand() < 0 )
-       return;
+       if (st0_tag == TAG_Valid) {
+               long e;
 
-      push();
-      sign = getsign(st1_ptr);
-      FPU_to_exp16(st1_ptr, st_new_ptr);
-      goto denormal_arg;
-    }
-  else if ( st0_tag == TW_Infinity )
-    {
-      sign = getsign(st0_ptr);
-      setpositive(st0_ptr);
-      push();
-      FPU_copy_to_reg0(&CONST_INF, TAG_Special);
-      setsign(st_new_ptr, sign);
-      return;
-    }
-  else if ( st0_tag == TW_NaN )
-    {
-      if ( real_1op_NaN(st0_ptr) < 0 )
-       return;
+               push();
+               sign = getsign(st1_ptr);
+               reg_copy(st1_ptr, st_new_ptr);
+               setexponent16(st_new_ptr, exponent(st_new_ptr));
+
+             denormal_arg:
+
+               e = exponent16(st_new_ptr);
+               convert_l2reg(&e, 1);
+               setexponentpos(st_new_ptr, 0);
+               setsign(st_new_ptr, sign);
+               FPU_settag0(TAG_Valid); /* Needed if arg was a denormal */
+               return;
+       } else if (st0_tag == TAG_Zero) {
+               sign = getsign(st0_ptr);
+
+               if (FPU_divide_by_zero(0, SIGN_NEG) < 0)
+                       return;
 
-      push();
-      FPU_copy_to_reg0(st0_ptr, TAG_Special);
-      return;
-    }
-  else if ( st0_tag == TAG_Empty )
-    {
-      /* Is this the correct behaviour? */
-      if ( control_word & EX_Invalid )
-       {
-         FPU_stack_underflow();
-         push();
-         FPU_stack_underflow();
+               push();
+               FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+               setsign(st_new_ptr, sign);
+               return;
+       }
+
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+
+       if (st0_tag == TW_Denormal) {
+               if (denormal_operand() < 0)
+                       return;
+
+               push();
+               sign = getsign(st1_ptr);
+               FPU_to_exp16(st1_ptr, st_new_ptr);
+               goto denormal_arg;
+       } else if (st0_tag == TW_Infinity) {
+               sign = getsign(st0_ptr);
+               setpositive(st0_ptr);
+               push();
+               FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+               setsign(st_new_ptr, sign);
+               return;
+       } else if (st0_tag == TW_NaN) {
+               if (real_1op_NaN(st0_ptr) < 0)
+                       return;
+
+               push();
+               FPU_copy_to_reg0(st0_ptr, TAG_Special);
+               return;
+       } else if (st0_tag == TAG_Empty) {
+               /* Is this the correct behaviour? */
+               if (control_word & EX_Invalid) {
+                       FPU_stack_underflow();
+                       push();
+                       FPU_stack_underflow();
+               } else
+                       EXCEPTION(EX_StackUnder);
        }
-      else
-       EXCEPTION(EX_StackUnder);
-    }
 #ifdef PARANOID
-  else
-    EXCEPTION(EX_INTERNAL | 0x119);
+       else
+               EXCEPTION(EX_INTERNAL | 0x119);
 #endif /* PARANOID */
 }
 
-
 static void fdecstp(void)
 {
-  clear_C1();
-  top--;
+       clear_C1();
+       top--;
 }
 
 static void fincstp(void)
 {
-  clear_C1();
-  top++;
+       clear_C1();
+       top++;
 }
 
-
 static void fsqrt_(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  int expon;
-
-  clear_C1();
-
-  if ( st0_tag == TAG_Valid )
-    {
-      u_char tag;
-      
-      if (signnegative(st0_ptr))
-       {
-         arith_invalid(0);  /* sqrt(negative) is invalid */
-         return;
-       }
+       int expon;
+
+       clear_C1();
 
-      /* make st(0) in  [1.0 .. 4.0) */
-      expon = exponent(st0_ptr);
-
-    denormal_arg:
-
-      setexponent16(st0_ptr, (expon & 1));
-
-      /* Do the computation, the sign of the result will be positive. */
-      tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
-      addexponent(st0_ptr, expon >> 1);
-      FPU_settag0(tag);
-      return;
-    }
-
-  if ( st0_tag == TAG_Zero )
-    return;
-
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-
-  if ( st0_tag == TW_Infinity )
-    {
-      if ( signnegative(st0_ptr) )
-       arith_invalid(0);  /* sqrt(-Infinity) is invalid */
-      return;
-    }
-  else if ( st0_tag == TW_Denormal )
-    {
-      if (signnegative(st0_ptr))
-       {
-         arith_invalid(0);  /* sqrt(negative) is invalid */
-         return;
+       if (st0_tag == TAG_Valid) {
+               u_char tag;
+
+               if (signnegative(st0_ptr)) {
+                       arith_invalid(0);       /* sqrt(negative) is invalid */
+                       return;
+               }
+
+               /* make st(0) in  [1.0 .. 4.0) */
+               expon = exponent(st0_ptr);
+
+             denormal_arg:
+
+               setexponent16(st0_ptr, (expon & 1));
+
+               /* Do the computation, the sign of the result will be positive. */
+               tag = wm_sqrt(st0_ptr, 0, 0, control_word, SIGN_POS);
+               addexponent(st0_ptr, expon >> 1);
+               FPU_settag0(tag);
+               return;
        }
 
-      if ( denormal_operand() < 0 )
-       return;
+       if (st0_tag == TAG_Zero)
+               return;
 
-      FPU_to_exp16(st0_ptr, st0_ptr);
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
 
-      expon = exponent16(st0_ptr);
+       if (st0_tag == TW_Infinity) {
+               if (signnegative(st0_ptr))
+                       arith_invalid(0);       /* sqrt(-Infinity) is invalid */
+               return;
+       } else if (st0_tag == TW_Denormal) {
+               if (signnegative(st0_ptr)) {
+                       arith_invalid(0);       /* sqrt(negative) is invalid */
+                       return;
+               }
 
-      goto denormal_arg;
-    }
+               if (denormal_operand() < 0)
+                       return;
 
-  single_arg_error(st0_ptr, st0_tag);
+               FPU_to_exp16(st0_ptr, st0_ptr);
 
-}
+               expon = exponent16(st0_ptr);
+
+               goto denormal_arg;
+       }
 
+       single_arg_error(st0_ptr, st0_tag);
+
+}
 
 static void frndint_(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  int flags, tag;
+       int flags, tag;
 
-  if ( st0_tag == TAG_Valid )
-    {
-      u_char sign;
+       if (st0_tag == TAG_Valid) {
+               u_char sign;
 
-    denormal_arg:
+             denormal_arg:
 
-      sign = getsign(st0_ptr);
+               sign = getsign(st0_ptr);
 
-      if (exponent(st0_ptr) > 63)
-       return;
+               if (exponent(st0_ptr) > 63)
+                       return;
+
+               if (st0_tag == TW_Denormal) {
+                       if (denormal_operand() < 0)
+                               return;
+               }
+
+               /* Fortunately, this can't overflow to 2^64 */
+               if ((flags = FPU_round_to_int(st0_ptr, st0_tag)))
+                       set_precision_flag(flags);
 
-      if ( st0_tag == TW_Denormal )
-       {
-         if (denormal_operand() < 0 )
-           return;
+               setexponent16(st0_ptr, 63);
+               tag = FPU_normalize(st0_ptr);
+               setsign(st0_ptr, sign);
+               FPU_settag0(tag);
+               return;
        }
 
-      /* Fortunately, this can't overflow to 2^64 */
-      if ( (flags = FPU_round_to_int(st0_ptr, st0_tag)) )
-       set_precision_flag(flags);
-
-      setexponent16(st0_ptr, 63);
-      tag = FPU_normalize(st0_ptr);
-      setsign(st0_ptr, sign);
-      FPU_settag0(tag);
-      return;
-    }
-
-  if ( st0_tag == TAG_Zero )
-    return;
-
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-
-  if ( st0_tag == TW_Denormal )
-    goto denormal_arg;
-  else if ( st0_tag == TW_Infinity )
-    return;
-  else
-    single_arg_error(st0_ptr, st0_tag);
-}
+       if (st0_tag == TAG_Zero)
+               return;
 
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+
+       if (st0_tag == TW_Denormal)
+               goto denormal_arg;
+       else if (st0_tag == TW_Infinity)
+               return;
+       else
+               single_arg_error(st0_ptr, st0_tag);
+}
 
 static int fsin(FPU_REG *st0_ptr, u_char tag)
 {
-  u_char arg_sign = getsign(st0_ptr);
-
-  if ( tag == TAG_Valid )
-    {
-      int q;
-
-      if ( exponent(st0_ptr) > -40 )
-       {
-         if ( (q = trig_arg(st0_ptr, 0)) == -1 )
-           {
-             /* Operand is out of range */
-             return 1;
-           }
-
-         poly_sine(st0_ptr);
-         
-         if (q & 2)
-           changesign(st0_ptr);
-
-         setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
-
-         /* We do not really know if up or down */
-         set_precision_flag_up();
-         return 0;
+       u_char arg_sign = getsign(st0_ptr);
+
+       if (tag == TAG_Valid) {
+               int q;
+
+               if (exponent(st0_ptr) > -40) {
+                       if ((q = trig_arg(st0_ptr, 0)) == -1) {
+                               /* Operand is out of range */
+                               return 1;
+                       }
+
+                       poly_sine(st0_ptr);
+
+                       if (q & 2)
+                               changesign(st0_ptr);
+
+                       setsign(st0_ptr, getsign(st0_ptr) ^ arg_sign);
+
+                       /* We do not really know if up or down */
+                       set_precision_flag_up();
+                       return 0;
+               } else {
+                       /* For a small arg, the result == the argument */
+                       set_precision_flag_up();        /* Must be up. */
+                       return 0;
+               }
        }
-      else
-       {
-         /* For a small arg, the result == the argument */
-         set_precision_flag_up();  /* Must be up. */
-         return 0;
+
+       if (tag == TAG_Zero) {
+               setcc(0);
+               return 0;
        }
-    }
-
-  if ( tag == TAG_Zero )
-    {
-      setcc(0);
-      return 0;
-    }
-
-  if ( tag == TAG_Special )
-    tag = FPU_Special(st0_ptr);
-
-  if ( tag == TW_Denormal )
-    {
-      if ( denormal_operand() < 0 )
-       return 1;
-
-      /* For a small arg, the result == the argument */
-      /* Underflow may happen */
-      FPU_to_exp16(st0_ptr, st0_ptr);
-      
-      tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
-
-      FPU_settag0(tag);
-
-      return 0;
-    }
-  else if ( tag == TW_Infinity )
-    {
-      /* The 80486 treats infinity as an invalid operand */
-      arith_invalid(0);
-      return 1;
-    }
-  else
-    {
-      single_arg_error(st0_ptr, tag);
-      return 1;
-    }
-}
 
+       if (tag == TAG_Special)
+               tag = FPU_Special(st0_ptr);
+
+       if (tag == TW_Denormal) {
+               if (denormal_operand() < 0)
+                       return 1;
+
+               /* For a small arg, the result == the argument */
+               /* Underflow may happen */
+               FPU_to_exp16(st0_ptr, st0_ptr);
+
+               tag = FPU_round(st0_ptr, 1, 0, FULL_PRECISION, arg_sign);
+
+               FPU_settag0(tag);
+
+               return 0;
+       } else if (tag == TW_Infinity) {
+               /* The 80486 treats infinity as an invalid operand */
+               arith_invalid(0);
+               return 1;
+       } else {
+               single_arg_error(st0_ptr, tag);
+               return 1;
+       }
+}
 
 static int f_cos(FPU_REG *st0_ptr, u_char tag)
 {
-  u_char st0_sign;
-
-  st0_sign = getsign(st0_ptr);
-
-  if ( tag == TAG_Valid )
-    {
-      int q;
-
-      if ( exponent(st0_ptr) > -40 )
-       {
-         if ( (exponent(st0_ptr) < 0)
-             || ((exponent(st0_ptr) == 0)
-                 && (significand(st0_ptr) <= 0xc90fdaa22168c234LL)) )
-           {
-             poly_cos(st0_ptr);
-
-             /* We do not really know if up or down */
-             set_precision_flag_down();
-         
-             return 0;
-           }
-         else if ( (q = trig_arg(st0_ptr, FCOS)) != -1 )
-           {
-             poly_sine(st0_ptr);
-
-             if ((q+1) & 2)
-               changesign(st0_ptr);
-
-             /* We do not really know if up or down */
-             set_precision_flag_down();
-         
-             return 0;
-           }
-         else
-           {
-             /* Operand is out of range */
-             return 1;
-           }
-       }
-      else
-       {
-       denormal_arg:
+       u_char st0_sign;
+
+       st0_sign = getsign(st0_ptr);
 
-         setcc(0);
-         FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+       if (tag == TAG_Valid) {
+               int q;
+
+               if (exponent(st0_ptr) > -40) {
+                       if ((exponent(st0_ptr) < 0)
+                           || ((exponent(st0_ptr) == 0)
+                               && (significand(st0_ptr) <=
+                                   0xc90fdaa22168c234LL))) {
+                               poly_cos(st0_ptr);
+
+                               /* We do not really know if up or down */
+                               set_precision_flag_down();
+
+                               return 0;
+                       } else if ((q = trig_arg(st0_ptr, FCOS)) != -1) {
+                               poly_sine(st0_ptr);
+
+                               if ((q + 1) & 2)
+                                       changesign(st0_ptr);
+
+                               /* We do not really know if up or down */
+                               set_precision_flag_down();
+
+                               return 0;
+                       } else {
+                               /* Operand is out of range */
+                               return 1;
+                       }
+               } else {
+                     denormal_arg:
+
+                       setcc(0);
+                       FPU_copy_to_reg0(&CONST_1, TAG_Valid);
 #ifdef PECULIAR_486
-         set_precision_flag_down();  /* 80486 appears to do this. */
+                       set_precision_flag_down();      /* 80486 appears to do this. */
 #else
-         set_precision_flag_up();  /* Must be up. */
+                       set_precision_flag_up();        /* Must be up. */
 #endif /* PECULIAR_486 */
-         return 0;
+                       return 0;
+               }
+       } else if (tag == TAG_Zero) {
+               FPU_copy_to_reg0(&CONST_1, TAG_Valid);
+               setcc(0);
+               return 0;
        }
-    }
-  else if ( tag == TAG_Zero )
-    {
-      FPU_copy_to_reg0(&CONST_1, TAG_Valid);
-      setcc(0);
-      return 0;
-    }
-
-  if ( tag == TAG_Special )
-    tag = FPU_Special(st0_ptr);
-
-  if ( tag == TW_Denormal )
-    {
-      if ( denormal_operand() < 0 )
-       return 1;
-
-      goto denormal_arg;
-    }
-  else if ( tag == TW_Infinity )
-    {
-      /* The 80486 treats infinity as an invalid operand */
-      arith_invalid(0);
-      return 1;
-    }
-  else
-    {
-      single_arg_error(st0_ptr, tag);  /* requires st0_ptr == &st(0) */
-      return 1;
-    }
-}
 
+       if (tag == TAG_Special)
+               tag = FPU_Special(st0_ptr);
+
+       if (tag == TW_Denormal) {
+               if (denormal_operand() < 0)
+                       return 1;
+
+               goto denormal_arg;
+       } else if (tag == TW_Infinity) {
+               /* The 80486 treats infinity as an invalid operand */
+               arith_invalid(0);
+               return 1;
+       } else {
+               single_arg_error(st0_ptr, tag); /* requires st0_ptr == &st(0) */
+               return 1;
+       }
+}
 
 static void fcos(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  f_cos(st0_ptr, st0_tag);
+       f_cos(st0_ptr, st0_tag);
 }
 
-
 static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st_new_ptr;
-  FPU_REG arg;
-  u_char tag;
-
-  /* Stack underflow has higher priority */
-  if ( st0_tag == TAG_Empty )
-    {
-      FPU_stack_underflow();  /* Puts a QNaN in st(0) */
-      if ( control_word & CW_Invalid )
-       {
-         st_new_ptr = &st(-1);
-         push();
-         FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+       FPU_REG *st_new_ptr;
+       FPU_REG arg;
+       u_char tag;
+
+       /* Stack underflow has higher priority */
+       if (st0_tag == TAG_Empty) {
+               FPU_stack_underflow();  /* Puts a QNaN in st(0) */
+               if (control_word & CW_Invalid) {
+                       st_new_ptr = &st(-1);
+                       push();
+                       FPU_stack_underflow();  /* Puts a QNaN in the new st(0) */
+               }
+               return;
        }
-      return;
-    }
-
-  if ( STACK_OVERFLOW )
-    { FPU_stack_overflow(); return; }
-
-  if ( st0_tag == TAG_Special )
-    tag = FPU_Special(st0_ptr);
-  else
-    tag = st0_tag;
-
-  if ( tag == TW_NaN )
-    {
-      single_arg_2_error(st0_ptr, TW_NaN);
-      return;
-    }
-  else if ( tag == TW_Infinity )
-    {
-      /* The 80486 treats infinity as an invalid operand */
-      if ( arith_invalid(0) >= 0 )
-       {
-         /* Masked response */
-         push();
-         arith_invalid(0);
+
+       if (STACK_OVERFLOW) {
+               FPU_stack_overflow();
+               return;
        }
-      return;
-    }
-
-  reg_copy(st0_ptr, &arg);
-  if ( !fsin(st0_ptr, st0_tag) )
-    {
-      push();
-      FPU_copy_to_reg0(&arg, st0_tag);
-      f_cos(&st(0), st0_tag);
-    }
-  else
-    {
-      /* An error, so restore st(0) */
-      FPU_copy_to_reg0(&arg, st0_tag);
-    }
-}
 
+       if (st0_tag == TAG_Special)
+               tag = FPU_Special(st0_ptr);
+       else
+               tag = st0_tag;
+
+       if (tag == TW_NaN) {
+               single_arg_2_error(st0_ptr, TW_NaN);
+               return;
+       } else if (tag == TW_Infinity) {
+               /* The 80486 treats infinity as an invalid operand */
+               if (arith_invalid(0) >= 0) {
+                       /* Masked response */
+                       push();
+                       arith_invalid(0);
+               }
+               return;
+       }
+
+       reg_copy(st0_ptr, &arg);
+       if (!fsin(st0_ptr, st0_tag)) {
+               push();
+               FPU_copy_to_reg0(&arg, st0_tag);
+               f_cos(&st(0), st0_tag);
+       } else {
+               /* An error, so restore st(0) */
+               FPU_copy_to_reg0(&arg, st0_tag);
+       }
+}
 
 /*---------------------------------------------------------------------------*/
 /* The following all require two arguments: st(0) and st(1) */
@@ -826,1020 +743,901 @@ static void fsincos(FPU_REG *st0_ptr, u_char st0_tag)
    result must be zero.
  */
 static void rem_kernel(unsigned long long st0, unsigned long long *y,
-                      unsigned long long st1,
-                      unsigned long long q, int n)
+                      unsigned long long st1, unsigned long long q, int n)
 {
-  int dummy;
-  unsigned long long x;
-
-  x = st0 << n;
-
-  /* Do the required multiplication and subtraction in the one operation */
-
-  /* lsw x -= lsw st1 * lsw q */
-  asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
-               :"=m" (((unsigned *)&x)[0]), "=m" (((unsigned *)&x)[1]),
-               "=a" (dummy)
-               :"2" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[0])
-               :"%dx");
-  /* msw x -= msw st1 * lsw q */
-  asm volatile ("mull %3; subl %%eax,%0"
-               :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
-               :"1" (((unsigned *)&st1)[1]), "m" (((unsigned *)&q)[0])
-               :"%dx");
-  /* msw x -= lsw st1 * msw q */
-  asm volatile ("mull %3; subl %%eax,%0"
-               :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
-               :"1" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[1])
-               :"%dx");
-
-  *y = x;
+       int dummy;
+       unsigned long long x;
+
+       x = st0 << n;
+
+       /* Do the required multiplication and subtraction in the one operation */
+
+       /* lsw x -= lsw st1 * lsw q */
+       asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1":"=m"
+                     (((unsigned *)&x)[0]), "=m"(((unsigned *)&x)[1]),
+                     "=a"(dummy)
+                     :"2"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[0])
+                     :"%dx");
+       /* msw x -= msw st1 * lsw q */
+       asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
+                     "=a"(dummy)
+                     :"1"(((unsigned *)&st1)[1]), "m"(((unsigned *)&q)[0])
+                     :"%dx");
+       /* msw x -= lsw st1 * msw q */
+       asm volatile ("mull %3; subl %%eax,%0":"=m" (((unsigned *)&x)[1]),
+                     "=a"(dummy)
+                     :"1"(((unsigned *)&st1)[0]), "m"(((unsigned *)&q)[1])
+                     :"%dx");
+
+       *y = x;
 }
 
-
 /* Remainder of st(0) / st(1) */
 /* This routine produces exact results, i.e. there is never any
    rounding or truncation, etc of the result. */
 static void do_fprem(FPU_REG *st0_ptr, u_char st0_tag, int round)
 {
-  FPU_REG *st1_ptr = &st(1);
-  u_char st1_tag = FPU_gettagi(1);
-
-  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
-    {
-      FPU_REG tmp, st0, st1;
-      u_char st0_sign, st1_sign;
-      u_char tmptag;
-      int tag;
-      int old_cw;
-      int expdif;
-      long long q;
-      unsigned short saved_status;
-      int cc;
-
-    fprem_valid:
-      /* Convert registers for internal use. */
-      st0_sign = FPU_to_exp16(st0_ptr, &st0);
-      st1_sign = FPU_to_exp16(st1_ptr, &st1);
-      expdif = exponent16(&st0) - exponent16(&st1);
-
-      old_cw = control_word;
-      cc = 0;
-
-      /* We want the status following the denorm tests, but don't want
-        the status changed by the arithmetic operations. */
-      saved_status = partial_status;
-      control_word &= ~CW_RC;
-      control_word |= RC_CHOP;
-
-      if ( expdif < 64 )
-       {
-         /* This should be the most common case */
-
-         if ( expdif > -2 )
-           {
-             u_char sign = st0_sign ^ st1_sign;
-             tag = FPU_u_div(&st0, &st1, &tmp,
-                             PR_64_BITS | RC_CHOP | 0x3f,
-                             sign);
-             setsign(&tmp, sign);
-
-             if ( exponent(&tmp) >= 0 )
-               {
-                 FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't
-                                                  overflow to 2^64 */
-                 q = significand(&tmp);
-
-                 rem_kernel(significand(&st0),
-                            &significand(&tmp),
-                            significand(&st1),
-                            q, expdif);
-
-                 setexponent16(&tmp, exponent16(&st1));
-               }
-             else
-               {
-                 reg_copy(&st0, &tmp);
-                 q = 0;
-               }
-
-             if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
-               {
-                 /* We may need to subtract st(1) once more,
-                    to get a result <= 1/2 of st(1). */
-                 unsigned long long x;
-                 expdif = exponent16(&st1) - exponent16(&tmp);
-                 if ( expdif <= 1 )
-                   {
-                     if ( expdif == 0 )
-                       x = significand(&st1) - significand(&tmp);
-                     else /* expdif is 1 */
-                       x = (significand(&st1) << 1) - significand(&tmp);
-                     if ( (x < significand(&tmp)) ||
-                         /* or equi-distant (from 0 & st(1)) and q is odd */
-                         ((x == significand(&tmp)) && (q & 1) ) )
-                       {
-                         st0_sign = ! st0_sign;
-                         significand(&tmp) = x;
-                         q++;
+       FPU_REG *st1_ptr = &st(1);
+       u_char st1_tag = FPU_gettagi(1);
+
+       if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+               FPU_REG tmp, st0, st1;
+               u_char st0_sign, st1_sign;
+               u_char tmptag;
+               int tag;
+               int old_cw;
+               int expdif;
+               long long q;
+               unsigned short saved_status;
+               int cc;
+
+             fprem_valid:
+               /* Convert registers for internal use. */
+               st0_sign = FPU_to_exp16(st0_ptr, &st0);
+               st1_sign = FPU_to_exp16(st1_ptr, &st1);
+               expdif = exponent16(&st0) - exponent16(&st1);
+
+               old_cw = control_word;
+               cc = 0;
+
+               /* We want the status following the denorm tests, but don't want
+                  the status changed by the arithmetic operations. */
+               saved_status = partial_status;
+               control_word &= ~CW_RC;
+               control_word |= RC_CHOP;
+
+               if (expdif < 64) {
+                       /* This should be the most common case */
+
+                       if (expdif > -2) {
+                               u_char sign = st0_sign ^ st1_sign;
+                               tag = FPU_u_div(&st0, &st1, &tmp,
+                                               PR_64_BITS | RC_CHOP | 0x3f,
+                                               sign);
+                               setsign(&tmp, sign);
+
+                               if (exponent(&tmp) >= 0) {
+                                       FPU_round_to_int(&tmp, tag);    /* Fortunately, this can't
+                                                                          overflow to 2^64 */
+                                       q = significand(&tmp);
+
+                                       rem_kernel(significand(&st0),
+                                                  &significand(&tmp),
+                                                  significand(&st1),
+                                                  q, expdif);
+
+                                       setexponent16(&tmp, exponent16(&st1));
+                               } else {
+                                       reg_copy(&st0, &tmp);
+                                       q = 0;
+                               }
+
+                               if ((round == RC_RND)
+                                   && (tmp.sigh & 0xc0000000)) {
+                                       /* We may need to subtract st(1) once more,
+                                          to get a result <= 1/2 of st(1). */
+                                       unsigned long long x;
+                                       expdif =
+                                           exponent16(&st1) - exponent16(&tmp);
+                                       if (expdif <= 1) {
+                                               if (expdif == 0)
+                                                       x = significand(&st1) -
+                                                           significand(&tmp);
+                                               else    /* expdif is 1 */
+                                                       x = (significand(&st1)
+                                                            << 1) -
+                                                           significand(&tmp);
+                                               if ((x < significand(&tmp)) ||
+                                                   /* or equi-distant (from 0 & st(1)) and q is odd */
+                                                   ((x == significand(&tmp))
+                                                    && (q & 1))) {
+                                                       st0_sign = !st0_sign;
+                                                       significand(&tmp) = x;
+                                                       q++;
+                                               }
+                                       }
+                               }
+
+                               if (q & 4)
+                                       cc |= SW_C0;
+                               if (q & 2)
+                                       cc |= SW_C3;
+                               if (q & 1)
+                                       cc |= SW_C1;
+                       } else {
+                               control_word = old_cw;
+                               setcc(0);
+                               return;
                        }
-                   }
-               }
-
-             if (q & 4) cc |= SW_C0;
-             if (q & 2) cc |= SW_C3;
-             if (q & 1) cc |= SW_C1;
-           }
-         else
-           {
-             control_word = old_cw;
-             setcc(0);
-             return;
-           }
-       }
-      else
-       {
-         /* There is a large exponent difference ( >= 64 ) */
-         /* To make much sense, the code in this section should
-            be done at high precision. */
-         int exp_1, N;
-         u_char sign;
-
-         /* prevent overflow here */
-         /* N is 'a number between 32 and 63' (p26-113) */
-         reg_copy(&st0, &tmp);
-         tmptag = st0_tag;
-         N = (expdif & 0x0000001f) + 32;  /* This choice gives results
-                                             identical to an AMD 486 */
-         setexponent16(&tmp, N);
-         exp_1 = exponent16(&st1);
-         setexponent16(&st1, 0);
-         expdif -= N;
-
-         sign = getsign(&tmp) ^ st1_sign;
-         tag = FPU_u_div(&tmp, &st1, &tmp, PR_64_BITS | RC_CHOP | 0x3f,
-                         sign);
-         setsign(&tmp, sign);
-
-         FPU_round_to_int(&tmp, tag);  /* Fortunately, this can't
-                                          overflow to 2^64 */
-
-         rem_kernel(significand(&st0),
-                    &significand(&tmp),
-                    significand(&st1),
-                    significand(&tmp),
-                    exponent(&tmp)
-                    ); 
-         setexponent16(&tmp, exp_1 + expdif);
-
-         /* It is possible for the operation to be complete here.
-            What does the IEEE standard say? The Intel 80486 manual
-            implies that the operation will never be completed at this
-            point, and the behaviour of a real 80486 confirms this.
-          */
-         if ( !(tmp.sigh | tmp.sigl) )
-           {
-             /* The result is zero */
-             control_word = old_cw;
-             partial_status = saved_status;
-             FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
-             setsign(&st0, st0_sign);
+               } else {
+                       /* There is a large exponent difference ( >= 64 ) */
+                       /* To make much sense, the code in this section should
+                          be done at high precision. */
+                       int exp_1, N;
+                       u_char sign;
+
+                       /* prevent overflow here */
+                       /* N is 'a number between 32 and 63' (p26-113) */
+                       reg_copy(&st0, &tmp);
+                       tmptag = st0_tag;
+                       N = (expdif & 0x0000001f) + 32; /* This choice gives results
+                                                          identical to an AMD 486 */
+                       setexponent16(&tmp, N);
+                       exp_1 = exponent16(&st1);
+                       setexponent16(&st1, 0);
+                       expdif -= N;
+
+                       sign = getsign(&tmp) ^ st1_sign;
+                       tag =
+                           FPU_u_div(&tmp, &st1, &tmp,
+                                     PR_64_BITS | RC_CHOP | 0x3f, sign);
+                       setsign(&tmp, sign);
+
+                       FPU_round_to_int(&tmp, tag);    /* Fortunately, this can't
+                                                          overflow to 2^64 */
+
+                       rem_kernel(significand(&st0),
+                                  &significand(&tmp),
+                                  significand(&st1),
+                                  significand(&tmp), exponent(&tmp)
+                           );
+                       setexponent16(&tmp, exp_1 + expdif);
+
+                       /* It is possible for the operation to be complete here.
+                          What does the IEEE standard say? The Intel 80486 manual
+                          implies that the operation will never be completed at this
+                          point, and the behaviour of a real 80486 confirms this.
+                        */
+                       if (!(tmp.sigh | tmp.sigl)) {
+                               /* The result is zero */
+                               control_word = old_cw;
+                               partial_status = saved_status;
+                               FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+                               setsign(&st0, st0_sign);
 #ifdef PECULIAR_486
-             setcc(SW_C2);
+                               setcc(SW_C2);
 #else
-             setcc(0);
+                               setcc(0);
 #endif /* PECULIAR_486 */
-             return;
-           }
-         cc = SW_C2;
-       }
+                               return;
+                       }
+                       cc = SW_C2;
+               }
 
-      control_word = old_cw;
-      partial_status = saved_status;
-      tag = FPU_normalize_nuo(&tmp);
-      reg_copy(&tmp, st0_ptr);
-
-      /* The only condition to be looked for is underflow,
-        and it can occur here only if underflow is unmasked. */
-      if ( (exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
-         && !(control_word & CW_Underflow) )
-       {
-         setcc(cc);
-         tag = arith_underflow(st0_ptr);
-         setsign(st0_ptr, st0_sign);
-         FPU_settag0(tag);
-         return;
-       }
-      else if ( (exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero) )
-       {
-         stdexp(st0_ptr);
-         setsign(st0_ptr, st0_sign);
-       }
-      else
-       {
-         tag = FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
-       }
-      FPU_settag0(tag);
-      setcc(cc);
+               control_word = old_cw;
+               partial_status = saved_status;
+               tag = FPU_normalize_nuo(&tmp);
+               reg_copy(&tmp, st0_ptr);
+
+               /* The only condition to be looked for is underflow,
+                  and it can occur here only if underflow is unmasked. */
+               if ((exponent16(&tmp) <= EXP_UNDER) && (tag != TAG_Zero)
+                   && !(control_word & CW_Underflow)) {
+                       setcc(cc);
+                       tag = arith_underflow(st0_ptr);
+                       setsign(st0_ptr, st0_sign);
+                       FPU_settag0(tag);
+                       return;
+               } else if ((exponent16(&tmp) > EXP_UNDER) || (tag == TAG_Zero)) {
+                       stdexp(st0_ptr);
+                       setsign(st0_ptr, st0_sign);
+               } else {
+                       tag =
+                           FPU_round(st0_ptr, 0, 0, FULL_PRECISION, st0_sign);
+               }
+               FPU_settag0(tag);
+               setcc(cc);
 
-      return;
-    }
+               return;
+       }
 
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-  if ( st1_tag == TAG_Special )
-    st1_tag = FPU_Special(st1_ptr);
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+       if (st1_tag == TAG_Special)
+               st1_tag = FPU_Special(st1_ptr);
 
-  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+       if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
            || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
-           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
-    {
-      if ( denormal_operand() < 0 )
-       return;
-      goto fprem_valid;
-    }
-  else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
-    {
-      FPU_stack_underflow();
-      return;
-    }
-  else if ( st0_tag == TAG_Zero )
-    {
-      if ( st1_tag == TAG_Valid )
-       {
-         setcc(0); return;
-       }
-      else if ( st1_tag == TW_Denormal )
-       {
-         if ( denormal_operand() < 0 )
-           return;
-         setcc(0); return;
-       }
-      else if ( st1_tag == TAG_Zero )
-       { arith_invalid(0); return; } /* fprem(?,0) always invalid */
-      else if ( st1_tag == TW_Infinity )
-       { setcc(0); return; }
-    }
-  else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
-    {
-      if ( st1_tag == TAG_Zero )
-       {
-         arith_invalid(0); /* fprem(Valid,Zero) is invalid */
-         return;
-       }
-      else if ( st1_tag != TW_NaN )
-       {
-         if ( ((st0_tag == TW_Denormal) || (st1_tag == TW_Denormal))
-              && (denormal_operand() < 0) )
-           return;
-
-         if ( st1_tag == TW_Infinity )
-           {
-             /* fprem(Valid,Infinity) is o.k. */
-             setcc(0); return;
-           }
-       }
-    }
-  else if ( st0_tag == TW_Infinity )
-    {
-      if ( st1_tag != TW_NaN )
-       {
-         arith_invalid(0); /* fprem(Infinity,?) is invalid */
-         return;
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+               if (denormal_operand() < 0)
+                       return;
+               goto fprem_valid;
+       } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+               FPU_stack_underflow();
+               return;
+       } else if (st0_tag == TAG_Zero) {
+               if (st1_tag == TAG_Valid) {
+                       setcc(0);
+                       return;
+               } else if (st1_tag == TW_Denormal) {
+                       if (denormal_operand() < 0)
+                               return;
+                       setcc(0);
+                       return;
+               } else if (st1_tag == TAG_Zero) {
+                       arith_invalid(0);
+                       return;
+               } /* fprem(?,0) always invalid */
+               else if (st1_tag == TW_Infinity) {
+                       setcc(0);
+                       return;
+               }
+       } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+               if (st1_tag == TAG_Zero) {
+                       arith_invalid(0);       /* fprem(Valid,Zero) is invalid */
+                       return;
+               } else if (st1_tag != TW_NaN) {
+                       if (((st0_tag == TW_Denormal)
+                            || (st1_tag == TW_Denormal))
+                           && (denormal_operand() < 0))
+                               return;
+
+                       if (st1_tag == TW_Infinity) {
+                               /* fprem(Valid,Infinity) is o.k. */
+                               setcc(0);
+                               return;
+                       }
+               }
+       } else if (st0_tag == TW_Infinity) {
+               if (st1_tag != TW_NaN) {
+                       arith_invalid(0);       /* fprem(Infinity,?) is invalid */
+                       return;
+               }
        }
-    }
 
-  /* One of the registers must contain a NaN if we got here. */
+       /* One of the registers must contain a NaN if we got here. */
 
 #ifdef PARANOID
-  if ( (st0_tag != TW_NaN) && (st1_tag != TW_NaN) )
-      EXCEPTION(EX_INTERNAL | 0x118);
+       if ((st0_tag != TW_NaN) && (st1_tag != TW_NaN))
+               EXCEPTION(EX_INTERNAL | 0x118);
 #endif /* PARANOID */
 
-  real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
+       real_2op_NaN(st1_ptr, st1_tag, 0, st1_ptr);
 
 }
 
-
 /* ST(1) <- ST(1) * log ST;  pop ST */
 static void fyl2x(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st1_ptr = &st(1), exponent;
-  u_char st1_tag = FPU_gettagi(1);
-  u_char sign;
-  int e, tag;
-
-  clear_C1();
-
-  if ( (st0_tag == TAG_Valid) && (st1_tag == TAG_Valid) )
-    {
-    both_valid:
-      /* Both regs are Valid or Denormal */
-      if ( signpositive(st0_ptr) )
-       {
-         if ( st0_tag == TW_Denormal )
-           FPU_to_exp16(st0_ptr, st0_ptr);
-         else
-           /* Convert st(0) for internal use. */
-           setexponent16(st0_ptr, exponent(st0_ptr));
-
-         if ( (st0_ptr->sigh == 0x80000000) && (st0_ptr->sigl == 0) )
-           {
-             /* Special case. The result can be precise. */
-             u_char esign;
-             e = exponent16(st0_ptr);
-             if ( e >= 0 )
-               {
-                 exponent.sigh = e;
-                 esign = SIGN_POS;
-               }
-             else
-               {
-                 exponent.sigh = -e;
-                 esign = SIGN_NEG;
+       FPU_REG *st1_ptr = &st(1), exponent;
+       u_char st1_tag = FPU_gettagi(1);
+       u_char sign;
+       int e, tag;
+
+       clear_C1();
+
+       if ((st0_tag == TAG_Valid) && (st1_tag == TAG_Valid)) {
+             both_valid:
+               /* Both regs are Valid or Denormal */
+               if (signpositive(st0_ptr)) {
+                       if (st0_tag == TW_Denormal)
+                               FPU_to_exp16(st0_ptr, st0_ptr);
+                       else
+                               /* Convert st(0) for internal use. */
+                               setexponent16(st0_ptr, exponent(st0_ptr));
+
+                       if ((st0_ptr->sigh == 0x80000000)
+                           && (st0_ptr->sigl == 0)) {
+                               /* Special case. The result can be precise. */
+                               u_char esign;
+                               e = exponent16(st0_ptr);
+                               if (e >= 0) {
+                                       exponent.sigh = e;
+                                       esign = SIGN_POS;
+                               } else {
+                                       exponent.sigh = -e;
+                                       esign = SIGN_NEG;
+                               }
+                               exponent.sigl = 0;
+                               setexponent16(&exponent, 31);
+                               tag = FPU_normalize_nuo(&exponent);
+                               stdexp(&exponent);
+                               setsign(&exponent, esign);
+                               tag =
+                                   FPU_mul(&exponent, tag, 1, FULL_PRECISION);
+                               if (tag >= 0)
+                                       FPU_settagi(1, tag);
+                       } else {
+                               /* The usual case */
+                               sign = getsign(st1_ptr);
+                               if (st1_tag == TW_Denormal)
+                                       FPU_to_exp16(st1_ptr, st1_ptr);
+                               else
+                                       /* Convert st(1) for internal use. */
+                                       setexponent16(st1_ptr,
+                                                     exponent(st1_ptr));
+                               poly_l2(st0_ptr, st1_ptr, sign);
+                       }
+               } else {
+                       /* negative */
+                       if (arith_invalid(1) < 0)
+                               return;
                }
-             exponent.sigl = 0;
-             setexponent16(&exponent, 31);
-             tag = FPU_normalize_nuo(&exponent);
-             stdexp(&exponent);
-             setsign(&exponent, esign);
-             tag = FPU_mul(&exponent, tag, 1, FULL_PRECISION);
-             if ( tag >= 0 )
-               FPU_settagi(1, tag);
-           }
-         else
-           {
-             /* The usual case */
-             sign = getsign(st1_ptr);
-             if ( st1_tag == TW_Denormal )
-               FPU_to_exp16(st1_ptr, st1_ptr);
-             else
-               /* Convert st(1) for internal use. */
-               setexponent16(st1_ptr, exponent(st1_ptr));
-             poly_l2(st0_ptr, st1_ptr, sign);
-           }
-       }
-      else
-       {
-         /* negative */
-         if ( arith_invalid(1) < 0 )
-           return;
-       }
 
-      FPU_pop();
-
-      return;
-    }
-
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-  if ( st1_tag == TAG_Special )
-    st1_tag = FPU_Special(st1_ptr);
-
-  if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
-    {
-      FPU_stack_underflow_pop(1);
-      return;
-    }
-  else if ( (st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal) )
-    {
-      if ( st0_tag == TAG_Zero )
-       {
-         if ( st1_tag == TAG_Zero )
-           {
-             /* Both args zero is invalid */
-             if ( arith_invalid(1) < 0 )
-               return;
-           }
-         else
-           {
-             u_char sign;
-             sign = getsign(st1_ptr)^SIGN_NEG;
-             if ( FPU_divide_by_zero(1, sign) < 0 )
-               return;
+               FPU_pop();
 
-             setsign(st1_ptr, sign);
-           }
-       }
-      else if ( st1_tag == TAG_Zero )
-       {
-         /* st(1) contains zero, st(0) valid <> 0 */
-         /* Zero is the valid answer */
-         sign = getsign(st1_ptr);
-         
-         if ( signnegative(st0_ptr) )
-           {
-             /* log(negative) */
-             if ( arith_invalid(1) < 0 )
                return;
-           }
-         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
-         else
-           {
-             if ( exponent(st0_ptr) < 0 )
-               sign ^= SIGN_NEG;
-
-             FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
-             setsign(st1_ptr, sign);
-           }
        }
-      else
-       {
-         /* One or both operands are denormals. */
-         if ( denormal_operand() < 0 )
-           return;
-         goto both_valid;
-       }
-    }
-  else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
-    {
-      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
-       return;
-    }
-  /* One or both arg must be an infinity */
-  else if ( st0_tag == TW_Infinity )
-    {
-      if ( (signnegative(st0_ptr)) || (st1_tag == TAG_Zero) )
-       {
-         /* log(-infinity) or 0*log(infinity) */
-         if ( arith_invalid(1) < 0 )
-           return;
-       }
-      else
-       {
-         u_char sign = getsign(st1_ptr);
 
-         if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+       if (st1_tag == TAG_Special)
+               st1_tag = FPU_Special(st1_ptr);
 
-         FPU_copy_to_reg1(&CONST_INF, TAG_Special);
-         setsign(st1_ptr, sign);
-       }
-    }
-  /* st(1) must be infinity here */
-  else if ( ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
-           && ( signpositive(st0_ptr) ) )
-    {
-      if ( exponent(st0_ptr) >= 0 )
-       {
-         if ( (exponent(st0_ptr) == 0) &&
-             (st0_ptr->sigh == 0x80000000) &&
-             (st0_ptr->sigl == 0) )
-           {
-             /* st(0) holds 1.0 */
-             /* infinity*log(1) */
-             if ( arith_invalid(1) < 0 )
+       if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+               FPU_stack_underflow_pop(1);
                return;
-           }
-         /* else st(0) is positive and > 1.0 */
+       } else if ((st0_tag <= TW_Denormal) && (st1_tag <= TW_Denormal)) {
+               if (st0_tag == TAG_Zero) {
+                       if (st1_tag == TAG_Zero) {
+                               /* Both args zero is invalid */
+                               if (arith_invalid(1) < 0)
+                                       return;
+                       } else {
+                               u_char sign;
+                               sign = getsign(st1_ptr) ^ SIGN_NEG;
+                               if (FPU_divide_by_zero(1, sign) < 0)
+                                       return;
+
+                               setsign(st1_ptr, sign);
+                       }
+               } else if (st1_tag == TAG_Zero) {
+                       /* st(1) contains zero, st(0) valid <> 0 */
+                       /* Zero is the valid answer */
+                       sign = getsign(st1_ptr);
+
+                       if (signnegative(st0_ptr)) {
+                               /* log(negative) */
+                               if (arith_invalid(1) < 0)
+                                       return;
+                       } else if ((st0_tag == TW_Denormal)
+                                  && (denormal_operand() < 0))
+                               return;
+                       else {
+                               if (exponent(st0_ptr) < 0)
+                                       sign ^= SIGN_NEG;
+
+                               FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+                               setsign(st1_ptr, sign);
+                       }
+               } else {
+                       /* One or both operands are denormals. */
+                       if (denormal_operand() < 0)
+                               return;
+                       goto both_valid;
+               }
+       } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+               if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+                       return;
+       }
+       /* One or both arg must be an infinity */
+       else if (st0_tag == TW_Infinity) {
+               if ((signnegative(st0_ptr)) || (st1_tag == TAG_Zero)) {
+                       /* log(-infinity) or 0*log(infinity) */
+                       if (arith_invalid(1) < 0)
+                               return;
+               } else {
+                       u_char sign = getsign(st1_ptr);
+
+                       if ((st1_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
+
+                       FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+                       setsign(st1_ptr, sign);
+               }
        }
-      else
-       {
-         /* st(0) is positive and < 1.0 */
+       /* st(1) must be infinity here */
+       else if (((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal))
+                && (signpositive(st0_ptr))) {
+               if (exponent(st0_ptr) >= 0) {
+                       if ((exponent(st0_ptr) == 0) &&
+                           (st0_ptr->sigh == 0x80000000) &&
+                           (st0_ptr->sigl == 0)) {
+                               /* st(0) holds 1.0 */
+                               /* infinity*log(1) */
+                               if (arith_invalid(1) < 0)
+                                       return;
+                       }
+                       /* else st(0) is positive and > 1.0 */
+               } else {
+                       /* st(0) is positive and < 1.0 */
 
-         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
+                       if ((st0_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
 
-         changesign(st1_ptr);
-       }
-    }
-  else
-    {
-      /* st(0) must be zero or negative */
-      if ( st0_tag == TAG_Zero )
-       {
-         /* This should be invalid, but a real 80486 is happy with it. */
+                       changesign(st1_ptr);
+               }
+       } else {
+               /* st(0) must be zero or negative */
+               if (st0_tag == TAG_Zero) {
+                       /* This should be invalid, but a real 80486 is happy with it. */
 
 #ifndef PECULIAR_486
-         sign = getsign(st1_ptr);
-         if ( FPU_divide_by_zero(1, sign) < 0 )
-           return;
+                       sign = getsign(st1_ptr);
+                       if (FPU_divide_by_zero(1, sign) < 0)
+                               return;
 #endif /* PECULIAR_486 */
 
-         changesign(st1_ptr);
+                       changesign(st1_ptr);
+               } else if (arith_invalid(1) < 0)        /* log(negative) */
+                       return;
        }
-      else if ( arith_invalid(1) < 0 )   /* log(negative) */
-       return;
-    }
 
-  FPU_pop();
+       FPU_pop();
 }
 
-
 static void fpatan(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st1_ptr = &st(1);
-  u_char st1_tag = FPU_gettagi(1);
-  int tag;
+       FPU_REG *st1_ptr = &st(1);
+       u_char st1_tag = FPU_gettagi(1);
+       int tag;
 
-  clear_C1();
-  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
-    {
-    valid_atan:
+       clear_C1();
+       if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+             valid_atan:
 
-      poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
+               poly_atan(st0_ptr, st0_tag, st1_ptr, st1_tag);
 
-      FPU_pop();
+               FPU_pop();
 
-      return;
-    }
+               return;
+       }
 
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-  if ( st1_tag == TAG_Special )
-    st1_tag = FPU_Special(st1_ptr);
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+       if (st1_tag == TAG_Special)
+               st1_tag = FPU_Special(st1_ptr);
 
-  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+       if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
            || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
-           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
-    {
-      if ( denormal_operand() < 0 )
-       return;
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+               if (denormal_operand() < 0)
+                       return;
 
-      goto valid_atan;
-    }
-  else if ( (st0_tag == TAG_Empty) || (st1_tag == TAG_Empty) )
-    {
-      FPU_stack_underflow_pop(1);
-      return;
-    }
-  else if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
-    {
-      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0 )
-         FPU_pop();
-      return;
-    }
-  else if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
-    {
-      u_char sign = getsign(st1_ptr);
-      if ( st0_tag == TW_Infinity )
-       {
-         if ( st1_tag == TW_Infinity )
-           {
-             if ( signpositive(st0_ptr) )
-               {
-                 FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
-               }
-             else
-               {
-                 setpositive(st1_ptr);
-                 tag = FPU_u_add(&CONST_PI4, &CONST_PI2, st1_ptr,
-                                 FULL_PRECISION, SIGN_POS,
-                                 exponent(&CONST_PI4), exponent(&CONST_PI2));
-                 if ( tag >= 0 )
-                   FPU_settagi(1, tag);
-               }
-           }
-         else
-           {
-             if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
+               goto valid_atan;
+       } else if ((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) {
+               FPU_stack_underflow_pop(1);
+               return;
+       } else if ((st0_tag == TW_NaN) || (st1_tag == TW_NaN)) {
+               if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) >= 0)
+                       FPU_pop();
                return;
+       } else if ((st0_tag == TW_Infinity) || (st1_tag == TW_Infinity)) {
+               u_char sign = getsign(st1_ptr);
+               if (st0_tag == TW_Infinity) {
+                       if (st1_tag == TW_Infinity) {
+                               if (signpositive(st0_ptr)) {
+                                       FPU_copy_to_reg1(&CONST_PI4, TAG_Valid);
+                               } else {
+                                       setpositive(st1_ptr);
+                                       tag =
+                                           FPU_u_add(&CONST_PI4, &CONST_PI2,
+                                                     st1_ptr, FULL_PRECISION,
+                                                     SIGN_POS,
+                                                     exponent(&CONST_PI4),
+                                                     exponent(&CONST_PI2));
+                                       if (tag >= 0)
+                                               FPU_settagi(1, tag);
+                               }
+                       } else {
+                               if ((st1_tag == TW_Denormal)
+                                   && (denormal_operand() < 0))
+                                       return;
+
+                               if (signpositive(st0_ptr)) {
+                                       FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
+                                       setsign(st1_ptr, sign); /* An 80486 preserves the sign */
+                                       FPU_pop();
+                                       return;
+                               } else {
+                                       FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+                               }
+                       }
+               } else {
+                       /* st(1) is infinity, st(0) not infinity */
+                       if ((st0_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
 
-             if ( signpositive(st0_ptr) )
-               {
-                 FPU_copy_to_reg1(&CONST_Z, TAG_Zero);
-                 setsign(st1_ptr, sign);   /* An 80486 preserves the sign */
-                 FPU_pop();
-                 return;
+                       FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
                }
-             else
-               {
-                 FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+               setsign(st1_ptr, sign);
+       } else if (st1_tag == TAG_Zero) {
+               /* st(0) must be valid or zero */
+               u_char sign = getsign(st1_ptr);
+
+               if ((st0_tag == TW_Denormal) && (denormal_operand() < 0))
+                       return;
+
+               if (signpositive(st0_ptr)) {
+                       /* An 80486 preserves the sign */
+                       FPU_pop();
+                       return;
                }
-           }
-       }
-      else
-       {
-         /* st(1) is infinity, st(0) not infinity */
-         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
 
-         FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
-       }
-      setsign(st1_ptr, sign);
-    }
-  else if ( st1_tag == TAG_Zero )
-    {
-      /* st(0) must be valid or zero */
-      u_char sign = getsign(st1_ptr);
-
-      if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-       return;
+               FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
+               setsign(st1_ptr, sign);
+       } else if (st0_tag == TAG_Zero) {
+               /* st(1) must be TAG_Valid here */
+               u_char sign = getsign(st1_ptr);
 
-      if ( signpositive(st0_ptr) )
-       {
-         /* An 80486 preserves the sign */
-         FPU_pop();
-         return;
-       }
+               if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
+                       return;
 
-      FPU_copy_to_reg1(&CONST_PI, TAG_Valid);
-      setsign(st1_ptr, sign);
-    }
-  else if ( st0_tag == TAG_Zero )
-    {
-      /* st(1) must be TAG_Valid here */
-      u_char sign = getsign(st1_ptr);
-
-      if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
-       return;
-
-      FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
-      setsign(st1_ptr, sign);
-    }
+               FPU_copy_to_reg1(&CONST_PI2, TAG_Valid);
+               setsign(st1_ptr, sign);
+       }
 #ifdef PARANOID
-  else
-    EXCEPTION(EX_INTERNAL | 0x125);
+       else
+               EXCEPTION(EX_INTERNAL | 0x125);
 #endif /* PARANOID */
 
-  FPU_pop();
-  set_precision_flag_up();  /* We do not really know if up or down */
+       FPU_pop();
+       set_precision_flag_up();        /* We do not really know if up or down */
 }
 
-
 static void fprem(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  do_fprem(st0_ptr, st0_tag, RC_CHOP);
+       do_fprem(st0_ptr, st0_tag, RC_CHOP);
 }
 
-
 static void fprem1(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  do_fprem(st0_ptr, st0_tag, RC_RND);
+       do_fprem(st0_ptr, st0_tag, RC_RND);
 }
 
-
 static void fyl2xp1(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  u_char sign, sign1;
-  FPU_REG *st1_ptr = &st(1), a, b;
-  u_char st1_tag = FPU_gettagi(1);
+       u_char sign, sign1;
+       FPU_REG *st1_ptr = &st(1), a, b;
+       u_char st1_tag = FPU_gettagi(1);
 
-  clear_C1();
-  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
-    {
-    valid_yl2xp1:
+       clear_C1();
+       if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+             valid_yl2xp1:
 
-      sign = getsign(st0_ptr);
-      sign1 = getsign(st1_ptr);
+               sign = getsign(st0_ptr);
+               sign1 = getsign(st1_ptr);
 
-      FPU_to_exp16(st0_ptr, &a);
-      FPU_to_exp16(st1_ptr, &b);
+               FPU_to_exp16(st0_ptr, &a);
+               FPU_to_exp16(st1_ptr, &b);
 
-      if ( poly_l2p1(sign, sign1, &a, &b, st1_ptr) )
-       return;
+               if (poly_l2p1(sign, sign1, &a, &b, st1_ptr))
+                       return;
 
-      FPU_pop();
-      return;
-    }
+               FPU_pop();
+               return;
+       }
 
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-  if ( st1_tag == TAG_Special )
-    st1_tag = FPU_Special(st1_ptr);
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+       if (st1_tag == TAG_Special)
+               st1_tag = FPU_Special(st1_ptr);
 
-  if ( ((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
+       if (((st0_tag == TAG_Valid) && (st1_tag == TW_Denormal))
            || ((st0_tag == TW_Denormal) && (st1_tag == TAG_Valid))
-           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal)) )
-    {
-      if ( denormal_operand() < 0 )
-       return;
-
-      goto valid_yl2xp1;
-    }
-  else if ( (st0_tag == TAG_Empty) | (st1_tag == TAG_Empty) )
-    {
-      FPU_stack_underflow_pop(1);
-      return;
-    }
-  else if ( st0_tag == TAG_Zero )
-    {
-      switch ( st1_tag )
-       {
-       case TW_Denormal:
-         if ( denormal_operand() < 0 )
-           return;
-
-       case TAG_Zero:
-       case TAG_Valid:
-         setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
-         FPU_copy_to_reg1(st0_ptr, st0_tag);
-         break;
-
-       case TW_Infinity:
-         /* Infinity*log(1) */
-         if ( arith_invalid(1) < 0 )
-           return;
-         break;
+           || ((st0_tag == TW_Denormal) && (st1_tag == TW_Denormal))) {
+               if (denormal_operand() < 0)
+                       return;
 
-       case TW_NaN:
-         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
-           return;
-         break;
-
-       default:
+               goto valid_yl2xp1;
+       } else if ((st0_tag == TAG_Empty) | (st1_tag == TAG_Empty)) {
+               FPU_stack_underflow_pop(1);
+               return;
+       } else if (st0_tag == TAG_Zero) {
+               switch (st1_tag) {
+               case TW_Denormal:
+                       if (denormal_operand() < 0)
+                               return;
+
+               case TAG_Zero:
+               case TAG_Valid:
+                       setsign(st0_ptr, getsign(st0_ptr) ^ getsign(st1_ptr));
+                       FPU_copy_to_reg1(st0_ptr, st0_tag);
+                       break;
+
+               case TW_Infinity:
+                       /* Infinity*log(1) */
+                       if (arith_invalid(1) < 0)
+                               return;
+                       break;
+
+               case TW_NaN:
+                       if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+                               return;
+                       break;
+
+               default:
 #ifdef PARANOID
-         EXCEPTION(EX_INTERNAL | 0x116);
-         return;
+                       EXCEPTION(EX_INTERNAL | 0x116);
+                       return;
 #endif /* PARANOID */
-         break;
-       }
-    }
-  else if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
-    {
-      switch ( st1_tag )
-       {
-       case TAG_Zero:
-         if ( signnegative(st0_ptr) )
-           {
-             if ( exponent(st0_ptr) >= 0 )
-               {
-                 /* st(0) holds <= -1.0 */
-#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */
-                 changesign(st1_ptr);
+                       break;
+               }
+       } else if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+               switch (st1_tag) {
+               case TAG_Zero:
+                       if (signnegative(st0_ptr)) {
+                               if (exponent(st0_ptr) >= 0) {
+                                       /* st(0) holds <= -1.0 */
+#ifdef PECULIAR_486            /* Stupid 80486 doesn't worry about log(negative). */
+                                       changesign(st1_ptr);
 #else
-                 if ( arith_invalid(1) < 0 )
-                   return;
+                                       if (arith_invalid(1) < 0)
+                                               return;
 #endif /* PECULIAR_486 */
-               }
-             else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-               return;
-             else
-               changesign(st1_ptr);
-           }
-         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
-         break;
-
-       case TW_Infinity:
-         if ( signnegative(st0_ptr) )
-           {
-             if ( (exponent(st0_ptr) >= 0) &&
-                 !((st0_ptr->sigh == 0x80000000) &&
-                   (st0_ptr->sigl == 0)) )
-               {
-                 /* st(0) holds < -1.0 */
-#ifdef PECULIAR_486   /* Stupid 80486 doesn't worry about log(negative). */
-                 changesign(st1_ptr);
+                               } else if ((st0_tag == TW_Denormal)
+                                          && (denormal_operand() < 0))
+                                       return;
+                               else
+                                       changesign(st1_ptr);
+                       } else if ((st0_tag == TW_Denormal)
+                                  && (denormal_operand() < 0))
+                               return;
+                       break;
+
+               case TW_Infinity:
+                       if (signnegative(st0_ptr)) {
+                               if ((exponent(st0_ptr) >= 0) &&
+                                   !((st0_ptr->sigh == 0x80000000) &&
+                                     (st0_ptr->sigl == 0))) {
+                                       /* st(0) holds < -1.0 */
+#ifdef PECULIAR_486            /* Stupid 80486 doesn't worry about log(negative). */
+                                       changesign(st1_ptr);
 #else
-                 if ( arith_invalid(1) < 0 ) return;
+                                       if (arith_invalid(1) < 0)
+                                               return;
 #endif /* PECULIAR_486 */
+                               } else if ((st0_tag == TW_Denormal)
+                                          && (denormal_operand() < 0))
+                                       return;
+                               else
+                                       changesign(st1_ptr);
+                       } else if ((st0_tag == TW_Denormal)
+                                  && (denormal_operand() < 0))
+                               return;
+                       break;
+
+               case TW_NaN:
+                       if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+                               return;
                }
-             else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-               return;
-             else
-               changesign(st1_ptr);
-           }
-         else if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
-         break;
-
-       case TW_NaN:
-         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
-           return;
-       }
 
-    }
-  else if ( st0_tag == TW_NaN )
-    {
-      if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
-       return;
-    }
-  else if ( st0_tag == TW_Infinity )
-    {
-      if ( st1_tag == TW_NaN )
-       {
-         if ( real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0 )
-           return;
-       }
-      else if ( signnegative(st0_ptr) )
-       {
+       } else if (st0_tag == TW_NaN) {
+               if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+                       return;
+       } else if (st0_tag == TW_Infinity) {
+               if (st1_tag == TW_NaN) {
+                       if (real_2op_NaN(st0_ptr, st0_tag, 1, st0_ptr) < 0)
+                               return;
+               } else if (signnegative(st0_ptr)) {
 #ifndef PECULIAR_486
-         /* This should have higher priority than denormals, but... */
-         if ( arith_invalid(1) < 0 )  /* log(-infinity) */
-           return;
+                       /* This should have higher priority than denormals, but... */
+                       if (arith_invalid(1) < 0)       /* log(-infinity) */
+                               return;
 #endif /* PECULIAR_486 */
-         if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
+                       if ((st1_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
 #ifdef PECULIAR_486
-         /* Denormal operands actually get higher priority */
-         if ( arith_invalid(1) < 0 )  /* log(-infinity) */
-           return;
+                       /* Denormal operands actually get higher priority */
+                       if (arith_invalid(1) < 0)       /* log(-infinity) */
+                               return;
 #endif /* PECULIAR_486 */
-       }
-      else if ( st1_tag == TAG_Zero )
-       {
-         /* log(infinity) */
-         if ( arith_invalid(1) < 0 )
-           return;
-       }
-       
-      /* st(1) must be valid here. */
+               } else if (st1_tag == TAG_Zero) {
+                       /* log(infinity) */
+                       if (arith_invalid(1) < 0)
+                               return;
+               }
 
-      else if ( (st1_tag == TW_Denormal) && (denormal_operand() < 0) )
-       return;
+               /* st(1) must be valid here. */
+
+               else if ((st1_tag == TW_Denormal) && (denormal_operand() < 0))
+                       return;
 
-      /* The Manual says that log(Infinity) is invalid, but a real
-        80486 sensibly says that it is o.k. */
-      else
-       {
-         u_char sign = getsign(st1_ptr);
-         FPU_copy_to_reg1(&CONST_INF, TAG_Special);
-         setsign(st1_ptr, sign);
+               /* The Manual says that log(Infinity) is invalid, but a real
+                  80486 sensibly says that it is o.k. */
+               else {
+                       u_char sign = getsign(st1_ptr);
+                       FPU_copy_to_reg1(&CONST_INF, TAG_Special);
+                       setsign(st1_ptr, sign);
+               }
        }
-    }
 #ifdef PARANOID
-  else
-    {
-      EXCEPTION(EX_INTERNAL | 0x117);
-      return;
-    }
+       else {
+               EXCEPTION(EX_INTERNAL | 0x117);
+               return;
+       }
 #endif /* PARANOID */
 
-  FPU_pop();
-  return;
+       FPU_pop();
+       return;
 
 }
 
-
 static void fscale(FPU_REG *st0_ptr, u_char st0_tag)
 {
-  FPU_REG *st1_ptr = &st(1);
-  u_char st1_tag = FPU_gettagi(1);
-  int old_cw = control_word;
-  u_char sign = getsign(st0_ptr);
-
-  clear_C1();
-  if ( !((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid)) )
-    {
-      long scale;
-      FPU_REG tmp;
-
-      /* Convert register for internal use. */
-      setexponent16(st0_ptr, exponent(st0_ptr));
-
-    valid_scale:
-
-      if ( exponent(st1_ptr) > 30 )
-       {
-         /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
-
-         if ( signpositive(st1_ptr) )
-           {
-             EXCEPTION(EX_Overflow);
-             FPU_copy_to_reg0(&CONST_INF, TAG_Special);
-           }
-         else
-           {
-             EXCEPTION(EX_Underflow);
-             FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
-           }
-         setsign(st0_ptr, sign);
-         return;
-       }
-
-      control_word &= ~CW_RC;
-      control_word |= RC_CHOP;
-      reg_copy(st1_ptr, &tmp);
-      FPU_round_to_int(&tmp, st1_tag);      /* This can never overflow here */
-      control_word = old_cw;
-      scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
-      scale += exponent16(st0_ptr);
-
-      setexponent16(st0_ptr, scale);
-
-      /* Use FPU_round() to properly detect under/overflow etc */
-      FPU_round(st0_ptr, 0, 0, control_word, sign);
-
-      return;
-    }
-
-  if ( st0_tag == TAG_Special )
-    st0_tag = FPU_Special(st0_ptr);
-  if ( st1_tag == TAG_Special )
-    st1_tag = FPU_Special(st1_ptr);
-
-  if ( (st0_tag == TAG_Valid) || (st0_tag == TW_Denormal) )
-    {
-      switch ( st1_tag )
-       {
-       case TAG_Valid:
-         /* st(0) must be a denormal */
-         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
-
-         FPU_to_exp16(st0_ptr, st0_ptr);  /* Will not be left on stack */
-         goto valid_scale;
-
-       case TAG_Zero:
-         if ( st0_tag == TW_Denormal )
-           denormal_operand();
-         return;
-
-       case TW_Denormal:
-         denormal_operand();
-         return;
-
-       case TW_Infinity:
-         if ( (st0_tag == TW_Denormal) && (denormal_operand() < 0) )
-           return;
-
-         if ( signpositive(st1_ptr) )
-           FPU_copy_to_reg0(&CONST_INF, TAG_Special);
-         else
-           FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
-         setsign(st0_ptr, sign);
-         return;
+       FPU_REG *st1_ptr = &st(1);
+       u_char st1_tag = FPU_gettagi(1);
+       int old_cw = control_word;
+       u_char sign = getsign(st0_ptr);
+
+       clear_C1();
+       if (!((st0_tag ^ TAG_Valid) | (st1_tag ^ TAG_Valid))) {
+               long scale;
+               FPU_REG tmp;
+
+               /* Convert register for internal use. */
+               setexponent16(st0_ptr, exponent(st0_ptr));
+
+             valid_scale:
+
+               if (exponent(st1_ptr) > 30) {
+                       /* 2^31 is far too large, would require 2^(2^30) or 2^(-2^30) */
+
+                       if (signpositive(st1_ptr)) {
+                               EXCEPTION(EX_Overflow);
+                               FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+                       } else {
+                               EXCEPTION(EX_Underflow);
+                               FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+                       }
+                       setsign(st0_ptr, sign);
+                       return;
+               }
 
-       case TW_NaN:
-         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
-         return;
-       }
-    }
-  else if ( st0_tag == TAG_Zero )
-    {
-      switch ( st1_tag )
-       {
-       case TAG_Valid:
-       case TAG_Zero:
-         return;
+               control_word &= ~CW_RC;
+               control_word |= RC_CHOP;
+               reg_copy(st1_ptr, &tmp);
+               FPU_round_to_int(&tmp, st1_tag);        /* This can never overflow here */
+               control_word = old_cw;
+               scale = signnegative(st1_ptr) ? -tmp.sigl : tmp.sigl;
+               scale += exponent16(st0_ptr);
 
-       case TW_Denormal:
-         denormal_operand();
-         return;
+               setexponent16(st0_ptr, scale);
 
-       case TW_Infinity:
-         if ( signpositive(st1_ptr) )
-           arith_invalid(0); /* Zero scaled by +Infinity */
-         return;
+               /* Use FPU_round() to properly detect under/overflow etc */
+               FPU_round(st0_ptr, 0, 0, control_word, sign);
 
-       case TW_NaN:
-         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
-         return;
+               return;
        }
-    }
-  else if ( st0_tag == TW_Infinity )
-    {
-      switch ( st1_tag )
-       {
-       case TAG_Valid:
-       case TAG_Zero:
-         return;
-
-       case TW_Denormal:
-         denormal_operand();
-         return;
 
-       case TW_Infinity:
-         if ( signnegative(st1_ptr) )
-           arith_invalid(0); /* Infinity scaled by -Infinity */
-         return;
-
-       case TW_NaN:
-         real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
-         return;
+       if (st0_tag == TAG_Special)
+               st0_tag = FPU_Special(st0_ptr);
+       if (st1_tag == TAG_Special)
+               st1_tag = FPU_Special(st1_ptr);
+
+       if ((st0_tag == TAG_Valid) || (st0_tag == TW_Denormal)) {
+               switch (st1_tag) {
+               case TAG_Valid:
+                       /* st(0) must be a denormal */
+                       if ((st0_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
+
+                       FPU_to_exp16(st0_ptr, st0_ptr); /* Will not be left on stack */
+                       goto valid_scale;
+
+               case TAG_Zero:
+                       if (st0_tag == TW_Denormal)
+                               denormal_operand();
+                       return;
+
+               case TW_Denormal:
+                       denormal_operand();
+                       return;
+
+               case TW_Infinity:
+                       if ((st0_tag == TW_Denormal)
+                           && (denormal_operand() < 0))
+                               return;
+
+                       if (signpositive(st1_ptr))
+                               FPU_copy_to_reg0(&CONST_INF, TAG_Special);
+                       else
+                               FPU_copy_to_reg0(&CONST_Z, TAG_Zero);
+                       setsign(st0_ptr, sign);
+                       return;
+
+               case TW_NaN:
+                       real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+                       return;
+               }
+       } else if (st0_tag == TAG_Zero) {
+               switch (st1_tag) {
+               case TAG_Valid:
+               case TAG_Zero:
+                       return;
+
+               case TW_Denormal:
+                       denormal_operand();
+                       return;
+
+               case TW_Infinity:
+                       if (signpositive(st1_ptr))
+                               arith_invalid(0);       /* Zero scaled by +Infinity */
+                       return;
+
+               case TW_NaN:
+                       real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+                       return;
+               }
+       } else if (st0_tag == TW_Infinity) {
+               switch (st1_tag) {
+               case TAG_Valid:
+               case TAG_Zero:
+                       return;
+
+               case TW_Denormal:
+                       denormal_operand();
+                       return;
+
+               case TW_Infinity:
+                       if (signnegative(st1_ptr))
+                               arith_invalid(0);       /* Infinity scaled by -Infinity */
+                       return;
+
+               case TW_NaN:
+                       real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+                       return;
+               }
+       } else if (st0_tag == TW_NaN) {
+               if (st1_tag != TAG_Empty) {
+                       real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr);
+                       return;
+               }
        }
-    }
-  else if ( st0_tag == TW_NaN )
-    {
-      if ( st1_tag != TAG_Empty )
-       { real_2op_NaN(st1_ptr, st1_tag, 0, st0_ptr); return; }
-    }
-
 #ifdef PARANOID
-  if ( !((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty)) )
-    {
-      EXCEPTION(EX_INTERNAL | 0x115);
-      return;
-    }
+       if (!((st0_tag == TAG_Empty) || (st1_tag == TAG_Empty))) {
+               EXCEPTION(EX_INTERNAL | 0x115);
+               return;
+       }
 #endif
 
-  /* At least one of st(0), st(1) must be empty */
-  FPU_stack_underflow();
+       /* At least one of st(0), st(1) must be empty */
+       FPU_stack_underflow();
 
 }
 
-
 /*---------------------------------------------------------------------------*/
 
 static FUNC_ST0 const trig_table_a[] = {
-  f2xm1, fyl2x, fptan, fpatan,
-  fxtract, fprem1, (FUNC_ST0)fdecstp, (FUNC_ST0)fincstp
+       f2xm1, fyl2x, fptan, fpatan,
+       fxtract, fprem1, (FUNC_ST0) fdecstp, (FUNC_ST0) fincstp
 };
 
 void FPU_triga(void)
 {
-  (trig_table_a[FPU_rm])(&st(0), FPU_gettag0());
+       (trig_table_a[FPU_rm]) (&st(0), FPU_gettag0());
 }
 
-
-static FUNC_ST0 const trig_table_b[] =
-  {
-    fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0)fsin, fcos
-  };
+static FUNC_ST0 const trig_table_b[] = {
+       fprem, fyl2xp1, fsqrt_, fsincos, frndint_, fscale, (FUNC_ST0) fsin, fcos
+};
 
 void FPU_trigb(void)
 {
-  (trig_table_b[FPU_rm])(&st(0), FPU_gettag0());
+       (trig_table_b[FPU_rm]) (&st(0), FPU_gettag0());
 }