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