1*40599Sbostic /*
2*40599Sbostic * Copyright (c) 1982 Regents of the University of California
3*40599Sbostic */
4*40599Sbostic #ifndef lint
5*40599Sbostic static char sccsid[] = "@(#)bignum1.c 4.4 6/30/83";
6*40599Sbostic #endif not lint
7*40599Sbostic
8*40599Sbostic #include <errno.h>
9*40599Sbostic #include <stdio.h>
10*40599Sbostic #include "as.h"
11*40599Sbostic
12*40599Sbostic Bignum Znumber;
13*40599Sbostic
14*40599Sbostic /*
15*40599Sbostic * Construct an integer.
16*40599Sbostic */
17*40599Sbostic
as_atoi(ccp,radix,ovfp)18*40599Sbostic Bignum as_atoi(ccp, radix, ovfp)
19*40599Sbostic reg char *ccp; /* character cp */
20*40599Sbostic int radix;
21*40599Sbostic Ovf *ovfp;
22*40599Sbostic {
23*40599Sbostic reg chptr bcp;
24*40599Sbostic chptr tcp;
25*40599Sbostic reg int i;
26*40599Sbostic int val;
27*40599Sbostic Bignum n_n;
28*40599Sbostic Bignum t_n;
29*40599Sbostic int sign;
30*40599Sbostic Ovf ovf;
31*40599Sbostic
32*40599Sbostic ovf = 0;
33*40599Sbostic sign = 0;
34*40599Sbostic for (; *ccp; ccp++){
35*40599Sbostic switch(*ccp){
36*40599Sbostic case '0':
37*40599Sbostic case '+': continue;
38*40599Sbostic case '-': sign ^= 1;
39*40599Sbostic continue;
40*40599Sbostic }
41*40599Sbostic break;
42*40599Sbostic }
43*40599Sbostic
44*40599Sbostic n_n = Znumber;
45*40599Sbostic t_n = Znumber;
46*40599Sbostic bcp = CH_FIELD(n_n); (void)numclear(bcp);
47*40599Sbostic tcp = CH_FIELD(t_n); (void)numclear(tcp);
48*40599Sbostic for (; *ccp; ccp++){
49*40599Sbostic switch(*ccp){
50*40599Sbostic case '8': case '9':
51*40599Sbostic if (radix < 10)
52*40599Sbostic goto done;
53*40599Sbostic /*FALLTHROUGH*/
54*40599Sbostic case '0': case '1': case '2': case '3': case '4':
55*40599Sbostic case '5': case '6': case '7':
56*40599Sbostic val = *ccp - '0';
57*40599Sbostic break;
58*40599Sbostic case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
59*40599Sbostic if (radix < 16)
60*40599Sbostic goto done;
61*40599Sbostic val = *ccp - 'A' + 10;
62*40599Sbostic break;
63*40599Sbostic case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
64*40599Sbostic if (radix < 16)
65*40599Sbostic goto done;
66*40599Sbostic val = *ccp - 'a' + 10;
67*40599Sbostic break;
68*40599Sbostic default:
69*40599Sbostic goto done;
70*40599Sbostic }
71*40599Sbostic switch(radix){
72*40599Sbostic case 8:
73*40599Sbostic ovf |= numshift(3, bcp, bcp);
74*40599Sbostic break;
75*40599Sbostic case 16:
76*40599Sbostic ovf |= numshift(4, bcp, bcp);
77*40599Sbostic break;
78*40599Sbostic case 10:
79*40599Sbostic ovf |= numshift(1, tcp, bcp);
80*40599Sbostic ovf |= numshift(3, bcp, bcp);
81*40599Sbostic ovf |= numaddv(bcp, tcp, bcp);
82*40599Sbostic break;
83*40599Sbostic }
84*40599Sbostic ovf |= numaddd(bcp, bcp, val);
85*40599Sbostic }
86*40599Sbostic done: ;
87*40599Sbostic ovf |= posovf(bcp);
88*40599Sbostic if (sign){
89*40599Sbostic if (ovf & OVF_MAXINT) {
90*40599Sbostic ovf &= ~(OVF_MAXINT | OVF_POSOVF);
91*40599Sbostic } else {
92*40599Sbostic ovf |= numnegate(bcp, bcp);
93*40599Sbostic }
94*40599Sbostic }
95*40599Sbostic /*
96*40599Sbostic * find the highest set unit of the number
97*40599Sbostic */
98*40599Sbostic val = sign ? -1 : 0;
99*40599Sbostic for (i = 0; i < CH_N; i++){
100*40599Sbostic if (bcp[i] == val)
101*40599Sbostic break;
102*40599Sbostic }
103*40599Sbostic {
104*40599Sbostic static u_char tagtab[4][8] = {
105*40599Sbostic { TYPB,
106*40599Sbostic TYPW,
107*40599Sbostic TYPL, TYPL,
108*40599Sbostic TYPQ, TYPQ, TYPQ, TYPQ },
109*40599Sbostic { TYPW,
110*40599Sbostic TYPL,
111*40599Sbostic TYPQ, TYPQ },
112*40599Sbostic { 0 },
113*40599Sbostic { TYPL,
114*40599Sbostic TYPQ }
115*40599Sbostic };
116*40599Sbostic /*
117*40599Sbostic * i indexes to the null chunk; make it point to the
118*40599Sbostic * last non null chunk
119*40599Sbostic */
120*40599Sbostic i -= 1;
121*40599Sbostic if (i < 0)
122*40599Sbostic i = 0;
123*40599Sbostic n_n.num_tag = tagtab[HOC][i];
124*40599Sbostic assert(n_n.num_tag != 0, " Botch width computation");
125*40599Sbostic }
126*40599Sbostic *ovfp = ovf;
127*40599Sbostic return(n_n);
128*40599Sbostic }
129*40599Sbostic
as_atof(numbuf,radix)130*40599Sbostic Bignum as_atof (numbuf, radix)
131*40599Sbostic char *numbuf;
132*40599Sbostic {
133*40599Sbostic double atof ();
134*40599Sbostic Bignum number;
135*40599Sbostic
136*40599Sbostic number = Znumber;
137*40599Sbostic number.num_tag = radix;
138*40599Sbostic switch (radix)
139*40599Sbostic {
140*40599Sbostic case TYPD:
141*40599Sbostic number.num_num.numFd_float.Fd_value = atof (numbuf);
142*40599Sbostic break;
143*40599Sbostic case TYPF:
144*40599Sbostic number.num_num.numFf_float.Ff_value = atof (numbuf);
145*40599Sbostic break;
146*40599Sbostic }
147*40599Sbostic
148*40599Sbostic return (number);
149*40599Sbostic }
150*40599Sbostic
posovf(src)151*40599Sbostic Ovf posovf(src)
152*40599Sbostic reg chptr src;
153*40599Sbostic {
154*40599Sbostic reg int i;
155*40599Sbostic Ovf overflow = 0;
156*40599Sbostic
157*40599Sbostic if (src[HOC] & SIGNBIT)
158*40599Sbostic overflow = OVF_POSOVF;
159*40599Sbostic if (src[HOC] == SIGNBIT){
160*40599Sbostic for (i = HOC - 1; i >= 0; --i){
161*40599Sbostic if (src[i] != 0)
162*40599Sbostic return(overflow);
163*40599Sbostic }
164*40599Sbostic overflow |= OVF_MAXINT;
165*40599Sbostic }
166*40599Sbostic return(overflow);
167*40599Sbostic }
168*40599Sbostic
169*40599Sbostic /*
170*40599Sbostic * check if the number is clear
171*40599Sbostic */
isclear(dst)172*40599Sbostic int isclear(dst)
173*40599Sbostic reg chptr dst;
174*40599Sbostic {
175*40599Sbostic return(!isunequal(dst, CH_FIELD(Znumber)));
176*40599Sbostic }
177*40599Sbostic
isunequal(src1,src2)178*40599Sbostic int isunequal(src1, src2)
179*40599Sbostic reg chptr src1, src2;
180*40599Sbostic {
181*40599Sbostic reg int i;
182*40599Sbostic
183*40599Sbostic i = CH_N;
184*40599Sbostic do{
185*40599Sbostic if (*src1++ != *src2++)
186*40599Sbostic return(i);
187*40599Sbostic }while(--i);
188*40599Sbostic return(0);
189*40599Sbostic }
190*40599Sbostic
numclear(dst)191*40599Sbostic Ovf numclear(dst)
192*40599Sbostic reg chptr dst;
193*40599Sbostic {
194*40599Sbostic reg int i;
195*40599Sbostic i = CH_N;
196*40599Sbostic do{
197*40599Sbostic *dst++ = 0;
198*40599Sbostic }while(--i);
199*40599Sbostic return(0);
200*40599Sbostic }
201*40599Sbostic
numshift(n,dst,src)202*40599Sbostic Ovf numshift(n, dst, src)
203*40599Sbostic int n;
204*40599Sbostic reg chptr dst, src;
205*40599Sbostic {
206*40599Sbostic reg int i;
207*40599Sbostic reg u_int carryi, carryo;
208*40599Sbostic reg u_int mask;
209*40599Sbostic reg u_int value;
210*40599Sbostic
211*40599Sbostic i = CH_N;
212*40599Sbostic if (n == 0){
213*40599Sbostic do{
214*40599Sbostic *dst++ = *src++;
215*40599Sbostic } while(--i);
216*40599Sbostic return(0);
217*40599Sbostic }
218*40599Sbostic
219*40599Sbostic carryi = 0;
220*40599Sbostic mask = ONES(n);
221*40599Sbostic
222*40599Sbostic if (n > 0){
223*40599Sbostic do{
224*40599Sbostic value = *src++;
225*40599Sbostic carryo = (value >> (CH_BITS - n)) & mask;
226*40599Sbostic value <<= n;
227*40599Sbostic value &= ~mask;
228*40599Sbostic *dst++ = value | carryi;
229*40599Sbostic carryi = carryo;
230*40599Sbostic } while (--i);
231*40599Sbostic return(carryi ? OVF_LSHIFT : 0);
232*40599Sbostic } else {
233*40599Sbostic n = -n;
234*40599Sbostic src += CH_N;
235*40599Sbostic dst += CH_N;
236*40599Sbostic do{
237*40599Sbostic value = *--src;
238*40599Sbostic carryo = value & mask;
239*40599Sbostic value >>= n;
240*40599Sbostic value &= ONES(CH_BITS - n);
241*40599Sbostic *--dst = value | carryi;
242*40599Sbostic carryi = carryo << (CH_BITS - n);
243*40599Sbostic } while (--i);
244*40599Sbostic return(carryi ? OVF_LSHIFT : 0);
245*40599Sbostic }
246*40599Sbostic }
247*40599Sbostic
numaddd(dst,src1,val)248*40599Sbostic Ovf numaddd(dst, src1, val)
249*40599Sbostic chptr dst, src1;
250*40599Sbostic int val;
251*40599Sbostic {
252*40599Sbostic static Bignum work;
253*40599Sbostic
254*40599Sbostic work.num_uchar[3] = val;
255*40599Sbostic return (numaddv(dst, src1, CH_FIELD(work)));
256*40599Sbostic }
257*40599Sbostic
numaddv(dst,src1,src2)258*40599Sbostic Ovf numaddv(dst, src1, src2)
259*40599Sbostic reg chptr dst, src1, src2;
260*40599Sbostic {
261*40599Sbostic reg int i;
262*40599Sbostic reg int carry;
263*40599Sbostic reg u_int A,B,value;
264*40599Sbostic
265*40599Sbostic carry = 0;
266*40599Sbostic i = CH_N;
267*40599Sbostic do{
268*40599Sbostic A = *src1++;
269*40599Sbostic B = *src2++;
270*40599Sbostic value = A + B + carry;
271*40599Sbostic *dst++ = value;
272*40599Sbostic carry = 0;
273*40599Sbostic if (value < A || value < B)
274*40599Sbostic carry = 1;
275*40599Sbostic } while (--i);
276*40599Sbostic return(carry ? OVF_ADDV : 0);
277*40599Sbostic }
278*40599Sbostic
numnegate(dst,src)279*40599Sbostic Ovf numnegate(dst, src)
280*40599Sbostic chptr dst, src;
281*40599Sbostic {
282*40599Sbostic Ovf ovf;
283*40599Sbostic
284*40599Sbostic ovf = num1comp(dst, src) ;
285*40599Sbostic ovf |= numaddd(dst, dst, 1);
286*40599Sbostic return(ovf);
287*40599Sbostic }
288*40599Sbostic
num1comp(dst,src)289*40599Sbostic Ovf num1comp(dst, src)
290*40599Sbostic reg chptr dst, src;
291*40599Sbostic {
292*40599Sbostic reg int i;
293*40599Sbostic i = CH_N;
294*40599Sbostic do{
295*40599Sbostic *dst++ = ~ *src++;
296*40599Sbostic }while (--i);
297*40599Sbostic return(0);
298*40599Sbostic }
299*40599Sbostic
bignumprint(number)300*40599Sbostic bignumprint(number)
301*40599Sbostic Bignum number; /* number presented */
302*40599Sbostic {
303*40599Sbostic switch (num_type)
304*40599Sbostic {
305*40599Sbostic case TYPQ:
306*40599Sbostic printf ("val[msd] = 0x%x, val[lsd] = 0x%x.",
307*40599Sbostic number.num_num.numIq_int.Iq_ulong[1],
308*40599Sbostic number.num_num.numIq_int.Iq_ulong[0]);
309*40599Sbostic break;
310*40599Sbostic case TYPF:
311*40599Sbostic printf ("value %20.17f",
312*40599Sbostic number.num_num.numFf_float.Ff_value);
313*40599Sbostic break;
314*40599Sbostic case TYPD:
315*40599Sbostic printf ("value %20.17f",
316*40599Sbostic number.num_num.numFd_float.Fd_value);
317*40599Sbostic break;
318*40599Sbostic default:
319*40599Sbostic break;
320*40599Sbostic }
321*40599Sbostic }
322*40599Sbostic
323