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