|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)operand.c 1.1 86/02/03 Copyr 1985 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1985 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include "as.h" ! 10: #include <ctype.h> ! 11: ! 12: short cinfo[128] = { ! 13: ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ! 14: ERR, SPC, EOL, SPC, SPC, SPC, ERR, ERR, ! 15: ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ! 16: ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ! 17: SPC, ERR, QUO, IMM, S+T, ERR, ERR, ERR, ! 18: LP, RP, MUL, ADD, COM, SUB, S+T, DIV, ! 19: D+T, D+T, D+T, D+T, D+T, D+T, D+T, D+T, ! 20: D+T, D+T, COL, EOL, ERR, EQL, ERR, ERR, ! 21: IND, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 22: S+T, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 23: S+T, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 24: S+T, S+T, S+T, ERR, ERR, ERR, ERR, S+T, ! 25: ERR, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 26: S+T, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 27: S+T, S+T, S+T, S+T, S+T, S+T, S+T, S+T, ! 28: S+T, S+T, S+T, LB, EOL, RB, NOT, S+T ! 29: }; ! 30: ! 31: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */ ! 32: #if AS ! 33: char *ll_format = "*%c%06d"; ! 34: #else C2 ! 35: char *ll_format = "LX%c%06d"; ! 36: #endif ! 37: ! 38: int ll_val[10]; ! 39: ! 40: static struct suffix { ! 41: int indx_sx; /* index register */ ! 42: int scale_sx; /* index scaling */ ! 43: long disp_sx; /* displacement */ ! 44: struct sym_bkt *sym_sx; /* symbolic displacement */ ! 45: unsigned flags_sx; /* see below */ ! 46: } fix [2]; ! 47: ! 48: static struct suffix zero_suffix = { 0 }; ! 49: ! 50: /* flags_sx values */ ! 51: #define SX_INDXW 1 /* word-size index specified */ ! 52: #define SX_INDXL 2 /* long-size index specified */ ! 53: #define SX_DISPW 4 /* word-size displacement specified */ ! 54: #define SX_DISPL 8 /* long-size displacement specified */ ! 55: #define SX_GOTINDEX 020 /* index register specified */ ! 56: #define SX_GOTDISP 040 /* displacement specified */ ! 57: #if C2 ! 58: #define SX_CXDISP 0100 /* displacement is complex */ ! 59: #endif ! 60: ! 61: static struct oper zero_oper = { T_NULL, 0, 0, NULL, 0, 0, 0}; ! 62: ! 63: char *suffix(), *exp(), *term(), *scan_reg_or_immed(); ! 64: char * scan_float(); ! 65: double atof(); ! 66: ! 67: /* ! 68: * Fetches operand value and register subfields and loads them into ! 69: * the operand structure. This routine will fetch only one set of value ! 70: * and register subfields. It will move line pointer to first untouched char. ! 71: */ ! 72: char * ! 73: soperand(lptr,opnd) ! 74: register char *lptr; ! 75: struct oper *opnd; ! 76: { ! 77: struct oper spare_oper; ! 78: int v; ! 79: ! 80: *opnd = zero_oper; ! 81: spare_oper = zero_oper; ! 82: ! 83: if ((v=cinfo[*lptr]) == IMM) { ! 84: lptr = exp(++lptr,opnd); ! 85: if (opnd->type_o == T_REG) ! 86: PROG_ERROR(E_REG); ! 87: if (opnd->type_o == T_FLOAT) ! 88: /* immediate value is floating-point */ ! 89: opnd->flags_o |= O_FLOAT; ! 90: opnd->type_o = T_IMMED; ! 91: } else if (v == IND) { ! 92: /* index mode, omitted base */ ! 93: /* expecting LP next */ ! 94: lptr += 1; ! 95: skipb(lptr); ! 96: if (cinfo[*lptr] == LP) ! 97: goto index_mode; ! 98: else ! 99: PROG_ERROR(E_OPERAND); ! 100: } else { ! 101: lptr = exp(lptr,opnd); ! 102: skipb(lptr); ! 103: switch (opnd->type_o){ ! 104: case T_REG: ! 105: switch (cinfo[*lptr]){ ! 106: case COL: ! 107: /* should be a register pair */ ! 108: lptr = exp( ++lptr, &spare_oper); ! 109: if (spare_oper.type_o != T_REG) ! 110: PROG_ERROR(E_OPERAND); ! 111: #if AS ! 112: if (!ext_instruction_set) ! 113: PROG_ERROR(E_OPERAND); ! 114: #endif ! 115: opnd->type_o = T_REGPAIR; ! 116: opnd->reg_o = spare_oper.value_o; ! 117: break; ! 118: case IND: ! 119: if (!(areg(opnd->value_o)||pcreg(opnd->value_o))) ! 120: PROG_ERROR(E_OPERAND); ! 121: lptr += 1; ! 122: skipb(lptr); ! 123: switch (cinfo[*lptr]){ ! 124: default: ! 125: opnd->type_o = T_DEFER; ! 126: break; ! 127: case ADD: ! 128: opnd->type_o = T_POSTINC; ! 129: lptr++; ! 130: break; ! 131: case SUB: ! 132: opnd->type_o = T_PREDEC; ! 133: lptr++; ! 134: break; ! 135: case LP: ! 136: /* defer or indexing coming up here */ ! 137: index_mode: ! 138: lptr = suffix( lptr, &fix[0] ); ! 139: if (cinfo[*lptr] != IND){ ! 140: simplify1( opnd, &fix[0] ); ! 141: } else { ! 142: lptr = suffix( ++lptr, &fix[1] ); ! 143: simplify2( opnd, &fix[0], &fix[1] ); ! 144: } ! 145: break; ! 146: case IND: ! 147: lptr = suffix( ++lptr, &fix[1] ); ! 148: simplify2( opnd, &zero_suffix, &fix[1] ); ! 149: break; ! 150: } ! 151: #if AS ! 152: if (opnd->type_o == T_INDEX && !ext_instruction_set) ! 153: if ( (opnd->flags_o&(O_BSUPRESS|O_INDIRECT|O_WDISP|O_LDISP)) || ! 154: opnd->scale_o != 1 || !(opnd->flags_o&O_PREINDEX)) ! 155: PROG_ERROR( E_OPERAND ); ! 156: #endif ! 157: /* flow through */ ! 158: default: ! 159: break; ! 160: } ! 161: break; ! 162: case T_NORMAL: ! 163: if (cinfo[*lptr] == COL ){ ! 164: switch (*++lptr) { ! 165: case 'W': ! 166: case 'w': opnd->type_o = T_ABSS; ! 167: lptr++; ! 168: break; ! 169: case 'L': ! 170: case 'l': opnd->type_o = T_ABSL; ! 171: lptr++; ! 172: break; ! 173: } ! 174: } ! 175: if (cinfo[*lptr] == IND) ! 176: goto index_mode; ! 177: break; ! 178: } ! 179: } ! 180: skipb( lptr ); ! 181: if ( cinfo[ *lptr ] == LB ) { ! 182: /* oh, boy, bitfields */ ! 183: opnd->flags_o |= O_BFLD; ! 184: spare_oper = zero_oper; ! 185: lptr = scan_reg_or_immed( lptr+1, &spare_oper); ! 186: v = spare_oper.value_o; ! 187: if (spare_oper.type_o == T_REG){ ! 188: opnd->flags_o |= O_BFOREG; ! 189: } else if ((spare_oper.sym_o && !(spare_oper.sym_o->attr_s&S_DEF)) || v < 0 || v > 31){ ! 190: PROG_ERROR(E_CONSTANT); ! 191: } ! 192: opnd->bfoffset_o = v; ! 193: skipb( lptr ); ! 194: if ( cinfo[ *lptr ] == COL) ! 195: lptr ++; ! 196: else ! 197: PROG_ERROR(E_OPERAND); ! 198: spare_oper = zero_oper; ! 199: lptr = scan_reg_or_immed( lptr, &spare_oper); ! 200: v = spare_oper.value_o; ! 201: if (spare_oper.type_o == T_REG){ ! 202: opnd->flags_o |= O_BFWREG; ! 203: } else if ((spare_oper.sym_o && !(spare_oper.sym_o->attr_s&S_DEF)) || v < 0 || v > 31){ ! 204: PROG_ERROR(E_CONSTANT); ! 205: } ! 206: opnd->bfwidth_o = v; ! 207: skipb( lptr ); ! 208: if ( cinfo[ *lptr ] == RB ) ! 209: lptr++; ! 210: else ! 211: PROG_ERROR(E_OPERAND); ! 212: } ! 213: return(lptr); ! 214: } /* end soperand */ ! 215: ! 216: static char * ! 217: scan_reg_or_immed( lptr, o ) ! 218: register char *lptr; ! 219: register struct oper *o; ! 220: { ! 221: skipb( lptr ); ! 222: if (cinfo[*lptr] == IMM) { ! 223: lptr = exp(++lptr,o); ! 224: if (o->type_o == T_REG) ! 225: PROG_ERROR(E_REG); ! 226: if (o->sym_o && !(o->sym_o->attr_s&S_DEF)) ! 227: PROG_ERROR(E_REG); ! 228: o->type_o = T_IMMED; ! 229: } else { ! 230: lptr = exp( lptr, o ); ! 231: if ( o->type_o != T_REG || o->value_o > D7REG) ! 232: PROG_ERROR(E_OPERAND); ! 233: } ! 234: return lptr; ! 235: } ! 236: ! 237: static char * ! 238: opt_length( lptr, fp, wflag, lflag ) ! 239: register char * lptr; ! 240: struct suffix * fp; ! 241: { ! 242: char * save = lptr; ! 243: if (cinfo[ *lptr ] == COL){ ! 244: lptr++; ! 245: skipb( lptr ); ! 246: switch ( *lptr ){ ! 247: case 'l': ! 248: case 'L': ! 249: fp->flags_sx |= lflag; ! 250: lptr++; ! 251: break; ! 252: case 'w': ! 253: case 'W': ! 254: fp->flags_sx |= wflag; ! 255: lptr++; ! 256: break; ! 257: default: return save; /* : yes, length, no: may be scale */ ! 258: } ! 259: } ! 260: return lptr; ! 261: } ! 262: static char * ! 263: opt_scale( lptr, fp ) ! 264: char * lptr; ! 265: struct suffix * fp; ! 266: { ! 267: fp->scale_sx = 1; ! 268: if (cinfo[ *lptr ] == COL){ ! 269: lptr++; ! 270: skipb( lptr ); ! 271: switch ( *lptr ){ ! 272: case '1': ! 273: case '2': ! 274: case '4': ! 275: case '8': ! 276: fp->scale_sx = *lptr - '0'; ! 277: lptr++; ! 278: break; ! 279: default: PROG_ERROR(E_OPERAND); ! 280: } ! 281: } ! 282: return lptr; ! 283: } ! 284: ! 285: static char * ! 286: suffix( lptr, fixp ) ! 287: register char * lptr; ! 288: register struct suffix * fixp; ! 289: { ! 290: /* ! 291: * scan for open paran. look for displacement, optional length ! 292: * specifier, then index register, optional length specifier, optional ! 293: * scale specifier. ! 294: * fill in suffix structure with what we find. ! 295: */ ! 296: struct oper o; ! 297: o = zero_oper; ! 298: *fixp = zero_suffix; ! 299: skipb( lptr ); ! 300: if (cinfo[ *lptr ] == LP ) ! 301: lptr += 1; ! 302: else ! 303: return lptr; /* guess that null suffix might be ok */ ! 304: lptr = exp( lptr , &o ); ! 305: if ( o.type_o == T_NORMAL ){ ! 306: fixp->disp_sx = o.value_o; ! 307: fixp->sym_sx = o.sym_o; ! 308: fixp->flags_sx |= SX_GOTDISP; ! 309: #if C2 ! 310: if (o.flags_o&O_COMPLEX) ! 311: fixp->flags_sx |= SX_CXDISP; ! 312: #endif ! 313: lptr = opt_length( lptr, fixp, SX_DISPW, SX_DISPL ); ! 314: skipb( lptr ); ! 315: if (cinfo[ *lptr ] == COM) ! 316: lptr = exp( ++lptr, &o ); ! 317: else ! 318: goto scan_rp; ! 319: } ! 320: /* now we're talking index */ ! 321: if ( o.type_o != T_REG ){ ! 322: PROG_ERROR( E_OPERAND); ! 323: } ! 324: fixp->flags_sx |= SX_GOTINDEX; ! 325: fixp->indx_sx = o.value_o; ! 326: lptr = opt_length( lptr, fixp, SX_INDXW, SX_INDXL ); ! 327: lptr = opt_scale( lptr, fixp ); ! 328: scan_rp: ! 329: skipb( lptr ); ! 330: if (cinfo[ *lptr ] == RP) ! 331: lptr ++; ! 332: else ! 333: PROG_ERROR( E_OPERAND); ! 334: return lptr; ! 335: } ! 336: ! 337: static ! 338: simplify1( oper, fp ) ! 339: register struct oper * oper; ! 340: register struct suffix *fp; ! 341: { ! 342: register bval = oper->value_o; ! 343: /* we have some form of deferred or indexed addressing here */ ! 344: /* try to make the best of it. */ ! 345: /* ! 346: * examples are: ! 347: * a0@(disp) ! 348: * a0@(disp,d0:w:2) ! 349: * a0@(d0:w:2) ! 350: * pc@(disp) ! 351: * pc@(disp,d0:w:2) ! 352: * pc@(d0:w:2) ! 353: * @(d0) ! 354: * @(disp,d0) ! 355: */ ! 356: switch (oper->type_o){ ! 357: case T_REG: ! 358: if( !(fp->flags_sx&(SX_GOTINDEX|SX_DISPL)) ){ ! 359: /* displacement mode */ ! 360: oper->type_o = T_DISPL; ! 361: oper->reg_o = bval; ! 362: oper->value_o = fp->disp_sx; ! 363: oper->sym_o = fp->sym_sx; ! 364: } else { ! 365: /* index mode */ ! 366: imode: ! 367: oper->type_o = T_INDEX; ! 368: oper->reg_o = bval; ! 369: oper->disp_o = fp->disp_sx; ! 370: oper->sym_o = fp->sym_sx; ! 371: if (fp->flags_sx&SX_GOTINDEX){ ! 372: oper->value_o = fp->indx_sx; ! 373: oper->scale_o = fp->scale_sx; ! 374: if (fp->flags_sx&SX_INDXW) ! 375: oper->flags_o|= O_WINDEX|O_PREINDEX; ! 376: else ! 377: oper->flags_o|= O_LINDEX|O_PREINDEX; ! 378: } else { ! 379: oper->value_o = 0; ! 380: oper->scale_o = 0; ! 381: } ! 382: if (fp->flags_sx & SX_DISPL) ! 383: oper->flags_o|= O_LDISP; ! 384: else if (fp->flags_sx & SX_DISPW) ! 385: oper->flags_o|= O_WDISP; ! 386: /* else short form indexing */ ! 387: } ! 388: break; ! 389: case T_NULL: ! 390: /* @(disp,d0) */ ! 391: /* @(d0) */ ! 392: /* index mode, supressed base */ ! 393: oper->type_o= T_INDEX; ! 394: oper->flags_o|= O_BSUPRESS; ! 395: oper->reg_o = A0REG; /* Supress THIS register */ ! 396: oper->disp_o= fp->disp_sx; ! 397: oper->sym_o= fp->sym_sx; ! 398: if(fp->flags_sx & SX_DISPL) ! 399: oper->flags_o |= O_LDISP; ! 400: else if (fp->flags_sx & SX_DISPW) ! 401: oper->flags_o |= O_WDISP; ! 402: do_index: ! 403: if (fp->flags_sx & SX_GOTINDEX){ ! 404: oper->value_o = fp->indx_sx; ! 405: oper->scale_o = fp->scale_sx; ! 406: if (fp->flags_sx & (SX_INDXW) ) ! 407: oper->flags_o |= O_PREINDEX|O_WINDEX; ! 408: else ! 409: oper->flags_o |= O_PREINDEX|O_LINDEX; ! 410: } else { ! 411: oper->value_o = 0; ! 412: oper->scale_o = 0; ! 413: } ! 414: break; ! 415: case T_ABSS: ! 416: oper->flags_o = O_WDISP; ! 417: goto normal; ! 418: case T_ABSL: ! 419: oper->flags_o = O_LDISP; ! 420: goto normal; ! 421: case T_NORMAL: ! 422: /* disp@ */ ! 423: /* disp@(d0) */ ! 424: /* index mode, supressed base */ ! 425: oper->flags_o = 0; ! 426: normal: ! 427: oper->type_o = T_INDEX; ! 428: oper->flags_o|= O_BSUPRESS; ! 429: oper->reg_o = A0REG; /* Supress THIS register */ ! 430: oper->disp_o = oper->value_o; ! 431: if (fp->flags_sx&SX_GOTDISP) ! 432: PROG_ERROR(E_OPERAND); ! 433: goto do_index; ! 434: default: ! 435: PROG_ERROR(E_OPERAND); ! 436: } ! 437: #if C2 ! 438: if (fp->flags_sx&SX_CXDISP) ! 439: oper->flags_o |= O_COMPLEX; ! 440: #endif ! 441: } ! 442: ! 443: static ! 444: simplify2( oper, fp, dfp ) ! 445: register struct oper * oper; ! 446: struct suffix *fp; ! 447: register struct suffix *dfp; ! 448: { ! 449: /* ! 450: * we have a memory indirect operand. ! 451: * examples: ! 452: * a0@(disp:l,d0:l:4)@(disp:w) ! 453: * a0@(disp)@(disp,d0:l:4) ! 454: * a0@@ ! 455: * @(disp,d0)@(disp) ! 456: * @(d0)@ ! 457: * @(disp)@ ! 458: * @(disp,d0)@ ! 459: * @(disp)@(d0) ! 460: */ ! 461: simplify1( oper, fp ); ! 462: if (oper->type_o == T_DISPL){ ! 463: oper->type_o = T_INDEX; ! 464: oper->disp_o = oper->value_o; ! 465: oper->value_o = 0; ! 466: } ! 467: /* now build on that with second suffix */ ! 468: oper->flags_o |= O_INDIRECT; ! 469: oper->disp2_o = dfp->disp_sx; ! 470: oper->sym2_o = dfp->sym_sx; ! 471: if (dfp->flags_sx & SX_DISPL) ! 472: oper->flags_o |= O_LDISP2; ! 473: else if (dfp->flags_sx & SX_DISPW) ! 474: oper->flags_o |= O_WDISP2; ! 475: if (dfp->flags_sx & SX_GOTINDEX){ ! 476: if (oper->flags_o&O_PREINDEX) ! 477: PROG_ERROR(E_OPERAND); ! 478: oper->value_o = dfp->indx_sx; ! 479: oper->flags_o |= O_POSTINDEX; ! 480: oper->scale_o = dfp->scale_sx; ! 481: if (dfp->flags_sx&SX_INDXW) ! 482: oper->flags_o |= O_WINDEX; ! 483: else ! 484: oper->flags_o |= O_LINDEX; ! 485: } ! 486: ! 487: #if C2 ! 488: if (fp->flags_sx&SX_CXDISP) ! 489: oper->flags_o |= O_COMPLEX2; ! 490: #endif ! 491: } ! 492: ! 493: /* read expression */ ! 494: char * ! 495: exp(lptr, arg1) ! 496: register char *lptr; ! 497: register struct oper *arg1; ! 498: { ! 499: struct oper arg2; /* holds value of right hand term */ ! 500: register int i; ! 501: static struct oper zero_opr; ! 502: #if AS ! 503: # define MKCOMPLEX( op ) ! 504: #endif ! 505: #if C2 ! 506: # define MKCOMPLEX( op ) if (arg1->sym_o&&arg2.sym_o || \ ! 507: arg1->flags_o&O_COMPLEX || arg2.flags_o&O_COMPLEX){ \ ! 508: ocomplex( op, arg1, &arg2 ); continue; \ ! 509: } ! 510: #endif ! 511: ! 512: skipb(lptr); /* Find the operator */ ! 513: i = cinfo[*lptr]; ! 514: if (i==EOL || i==COM){ /* nil operand is zero */ ! 515: arg1->sym_o = NULL; ! 516: arg1->value_o = 0; ! 517: return(lptr); ! 518: } ! 519: lptr = term( lptr, arg1 ); ! 520: ! 521: while (1) { ! 522: arg2 = zero_opr; ! 523: skipb(lptr); ! 524: switch (cinfo[*lptr]) { ! 525: case ADD: lptr = term( ++lptr, &arg2 ); ! 526: if (arg1->type_o==T_REG || arg2.type_o==T_REG) ! 527: break; ! 528: #if AS ! 529: if (arg1->sym_o && arg2.sym_o) ! 530: if (pass==2) break; ! 531: #endif ! 532: MKCOMPLEX( ADD ); ! 533: if (arg2.sym_o) ! 534: arg1->sym_o = arg2.sym_o; ! 535: arg1->value_o += arg2.value_o; ! 536: arg1->flags_o |= arg2.flags_o&O_COMPLEX; ! 537: continue; ! 538: ! 539: case MUL: lptr = term(++lptr,&arg2); ! 540: if (arg1->type_o==T_REG || arg2.type_o==T_REG) ! 541: break; ! 542: #if AS ! 543: if (arg1->sym_o || arg2.sym_o) ! 544: if (pass==2) break; ! 545: #endif ! 546: MKCOMPLEX( MUL ); ! 547: arg1->value_o *= arg2.value_o; ! 548: arg1->flags_o |= arg2.flags_o&O_COMPLEX; ! 549: continue; ! 550: ! 551: case DIV: lptr = term( ++lptr, &arg2 ); ! 552: if (arg1->type_o==T_REG || arg2.type_o==T_REG) ! 553: break; ! 554: #if AS ! 555: if (arg1->sym_o || arg2.sym_o) ! 556: if (pass==2) break; ! 557: else if (arg2.value_o == 0) arg2.value_o = 1; ! 558: #endif ! 559: MKCOMPLEX( DIV ); ! 560: arg1->value_o /= arg2.value_o; ! 561: arg1->flags_o |= arg2.flags_o&O_COMPLEX; ! 562: continue; ! 563: ! 564: case SUB: lptr = term( ++lptr, &arg2 ); ! 565: if (arg1->type_o==T_REG || arg2.type_o==T_REG) ! 566: break; ! 567: if (arg2.sym_o){ /* if B is relocatable, */ ! 568: if (arg1->sym_o){ /* and A is relocatable, */ ! 569: #if AS ! 570: if (arg2.sym_o->csect_s != arg1->sym_o->csect_s ! 571: && pass == 2){ ! 572: break; /* break into error */ ! 573: } else { ! 574: /* result is absolute (no offset) */ ! 575: arg1->sym_o = NULL; ! 576: /* but not a simple address for sdi's */ ! 577: arg1->flags_o |= O_COMPLEX; ! 578: } ! 579: #endif ! 580: #if C2 ! 581: /* operand cannot be understood at this time */ ! 582: ocomplex( SUB, arg1, &arg2 ); ! 583: continue; ! 584: #endif ! 585: } ! 586: else break; /* if B rel., and A is not, */ ! 587: /* then break into relocation error */ ! 588: } ! 589: arg1->value_o -= arg2.value_o; ! 590: continue; ! 591: ! 592: default: return(lptr); ! 593: } ! 594: PROG_ERROR(E_RELOCATE); ! 595: return(lptr); ! 596: } ! 597: #undef MKCOMPLEX ! 598: } /* end exp <read expression> */ ! 599: ! 600: /* read term: either symbol, constant, or unary minus */ ! 601: char * ! 602: term( lptr, vp ) ! 603: register char *lptr; ! 604: register struct oper *vp; ! 605: { ! 606: register struct sym_bkt *sbp; ! 607: register int base = 10; ! 608: register long val; ! 609: register char *p; ! 610: register int i; ! 611: char savechar, *t; ! 612: char token[50]; ! 613: ! 614: skipb(lptr); ! 615: i = cinfo[*lptr]; ! 616: ! 617: /* here for number */ ! 618: if (i & D){ ! 619: p = lptr; ! 620: val = 0; ! 621: if (*lptr == '0'){ ! 622: lptr++; ! 623: switch( *lptr){ ! 624: case 'x': ! 625: case 'X': ! 626: lptr++; ! 627: /* hexidecimal number */ ! 628: while (1){ ! 629: if (cinfo[*lptr] & D) ! 630: val = val*16 + *lptr++ - '0'; ! 631: else if (*lptr>='A' && *lptr<='F') ! 632: val = val*16 + *lptr++ - 'A' + 10; ! 633: else if (*lptr>='a' && *lptr<='f') ! 634: val = val*16 + *lptr++ - 'a' + 10; ! 635: else break; ! 636: } ! 637: break; ! 638: case 'f': ! 639: /* ! 640: * be careful not to confuse the floating-point ! 641: * constant 0f0.0 with the local label reference * 0f . ! 642: * for legitimate floating constants, the next ! 643: * character can be a digit, a decimal point, ! 644: * a negative sign, or one of the letters ! 645: * 'n', 'N', 'i', or 'I'. ! 646: */ ! 647: switch (*(lptr+1)){ ! 648: case '0':case '1':case '2':case '3':case '4': ! 649: case '5': case '6':case '7':case '8':case '9': ! 650: case '.': case '-': case '+': ! 651: case 'n':case 'N': case 'i':case 'I': ! 652: break; ! 653: default: ! 654: val = 0; ! 655: goto got_a_number; ! 656: } ! 657: /* FALL THROUGH */ ! 658: case 'F': ! 659: case 'R': ! 660: case 'r': ! 661: lptr = scan_float( lptr, vp ); ! 662: return (lptr); ! 663: default: ! 664: /* octal number */ ! 665: while (cinfo[*lptr] & D){ ! 666: if (*lptr == '8' || *lptr == '9') ! 667: PROG_ERROR(E_CONSTANT); ! 668: val = val*8 + *lptr++ - '0'; ! 669: } ! 670: } ! 671: } else { ! 672: /* decimal number */ ! 673: while (cinfo[*lptr] & D) ! 674: val = val*10 + *lptr++ - '0'; ! 675: } ! 676: got_a_number: ! 677: if (*lptr == '$') ! 678: { lptr = p; goto sym; } ! 679: if (*lptr == 'b' || *lptr == 'f'){ ! 680: /* local label reference, of form [0-9][bh] */ ! 681: /* single digits only */ ! 682: if (lptr > p+1 ){ ! 683: PROG_ERROR(E_SYMLEN); ! 684: } ! 685: val = ll_val[*p-'0'] + (*lptr++=='f'); ! 686: if (val < 0 ) PROG_ERROR(E_SYMDEF); ! 687: sprintf(token, ll_format, *p, val); ! 688: sbp = lookup(token); ! 689: goto sym2; ! 690: ! 691: } ! 692: vp->value_o = val; ! 693: vp->sym_o = NULL; ! 694: vp->type_o = T_NORMAL; ! 695: return(lptr); ! 696: } ! 697: ! 698: /* here for symbol name */ ! 699: if (i & S) { ! 700: sym: t = lptr; ! 701: while (cinfo[*lptr] & T) ! 702: lptr++; ! 703: savechar = *lptr; ! 704: *lptr = '\0'; ! 705: sbp = lookup(t); /* find its symbol bucket */ ! 706: *lptr = savechar; ! 707: sym2: ! 708: #if C2 ! 709: sbp->nuse_s++; ! 710: #endif ! 711: if (sbp->attr_s & S_DEF ! 712: #if C2 ! 713: && sbp->csect_s == C_UNDEF ! 714: #endif ! 715: ){ ! 716: /* if it's defined, use its value */ ! 717: vp->value_o = sbp->value_s; ! 718: } else ! 719: vp->value_o = 0; ! 720: if (sbp->attr_s & S_REG){ ! 721: vp->type_o = T_REG; ! 722: vp->sym_o = NULL; ! 723: } else { ! 724: vp->sym_o = ((sbp->attr_s & S_DEF) && ! 725: (sbp->csect_s == C_UNDEF )) ? 0 : sbp; ! 726: vp->type_o = T_NORMAL; ! 727: } ! 728: return(lptr); ! 729: } ! 730: ! 731: /* check for unary minus */ ! 732: if (i == SUB) { ! 733: lptr = term(++lptr,vp); ! 734: if (vp->sym_o){ ! 735: #if AS ! 736: PROG_ERROR(E_RELOCATE); ! 737: #endif ! 738: #if C2 ! 739: if (vp->sym_o){ ! 740: ocomplex( SUB, vp, 0); ! 741: return(lptr); ! 742: } ! 743: #endif ! 744: } ! 745: vp->value_o = -(vp->value_o); ! 746: return(lptr); ! 747: } ! 748: ! 749: /* check for complement */ ! 750: if (i == NOT) { ! 751: lptr = term(++lptr,vp); ! 752: if (vp->sym_o){ ! 753: #if AS ! 754: PROG_ERROR(E_RELOCATE); ! 755: #endif ! 756: #if C2 ! 757: if (vp->sym_o){ ! 758: ocomplex( NOT, vp, 0); ! 759: return(lptr); ! 760: } ! 761: #endif ! 762: } ! 763: vp->value_o = ~(vp->value_o); ! 764: return(lptr); ! 765: } ! 766: ! 767: /* here for string */ ! 768: if (i == QUO) { ! 769: vp->stringval_o = lptr+1; ! 770: /* scan over the quoted string, being careful of \-stuff */ ! 771: do{ ! 772: i = *++lptr; ! 773: if (i=='\\') ! 774: switch (i = *++lptr){ ! 775: case '"': i = '\\'; /* fake-out loop test by covering up \"*/ ! 776: } ! 777: }while (i!='\n' && i!='"'); ! 778: if (i == '\n'){ ! 779: PROG_ERROR(E_STRING); ! 780: } ! 781: *lptr++ = 0; ! 782: vp->sym_o = NULL; ! 783: vp->type_o = T_STRING; ! 784: return(lptr); ! 785: } ! 786: ! 787: /* new, improved kluge -- parens !! */ ! 788: if (i==LP) { ! 789: lptr = exp(++lptr, vp); ! 790: skipb(lptr); ! 791: if ((i=cinfo[*lptr]) == RP) { ! 792: lptr++; ! 793: } else { ! 794: PROG_ERROR( E_PAREN ); ! 795: } ! 796: return( lptr ); ! 797: } ! 798: ! 799: PROG_ERROR(E_TERM); ! 800: return(lptr); ! 801: } /* end term */ ! 802: ! 803: char * ! 804: scan_float( lptr, vp ) ! 805: register char * lptr; ! 806: struct oper *vp; ! 807: { ! 808: /* ! 809: * lptr address a string which is a 'd' or an 'f', followed ! 810: * by a floating-point number. The latter looks like: ! 811: * [+-]nan( [0-9a-f]+ ) ! 812: * or [+-]inf ! 813: * or [+-][0-9]+[.[0-9]+][e[+-][0-9]+] ! 814: * in the latter case, we call atof to do the conversion work. ! 815: * We do not take great care in syntax checking the number. ! 816: */ ! 817: int s=0; ! 818: union{ double d; float f; int x[2]; } fp; ! 819: unsigned nanno, nanno2; ! 820: register char *nbegin; ! 821: char c; ! 822: ! 823: lptr++; /* skip the f */ ! 824: nbegin = lptr; ! 825: again: ! 826: switch ( *lptr++){ ! 827: case '+': if (s) goto bad_num; s = 1; goto again; ! 828: case '-': if (s) goto bad_num; s = -1; goto again; ! 829: case 'N': ! 830: case 'n': /* nan */ ! 831: if (*lptr++ != 'a') goto bad_num; ! 832: if (*lptr++ != 'n') goto bad_num; ! 833: if (*lptr++ != '(') goto bad_num; ! 834: nanno = nanno2 = 0; ! 835: while( isxdigit(c = *lptr++)){ ! 836: if (isdigit(c)) c -= '0'; ! 837: else if (isupper(c)) c -= 'a'-10; ! 838: else c -= 'A'-10; ! 839: nanno2 = (nanno2 << 8) | (nanno >> 24); ! 840: nanno = (nanno<<8) | c; ! 841: } ! 842: if (c != ')') goto bad_num; ! 843: goto make_indef; ! 844: ! 845: case 'I': ! 846: case 'i': /* inf */ ! 847: if (*lptr++ != 'n') goto bad_num; ! 848: if (*lptr++ != 'f') goto bad_num; ! 849: if (strncmp(lptr,"inity",5) == 0) ! 850: lptr += 5; ! 851: nanno = nanno2 = 0; ! 852: make_indef: ! 853: fp.x[0] = ((s<0)?0xfff00000:0x7ff00000) | nanno2; ! 854: fp.x[1] = nanno; ! 855: break; ! 856: case '0': case '1': case '2': case '3': case '4': ! 857: case '5': case '6': case '7': case '8': case '9': ! 858: /* scan for more digits */ ! 859: while( isdigit( c = *lptr++ ) ) ! 860: continue; ! 861: if (c != '.' ) ! 862: goto scan_exp; ! 863: /* FALL THROUGH */ ! 864: case '.': ! 865: /* scan for more digits */ ! 866: while( isdigit( c = *lptr++ ) ) ! 867: continue; ! 868: scan_exp: ! 869: s = 0; ! 870: switch(c){ ! 871: case '+': ! 872: case '-': ! 873: s = 1; ! 874: /* FALL THROUGH */ ! 875: case 'e': ! 876: case 'E': ! 877: switch ( c= *lptr++ ){ ! 878: case '+': ! 879: case '-': ! 880: if (s) goto bad_num; ! 881: c = *lptr++; ! 882: /* FALL THROUGH */ ! 883: default: ! 884: s = 0; /* count chars: 0 is not ok */ ! 885: while( isdigit(c) ){ ! 886: c = *lptr++; ! 887: s++; ! 888: } ! 889: if (s == 0) goto bad_num; ! 890: break; ! 891: } ! 892: break; ! 893: } ! 894: fp.d = atof( nbegin ); ! 895: lptr--; ! 896: break; ! 897: default: ! 898: bad_num: ! 899: PROG_ERROR( E_BADCHAR ); ! 900: return lptr; ! 901: } ! 902: vp->fval_o = fp.d; ! 903: vp->type_o = T_FLOAT; ! 904: return lptr; ! 905: } ! 906: ! 907: ! 908: static void ! 909: printoffset( value, sym, cmplx ) ! 910: int value; ! 911: struct sym_bkt *sym; ! 912: int cmplx; ! 913: { ! 914: register struct optree *ot; ! 915: register char c = '?'; ! 916: struct oper *op; ! 917: if (cmplx){ ! 918: ot = (struct optree*)sym; ! 919: if (ot->right_t == NULL){ ! 920: /* unary operation */ ! 921: switch(ot->op_t){ ! 922: case SUB: c = '-'; break; ! 923: case NOT: c = '~'; break; ! 924: } ! 925: printf("%c(",c); ! 926: op=ot->left_t; ! 927: printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX); ! 928: putchar(')'); ! 929: } else { ! 930: /* binary */ ! 931: putchar('('); ! 932: op=ot->left_t; ! 933: printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX); ! 934: switch(ot->op_t){ ! 935: case ADD: c = '+'; break; ! 936: case SUB: c = '-'; break; ! 937: case MUL: c = '*'; break; ! 938: case DIV: c = '/'; break; ! 939: } ! 940: printf(")%c(", c); ! 941: op=ot->right_t;; ! 942: printoffset(op->value_o, op->sym_o, op->flags_o&O_COMPLEX); ! 943: putchar(')'); ! 944: } ! 945: return; ! 946: } ! 947: if (sym != NULL){ ! 948: fputs(sym->name_s, stdout); ! 949: if (value) ! 950: printf("+%d", value); ! 951: } else { ! 952: printf("%d", value); ! 953: } ! 954: } ! 955: ! 956: ! 957: char *rnames[] = { ! 958: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", ! 959: "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", ! 960: "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7", ! 961: "cc", "fcc", "pc", "sr", "usp", "sfc", "dfc", "vbr", ! 962: "cacr", "caar", "msp", "isp", "fpc", "fps", "fpi" ! 963: }; ! 964: ! 965: static void ! 966: printindex( o ) ! 967: register struct oper *o; ! 968: { ! 969: printf("%s:%c", rnames[o->value_o], o->flags_o&O_WINDEX ? 'w' : 'l'); ! 970: if (o->scale_o != 1) printf(":%d", o->scale_o); ! 971: } ! 972: ! 973: printoperand( o ) ! 974: register struct oper *o; ! 975: { ! 976: switch (o->type_o){ ! 977: case T_REG: printf("%s", rnames[o->value_o]); break; ! 978: case T_DEFER: printf("%s@", rnames[o->value_o]); break; ! 979: case T_POSTINC: printf("%s@+", rnames[o->value_o]); break; ! 980: case T_PREDEC: printf("%s@-", rnames[o->value_o]); break; ! 981: case T_DISPL: printf("%s@(", rnames[o->reg_o]); ! 982: printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX); ! 983: putchar(')'); ! 984: break; ! 985: case T_INDEX: ! 986: if (!(o->flags_o&O_BSUPRESS)){ ! 987: printf("%s@", rnames[o->reg_o]); ! 988: } ! 989: putchar('('); ! 990: printoffset(o->disp_o, o->sym_o, o->flags_o&O_COMPLEX); ! 991: if (o->flags_o & O_WDISP) fputs(":w", stdout); ! 992: else if (o->flags_o & O_LDISP) fputs(":l", stdout); ! 993: if (o->flags_o&O_PREINDEX){ ! 994: putchar(','); ! 995: printindex( o ); ! 996: } ! 997: putchar(')'); ! 998: if (o->flags_o&O_INDIRECT){ ! 999: putchar('@'); ! 1000: if (o->disp2_o || o->sym2_o || o->flags_o&O_POSTINDEX){ ! 1001: putchar('('); ! 1002: if (o->disp2_o || o->sym2_o ){ ! 1003: printoffset(o->disp2_o, o->sym2_o, o->flags_o&O_COMPLEX2); ! 1004: if (o->flags_o&O_POSTINDEX) ! 1005: putchar(','); ! 1006: } ! 1007: if (o->flags_o&O_POSTINDEX){ ! 1008: printindex( o ); ! 1009: } ! 1010: putchar(')'); ! 1011: } ! 1012: } ! 1013: break; ! 1014: case T_ABSS: ! 1015: case T_ABSL: ! 1016: printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX); ! 1017: fputs( (o->type_o == T_ABSS) ? ":w" : ":l", stdout); ! 1018: break; ! 1019: case T_IMMED: ! 1020: putchar('#'); ! 1021: if (o->flags_o & O_FLOAT) goto float_val; ! 1022: /* FALL THROUGH */ ! 1023: case T_NORMAL: ! 1024: printoffset(o->value_o, o->sym_o, o->flags_o&O_COMPLEX); ! 1025: break; ! 1026: case T_STRING: ! 1027: printf("\"%s\"", o->stringval_o); ! 1028: break; ! 1029: case T_REGPAIR: printf("%s:%s", rnames[o->value_o],rnames[o->reg_o]); ! 1030: break; ! 1031: float_val: ! 1032: case T_FLOAT: printf("0r%.17e", o->fval_o); ! 1033: break; ! 1034: default: ! 1035: printf("UNKNOWN(%d)", o->type_o); ! 1036: break; ! 1037: } ! 1038: if (o->flags_o&O_BFLD){ ! 1039: /* bit field */ ! 1040: /* first the offset part */ ! 1041: if (o->flags_o&O_BFOREG) ! 1042: printf("{%s:",rnames[o->bfoffset_o]); ! 1043: else ! 1044: printf("{#%d:",o->bfoffset_o); ! 1045: /* then the width part */ ! 1046: if (o->flags_o&O_BFWREG) ! 1047: printf("%s}",rnames[o->bfwidth_o]); ! 1048: else ! 1049: printf("#%d}",o->bfwidth_o); ! 1050: } ! 1051: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.