1769Speter /* Copyright (c) 1979 Regents of the University of California */ 2769Speter 3*10656Speter static char sccsid[] = "@(#)put.c 1.21 02/01/83"; 4769Speter 5769Speter #include "whoami.h" 6769Speter #include "opcode.h" 7769Speter #include "0.h" 8769Speter #include "objfmt.h" 9769Speter #ifdef PC 10769Speter # include "pc.h" 11*10656Speter # include "align.h" 12769Speter #endif PC 13769Speter 14769Speter short *obufp = obuf; 15769Speter 16769Speter /* 17769Speter * If DEBUG is defined, include the table 18769Speter * of the printing opcode names. 19769Speter */ 20769Speter #ifdef DEBUG 21769Speter #include "OPnames.h" 22769Speter #endif 23769Speter 24769Speter #ifdef OBJ 25769Speter /* 26769Speter * Put is responsible for the interpreter equivalent of code 27769Speter * generation. Since the interpreter is specifically designed 28769Speter * for Pascal, little work is required here. 29769Speter */ 30769Speter put(a) 31769Speter { 32769Speter register int *p, i; 33769Speter register char *cp; 343077Smckusic register short *sp; 353077Smckusic register long *lp; 36769Speter int n, subop, suboppr, op, oldlc, w; 37769Speter char *string; 38769Speter static int casewrd; 39769Speter 40769Speter /* 41769Speter * It would be nice to do some more 42769Speter * optimizations here. The work 43769Speter * done to collapse offsets in lval 44769Speter * should be done here, the IFEQ etc 45769Speter * relational operators could be used 46769Speter * etc. 47769Speter */ 48769Speter oldlc = lc; 493317Speter if ( !CGENNING ) 50769Speter /* 51769Speter * code disabled - do nothing 52769Speter */ 53769Speter return (oldlc); 54769Speter p = &a; 55769Speter n = *p++; 563077Smckusic suboppr = subop = (*p >> 8) & 0377; 57769Speter op = *p & 0377; 58769Speter string = 0; 59769Speter #ifdef DEBUG 60769Speter if ((cp = otext[op]) == NIL) { 61769Speter printf("op= %o\n", op); 62769Speter panic("put"); 63769Speter } 64769Speter #endif 65769Speter switch (op) { 66769Speter case O_ABORT: 67769Speter cp = "*"; 68769Speter break; 692221Smckusic case O_AS: 702221Smckusic switch(p[1]) { 716594Smckusick case 0: 726594Smckusick break; 732221Smckusic case 2: 742221Smckusic op = O_AS2; 756594Smckusick n = 1; 762221Smckusic break; 772221Smckusic case 4: 782221Smckusic op = O_AS4; 796594Smckusick n = 1; 802221Smckusic break; 812221Smckusic case 8: 822221Smckusic op = O_AS8; 836594Smckusick n = 1; 842221Smckusic break; 852221Smckusic default: 862221Smckusic goto pack; 872221Smckusic } 883077Smckusic # ifdef DEBUG 893077Smckusic cp = otext[op]; 903077Smckusic # endif DEBUG 912221Smckusic break; 923077Smckusic case O_CONG: 933077Smckusic case O_LVCON: 943077Smckusic case O_CON: 95769Speter case O_LINO: 96769Speter case O_NEW: 97769Speter case O_DISPOSE: 987965Smckusick case O_DFDISP: 99769Speter case O_IND: 100769Speter case O_OFF: 101769Speter case O_INX2: 102769Speter case O_INX4: 103769Speter case O_CARD: 104769Speter case O_ADDT: 105769Speter case O_SUBT: 106769Speter case O_MULT: 107769Speter case O_IN: 108769Speter case O_CASE1OP: 109769Speter case O_CASE2OP: 110769Speter case O_CASE4OP: 1111199Speter case O_FRTN: 112769Speter case O_WRITES: 1133173Smckusic case O_WRITEC: 114769Speter case O_WRITEF: 115769Speter case O_MAX: 116769Speter case O_MIN: 117769Speter case O_ARGV: 118769Speter case O_CTTOT: 119769Speter case O_INCT: 120769Speter case O_RANG2: 121769Speter case O_RSNG2: 122769Speter case O_RANG42: 123769Speter case O_RSNG42: 1242105Smckusic case O_SUCC2: 1252105Smckusic case O_SUCC24: 1262105Smckusic case O_PRED2: 1272105Smckusic case O_PRED24: 128769Speter if (p[1] == 0) 129769Speter break; 130769Speter case O_CON2: 131769Speter case O_CON24: 1322221Smckusic pack: 133769Speter if (p[1] < 128 && p[1] >= -128) { 134769Speter suboppr = subop = p[1]; 135769Speter p++; 136769Speter n--; 137769Speter if (op == O_CON2) { 138769Speter op = O_CON1; 1393077Smckusic # ifdef DEBUG 1403077Smckusic cp = otext[O_CON1]; 1413077Smckusic # endif DEBUG 142769Speter } 143769Speter if (op == O_CON24) { 144769Speter op = O_CON14; 1453077Smckusic # ifdef DEBUG 1463077Smckusic cp = otext[O_CON14]; 1473077Smckusic # endif DEBUG 148769Speter } 149769Speter } 150769Speter break; 151769Speter case O_CON8: 152769Speter { 153769Speter short *sp = &p[1]; 154769Speter 155769Speter #ifdef DEBUG 156769Speter if ( opt( 'k' ) ) 1573317Speter printf ( "%5d\tCON8\t%22.14e\n" , 158769Speter lc - HEADER_BYTES , 159769Speter * ( ( double * ) &p[1] ) ); 160769Speter #endif 1613077Smckusic # ifdef DEC11 1623077Smckusic word(op); 1633077Smckusic # else 1643077Smckusic word(op << 8); 1653077Smckusic # endif DEC11 166769Speter for ( i = 1 ; i <= 4 ; i ++ ) 167769Speter word ( *sp ++ ); 168769Speter return ( oldlc ); 169769Speter } 170769Speter default: 171769Speter if (op >= O_REL2 && op <= O_REL84) { 1721883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 173769Speter i -= 30; 174769Speter else 175769Speter i += 2; 176769Speter #ifdef DEBUG 177769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 178769Speter #endif 179769Speter suboppr = 0; 180769Speter } 181769Speter break; 182769Speter case O_IF: 183769Speter case O_TRA: 184769Speter /***** 185769Speter codeline = 0; 186769Speter *****/ 1872184Smckusic /* relative addressing */ 1882184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 1892184Smckusic break; 190769Speter case O_FOR1U: 191769Speter case O_FOR2U: 192769Speter case O_FOR1D: 193769Speter case O_FOR2D: 1944025Smckusic /* sub opcode optimization */ 1954025Smckusic if (p[1] < 128 && p[1] >= -128 && p[1] != 0) { 1964025Smckusic suboppr = subop = p[1]; 1974025Smckusic p++; 1984025Smckusic n--; 1994025Smckusic } 200769Speter /* relative addressing */ 2014025Smckusic p[n - 1] -= ( unsigned ) lc + (n - 1) * sizeof(short); 202769Speter break; 203769Speter case O_CONC: 204769Speter #ifdef DEBUG 205769Speter (string = "'x'")[1] = p[1]; 206769Speter #endif 207769Speter suboppr = 0; 208769Speter op = O_CON1; 2093077Smckusic # ifdef DEBUG 2103077Smckusic cp = otext[O_CON1]; 2113077Smckusic # endif DEBUG 212769Speter subop = p[1]; 213769Speter goto around; 214769Speter case O_CONC4: 215769Speter #ifdef DEBUG 216769Speter (string = "'x'")[1] = p[1]; 217769Speter #endif 218769Speter suboppr = 0; 219769Speter op = O_CON14; 220769Speter subop = p[1]; 221769Speter goto around; 222769Speter case O_CON1: 223769Speter case O_CON14: 224769Speter suboppr = subop = p[1]; 225769Speter around: 226769Speter n--; 227769Speter break; 228769Speter case O_CASEBEG: 229769Speter casewrd = 0; 230769Speter return (oldlc); 231769Speter case O_CASEEND: 232769Speter if ((unsigned) lc & 1) { 233769Speter lc--; 234769Speter word(casewrd); 235769Speter } 236769Speter return (oldlc); 237769Speter case O_CASE1: 238769Speter #ifdef DEBUG 239769Speter if (opt('k')) 2403317Speter printf("%5d\tCASE1\t%d\n" 2413077Smckusic , lc - HEADER_BYTES, p[1]); 242769Speter #endif 243769Speter /* 244769Speter * this to build a byte size case table 245769Speter * saving bytes across calls in casewrd 246769Speter * so they can be put out by word() 247769Speter */ 248769Speter lc++; 249769Speter if ((unsigned) lc & 1) 2503077Smckusic # ifdef DEC11 2513077Smckusic casewrd = p[1] & 0377; 2523077Smckusic # else 2533077Smckusic casewrd = (p[1] & 0377) << 8; 2543077Smckusic # endif DEC11 255769Speter else { 256769Speter lc -= 2; 2573077Smckusic # ifdef DEC11 2583077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2593077Smckusic # else 2603077Smckusic word((p[1] & 0377) | casewrd); 2613077Smckusic # endif DEC11 262769Speter } 263769Speter return (oldlc); 264769Speter case O_CASE2: 265769Speter #ifdef DEBUG 266769Speter if (opt('k')) 2673317Speter printf("%5d\tCASE2\t%d\n" 2683077Smckusic , lc - HEADER_BYTES , p[1]); 269769Speter #endif 2703077Smckusic word(p[1]); 271769Speter return (oldlc); 2724025Smckusic case O_FOR4U: 2734025Smckusic case O_FOR4D: 2744025Smckusic /* sub opcode optimization */ 2754025Smckusic lp = (long *)&p[1]; 2764025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2774025Smckusic suboppr = subop = *lp; 2784025Smckusic p += (sizeof(long) / sizeof(int)); 2794025Smckusic n--; 2804025Smckusic } 2814025Smckusic /* relative addressing */ 2824025Smckusic p[1 + (n - 2) * (sizeof(long) / sizeof(int))] -= 2834025Smckusic (unsigned)lc + (sizeof(short) + 2844025Smckusic (n - 2) * sizeof(long)); 2854025Smckusic goto longgen; 286769Speter case O_PUSH: 2873077Smckusic lp = (long *)&p[1]; 2883077Smckusic if (*lp == 0) 289769Speter return (oldlc); 2904025Smckusic /* and fall through */ 2914025Smckusic case O_RANG4: 2924025Smckusic case O_RANG24: 2934025Smckusic case O_RSNG4: 2944025Smckusic case O_RSNG24: 2954025Smckusic case O_SUCC4: 2964025Smckusic case O_PRED4: 2974025Smckusic /* sub opcode optimization */ 2984025Smckusic lp = (long *)&p[1]; 2994025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 3003077Smckusic suboppr = subop = *lp; 3014025Smckusic p += (sizeof(long) / sizeof(int)); 302769Speter n--; 303769Speter } 304769Speter goto longgen; 305769Speter case O_TRA4: 306769Speter case O_CALL: 3071199Speter case O_FSAV: 308769Speter case O_GOTO: 309769Speter case O_NAM: 310769Speter case O_READE: 311769Speter /* absolute long addressing */ 3123077Smckusic lp = (long *)&p[1]; 3133077Smckusic *lp -= HEADER_BYTES; 314769Speter goto longgen; 315769Speter case O_RV1: 316769Speter case O_RV14: 317769Speter case O_RV2: 318769Speter case O_RV24: 319769Speter case O_RV4: 320769Speter case O_RV8: 321769Speter case O_RV: 322769Speter case O_LV: 3232105Smckusic /* 3242105Smckusic * positive offsets represent arguments 3252105Smckusic * and must use "ap" display entry rather 3262105Smckusic * than the "fp" entry 3272105Smckusic */ 3282105Smckusic if (p[1] >= 0) { 3292105Smckusic subop++; 3302105Smckusic suboppr++; 3312105Smckusic } 3323077Smckusic # ifdef PDP11 3333077Smckusic break; 3343077Smckusic # else 3353077Smckusic /* 3363077Smckusic * offsets out of range of word addressing 3373077Smckusic * must use long offset opcodes 3383077Smckusic */ 3393077Smckusic if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) 3403077Smckusic break; 3413077Smckusic else { 342769Speter op += O_LRV - O_RV; 3433077Smckusic # ifdef DEBUG 3443077Smckusic cp = otext[op]; 3453077Smckusic # endif DEBUG 3463077Smckusic } 3473077Smckusic /* and fall through */ 3483077Smckusic # endif PDP11 349769Speter case O_BEG: 350769Speter case O_NODUMP: 351769Speter case O_CON4: 352769Speter case O_CASE4: 353769Speter longgen: 354769Speter n = (n << 1) - 1; 35510562Smckusick if ( op == O_LRV || op == O_FOR4U || op == O_FOR4D) { 356769Speter n--; 35710562Smckusick # if defined(ADDR32) && !defined(DEC11) 35810562Smckusick p[n / 2] <<= 16; 35910562Smckusick # endif 36010562Smckusick } 361769Speter #ifdef DEBUG 3623077Smckusic if (opt('k')) { 3633317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 364769Speter if (suboppr) 3653077Smckusic printf(":%d", suboppr); 3663077Smckusic for ( i = 2, lp = (long *)&p[1]; i < n 367769Speter ; i += sizeof ( long )/sizeof ( short ) ) 368769Speter printf( "\t%D " , *lp ++ ); 3693377Speter if (i == n) { 3703377Speter sp = (short *)lp; 3713377Speter printf( "\t%d ", *sp ); 3723377Speter } 373769Speter pchr ( '\n' ); 3743077Smckusic } 375769Speter #endif 376769Speter if ( op != O_CASE4 ) 3773077Smckusic # ifdef DEC11 3783077Smckusic word((op & 0377) | subop << 8); 3793077Smckusic # else 3803077Smckusic word(op << 8 | (subop & 0377)); 3813077Smckusic # endif DEC11 3823077Smckusic for ( i = 1, sp = (short *)&p[1]; i < n; i++) 3833077Smckusic word ( *sp ++ ); 384769Speter return ( oldlc ); 385769Speter } 386769Speter #ifdef DEBUG 387769Speter if (opt('k')) { 3883317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 389769Speter if (suboppr) 390769Speter printf(":%d", suboppr); 391769Speter if (string) 392769Speter printf("\t%s",string); 393769Speter if (n > 1) 394769Speter pchr('\t'); 395769Speter for (i=1; i<n; i++) 3963077Smckusic printf("%d ", p[i]); 397769Speter pchr('\n'); 398769Speter } 399769Speter #endif 400769Speter if (op != NIL) 4013077Smckusic # ifdef DEC11 4023077Smckusic word((op & 0377) | subop << 8); 4033077Smckusic # else 4043077Smckusic word(op << 8 | (subop & 0377)); 4053077Smckusic # endif DEC11 406769Speter for (i=1; i<n; i++) 407769Speter word(p[i]); 408769Speter return (oldlc); 409769Speter } 410769Speter #endif OBJ 411769Speter 412769Speter /* 413769Speter * listnames outputs a list of enumerated type names which 414769Speter * can then be selected from to output a TSCAL 415769Speter * a pointer to the address in the code of the namelist 416769Speter * is kept in value[ NL_ELABEL ]. 417769Speter */ 418769Speter listnames(ap) 419769Speter 420769Speter register struct nl *ap; 421769Speter { 422769Speter struct nl *next; 423769Speter register int oldlc, len; 424769Speter register unsigned w; 425769Speter register char *strptr; 426769Speter 4273317Speter if ( !CGENNING ) 428769Speter /* code is off - do nothing */ 429769Speter return(NIL); 430769Speter if (ap->class != TYPE) 431769Speter ap = ap->type; 432769Speter if (ap->value[ NL_ELABEL ] != 0) { 433769Speter /* the list already exists */ 434769Speter return( ap -> value[ NL_ELABEL ] ); 435769Speter } 436769Speter # ifdef OBJ 437769Speter oldlc = lc; 438769Speter put(2, O_TRA, lc); 439769Speter ap->value[ NL_ELABEL ] = lc; 440769Speter # endif OBJ 441769Speter # ifdef PC 442*10656Speter putprintf(" .data", 0); 443*10656Speter aligndot(A_STRUCT); 444769Speter ap -> value[ NL_ELABEL ] = getlab(); 445769Speter putlab( ap -> value[ NL_ELABEL ] ); 446769Speter # endif PC 447769Speter /* number of scalars */ 448769Speter next = ap->type; 449769Speter len = next->range[1]-next->range[0]+1; 450769Speter # ifdef OBJ 451769Speter put(2, O_CASE2, len); 452769Speter # endif OBJ 453769Speter # ifdef PC 454769Speter putprintf( " .word %d" , 0 , len ); 455769Speter # endif PC 456769Speter /* offsets of each scalar name */ 457769Speter len = (len+1)*sizeof(short); 458769Speter # ifdef OBJ 459769Speter put(2, O_CASE2, len); 460769Speter # endif OBJ 461769Speter # ifdef PC 462769Speter putprintf( " .word %d" , 0 , len ); 463769Speter # endif PC 464769Speter next = ap->chain; 465769Speter do { 466769Speter for(strptr = next->symbol; *strptr++; len++) 467769Speter continue; 468769Speter len++; 469769Speter # ifdef OBJ 470769Speter put(2, O_CASE2, len); 471769Speter # endif OBJ 472769Speter # ifdef PC 473769Speter putprintf( " .word %d" , 0 , len ); 474769Speter # endif PC 475769Speter } while (next = next->chain); 476769Speter /* list of scalar names */ 477769Speter strptr = getnext(ap, &next); 478769Speter # ifdef OBJ 479769Speter do { 4803077Smckusic # ifdef DEC11 4813077Smckusic w = (unsigned) *strptr; 4823077Smckusic # else 4833077Smckusic w = *strptr << 8; 4843077Smckusic # endif DEC11 485769Speter if (!*strptr++) 486769Speter strptr = getnext(next, &next); 4873077Smckusic # ifdef DEC11 4883077Smckusic w |= *strptr << 8; 4893077Smckusic # else 4903077Smckusic w |= (unsigned) *strptr; 4913077Smckusic # endif DEC11 492769Speter if (!*strptr++) 493769Speter strptr = getnext(next, &next); 494769Speter word(w); 495769Speter } while (next); 496769Speter /* jump over the mess */ 497769Speter patch(oldlc); 498769Speter # endif OBJ 499769Speter # ifdef PC 500769Speter while ( next ) { 501769Speter while ( *strptr ) { 502769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 503769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 504769Speter putprintf( ",0%o" , 1 , *strptr++ ); 505769Speter } 506769Speter putprintf( "" , 0 ); 507769Speter } 508769Speter putprintf( " .byte 0" , 0 ); 509769Speter strptr = getnext( next , &next ); 510769Speter } 511769Speter putprintf( " .text" , 0 ); 512769Speter # endif PC 513769Speter return( ap -> value[ NL_ELABEL ] ); 514769Speter } 515769Speter 516769Speter getnext(next, new) 517769Speter 518769Speter struct nl *next, **new; 519769Speter { 520769Speter if (next != NIL) { 521769Speter next = next->chain; 522769Speter *new = next; 523769Speter } 524769Speter if (next == NIL) 525769Speter return(""); 526769Speter #ifdef OBJ 5273317Speter if (opt('k') && CGENNING ) 5283317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5292213Speter #endif OBJ 530769Speter return(next->symbol); 531769Speter } 532769Speter 533769Speter #ifdef OBJ 534769Speter /* 535769Speter * Putspace puts out a table 536769Speter * of nothing to leave space 537769Speter * for the case branch table e.g. 538769Speter */ 539769Speter putspace(n) 540769Speter int n; 541769Speter { 542769Speter register i; 543769Speter 5443317Speter if ( !CGENNING ) 545769Speter /* 546769Speter * code disabled - do nothing 547769Speter */ 548769Speter return(lc); 549769Speter #ifdef DEBUG 550769Speter if (opt('k')) 5513317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 552769Speter #endif 553769Speter for (i = even(n); i > 0; i -= 2) 554769Speter word(0); 555769Speter } 556769Speter 557769Speter putstr(sptr, padding) 558769Speter 559769Speter char *sptr; 560769Speter int padding; 561769Speter { 562769Speter register unsigned short w; 563769Speter register char *strptr = sptr; 564769Speter register int pad = padding; 565769Speter 5663317Speter if ( !CGENNING ) 567769Speter /* 568769Speter * code disabled - do nothing 569769Speter */ 570769Speter return(lc); 571769Speter #ifdef DEBUG 572769Speter if (opt('k')) 5733317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 574769Speter #endif 575769Speter if (pad == 0) { 576769Speter do { 5773077Smckusic # ifdef DEC11 5783077Smckusic w = (unsigned short) * strptr; 5793077Smckusic # else 5803077Smckusic w = (unsigned short)*strptr<<8; 5813077Smckusic # endif DEC11 582769Speter if (w) 5833077Smckusic # ifdef DEC11 5843077Smckusic w |= *++strptr << 8; 5853077Smckusic # else 5863077Smckusic w |= *++strptr; 5873077Smckusic # endif DEC11 588769Speter word(w); 589769Speter } while (*strptr++); 590769Speter } else { 5913077Smckusic # ifdef DEC11 5923077Smckusic do { 5933077Smckusic w = (unsigned short) * strptr; 5943077Smckusic if (w) { 5953077Smckusic if (*++strptr) 5963077Smckusic w |= *strptr << 8; 5973077Smckusic else { 5983077Smckusic w |= ' \0'; 5993077Smckusic pad--; 6003077Smckusic } 6013077Smckusic word(w); 6023077Smckusic } 6033077Smckusic } while (*strptr++); 6043077Smckusic # else 6053077Smckusic do { 6063077Smckusic w = (unsigned short)*strptr<<8; 6073077Smckusic if (w) { 6083077Smckusic if (*++strptr) 6093077Smckusic w |= *strptr; 6103077Smckusic else { 6113077Smckusic w |= ' '; 6123077Smckusic pad--; 6133077Smckusic } 6143077Smckusic word(w); 6153077Smckusic } 6163077Smckusic } while (*strptr++); 6173077Smckusic # endif DEC11 618769Speter while (pad > 1) { 619769Speter word(' '); 620769Speter pad -= 2; 621769Speter } 622769Speter if (pad == 1) 6233077Smckusic # ifdef DEC11 6243077Smckusic word(' '); 6253077Smckusic # else 6263077Smckusic word(' \0'); 6273077Smckusic # endif DEC11 628769Speter else 629769Speter word(0); 630769Speter } 631769Speter } 632769Speter #endif OBJ 633769Speter 634769Speter lenstr(sptr, padding) 635769Speter 636769Speter char *sptr; 637769Speter int padding; 638769Speter 639769Speter { 640769Speter register int cnt; 641769Speter register char *strptr = sptr; 642769Speter 643769Speter cnt = padding; 644769Speter do { 645769Speter cnt++; 646769Speter } while (*strptr++); 647769Speter return((++cnt) & ~1); 648769Speter } 649769Speter 650769Speter /* 651769Speter * Patch repairs the branch 652769Speter * at location loc to come 653769Speter * to the current location. 654769Speter * for PC, this puts down the label 655769Speter * and the branch just references that label. 656769Speter * lets here it for two pass assemblers. 657769Speter */ 658769Speter patch(loc) 659769Speter { 660769Speter 661769Speter # ifdef OBJ 6623077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 663769Speter # endif OBJ 664769Speter # ifdef PC 665769Speter putlab( loc ); 666769Speter # endif PC 667769Speter } 668769Speter 669769Speter #ifdef OBJ 670769Speter patch4(loc) 671769Speter { 6723077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 673769Speter } 674769Speter 675769Speter /* 6767921Smckusick * Patchfil makes loc+2 have jmploc 677769Speter * as its contents. 678769Speter */ 6797921Smckusick patchfil(loc, jmploc, words) 680769Speter PTR_DCL loc; 6817921Smckusick long jmploc; 6823077Smckusic int words; 683769Speter { 684769Speter register i; 68510562Smckusick short val; 686769Speter 6873317Speter if ( !CGENNING ) 688769Speter return; 689769Speter if (loc > (unsigned) lc) 690769Speter panic("patchfil"); 691769Speter #ifdef DEBUG 692769Speter if (opt('k')) 6937921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 694769Speter #endif 6957921Smckusick val = jmploc; 696769Speter do { 6973077Smckusic # ifndef DEC11 6983077Smckusic if (words > 1) 6997921Smckusick val = jmploc >> 16; 7003077Smckusic else 7017921Smckusick val = jmploc; 7023077Smckusic # endif DEC11 703769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 70410562Smckusick if (i >= 0 && i < 1024) { 7053077Smckusic obuf[i] = val; 70610562Smckusick } else { 707769Speter lseek(ofil, (long) loc+2, 0); 7083077Smckusic write(ofil, &val, 2); 709769Speter lseek(ofil, (long) 0, 2); 710769Speter } 711769Speter loc += 2; 7123077Smckusic # ifdef DEC11 7137921Smckusick val = jmploc >> 16; 7143077Smckusic # endif DEC11 715769Speter } while (--words); 716769Speter } 717769Speter 718769Speter /* 719769Speter * Put the word o into the code 720769Speter */ 721769Speter word(o) 722769Speter int o; 723769Speter { 724769Speter 725769Speter *obufp = o; 726769Speter obufp++; 727769Speter lc += 2; 728769Speter if (obufp >= obuf+512) 729769Speter pflush(); 730769Speter } 731769Speter 732769Speter extern char *obj; 733769Speter /* 734769Speter * Flush the code buffer 735769Speter */ 736769Speter pflush() 737769Speter { 738769Speter register i; 739769Speter 740769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 741769Speter if (i != 0 && write(ofil, obuf, i) != i) 742769Speter perror(obj), pexit(DIED); 743769Speter obufp = obuf; 744769Speter } 745769Speter #endif OBJ 746769Speter 747769Speter /* 748769Speter * Getlab - returns the location counter. 749769Speter * included here for the eventual code generator. 750769Speter * for PC, thank you! 751769Speter */ 752769Speter getlab() 753769Speter { 754769Speter # ifdef OBJ 755769Speter 756769Speter return (lc); 757769Speter # endif OBJ 758769Speter # ifdef PC 759769Speter static long lastlabel; 760769Speter 761769Speter return ( ++lastlabel ); 762769Speter # endif PC 763769Speter } 764769Speter 765769Speter /* 766769Speter * Putlab - lay down a label. 767769Speter * for PC, just print the label name with a colon after it. 768769Speter */ 769769Speter putlab(l) 770769Speter int l; 771769Speter { 772769Speter 773769Speter # ifdef PC 774769Speter putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l ); 775769Speter putprintf( ":" , 0 ); 776769Speter # endif PC 777769Speter return (l); 778769Speter } 779