1 /* #include <xcmpinclude.h> */
7 #define MASK 0x7fffffff
10 object
fixnum_times();
12 object
shift_integer();
14 #define FIXNUMP(x) (type_of(x)==t_fixnum)
16 /* Note: the modulus is guaranteed > 0 */
18 #define FIX_MOD(X,MOD) {register int MOD_2; \
19 if (X > (MOD_2=(MOD >>1))) X=X-MOD; else \
20 if (X < -MOD_2) X=X+MOD;}
24 #define MYmake_fixnum(doto,x) \
25 {register int CMPt1; \
27 ((((CMPt1=(x))+1024)&-2048)==0?small_fixnum(CMPt1):make_fixnum(CMPt1));}
35 { asm("movl a6@(8),d1");
36 asm("mulsl a6@(12),d0:d1");
37 asm("divsl a6@(16),d0:d1");
40 /* adds m and n returning the remainder modulo mod */
44 { asm("movl a6@(0x8),d1");
45 asm("addl a6@(0xc),d1");
46 asm("bvs plus_overflow_case");
47 asm("divsll a6@(16),d0:d1");
48 asm("bra plus_endend");
49 asm ("plus_overflow_case:");
50 asm("bcs plus_neg_args");
53 asm("plus_neg_args:");
56 asm("divsl a6@(16),d0:d1");
61 /* subtracts n from m returning the remainder modulo mod */
65 { asm("movl a6@(0x8),d1");
66 asm("subl a6@(0xc),d1");
67 asm("bvs sub_overflow_case");
68 asm("divsll a6@(16),d0:d1");
69 asm("bra sub_endend");
70 asm ("sub_overflow_case:");
71 asm("bcc sub_neg_args");
77 asm("divsl a6@(16),d0:d1");
83 /* like fixnum_times multiply to ints to get a t_fixnum or t_bignum ,
84 but utilize the ordinary mulsl for the common small case */
90 asm("movl a6@(8),d0");
91 asm("mulsl a6@(12),d0");
92 asm("bvs ftimes_overflow");
93 asm("movl d0,a6@(8)");
94 MYmake_fixnum(res
=,*&m
);
95 asm("bra ftimes_end");
96 asm("ftimes_overflow:");
97 res
=fixnum_times(m
,n
);
108 { asm("movl a6@(8),d0");
109 asm("mulsl a6@(12),d1:d0");
110 asm("movl d1, _TOPhalf");
116 /* multiply fixnum objects m and n faster than number_times */
123 ans=ftimes1(fix(m),fix(n));
125 { if (TOPhalf==-1) return (CMPmake_fixnum(ans));
126 else return (number_times(m,n));}
128 { if (TOPhalf==0) return (CMPmake_fixnum(ans));
129 else return (number_times(m,n));}}
136 {if (FIXNUMP(a
) && FIXNUMP(b
))
137 {if (mod
==Cnil
) return ftimes(fix(a
),fix(b
));
138 else if (FIXNUMP(mod
))
139 {register int res
, m
;
140 res
=dblrem(fix(a
),fix(b
),m
=fix(mod
));
142 MYmake_fixnum(return,res
);}}
143 return mcmod(number_times(a
,b
),mod
);}
148 {if (mod
==Cnil
) return(x
);
150 if((type_of(mod
)==t_fixnum
&& type_of(x
)==t_fixnum
))
152 mm
=fix(mod
);xx
=(fix(x
)%mm
);
154 MYmake_fixnum(return,xx
);
159 integer_quotient_remainder_1(x
,mod
,&qp
,&rp
);
160 mod2
=shift_integer(mod
,-1);
161 compare
=number_compare(rp
,mod2
);
162 if (compare
> 0) rp
=number_minus(rp
,mod
);
166 /* add two fixnums: First add m and n, then if there is an overflow condition
167 branch to construct bignum. Otherwise set res = the result,
168 and then act on it. The use of *&m is to inhibit compilers from making
169 the arg m a register, so that we would not know where it was. */
176 asm("movl a6@(0x8),d0");
177 asm("addl a6@(0xc),d0");
178 asm("bvs fplus_overflow_case");
179 asm("movl d0,a6@(0x8)");
180 asm("jra fplus_rest");
181 asm ("fplus_overflow_case:");
182 asm("movl d0,a6@(0x8)");
183 res
=((*&n
>0)?bignum2(1, *&m
& MASK
):bignum2(-2, *&m
& MASK
));
184 asm ("jra fplus_end");
186 MYmake_fixnum(res
=,*&m
);
192 /* subtract two fixnums:
193 First m - n, then if there is an overflow condition
194 branch to construct bignum. Otherwise set res = the result,
195 and then act on it. The use of *&m is to inhibit compilers from making
196 the arg m a register, so that we would not know where it was. */
202 asm("movl a6@(0x8),d0");
203 asm("subl a6@(0xc),d0");
204 asm("bvs fminus_overflow_case");
205 asm("movl d0,a6@(0x8)");
206 asm("jra fminus_rest");
207 asm ("fminus_overflow_case:");
208 asm("movl d0,a6@(0x8)");
209 res
=((*&n
<0)?bignum2(1, *&m
& MASK
):bignum2(-2, *&m
& MASK
));
210 asm ("jra fminus_end");
212 MYmake_fixnum(res
=,*&m
);
220 /* in fixnum case of m and mod put it into the right range. */
225 {int register res
,m2
;
228 if (res
> m2
) return( m
- mod
);
229 else if (res
< -m2
) return (res
+ mod
);
237 res
=((fix(a
)-fix(b
))%(m
=fix(mod
)));
239 MYmake_fixnum(return,res
);}
241 {if (FIXNUMP(a
) && FIXNUMP(b
))
242 return fminus(fix(a
),fix(b
));
243 else return(number_minus(a
,b
));
245 else return(mcmod(number_minus(a
,b
),mod
));}
254 res
=((fix(a
)+fix(b
))%(m
=fix(mod
)));
256 MYmake_fixnum(return,res
);}
259 {if (FIXNUMP(a
) && FIXNUMP(b
))
260 return fplus(fix(a
),fix(b
));
261 else return(number_plus(a
,b
));
264 return(mcmod(number_plus(a
,b
),mod
));}
270 {if (FIXNUMP(a) && FIXNUMP(b))
271 {if (mod==Cnil) return fplus(fix(a),(- fix(b)));
272 else if (FIXNUMP(mod))
273 {register int res, m ;
274 res=subrem(fix(a),fix(b),m=fix(mod));
276 return (CMPmake_fixnum(res));}}
277 return mcmod(number_minus(a,b),mod);}
283 {if (FIXNUMP(a) && FIXNUMP(b))
284 {if (mod==Cnil) return fplus(fix(a),fix(b));
285 else if (FIXNUMP(mod))
286 {register int res, m ,m2;
287 res=plusrem(fix(a),fix(b),m=fix(mod));
289 if (res > m2) res=res-m;
290 else if (res < -m2) res=res+m;
291 return (CMPmake_fixnum(res));}}
292 return mcmod(number_plus(a,b),mod);}