|
|
1.1 ! root 1: head 1.2; ! 2: access ; ! 3: symbols ; ! 4: locks bin:1.2; ! 5: comment @ * @; ! 6: ! 7: ! 8: 1.2 ! 9: date 91.02.06.20.44.23; author bin; state Exp; ! 10: branches ; ! 11: next 1.1; ! 12: ! 13: 1.1 ! 14: date 91.02.06.20.44.12; author bin; state Exp; ! 15: branches ; ! 16: next ; ! 17: ! 18: ! 19: desc ! 20: @steve 2/6/91 ! 21: Initial MWC RCS revision. ! 22: @ ! 23: ! 24: ! 25: 1.2 ! 26: log ! 27: @steve 2/6/91 ! 28: Extensive changes from cef: descriptive error messages, bug fixes, ! 29: who knows what else. ! 30: @ ! 31: text ! 32: @/* ! 33: * Instruction formatting ! 34: * and decoding. This is for the Intel ! 35: * iAPX-86 microprocessor. ! 36: * Small addressing model (perhaps with ! 37: * separated CS and SS,DS,ES). ! 38: * No formatting for the large model calls, ! 39: * returns or jumps. ! 40: */ ! 41: #include "asm.h" ! 42: ! 43: /* ! 44: * Branch map. ! 45: */ ! 46: int *bp; ! 47: int bm; ! 48: int bb[NB]; ! 49: ! 50: /* ! 51: * Read and format machine instructions. ! 52: * The argument `sp' is a pointer to the symbol ! 53: * table entry of the opcode. The `s_kind' field ! 54: * holds the operation kind; this determines the ! 55: * format and the semantics of the operation. ! 56: */ ! 57: machine(sp) ! 58: struct sym *sp; ! 59: { ! 60: register op, m1, m2; ! 61: struct expr e1, e2; ! 62: int disp, flag, ob, rf, si, rn; ! 63: ! 64: op = sp->s_addr; ! 65: switch (sp->s_kind) { ! 66: ! 67: case S_EVEN: ! 68: if ((dot->s_addr&01) != 0) { ! 69: if (inbss == 0) ! 70: outab(0); ! 71: else ! 72: ++dot->s_addr; ! 73: } ! 74: lmode = ALIST; ! 75: break; ! 76: ! 77: case S_ODD: ! 78: if ((dot->s_addr&01) == 0) { ! 79: if (inbss == 0) ! 80: outab(0); ! 81: else ! 82: ++dot->s_addr; ! 83: } ! 84: lmode = ALIST; ! 85: break; ! 86: ! 87: case S_INH: ! 88: outab(op); ! 89: if (op==AAM || op==AAD) /* Need suffix byte */ ! 90: outab(APB); ! 91: break; ! 92: ! 93: case S_INT: ! 94: expr(&e1, 0); ! 95: if (isabsn(&e1, 3)) { ! 96: outab(INT3); ! 97: break; ! 98: } ! 99: outab(INT); ! 100: outrb(&e1, 0); ! 101: break; ! 102: ! 103: case S_SYS: ! 104: expr(&e1, 0); ! 105: if (e1.e_type == E_ACON) { ! 106: outab(INT); ! 107: e1.e_addr += 128; ! 108: outrb(&e1, 0); ! 109: break; ! 110: } ! 111: aerr("expected constant"); ! 112: break; ! 113: ! 114: case S_OVER: ! 115: if (addr(&e1) == SEGR) { ! 116: out3(SEGPFX, rof(e1)); ! 117: break; ! 118: } ! 119: aerr("segment override by non-segment register"); ! 120: break; ! 121: ! 122: case S_RET: ! 123: if (more() == 0) { ! 124: outab(op); ! 125: break; ! 126: } ! 127: expr(&e1, 0); ! 128: outab(op-1); /* Use ret n form */ ! 129: outrw(&e1, 0); ! 130: break; ! 131: ! 132: case S_PUSH: ! 133: m1 = addr(&e1); ! 134: rn = rof(e1); ! 135: if (m1 == SEGR) { ! 136: if (op == PUSH) ! 137: out3(PUSHSR, rn); ! 138: else { ! 139: if (e1.e_mode == CS) /* No pop CS */ ! 140: aerr("no 'pop CS' instruction"); ! 141: out3(POPSR, rn); ! 142: } ! 143: break; ! 144: } ! 145: if (m1 == WR) { ! 146: if (op == PUSH) ! 147: outab(PUSHR | rn); ! 148: else ! 149: outab(POPR | rn); ! 150: break; ! 151: } ! 152: if ( m1 == IM ) { ! 153: if ( (e1.e_type == E_ACON) ! 154: && ( ((e1.e_addr & 0xFF80) == 0xFF80) ! 155: || ((e1.e_addr & 0xFF80) == 0x0000) ) ) { ! 156: outab( PUSHIB ); ! 157: outab( e1.e_addr ); ! 158: } ! 159: else { ! 160: outab( PUSHIW ); ! 161: outrw(&e1, 0); ! 162: } ! 163: break; ! 164: } ! 165: outgen(op, ((op==PUSH) ? 6 : 0), &e1); ! 166: break; ! 167: ! 168: case S_IN: ! 169: m1 = addr(&e1); ! 170: comma(); ! 171: m2 = addr(&e2); ! 172: IN_OUT: ! 173: if (m1 == WR && rof(e1) == AX) ! 174: op |= W; ! 175: else if (m1 == BR && rof(e1) == reg(AL)) ! 176: op &= ~W; ! 177: else { ! 178: aerr("(in|out)(b|) must use AX or AL"); ! 179: break; ! 180: } ! 181: if (m2 == WR && rof(e2) == DX) { ! 182: outab(op|010); ! 183: break; ! 184: } else if (m2 == DIR) { ! 185: outab(op); ! 186: outrb(&e2, 0); ! 187: break; ! 188: } ! 189: aerr("(in|out)(b|) must use DX or constant"); ! 190: break; ! 191: ! 192: case S_OUT: ! 193: m2 = addr(&e2); ! 194: comma(); ! 195: m1 = addr(&e1); ! 196: goto IN_OUT; ! 197: ! 198: case S_SHL: ! 199: case S_SHLB: ! 200: m1 = addr(&e1); ! 201: comma(); ! 202: m2 = addr(&e2); ! 203: ob = SHL; ! 204: if (sp->s_kind == S_SHL) ! 205: ob |= W; ! 206: bytecheck(ob, m1, NONE); ! 207: if (m2 == BR && e2.e_addr == CL) ! 208: ob |= V; ! 209: else if ( (m2 == IM) && (e2.e_type == E_ACON) ) { ! 210: if ( e2.e_addr != 1 ) ! 211: ob = (ob & W) ? (SHLI|W) : SHLI; ! 212: } ! 213: else ! 214: aerr("Improper shift amount"); ! 215: outgen(ob, op, &e1); ! 216: if ( (ob & ~W) == SHLI ) ! 217: outab( e2.e_addr ); ! 218: break; ! 219: ! 220: case S_JMP: ! 221: if (addr(&e1) != DIR) ! 222: aerr("jmp must be direct address"); ! 223: if (pass == 0) { ! 224: dot->s_addr += 3; ! 225: if (op != JMP) ! 226: dot->s_addr += 2; ! 227: } else if (pass == 1) { ! 228: if (e1.e_type != E_DIR ! 229: || e1.e_base.e_lp != dot->s_base.s_lp) { ! 230: /* long */ ! 231: dot->s_addr += 3; ! 232: if (op != JMP) ! 233: dot->s_addr += 2; ! 234: flag = 1; ! 235: } else { ! 236: if (e1.e_addr >= dot->s_addr) ! 237: e1.e_addr -= fuzz; ! 238: dot->s_addr += 2; ! 239: disp = e1.e_addr - dot->s_addr; ! 240: flag = 0; ! 241: if (disp<-128 || disp>127) { ! 242: /* long */ ! 243: flag = 1; ! 244: ++dot->s_addr; ! 245: if (op != JMP) ! 246: dot->s_addr += 2; ! 247: } ! 248: } ! 249: setbit(flag); ! 250: } else if (getbit()) { ! 251: if (op != JMP) { ! 252: outab(op ^ 01); ! 253: outab(03); ! 254: } ! 255: outab(0xE9); ! 256: outrw(&e1, 1); ! 257: } else { ! 258: disp = e1.e_addr - dot->s_addr - 2; ! 259: outab(op); ! 260: outab(disp); ! 261: } ! 262: break; ! 263: ! 264: case S_REL: ! 265: if (addr(&e1) != DIR ! 266: || e1.e_type != E_DIR ! 267: || e1.e_base.e_lp != dot->s_base.s_lp) ! 268: aerr("not a direct address in this segment"); ! 269: disp = e1.e_addr - dot->s_addr - 2; ! 270: if (disp<-128 || disp>127) ! 271: aerr("address out of range"); ! 272: outab(op); ! 273: outab(disp); ! 274: break; ! 275: ! 276: case S_IJMP: ! 277: addr(&e1); ! 278: outgen(IJORC, op, &e1); ! 279: break; ! 280: ! 281: case S_CALL: ! 282: if (addr(&e1) != DIR) ! 283: aerr("not a direct address"); ! 284: outab(DCALL); ! 285: outrw(&e1, 1); ! 286: break; ! 287: ! 288: case S_DOP: ! 289: m1 = addr(&e1); ! 290: comma(); ! 291: m2 = addr(&e2); ! 292: bytecheck(op, m1, m2); ! 293: if (m2 == IM) { ! 294: si = 0; ! 295: if (isalax(&e1)) { ! 296: if (op == TESTW) ! 297: op = TESTAW; ! 298: else if (op == TESTB) ! 299: op = TESTAB; ! 300: else ! 301: op |= 04; ! 302: outab(op); ! 303: } else { ! 304: if (op==TESTW || op==TESTB) { ! 305: rf = 0; ! 306: if (op == TESTW) ! 307: op = TESTMW; ! 308: else ! 309: op = TESTMB; ! 310: } else { ! 311: rf = (op&070)>>3; ! 312: op = (op&W)|0200; ! 313: if (ishort(sp, &e2)) { ! 314: ++si; ! 315: op |= S; ! 316: } ! 317: } ! 318: outgen(op, rf, &e1); ! 319: } ! 320: if (si || (op&W)==0) ! 321: outrb(&e2, 0); ! 322: else ! 323: outrw(&e2, 0); ! 324: break; ! 325: } ! 326: /* Dest is reg */ ! 327: if (m1==BR || m1==WR) { ! 328: if (op!=TESTB && op!=TESTW) ! 329: op |= D; ! 330: outgen(op, rof(e1), &e2); ! 331: break; ! 332: } ! 333: /* Dest is mem */ ! 334: outgen(op, rof(e2), &e1); ! 335: break; ! 336: ! 337: case S_XCHG: ! 338: m1 = addr(&e1); ! 339: comma(); ! 340: m2 = addr(&e2); ! 341: bytecheck(op, m1, m2); ! 342: if (m1==WR && m2==WR) { ! 343: if (isalax(&e1)) { ! 344: outab(XCHGR | rof(e2)); ! 345: break; ! 346: } ! 347: if (isalax(&e2)) { ! 348: outab(XCHGR | rof(e1)); ! 349: break; ! 350: } ! 351: } ! 352: if (m1==BR || m1==WR) { ! 353: outgen(op, rof(e1), &e2); ! 354: break; ! 355: } ! 356: if (m2==BR || m2==WR) { ! 357: outgen(op, rof(e2), &e1); ! 358: break; ! 359: } ! 360: aerr("improper operand pair"); ! 361: break; ! 362: ! 363: case S_SOP: ! 364: case S_SOPB: ! 365: m1 = addr(&e1); ! 366: ob = (op < 2) ? INCDEC : NOTNEG; ! 367: if (sp->s_kind == S_SOP) ! 368: ob |= W; ! 369: bytecheck(ob, m1, NONE); ! 370: if (op<2 && m1==WR) { ! 371: outab(IDREG | (op<<3) | rof(e1)); ! 372: break; ! 373: } ! 374: outgen(ob, op, &e1); ! 375: break; ! 376: ! 377: case S_ESC: ! 378: addr(&e1); ! 379: outgen(ESC, 0, &e1); ! 380: break; ! 381: ! 382: case S_LEA: ! 383: m1 = addr(&e1); ! 384: comma(); ! 385: m2 = addr(&e2); ! 386: if (m1!=WR) ! 387: aerr("must load address into register"); ! 388: if(m2!=DIR && m2!=X) ! 389: aerr("must load direct address"); ! 390: outgen(op, rof(e1), &e2); ! 391: break; ! 392: ! 393: case S_MOV: ! 394: m1 = addr(&e1); ! 395: comma(); ! 396: m2 = addr(&e2); ! 397: bytecheck(op, m1, m2); ! 398: if (m2 == IM) { ! 399: if (m1 == BR) { ! 400: outab(MVIB | rof(e1)); ! 401: outrb(&e2, 0); ! 402: break; ! 403: } ! 404: if (m1 == WR) { ! 405: outab(MVIW | rof(e1)); ! 406: outrw(&e2, 0); ! 407: break; ! 408: } ! 409: /* To memory */ ! 410: outgen((MVI|(op&W)), 0, &e1); ! 411: if ((op&W) == 0) ! 412: outrb(&e2, 0); ! 413: else ! 414: outrw(&e2, 0); ! 415: break; ! 416: } ! 417: /* Quick load */ ! 418: if (isalax(&e1) && m2==DIR) { ! 419: outab(MOVMA|(op&W)); ! 420: outrw(&e2, 0); ! 421: break; ! 422: } ! 423: /* Quick store */ ! 424: if (m1==DIR && isalax(&e2)) { ! 425: outab(MOVAM|(op&W)); ! 426: outrw(&e1, 0); ! 427: break; ! 428: } ! 429: if (m1 == SEGR) ! 430: outgen(MOVSEG|D, rof(e1), &e2); ! 431: else if (m2 == SEGR) ! 432: outgen(MOVSEG, rof(e2), &e1); ! 433: else if (m1==WR || m1==BR) ! 434: outgen(op|D, rof(e1), &e2); ! 435: else ! 436: outgen(op, rof(e2), &e1); ! 437: break; ! 438: ! 439: case S_MUL: ! 440: case S_MULB: ! 441: m1 = addr(&e1); ! 442: ob = MULDIV; ! 443: if (sp->s_kind == S_MUL) ! 444: ob |= W; ! 445: bytecheck(ob, m1, NONE); ! 446: outgen(ob, op, &e1); ! 447: break; ! 448: case S_PROT0: ! 449: case S_PROT1: ! 450: /* ! 451: * Protection control. ! 452: */ ! 453: m1 = addr(&e1); ! 454: if ( (m1 != WR) && (m1 != DIR) && (m1 != X) ) ! 455: aerr(); ! 456: outab( 0x0F ); ! 457: outgen( (sp->s_kind == S_PROT0) ? 0x00 : 0x01, op, &e1 ); ! 458: break; ! 459: ! 460: case S_PROTR: ! 461: /* ! 462: * Protection control to register. ! 463: */ ! 464: if ( op == ARPL ) { ! 465: m2 = addr(&e2); ! 466: comma(); ! 467: m1 = addr(&e1 ); ! 468: } ! 469: else if ( op == CLTS ) { ! 470: outab( 0x0F ); ! 471: outab( op ); ! 472: break; ! 473: } ! 474: else { ! 475: m1 = addr(&e1); ! 476: comma(); ! 477: m2 = addr(&e2); ! 478: } ! 479: if (m1!=WR || (m2!=WR &&m2!=DIR && m2!=X)) ! 480: aerr("Improper operand"); ! 481: if ( op != ARPL ) ! 482: outab( 0x0F ); ! 483: outgen(op, rof(e1), &e2); ! 484: break; ! 485: ! 486: case S_ENTER: ! 487: m1 = addr(&e1); ! 488: comma(); ! 489: m2 = addr(&e2); ! 490: if ( (m1 != DIR) || (e1.e_type != E_ACON) ! 491: || (m2 != DIR) || (e2.e_type != E_ACON) ) ! 492: aerr(); ! 493: outab( op ); ! 494: outrw( &e1, 0); ! 495: outrb( &e2, 0 ); ! 496: break; ! 497: ! 498: /* Floating point operations. */ ! 499: /* No operands. */ ! 500: case S_FP_F: ! 501: outab((sp->s_flag==S_NW) ? FNOP : FWAIT); ! 502: outab(BYTE1(op)); ! 503: outab(BYTE2(op)); ! 504: break; ! 505: /* Memory operand. */ ! 506: case S_FP_M: ! 507: outab((sp->s_flag==S_NW) ? FNOP : FWAIT); ! 508: m1 = addr(&e1); ! 509: if (m1 != DIR && m1 != X) ! 510: qerr("invalid operand type"); ! 511: outgen(BYTE1(op), BYTE2(op), &e1); ! 512: break; ! 513: /* Two optional fp stack operands. */ ! 514: /* The opcode in the table is for the format "f<op> st<n>,st". */ ! 515: /* Some nasty fudging here; thanks again, Intel. */ ! 516: case S_FP_S: ! 517: outab(FWAIT); ! 518: if (fp_reg2(&e1, &e2)) { ! 519: if (e1.e_mode == ST) { ! 520: /* "f<op> st,st<n>". */ ! 521: /* Change BYTE1 from 0xDC to 0xD8. */ ! 522: outab(BYTE1(op)^4); ! 523: if (sp->s_flag == S_FIX) ! 524: outab((BYTE2(op)^8)|rof(e2)); ! 525: else ! 526: outab(BYTE2(op)|rof(e2)); ! 527: } ! 528: else { ! 529: /* "f<op> st<n>,st". */ ! 530: outab(BYTE1(op)); ! 531: outab(BYTE2(op)|rof(e1)); ! 532: } ! 533: } ! 534: else { /* No args supplied; "f<op>" means "f<op>p st1,st". */ ! 535: /* Change BYTE1 from 0xDC to 0xDE. */ ! 536: outab(BYTE1(op)|2); ! 537: outab(BYTE2(op)|1); ! 538: } ! 539: break; ! 540: /* Two optional fp stack operands. */ ! 541: case S_FP_SP: ! 542: fp_reg2(&e1, &e2); ! 543: if (e2.e_mode != ST) ! 544: qerr("invalid operand type"); ! 545: outab(FWAIT); ! 546: outab(BYTE1(op)); ! 547: outab((BYTE2(op))|rof(e1)); ! 548: break; ! 549: /* One optional fp stack operand (default: ST). */ ! 550: case S_FP_S1: ! 551: fp_reg(&e1); ! 552: outab(FWAIT); ! 553: outab(BYTE1(op)); ! 554: outab(BYTE2(op)|rof(e1)); ! 555: break; ! 556: ! 557: default: ! 558: err('o', "unknown operator"); ! 559: } ! 560: } ! 561: ! 562: /* ! 563: * Check if the next non blank ! 564: * character is a comma. Give an error if ! 565: * not (and give up). ! 566: */ ! 567: comma() ! 568: { ! 569: if (getnb() != ',') ! 570: qerr("expected comma"); ! 571: } ! 572: ! 573: /* ! 574: * Output `general' format instructions. ! 575: * `Op' is the opcode, `r' is the general ! 576: * register (bits 3-5 of the postbyte) and ! 577: * `esp' is an address. ! 578: * The address must not be the flags, a ! 579: * segment register, (dx) or an immediate ! 580: * thing. ! 581: */ ! 582: outgen(op, r, esp) ! 583: register struct expr *esp; ! 584: { ! 585: register disp, mode, regm; ! 586: ! 587: outab(op); ! 588: mode = esp->e_mode & MMASK; ! 589: regm = esp->e_mode & RMASK; ! 590: if (mode==IDX || mode==ICL || mode==IM || mode==SEGR) { ! 591: aerr("invalid operand"); ! 592: return; ! 593: } ! 594: if (mode==BR || mode==WR) { ! 595: outab(0300 | (r<<3) | regm); ! 596: return; ! 597: } ! 598: if (mode == DIR) { ! 599: outab(0006 | (r<<3)); ! 600: outrw(esp, 0); ! 601: return; ! 602: } ! 603: /* Mode is X */ ! 604: if (esp->e_type == E_ACON) { ! 605: disp = esp->e_addr; /* Displacement */ ! 606: if (regm!=6 && disp==0) { ! 607: outab((r<<3) | regm); ! 608: return; ! 609: } ! 610: if (disp>=-128 && disp<=127) { ! 611: outab(0100 | (r<<3) | regm); ! 612: outab(disp); ! 613: return; ! 614: } ! 615: } ! 616: outab(0200 | (r<<3) | regm); ! 617: outrw(esp, 0); ! 618: } ! 619: ! 620: /* ! 621: * Output a byte that looks like ! 622: * `bbbbbaaa'; this is a somewhat common ! 623: * format on the iAPX-86. ! 624: */ ! 625: out3(a, b) ! 626: { ! 627: outab(a | (b<<3)); ! 628: } ! 629: ! 630: /* ! 631: * Some consistancy checks. ! 632: * The `op' is an opcode with a valid `W' bit. ! 633: * `m1' and `m2' are modes. ! 634: */ ! 635: bytecheck(op, m1, m2) ! 636: register op, m1, m2; ! 637: { ! 638: register bad; ! 639: ! 640: bad = 0; ! 641: if (m1 == BR) { ! 642: if ((op&W) != 0) ! 643: ++bad; ! 644: if (m2==WR || m2==SEGR) ! 645: ++bad; ! 646: } ! 647: if (m1==WR || m1==SEGR) { ! 648: if ((op&W) == 0) ! 649: ++bad; ! 650: if (m2 == BR) ! 651: ++bad; ! 652: } ! 653: if (m2 == BR) { ! 654: if ((op&W) != 0) ! 655: ++bad; ! 656: if (m1==WR || m1==SEGR) ! 657: ++bad; ! 658: } ! 659: if (m2==WR || m2==SEGR) { ! 660: if ((op&W) == 0) ! 661: ++bad; ! 662: if (m1 == BR) ! 663: ++bad; ! 664: } ! 665: if (bad) ! 666: aerr("invalid operand"); ! 667: } ! 668: ! 669: /* ! 670: * Check to see if an address is ! 671: * one of the two machine accumulator registers. ! 672: * (AX or AL). ! 673: * True return if so. ! 674: */ ! 675: isalax(esp) ! 676: register struct expr *esp; ! 677: { ! 678: if (esp->e_mode==AX || esp->e_mode==AL) ! 679: return (1); ! 680: return (0); ! 681: } ! 682: ! 683: /* ! 684: * Set up the big bit table ! 685: * used by the branch adjustment code. ! 686: */ ! 687: minit() ! 688: { ! 689: bp = bb; ! 690: bm = 1; ! 691: } ! 692: ! 693: /* ! 694: * Store `b' in the next slot of the ! 695: * bit table. ! 696: * If no room, throw it away. ! 697: */ ! 698: setbit(b) ! 699: { ! 700: if (bp >= &bb[NB]) ! 701: return; ! 702: if (b) ! 703: *bp |= bm; ! 704: bm <<= 1; ! 705: if (bm == 0) { ! 706: bm = 1; ! 707: ++bp; ! 708: } ! 709: } ! 710: ! 711: /* ! 712: * Get the next bit from the bit ! 713: * table. ! 714: * If none left, return a `1'. ! 715: * This will get the long form of ! 716: * branches. ! 717: */ ! 718: getbit() ! 719: { ! 720: register f; ! 721: ! 722: if (bp >= &bb[NB]) ! 723: return (1); ! 724: f = *bp & bm; ! 725: bm <<= 1; ! 726: if (bm == 0) { ! 727: bm = 1; ! 728: ++bp; ! 729: } ! 730: return (f); ! 731: } ! 732: ! 733: /* ! 734: * This routine checks if the expression ! 735: * pointed to by `esp' is an absolute expression ! 736: * and has value `n'. This is used to check out ! 737: * the address fields of shifts and of interrupt ! 738: * request instructions. ! 739: */ ! 740: isabsn(esp, n) ! 741: register struct expr *esp; ! 742: { ! 743: if (esp->e_type==E_ACON && esp->e_addr==n) ! 744: return (1); ! 745: return (0); ! 746: } ! 747: ! 748: /* ! 749: * This routine checks if an immediate ! 750: * operand fits in 8 bits. It is used to check ! 751: * for immediate length in instructions that ! 752: * can take the w:s immediate. ! 753: */ ! 754: ishort(sp, esp) ! 755: register struct sym *sp; ! 756: register struct expr *esp; ! 757: { ! 758: register n; ! 759: ! 760: if ((sp->s_flag&S_OBL) == 0) ! 761: return (0); ! 762: if (esp->e_type != E_ACON) ! 763: return (0); ! 764: n = esp->e_addr&0177600; ! 765: if (n!=0 && n!=0177600) ! 766: return (0); ! 767: return (1); ! 768: } ! 769: ! 770: /* ! 771: * Make up the initial set of ! 772: * location counters. ! 773: * Poke one in every nonsegmented ! 774: * space. Add a special one for ! 775: * the C compiler's strings. ! 776: */ ! 777: locinit() ! 778: { ! 779: struct loc *locdef(); ! 780: ! 781: defloc = locdef(".shri", L_SHRI); ! 782: locdef(".prvi", L_PRVI); ! 783: locdef(".bssi", L_BSSI); ! 784: locdef(".shrd", L_SHRD); ! 785: locdef(".prvd", L_PRVD); ! 786: locdef(".bssd", L_BSSD); ! 787: locdef(".strn", L_PRVD); ! 788: locdef(".symt", L_DEBUG); ! 789: nloc = NLSEG; ! 790: } ! 791: ! 792: struct loc * ! 793: locdef(cp, t) ! 794: char *cp; ! 795: { ! 796: register char *cp1, *cp2; ! 797: register struct loc *lp; ! 798: struct sym *sp; ! 799: struct loc *lp1, *lp2; ! 800: int c; ! 801: char id[NCPLN]; ! 802: ! 803: lp = (struct loc *) new(sizeof(struct loc)); ! 804: lp->l_seg = t; ! 805: lp->l_lp = NULL; ! 806: lp->l_fuzz = 0; ! 807: lp->l_break = 0; ! 808: lp->l_offset = 0; ! 809: lp1 = NULL; ! 810: lp2 = loc[t]; ! 811: while (lp2 != NULL) { ! 812: lp1 = lp2; ! 813: lp2 = lp2->l_lp; ! 814: } ! 815: if (lp1 == NULL) ! 816: loc[t] = lp; else ! 817: lp1->l_lp = lp; ! 818: cp1 = cp; ! 819: cp2 = &id[0]; ! 820: while (c = *cp1++) ! 821: if (cp2 < &id[NCPLN]) ! 822: *cp2++ = c; ! 823: while (cp2 < &id[NCPLN]) ! 824: *cp2++ = 0; ! 825: sp = lookup(id, 1); ! 826: sp->s_kind = S_LOC; ! 827: sp->s_flag = 0; ! 828: sp->s_addr = (address)lp; ! 829: return (lp); ! 830: } ! 831: @ ! 832: ! 833: ! 834: 1.1 ! 835: log ! 836: @Initial revision ! 837: @ ! 838: text ! 839: @d80 1 ! 840: a80 1 ! 841: aerr(); ! 842: d88 1 ! 843: a88 1 ! 844: aerr(); ! 845: d109 1 ! 846: a109 1 ! 847: aerr(); ! 848: d121 13 ! 849: d147 1 ! 850: a147 1 ! 851: aerr(); ! 852: d158 1 ! 853: a158 1 ! 854: aerr(); ! 855: d178 6 ! 856: a183 2 ! 857: else if (m2!=IM || !isabsn(&e2, 1)) ! 858: aerr(); ! 859: d185 2 ! 860: d191 1 ! 861: a191 1 ! 862: aerr(); ! 863: d237 1 ! 864: a237 1 ! 865: aerr(); ! 866: d240 1 ! 867: a240 1 ! 868: aerr(); ! 869: d252 1 ! 870: a252 1 ! 871: aerr(); ! 872: d329 1 ! 873: a329 1 ! 874: aerr(); ! 875: d355 4 ! 876: a358 2 ! 877: if (m1!=WR || (m2!=DIR && m2!=X)) ! 878: aerr(); ! 879: d417 11 ! 880: d429 97 ! 881: d527 1 ! 882: a527 1 ! 883: err('o'); ! 884: d539 1 ! 885: a539 1 ! 886: qerr(); ! 887: d560 1 ! 888: a560 1 ! 889: aerr(); ! 890: d635 1 ! 891: a635 1 ! 892: aerr(); ! 893: d797 1 ! 894: a797 1 ! 895: sp->s_addr = lp; ! 896: @
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.