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

Defined functions

as_atof defined in line 18; used 2 times
as_atoi defined in line 51; used 2 times
bignumwrite defined in line 375; used 2 times
isclear defined in line 187; used 2 times
isunequal defined in line 193; used 1 times
num1comp defined in line 304; used 4 times
numaddd defined in line 263; used 6 times
numaddv defined in line 273; used 6 times
numclear defined in line 206; used 7 times
numnegate defined in line 294; used 4 times
numshift defined in line 217; used 19 times
posovf defined in line 166; used 2 times
slitflt defined in line 321; used 1 times

Defined variables

sccsid defined in line 8; never used

Defined macros

EXPPREC defined in line 326; used 3 times
MANTPREC defined in line 327; used 5 times
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1503
Valid CSS Valid XHTML 1.0 Strict