#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*/
|
|
|