patch-2.1.73 linux/arch/i386/math-emu/poly_atan.c

Next file: linux/arch/i386/math-emu/poly_l2.c
Previous file: linux/arch/i386/math-emu/poly_2xm1.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.72/linux/arch/i386/math-emu/poly_atan.c linux/arch/i386/math-emu/poly_atan.c
@@ -3,9 +3,9 @@
  |                                                                           |
  | Compute the arctan of a FPU_REG, using a polynomial approximation.        |
  |                                                                           |
- | Copyright (C) 1992,1993,1994                                              |
- |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ | Copyright (C) 1992,1993,1994,1997                                         |
+ |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
+ |                  E-mail   billm@suburbia.net                              |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
@@ -13,6 +13,7 @@
 #include "exception.h"
 #include "reg_constant.h"
 #include "fpu_emu.h"
+#include "fpu_system.h"
 #include "status_w.h"
 #include "control_w.h"
 #include "poly.h"
@@ -51,31 +52,57 @@
 /*--- poly_atan() -----------------------------------------------------------+
  |                                                                           |
  +---------------------------------------------------------------------------*/
-void	poly_atan(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *result)
+void	poly_atan(FPU_REG *st0_ptr, u_char st0_tag,
+		  FPU_REG *st1_ptr, u_char st1_tag)
 {
-  char		        transformed, inverted,
-                        sign1 = arg1->sign, sign2 = arg2->sign;
-  long int   		exponent, dummy_exp;
-  Xsig                  accumulator, Numer, Denom, accumulatore, argSignif,
-                        argSq, argSqSq;
+  u_char	transformed, inverted,
+                sign1, sign2;
+  int           exponent;
+  long int   	dummy_exp;
+  Xsig          accumulator, Numer, Denom, accumulatore, argSignif,
+                argSq, argSqSq;
+  u_char        tag;
   
+  sign1 = getsign(st0_ptr);
+  sign2 = getsign(st1_ptr);
+  if ( st0_tag == TAG_Valid )
+    {
+      exponent = exponent(st0_ptr);
+    }
+  else
+    {
+      /* This gives non-compatible stack contents... */
+      FPU_to_exp16(st0_ptr, st0_ptr);
+      exponent = exponent16(st0_ptr);
+    }
+  if ( st1_tag == TAG_Valid )
+    {
+      exponent -= exponent(st1_ptr);
+    }
+  else
+    {
+      /* This gives non-compatible stack contents... */
+      FPU_to_exp16(st1_ptr, st1_ptr);
+      exponent -= exponent16(st1_ptr);
+    }
 
-  arg1->sign = arg2->sign = SIGN_POS;
-  if ( (compare(arg2) & ~COMP_Denormal) == COMP_A_lt_B )
+  if ( (exponent < 0) || ((exponent == 0) &&
+			  ((st0_ptr->sigh < st1_ptr->sigh) ||
+			   ((st0_ptr->sigh == st1_ptr->sigh) &&
+			    (st0_ptr->sigl < st1_ptr->sigl))) ) )
     {
       inverted = 1;
-      exponent = arg1->exp - arg2->exp;
       Numer.lsw = Denom.lsw = 0;
-      XSIG_LL(Numer) = significand(arg1);
-      XSIG_LL(Denom) = significand(arg2);
+      XSIG_LL(Numer) = significand(st0_ptr);
+      XSIG_LL(Denom) = significand(st1_ptr);
     }
   else
     {
       inverted = 0;
-      exponent = arg2->exp - arg1->exp;
+      exponent = -exponent;
       Numer.lsw = Denom.lsw = 0;
-      XSIG_LL(Numer) = significand(arg2);
-      XSIG_LL(Denom) = significand(arg1);
+      XSIG_LL(Numer) = significand(st1_ptr);
+      XSIG_LL(Denom) = significand(st0_ptr);
      }
   div_Xsig(&Numer, &Denom, &argSignif);
   exponent += norm_Xsig(&argSignif);
@@ -189,9 +216,14 @@
     }
 
   exponent += round_Xsig(&accumulator);
-  significand(result) = XSIG_LL(accumulator);
-  result->exp = exponent + EXP_BIAS;
-  result->tag = TW_Valid;
-  result->sign = sign2;
+
+  significand(st1_ptr) = XSIG_LL(accumulator);
+  setexponent16(st1_ptr, exponent);
+
+  tag = FPU_round(st1_ptr, 1, 0, FULL_PRECISION, sign2);
+  FPU_settagi(1, tag);
+
+  set_precision_flag_up();  /* We do not really know if up or down,
+			       use this as the default. */
 
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov