#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{false,true}bool;
|
typedef enum{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{tetra h,l;}octa;
|
typedef struct{tetra h,l;}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{zro,num,inf,nan}ftype;
|
typedef enum{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 oplus(y,z)
|
octa 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)x.h++;
|
if(x.l<y.l)x.h++;
|
return x;
|
return x;
|
}
|
}
|
|
|
octa ominus ARGS((octa,octa));
|
octa ominus ARGS((octa,octa));
|
octa ominus(y,z)
|
octa 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)x.h--;
|
if(x.l> y.l)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 incr(y,delta)
|
octa incr(y,delta)
|
octa y;
|
octa y;
|
int delta;
|
int delta;
|
{octa x;
|
{octa x;
|
x.h= y.h;x.l= y.l+delta;
|
x.h= y.h;x.l= y.l+delta;
|
if(delta>=0){
|
if(delta>=0){
|
if(x.l<y.l)x.h++;
|
if(x.l<y.l)x.h++;
|
}else if(x.l> y.l)x.h--;
|
}else if(x.l> y.l)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 shift_left(y,s)
|
octa shift_left(y,s)
|
octa y;
|
octa y;
|
int s;
|
int s;
|
{
|
{
|
while(s>=32)y.h= y.l,y.l= 0,s-= 32;
|
while(s>=32)y.h= y.l,y.l= 0,s-= 32;
|
if(s){register tetra yhl= y.h<<s,ylh= y.l>>(32-s);
|
if(s){register tetra yhl= y.h<<s,ylh= y.l>>(32-s);
|
y.h= yhl+ylh;y.l<<= s;
|
y.h= yhl+ylh;y.l<<= s;
|
}
|
}
|
return y;
|
return y;
|
}
|
}
|
|
|
octa shift_right ARGS((octa,int,int));
|
octa shift_right ARGS((octa,int,int));
|
octa shift_right(y,s,u)
|
octa shift_right(y,s,u)
|
octa y;
|
octa y;
|
int s,u;
|
int s,u;
|
{
|
{
|
while(s>=32)y.l= y.h,y.h= (u?0:-(y.h>>31)),s-= 32;
|
while(s>=32)y.l= y.h,y.h= (u?0:-(y.h>>31)),s-= 32;
|
if(s){register tetra yhl= y.h<<(32-s),ylh= y.l>>s;
|
if(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.l= yhl+ylh;
|
y.h= (u?0:(-(y.h>>31))<<(32-s))+(y.h>>s);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 omult(y,z)
|
octa 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]= y.l&0xffff;
|
u[3]= y.h>>16,u[2]= y.h&0xffff,u[1]= y.l>>16,u[0]= y.l&0xffff;
|
v[3]= z.h>>16,v[2]= z.h&0xffff,v[1]= z.l>>16,v[0]= z.l&0xffff;
|
v[3]= z.h>>16,v[2]= z.h&0xffff,v[1]= z.l>>16,v[0]= z.l&0xffff;
|
|
|
/*:10*/
|
/*:10*/
|
#line 159 "./mmix-arith.w"
|
#line 159 "./mmix-arith.w"
|
;
|
;
|
for(j= 0;j<4;j++)w[j]= 0;
|
for(j= 0;j<4;j++)w[j]= 0;
|
for(j= 0;j<4;j++)
|
for(j= 0;j<4;j++)
|
if(!v[j])w[j+4]= 0;
|
if(!v[j])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 signed_omult(y,z)
|
octa 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)aux= ominus(aux,z);
|
if(y.h&sign_bit)aux= ominus(aux,z);
|
if(z.h&sign_bit)aux= ominus(aux,y);
|
if(z.h&sign_bit)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 odiv(x,y,z)
|
octa 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;return x;
|
aux= y;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]= x.l&0xffff;
|
u[7]= x.h>>16,u[6]= x.h&0xffff,u[5]= x.l>>16,u[4]= x.l&0xffff;
|
u[3]= y.h>>16,u[2]= y.h&0xffff,u[1]= y.l>>16,u[0]= y.l&0xffff;
|
u[3]= y.h>>16,u[2]= y.h&0xffff,u[1]= y.l>>16,u[0]= y.l&0xffff;
|
v[3]= z.h>>16,v[2]= z.h&0xffff,v[1]= z.l>>16,v[0]= z.l&0xffff;
|
v[3]= z.h>>16,v[2]= z.h&0xffff,v[1]= z.l>>16,v[0]= 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)while(qhat==0x10000||qhat*vmh> (rhat<<16)+u[j+n-2]){
|
if(n> 1)while(qhat==0x10000||qhat*vmh> (rhat<<16)+u[j+n-2]){
|
qhat--,rhat+= vh;
|
qhat--,rhat+= vh;
|
if(rhat>=0x10000)break;
|
if(rhat>=0x10000)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--)u[j]= 0;
|
for(j= 3;j>=n;j--)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 signed_odiv(y,z)
|
octa 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)sy= 2,yy= ominus(zero_octa,y);
|
if(y.h&sign_bit)sy= 2,yy= ominus(zero_octa,y);
|
else sy= 0,yy= y;
|
else sy= 0,yy= y;
|
if(z.h&sign_bit)sz= 1,zz= ominus(zero_octa,z);
|
if(z.h&sign_bit)sz= 1,zz= ominus(zero_octa,z);
|
else sz= 0,zz= z;
|
else 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:aux= ominus(zero_octa,aux);
|
case 2+1:aux= ominus(zero_octa,aux);
|
if(q.h==sign_bit)overflow= true;
|
if(q.h==sign_bit)overflow= true;
|
case 0+0:return q;
|
case 0+0:return q;
|
case 2+0:if(aux.h||aux.l)aux= ominus(zz,aux);
|
case 2+0:if(aux.h||aux.l)aux= ominus(zz,aux);
|
goto negate_q;
|
goto negate_q;
|
case 0+1:if(aux.h||aux.l)aux= ominus(aux,zz);
|
case 0+1:if(aux.h||aux.l)aux= ominus(aux,zz);
|
negate_q:if(aux.h||aux.l)return ominus(neg_one,q);
|
negate_q:if(aux.h||aux.l)return ominus(neg_one,q);
|
else return ominus(zero_octa,q);
|
else 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 oand(y,z)
|
octa oand(y,z)
|
octa y,z;
|
octa y,z;
|
{octa x;
|
{octa x;
|
x.h= y.h&z.h;x.l= y.l&z.l;
|
x.h= y.h&z.h;x.l= y.l&z.l;
|
return x;
|
return x;
|
}
|
}
|
|
|
octa oandn ARGS((octa,octa));
|
octa oandn ARGS((octa,octa));
|
octa oandn(y,z)
|
octa oandn(y,z)
|
octa y,z;
|
octa y,z;
|
{octa x;
|
{octa x;
|
x.h= y.h&~z.h;x.l= y.l&~z.l;
|
x.h= y.h&~z.h;x.l= y.l&~z.l;
|
return x;
|
return x;
|
}
|
}
|
|
|
octa oxor ARGS((octa,octa));
|
octa oxor ARGS((octa,octa));
|
octa oxor(y,z)
|
octa oxor(y,z)
|
octa y,z;
|
octa y,z;
|
{octa x;
|
{octa x;
|
x.h= y.h^z.h;x.l= y.l^z.l;
|
x.h= y.h^z.h;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 count_bits(x)
|
int 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 byte_diff(y,z)
|
tetra 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 wyde_diff(y,z)
|
tetra 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 bool_mult(y,z,xor)
|
octa 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;k++,o= shift_right(o,8,1))
|
for(k= 0,o= y,x= zero_octa;o.h||o.l;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)x.h^= a&c,x.l^= b&c;
|
if(xor)x.h^= a&c,x.l^= b&c;
|
else x.h|= a&c,x.l|= b&c;
|
else 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 fpack(f,e,s,r)
|
octa 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)e= 0x7ff,o= zero_octa;
|
if(e> 0x7fd)e= 0x7ff,o= zero_octa;
|
else{
|
else{
|
if(e<0){
|
if(e<0){
|
if(e<-54)o.h= 0,o.l= 1;
|
if(e<-54)o.h= 0,o.l= 1;
|
else{octa oo;
|
else{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)o.l|= 1;
|
if(oo.l!=f.l||oo.h!=f.h)o.l|= 1;
|
|
|
}
|
}
|
e= 0;
|
e= 0;
|
}else o= f;
|
}else o= f;
|
}
|
}
|
/*33:*/
|
/*33:*/
|
#line 533 "./mmix-arith.w"
|
#line 533 "./mmix-arith.w"
|
|
|
if(o.l&3)exceptions|= X_BIT;
|
if(o.l&3)exceptions|= X_BIT;
|
switch(r){
|
switch(r){
|
case ROUND_DOWN:if(s=='-')o= incr(o,3);break;
|
case ROUND_DOWN:if(s=='-')o= incr(o,3);break;
|
case ROUND_UP:if(s!='-')o= incr(o,3);
|
case ROUND_UP:if(s!='-')o= incr(o,3);
|
case ROUND_OFF:break;
|
case ROUND_OFF:break;
|
case ROUND_NEAR:o= incr(o,o.l&4?2:1);break;
|
case ROUND_NEAR:o= incr(o,o.l&4?2:1);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)exceptions|= O_BIT+X_BIT;
|
if(o.h>=0x7ff00000)exceptions|= O_BIT+X_BIT;
|
else if(o.h<0x100000)exceptions|= U_BIT;
|
else if(o.h<0x100000)exceptions|= U_BIT;
|
if(s=='-')o.h|= sign_bit;
|
if(s=='-')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 sfpack(f,e,s,r)
|
tetra 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)e= 0x47f,o= 0;
|
if(e> 0x47d)e= 0x47f,o= 0;
|
else{
|
else{
|
o= shift_left(f,3).h;
|
o= shift_left(f,3).h;
|
if(f.l&0x1fffffff)o|= 1;
|
if(f.l&0x1fffffff)o|= 1;
|
if(e<0x380){
|
if(e<0x380){
|
if(e<0x380-25)o= 1;
|
if(e<0x380-25)o= 1;
|
else{register tetra o0,oo;
|
else{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)o|= 1;
|
if(oo!=o0)o|= 1;
|
|
|
}
|
}
|
e= 0x380;
|
e= 0x380;
|
}
|
}
|
}
|
}
|
/*35:*/
|
/*35:*/
|
#line 579 "./mmix-arith.w"
|
#line 579 "./mmix-arith.w"
|
|
|
if(o&3)exceptions|= X_BIT;
|
if(o&3)exceptions|= X_BIT;
|
switch(r){
|
switch(r){
|
case ROUND_DOWN:if(s=='-')o+= 3;break;
|
case ROUND_DOWN:if(s=='-')o+= 3;break;
|
case ROUND_UP:if(s!='-')o+= 3;
|
case ROUND_UP:if(s!='-')o+= 3;
|
case ROUND_OFF:break;
|
case ROUND_OFF:break;
|
case ROUND_NEAR:o+= (o&4?2:1);break;
|
case ROUND_NEAR:o+= (o&4?2:1);break;
|
}
|
}
|
o= o>>2;
|
o= o>>2;
|
o+= (e-0x380)<<23;
|
o+= (e-0x380)<<23;
|
if(o>=0x7f800000)exceptions|= O_BIT+X_BIT;
|
if(o>=0x7f800000)exceptions|= O_BIT+X_BIT;
|
else if(o<0x100000)exceptions|= U_BIT;
|
else if(o<0x100000)exceptions|= U_BIT;
|
if(s=='-')o|= sign_bit;
|
if(s=='-')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 funpack(x,f,e,s)
|
ftype 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;return zro;
|
*e= zero_exponent;return zro;
|
}
|
}
|
do{ee--;*f= shift_left(*f,1);}while(!(f->h&0x400000));
|
do{ee--;*f= shift_left(*f,1);}while(!(f->h&0x400000));
|
*e= ee;return num;
|
*e= ee;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 sfunpack(x,f,e,s)
|
ftype 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;return zro;
|
*e= zero_exponent;return zro;
|
}
|
}
|
do{ee--;*f= shift_left(*f,1);}while(!(f->h&0x400000));
|
do{ee--;*f= shift_left(*f,1);}while(!(f->h&0x400000));
|
*e= ee+0x380;return num;
|
*e= ee+0x380;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 load_sf(z)
|
octa load_sf(z)
|
tetra z;
|
tetra z;
|
{
|
{
|
octa f,x;int e;char s;ftype t;
|
octa f,x;int e;char s;ftype t;
|
t= sfunpack(z,&f,&e,&s);
|
t= sfunpack(z,&f,&e,&s);
|
switch(t){
|
switch(t){
|
case zro:x= zero_octa;break;
|
case zro:x= zero_octa;break;
|
case num:return fpack(f,e,s,ROUND_OFF);
|
case num:return fpack(f,e,s,ROUND_OFF);
|
case inf:x= inf_octa;break;
|
case inf:x= inf_octa;break;
|
case nan:x= shift_right(f,2,1);x.h|= 0x7ff00000;break;
|
case nan:x= shift_right(f,2,1);x.h|= 0x7ff00000;break;
|
}
|
}
|
if(s=='-')x.h|= sign_bit;
|
if(s=='-')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 store_sf(x)
|
tetra store_sf(x)
|
octa x;
|
octa x;
|
{
|
{
|
octa f;tetra z;int e;char s;ftype t;
|
octa f;tetra z;int e;char s;ftype t;
|
t= funpack(x,&f,&e,&s);
|
t= funpack(x,&f,&e,&s);
|
switch(t){
|
switch(t){
|
case zro:z= 0;break;
|
case zro:z= 0;break;
|
case num:return sfpack(f,e,s,cur_round);
|
case num:return sfpack(f,e,s,cur_round);
|
case inf:z= 0x7f800000;break;
|
case inf:z= 0x7f800000;break;
|
case nan:if(!(f.h&0x200000)){
|
case nan:if(!(f.h&0x200000)){
|
f.h|= 0x200000;exceptions|= I_BIT;
|
f.h|= 0x200000;exceptions|= I_BIT;
|
}
|
}
|
z= 0x7f800000|(f.h<<1)|(f.l>>31);break;
|
z= 0x7f800000|(f.h<<1)|(f.l>>31);break;
|
}
|
}
|
if(s=='-')z|= sign_bit;
|
if(s=='-')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 fmult(y,z)
|
octa 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:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*nan+nan:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
return z;
|
return z;
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
if(!(y.h&0x80000))exceptions|= I_BIT,y.h|= 0x80000;
|
if(!(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+num:case 4*num+zro:x= zero_octa;break;
|
case 4*zro+zro:case 4*zro+num:case 4*num+zro:x= zero_octa;break;
|
case 4*num+inf:case 4*inf+num:case 4*inf+inf:x= inf_octa;break;
|
case 4*num+inf:case 4*inf+num:case 4*inf+inf:x= inf_octa;break;
|
case 4*zro+inf:case 4*inf+zro:x= standard_NaN;
|
case 4*zro+inf:case 4*inf+zro:x= standard_NaN;
|
exceptions|= I_BIT;break;
|
exceptions|= I_BIT;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)xf= aux;
|
if(aux.h>=0x400000)xf= aux;
|
else xf= shift_left(aux,1),xe--;
|
else xf= shift_left(aux,1),xe--;
|
if(x.h||x.l)xf.l|= 1;
|
if(x.h||x.l)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=='-')x.h|= sign_bit;
|
if(xs=='-')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 fdivide(y,z)
|
octa 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:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*nan+nan:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
return z;
|
return z;
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
if(!(y.h&0x80000))exceptions|= I_BIT,y.h|= 0x80000;
|
if(!(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+num:case 4*num+inf:x= zero_octa;break;
|
case 4*zro+inf:case 4*zro+num:case 4*num+inf:x= zero_octa;break;
|
case 4*num+zro:exceptions|= Z_BIT;
|
case 4*num+zro:exceptions|= Z_BIT;
|
case 4*inf+num:case 4*inf+zro:x= inf_octa;break;
|
case 4*inf+num:case 4*inf+zro:x= inf_octa;break;
|
case 4*zro+zro:case 4*inf+inf:x= standard_NaN;
|
case 4*zro+zro:case 4*inf+inf:x= standard_NaN;
|
exceptions|= I_BIT;break;
|
exceptions|= I_BIT;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)xf.l|= 1;
|
if(aux.h||aux.l)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=='-')x.h|= sign_bit;
|
if(xs=='-')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 fplus(y,z)
|
octa 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:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*nan+nan:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
return z;
|
return z;
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
if(!(y.h&0x80000))exceptions|= I_BIT,y.h|= 0x80000;
|
if(!(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:return fpack(zf,ze,zs,ROUND_OFF);break;
|
case 4*zro+num:return fpack(zf,ze,zs,ROUND_OFF);break;
|
case 4*num+zro:return fpack(yf,ye,ys,ROUND_OFF);break;
|
case 4*num+zro:return fpack(yf,ye,ys,ROUND_OFF);break;
|
case 4*inf+inf:if(ys!=zs){
|
case 4*inf+inf:if(ys!=zs){
|
exceptions|= I_BIT;x= standard_NaN;xs= zs;break;
|
exceptions|= I_BIT;x= standard_NaN;xs= zs;break;
|
}
|
}
|
case 4*num+inf:case 4*zro+inf:x= inf_octa;xs= zs;break;
|
case 4*num+inf:case 4*zro+inf:x= inf_octa;xs= zs;break;
|
case 4*inf+num:case 4*inf+zro:x= inf_octa;xs= ys;break;
|
case 4*inf+num:case 4*inf+zro:x= inf_octa;xs= ys;break;
|
case 4*num+num:if(y.h!=(z.h^0x80000000)||y.l!=z.l)
|
case 4*num+num: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||(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 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)zf= shift_right(zf,d,1);
|
if(d<=2)zf= shift_right(zf,d,1);
|
else if(d> 53)zf.h= 0,zf.l= 1;
|
else if(d> 53)zf.h= 0,zf.l= 1;
|
else{
|
else{
|
if(ys!=zs)d--,xe--,yf= shift_left(yf,1);
|
if(ys!=zs)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)zf.l|= 1;
|
if(oo.l!=o.l||oo.h!=o.h)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)xe++,d= xf.l&1,xf= shift_right(xf,1,1),xf.l|= d;
|
if(xf.h>=0x800000)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)xe++,d= xf.l&1,xf= shift_right(xf,1,1),xf.l|= d;
|
if(xf.h>=0x800000)xe++,d= xf.l&1,xf= shift_right(xf,1,1),xf.l|= d;
|
else while(xf.h<0x400000)xe--,xf= shift_left(xf,1);
|
else while(xf.h<0x400000)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:x= zero_octa;
|
case 4*zro+zro:x= zero_octa;
|
xs= (ys==zs?ys:cur_round==ROUND_DOWN?'-':'+');break;
|
xs= (ys==zs?ys:cur_round==ROUND_DOWN?'-':'+');break;
|
}
|
}
|
if(xs=='-')x.h|= sign_bit;
|
if(xs=='-')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 fepscomp(y,z,e,s)
|
int 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=='-')return 2;
|
if(es=='-')return 2;
|
switch(et){
|
switch(et){
|
case nan:return 2;
|
case nan:return 2;
|
case inf:ee= 10000;
|
case inf:ee= 10000;
|
case num:case zro:break;
|
case num:case zro: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+inf:case 4*nan+num:case 4*nan+zro:
|
case 4*nan+nan:case 4*nan+inf:case 4*nan+num:case 4*nan+zro:
|
case 4*inf+nan:case 4*num+nan:case 4*zro+nan:return 2;
|
case 4*inf+nan:case 4*num+nan:case 4*zro+nan:return 2;
|
case 4*inf+inf:return(ys==zs||ee>=1023);
|
case 4*inf+inf:return(ys==zs||ee>=1023);
|
case 4*inf+num:case 4*inf+zro:case 4*num+inf:case 4*zro+inf:
|
case 4*inf+num:case 4*inf+zro:case 4*num+inf:case 4*zro+inf:
|
return(s&&ee>=1022);
|
return(s&&ee>=1022);
|
case 4*zro+zro:return 1;
|
case 4*zro+zro:return 1;
|
case 4*zro+num:case 4*num+zro:if(!s)return 0;
|
case 4*zro+num:case 4*num+zro:if(!s)return 0;
|
case 4*num+num:break;
|
case 4*num+num: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)yf= shift_left(y,2),ye= 0;
|
if(ye<0&&yt!=zro)yf= shift_left(y,2),ye= 0;
|
if(ze<0&&zt!=zro)zf= shift_left(z,2),ze= 0;
|
if(ze<0&&zt!=zro)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)ze= ye;
|
if(ze==zero_exponent)ze= ye;
|
d= ye-ze;
|
d= ye-ze;
|
if(!s)ee-= d;
|
if(!s)ee-= d;
|
if(ee>=1023)return 1;
|
if(ee>=1023)return 1;
|
/*53:*/
|
/*53:*/
|
#line 956 "./mmix-arith.w"
|
#line 956 "./mmix-arith.w"
|
|
|
if(d> 54)o= zero_octa,oo= zf;
|
if(d> 54)o= zero_octa,oo= zf;
|
else o= shift_right(zf,d,1),oo= shift_left(o,d);
|
else 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)return 0;
|
if(ee<1020)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)return 1;
|
if(!o.h&&!o.l)return 1;
|
if(ee<968)return 0;
|
if(ee<968)return 0;
|
if(ee>=1021)ef= shift_left(ef,ee-1021);
|
if(ee>=1021)ef= shift_left(ef,ee-1021);
|
else ef= shift_right(ef,1021-ee,1);
|
else 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 print_float(x)
|
void 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)printf("-");
|
if(x.h&sign_bit)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.");return;
|
printf("0.");return;
|
}
|
}
|
if(e==0x7ff){
|
if(e==0x7ff){
|
printf("Inf");return;
|
printf("Inf");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)e= 1;
|
if(!e)e= 1;
|
else if(e==0x7ff){
|
else if(e==0x7ff){
|
printf("NaN");
|
printf("NaN");
|
if(g.h==0x100000&&g.l==1)return;
|
if(g.h==0x100000&&g.l==1)return;
|
e= 0x3ff;
|
e= 0x3ff;
|
}else f.h|= 0x200000,g.h|= 0x200000;
|
}else 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]= shift_right(f,magic_offset+28-e-28*k,1).l&0xfffffff;
|
ff.dat[k-1]= shift_right(f,magic_offset+28-e-28*k,1).l&0xfffffff;
|
gg.dat[k-1]= shift_right(g,magic_offset+28-e-28*k,1).l&0xfffffff;
|
gg.dat[k-1]= 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]= shift_left(f,e+28*k-(magic_offset-28)).l&0xfffffff;
|
ff.dat[k+1]= shift_left(f,e+28*k-(magic_offset-28)).l&0xfffffff;
|
gg.dat[k+1]= shift_left(g,e+28*k-(magic_offset-28)).l&0xfffffff;
|
gg.dat[k+1]= 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,0x10000000);
|
bignum_dec(&ff,&tt,0x10000000),bignum_dec(&gg,&tt,0x10000000);
|
if(bignum_compare(&gg,&tt)>=open)break;
|
if(bignum_compare(&gg,&tt)>=open)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++)bignum_dec(&gg,&tt,0x10000000);
|
for(k= j;bignum_compare(&gg,&tt)>=open;k++)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)ff.dat[origin]= 0;
|
if(ff.a> origin)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)e--;
|
if(gg.a> origin)e--;
|
else*p++= ff.dat[origin]+'0',ff.dat[origin]= 0,gg.dat[origin]= 0;
|
else*p++= ff.dat[origin]+'0',ff.dat[origin]= 0,gg.dat[origin]= 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)printf(".%0*d%s",-e,0,s);
|
else if(e<0)printf(".%0*d%s",-e,0,s);
|
else if(strlen(s)>=e)printf("%.*s.%s",e,s,s+e);
|
else if(strlen(s)>=e)printf("%.*s.%s",e,s,s+e);
|
else printf("%s%0*d.",s,e-(int)strlen(s),0);
|
else 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 bignum_times_ten(f)
|
static void bignum_times_ten(f)
|
bignum*f;
|
bignum*f;
|
{
|
{
|
register tetra*p,*q;register tetra x,carry;
|
register tetra*p,*q;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)f->a--;
|
if(carry)f->a--;
|
if(f->dat[f->b]==0&&f->b> f->a)f->b--;
|
if(f->dat[f->b]==0&&f->b> f->a)f->b--;
|
}
|
}
|
|
|
/*:60*//*61:*/
|
/*:60*//*61:*/
|
#line 1138 "./mmix-arith.w"
|
#line 1138 "./mmix-arith.w"
|
|
|
static int bignum_compare(f,g)
|
static int 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)return f->a> g->a?-1:1;
|
if(f->a!=g->a)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)return*p<*q?-1:1;
|
if(*p!=*q)return*p<*q?-1:1;
|
if(q==qq)return p<pp;
|
if(q==qq)return p<pp;
|
}
|
}
|
return-1;
|
return-1;
|
}
|
}
|
|
|
/*:61*//*62:*/
|
/*:61*//*62:*/
|
#line 1155 "./mmix-arith.w"
|
#line 1155 "./mmix-arith.w"
|
|
|
static void bignum_dec(f,g,r)
|
static void 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)f->dat[++f->b]= 0;
|
while(g->b> f->b)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)borrow= 0,*p= x;
|
if(x>=0)borrow= 0,*p= x;
|
else borrow= 1,*p= x+r;
|
else borrow= 1,*p= x+r;
|
}
|
}
|
for(;borrow;p--)
|
for(;borrow;p--)
|
if(*p)borrow= 0,*p= *p-1;
|
if(*p)borrow= 0,*p= *p-1;
|
else*p= r-1;
|
else*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)f->b--;
|
while(f->dat[f->b]==0)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 scan_const(s)
|
int 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=='-')sign= *p++;else sign= '+';
|
if(*p=='+'||*p=='-')sign= *p++;else sign= '+';
|
if(strncmp(p,"NaN",3)==0)NaN= true,p+= 3;
|
if(strncmp(p,"NaN",3)==0)NaN= true,p+= 3;
|
else NaN= false;
|
else 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)*q++= *p;
|
if(q<buf_max)*q++= *p;
|
else if(*(q-1)=='0')*(q-1)= *p;
|
else if(*(q-1)=='0')*(q-1)= *p;
|
}
|
}
|
if(NaN)*q++= '1';
|
if(NaN)*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)zeros++;
|
if(*p=='0'&&q==buf0)zeros++;
|
else if(q<buf_max)*q++= *p;
|
else if(q<buf_max)*q++= *p;
|
else if(*(q-1)=='0')*(q-1)= *p;
|
else if(*(q-1)=='0')*(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=='-')exp_sign= *p++;else exp_sign= '+';
|
if(*p=='+'||*p=='-')exp_sign= *p++;else 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)exp= 10*exp+*p-'0';
|
if(exp<1000)exp= 10*exp+*p-'0';
|
if(!dec_pt)dec_pt= q,zeros= 0;
|
if(!dec_pt)dec_pt= q,zeros= 0;
|
if(exp_sign=='-')exp= -exp;
|
if(exp_sign=='-')exp= -exp;
|
next_char= p;
|
next_char= p;
|
}
|
}
|
}
|
}
|
|
|
/*:77*/
|
/*:77*/
|
#line 1408 "./mmix-arith.w"
|
#line 1408 "./mmix-arith.w"
|
|
|
else exp= 0;
|
else 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;goto packit;
|
make_it_zero:exp= -99999;goto packit;
|
}
|
}
|
if(x<0){
|
if(x<0){
|
make_it_infinite:exp= 99999;goto packit;
|
make_it_infinite:exp= 99999;goto packit;
|
}
|
}
|
ff.a= x/9;
|
ff.a= x/9;
|
for(p= q;p<q+8;p++)*p= '0';
|
for(p= q;p<q+8;p++)*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++)x= 10*x+*pp-'0';
|
for(x= *p-'0',pp= p+1;pp<p+9;pp++)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)if(strncmp(p,"000000000",9)!=0)x= 1;
|
for(x= 0;p<=q;p+= 9)if(strncmp(p,"000000000",9)!=0)x= 1;
|
ff.dat[156]+= x;
|
ff.dat[156]+= x;
|
|
|
while(ff.dat[ff.b]==0)ff.b--;
|
while(ff.dat[ff.b]==0)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--)bignum_double(&ff);
|
for(exp= 0x3fe;ff.a> 36;exp--)bignum_double(&ff);
|
for(k= 54;k;k--){
|
for(k= 54;k;k--){
|
if(ff.dat[36]){
|
if(ff.dat[36]){
|
if(k>=32)val.h|= 1<<(k-32);else val.l|= 1<<k;
|
if(k>=32)val.h|= 1<<(k-32);else val.l|= 1<<k;
|
ff.dat[36]= 0;
|
ff.dat[36]= 0;
|
if(ff.b==36)break;
|
if(ff.b==36)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++)bignum_double(&tt);
|
for(exp= 0x3fe;bignum_compare(&ff,&tt)>=0;exp++)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)val.h|= 1<<(k-32);else val.l|= 1<<k;
|
if(k>=32)val.h|= 1<<(k-32);else val.l|= 1<<k;
|
bignum_dec(&ff,&tt,1000000000);
|
bignum_dec(&ff,&tt,1000000000);
|
if(ff.a==bignum_prec-1)break;
|
if(ff.a==bignum_prec-1)break;
|
}
|
}
|
}
|
}
|
}
|
}
|
if(k==0)val.l|= 1;
|
if(k==0)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)val.h|= 0x7fffffff,val.l= 0xffffffff;
|
if((val.h&0x7fffffff)==0x40000000)val.h|= 0x7fffffff,val.l= 0xffffffff;
|
else if((val.h&0x7fffffff)==0x3ff00000&&!val.l)val.h|= 0x40000000,val.l= 1;
|
else if((val.h&0x7fffffff)==0x3ff00000&&!val.l)val.h|= 0x40000000,val.l= 1;
|
else val.h|= 0x40000000;
|
else 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=='-')val= ominus(zero_octa,val);
|
if(sign=='-')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;return-1;
|
no_const_found:next_char= s;return-1;
|
}
|
}
|
|
|
/*:68*//*82:*/
|
/*:68*//*82:*/
|
#line 1511 "./mmix-arith.w"
|
#line 1511 "./mmix-arith.w"
|
|
|
static void bignum_double(f)
|
static void bignum_double(f)
|
bignum*f;
|
bignum*f;
|
{
|
{
|
register tetra*p,*q;register int x,carry;
|
register tetra*p,*q;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)carry= 1,*p= x-1000000000;
|
if(x>=1000000000)carry= 1,*p= x-1000000000;
|
else carry= 0,*p= x;
|
else carry= 0,*p= x;
|
}
|
}
|
*p= carry;
|
*p= carry;
|
if(carry)f->a--;
|
if(carry)f->a--;
|
if(f->dat[f->b]==0&&f->b> f->a)f->b--;
|
if(f->dat[f->b]==0&&f->b> f->a)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 fcomp(y,z)
|
int 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*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*nan+nan:case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:return 2;
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:return 2;
|
case 4*zro+zro:return 0;
|
case 4*zro+zro:return 0;
|
case 4*zro+num:case 4*num+zro:case 4*zro+inf:case 4*inf+zro:
|
case 4*zro+num:case 4*num+zro:case 4*zro+inf:case 4*inf+zro:
|
case 4*num+num:case 4*num+inf:case 4*inf+num:case 4*inf+inf:
|
case 4*num+num:case 4*num+inf:case 4*inf+num:case 4*inf+inf:
|
if(ys!=zs)x= 1;
|
if(ys!=zs)x= 1;
|
else if(y.h> z.h)x= 1;
|
else if(y.h> z.h)x= 1;
|
else if(y.h<z.h)x= -1;
|
else if(y.h<z.h)x= -1;
|
else if(y.l> z.l)x= 1;
|
else if(y.l> z.l)x= 1;
|
else if(y.l<z.l)x= -1;
|
else if(y.l<z.l)x= -1;
|
else return 0;
|
else 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 fintegerize(z,r)
|
octa 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)r= cur_round;
|
if(!r)r= cur_round;
|
switch(zt){
|
switch(zt){
|
case nan:if(!(z.h&0x80000)){exceptions|= I_BIT;z.h|= 0x80000;}
|
case nan:if(!(z.h&0x80000)){exceptions|= I_BIT;z.h|= 0x80000;}
|
case inf:case zro:return z;
|
case inf:case zro:return z;
|
case num:/*87:*/
|
case num:/*87:*/
|
#line 1627 "./mmix-arith.w"
|
#line 1627 "./mmix-arith.w"
|
|
|
if(ze>=1074)return fpack(zf,ze,zs,ROUND_OFF);
|
if(ze>=1074)return fpack(zf,ze,zs,ROUND_OFF);
|
if(ze<=1020)xf.h= 0,xf.l= 1;
|
if(ze<=1020)xf.h= 0,xf.l= 1;
|
else{octa oo;
|
else{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)xf.l|= 1;
|
if(oo.l!=zf.l||oo.h!=zf.h)xf.l|= 1;
|
|
|
}
|
}
|
switch(r){
|
switch(r){
|
case ROUND_DOWN:if(zs=='-')xf= incr(xf,3);break;
|
case ROUND_DOWN:if(zs=='-')xf= incr(xf,3);break;
|
case ROUND_UP:if(zs!='-')xf= incr(xf,3);
|
case ROUND_UP:if(zs!='-')xf= incr(xf,3);
|
case ROUND_OFF:break;
|
case ROUND_OFF:break;
|
case ROUND_NEAR:xf= incr(xf,xf.l&4?2:1);break;
|
case ROUND_NEAR:xf= incr(xf,xf.l&4?2:1);break;
|
}
|
}
|
xf.l&= 0xfffffffc;
|
xf.l&= 0xfffffffc;
|
if(ze>=1022)return fpack(shift_left(xf,1074-ze),ze,zs,ROUND_OFF);
|
if(ze>=1022)return fpack(shift_left(xf,1074-ze),ze,zs,ROUND_OFF);
|
if(xf.l)xf.h= 0x3ff00000,xf.l= 0;
|
if(xf.l)xf.h= 0x3ff00000,xf.l= 0;
|
if(zs=='-')xf.h|= sign_bit;
|
if(zs=='-')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 fixit(z,r)
|
octa 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)r= cur_round;
|
if(!r)r= cur_round;
|
switch(zt){
|
switch(zt){
|
case nan:case inf:exceptions|= I_BIT;return z;
|
case nan:case inf:exceptions|= I_BIT;return z;
|
case zro:return zero_octa;
|
case zro:return zero_octa;
|
case num:if(funpack(fintegerize(z,r),&zf,&ze,&zs)==zro)return zero_octa;
|
case num:if(funpack(fintegerize(z,r),&zf,&ze,&zs)==zro)return zero_octa;
|
if(ze<=1076)o= shift_right(zf,1076-ze,1);
|
if(ze<=1076)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.l||zs!='-')))))exceptions|= W_BIT;
|
(zf.h==0x400000&&(zf.l||zs!='-')))))exceptions|= W_BIT;
|
if(ze>=1140)return zero_octa;
|
if(ze>=1140)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 floatit(z,r,u,p)
|
octa floatit(z,r,u,p)
|
octa z;
|
octa z;
|
int r;
|
int r;
|
int u;
|
int u;
|
int p;
|
int p;
|
{
|
{
|
int e;char s;
|
int e;char s;
|
register int t;
|
register int t;
|
exceptions= 0;
|
exceptions= 0;
|
if(!z.h&&!z.l)return zero_octa;
|
if(!z.h&&!z.l)return zero_octa;
|
if(!r)r= cur_round;
|
if(!r)r= cur_round;
|
if(!u&&(z.h&sign_bit))s= '-',z= ominus(zero_octa,z);else s= '+';
|
if(!u&&(z.h&sign_bit))s= '-',z= ominus(zero_octa,z);else s= '+';
|
e= 1076;
|
e= 1076;
|
while(z.h<0x400000)e--,z= shift_left(z,1);
|
while(z.h<0x400000)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 tetra t;
|
register int ex;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 froot(z,r)
|
octa 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)r= cur_round;
|
if(!r)r= cur_round;
|
zt= funpack(z,&zf,&ze,&zs);
|
zt= funpack(z,&zf,&ze,&zs);
|
if(zs=='-'&&zt!=zro)exceptions|= I_BIT,x= standard_NaN;
|
if(zs=='-'&&zt!=zro)exceptions|= I_BIT,x= standard_NaN;
|
else switch(zt){
|
else switch(zt){
|
case nan:if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
case nan:if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
return z;
|
return z;
|
case inf:case zro:x= z;break;
|
case inf:case zro:x= z;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)zf= shift_left(zf,1);
|
if(ze&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);xf= shift_left(xf,1);
|
rf= shift_left(rf,2);xf= shift_left(xf,1);
|
if(k>=43)rf= incr(rf,(zf.h>>(2*(k-43)))&3);
|
if(k>=43)rf= incr(rf,(zf.h>>(2*(k-43)))&3);
|
else if(k>=27)rf= incr(rf,(zf.l>>(2*(k-27)))&3);
|
else if(k>=27)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++;rf= ominus(rf,xf);xf.l++;
|
xf.l++;rf= ominus(rf,xf);xf.l++;
|
}
|
}
|
}
|
}
|
if(rf.h||rf.l)xf.l++;
|
if(rf.h||rf.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=='-')x.h|= sign_bit;
|
if(zs=='-')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 fremstep(y,z,delta)
|
octa 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:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*nan+nan:if(!(y.h&0x80000))exceptions|= I_BIT;
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
case 4*zro+nan:case 4*num+nan:case 4*inf+nan:
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
if(!(z.h&0x80000))exceptions|= I_BIT,z.h|= 0x80000;
|
return z;
|
return z;
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
case 4*nan+zro:case 4*nan+num:case 4*nan+inf:
|
if(!(y.h&0x80000))exceptions|= I_BIT,y.h|= 0x80000;
|
if(!(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*num+zro:case 4*inf+zro:
|
case 4*zro+zro:case 4*num+zro:case 4*inf+zro:
|
case 4*inf+num:case 4*inf+inf:x= standard_NaN;
|
case 4*inf+num:case 4*inf+inf:x= standard_NaN;
|
exceptions|= I_BIT;break;
|
exceptions|= I_BIT;break;
|
case 4*zro+num:case 4*zro+inf:case 4*num+inf:return y;
|
case 4*zro+num:case 4*zro+inf:case 4*num+inf: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)thresh= ze;
|
if(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)goto zero_out;
|
if(yf.h==zf.h&&yf.l==zf.l)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)goto try_complement;
|
if(ye==ze)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)odd= 1;
|
if(ye==ze)odd= 1;
|
while(yf.h<0x400000)ye--,yf= shift_left(yf,1);
|
while(yf.h<0x400000)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;return fpack(yf,ye,ys,ROUND_OFF);
|
exceptions|= E_BIT;return fpack(yf,ye,ys,ROUND_OFF);
|
}
|
}
|
if(ye<ze-1)return fpack(yf,ye,ys,ROUND_OFF);
|
if(ye<ze-1)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||(xf.h==yf.h&&(xf.l> yf.l||(xf.l==yf.l&&!odd))))
|
if(xf.h> yf.h||(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)xe--,xf= shift_left(xf,1);
|
while(xf.h<0x400000)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=='-')x.h|= sign_bit;
|
if(ys=='-')x.h|= sign_bit;
|
return x;
|
return x;
|
}
|
}
|
|
|
/*:93*/
|
/*:93*/
|
#line 41 "./mmix-arith.w"
|
#line 41 "./mmix-arith.w"
|
|
|
|
|
/*:1*/
|
/*:1*/
|
|
|