|
|
1.1 root 1: /*
2: * Copyright (c) 1982 Regents of the University of California
3: */
4: #ifndef lint
5: static char sccsid[] = "@(#)bignum1.c 4.4 6/30/83";
6: #endif not lint
7:
8: #include <errno.h>
9: #include <stdio.h>
10: #include "as.h"
11:
12: /*
13: * Construct a floating point number
14: */
15: Bignum as_atof(numbuf, radix, ovfp)
16: char *numbuf;
17: int radix;
18: Ovf *ovfp;
19: {
20: Bignum number;
21: extern int errno;
22: double atof();
23:
24: number = Znumber;
25: errno = 0;
26: switch(radix){
27: case TYPF:
28: case TYPD:
29: number.num_tag = TYPD;
30: *ovfp = 0;
31: number.num_num.numFd_float.Fd_value = atof(numbuf);
32: break;
33: case TYPG:
34: case TYPH:
35: number = bigatof(numbuf, radix);
36: break;
37: }
38: if (errno == ERANGE && passno == 2){
39: yywarning("Floating conversion over/underflowed\n");
40: }
41: return(number);
42: }
43:
44: /*
45: * Construct an integer.
46: */
47:
48: Bignum as_atoi(ccp, radix, ovfp)
49: reg char *ccp; /* character cp */
50: int radix;
51: Ovf *ovfp;
52: {
53: reg chptr bcp;
54: chptr tcp;
55: reg int i;
56: int val;
57: Bignum n_n;
58: Bignum t_n;
59: int sign;
60: Ovf ovf;
61:
62: ovf = 0;
63: sign = 0;
64: for (; *ccp; ccp++){
65: switch(*ccp){
66: case '0':
67: case '+': continue;
68: case '-': sign ^= 1;
69: continue;
70: }
71: break;
72: }
73:
74: n_n = Znumber;
75: t_n = Znumber;
76: bcp = CH_FIELD(n_n); (void)numclear(bcp);
77: tcp = CH_FIELD(t_n); (void)numclear(tcp);
78: for (; *ccp; ccp++){
79: switch(*ccp){
80: case '8': case '9':
81: if (radix < 10)
82: goto done;
83: /*FALLTHROUGH*/
84: case '0': case '1': case '2': case '3': case '4':
85: case '5': case '6': case '7':
86: val = *ccp - '0';
87: break;
88: case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
89: if (radix < 16)
90: goto done;
91: val = *ccp - 'A' + 10;
92: break;
93: case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
94: if (radix < 16)
95: goto done;
96: val = *ccp - 'a' + 10;
97: break;
98: default:
99: goto done;
100: }
101: switch(radix){
102: case 8:
103: ovf |= numshift(3, bcp, bcp);
104: break;
105: case 16:
106: ovf |= numshift(4, bcp, bcp);
107: break;
108: case 10:
109: ovf |= numshift(1, tcp, bcp);
110: ovf |= numshift(3, bcp, bcp);
111: ovf |= numaddv(bcp, tcp, bcp);
112: break;
113: }
114: ovf |= numaddd(bcp, bcp, val);
115: }
116: done: ;
117: ovf |= posovf(bcp);
118: if (sign){
119: if (ovf & OVF_MAXINT) {
120: ovf &= ~(OVF_MAXINT | OVF_POSOVF);
121: } else {
122: ovf |= numnegate(bcp, bcp);
123: }
124: }
125: /*
126: * find the highest set unit of the number
127: */
128: val = sign ? -1 : 0;
129: for (i = 0; i < CH_N; i++){
130: if (bcp[i] == val)
131: break;
132: }
133: {
134: static u_char tagtab[4][16] = {
135: { TYPB,
136: TYPW,
137: TYPL, TYPL,
138: TYPQ, TYPQ, TYPQ, TYPQ,
139: TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO, TYPO},
140: { TYPW,
141: TYPL,
142: TYPQ, TYPQ,
143: TYPO, TYPO, TYPO, TYPO},
144: { 0 },
145: { TYPL,
146: TYPQ,
147: TYPO, TYPO }
148: };
149: /*
150: * i indexes to the null chunk; make it point to the
151: * last non null chunk
152: */
153: i -= 1;
154: if (i < 0)
155: i = 0;
156: n_n.num_tag = tagtab[HOC][i];
157: assert(n_n.num_tag != 0, "Botch width computation");
158: }
159: *ovfp = ovf;
160: return(n_n);
161: }
162:
163: Ovf posovf(src)
164: reg chptr src;
165: {
166: reg int i;
167: Ovf overflow = 0;
168:
169: if (src[HOC] & SIGNBIT)
170: overflow = OVF_POSOVF;
171: if (src[HOC] == SIGNBIT){
172: for (i = HOC - 1; i >= 0; --i){
173: if (src[i] != 0)
174: return(overflow);
175: }
176: overflow |= OVF_MAXINT;
177: }
178: return(overflow);
179: }
180:
181: /*
182: * check if the number is clear
183: */
184: int isclear(dst)
185: reg chptr dst;
186: {
187: return(!isunequal(dst, CH_FIELD(Znumber)));
188: }
189:
190: int isunequal(src1, src2)
191: reg chptr src1, src2;
192: {
193: reg int i;
194:
195: i = CH_N;
196: do{
197: if (*src1++ != *src2++)
198: return(i);
199: }while(--i);
200: return(0);
201: }
202:
203: Ovf numclear(dst)
204: reg chptr dst;
205: {
206: reg int i;
207: i = CH_N;
208: do{
209: *dst++ = 0;
210: }while(--i);
211: return(0);
212: }
213:
214: Ovf numshift(n, dst, src)
215: int n;
216: reg chptr dst, src;
217: {
218: reg int i;
219: reg u_int carryi, carryo;
220: reg u_int mask;
221: reg u_int value;
222:
223: i = CH_N;
224: if (n == 0){
225: do{
226: *dst++ = *src++;
227: } while(--i);
228: return(0);
229: }
230:
231: carryi = 0;
232: mask = ONES(n);
233:
234: if (n > 0){
235: do{
236: value = *src++;
237: carryo = (value >> (CH_BITS - n)) & mask;
238: value <<= n;
239: value &= ~mask;
240: *dst++ = value | carryi;
241: carryi = carryo;
242: } while (--i);
243: return(carryi ? OVF_LSHIFT : 0);
244: } else {
245: n = -n;
246: src += CH_N;
247: dst += CH_N;
248: do{
249: value = *--src;
250: carryo = value & mask;
251: value >>= n;
252: value &= ONES(CH_BITS - n);
253: *--dst = value | carryi;
254: carryi = carryo << (CH_BITS - n);
255: } while (--i);
256: return(carryi ? OVF_LSHIFT : 0);
257: }
258: }
259:
260: Ovf numaddd(dst, src1, val)
261: chptr dst, src1;
262: int val;
263: {
264: static Bignum work;
265:
266: work.num_uchar[0] = val;
267: return (numaddv(dst, src1, CH_FIELD(work)));
268: }
269:
270: Ovf numaddv(dst, src1, src2)
271: reg chptr dst, src1, src2;
272: {
273: reg int i;
274: reg int carry;
275: reg u_int A,B,value;
276:
277: carry = 0;
278: i = CH_N;
279: do{
280: A = *src1++;
281: B = *src2++;
282: value = A + B + carry;
283: *dst++ = value;
284: carry = 0;
285: if (value < A || value < B)
286: carry = 1;
287: } while (--i);
288: return(carry ? OVF_ADDV : 0);
289: }
290:
291: Ovf numnegate(dst, src)
292: chptr dst, src;
293: {
294: Ovf ovf;
295:
296: ovf = num1comp(dst, src) ;
297: ovf |= numaddd(dst, dst, 1);
298: return(ovf);
299: }
300:
301: Ovf num1comp(dst, src)
302: reg chptr dst, src;
303: {
304: reg int i;
305: i = CH_N;
306: do{
307: *dst++ = ~ *src++;
308: }while (--i);
309: return(0);
310: }
311:
312: /*
313: * Determine if floating point numbers are
314: * capable of being represented as a one byte immediate literal constant
315: * If it is, then stuff the value into *valuep.
316: * argtype is how the instruction will interpret the number.
317: */
318: int slitflt(number, argtype, valuep)
319: Bignum number; /* number presented */
320: int argtype; /* what the instruction expects */
321: int *valuep;
322: {
323: #define EXPPREC 3
324: #define MANTPREC 3
325:
326: int mask;
327: reg int i;
328: Bignum unpacked;
329: Ovf ovf;
330:
331: *valuep = 0;
332: if (!ty_float[argtype])
333: return(0);
334: unpacked = bignumunpack(number, &ovf);
335: assert(ovf == 0, "overflow in unpacking floating #!?");
336: if (unpacked.num_sign)
337: return(0);
338: if (unpacked.num_exponent < 0)
339: return(0);
340: if (unpacked.num_exponent > ONES(EXPPREC))
341: return(0);
342: for (i = 0; i < HOC; i++){
343: if (CH_FIELD(unpacked)[i])
344: return(0);
345: }
346: if ((CH_FIELD(unpacked)[HOC]) & ONES(CH_BITS - MANTPREC))
347: return(0);
348: *valuep = (unpacked.num_exponent & ONES(EXPPREC)) << MANTPREC;
349: mask = (CH_FIELD(unpacked)[HOC]) >> (CH_BITS - MANTPREC);
350: mask &= ONES(MANTPREC);
351: *valuep |= mask;
352: *valuep &= ONES(MANTPREC + EXPPREC);
353: return(1);
354: }
355:
356: #ifndef STANDALONE
357: /*
358: * Output a big number to txtfil
359: * Called only when passno == 2
360: *
361: * The conversion specifies the width of the number to be written out.
362: * The width is supplied from either an initialized data directive
363: * (for example .float, .double), or from the operand size
364: * defined by an operator.
365: * If the number is of type quad or octal,
366: * we just write it out; this allows one to specify bit
367: * patterns for floating point numbers.
368: * If the number is one of the floating types and the conversion
369: * is not the same type, then we complain, but do the conversion anyway.
370: * The conversion is strict.
371: */
372: bignumwrite(number, toconv)
373: Bignum number;
374: int toconv; /* one of TYP[QO FDGH] */
375: {
376: reg u_int *bp;
377:
378: if (passno != 2)
379: return;
380:
381: bp = &number.num_uint[0];
382: switch(number.num_tag){
383: case TYPB:
384: case TYPW:
385: case TYPL:
386: case TYPQ:
387: case TYPO:
388: number = intconvert(number, toconv);
389: break;
390: default:
391: number = floatconvert(number, toconv);
392: break;
393: }
394: bwrite((char *)bp, ty_nbyte[toconv], txtfil);
395: }
396: #endif STANDALONE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.