1769Speter /* Copyright (c) 1979 Regents of the University of California */ 2769Speter 3*7921Smckusick static char sccsid[] = "@(#)put.c 1.17 08/26/82"; 4769Speter 5769Speter #include "whoami.h" 6769Speter #include "opcode.h" 7769Speter #include "0.h" 8769Speter #include "objfmt.h" 9769Speter #ifdef PC 10769Speter # include "pc.h" 11769Speter #endif PC 12769Speter 13769Speter short *obufp = obuf; 14769Speter 15769Speter /* 16769Speter * If DEBUG is defined, include the table 17769Speter * of the printing opcode names. 18769Speter */ 19769Speter #ifdef DEBUG 20769Speter #include "OPnames.h" 21769Speter #endif 22769Speter 23769Speter #ifdef OBJ 24769Speter /* 25769Speter * Put is responsible for the interpreter equivalent of code 26769Speter * generation. Since the interpreter is specifically designed 27769Speter * for Pascal, little work is required here. 28769Speter */ 29769Speter put(a) 30769Speter { 31769Speter register int *p, i; 32769Speter register char *cp; 333077Smckusic register short *sp; 343077Smckusic register long *lp; 35769Speter int n, subop, suboppr, op, oldlc, w; 36769Speter char *string; 37769Speter static int casewrd; 38769Speter 39769Speter /* 40769Speter * It would be nice to do some more 41769Speter * optimizations here. The work 42769Speter * done to collapse offsets in lval 43769Speter * should be done here, the IFEQ etc 44769Speter * relational operators could be used 45769Speter * etc. 46769Speter */ 47769Speter oldlc = lc; 483317Speter if ( !CGENNING ) 49769Speter /* 50769Speter * code disabled - do nothing 51769Speter */ 52769Speter return (oldlc); 53769Speter p = &a; 54769Speter n = *p++; 553077Smckusic suboppr = subop = (*p >> 8) & 0377; 56769Speter op = *p & 0377; 57769Speter string = 0; 58769Speter #ifdef DEBUG 59769Speter if ((cp = otext[op]) == NIL) { 60769Speter printf("op= %o\n", op); 61769Speter panic("put"); 62769Speter } 63769Speter #endif 64769Speter switch (op) { 65769Speter case O_ABORT: 66769Speter cp = "*"; 67769Speter break; 682221Smckusic case O_AS: 692221Smckusic switch(p[1]) { 706594Smckusick case 0: 716594Smckusick break; 722221Smckusic case 2: 732221Smckusic op = O_AS2; 746594Smckusick n = 1; 752221Smckusic break; 762221Smckusic case 4: 772221Smckusic op = O_AS4; 786594Smckusick n = 1; 792221Smckusic break; 802221Smckusic case 8: 812221Smckusic op = O_AS8; 826594Smckusick n = 1; 832221Smckusic break; 842221Smckusic default: 852221Smckusic goto pack; 862221Smckusic } 873077Smckusic # ifdef DEBUG 883077Smckusic cp = otext[op]; 893077Smckusic # endif DEBUG 902221Smckusic break; 913077Smckusic case O_CONG: 923077Smckusic case O_LVCON: 933077Smckusic case O_CON: 94769Speter case O_LINO: 95769Speter case O_NEW: 96769Speter case O_DISPOSE: 97769Speter case O_IND: 98769Speter case O_OFF: 99769Speter case O_INX2: 100769Speter case O_INX4: 101769Speter case O_CARD: 102769Speter case O_ADDT: 103769Speter case O_SUBT: 104769Speter case O_MULT: 105769Speter case O_IN: 106769Speter case O_CASE1OP: 107769Speter case O_CASE2OP: 108769Speter case O_CASE4OP: 1091199Speter case O_FRTN: 110769Speter case O_WRITES: 1113173Smckusic case O_WRITEC: 112769Speter case O_WRITEF: 113769Speter case O_MAX: 114769Speter case O_MIN: 115769Speter case O_ARGV: 116769Speter case O_CTTOT: 117769Speter case O_INCT: 118769Speter case O_RANG2: 119769Speter case O_RSNG2: 120769Speter case O_RANG42: 121769Speter case O_RSNG42: 1222105Smckusic case O_SUCC2: 1232105Smckusic case O_SUCC24: 1242105Smckusic case O_PRED2: 1252105Smckusic case O_PRED24: 126769Speter if (p[1] == 0) 127769Speter break; 128769Speter case O_CON2: 129769Speter case O_CON24: 1302221Smckusic pack: 131769Speter if (p[1] < 128 && p[1] >= -128) { 132769Speter suboppr = subop = p[1]; 133769Speter p++; 134769Speter n--; 135769Speter if (op == O_CON2) { 136769Speter op = O_CON1; 1373077Smckusic # ifdef DEBUG 1383077Smckusic cp = otext[O_CON1]; 1393077Smckusic # endif DEBUG 140769Speter } 141769Speter if (op == O_CON24) { 142769Speter op = O_CON14; 1433077Smckusic # ifdef DEBUG 1443077Smckusic cp = otext[O_CON14]; 1453077Smckusic # endif DEBUG 146769Speter } 147769Speter } 148769Speter break; 149769Speter case O_CON8: 150769Speter { 151769Speter short *sp = &p[1]; 152769Speter 153769Speter #ifdef DEBUG 154769Speter if ( opt( 'k' ) ) 1553317Speter printf ( "%5d\tCON8\t%22.14e\n" , 156769Speter lc - HEADER_BYTES , 157769Speter * ( ( double * ) &p[1] ) ); 158769Speter #endif 1593077Smckusic # ifdef DEC11 1603077Smckusic word(op); 1613077Smckusic # else 1623077Smckusic word(op << 8); 1633077Smckusic # endif DEC11 164769Speter for ( i = 1 ; i <= 4 ; i ++ ) 165769Speter word ( *sp ++ ); 166769Speter return ( oldlc ); 167769Speter } 168769Speter default: 169769Speter if (op >= O_REL2 && op <= O_REL84) { 1701883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 171769Speter i -= 30; 172769Speter else 173769Speter i += 2; 174769Speter #ifdef DEBUG 175769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 176769Speter #endif 177769Speter suboppr = 0; 178769Speter } 179769Speter break; 180769Speter case O_IF: 181769Speter case O_TRA: 182769Speter /***** 183769Speter codeline = 0; 184769Speter *****/ 1852184Smckusic /* relative addressing */ 1862184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 1872184Smckusic break; 188769Speter case O_FOR1U: 189769Speter case O_FOR2U: 190769Speter case O_FOR1D: 191769Speter case O_FOR2D: 1924025Smckusic /* sub opcode optimization */ 1934025Smckusic if (p[1] < 128 && p[1] >= -128 && p[1] != 0) { 1944025Smckusic suboppr = subop = p[1]; 1954025Smckusic p++; 1964025Smckusic n--; 1974025Smckusic } 198769Speter /* relative addressing */ 1994025Smckusic p[n - 1] -= ( unsigned ) lc + (n - 1) * sizeof(short); 200769Speter break; 201769Speter case O_CONC: 202769Speter #ifdef DEBUG 203769Speter (string = "'x'")[1] = p[1]; 204769Speter #endif 205769Speter suboppr = 0; 206769Speter op = O_CON1; 2073077Smckusic # ifdef DEBUG 2083077Smckusic cp = otext[O_CON1]; 2093077Smckusic # endif DEBUG 210769Speter subop = p[1]; 211769Speter goto around; 212769Speter case O_CONC4: 213769Speter #ifdef DEBUG 214769Speter (string = "'x'")[1] = p[1]; 215769Speter #endif 216769Speter suboppr = 0; 217769Speter op = O_CON14; 218769Speter subop = p[1]; 219769Speter goto around; 220769Speter case O_CON1: 221769Speter case O_CON14: 222769Speter suboppr = subop = p[1]; 223769Speter around: 224769Speter n--; 225769Speter break; 226769Speter case O_CASEBEG: 227769Speter casewrd = 0; 228769Speter return (oldlc); 229769Speter case O_CASEEND: 230769Speter if ((unsigned) lc & 1) { 231769Speter lc--; 232769Speter word(casewrd); 233769Speter } 234769Speter return (oldlc); 235769Speter case O_CASE1: 236769Speter #ifdef DEBUG 237769Speter if (opt('k')) 2383317Speter printf("%5d\tCASE1\t%d\n" 2393077Smckusic , lc - HEADER_BYTES, p[1]); 240769Speter #endif 241769Speter /* 242769Speter * this to build a byte size case table 243769Speter * saving bytes across calls in casewrd 244769Speter * so they can be put out by word() 245769Speter */ 246769Speter lc++; 247769Speter if ((unsigned) lc & 1) 2483077Smckusic # ifdef DEC11 2493077Smckusic casewrd = p[1] & 0377; 2503077Smckusic # else 2513077Smckusic casewrd = (p[1] & 0377) << 8; 2523077Smckusic # endif DEC11 253769Speter else { 254769Speter lc -= 2; 2553077Smckusic # ifdef DEC11 2563077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2573077Smckusic # else 2583077Smckusic word((p[1] & 0377) | casewrd); 2593077Smckusic # endif DEC11 260769Speter } 261769Speter return (oldlc); 262769Speter case O_CASE2: 263769Speter #ifdef DEBUG 264769Speter if (opt('k')) 2653317Speter printf("%5d\tCASE2\t%d\n" 2663077Smckusic , lc - HEADER_BYTES , p[1]); 267769Speter #endif 2683077Smckusic word(p[1]); 269769Speter return (oldlc); 2704025Smckusic case O_FOR4U: 2714025Smckusic case O_FOR4D: 2724025Smckusic /* sub opcode optimization */ 2734025Smckusic lp = (long *)&p[1]; 2744025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2754025Smckusic suboppr = subop = *lp; 2764025Smckusic p += (sizeof(long) / sizeof(int)); 2774025Smckusic n--; 2784025Smckusic } 2794025Smckusic /* relative addressing */ 2804025Smckusic p[1 + (n - 2) * (sizeof(long) / sizeof(int))] -= 2814025Smckusic (unsigned)lc + (sizeof(short) + 2824025Smckusic (n - 2) * sizeof(long)); 2834025Smckusic goto longgen; 284769Speter case O_PUSH: 2853077Smckusic lp = (long *)&p[1]; 2863077Smckusic if (*lp == 0) 287769Speter return (oldlc); 2884025Smckusic /* and fall through */ 2894025Smckusic case O_RANG4: 2904025Smckusic case O_RANG24: 2914025Smckusic case O_RSNG4: 2924025Smckusic case O_RSNG24: 2934025Smckusic case O_SUCC4: 2944025Smckusic case O_PRED4: 2954025Smckusic /* sub opcode optimization */ 2964025Smckusic lp = (long *)&p[1]; 2974025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2983077Smckusic suboppr = subop = *lp; 2994025Smckusic p += (sizeof(long) / sizeof(int)); 300769Speter n--; 301769Speter } 302769Speter goto longgen; 303769Speter case O_TRA4: 304769Speter case O_CALL: 3051199Speter case O_FSAV: 306769Speter case O_GOTO: 307769Speter case O_NAM: 308769Speter case O_READE: 309769Speter /* absolute long addressing */ 3103077Smckusic lp = (long *)&p[1]; 3113077Smckusic *lp -= HEADER_BYTES; 312769Speter goto longgen; 313769Speter case O_RV1: 314769Speter case O_RV14: 315769Speter case O_RV2: 316769Speter case O_RV24: 317769Speter case O_RV4: 318769Speter case O_RV8: 319769Speter case O_RV: 320769Speter case O_LV: 3212105Smckusic /* 3222105Smckusic * positive offsets represent arguments 3232105Smckusic * and must use "ap" display entry rather 3242105Smckusic * than the "fp" entry 3252105Smckusic */ 3262105Smckusic if (p[1] >= 0) { 3272105Smckusic subop++; 3282105Smckusic suboppr++; 3292105Smckusic } 3303077Smckusic # ifdef PDP11 3313077Smckusic break; 3323077Smckusic # else 3333077Smckusic /* 3343077Smckusic * offsets out of range of word addressing 3353077Smckusic * must use long offset opcodes 3363077Smckusic */ 3373077Smckusic if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) 3383077Smckusic break; 3393077Smckusic else { 340769Speter op += O_LRV - O_RV; 3413077Smckusic # ifdef DEBUG 3423077Smckusic cp = otext[op]; 3433077Smckusic # endif DEBUG 3443077Smckusic } 3453077Smckusic /* and fall through */ 3463077Smckusic # endif PDP11 347769Speter case O_BEG: 348769Speter case O_NODUMP: 349769Speter case O_CON4: 350769Speter case O_CASE4: 351769Speter longgen: 352769Speter n = (n << 1) - 1; 3532184Smckusic if ( op == O_LRV || op == O_FOR4U || op == O_FOR4D) 354769Speter n--; 355769Speter #ifdef DEBUG 3563077Smckusic if (opt('k')) { 3573317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 358769Speter if (suboppr) 3593077Smckusic printf(":%d", suboppr); 3603077Smckusic for ( i = 2, lp = (long *)&p[1]; i < n 361769Speter ; i += sizeof ( long )/sizeof ( short ) ) 362769Speter printf( "\t%D " , *lp ++ ); 3633377Speter if (i == n) { 3643377Speter sp = (short *)lp; 3653377Speter printf( "\t%d ", *sp ); 3663377Speter } 367769Speter pchr ( '\n' ); 3683077Smckusic } 369769Speter #endif 370769Speter if ( op != O_CASE4 ) 3713077Smckusic # ifdef DEC11 3723077Smckusic word((op & 0377) | subop << 8); 3733077Smckusic # else 3743077Smckusic word(op << 8 | (subop & 0377)); 3753077Smckusic # endif DEC11 3763077Smckusic for ( i = 1, sp = (short *)&p[1]; i < n; i++) 3773077Smckusic word ( *sp ++ ); 378769Speter return ( oldlc ); 379769Speter } 380769Speter #ifdef DEBUG 381769Speter if (opt('k')) { 3823317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 383769Speter if (suboppr) 384769Speter printf(":%d", suboppr); 385769Speter if (string) 386769Speter printf("\t%s",string); 387769Speter if (n > 1) 388769Speter pchr('\t'); 389769Speter for (i=1; i<n; i++) 3903077Smckusic printf("%d ", p[i]); 391769Speter pchr('\n'); 392769Speter } 393769Speter #endif 394769Speter if (op != NIL) 3953077Smckusic # ifdef DEC11 3963077Smckusic word((op & 0377) | subop << 8); 3973077Smckusic # else 3983077Smckusic word(op << 8 | (subop & 0377)); 3993077Smckusic # endif DEC11 400769Speter for (i=1; i<n; i++) 401769Speter word(p[i]); 402769Speter return (oldlc); 403769Speter } 404769Speter #endif OBJ 405769Speter 406769Speter /* 407769Speter * listnames outputs a list of enumerated type names which 408769Speter * can then be selected from to output a TSCAL 409769Speter * a pointer to the address in the code of the namelist 410769Speter * is kept in value[ NL_ELABEL ]. 411769Speter */ 412769Speter listnames(ap) 413769Speter 414769Speter register struct nl *ap; 415769Speter { 416769Speter struct nl *next; 417769Speter register int oldlc, len; 418769Speter register unsigned w; 419769Speter register char *strptr; 420769Speter 4213317Speter if ( !CGENNING ) 422769Speter /* code is off - do nothing */ 423769Speter return(NIL); 424769Speter if (ap->class != TYPE) 425769Speter ap = ap->type; 426769Speter if (ap->value[ NL_ELABEL ] != 0) { 427769Speter /* the list already exists */ 428769Speter return( ap -> value[ NL_ELABEL ] ); 429769Speter } 430769Speter # ifdef OBJ 431769Speter oldlc = lc; 432769Speter put(2, O_TRA, lc); 433769Speter ap->value[ NL_ELABEL ] = lc; 434769Speter # endif OBJ 435769Speter # ifdef PC 436769Speter putprintf( " .data" , 0 ); 437769Speter putprintf( " .align 1" , 0 ); 438769Speter ap -> value[ NL_ELABEL ] = getlab(); 439769Speter putlab( ap -> value[ NL_ELABEL ] ); 440769Speter # endif PC 441769Speter /* number of scalars */ 442769Speter next = ap->type; 443769Speter len = next->range[1]-next->range[0]+1; 444769Speter # ifdef OBJ 445769Speter put(2, O_CASE2, len); 446769Speter # endif OBJ 447769Speter # ifdef PC 448769Speter putprintf( " .word %d" , 0 , len ); 449769Speter # endif PC 450769Speter /* offsets of each scalar name */ 451769Speter len = (len+1)*sizeof(short); 452769Speter # ifdef OBJ 453769Speter put(2, O_CASE2, len); 454769Speter # endif OBJ 455769Speter # ifdef PC 456769Speter putprintf( " .word %d" , 0 , len ); 457769Speter # endif PC 458769Speter next = ap->chain; 459769Speter do { 460769Speter for(strptr = next->symbol; *strptr++; len++) 461769Speter continue; 462769Speter len++; 463769Speter # ifdef OBJ 464769Speter put(2, O_CASE2, len); 465769Speter # endif OBJ 466769Speter # ifdef PC 467769Speter putprintf( " .word %d" , 0 , len ); 468769Speter # endif PC 469769Speter } while (next = next->chain); 470769Speter /* list of scalar names */ 471769Speter strptr = getnext(ap, &next); 472769Speter # ifdef OBJ 473769Speter do { 4743077Smckusic # ifdef DEC11 4753077Smckusic w = (unsigned) *strptr; 4763077Smckusic # else 4773077Smckusic w = *strptr << 8; 4783077Smckusic # endif DEC11 479769Speter if (!*strptr++) 480769Speter strptr = getnext(next, &next); 4813077Smckusic # ifdef DEC11 4823077Smckusic w |= *strptr << 8; 4833077Smckusic # else 4843077Smckusic w |= (unsigned) *strptr; 4853077Smckusic # endif DEC11 486769Speter if (!*strptr++) 487769Speter strptr = getnext(next, &next); 488769Speter word(w); 489769Speter } while (next); 490769Speter /* jump over the mess */ 491769Speter patch(oldlc); 492769Speter # endif OBJ 493769Speter # ifdef PC 494769Speter while ( next ) { 495769Speter while ( *strptr ) { 496769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 497769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 498769Speter putprintf( ",0%o" , 1 , *strptr++ ); 499769Speter } 500769Speter putprintf( "" , 0 ); 501769Speter } 502769Speter putprintf( " .byte 0" , 0 ); 503769Speter strptr = getnext( next , &next ); 504769Speter } 505769Speter putprintf( " .text" , 0 ); 506769Speter # endif PC 507769Speter return( ap -> value[ NL_ELABEL ] ); 508769Speter } 509769Speter 510769Speter getnext(next, new) 511769Speter 512769Speter struct nl *next, **new; 513769Speter { 514769Speter if (next != NIL) { 515769Speter next = next->chain; 516769Speter *new = next; 517769Speter } 518769Speter if (next == NIL) 519769Speter return(""); 520769Speter #ifdef OBJ 5213317Speter if (opt('k') && CGENNING ) 5223317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5232213Speter #endif OBJ 524769Speter return(next->symbol); 525769Speter } 526769Speter 527769Speter #ifdef OBJ 528769Speter /* 529769Speter * Putspace puts out a table 530769Speter * of nothing to leave space 531769Speter * for the case branch table e.g. 532769Speter */ 533769Speter putspace(n) 534769Speter int n; 535769Speter { 536769Speter register i; 537769Speter 5383317Speter if ( !CGENNING ) 539769Speter /* 540769Speter * code disabled - do nothing 541769Speter */ 542769Speter return(lc); 543769Speter #ifdef DEBUG 544769Speter if (opt('k')) 5453317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 546769Speter #endif 547769Speter for (i = even(n); i > 0; i -= 2) 548769Speter word(0); 549769Speter } 550769Speter 551769Speter putstr(sptr, padding) 552769Speter 553769Speter char *sptr; 554769Speter int padding; 555769Speter { 556769Speter register unsigned short w; 557769Speter register char *strptr = sptr; 558769Speter register int pad = padding; 559769Speter 5603317Speter if ( !CGENNING ) 561769Speter /* 562769Speter * code disabled - do nothing 563769Speter */ 564769Speter return(lc); 565769Speter #ifdef DEBUG 566769Speter if (opt('k')) 5673317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 568769Speter #endif 569769Speter if (pad == 0) { 570769Speter do { 5713077Smckusic # ifdef DEC11 5723077Smckusic w = (unsigned short) * strptr; 5733077Smckusic # else 5743077Smckusic w = (unsigned short)*strptr<<8; 5753077Smckusic # endif DEC11 576769Speter if (w) 5773077Smckusic # ifdef DEC11 5783077Smckusic w |= *++strptr << 8; 5793077Smckusic # else 5803077Smckusic w |= *++strptr; 5813077Smckusic # endif DEC11 582769Speter word(w); 583769Speter } while (*strptr++); 584769Speter } else { 5853077Smckusic # ifdef DEC11 5863077Smckusic do { 5873077Smckusic w = (unsigned short) * strptr; 5883077Smckusic if (w) { 5893077Smckusic if (*++strptr) 5903077Smckusic w |= *strptr << 8; 5913077Smckusic else { 5923077Smckusic w |= ' \0'; 5933077Smckusic pad--; 5943077Smckusic } 5953077Smckusic word(w); 5963077Smckusic } 5973077Smckusic } while (*strptr++); 5983077Smckusic # else 5993077Smckusic do { 6003077Smckusic w = (unsigned short)*strptr<<8; 6013077Smckusic if (w) { 6023077Smckusic if (*++strptr) 6033077Smckusic w |= *strptr; 6043077Smckusic else { 6053077Smckusic w |= ' '; 6063077Smckusic pad--; 6073077Smckusic } 6083077Smckusic word(w); 6093077Smckusic } 6103077Smckusic } while (*strptr++); 6113077Smckusic # endif DEC11 612769Speter while (pad > 1) { 613769Speter word(' '); 614769Speter pad -= 2; 615769Speter } 616769Speter if (pad == 1) 6173077Smckusic # ifdef DEC11 6183077Smckusic word(' '); 6193077Smckusic # else 6203077Smckusic word(' \0'); 6213077Smckusic # endif DEC11 622769Speter else 623769Speter word(0); 624769Speter } 625769Speter } 626769Speter #endif OBJ 627769Speter 628769Speter lenstr(sptr, padding) 629769Speter 630769Speter char *sptr; 631769Speter int padding; 632769Speter 633769Speter { 634769Speter register int cnt; 635769Speter register char *strptr = sptr; 636769Speter 637769Speter cnt = padding; 638769Speter do { 639769Speter cnt++; 640769Speter } while (*strptr++); 641769Speter return((++cnt) & ~1); 642769Speter } 643769Speter 644769Speter /* 645769Speter * Patch repairs the branch 646769Speter * at location loc to come 647769Speter * to the current location. 648769Speter * for PC, this puts down the label 649769Speter * and the branch just references that label. 650769Speter * lets here it for two pass assemblers. 651769Speter */ 652769Speter patch(loc) 653769Speter { 654769Speter 655769Speter # ifdef OBJ 6563077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 657769Speter # endif OBJ 658769Speter # ifdef PC 659769Speter putlab( loc ); 660769Speter # endif PC 661769Speter } 662769Speter 663769Speter #ifdef OBJ 664769Speter patch4(loc) 665769Speter { 6663077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 667769Speter } 668769Speter 669769Speter /* 670*7921Smckusick * Patchfil makes loc+2 have jmploc 671769Speter * as its contents. 672769Speter */ 673*7921Smckusick patchfil(loc, jmploc, words) 674769Speter PTR_DCL loc; 675*7921Smckusick long jmploc; 6763077Smckusic int words; 677769Speter { 678769Speter register i; 6793077Smckusic int val; 680769Speter 6813317Speter if ( !CGENNING ) 682769Speter return; 683769Speter if (loc > (unsigned) lc) 684769Speter panic("patchfil"); 685769Speter #ifdef DEBUG 686769Speter if (opt('k')) 687*7921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 688769Speter #endif 689*7921Smckusick val = jmploc; 690769Speter do { 6913077Smckusic # ifndef DEC11 6923077Smckusic if (words > 1) 693*7921Smckusick val = jmploc >> 16; 6943077Smckusic else 695*7921Smckusick val = jmploc; 6963077Smckusic # endif DEC11 697769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 698769Speter if (i >= 0 && i < 1024) 6993077Smckusic obuf[i] = val; 700769Speter else { 701769Speter lseek(ofil, (long) loc+2, 0); 7023077Smckusic write(ofil, &val, 2); 703769Speter lseek(ofil, (long) 0, 2); 704769Speter } 705769Speter loc += 2; 7063077Smckusic # ifdef DEC11 707*7921Smckusick val = jmploc >> 16; 7083077Smckusic # endif DEC11 709769Speter } while (--words); 710769Speter } 711769Speter 712769Speter /* 713769Speter * Put the word o into the code 714769Speter */ 715769Speter word(o) 716769Speter int o; 717769Speter { 718769Speter 719769Speter *obufp = o; 720769Speter obufp++; 721769Speter lc += 2; 722769Speter if (obufp >= obuf+512) 723769Speter pflush(); 724769Speter } 725769Speter 726769Speter extern char *obj; 727769Speter /* 728769Speter * Flush the code buffer 729769Speter */ 730769Speter pflush() 731769Speter { 732769Speter register i; 733769Speter 734769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 735769Speter if (i != 0 && write(ofil, obuf, i) != i) 736769Speter perror(obj), pexit(DIED); 737769Speter obufp = obuf; 738769Speter } 739769Speter #endif OBJ 740769Speter 741769Speter /* 742769Speter * Getlab - returns the location counter. 743769Speter * included here for the eventual code generator. 744769Speter * for PC, thank you! 745769Speter */ 746769Speter getlab() 747769Speter { 748769Speter # ifdef OBJ 749769Speter 750769Speter return (lc); 751769Speter # endif OBJ 752769Speter # ifdef PC 753769Speter static long lastlabel; 754769Speter 755769Speter return ( ++lastlabel ); 756769Speter # endif PC 757769Speter } 758769Speter 759769Speter /* 760769Speter * Putlab - lay down a label. 761769Speter * for PC, just print the label name with a colon after it. 762769Speter */ 763769Speter putlab(l) 764769Speter int l; 765769Speter { 766769Speter 767769Speter # ifdef PC 768769Speter putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l ); 769769Speter putprintf( ":" , 0 ); 770769Speter # endif PC 771769Speter return (l); 772769Speter } 773