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