OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [tags/] [eco32-0.26/] [fp/] [implementation/] [arith/] [fp.c] - Diff between revs 15 and 270

Only display areas with differences | Details | Blame | View Log

Rev 15 Rev 270
#define sign_bit ((unsigned) 0x80000000)  \
#define sign_bit ((unsigned) 0x80000000)  \
 
 
#define ROUND_OFF 1
#define ROUND_OFF 1
#define ROUND_UP 2
#define ROUND_UP 2
#define ROUND_DOWN 3
#define ROUND_DOWN 3
#define ROUND_NEAR 4 \
#define ROUND_NEAR 4 \
 
 
#define X_BIT (1<<8)
#define X_BIT (1<<8)
#define Z_BIT (1<<9)
#define Z_BIT (1<<9)
#define U_BIT (1<<10)
#define U_BIT (1<<10)
#define O_BIT (1<<11)
#define O_BIT (1<<11)
#define I_BIT (1<<12)
#define I_BIT (1<<12)
#define W_BIT (1<<13)
#define W_BIT (1<<13)
#define V_BIT (1<<14)
#define V_BIT (1<<14)
#define D_BIT (1<<15)
#define D_BIT (1<<15)
#define E_BIT (1<<18)  \
#define E_BIT (1<<18)  \
 
 
#define zero_exponent (-1000)  \
#define zero_exponent (-1000)  \
 
 
#define bignum_prec 157 \
#define bignum_prec 157 \
 
 
#define magic_offset 2112
#define magic_offset 2112
#define origin 37 \
#define origin 37 \
 
 
#define buf0 (buf+8)
#define buf0 (buf+8)
#define buf_max (buf+777)  \
#define buf_max (buf+777)  \
 
 
/*1:*/
/*1:*/
#line 32 "./mmix-arith.w"
#line 32 "./mmix-arith.w"
 
 
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
/*2:*/
/*2:*/
#line 49 "./mmix-arith.w"
#line 49 "./mmix-arith.w"
 
 
#ifdef __STDC__
#ifdef __STDC__
#define ARGS(list) list
#define ARGS(list) list
#else
#else
#define ARGS(list) ()
#define ARGS(list) ()
#endif
#endif
 
 
/*:2*/
/*:2*/
#line 36 "./mmix-arith.w"
#line 36 "./mmix-arith.w"
 
 
typedef enum
typedef enum
{ false, true } bool;
{ false, true } bool;
/*3:*/
/*3:*/
#line 60 "./mmix-arith.w"
#line 60 "./mmix-arith.w"
 
 
typedef unsigned int tetra;
typedef unsigned int tetra;
 
 
typedef struct
typedef struct
{
{
  tetra h, l;
  tetra h, l;
} octa;
} octa;
 
 
/*:3*/
/*:3*/
#line 38 "./mmix-arith.w"
#line 38 "./mmix-arith.w"
 
 
/*36:*/
/*36:*/
#line 605 "./mmix-arith.w"
#line 605 "./mmix-arith.w"
 
 
typedef enum
typedef enum
{ zro, num, inf, nan } ftype;
{ zro, num, inf, nan } ftype;
 
 
       /*:36*//*59: */
       /*:36*//*59: */
#line 1110 "./mmix-arith.w"
#line 1110 "./mmix-arith.w"
 
 
typedef struct
typedef struct
{
{
  int a;
  int a;
  int b;
  int b;
  tetra dat[bignum_prec];
  tetra dat[bignum_prec];
} bignum;
} bignum;
 
 
/*:59*/
/*:59*/
#line 39 "./mmix-arith.w"
#line 39 "./mmix-arith.w"
 
 
/*4:*/
/*4:*/
#line 67 "./mmix-arith.w"
#line 67 "./mmix-arith.w"
 
 
octa zero_octa;
octa zero_octa;
octa neg_one = { -1, -1 };
octa neg_one = { -1, -1 };
octa inf_octa = { 0x7ff00000, 0 };
octa inf_octa = { 0x7ff00000, 0 };
octa standard_NaN = { 0x7ff80000, 0 };
octa standard_NaN = { 0x7ff80000, 0 };
octa aux;
octa aux;
bool overflow;
bool overflow;
 
 
      /*:4*//*9: */
      /*:4*//*9: */
#line 174 "./mmix-arith.w"
#line 174 "./mmix-arith.w"
 
 
extern octa aux;
extern octa aux;
extern bool overflow;
extern bool overflow;
 
 
      /*:9*//*30: */
      /*:9*//*30: */
#line 464 "./mmix-arith.w"
#line 464 "./mmix-arith.w"
 
 
int cur_round;
int cur_round;
 
 
       /*:30*//*32: */
       /*:30*//*32: */
#line 528 "./mmix-arith.w"
#line 528 "./mmix-arith.w"
 
 
int exceptions;
int exceptions;
 
 
       /*:32*//*69: */
       /*:32*//*69: */
#line 1359 "./mmix-arith.w"
#line 1359 "./mmix-arith.w"
 
 
octa val;
octa val;
char *next_char;
char *next_char;
 
 
       /*:69*//*75: */
       /*:69*//*75: */
#line 1432 "./mmix-arith.w"
#line 1432 "./mmix-arith.w"
 
 
static char buf[785] = "00000000";
static char buf[785] = "00000000";
 
 
/*:75*/
/*:75*/
#line 40 "./mmix-arith.w"
#line 40 "./mmix-arith.w"
 
 
/*5:*/
/*5:*/
#line 78 "./mmix-arith.w"
#line 78 "./mmix-arith.w"
 
 
octa oplus ARGS ((octa, octa));
octa oplus ARGS ((octa, octa));
octa
octa
oplus (y, z)
oplus (y, z)
     octa y, z;
     octa y, z;
{
{
  octa x;
  octa x;
  x.h = y.h + z.h;
  x.h = y.h + z.h;
  x.l = y.l + z.l;
  x.l = y.l + z.l;
  if (x.l < y.l)
  if (x.l < y.l)
    x.h++;
    x.h++;
  return x;
  return x;
}
}
 
 
octa ominus ARGS ((octa, octa));
octa ominus ARGS ((octa, octa));
octa
octa
ominus (y, z)
ominus (y, z)
     octa y, z;
     octa y, z;
{
{
  octa x;
  octa x;
  x.h = y.h - z.h;
  x.h = y.h - z.h;
  x.l = y.l - z.l;
  x.l = y.l - z.l;
  if (x.l > y.l)
  if (x.l > y.l)
    x.h--;
    x.h--;
  return x;
  return x;
}
}
 
 
      /*:5*//*6: */
      /*:5*//*6: */
#line 102 "./mmix-arith.w"
#line 102 "./mmix-arith.w"
 
 
octa incr ARGS ((octa, int));
octa incr ARGS ((octa, int));
octa
octa
incr (y, delta)
incr (y, delta)
     octa y;
     octa y;
     int delta;
     int delta;
{
{
  octa x;
  octa x;
  x.h = y.h;
  x.h = y.h;
  x.l = y.l + delta;
  x.l = y.l + delta;
  if (delta >= 0)
  if (delta >= 0)
    {
    {
      if (x.l < y.l)
      if (x.l < y.l)
        x.h++;
        x.h++;
    }
    }
  else if (x.l > y.l)
  else if (x.l > y.l)
    x.h--;
    x.h--;
  return x;
  return x;
}
}
 
 
      /*:6*//*7: */
      /*:6*//*7: */
#line 117 "./mmix-arith.w"
#line 117 "./mmix-arith.w"
 
 
octa shift_left ARGS ((octa, int));
octa shift_left ARGS ((octa, int));
octa
octa
shift_left (y, s)
shift_left (y, s)
     octa y;
     octa y;
     int s;
     int s;
{
{
  while (s >= 32)
  while (s >= 32)
    y.h = y.l, y.l = 0, s -= 32;
    y.h = y.l, y.l = 0, s -= 32;
  if (s)
  if (s)
    {
    {
      register tetra yhl = y.h << s, ylh = y.l >> (32 - s);
      register tetra yhl = y.h << s, ylh = y.l >> (32 - s);
      y.h = yhl + ylh;
      y.h = yhl + ylh;
      y.l <<= s;
      y.l <<= s;
    }
    }
  return y;
  return y;
}
}
 
 
octa shift_right ARGS ((octa, int, int));
octa shift_right ARGS ((octa, int, int));
octa
octa
shift_right (y, s, u)
shift_right (y, s, u)
     octa y;
     octa y;
     int s, u;
     int s, u;
{
{
  while (s >= 32)
  while (s >= 32)
    y.l = y.h, y.h = (u ? 0 : -(y.h >> 31)), s -= 32;
    y.l = y.h, y.h = (u ? 0 : -(y.h >> 31)), s -= 32;
  if (s)
  if (s)
    {
    {
      register tetra yhl = y.h << (32 - s), ylh = y.l >> s;
      register tetra yhl = y.h << (32 - s), ylh = y.l >> s;
      y.h = (u ? 0 : (-(y.h >> 31)) << (32 - s)) + (y.h >> s);
      y.h = (u ? 0 : (-(y.h >> 31)) << (32 - s)) + (y.h >> s);
      y.l = yhl + ylh;
      y.l = yhl + ylh;
    }
    }
  return y;
  return y;
}
}
 
 
      /*:7*//*8: */
      /*:7*//*8: */
#line 150 "./mmix-arith.w"
#line 150 "./mmix-arith.w"
 
 
octa omult ARGS ((octa, octa));
octa omult ARGS ((octa, octa));
octa
octa
omult (y, z)
omult (y, z)
     octa y, z;
     octa y, z;
{
{
  register int i, j, k;
  register int i, j, k;
  tetra u[4], v[4], w[8];
  tetra u[4], v[4], w[8];
  register tetra t;
  register tetra t;
  octa acc;
  octa acc;
/*10:*/
/*10:*/
#line 178 "./mmix-arith.w"
#line 178 "./mmix-arith.w"
 
 
  u[3] = y.h >> 16, u[2] = y.h & 0xffff, u[1] = y.l >> 16, u[0] =
  u[3] = y.h >> 16, u[2] = y.h & 0xffff, u[1] = y.l >> 16, u[0] =
    y.l & 0xffff;
    y.l & 0xffff;
  v[3] = z.h >> 16, v[2] = z.h & 0xffff, v[1] = z.l >> 16, v[0] =
  v[3] = z.h >> 16, v[2] = z.h & 0xffff, v[1] = z.l >> 16, v[0] =
    z.l & 0xffff;
    z.l & 0xffff;
 
 
/*:10*/
/*:10*/
#line 159 "./mmix-arith.w"
#line 159 "./mmix-arith.w"
  ;
  ;
  for (j = 0; j < 4; j++)
  for (j = 0; j < 4; j++)
    w[j] = 0;
    w[j] = 0;
  for (j = 0; j < 4; j++)
  for (j = 0; j < 4; j++)
    if (!v[j])
    if (!v[j])
      w[j + 4] = 0;
      w[j + 4] = 0;
    else
    else
      {
      {
        for (i = k = 0; i < 4; i++)
        for (i = k = 0; i < 4; i++)
          {
          {
            t = u[i] * v[j] + w[i + j] + k;
            t = u[i] * v[j] + w[i + j] + k;
            w[i + j] = t & 0xffff, k = t >> 16;
            w[i + j] = t & 0xffff, k = t >> 16;
          }
          }
        w[j + 4] = k;
        w[j + 4] = k;
      }
      }
/*11:*/
/*11:*/
#line 182 "./mmix-arith.w"
#line 182 "./mmix-arith.w"
 
 
  aux.h = (w[7] << 16) + w[6], aux.l = (w[5] << 16) + w[4];
  aux.h = (w[7] << 16) + w[6], aux.l = (w[5] << 16) + w[4];
  acc.h = (w[3] << 16) + w[2], acc.l = (w[1] << 16) + w[0];
  acc.h = (w[3] << 16) + w[2], acc.l = (w[1] << 16) + w[0];
 
 
/*:11*/
/*:11*/
#line 170 "./mmix-arith.w"
#line 170 "./mmix-arith.w"
  ;
  ;
  return acc;
  return acc;
}
}
 
 
      /*:8*//*12: */
      /*:8*//*12: */
#line 191 "./mmix-arith.w"
#line 191 "./mmix-arith.w"
 
 
octa signed_omult ARGS ((octa, octa));
octa signed_omult ARGS ((octa, octa));
octa
octa
signed_omult (y, z)
signed_omult (y, z)
     octa y, z;
     octa y, z;
{
{
  octa acc;
  octa acc;
  acc = omult (y, z);
  acc = omult (y, z);
  if (y.h & sign_bit)
  if (y.h & sign_bit)
    aux = ominus (aux, z);
    aux = ominus (aux, z);
  if (z.h & sign_bit)
  if (z.h & sign_bit)
    aux = ominus (aux, y);
    aux = ominus (aux, y);
  overflow = (aux.h != aux.l || (aux.h ^ (aux.h >> 1) ^ (acc.h & sign_bit)));
  overflow = (aux.h != aux.l || (aux.h ^ (aux.h >> 1) ^ (acc.h & sign_bit)));
  return acc;
  return acc;
}
}
 
 
       /*:12*//*13: */
       /*:12*//*13: */
#line 215 "./mmix-arith.w"
#line 215 "./mmix-arith.w"
 
 
octa odiv ARGS ((octa, octa, octa));
octa odiv ARGS ((octa, octa, octa));
octa
octa
odiv (x, y, z)
odiv (x, y, z)
     octa x, y, z;
     octa x, y, z;
{
{
  register int i, j, k, n, d;
  register int i, j, k, n, d;
  tetra u[8], v[4], q[4], mask, qhat, rhat, vh, vmh;
  tetra u[8], v[4], q[4], mask, qhat, rhat, vh, vmh;
  register tetra t;
  register tetra t;
  octa acc;
  octa acc;
/*14:*/
/*14:*/
#line 234 "./mmix-arith.w"
#line 234 "./mmix-arith.w"
 
 
  if (x.h > z.h || (x.h == z.h && x.l >= z.l))
  if (x.h > z.h || (x.h == z.h && x.l >= z.l))
    {
    {
      aux = y;
      aux = y;
      return x;
      return x;
    }
    }
 
 
/*:14*/
/*:14*/
#line 224 "./mmix-arith.w"
#line 224 "./mmix-arith.w"
  ;
  ;
/*15:*/
/*15:*/
#line 239 "./mmix-arith.w"
#line 239 "./mmix-arith.w"
 
 
  u[7] = x.h >> 16, u[6] = x.h & 0xffff, u[5] = x.l >> 16, u[4] =
  u[7] = x.h >> 16, u[6] = x.h & 0xffff, u[5] = x.l >> 16, u[4] =
    x.l & 0xffff;
    x.l & 0xffff;
  u[3] = y.h >> 16, u[2] = y.h & 0xffff, u[1] = y.l >> 16, u[0] =
  u[3] = y.h >> 16, u[2] = y.h & 0xffff, u[1] = y.l >> 16, u[0] =
    y.l & 0xffff;
    y.l & 0xffff;
  v[3] = z.h >> 16, v[2] = z.h & 0xffff, v[1] = z.l >> 16, v[0] =
  v[3] = z.h >> 16, v[2] = z.h & 0xffff, v[1] = z.l >> 16, v[0] =
    z.l & 0xffff;
    z.l & 0xffff;
 
 
/*:15*/
/*:15*/
#line 225 "./mmix-arith.w"
#line 225 "./mmix-arith.w"
  ;
  ;
/*16:*/
/*16:*/
#line 244 "./mmix-arith.w"
#line 244 "./mmix-arith.w"
 
 
  for (n = 4; v[n - 1] == 0; n--);
  for (n = 4; v[n - 1] == 0; n--);
 
 
/*:16*/
/*:16*/
#line 226 "./mmix-arith.w"
#line 226 "./mmix-arith.w"
  ;
  ;
/*17:*/
/*17:*/
#line 250 "./mmix-arith.w"
#line 250 "./mmix-arith.w"
 
 
  vh = v[n - 1];
  vh = v[n - 1];
  for (d = 0; vh < 0x8000; d++, vh <<= 1);
  for (d = 0; vh < 0x8000; d++, vh <<= 1);
  for (j = k = 0; j < n + 4; j++)
  for (j = k = 0; j < n + 4; j++)
    {
    {
      t = (u[j] << d) + k;
      t = (u[j] << d) + k;
      u[j] = t & 0xffff, k = t >> 16;
      u[j] = t & 0xffff, k = t >> 16;
    }
    }
  for (j = k = 0; j < n; j++)
  for (j = k = 0; j < n; j++)
    {
    {
      t = (v[j] << d) + k;
      t = (v[j] << d) + k;
      v[j] = t & 0xffff, k = t >> 16;
      v[j] = t & 0xffff, k = t >> 16;
    }
    }
  vh = v[n - 1];
  vh = v[n - 1];
  vmh = (n > 1 ? v[n - 2] : 0);
  vmh = (n > 1 ? v[n - 2] : 0);
 
 
/*:17*/
/*:17*/
#line 227 "./mmix-arith.w"
#line 227 "./mmix-arith.w"
  ;
  ;
  for (j = 3; j >= 0; j--)       /*20: */
  for (j = 3; j >= 0; j--)       /*20: */
#line 276 "./mmix-arith.w"
#line 276 "./mmix-arith.w"
 
 
    {
    {
/*21:*/
/*21:*/
#line 284 "./mmix-arith.w"
#line 284 "./mmix-arith.w"
 
 
      t = (u[j + n] << 16) + u[j + n - 1];
      t = (u[j + n] << 16) + u[j + n - 1];
      qhat = t / vh, rhat = t - vh * qhat;
      qhat = t / vh, rhat = t - vh * qhat;
      if (n > 1)
      if (n > 1)
        while (qhat == 0x10000 || qhat * vmh > (rhat << 16) + u[j + n - 2])
        while (qhat == 0x10000 || qhat * vmh > (rhat << 16) + u[j + n - 2])
          {
          {
            qhat--, rhat += vh;
            qhat--, rhat += vh;
            if (rhat >= 0x10000)
            if (rhat >= 0x10000)
              break;
              break;
          }
          }
 
 
/*:21*/
/*:21*/
#line 278 "./mmix-arith.w"
#line 278 "./mmix-arith.w"
      ;
      ;
/*22:*/
/*22:*/
#line 296 "./mmix-arith.w"
#line 296 "./mmix-arith.w"
 
 
      for (i = k = 0; i < n; i++)
      for (i = k = 0; i < n; i++)
        {
        {
          t = u[i + j] + 0xffff0000 - k - qhat * v[i];
          t = u[i + j] + 0xffff0000 - k - qhat * v[i];
          u[i + j] = t & 0xffff, k = 0xffff - (t >> 16);
          u[i + j] = t & 0xffff, k = 0xffff - (t >> 16);
        }
        }
 
 
/*:22*/
/*:22*/
#line 279 "./mmix-arith.w"
#line 279 "./mmix-arith.w"
      ;
      ;
/*23:*/
/*23:*/
#line 305 "./mmix-arith.w"
#line 305 "./mmix-arith.w"
 
 
      if (u[j + n] != k)
      if (u[j + n] != k)
        {
        {
          qhat--;
          qhat--;
          for (i = k = 0; i < n; i++)
          for (i = k = 0; i < n; i++)
            {
            {
              t = u[i + j] + v[i] + k;
              t = u[i + j] + v[i] + k;
              u[i + j] = t & 0xffff, k = t >> 16;
              u[i + j] = t & 0xffff, k = t >> 16;
            }
            }
        }
        }
 
 
/*:23*/
/*:23*/
#line 280 "./mmix-arith.w"
#line 280 "./mmix-arith.w"
      ;
      ;
      q[j] = qhat;
      q[j] = qhat;
    }
    }
 
 
/*:20*/
/*:20*/
#line 228 "./mmix-arith.w"
#line 228 "./mmix-arith.w"
  ;
  ;
/*18:*/
/*18:*/
#line 264 "./mmix-arith.w"
#line 264 "./mmix-arith.w"
 
 
  mask = (1 << d) - 1;
  mask = (1 << d) - 1;
  for (j = 3; j >= n; j--)
  for (j = 3; j >= n; j--)
    u[j] = 0;
    u[j] = 0;
  for (k = 0; j >= 0; j--)
  for (k = 0; j >= 0; j--)
    {
    {
      t = (k << 16) + u[j];
      t = (k << 16) + u[j];
      u[j] = t >> d, k = t & mask;
      u[j] = t >> d, k = t & mask;
    }
    }
 
 
/*:18*/
/*:18*/
#line 229 "./mmix-arith.w"
#line 229 "./mmix-arith.w"
  ;
  ;
/*19:*/
/*19:*/
#line 272 "./mmix-arith.w"
#line 272 "./mmix-arith.w"
 
 
  acc.h = (q[3] << 16) + q[2], acc.l = (q[1] << 16) + q[0];
  acc.h = (q[3] << 16) + q[2], acc.l = (q[1] << 16) + q[0];
  aux.h = (u[3] << 16) + u[2], aux.l = (u[1] << 16) + u[0];
  aux.h = (u[3] << 16) + u[2], aux.l = (u[1] << 16) + u[0];
 
 
/*:19*/
/*:19*/
#line 230 "./mmix-arith.w"
#line 230 "./mmix-arith.w"
  ;
  ;
  return acc;
  return acc;
}
}
 
 
       /*:13*//*24: */
       /*:13*//*24: */
#line 317 "./mmix-arith.w"
#line 317 "./mmix-arith.w"
 
 
octa signed_odiv ARGS ((octa, octa));
octa signed_odiv ARGS ((octa, octa));
octa
octa
signed_odiv (y, z)
signed_odiv (y, z)
     octa y, z;
     octa y, z;
{
{
  octa yy, zz, q;
  octa yy, zz, q;
  register int sy, sz;
  register int sy, sz;
  if (y.h & sign_bit)
  if (y.h & sign_bit)
    sy = 2, yy = ominus (zero_octa, y);
    sy = 2, yy = ominus (zero_octa, y);
  else
  else
    sy = 0, yy = y;
    sy = 0, yy = y;
  if (z.h & sign_bit)
  if (z.h & sign_bit)
    sz = 1, zz = ominus (zero_octa, z);
    sz = 1, zz = ominus (zero_octa, z);
  else
  else
    sz = 0, zz = z;
    sz = 0, zz = z;
  q = odiv (zero_octa, yy, zz);
  q = odiv (zero_octa, yy, zz);
  overflow = false;
  overflow = false;
  switch (sy + sz)
  switch (sy + sz)
    {
    {
    case 2 + 1:
    case 2 + 1:
      aux = ominus (zero_octa, aux);
      aux = ominus (zero_octa, aux);
      if (q.h == sign_bit)
      if (q.h == sign_bit)
        overflow = true;
        overflow = true;
    case 0 + 0:
    case 0 + 0:
      return q;
      return q;
    case 2 + 0:
    case 2 + 0:
      if (aux.h || aux.l)
      if (aux.h || aux.l)
        aux = ominus (zz, aux);
        aux = ominus (zz, aux);
      goto negate_q;
      goto negate_q;
    case 0 + 1:
    case 0 + 1:
      if (aux.h || aux.l)
      if (aux.h || aux.l)
        aux = ominus (aux, zz);
        aux = ominus (aux, zz);
    negate_q:if (aux.h || aux.l)
    negate_q:if (aux.h || aux.l)
        return ominus (neg_one, q);
        return ominus (neg_one, q);
      else
      else
        return ominus (zero_octa, q);
        return ominus (zero_octa, q);
    }
    }
}
}
 
 
       /*:24*//*25: */
       /*:24*//*25: */
#line 346 "./mmix-arith.w"
#line 346 "./mmix-arith.w"
 
 
octa oand ARGS ((octa, octa));
octa oand ARGS ((octa, octa));
octa
octa
oand (y, z)
oand (y, z)
     octa y, z;
     octa y, z;
{
{
  octa x;
  octa x;
  x.h = y.h & z.h;
  x.h = y.h & z.h;
  x.l = y.l & z.l;
  x.l = y.l & z.l;
  return x;
  return x;
}
}
 
 
octa oandn ARGS ((octa, octa));
octa oandn ARGS ((octa, octa));
octa
octa
oandn (y, z)
oandn (y, z)
     octa y, z;
     octa y, z;
{
{
  octa x;
  octa x;
  x.h = y.h & ~z.h;
  x.h = y.h & ~z.h;
  x.l = y.l & ~z.l;
  x.l = y.l & ~z.l;
  return x;
  return x;
}
}
 
 
octa oxor ARGS ((octa, octa));
octa oxor ARGS ((octa, octa));
octa
octa
oxor (y, z)
oxor (y, z)
     octa y, z;
     octa y, z;
{
{
  octa x;
  octa x;
  x.h = y.h ^ z.h;
  x.h = y.h ^ z.h;
  x.l = y.l ^ z.l;
  x.l = y.l ^ z.l;
  return x;
  return x;
}
}
 
 
       /*:25*//*26: */
       /*:25*//*26: */
#line 387 "./mmix-arith.w"
#line 387 "./mmix-arith.w"
 
 
int count_bits ARGS ((tetra));
int count_bits ARGS ((tetra));
int
int
count_bits (x)
count_bits (x)
     tetra x;
     tetra x;
{
{
  register int xx = x;
  register int xx = x;
  xx = xx - ((xx >> 1) & 0x55555555);
  xx = xx - ((xx >> 1) & 0x55555555);
  xx = (xx & 0x33333333) + ((xx >> 2) & 0x33333333);
  xx = (xx & 0x33333333) + ((xx >> 2) & 0x33333333);
  xx = (xx + (xx >> 4)) & 0x0f0f0f0f;
  xx = (xx + (xx >> 4)) & 0x0f0f0f0f;
  xx = xx + (xx >> 8);
  xx = xx + (xx >> 8);
  return (xx + (xx >> 16)) & 0xff;
  return (xx + (xx >> 16)) & 0xff;
}
}
 
 
       /*:26*//*27: */
       /*:26*//*27: */
#line 403 "./mmix-arith.w"
#line 403 "./mmix-arith.w"
 
 
tetra byte_diff ARGS ((tetra, tetra));
tetra byte_diff ARGS ((tetra, tetra));
tetra
tetra
byte_diff (y, z)
byte_diff (y, z)
     tetra y, z;
     tetra y, z;
{
{
  register tetra d = (y & 0x00ff00ff) + 0x01000100 - (z & 0x00ff00ff);
  register tetra d = (y & 0x00ff00ff) + 0x01000100 - (z & 0x00ff00ff);
  register tetra m = d & 0x01000100;
  register tetra m = d & 0x01000100;
  register tetra x = d & (m - (m >> 8));
  register tetra x = d & (m - (m >> 8));
  d = ((y >> 8) & 0x00ff00ff) + 0x01000100 - ((z >> 8) & 0x00ff00ff);
  d = ((y >> 8) & 0x00ff00ff) + 0x01000100 - ((z >> 8) & 0x00ff00ff);
  m = d & 0x01000100;
  m = d & 0x01000100;
  return x + ((d & (m - (m >> 8))) << 8);
  return x + ((d & (m - (m >> 8))) << 8);
}
}
 
 
       /*:27*//*28: */
       /*:27*//*28: */
#line 421 "./mmix-arith.w"
#line 421 "./mmix-arith.w"
 
 
tetra wyde_diff ARGS ((tetra, tetra));
tetra wyde_diff ARGS ((tetra, tetra));
tetra
tetra
wyde_diff (y, z)
wyde_diff (y, z)
     tetra y, z;
     tetra y, z;
{
{
  register tetra a = ((y >> 16) - (z >> 16)) & 0x10000;
  register tetra a = ((y >> 16) - (z >> 16)) & 0x10000;
  register tetra b = ((y & 0xffff) - (z & 0xffff)) & 0x10000;
  register tetra b = ((y & 0xffff) - (z & 0xffff)) & 0x10000;
  return y - (z ^ ((y ^ z) & (b - a - (b >> 16))));
  return y - (z ^ ((y ^ z) & (b - a - (b >> 16))));
}
}
 
 
       /*:28*//*29: */
       /*:28*//*29: */
#line 434 "./mmix-arith.w"
#line 434 "./mmix-arith.w"
 
 
octa bool_mult ARGS ((octa, octa, bool));
octa bool_mult ARGS ((octa, octa, bool));
octa
octa
bool_mult (y, z, xor)
bool_mult (y, z, xor)
     octa y, z;
     octa y, z;
     bool xor;
     bool xor;
{
{
  octa o, x;
  octa o, x;
  register tetra a, b, c;
  register tetra a, b, c;
  register int k;
  register int k;
  for (k = 0, o = y, x = zero_octa; o.h || o.l;
  for (k = 0, o = y, x = zero_octa; o.h || o.l;
       k++, o = shift_right (o, 8, 1))
       k++, o = shift_right (o, 8, 1))
    if (o.l & 0xff)
    if (o.l & 0xff)
      {
      {
        a = ((z.h >> k) & 0x01010101) * 0xff;
        a = ((z.h >> k) & 0x01010101) * 0xff;
        b = ((z.l >> k) & 0x01010101) * 0xff;
        b = ((z.l >> k) & 0x01010101) * 0xff;
        c = (o.l & 0xff) * 0x01010101;
        c = (o.l & 0xff) * 0x01010101;
        if (xor)
        if (xor)
          x.h ^= a & c, x.l ^= b & c;
          x.h ^= a & c, x.l ^= b & c;
        else
        else
          x.h |= a & c, x.l |= b & c;
          x.h |= a & c, x.l |= b & c;
      }
      }
  return x;
  return x;
}
}
 
 
       /*:29*//*31: */
       /*:29*//*31: */
#line 503 "./mmix-arith.w"
#line 503 "./mmix-arith.w"
 
 
octa fpack ARGS ((octa, int, char, int));
octa fpack ARGS ((octa, int, char, int));
octa
octa
fpack (f, e, s, r)
fpack (f, e, s, r)
     octa f;
     octa f;
     int e;
     int e;
     char s;
     char s;
     int r;
     int r;
{
{
  octa o;
  octa o;
  if (e > 0x7fd)
  if (e > 0x7fd)
    e = 0x7ff, o = zero_octa;
    e = 0x7ff, o = zero_octa;
  else
  else
    {
    {
      if (e < 0)
      if (e < 0)
        {
        {
          if (e < -54)
          if (e < -54)
            o.h = 0, o.l = 1;
            o.h = 0, o.l = 1;
          else
          else
            {
            {
              octa oo;
              octa oo;
              o = shift_right (f, -e, 1);
              o = shift_right (f, -e, 1);
              oo = shift_left (o, -e);
              oo = shift_left (o, -e);
              if (oo.l != f.l || oo.h != f.h)
              if (oo.l != f.l || oo.h != f.h)
                o.l |= 1;
                o.l |= 1;
 
 
            }
            }
          e = 0;
          e = 0;
        }
        }
      else
      else
        o = f;
        o = f;
    }
    }
/*33:*/
/*33:*/
#line 533 "./mmix-arith.w"
#line 533 "./mmix-arith.w"
 
 
  if (o.l & 3)
  if (o.l & 3)
    exceptions |= X_BIT;
    exceptions |= X_BIT;
  switch (r)
  switch (r)
    {
    {
    case ROUND_DOWN:
    case ROUND_DOWN:
      if (s == '-')
      if (s == '-')
        o = incr (o, 3);
        o = incr (o, 3);
      break;
      break;
    case ROUND_UP:
    case ROUND_UP:
      if (s != '-')
      if (s != '-')
        o = incr (o, 3);
        o = incr (o, 3);
    case ROUND_OFF:
    case ROUND_OFF:
      break;
      break;
    case ROUND_NEAR:
    case ROUND_NEAR:
      o = incr (o, o.l & 4 ? 2 : 1);
      o = incr (o, o.l & 4 ? 2 : 1);
      break;
      break;
    }
    }
  o = shift_right (o, 2, 1);
  o = shift_right (o, 2, 1);
  o.h += e << 20;
  o.h += e << 20;
  if (o.h >= 0x7ff00000)
  if (o.h >= 0x7ff00000)
    exceptions |= O_BIT + X_BIT;
    exceptions |= O_BIT + X_BIT;
  else if (o.h < 0x100000)
  else if (o.h < 0x100000)
    exceptions |= U_BIT;
    exceptions |= U_BIT;
  if (s == '-')
  if (s == '-')
    o.h |= sign_bit;
    o.h |= sign_bit;
  return o;
  return o;
 
 
/*:33*/
/*:33*/
#line 525 "./mmix-arith.w"
#line 525 "./mmix-arith.w"
  ;
  ;
}
}
 
 
       /*:31*//*34: */
       /*:31*//*34: */
#line 551 "./mmix-arith.w"
#line 551 "./mmix-arith.w"
 
 
tetra sfpack ARGS ((octa, int, char, int));
tetra sfpack ARGS ((octa, int, char, int));
tetra
tetra
sfpack (f, e, s, r)
sfpack (f, e, s, r)
     octa f;
     octa f;
     int e;
     int e;
     char s;
     char s;
     int r;
     int r;
{
{
  register tetra o;
  register tetra o;
  if (e > 0x47d)
  if (e > 0x47d)
    e = 0x47f, o = 0;
    e = 0x47f, o = 0;
  else
  else
    {
    {
      o = shift_left (f, 3).h;
      o = shift_left (f, 3).h;
      if (f.l & 0x1fffffff)
      if (f.l & 0x1fffffff)
        o |= 1;
        o |= 1;
      if (e < 0x380)
      if (e < 0x380)
        {
        {
          if (e < 0x380 - 25)
          if (e < 0x380 - 25)
            o = 1;
            o = 1;
          else
          else
            {
            {
              register tetra o0, oo;
              register tetra o0, oo;
              o0 = o;
              o0 = o;
              o = o >> (0x380 - e);
              o = o >> (0x380 - e);
              oo = o << (0x380 - e);
              oo = o << (0x380 - e);
              if (oo != o0)
              if (oo != o0)
                o |= 1;
                o |= 1;
 
 
            }
            }
          e = 0x380;
          e = 0x380;
        }
        }
    }
    }
/*35:*/
/*35:*/
#line 579 "./mmix-arith.w"
#line 579 "./mmix-arith.w"
 
 
  if (o & 3)
  if (o & 3)
    exceptions |= X_BIT;
    exceptions |= X_BIT;
  switch (r)
  switch (r)
    {
    {
    case ROUND_DOWN:
    case ROUND_DOWN:
      if (s == '-')
      if (s == '-')
        o += 3;
        o += 3;
      break;
      break;
    case ROUND_UP:
    case ROUND_UP:
      if (s != '-')
      if (s != '-')
        o += 3;
        o += 3;
    case ROUND_OFF:
    case ROUND_OFF:
      break;
      break;
    case ROUND_NEAR:
    case ROUND_NEAR:
      o += (o & 4 ? 2 : 1);
      o += (o & 4 ? 2 : 1);
      break;
      break;
    }
    }
  o = o >> 2;
  o = o >> 2;
  o += (e - 0x380) << 23;
  o += (e - 0x380) << 23;
  if (o >= 0x7f800000)
  if (o >= 0x7f800000)
    exceptions |= O_BIT + X_BIT;
    exceptions |= O_BIT + X_BIT;
  else if (o < 0x100000)
  else if (o < 0x100000)
    exceptions |= U_BIT;
    exceptions |= U_BIT;
  if (s == '-')
  if (s == '-')
    o |= sign_bit;
    o |= sign_bit;
  return o;
  return o;
 
 
/*:35*/
/*:35*/
#line 576 "./mmix-arith.w"
#line 576 "./mmix-arith.w"
  ;
  ;
}
}
 
 
       /*:34*//*37: */
       /*:34*//*37: */
#line 608 "./mmix-arith.w"
#line 608 "./mmix-arith.w"
 
 
ftype funpack ARGS ((octa, octa *, int *, char *));
ftype funpack ARGS ((octa, octa *, int *, char *));
ftype
ftype
funpack (x, f, e, s)
funpack (x, f, e, s)
     octa x;
     octa x;
     octa *f;
     octa *f;
     int *e;
     int *e;
     char *s;
     char *s;
{
{
  register int ee;
  register int ee;
  exceptions = 0;
  exceptions = 0;
  *s = (x.h & sign_bit ? '-' : '+');
  *s = (x.h & sign_bit ? '-' : '+');
  *f = shift_left (x, 2);
  *f = shift_left (x, 2);
  f->h &= 0x3fffff;
  f->h &= 0x3fffff;
  ee = (x.h >> 20) & 0x7ff;
  ee = (x.h >> 20) & 0x7ff;
  if (ee)
  if (ee)
    {
    {
      *e = ee - 1;
      *e = ee - 1;
      f->h |= 0x400000;
      f->h |= 0x400000;
      return (ee < 0x7ff ? num : f->h == 0x400000 && !f->l ? inf : nan);
      return (ee < 0x7ff ? num : f->h == 0x400000 && !f->l ? inf : nan);
    }
    }
  if (!x.l && !f->h)
  if (!x.l && !f->h)
    {
    {
      *e = zero_exponent;
      *e = zero_exponent;
      return zro;
      return zro;
    }
    }
  do
  do
    {
    {
      ee--;
      ee--;
      *f = shift_left (*f, 1);
      *f = shift_left (*f, 1);
    }
    }
  while (!(f->h & 0x400000));
  while (!(f->h & 0x400000));
  *e = ee;
  *e = ee;
  return num;
  return num;
}
}
 
 
       /*:37*//*38: */
       /*:37*//*38: */
#line 634 "./mmix-arith.w"
#line 634 "./mmix-arith.w"
 
 
ftype sfunpack ARGS ((tetra, octa *, int *, char *));
ftype sfunpack ARGS ((tetra, octa *, int *, char *));
ftype
ftype
sfunpack (x, f, e, s)
sfunpack (x, f, e, s)
     tetra x;
     tetra x;
     octa *f;
     octa *f;
     int *e;
     int *e;
     char *s;
     char *s;
{
{
  register int ee;
  register int ee;
  exceptions = 0;
  exceptions = 0;
  *s = (x & sign_bit ? '-' : '+');
  *s = (x & sign_bit ? '-' : '+');
  f->h = (x >> 1) & 0x3fffff, f->l = x << 31;
  f->h = (x >> 1) & 0x3fffff, f->l = x << 31;
  ee = (x >> 23) & 0xff;
  ee = (x >> 23) & 0xff;
  if (ee)
  if (ee)
    {
    {
      *e = ee + 0x380 - 1;
      *e = ee + 0x380 - 1;
      f->h |= 0x400000;
      f->h |= 0x400000;
      return (ee < 0xff ? num : (x & 0x7fffffff) == 0x7f800000 ? inf : nan);
      return (ee < 0xff ? num : (x & 0x7fffffff) == 0x7f800000 ? inf : nan);
    }
    }
  if (!(x & 0x7fffffff))
  if (!(x & 0x7fffffff))
    {
    {
      *e = zero_exponent;
      *e = zero_exponent;
      return zro;
      return zro;
    }
    }
  do
  do
    {
    {
      ee--;
      ee--;
      *f = shift_left (*f, 1);
      *f = shift_left (*f, 1);
    }
    }
  while (!(f->h & 0x400000));
  while (!(f->h & 0x400000));
  *e = ee + 0x380;
  *e = ee + 0x380;
  return num;
  return num;
}
}
 
 
       /*:38*//*39: */
       /*:38*//*39: */
#line 663 "./mmix-arith.w"
#line 663 "./mmix-arith.w"
 
 
octa load_sf ARGS ((tetra));
octa load_sf ARGS ((tetra));
octa
octa
load_sf (z)
load_sf (z)
     tetra z;
     tetra z;
{
{
  octa f, x;
  octa f, x;
  int e;
  int e;
  char s;
  char s;
  ftype t;
  ftype t;
  t = sfunpack (z, &f, &e, &s);
  t = sfunpack (z, &f, &e, &s);
  switch (t)
  switch (t)
    {
    {
    case zro:
    case zro:
      x = zero_octa;
      x = zero_octa;
      break;
      break;
    case num:
    case num:
      return fpack (f, e, s, ROUND_OFF);
      return fpack (f, e, s, ROUND_OFF);
    case inf:
    case inf:
      x = inf_octa;
      x = inf_octa;
      break;
      break;
    case nan:
    case nan:
      x = shift_right (f, 2, 1);
      x = shift_right (f, 2, 1);
      x.h |= 0x7ff00000;
      x.h |= 0x7ff00000;
      break;
      break;
    }
    }
  if (s == '-')
  if (s == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
       /*:39*//*40: */
       /*:39*//*40: */
#line 680 "./mmix-arith.w"
#line 680 "./mmix-arith.w"
 
 
tetra store_sf ARGS ((octa));
tetra store_sf ARGS ((octa));
tetra
tetra
store_sf (x)
store_sf (x)
     octa x;
     octa x;
{
{
  octa f;
  octa f;
  tetra z;
  tetra z;
  int e;
  int e;
  char s;
  char s;
  ftype t;
  ftype t;
  t = funpack (x, &f, &e, &s);
  t = funpack (x, &f, &e, &s);
  switch (t)
  switch (t)
    {
    {
    case zro:
    case zro:
      z = 0;
      z = 0;
      break;
      break;
    case num:
    case num:
      return sfpack (f, e, s, cur_round);
      return sfpack (f, e, s, cur_round);
    case inf:
    case inf:
      z = 0x7f800000;
      z = 0x7f800000;
      break;
      break;
    case nan:
    case nan:
      if (!(f.h & 0x200000))
      if (!(f.h & 0x200000))
        {
        {
          f.h |= 0x200000;
          f.h |= 0x200000;
          exceptions |= I_BIT;
          exceptions |= I_BIT;
        }
        }
      z = 0x7f800000 | (f.h << 1) | (f.l >> 31);
      z = 0x7f800000 | (f.h << 1) | (f.l >> 31);
      break;
      break;
    }
    }
  if (s == '-')
  if (s == '-')
    z |= sign_bit;
    z |= sign_bit;
  return z;
  return z;
}
}
 
 
       /*:40*//*41: */
       /*:40*//*41: */
#line 705 "./mmix-arith.w"
#line 705 "./mmix-arith.w"
 
 
octa fmult ARGS ((octa, octa));
octa fmult ARGS ((octa, octa));
octa
octa
fmult (y, z)
fmult (y, z)
     octa y, z;
     octa y, z;
{
{
  ftype yt, zt;
  ftype yt, zt;
  int ye, ze;
  int ye, ze;
  char ys, zs;
  char ys, zs;
  octa x, xf, yf, zf;
  octa x, xf, yf, zf;
  register int xe;
  register int xe;
  register char xs;
  register char xs;
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  xs = ys + zs - '+';
  xs = ys + zs - '+';
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
/*42:*/
/*42:*/
#line 731 "./mmix-arith.w"
#line 731 "./mmix-arith.w"
 
 
    case 4 * nan + nan:
    case 4 * nan + nan:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT;
        exceptions |= I_BIT;
    case 4 * zro + nan:
    case 4 * zro + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * inf + nan:
    case 4 * inf + nan:
      if (!(z.h & 0x80000))
      if (!(z.h & 0x80000))
        exceptions |= I_BIT, z.h |= 0x80000;
        exceptions |= I_BIT, z.h |= 0x80000;
      return z;
      return z;
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + inf:
    case 4 * nan + inf:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT, y.h |= 0x80000;
        exceptions |= I_BIT, y.h |= 0x80000;
      return y;
      return y;
 
 
/*:42*/
/*:42*/
#line 720 "./mmix-arith.w"
#line 720 "./mmix-arith.w"
      ;
      ;
    case 4 * zro + zro:
    case 4 * zro + zro:
    case 4 * zro + num:
    case 4 * zro + num:
    case 4 * num + zro:
    case 4 * num + zro:
      x = zero_octa;
      x = zero_octa;
      break;
      break;
    case 4 * num + inf:
    case 4 * num + inf:
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + inf:
    case 4 * inf + inf:
      x = inf_octa;
      x = inf_octa;
      break;
      break;
    case 4 * zro + inf:
    case 4 * zro + inf:
    case 4 * inf + zro:
    case 4 * inf + zro:
      x = standard_NaN;
      x = standard_NaN;
      exceptions |= I_BIT;
      exceptions |= I_BIT;
      break;
      break;
    case 4 * num + num: /*43: */
    case 4 * num + num: /*43: */
#line 740 "./mmix-arith.w"
#line 740 "./mmix-arith.w"
 
 
      xe = ye + ze - 0x3fd;
      xe = ye + ze - 0x3fd;
      x = omult (yf, shift_left (zf, 9));
      x = omult (yf, shift_left (zf, 9));
      if (aux.h >= 0x400000)
      if (aux.h >= 0x400000)
        xf = aux;
        xf = aux;
      else
      else
        xf = shift_left (aux, 1), xe--;
        xf = shift_left (aux, 1), xe--;
      if (x.h || x.l)
      if (x.h || x.l)
        xf.l |= 1;
        xf.l |= 1;
      return fpack (xf, xe, xs, cur_round);
      return fpack (xf, xe, xs, cur_round);
 
 
/*:43*/
/*:43*/
#line 725 "./mmix-arith.w"
#line 725 "./mmix-arith.w"
      ;
      ;
    }
    }
  if (xs == '-')
  if (xs == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
       /*:41*//*44: */
       /*:41*//*44: */
#line 748 "./mmix-arith.w"
#line 748 "./mmix-arith.w"
 
 
octa fdivide ARGS ((octa, octa));
octa fdivide ARGS ((octa, octa));
octa
octa
fdivide (y, z)
fdivide (y, z)
     octa y, z;
     octa y, z;
{
{
  ftype yt, zt;
  ftype yt, zt;
  int ye, ze;
  int ye, ze;
  char ys, zs;
  char ys, zs;
  octa x, xf, yf, zf;
  octa x, xf, yf, zf;
  register int xe;
  register int xe;
  register char xs;
  register char xs;
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  xs = ys + zs - '+';
  xs = ys + zs - '+';
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
/*42:*/
/*42:*/
#line 731 "./mmix-arith.w"
#line 731 "./mmix-arith.w"
 
 
    case 4 * nan + nan:
    case 4 * nan + nan:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT;
        exceptions |= I_BIT;
    case 4 * zro + nan:
    case 4 * zro + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * inf + nan:
    case 4 * inf + nan:
      if (!(z.h & 0x80000))
      if (!(z.h & 0x80000))
        exceptions |= I_BIT, z.h |= 0x80000;
        exceptions |= I_BIT, z.h |= 0x80000;
      return z;
      return z;
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + inf:
    case 4 * nan + inf:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT, y.h |= 0x80000;
        exceptions |= I_BIT, y.h |= 0x80000;
      return y;
      return y;
 
 
/*:42*/
/*:42*/
#line 763 "./mmix-arith.w"
#line 763 "./mmix-arith.w"
      ;
      ;
    case 4 * zro + inf:
    case 4 * zro + inf:
    case 4 * zro + num:
    case 4 * zro + num:
    case 4 * num + inf:
    case 4 * num + inf:
      x = zero_octa;
      x = zero_octa;
      break;
      break;
    case 4 * num + zro:
    case 4 * num + zro:
      exceptions |= Z_BIT;
      exceptions |= Z_BIT;
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + zro:
    case 4 * inf + zro:
      x = inf_octa;
      x = inf_octa;
      break;
      break;
    case 4 * zro + zro:
    case 4 * zro + zro:
    case 4 * inf + inf:
    case 4 * inf + inf:
      x = standard_NaN;
      x = standard_NaN;
      exceptions |= I_BIT;
      exceptions |= I_BIT;
      break;
      break;
    case 4 * num + num: /*45: */
    case 4 * num + num: /*45: */
#line 775 "./mmix-arith.w"
#line 775 "./mmix-arith.w"
 
 
      xe = ye - ze + 0x3fd;
      xe = ye - ze + 0x3fd;
      xf = odiv (yf, zero_octa, shift_left (zf, 9));
      xf = odiv (yf, zero_octa, shift_left (zf, 9));
      if (xf.h >= 0x800000)
      if (xf.h >= 0x800000)
        {
        {
          aux.l |= xf.l & 1;
          aux.l |= xf.l & 1;
          xf = shift_right (xf, 1, 1);
          xf = shift_right (xf, 1, 1);
          xe++;
          xe++;
        }
        }
      if (aux.h || aux.l)
      if (aux.h || aux.l)
        xf.l |= 1;
        xf.l |= 1;
      return fpack (xf, xe, xs, cur_round);
      return fpack (xf, xe, xs, cur_round);
 
 
/*:45*/
/*:45*/
#line 769 "./mmix-arith.w"
#line 769 "./mmix-arith.w"
      ;
      ;
    }
    }
  if (xs == '-')
  if (xs == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
       /*:44*//*46: */
       /*:44*//*46: */
#line 790 "./mmix-arith.w"
#line 790 "./mmix-arith.w"
 
 
octa fplus ARGS ((octa, octa));
octa fplus ARGS ((octa, octa));
octa
octa
fplus (y, z)
fplus (y, z)
     octa y, z;
     octa y, z;
{
{
  ftype yt, zt;
  ftype yt, zt;
  int ye, ze;
  int ye, ze;
  char ys, zs;
  char ys, zs;
  octa x, xf, yf, zf;
  octa x, xf, yf, zf;
  register int xe, d;
  register int xe, d;
  register char xs;
  register char xs;
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
/*42:*/
/*42:*/
#line 731 "./mmix-arith.w"
#line 731 "./mmix-arith.w"
 
 
    case 4 * nan + nan:
    case 4 * nan + nan:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT;
        exceptions |= I_BIT;
    case 4 * zro + nan:
    case 4 * zro + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * inf + nan:
    case 4 * inf + nan:
      if (!(z.h & 0x80000))
      if (!(z.h & 0x80000))
        exceptions |= I_BIT, z.h |= 0x80000;
        exceptions |= I_BIT, z.h |= 0x80000;
      return z;
      return z;
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + inf:
    case 4 * nan + inf:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT, y.h |= 0x80000;
        exceptions |= I_BIT, y.h |= 0x80000;
      return y;
      return y;
 
 
/*:42*/
/*:42*/
#line 804 "./mmix-arith.w"
#line 804 "./mmix-arith.w"
      ;
      ;
    case 4 * zro + num:
    case 4 * zro + num:
      return fpack (zf, ze, zs, ROUND_OFF);
      return fpack (zf, ze, zs, ROUND_OFF);
      break;
      break;
    case 4 * num + zro:
    case 4 * num + zro:
      return fpack (yf, ye, ys, ROUND_OFF);
      return fpack (yf, ye, ys, ROUND_OFF);
      break;
      break;
    case 4 * inf + inf:
    case 4 * inf + inf:
      if (ys != zs)
      if (ys != zs)
        {
        {
          exceptions |= I_BIT;
          exceptions |= I_BIT;
          x = standard_NaN;
          x = standard_NaN;
          xs = zs;
          xs = zs;
          break;
          break;
        }
        }
    case 4 * num + inf:
    case 4 * num + inf:
    case 4 * zro + inf:
    case 4 * zro + inf:
      x = inf_octa;
      x = inf_octa;
      xs = zs;
      xs = zs;
      break;
      break;
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + zro:
    case 4 * inf + zro:
      x = inf_octa;
      x = inf_octa;
      xs = ys;
      xs = ys;
      break;
      break;
    case 4 * num + num:
    case 4 * num + num:
      if (y.h != (z.h ^ 0x80000000) || y.l != z.l)
      if (y.h != (z.h ^ 0x80000000) || y.l != z.l)
/*47:*/
/*47:*/
#line 821 "./mmix-arith.w"
#line 821 "./mmix-arith.w"
 
 
        {
        {
          octa o, oo;
          octa o, oo;
          if (ye < ze
          if (ye < ze
              || (ye == ze && (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))))
              || (ye == ze && (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))))
/*48:*/
/*48:*/
#line 839 "./mmix-arith.w"
#line 839 "./mmix-arith.w"
 
 
            {
            {
              o = yf, yf = zf, zf = o;
              o = yf, yf = zf, zf = o;
              d = ye, ye = ze, ze = d;
              d = ye, ye = ze, ze = d;
              d = ys, ys = zs, zs = d;
              d = ys, ys = zs, zs = d;
            }
            }
 
 
/*:48*/
/*:48*/
#line 824 "./mmix-arith.w"
#line 824 "./mmix-arith.w"
          ;
          ;
          d = ye - ze;
          d = ye - ze;
          xs = ys, xe = ye;
          xs = ys, xe = ye;
          if (d)                /*49: */
          if (d)                /*49: */
#line 859 "./mmix-arith.w"
#line 859 "./mmix-arith.w"
 
 
            {
            {
              if (d <= 2)
              if (d <= 2)
                zf = shift_right (zf, d, 1);
                zf = shift_right (zf, d, 1);
              else if (d > 53)
              else if (d > 53)
                zf.h = 0, zf.l = 1;
                zf.h = 0, zf.l = 1;
              else
              else
                {
                {
                  if (ys != zs)
                  if (ys != zs)
                    d--, xe--, yf = shift_left (yf, 1);
                    d--, xe--, yf = shift_left (yf, 1);
                  o = zf;
                  o = zf;
                  zf = shift_right (o, d, 1);
                  zf = shift_right (o, d, 1);
                  oo = shift_left (zf, d);
                  oo = shift_left (zf, d);
                  if (oo.l != o.l || oo.h != o.h)
                  if (oo.l != o.l || oo.h != o.h)
                    zf.l |= 1;
                    zf.l |= 1;
                }
                }
            }
            }
 
 
/*:49*/
/*:49*/
#line 827 "./mmix-arith.w"
#line 827 "./mmix-arith.w"
          ;
          ;
          if (ys == zs)
          if (ys == zs)
            {
            {
              xf = oplus (yf, zf);
              xf = oplus (yf, zf);
              if (xf.h >= 0x800000)
              if (xf.h >= 0x800000)
                xe++, d = xf.l & 1, xf = shift_right (xf, 1, 1), xf.l |= d;
                xe++, d = xf.l & 1, xf = shift_right (xf, 1, 1), xf.l |= d;
            }
            }
          else
          else
            {
            {
              xf = ominus (yf, zf);
              xf = ominus (yf, zf);
              if (xf.h >= 0x800000)
              if (xf.h >= 0x800000)
                xe++, d = xf.l & 1, xf = shift_right (xf, 1, 1), xf.l |= d;
                xe++, d = xf.l & 1, xf = shift_right (xf, 1, 1), xf.l |= d;
              else
              else
                while (xf.h < 0x400000)
                while (xf.h < 0x400000)
                  xe--, xf = shift_left (xf, 1);
                  xe--, xf = shift_left (xf, 1);
            }
            }
          return fpack (xf, xe, xs, cur_round);
          return fpack (xf, xe, xs, cur_round);
        }
        }
 
 
/*:47*/
/*:47*/
#line 813 "./mmix-arith.w"
#line 813 "./mmix-arith.w"
      ;
      ;
    case 4 * zro + zro:
    case 4 * zro + zro:
      x = zero_octa;
      x = zero_octa;
      xs = (ys == zs ? ys : cur_round == ROUND_DOWN ? '-' : '+');
      xs = (ys == zs ? ys : cur_round == ROUND_DOWN ? '-' : '+');
      break;
      break;
    }
    }
  if (xs == '-')
  if (xs == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
       /*:46*//*50: */
       /*:46*//*50: */
#line 883 "./mmix-arith.w"
#line 883 "./mmix-arith.w"
 
 
int fepscomp ARGS ((octa, octa, octa, int));
int fepscomp ARGS ((octa, octa, octa, int));
int
int
fepscomp (y, z, e, s)
fepscomp (y, z, e, s)
     octa y, z, e;
     octa y, z, e;
     int s;
     int s;
{
{
  octa yf, zf, ef, o, oo;
  octa yf, zf, ef, o, oo;
  int ye, ze, ee;
  int ye, ze, ee;
  char ys, zs, es;
  char ys, zs, es;
  register int yt, zt, et, d;
  register int yt, zt, et, d;
  et = funpack (e, &ef, &ee, &es);
  et = funpack (e, &ef, &ee, &es);
  if (es == '-')
  if (es == '-')
    return 2;
    return 2;
  switch (et)
  switch (et)
    {
    {
    case nan:
    case nan:
      return 2;
      return 2;
    case inf:
    case inf:
      ee = 10000;
      ee = 10000;
    case num:
    case num:
    case zro:
    case zro:
      break;
      break;
    }
    }
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
    case 4 * nan + nan:
    case 4 * nan + nan:
    case 4 * nan + inf:
    case 4 * nan + inf:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * inf + nan:
    case 4 * inf + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * zro + nan:
    case 4 * zro + nan:
      return 2;
      return 2;
    case 4 * inf + inf:
    case 4 * inf + inf:
      return (ys == zs || ee >= 1023);
      return (ys == zs || ee >= 1023);
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + zro:
    case 4 * inf + zro:
    case 4 * num + inf:
    case 4 * num + inf:
    case 4 * zro + inf:
    case 4 * zro + inf:
      return (s && ee >= 1022);
      return (s && ee >= 1022);
    case 4 * zro + zro:
    case 4 * zro + zro:
      return 1;
      return 1;
    case 4 * zro + num:
    case 4 * zro + num:
    case 4 * num + zro:
    case 4 * num + zro:
      if (!s)
      if (!s)
        return 0;
        return 0;
    case 4 * num + num:
    case 4 * num + num:
      break;
      break;
    }
    }
/*51:*/
/*51:*/
#line 919 "./mmix-arith.w"
#line 919 "./mmix-arith.w"
 
 
/*52:*/
/*52:*/
#line 934 "./mmix-arith.w"
#line 934 "./mmix-arith.w"
 
 
  if (ye < 0 && yt != zro)
  if (ye < 0 && yt != zro)
    yf = shift_left (y, 2), ye = 0;
    yf = shift_left (y, 2), ye = 0;
  if (ze < 0 && zt != zro)
  if (ze < 0 && zt != zro)
    zf = shift_left (z, 2), ze = 0;
    zf = shift_left (z, 2), ze = 0;
 
 
/*:52*/
/*:52*/
#line 920 "./mmix-arith.w"
#line 920 "./mmix-arith.w"
  ;
  ;
  if (ye < ze || (ye == ze && (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))))
  if (ye < ze || (ye == ze && (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))))
/*48:*/
/*48:*/
#line 839 "./mmix-arith.w"
#line 839 "./mmix-arith.w"
 
 
    {
    {
      o = yf, yf = zf, zf = o;
      o = yf, yf = zf, zf = o;
      d = ye, ye = ze, ze = d;
      d = ye, ye = ze, ze = d;
      d = ys, ys = zs, zs = d;
      d = ys, ys = zs, zs = d;
    }
    }
 
 
/*:48*/
/*:48*/
#line 922 "./mmix-arith.w"
#line 922 "./mmix-arith.w"
  ;
  ;
  if (ze == zero_exponent)
  if (ze == zero_exponent)
    ze = ye;
    ze = ye;
  d = ye - ze;
  d = ye - ze;
  if (!s)
  if (!s)
    ee -= d;
    ee -= d;
  if (ee >= 1023)
  if (ee >= 1023)
    return 1;
    return 1;
/*53:*/
/*53:*/
#line 956 "./mmix-arith.w"
#line 956 "./mmix-arith.w"
 
 
  if (d > 54)
  if (d > 54)
    o = zero_octa, oo = zf;
    o = zero_octa, oo = zf;
  else
  else
    o = shift_right (zf, d, 1), oo = shift_left (o, d);
    o = shift_right (zf, d, 1), oo = shift_left (o, d);
  if (oo.h != zf.h || oo.l != zf.l)
  if (oo.h != zf.h || oo.l != zf.l)
    {
    {
      if (ee < 1020)
      if (ee < 1020)
        return 0;
        return 0;
      o = incr (o, ys == zs ? 0 : 1);
      o = incr (o, ys == zs ? 0 : 1);
    }
    }
  o = (ys == zs ? ominus (yf, o) : oplus (yf, o));
  o = (ys == zs ? ominus (yf, o) : oplus (yf, o));
 
 
/*:53*/
/*:53*/
#line 927 "./mmix-arith.w"
#line 927 "./mmix-arith.w"
  ;
  ;
  if (!o.h && !o.l)
  if (!o.h && !o.l)
    return 1;
    return 1;
  if (ee < 968)
  if (ee < 968)
    return 0;
    return 0;
  if (ee >= 1021)
  if (ee >= 1021)
    ef = shift_left (ef, ee - 1021);
    ef = shift_left (ef, ee - 1021);
  else
  else
    ef = shift_right (ef, 1021 - ee, 1);
    ef = shift_right (ef, 1021 - ee, 1);
  return o.h < ef.h || (o.h == ef.h && o.l <= ef.l);
  return o.h < ef.h || (o.h == ef.h && o.l <= ef.l);
 
 
/*:51*/
/*:51*/
#line 912 "./mmix-arith.w"
#line 912 "./mmix-arith.w"
  ;
  ;
}
}
 
 
       /*:50*//*54: */
       /*:50*//*54: */
#line 972 "./mmix-arith.w"
#line 972 "./mmix-arith.w"
 
 
static void bignum_times_ten ARGS ((bignum *));
static void bignum_times_ten ARGS ((bignum *));
static void bignum_dec ARGS ((bignum *, bignum *, tetra));
static void bignum_dec ARGS ((bignum *, bignum *, tetra));
static int bignum_compare ARGS ((bignum *, bignum *));
static int bignum_compare ARGS ((bignum *, bignum *));
void print_float ARGS ((octa));
void print_float ARGS ((octa));
void
void
print_float (x)
print_float (x)
     octa x;
     octa x;
{
{
/*56:*/
/*56:*/
#line 1035 "./mmix-arith.w"
#line 1035 "./mmix-arith.w"
 
 
  octa f, g;
  octa f, g;
  register int e;
  register int e;
  register int j, k;
  register int j, k;
 
 
  /*:56*//*66: */
  /*:56*//*66: */
#line 1281 "./mmix-arith.w"
#line 1281 "./mmix-arith.w"
 
 
  bignum ff, gg;
  bignum ff, gg;
  bignum tt;
  bignum tt;
  char s[18];
  char s[18];
  register char *p;
  register char *p;
 
 
/*:66*/
/*:66*/
#line 980 "./mmix-arith.w"
#line 980 "./mmix-arith.w"
  ;
  ;
  if (x.h & sign_bit)
  if (x.h & sign_bit)
    printf ("-");
    printf ("-");
/*55:*/
/*55:*/
#line 1019 "./mmix-arith.w"
#line 1019 "./mmix-arith.w"
 
 
  f = shift_left (x, 1);
  f = shift_left (x, 1);
  e = f.h >> 21;
  e = f.h >> 21;
  f.h &= 0x1fffff;
  f.h &= 0x1fffff;
  if (!f.h && !f.l)             /*57: */
  if (!f.h && !f.l)             /*57: */
#line 1045 "./mmix-arith.w"
#line 1045 "./mmix-arith.w"
 
 
    {
    {
      if (!e)
      if (!e)
        {
        {
          printf ("0.");
          printf ("0.");
          return;
          return;
        }
        }
      if (e == 0x7ff)
      if (e == 0x7ff)
        {
        {
          printf ("Inf");
          printf ("Inf");
          return;
          return;
        }
        }
      e--;
      e--;
      f.h = 0x3fffff, f.l = 0xffffffff;
      f.h = 0x3fffff, f.l = 0xffffffff;
      g.h = 0x400000, g.l = 2;
      g.h = 0x400000, g.l = 2;
    }
    }
 
 
/*:57*/
/*:57*/
#line 1023 "./mmix-arith.w"
#line 1023 "./mmix-arith.w"
 
 
  else
  else
    {
    {
      g = incr (f, 1);
      g = incr (f, 1);
      f = incr (f, -1);
      f = incr (f, -1);
      if (!e)
      if (!e)
        e = 1;
        e = 1;
      else if (e == 0x7ff)
      else if (e == 0x7ff)
        {
        {
          printf ("NaN");
          printf ("NaN");
          if (g.h == 0x100000 && g.l == 1)
          if (g.h == 0x100000 && g.l == 1)
            return;
            return;
          e = 0x3ff;
          e = 0x3ff;
        }
        }
      else
      else
        f.h |= 0x200000, g.h |= 0x200000;
        f.h |= 0x200000, g.h |= 0x200000;
    }
    }
 
 
/*:55*/
/*:55*/
#line 983 "./mmix-arith.w"
#line 983 "./mmix-arith.w"
  ;
  ;
/*63:*/
/*63:*/
#line 1195 "./mmix-arith.w"
#line 1195 "./mmix-arith.w"
 
 
  k = (magic_offset - e) / 28;
  k = (magic_offset - e) / 28;
  ff.dat[k - 1] =
  ff.dat[k - 1] =
    shift_right (f, magic_offset + 28 - e - 28 * k, 1).l & 0xfffffff;
    shift_right (f, magic_offset + 28 - e - 28 * k, 1).l & 0xfffffff;
  gg.dat[k - 1] =
  gg.dat[k - 1] =
    shift_right (g, magic_offset + 28 - e - 28 * k, 1).l & 0xfffffff;
    shift_right (g, magic_offset + 28 - e - 28 * k, 1).l & 0xfffffff;
  ff.dat[k] = shift_right (f, magic_offset - e - 28 * k, 1).l & 0xfffffff;
  ff.dat[k] = shift_right (f, magic_offset - e - 28 * k, 1).l & 0xfffffff;
  gg.dat[k] = shift_right (g, magic_offset - e - 28 * k, 1).l & 0xfffffff;
  gg.dat[k] = shift_right (g, magic_offset - e - 28 * k, 1).l & 0xfffffff;
  ff.dat[k + 1] =
  ff.dat[k + 1] =
    shift_left (f, e + 28 * k - (magic_offset - 28)).l & 0xfffffff;
    shift_left (f, e + 28 * k - (magic_offset - 28)).l & 0xfffffff;
  gg.dat[k + 1] =
  gg.dat[k + 1] =
    shift_left (g, e + 28 * k - (magic_offset - 28)).l & 0xfffffff;
    shift_left (g, e + 28 * k - (magic_offset - 28)).l & 0xfffffff;
  ff.a = (ff.dat[k - 1] ? k - 1 : k);
  ff.a = (ff.dat[k - 1] ? k - 1 : k);
  ff.b = (ff.dat[k + 1] ? k + 1 : k);
  ff.b = (ff.dat[k + 1] ? k + 1 : k);
  gg.a = (gg.dat[k - 1] ? k - 1 : k);
  gg.a = (gg.dat[k - 1] ? k - 1 : k);
  gg.b = (gg.dat[k + 1] ? k + 1 : k);
  gg.b = (gg.dat[k + 1] ? k + 1 : k);
 
 
/*:63*/
/*:63*/
#line 984 "./mmix-arith.w"
#line 984 "./mmix-arith.w"
  ;
  ;
/*64:*/
/*64:*/
#line 1223 "./mmix-arith.w"
#line 1223 "./mmix-arith.w"
 
 
  if (e > 0x401)                /*65: */
  if (e > 0x401)                /*65: */
#line 1254 "./mmix-arith.w"
#line 1254 "./mmix-arith.w"
 
 
    {
    {
      register int open = x.l & 1;
      register int open = x.l & 1;
      tt.dat[origin] = 10;
      tt.dat[origin] = 10;
      tt.a = tt.b = origin;
      tt.a = tt.b = origin;
      for (e = 1; bignum_compare (&gg, &tt) >= open; e++)
      for (e = 1; bignum_compare (&gg, &tt) >= open; e++)
        bignum_times_ten (&tt);
        bignum_times_ten (&tt);
      p = s;
      p = s;
      while (1)
      while (1)
        {
        {
          bignum_times_ten (&ff);
          bignum_times_ten (&ff);
          bignum_times_ten (&gg);
          bignum_times_ten (&gg);
          for (j = '0'; bignum_compare (&ff, &tt) >= 0; j++)
          for (j = '0'; bignum_compare (&ff, &tt) >= 0; j++)
            bignum_dec (&ff, &tt, 0x10000000), bignum_dec (&gg, &tt,
            bignum_dec (&ff, &tt, 0x10000000), bignum_dec (&gg, &tt,
                                                           0x10000000);
                                                           0x10000000);
          if (bignum_compare (&gg, &tt) >= open)
          if (bignum_compare (&gg, &tt) >= open)
            break;
            break;
          *p++ = j;
          *p++ = j;
          if (ff.a == bignum_prec - 1 && !open)
          if (ff.a == bignum_prec - 1 && !open)
            goto done;
            goto done;
        }
        }
      for (k = j; bignum_compare (&gg, &tt) >= open; k++)
      for (k = j; bignum_compare (&gg, &tt) >= open; k++)
        bignum_dec (&gg, &tt, 0x10000000);
        bignum_dec (&gg, &tt, 0x10000000);
      *p++ = (j + 1 + k) >> 1;
      *p++ = (j + 1 + k) >> 1;
    done:;
    done:;
    }
    }
 
 
/*:65*/
/*:65*/
#line 1224 "./mmix-arith.w"
#line 1224 "./mmix-arith.w"
 
 
  else
  else
    {
    {
      if (ff.a > origin)
      if (ff.a > origin)
        ff.dat[origin] = 0;
        ff.dat[origin] = 0;
      for (e = 1, p = s; gg.a > origin || ff.dat[origin] == gg.dat[origin];)
      for (e = 1, p = s; gg.a > origin || ff.dat[origin] == gg.dat[origin];)
        {
        {
          if (gg.a > origin)
          if (gg.a > origin)
            e--;
            e--;
          else
          else
            *p++ = ff.dat[origin] + '0', ff.dat[origin] = 0, gg.dat[origin] =
            *p++ = ff.dat[origin] + '0', ff.dat[origin] = 0, gg.dat[origin] =
              0;
              0;
          bignum_times_ten (&ff);
          bignum_times_ten (&ff);
          bignum_times_ten (&gg);
          bignum_times_ten (&gg);
        }
        }
      *p++ = ((ff.dat[origin] + 1 + gg.dat[origin]) >> 1) + '0';
      *p++ = ((ff.dat[origin] + 1 + gg.dat[origin]) >> 1) + '0';
    }
    }
  *p = '\0';
  *p = '\0';
 
 
/*:64*/
/*:64*/
#line 985 "./mmix-arith.w"
#line 985 "./mmix-arith.w"
  ;
  ;
/*67:*/
/*67:*/
#line 1296 "./mmix-arith.w"
#line 1296 "./mmix-arith.w"
 
 
  if (e > 17 || e < (int) strlen (s) - 17)
  if (e > 17 || e < (int) strlen (s) - 17)
    printf ("%c%s%se%d", s[0], (s[1] ? "." : ""), s + 1, e - 1);
    printf ("%c%s%se%d", s[0], (s[1] ? "." : ""), s + 1, e - 1);
  else if (e < 0)
  else if (e < 0)
    printf (".%0*d%s", -e, 0, s);
    printf (".%0*d%s", -e, 0, s);
  else if (strlen (s) >= e)
  else if (strlen (s) >= e)
    printf ("%.*s.%s", e, s, s + e);
    printf ("%.*s.%s", e, s, s + e);
  else
  else
    printf ("%s%0*d.", s, e - (int) strlen (s), 0);
    printf ("%s%0*d.", s, e - (int) strlen (s), 0);
 
 
/*:67*/
/*:67*/
#line 986 "./mmix-arith.w"
#line 986 "./mmix-arith.w"
  ;
  ;
}
}
 
 
       /*:54*//*60: */
       /*:54*//*60: */
#line 1120 "./mmix-arith.w"
#line 1120 "./mmix-arith.w"
 
 
static void
static void
bignum_times_ten (f)
bignum_times_ten (f)
     bignum *f;
     bignum *f;
{
{
  register tetra *p, *q;
  register tetra *p, *q;
  register tetra x, carry;
  register tetra x, carry;
  for (p = &f->dat[f->b], q = &f->dat[f->a], carry = 0; p >= q; p--)
  for (p = &f->dat[f->b], q = &f->dat[f->a], carry = 0; p >= q; p--)
    {
    {
      x = *p * 10 + carry;
      x = *p * 10 + carry;
      *p = x & 0xfffffff;
      *p = x & 0xfffffff;
      carry = x >> 28;
      carry = x >> 28;
    }
    }
  *p = carry;
  *p = carry;
  if (carry)
  if (carry)
    f->a--;
    f->a--;
  if (f->dat[f->b] == 0 && f->b > f->a)
  if (f->dat[f->b] == 0 && f->b > f->a)
    f->b--;
    f->b--;
}
}
 
 
       /*:60*//*61: */
       /*:60*//*61: */
#line 1138 "./mmix-arith.w"
#line 1138 "./mmix-arith.w"
 
 
static int
static int
bignum_compare (f, g)
bignum_compare (f, g)
     bignum *f, *g;
     bignum *f, *g;
{
{
  register tetra *p, *pp, *q, *qq;
  register tetra *p, *pp, *q, *qq;
  if (f->a != g->a)
  if (f->a != g->a)
    return f->a > g->a ? -1 : 1;
    return f->a > g->a ? -1 : 1;
  pp = &f->dat[f->b], qq = &g->dat[g->b];
  pp = &f->dat[f->b], qq = &g->dat[g->b];
  for (p = &f->dat[f->a], q = &g->dat[g->a]; p <= pp; p++, q++)
  for (p = &f->dat[f->a], q = &g->dat[g->a]; p <= pp; p++, q++)
    {
    {
      if (*p != *q)
      if (*p != *q)
        return *p < *q ? -1 : 1;
        return *p < *q ? -1 : 1;
      if (q == qq)
      if (q == qq)
        return p < pp;
        return p < pp;
    }
    }
  return -1;
  return -1;
}
}
 
 
       /*:61*//*62: */
       /*:61*//*62: */
#line 1155 "./mmix-arith.w"
#line 1155 "./mmix-arith.w"
 
 
static void
static void
bignum_dec (f, g, r)
bignum_dec (f, g, r)
     bignum *f, *g;
     bignum *f, *g;
     tetra r;
     tetra r;
{
{
  register tetra *p, *q, *qq;
  register tetra *p, *q, *qq;
  register int x, borrow;
  register int x, borrow;
  while (g->b > f->b)
  while (g->b > f->b)
    f->dat[++f->b] = 0;
    f->dat[++f->b] = 0;
  qq = &g->dat[g->a];
  qq = &g->dat[g->a];
  for (p = &f->dat[g->b], q = &g->dat[g->b], borrow = 0; q >= qq; p--, q--)
  for (p = &f->dat[g->b], q = &g->dat[g->b], borrow = 0; q >= qq; p--, q--)
    {
    {
      x = *p - *q - borrow;
      x = *p - *q - borrow;
      if (x >= 0)
      if (x >= 0)
        borrow = 0, *p = x;
        borrow = 0, *p = x;
      else
      else
        borrow = 1, *p = x + r;
        borrow = 1, *p = x + r;
    }
    }
  for (; borrow; p--)
  for (; borrow; p--)
    if (*p)
    if (*p)
      borrow = 0, *p = *p - 1;
      borrow = 0, *p = *p - 1;
    else
    else
      *p = r - 1;
      *p = r - 1;
  while (f->dat[f->a] == 0)
  while (f->dat[f->a] == 0)
    {
    {
      if (f->a == f->b)
      if (f->a == f->b)
        {
        {
          f->a = f->b = bignum_prec - 1, f->dat[bignum_prec - 1] = 0;
          f->a = f->b = bignum_prec - 1, f->dat[bignum_prec - 1] = 0;
          return;
          return;
        }
        }
      f->a++;
      f->a++;
    }
    }
  while (f->dat[f->b] == 0)
  while (f->dat[f->b] == 0)
    f->b--;
    f->b--;
}
}
 
 
       /*:62*//*68: */
       /*:62*//*68: */
#line 1340 "./mmix-arith.w"
#line 1340 "./mmix-arith.w"
 
 
static void bignum_double ARGS ((bignum *));
static void bignum_double ARGS ((bignum *));
int scan_const ARGS ((char *));
int scan_const ARGS ((char *));
int
int
scan_const (s)
scan_const (s)
     char *s;
     char *s;
{
{
/*70:*/
/*70:*/
#line 1363 "./mmix-arith.w"
#line 1363 "./mmix-arith.w"
 
 
  register char *p, *q;
  register char *p, *q;
  register bool NaN;
  register bool NaN;
  int sign;
  int sign;
 
 
  /*:70*//*76: */
  /*:70*//*76: */
#line 1435 "./mmix-arith.w"
#line 1435 "./mmix-arith.w"
 
 
  register char *dec_pt;
  register char *dec_pt;
  register int exp;
  register int exp;
  register int zeros;
  register int zeros;
 
 
  /*:76*//*81: */
  /*:76*//*81: */
#line 1503 "./mmix-arith.w"
#line 1503 "./mmix-arith.w"
 
 
  register int k, x;
  register int k, x;
  register char *pp;
  register char *pp;
  bignum ff, tt;
  bignum ff, tt;
 
 
/*:81*/
/*:81*/
#line 1346 "./mmix-arith.w"
#line 1346 "./mmix-arith.w"
  ;
  ;
  val.h = val.l = 0;
  val.h = val.l = 0;
  p = s;
  p = s;
  if (*p == '+' || *p == '-')
  if (*p == '+' || *p == '-')
    sign = *p++;
    sign = *p++;
  else
  else
    sign = '+';
    sign = '+';
  if (strncmp (p, "NaN", 3) == 0)
  if (strncmp (p, "NaN", 3) == 0)
    NaN = true, p += 3;
    NaN = true, p += 3;
  else
  else
    NaN = false;
    NaN = false;
  if ((isdigit (*p) && !NaN) || (*p == '.' && isdigit (*(p + 1))))
  if ((isdigit (*p) && !NaN) || (*p == '.' && isdigit (*(p + 1))))
/*73:*/
/*73:*/
#line 1396 "./mmix-arith.w"
#line 1396 "./mmix-arith.w"
 
 
    {
    {
      for (q = buf0, dec_pt = (char *) 0; isdigit (*p); p++)
      for (q = buf0, dec_pt = (char *) 0; isdigit (*p); p++)
        {
        {
          val = oplus (val, shift_left (val, 2));
          val = oplus (val, shift_left (val, 2));
          val = incr (shift_left (val, 1), *p - '0');
          val = incr (shift_left (val, 1), *p - '0');
          if (q > buf0 || *p != '0')
          if (q > buf0 || *p != '0')
            if (q < buf_max)
            if (q < buf_max)
              *q++ = *p;
              *q++ = *p;
            else if (*(q - 1) == '0')
            else if (*(q - 1) == '0')
              *(q - 1) = *p;
              *(q - 1) = *p;
        }
        }
      if (NaN)
      if (NaN)
        *q++ = '1';
        *q++ = '1';
      if (*p == '.')            /*74: */
      if (*p == '.')            /*74: */
#line 1415 "./mmix-arith.w"
#line 1415 "./mmix-arith.w"
 
 
        {
        {
          dec_pt = q;
          dec_pt = q;
          p++;
          p++;
          for (zeros = 0; isdigit (*p); p++)
          for (zeros = 0; isdigit (*p); p++)
            if (*p == '0' && q == buf0)
            if (*p == '0' && q == buf0)
              zeros++;
              zeros++;
            else if (q < buf_max)
            else if (q < buf_max)
              *q++ = *p;
              *q++ = *p;
            else if (*(q - 1) == '0')
            else if (*(q - 1) == '0')
              *(q - 1) = *p;
              *(q - 1) = *p;
        }
        }
 
 
/*:74*/
/*:74*/
#line 1406 "./mmix-arith.w"
#line 1406 "./mmix-arith.w"
      ;
      ;
      next_char = p;
      next_char = p;
      if (*p == 'e' && !NaN)    /*77: */
      if (*p == 'e' && !NaN)    /*77: */
#line 1447 "./mmix-arith.w"
#line 1447 "./mmix-arith.w"
 
 
        {
        {
          register char exp_sign;
          register char exp_sign;
          p++;
          p++;
          if (*p == '+' || *p == '-')
          if (*p == '+' || *p == '-')
            exp_sign = *p++;
            exp_sign = *p++;
          else
          else
            exp_sign = '+';
            exp_sign = '+';
          if (isdigit (*p))
          if (isdigit (*p))
            {
            {
              for (exp = *p++ - '0'; isdigit (*p); p++)
              for (exp = *p++ - '0'; isdigit (*p); p++)
                if (exp < 1000)
                if (exp < 1000)
                  exp = 10 * exp + *p - '0';
                  exp = 10 * exp + *p - '0';
              if (!dec_pt)
              if (!dec_pt)
                dec_pt = q, zeros = 0;
                dec_pt = q, zeros = 0;
              if (exp_sign == '-')
              if (exp_sign == '-')
                exp = -exp;
                exp = -exp;
              next_char = p;
              next_char = p;
            }
            }
        }
        }
 
 
/*:77*/
/*:77*/
#line 1408 "./mmix-arith.w"
#line 1408 "./mmix-arith.w"
 
 
      else
      else
        exp = 0;
        exp = 0;
      if (dec_pt)               /*78: */
      if (dec_pt)               /*78: */
#line 1460 "./mmix-arith.w"
#line 1460 "./mmix-arith.w"
 
 
        {
        {
/*79:*/
/*79:*/
#line 1477 "./mmix-arith.w"
#line 1477 "./mmix-arith.w"
 
 
          x = buf + 341 + zeros - dec_pt - exp;
          x = buf + 341 + zeros - dec_pt - exp;
          if (q == buf0 || x >= 1413)
          if (q == buf0 || x >= 1413)
            {
            {
            make_it_zero:exp = -99999;
            make_it_zero:exp = -99999;
              goto packit;
              goto packit;
            }
            }
          if (x < 0)
          if (x < 0)
            {
            {
            make_it_infinite:exp = 99999;
            make_it_infinite:exp = 99999;
              goto packit;
              goto packit;
            }
            }
          ff.a = x / 9;
          ff.a = x / 9;
          for (p = q; p < q + 8; p++)
          for (p = q; p < q + 8; p++)
            *p = '0';
            *p = '0';
          q = q - 1 - (q + 341 + zeros - dec_pt - exp) % 9;
          q = q - 1 - (q + 341 + zeros - dec_pt - exp) % 9;
          for (p = buf0 - x % 9, k = ff.a; p <= q && k <= 156; p += 9, k++)
          for (p = buf0 - x % 9, k = ff.a; p <= q && k <= 156; p += 9, k++)
/*80:*/
/*80:*/
#line 1497 "./mmix-arith.w"
#line 1497 "./mmix-arith.w"
 
 
            {
            {
              for (x = *p - '0', pp = p + 1; pp < p + 9; pp++)
              for (x = *p - '0', pp = p + 1; pp < p + 9; pp++)
                x = 10 * x + *pp - '0';
                x = 10 * x + *pp - '0';
              ff.dat[k] = x;
              ff.dat[k] = x;
            }
            }
 
 
/*:80*/
/*:80*/
#line 1490 "./mmix-arith.w"
#line 1490 "./mmix-arith.w"
          ;
          ;
          ff.b = k - 1;
          ff.b = k - 1;
          for (x = 0; p <= q; p += 9)
          for (x = 0; p <= q; p += 9)
            if (strncmp (p, "000000000", 9) != 0)
            if (strncmp (p, "000000000", 9) != 0)
              x = 1;
              x = 1;
          ff.dat[156] += x;
          ff.dat[156] += x;
 
 
          while (ff.dat[ff.b] == 0)
          while (ff.dat[ff.b] == 0)
            ff.b--;
            ff.b--;
 
 
/*:79*/
/*:79*/
#line 1462 "./mmix-arith.w"
#line 1462 "./mmix-arith.w"
          ;
          ;
/*83:*/
/*83:*/
#line 1526 "./mmix-arith.w"
#line 1526 "./mmix-arith.w"
 
 
          val = zero_octa;
          val = zero_octa;
          if (ff.a > 36)
          if (ff.a > 36)
            {
            {
              for (exp = 0x3fe; ff.a > 36; exp--)
              for (exp = 0x3fe; ff.a > 36; exp--)
                bignum_double (&ff);
                bignum_double (&ff);
              for (k = 54; k; k--)
              for (k = 54; k; k--)
                {
                {
                  if (ff.dat[36])
                  if (ff.dat[36])
                    {
                    {
                      if (k >= 32)
                      if (k >= 32)
                        val.h |= 1 << (k - 32);
                        val.h |= 1 << (k - 32);
                      else
                      else
                        val.l |= 1 << k;
                        val.l |= 1 << k;
                      ff.dat[36] = 0;
                      ff.dat[36] = 0;
                      if (ff.b == 36)
                      if (ff.b == 36)
                        break;
                        break;
                    }
                    }
                  bignum_double (&ff);
                  bignum_double (&ff);
                }
                }
            }
            }
          else
          else
            {
            {
              tt.a = tt.b = 36, tt.dat[36] = 2;
              tt.a = tt.b = 36, tt.dat[36] = 2;
              for (exp = 0x3fe; bignum_compare (&ff, &tt) >= 0; exp++)
              for (exp = 0x3fe; bignum_compare (&ff, &tt) >= 0; exp++)
                bignum_double (&tt);
                bignum_double (&tt);
              for (k = 54; k; k--)
              for (k = 54; k; k--)
                {
                {
                  bignum_double (&ff);
                  bignum_double (&ff);
                  if (bignum_compare (&ff, &tt) >= 0)
                  if (bignum_compare (&ff, &tt) >= 0)
                    {
                    {
                      if (k >= 32)
                      if (k >= 32)
                        val.h |= 1 << (k - 32);
                        val.h |= 1 << (k - 32);
                      else
                      else
                        val.l |= 1 << k;
                        val.l |= 1 << k;
                      bignum_dec (&ff, &tt, 1000000000);
                      bignum_dec (&ff, &tt, 1000000000);
                      if (ff.a == bignum_prec - 1)
                      if (ff.a == bignum_prec - 1)
                        break;
                        break;
                    }
                    }
                }
                }
            }
            }
          if (k == 0)
          if (k == 0)
            val.l |= 1;
            val.l |= 1;
 
 
/*:83*/
/*:83*/
#line 1463 "./mmix-arith.w"
#line 1463 "./mmix-arith.w"
          ;
          ;
        packit:         /*84: */
        packit:         /*84: */
#line 1559 "./mmix-arith.w"
#line 1559 "./mmix-arith.w"
 
 
          val = fpack (val, exp, sign, ROUND_NEAR);
          val = fpack (val, exp, sign, ROUND_NEAR);
          if (NaN)
          if (NaN)
            {
            {
              if ((val.h & 0x7fffffff) == 0x40000000)
              if ((val.h & 0x7fffffff) == 0x40000000)
                val.h |= 0x7fffffff, val.l = 0xffffffff;
                val.h |= 0x7fffffff, val.l = 0xffffffff;
              else if ((val.h & 0x7fffffff) == 0x3ff00000 && !val.l)
              else if ((val.h & 0x7fffffff) == 0x3ff00000 && !val.l)
                val.h |= 0x40000000, val.l = 1;
                val.h |= 0x40000000, val.l = 1;
              else
              else
                val.h |= 0x40000000;
                val.h |= 0x40000000;
            }
            }
 
 
/*:84*/
/*:84*/
#line 1464 "./mmix-arith.w"
#line 1464 "./mmix-arith.w"
          ;
          ;
          return 1;
          return 1;
        }
        }
 
 
/*:78*/
/*:78*/
#line 1410 "./mmix-arith.w"
#line 1410 "./mmix-arith.w"
      ;
      ;
      if (sign == '-')
      if (sign == '-')
        val = ominus (zero_octa, val);
        val = ominus (zero_octa, val);
      return 0;
      return 0;
    }
    }
 
 
/*:73*/
/*:73*/
#line 1353 "./mmix-arith.w"
#line 1353 "./mmix-arith.w"
  ;
  ;
  if (NaN)                      /*71: */
  if (NaN)                      /*71: */
#line 1368 "./mmix-arith.w"
#line 1368 "./mmix-arith.w"
 
 
    {
    {
      next_char = p;
      next_char = p;
      val.h = 0x600000, exp = 0x3fe;
      val.h = 0x600000, exp = 0x3fe;
      goto packit;
      goto packit;
    }
    }
 
 
/*:71*/
/*:71*/
#line 1354 "./mmix-arith.w"
#line 1354 "./mmix-arith.w"
  ;
  ;
  if (strncmp (p, "Inf", 3) == 0)        /*72: */
  if (strncmp (p, "Inf", 3) == 0)        /*72: */
#line 1375 "./mmix-arith.w"
#line 1375 "./mmix-arith.w"
 
 
    {
    {
      next_char = p + 3;
      next_char = p + 3;
      goto make_it_infinite;
      goto make_it_infinite;
    }
    }
 
 
/*:72*/
/*:72*/
#line 1355 "./mmix-arith.w"
#line 1355 "./mmix-arith.w"
  ;
  ;
no_const_found:next_char = s;
no_const_found:next_char = s;
  return -1;
  return -1;
}
}
 
 
       /*:68*//*82: */
       /*:68*//*82: */
#line 1511 "./mmix-arith.w"
#line 1511 "./mmix-arith.w"
 
 
static void
static void
bignum_double (f)
bignum_double (f)
     bignum *f;
     bignum *f;
{
{
  register tetra *p, *q;
  register tetra *p, *q;
  register int x, carry;
  register int x, carry;
  for (p = &f->dat[f->b], q = &f->dat[f->a], carry = 0; p >= q; p--)
  for (p = &f->dat[f->b], q = &f->dat[f->a], carry = 0; p >= q; p--)
    {
    {
      x = *p + *p + carry;
      x = *p + *p + carry;
      if (x >= 1000000000)
      if (x >= 1000000000)
        carry = 1, *p = x - 1000000000;
        carry = 1, *p = x - 1000000000;
      else
      else
        carry = 0, *p = x;
        carry = 0, *p = x;
    }
    }
  *p = carry;
  *p = carry;
  if (carry)
  if (carry)
    f->a--;
    f->a--;
  if (f->dat[f->b] == 0 && f->b > f->a)
  if (f->dat[f->b] == 0 && f->b > f->a)
    f->b--;
    f->b--;
}
}
 
 
       /*:82*//*85: */
       /*:82*//*85: */
#line 1575 "./mmix-arith.w"
#line 1575 "./mmix-arith.w"
 
 
int fcomp ARGS ((octa, octa));
int fcomp ARGS ((octa, octa));
int
int
fcomp (y, z)
fcomp (y, z)
     octa y, z;
     octa y, z;
{
{
  ftype yt, zt;
  ftype yt, zt;
  int ye, ze;
  int ye, ze;
  char ys, zs;
  char ys, zs;
  octa yf, zf;
  octa yf, zf;
  register int x;
  register int x;
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
    case 4 * nan + nan:
    case 4 * nan + nan:
    case 4 * zro + nan:
    case 4 * zro + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * inf + nan:
    case 4 * inf + nan:
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + inf:
    case 4 * nan + inf:
      return 2;
      return 2;
    case 4 * zro + zro:
    case 4 * zro + zro:
      return 0;
      return 0;
    case 4 * zro + num:
    case 4 * zro + num:
    case 4 * num + zro:
    case 4 * num + zro:
    case 4 * zro + inf:
    case 4 * zro + inf:
    case 4 * inf + zro:
    case 4 * inf + zro:
    case 4 * num + num:
    case 4 * num + num:
    case 4 * num + inf:
    case 4 * num + inf:
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + inf:
    case 4 * inf + inf:
      if (ys != zs)
      if (ys != zs)
        x = 1;
        x = 1;
      else if (y.h > z.h)
      else if (y.h > z.h)
        x = 1;
        x = 1;
      else if (y.h < z.h)
      else if (y.h < z.h)
        x = -1;
        x = -1;
      else if (y.l > z.l)
      else if (y.l > z.l)
        x = 1;
        x = 1;
      else if (y.l < z.l)
      else if (y.l < z.l)
        x = -1;
        x = -1;
      else
      else
        return 0;
        return 0;
      break;
      break;
    }
    }
  return (ys == '-' ? -x : x);
  return (ys == '-' ? -x : x);
}
}
 
 
       /*:85*//*86: */
       /*:85*//*86: */
#line 1608 "./mmix-arith.w"
#line 1608 "./mmix-arith.w"
 
 
octa fintegerize ARGS ((octa, int));
octa fintegerize ARGS ((octa, int));
octa
octa
fintegerize (z, r)
fintegerize (z, r)
     octa z;
     octa z;
     int r;
     int r;
{
{
  ftype zt;
  ftype zt;
  int ze;
  int ze;
  char zs;
  char zs;
  octa xf, zf;
  octa xf, zf;
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  if (!r)
  if (!r)
    r = cur_round;
    r = cur_round;
  switch (zt)
  switch (zt)
    {
    {
    case nan:
    case nan:
      if (!(z.h & 0x80000))
      if (!(z.h & 0x80000))
        {
        {
          exceptions |= I_BIT;
          exceptions |= I_BIT;
          z.h |= 0x80000;
          z.h |= 0x80000;
        }
        }
    case inf:
    case inf:
    case zro:
    case zro:
      return z;
      return z;
    case num:                   /*87: */
    case num:                   /*87: */
#line 1627 "./mmix-arith.w"
#line 1627 "./mmix-arith.w"
 
 
      if (ze >= 1074)
      if (ze >= 1074)
        return fpack (zf, ze, zs, ROUND_OFF);
        return fpack (zf, ze, zs, ROUND_OFF);
      if (ze <= 1020)
      if (ze <= 1020)
        xf.h = 0, xf.l = 1;
        xf.h = 0, xf.l = 1;
      else
      else
        {
        {
          octa oo;
          octa oo;
          xf = shift_right (zf, 1074 - ze, 1);
          xf = shift_right (zf, 1074 - ze, 1);
          oo = shift_left (xf, 1074 - ze);
          oo = shift_left (xf, 1074 - ze);
          if (oo.l != zf.l || oo.h != zf.h)
          if (oo.l != zf.l || oo.h != zf.h)
            xf.l |= 1;
            xf.l |= 1;
 
 
        }
        }
      switch (r)
      switch (r)
        {
        {
        case ROUND_DOWN:
        case ROUND_DOWN:
          if (zs == '-')
          if (zs == '-')
            xf = incr (xf, 3);
            xf = incr (xf, 3);
          break;
          break;
        case ROUND_UP:
        case ROUND_UP:
          if (zs != '-')
          if (zs != '-')
            xf = incr (xf, 3);
            xf = incr (xf, 3);
        case ROUND_OFF:
        case ROUND_OFF:
          break;
          break;
        case ROUND_NEAR:
        case ROUND_NEAR:
          xf = incr (xf, xf.l & 4 ? 2 : 1);
          xf = incr (xf, xf.l & 4 ? 2 : 1);
          break;
          break;
        }
        }
      xf.l &= 0xfffffffc;
      xf.l &= 0xfffffffc;
      if (ze >= 1022)
      if (ze >= 1022)
        return fpack (shift_left (xf, 1074 - ze), ze, zs, ROUND_OFF);
        return fpack (shift_left (xf, 1074 - ze), ze, zs, ROUND_OFF);
      if (xf.l)
      if (xf.l)
        xf.h = 0x3ff00000, xf.l = 0;
        xf.h = 0x3ff00000, xf.l = 0;
      if (zs == '-')
      if (zs == '-')
        xf.h |= sign_bit;
        xf.h |= sign_bit;
      return xf;
      return xf;
 
 
/*:87*/
/*:87*/
#line 1623 "./mmix-arith.w"
#line 1623 "./mmix-arith.w"
      ;
      ;
    }
    }
}
}
 
 
       /*:86*//*88: */
       /*:86*//*88: */
#line 1650 "./mmix-arith.w"
#line 1650 "./mmix-arith.w"
 
 
octa fixit ARGS ((octa, int));
octa fixit ARGS ((octa, int));
octa
octa
fixit (z, r)
fixit (z, r)
     octa z;
     octa z;
     int r;
     int r;
{
{
  ftype zt;
  ftype zt;
  int ze;
  int ze;
  char zs;
  char zs;
  octa zf, o;
  octa zf, o;
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  if (!r)
  if (!r)
    r = cur_round;
    r = cur_round;
  switch (zt)
  switch (zt)
    {
    {
    case nan:
    case nan:
    case inf:
    case inf:
      exceptions |= I_BIT;
      exceptions |= I_BIT;
      return z;
      return z;
    case zro:
    case zro:
      return zero_octa;
      return zero_octa;
    case num:
    case num:
      if (funpack (fintegerize (z, r), &zf, &ze, &zs) == zro)
      if (funpack (fintegerize (z, r), &zf, &ze, &zs) == zro)
        return zero_octa;
        return zero_octa;
      if (ze <= 1076)
      if (ze <= 1076)
        o = shift_right (zf, 1076 - ze, 1);
        o = shift_right (zf, 1076 - ze, 1);
      else
      else
        {
        {
          if (ze > 1085 || (ze == 1085 && (zf.h > 0x400000 ||
          if (ze > 1085 || (ze == 1085 && (zf.h > 0x400000 ||
                                           (zf.h == 0x400000
                                           (zf.h == 0x400000
                                            && (zf.l || zs != '-')))))
                                            && (zf.l || zs != '-')))))
            exceptions |= W_BIT;
            exceptions |= W_BIT;
          if (ze >= 1140)
          if (ze >= 1140)
            return zero_octa;
            return zero_octa;
          o = shift_left (zf, ze - 1076);
          o = shift_left (zf, ze - 1076);
        }
        }
      return (zs == '-' ? ominus (zero_octa, o) : o);
      return (zs == '-' ? ominus (zero_octa, o) : o);
    }
    }
}
}
 
 
       /*:88*//*89: */
       /*:88*//*89: */
#line 1681 "./mmix-arith.w"
#line 1681 "./mmix-arith.w"
 
 
octa floatit ARGS ((octa, int, int, int));
octa floatit ARGS ((octa, int, int, int));
octa
octa
floatit (z, r, u, p)
floatit (z, r, u, p)
     octa z;
     octa z;
     int r;
     int r;
     int u;
     int u;
     int p;
     int p;
{
{
  int e;
  int e;
  char s;
  char s;
  register int t;
  register int t;
  exceptions = 0;
  exceptions = 0;
  if (!z.h && !z.l)
  if (!z.h && !z.l)
    return zero_octa;
    return zero_octa;
  if (!r)
  if (!r)
    r = cur_round;
    r = cur_round;
  if (!u && (z.h & sign_bit))
  if (!u && (z.h & sign_bit))
    s = '-', z = ominus (zero_octa, z);
    s = '-', z = ominus (zero_octa, z);
  else
  else
    s = '+';
    s = '+';
  e = 1076;
  e = 1076;
  while (z.h < 0x400000)
  while (z.h < 0x400000)
    e--, z = shift_left (z, 1);
    e--, z = shift_left (z, 1);
  while (z.h >= 0x800000)
  while (z.h >= 0x800000)
    {
    {
      e++;
      e++;
      t = z.l & 1;
      t = z.l & 1;
      z = shift_right (z, 1, 1);
      z = shift_right (z, 1, 1);
      z.l |= t;
      z.l |= t;
    }
    }
  if (p)                        /*90: */
  if (p)                        /*90: */
#line 1707 "./mmix-arith.w"
#line 1707 "./mmix-arith.w"
 
 
    {
    {
      register int ex;
      register int ex;
      register tetra t;
      register tetra t;
      t = sfpack (z, e, s, r);
      t = sfpack (z, e, s, r);
      ex = exceptions;
      ex = exceptions;
      sfunpack (t, &z, &e, &s);
      sfunpack (t, &z, &e, &s);
      exceptions = ex;
      exceptions = ex;
    }
    }
 
 
/*:90*/
/*:90*/
#line 1703 "./mmix-arith.w"
#line 1703 "./mmix-arith.w"
  ;
  ;
  return fpack (z, e, s, r);
  return fpack (z, e, s, r);
}
}
 
 
       /*:89*//*91: */
       /*:89*//*91: */
#line 1718 "./mmix-arith.w"
#line 1718 "./mmix-arith.w"
 
 
octa froot ARGS ((octa, int));
octa froot ARGS ((octa, int));
octa
octa
froot (z, r)
froot (z, r)
     octa z;
     octa z;
     int r;
     int r;
{
{
  ftype zt;
  ftype zt;
  int ze;
  int ze;
  char zs;
  char zs;
  octa x, xf, rf, zf;
  octa x, xf, rf, zf;
  register int xe, k;
  register int xe, k;
  if (!r)
  if (!r)
    r = cur_round;
    r = cur_round;
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  if (zs == '-' && zt != zro)
  if (zs == '-' && zt != zro)
    exceptions |= I_BIT, x = standard_NaN;
    exceptions |= I_BIT, x = standard_NaN;
  else
  else
    switch (zt)
    switch (zt)
      {
      {
      case nan:
      case nan:
        if (!(z.h & 0x80000))
        if (!(z.h & 0x80000))
          exceptions |= I_BIT, z.h |= 0x80000;
          exceptions |= I_BIT, z.h |= 0x80000;
        return z;
        return z;
      case inf:
      case inf:
      case zro:
      case zro:
        x = z;
        x = z;
        break;
        break;
      case num:         /*92: */
      case num:         /*92: */
#line 1750 "./mmix-arith.w"
#line 1750 "./mmix-arith.w"
 
 
        xf.h = 0, xf.l = 2;
        xf.h = 0, xf.l = 2;
        xe = (ze + 0x3fe) >> 1;
        xe = (ze + 0x3fe) >> 1;
        if (ze & 1)
        if (ze & 1)
          zf = shift_left (zf, 1);
          zf = shift_left (zf, 1);
        rf.h = 0, rf.l = (zf.h >> 22) - 1;
        rf.h = 0, rf.l = (zf.h >> 22) - 1;
        for (k = 53; k; k--)
        for (k = 53; k; k--)
          {
          {
            rf = shift_left (rf, 2);
            rf = shift_left (rf, 2);
            xf = shift_left (xf, 1);
            xf = shift_left (xf, 1);
            if (k >= 43)
            if (k >= 43)
              rf = incr (rf, (zf.h >> (2 * (k - 43))) & 3);
              rf = incr (rf, (zf.h >> (2 * (k - 43))) & 3);
            else if (k >= 27)
            else if (k >= 27)
              rf = incr (rf, (zf.l >> (2 * (k - 27))) & 3);
              rf = incr (rf, (zf.l >> (2 * (k - 27))) & 3);
            if ((rf.l > xf.l && rf.h >= xf.h) || rf.h > xf.h)
            if ((rf.l > xf.l && rf.h >= xf.h) || rf.h > xf.h)
              {
              {
                xf.l++;
                xf.l++;
                rf = ominus (rf, xf);
                rf = ominus (rf, xf);
                xf.l++;
                xf.l++;
              }
              }
          }
          }
        if (rf.h || rf.l)
        if (rf.h || rf.l)
          xf.l++;
          xf.l++;
        return fpack (xf, xe, '+', r);
        return fpack (xf, xe, '+', r);
 
 
/*:92*/
/*:92*/
#line 1736 "./mmix-arith.w"
#line 1736 "./mmix-arith.w"
        ;
        ;
      }
      }
  if (zs == '-')
  if (zs == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
       /*:91*//*93: */
       /*:91*//*93: */
#line 1774 "./mmix-arith.w"
#line 1774 "./mmix-arith.w"
 
 
octa fremstep ARGS ((octa, octa, int));
octa fremstep ARGS ((octa, octa, int));
octa
octa
fremstep (y, z, delta)
fremstep (y, z, delta)
     octa y, z;
     octa y, z;
     int delta;
     int delta;
{
{
  ftype yt, zt;
  ftype yt, zt;
  int ye, ze;
  int ye, ze;
  char xs, ys, zs;
  char xs, ys, zs;
  octa x, xf, yf, zf;
  octa x, xf, yf, zf;
  register int xe, thresh, odd;
  register int xe, thresh, odd;
  yt = funpack (y, &yf, &ye, &ys);
  yt = funpack (y, &yf, &ye, &ys);
  zt = funpack (z, &zf, &ze, &zs);
  zt = funpack (z, &zf, &ze, &zs);
  switch (4 * yt + zt)
  switch (4 * yt + zt)
    {
    {
/*42:*/
/*42:*/
#line 731 "./mmix-arith.w"
#line 731 "./mmix-arith.w"
 
 
    case 4 * nan + nan:
    case 4 * nan + nan:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT;
        exceptions |= I_BIT;
    case 4 * zro + nan:
    case 4 * zro + nan:
    case 4 * num + nan:
    case 4 * num + nan:
    case 4 * inf + nan:
    case 4 * inf + nan:
      if (!(z.h & 0x80000))
      if (!(z.h & 0x80000))
        exceptions |= I_BIT, z.h |= 0x80000;
        exceptions |= I_BIT, z.h |= 0x80000;
      return z;
      return z;
    case 4 * nan + zro:
    case 4 * nan + zro:
    case 4 * nan + num:
    case 4 * nan + num:
    case 4 * nan + inf:
    case 4 * nan + inf:
      if (!(y.h & 0x80000))
      if (!(y.h & 0x80000))
        exceptions |= I_BIT, y.h |= 0x80000;
        exceptions |= I_BIT, y.h |= 0x80000;
      return y;
      return y;
 
 
/*:42*/
/*:42*/
#line 1788 "./mmix-arith.w"
#line 1788 "./mmix-arith.w"
      ;
      ;
    case 4 * zro + zro:
    case 4 * zro + zro:
    case 4 * num + zro:
    case 4 * num + zro:
    case 4 * inf + zro:
    case 4 * inf + zro:
    case 4 * inf + num:
    case 4 * inf + num:
    case 4 * inf + inf:
    case 4 * inf + inf:
      x = standard_NaN;
      x = standard_NaN;
      exceptions |= I_BIT;
      exceptions |= I_BIT;
      break;
      break;
    case 4 * zro + num:
    case 4 * zro + num:
    case 4 * zro + inf:
    case 4 * zro + inf:
    case 4 * num + inf:
    case 4 * num + inf:
      return y;
      return y;
    case 4 * num + num: /*94: */
    case 4 * num + num: /*94: */
#line 1809 "./mmix-arith.w"
#line 1809 "./mmix-arith.w"
 
 
      odd = 0;
      odd = 0;
      thresh = ye - delta;
      thresh = ye - delta;
      if (thresh < ze)
      if (thresh < ze)
        thresh = ze;
        thresh = ze;
      while (ye >= thresh)      /*95: */
      while (ye >= thresh)      /*95: */
#line 1830 "./mmix-arith.w"
#line 1830 "./mmix-arith.w"
 
 
        {
        {
          if (yf.h == zf.h && yf.l == zf.l)
          if (yf.h == zf.h && yf.l == zf.l)
            goto zero_out;
            goto zero_out;
          if (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))
          if (yf.h < zf.h || (yf.h == zf.h && yf.l < zf.l))
            {
            {
              if (ye == ze)
              if (ye == ze)
                goto try_complement;
                goto try_complement;
              ye--, yf = shift_left (yf, 1);
              ye--, yf = shift_left (yf, 1);
            }
            }
          yf = ominus (yf, zf);
          yf = ominus (yf, zf);
          if (ye == ze)
          if (ye == ze)
            odd = 1;
            odd = 1;
          while (yf.h < 0x400000)
          while (yf.h < 0x400000)
            ye--, yf = shift_left (yf, 1);
            ye--, yf = shift_left (yf, 1);
        }
        }
 
 
/*:95*/
/*:95*/
#line 1815 "./mmix-arith.w"
#line 1815 "./mmix-arith.w"
      ;
      ;
      if (ye >= ze)
      if (ye >= ze)
        {
        {
          exceptions |= E_BIT;
          exceptions |= E_BIT;
          return fpack (yf, ye, ys, ROUND_OFF);
          return fpack (yf, ye, ys, ROUND_OFF);
        }
        }
      if (ye < ze - 1)
      if (ye < ze - 1)
        return fpack (yf, ye, ys, ROUND_OFF);
        return fpack (yf, ye, ys, ROUND_OFF);
      yf = shift_right (yf, 1, 1);
      yf = shift_right (yf, 1, 1);
    try_complement:xf = ominus (zf, yf), xe = ze, xs = '+' + '-' - ys;
    try_complement:xf = ominus (zf, yf), xe = ze, xs = '+' + '-' - ys;
      if (xf.h > yf.h
      if (xf.h > yf.h
          || (xf.h == yf.h && (xf.l > yf.l || (xf.l == yf.l && !odd))))
          || (xf.h == yf.h && (xf.l > yf.l || (xf.l == yf.l && !odd))))
        xf = yf, xs = ys;
        xf = yf, xs = ys;
      while (xf.h < 0x400000)
      while (xf.h < 0x400000)
        xe--, xf = shift_left (xf, 1);
        xe--, xf = shift_left (xf, 1);
      return fpack (xf, xe, xs, ROUND_OFF);
      return fpack (xf, xe, xs, ROUND_OFF);
 
 
/*:94*/
/*:94*/
#line 1793 "./mmix-arith.w"
#line 1793 "./mmix-arith.w"
      ;
      ;
    zero_out:x = zero_octa;
    zero_out:x = zero_octa;
    }
    }
  if (ys == '-')
  if (ys == '-')
    x.h |= sign_bit;
    x.h |= sign_bit;
  return x;
  return x;
}
}
 
 
/*:93*/
/*:93*/
#line 41 "./mmix-arith.w"
#line 41 "./mmix-arith.w"
 
 
 
 
/*:1*/
/*:1*/
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.