6
/* #include "arith.h" */
10
/* I believe the instructions used here are ok for 68010.. */
16
/* static for gnuwin95 the save routine is not saving statics... */
19
#define FIXNUMP(x) (type_of(x)==t_fixnum)
21
/* Note: the gclModulus is guaranteed > 0 */
23
#define FIX_MOD(X,MOD) {register int MOD_2; \
24
if (X > (MOD_2=(MOD >>1))) X=X-MOD; else \
25
if (X < -MOD_2) X=X+MOD;}
29
/* #define MYmake_fixnum(doto,x) \ */
30
/* {register int CMPt1; \ */
32
/* ((((CMPt1=(x))+1024)&-2048)==0?small_fixnum(CMPt1):make_fixnum(CMPt1));} */
36
object ctimes(object a, object b),cplus(object a, object b),cdifference(object a, object b),cmod(object x);
38
object make_integer(__mpz_struct *u);
40
#define our_minus(a,b) ((FIXNUMP(a)&&FIXNUMP(b))?fixnum_sub(fix(a),fix(b)): \
42
#define our_plus(a,b) ((FIXNUMP(a)&&FIXNUMP(b))?fixnum_add(fix(a),fix(b)): \
44
#define our_times(a,b) number_times(a,b)
46
/* fix (and check) this on 64 bit machines, where long is the long long */
49
dblrem(int a, int b, int mod)
51
return (int)(((long long int)a*(long long int)b)%(long long int) mod);
60
{a= -a; sign= (b<0)? (b= -b,1) :-1;}
61
else { sign= (b<0) ? (b= -b,-1) : 1;}
62
{ mp_limb_t ar[2],q[2],aa;
64
ar[1]=mpn_mul_1(ar,&aa,1,b);
65
h = mpn_divrem_1(q,0,ar,2,mod);
66
return ((sign<0) ? -h :h);
73
{register object mod = *gclModulus;
74
if (mod==Cnil) return(x);
76
if((type_of(mod)==t_fixnum && type_of(x)==t_fixnum))
79
if (mm==2) {xx= (fix(x) & 1); return(small_fixnum(xx));}
82
MYmake_fixnum(return,xx);
87
integer_quotient_remainder_1(x,mod,&qp,&rp);
88
mod2=shift_integer(mod,-1);
89
compare = number_compare(rp,small_fixnum(0));
91
{compare=number_compare(rp,mod2);
92
if (compare > 0) rp=number_minus(rp,mod);}
94
if (number_compare(number_negate(mod2), rp) > 0)
95
{rp = number_plus(rp,mod);}
99
#define MOST_POSITIVE_FIX (((unsigned int) (~0) ) /2)
100
#define SMALL_MODULUS_P(mod) (FIXNUMP(mod) && (fix(mod) < (MOST_POSITIVE_FIX)/2))
102
ctimes(object a, object b)
103
{object mod = *gclModulus;
105
{register int res, m ;
106
res=dblrem(fix(a),fix(b),m=fix(mod));
108
MYmake_fixnum(return,res);}
110
{ return(our_times(a,b));}
111
return cmod(number_times(a,b));}
115
cdifference(object a, object b)
116
{object mod = *gclModulus;
117
if (SMALL_MODULUS_P(mod))
119
res=((fix(a)-fix(b))%(m=fix(mod)));
121
MYmake_fixnum(return,res);}
123
return (our_minus(a,b));
124
else return(cmod(number_minus(a,b)));}
127
cplus(object a, object b)
128
{object mod = *gclModulus;
129
if (SMALL_MODULUS_P(mod))
131
res=((fix(a)+fix(b))%(m=fix(mod)));
133
MYmake_fixnum(return,res);}
136
return (our_plus(a,b));
138
return(cmod(number_plus(a,b)));}
141
DEFUNO_NEW("CMOD",object,fScmod,SI
142
,1,1,NONE,OO,OO,OO,OO,void,siLcmod,(object num),"")
150
DEFUNO_NEW("CPLUS",object,fScplus,SI
151
,2,2,NONE,OO,OO,OO,OO,void,siLcplus,(object x0,object x1),"")
159
DEFUNO_NEW("CTIMES",object,fSctimes,SI
160
,2,2,NONE,OO,OO,OO,OO,void,siLctimes,(object x0,object x1),"")
169
DEFUNO_NEW("CDIFFERENCE",object,fScdifference,SI
170
,2,2,NONE,OO,OO,OO,OO,void,siLcdifference,(object x0,object x1),"")
173
x0=cdifference(x0,x1);
178
/* memq(register object a, register object b) */
180
/* {if ((a==b->c.c_car)||b==Cnil) return b; */
181
/* b=b->c.c_cdr;}} */
187
/* add_symbol("ctimes",&ctimes,"cplus",&cplus,"cdifference",&cdifference,"cmod",
189
gclModulus = (&((make_si_special("MODULUS",Cnil))->s.s_dbind));
190
make_si_function("CMOD",siLcmod);
191
make_si_function("CPLUS",siLcplus);
192
make_si_function("CTIMES",siLctimes);
193
make_si_function("CDIFFERENCE",siLcdifference);