1769Speter /* Copyright (c) 1979 Regents of the University of California */ 2769Speter 3*7965Smckusick static char sccsid[] = "@(#)put.c 1.18 08/29/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: 97*7965Smckusick case O_DFDISP: 98769Speter case O_IND: 99769Speter case O_OFF: 100769Speter case O_INX2: 101769Speter case O_INX4: 102769Speter case O_CARD: 103769Speter case O_ADDT: 104769Speter case O_SUBT: 105769Speter case O_MULT: 106769Speter case O_IN: 107769Speter case O_CASE1OP: 108769Speter case O_CASE2OP: 109769Speter case O_CASE4OP: 1101199Speter case O_FRTN: 111769Speter case O_WRITES: 1123173Smckusic case O_WRITEC: 113769Speter case O_WRITEF: 114769Speter case O_MAX: 115769Speter case O_MIN: 116769Speter case O_ARGV: 117769Speter case O_CTTOT: 118769Speter case O_INCT: 119769Speter case O_RANG2: 120769Speter case O_RSNG2: 121769Speter case O_RANG42: 122769Speter case O_RSNG42: 1232105Smckusic case O_SUCC2: 1242105Smckusic case O_SUCC24: 1252105Smckusic case O_PRED2: 1262105Smckusic case O_PRED24: 127769Speter if (p[1] == 0) 128769Speter break; 129769Speter case O_CON2: 130769Speter case O_CON24: 1312221Smckusic pack: 132769Speter if (p[1] < 128 && p[1] >= -128) { 133769Speter suboppr = subop = p[1]; 134769Speter p++; 135769Speter n--; 136769Speter if (op == O_CON2) { 137769Speter op = O_CON1; 1383077Smckusic # ifdef DEBUG 1393077Smckusic cp = otext[O_CON1]; 1403077Smckusic # endif DEBUG 141769Speter } 142769Speter if (op == O_CON24) { 143769Speter op = O_CON14; 1443077Smckusic # ifdef DEBUG 1453077Smckusic cp = otext[O_CON14]; 1463077Smckusic # endif DEBUG 147769Speter } 148769Speter } 149769Speter break; 150769Speter case O_CON8: 151769Speter { 152769Speter short *sp = &p[1]; 153769Speter 154769Speter #ifdef DEBUG 155769Speter if ( opt( 'k' ) ) 1563317Speter printf ( "%5d\tCON8\t%22.14e\n" , 157769Speter lc - HEADER_BYTES , 158769Speter * ( ( double * ) &p[1] ) ); 159769Speter #endif 1603077Smckusic # ifdef DEC11 1613077Smckusic word(op); 1623077Smckusic # else 1633077Smckusic word(op << 8); 1643077Smckusic # endif DEC11 165769Speter for ( i = 1 ; i <= 4 ; i ++ ) 166769Speter word ( *sp ++ ); 167769Speter return ( oldlc ); 168769Speter } 169769Speter default: 170769Speter if (op >= O_REL2 && op <= O_REL84) { 1711883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 172769Speter i -= 30; 173769Speter else 174769Speter i += 2; 175769Speter #ifdef DEBUG 176769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 177769Speter #endif 178769Speter suboppr = 0; 179769Speter } 180769Speter break; 181769Speter case O_IF: 182769Speter case O_TRA: 183769Speter /***** 184769Speter codeline = 0; 185769Speter *****/ 1862184Smckusic /* relative addressing */ 1872184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 1882184Smckusic break; 189769Speter case O_FOR1U: 190769Speter case O_FOR2U: 191769Speter case O_FOR1D: 192769Speter case O_FOR2D: 1934025Smckusic /* sub opcode optimization */ 1944025Smckusic if (p[1] < 128 && p[1] >= -128 && p[1] != 0) { 1954025Smckusic suboppr = subop = p[1]; 1964025Smckusic p++; 1974025Smckusic n--; 1984025Smckusic } 199769Speter /* relative addressing */ 2004025Smckusic p[n - 1] -= ( unsigned ) lc + (n - 1) * sizeof(short); 201769Speter break; 202769Speter case O_CONC: 203769Speter #ifdef DEBUG 204769Speter (string = "'x'")[1] = p[1]; 205769Speter #endif 206769Speter suboppr = 0; 207769Speter op = O_CON1; 2083077Smckusic # ifdef DEBUG 2093077Smckusic cp = otext[O_CON1]; 2103077Smckusic # endif DEBUG 211769Speter subop = p[1]; 212769Speter goto around; 213769Speter case O_CONC4: 214769Speter #ifdef DEBUG 215769Speter (string = "'x'")[1] = p[1]; 216769Speter #endif 217769Speter suboppr = 0; 218769Speter op = O_CON14; 219769Speter subop = p[1]; 220769Speter goto around; 221769Speter case O_CON1: 222769Speter case O_CON14: 223769Speter suboppr = subop = p[1]; 224769Speter around: 225769Speter n--; 226769Speter break; 227769Speter case O_CASEBEG: 228769Speter casewrd = 0; 229769Speter return (oldlc); 230769Speter case O_CASEEND: 231769Speter if ((unsigned) lc & 1) { 232769Speter lc--; 233769Speter word(casewrd); 234769Speter } 235769Speter return (oldlc); 236769Speter case O_CASE1: 237769Speter #ifdef DEBUG 238769Speter if (opt('k')) 2393317Speter printf("%5d\tCASE1\t%d\n" 2403077Smckusic , lc - HEADER_BYTES, p[1]); 241769Speter #endif 242769Speter /* 243769Speter * this to build a byte size case table 244769Speter * saving bytes across calls in casewrd 245769Speter * so they can be put out by word() 246769Speter */ 247769Speter lc++; 248769Speter if ((unsigned) lc & 1) 2493077Smckusic # ifdef DEC11 2503077Smckusic casewrd = p[1] & 0377; 2513077Smckusic # else 2523077Smckusic casewrd = (p[1] & 0377) << 8; 2533077Smckusic # endif DEC11 254769Speter else { 255769Speter lc -= 2; 2563077Smckusic # ifdef DEC11 2573077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2583077Smckusic # else 2593077Smckusic word((p[1] & 0377) | casewrd); 2603077Smckusic # endif DEC11 261769Speter } 262769Speter return (oldlc); 263769Speter case O_CASE2: 264769Speter #ifdef DEBUG 265769Speter if (opt('k')) 2663317Speter printf("%5d\tCASE2\t%d\n" 2673077Smckusic , lc - HEADER_BYTES , p[1]); 268769Speter #endif 2693077Smckusic word(p[1]); 270769Speter return (oldlc); 2714025Smckusic case O_FOR4U: 2724025Smckusic case O_FOR4D: 2734025Smckusic /* sub opcode optimization */ 2744025Smckusic lp = (long *)&p[1]; 2754025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2764025Smckusic suboppr = subop = *lp; 2774025Smckusic p += (sizeof(long) / sizeof(int)); 2784025Smckusic n--; 2794025Smckusic } 2804025Smckusic /* relative addressing */ 2814025Smckusic p[1 + (n - 2) * (sizeof(long) / sizeof(int))] -= 2824025Smckusic (unsigned)lc + (sizeof(short) + 2834025Smckusic (n - 2) * sizeof(long)); 2844025Smckusic goto longgen; 285769Speter case O_PUSH: 2863077Smckusic lp = (long *)&p[1]; 2873077Smckusic if (*lp == 0) 288769Speter return (oldlc); 2894025Smckusic /* and fall through */ 2904025Smckusic case O_RANG4: 2914025Smckusic case O_RANG24: 2924025Smckusic case O_RSNG4: 2934025Smckusic case O_RSNG24: 2944025Smckusic case O_SUCC4: 2954025Smckusic case O_PRED4: 2964025Smckusic /* sub opcode optimization */ 2974025Smckusic lp = (long *)&p[1]; 2984025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2993077Smckusic suboppr = subop = *lp; 3004025Smckusic p += (sizeof(long) / sizeof(int)); 301769Speter n--; 302769Speter } 303769Speter goto longgen; 304769Speter case O_TRA4: 305769Speter case O_CALL: 3061199Speter case O_FSAV: 307769Speter case O_GOTO: 308769Speter case O_NAM: 309769Speter case O_READE: 310769Speter /* absolute long addressing */ 3113077Smckusic lp = (long *)&p[1]; 3123077Smckusic *lp -= HEADER_BYTES; 313769Speter goto longgen; 314769Speter case O_RV1: 315769Speter case O_RV14: 316769Speter case O_RV2: 317769Speter case O_RV24: 318769Speter case O_RV4: 319769Speter case O_RV8: 320769Speter case O_RV: 321769Speter case O_LV: 3222105Smckusic /* 3232105Smckusic * positive offsets represent arguments 3242105Smckusic * and must use "ap" display entry rather 3252105Smckusic * than the "fp" entry 3262105Smckusic */ 3272105Smckusic if (p[1] >= 0) { 3282105Smckusic subop++; 3292105Smckusic suboppr++; 3302105Smckusic } 3313077Smckusic # ifdef PDP11 3323077Smckusic break; 3333077Smckusic # else 3343077Smckusic /* 3353077Smckusic * offsets out of range of word addressing 3363077Smckusic * must use long offset opcodes 3373077Smckusic */ 3383077Smckusic if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) 3393077Smckusic break; 3403077Smckusic else { 341769Speter op += O_LRV - O_RV; 3423077Smckusic # ifdef DEBUG 3433077Smckusic cp = otext[op]; 3443077Smckusic # endif DEBUG 3453077Smckusic } 3463077Smckusic /* and fall through */ 3473077Smckusic # endif PDP11 348769Speter case O_BEG: 349769Speter case O_NODUMP: 350769Speter case O_CON4: 351769Speter case O_CASE4: 352769Speter longgen: 353769Speter n = (n << 1) - 1; 3542184Smckusic if ( op == O_LRV || op == O_FOR4U || op == O_FOR4D) 355769Speter n--; 356769Speter #ifdef DEBUG 3573077Smckusic if (opt('k')) { 3583317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 359769Speter if (suboppr) 3603077Smckusic printf(":%d", suboppr); 3613077Smckusic for ( i = 2, lp = (long *)&p[1]; i < n 362769Speter ; i += sizeof ( long )/sizeof ( short ) ) 363769Speter printf( "\t%D " , *lp ++ ); 3643377Speter if (i == n) { 3653377Speter sp = (short *)lp; 3663377Speter printf( "\t%d ", *sp ); 3673377Speter } 368769Speter pchr ( '\n' ); 3693077Smckusic } 370769Speter #endif 371769Speter if ( op != O_CASE4 ) 3723077Smckusic # ifdef DEC11 3733077Smckusic word((op & 0377) | subop << 8); 3743077Smckusic # else 3753077Smckusic word(op << 8 | (subop & 0377)); 3763077Smckusic # endif DEC11 3773077Smckusic for ( i = 1, sp = (short *)&p[1]; i < n; i++) 3783077Smckusic word ( *sp ++ ); 379769Speter return ( oldlc ); 380769Speter } 381769Speter #ifdef DEBUG 382769Speter if (opt('k')) { 3833317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 384769Speter if (suboppr) 385769Speter printf(":%d", suboppr); 386769Speter if (string) 387769Speter printf("\t%s",string); 388769Speter if (n > 1) 389769Speter pchr('\t'); 390769Speter for (i=1; i<n; i++) 3913077Smckusic printf("%d ", p[i]); 392769Speter pchr('\n'); 393769Speter } 394769Speter #endif 395769Speter if (op != NIL) 3963077Smckusic # ifdef DEC11 3973077Smckusic word((op & 0377) | subop << 8); 3983077Smckusic # else 3993077Smckusic word(op << 8 | (subop & 0377)); 4003077Smckusic # endif DEC11 401769Speter for (i=1; i<n; i++) 402769Speter word(p[i]); 403769Speter return (oldlc); 404769Speter } 405769Speter #endif OBJ 406769Speter 407769Speter /* 408769Speter * listnames outputs a list of enumerated type names which 409769Speter * can then be selected from to output a TSCAL 410769Speter * a pointer to the address in the code of the namelist 411769Speter * is kept in value[ NL_ELABEL ]. 412769Speter */ 413769Speter listnames(ap) 414769Speter 415769Speter register struct nl *ap; 416769Speter { 417769Speter struct nl *next; 418769Speter register int oldlc, len; 419769Speter register unsigned w; 420769Speter register char *strptr; 421769Speter 4223317Speter if ( !CGENNING ) 423769Speter /* code is off - do nothing */ 424769Speter return(NIL); 425769Speter if (ap->class != TYPE) 426769Speter ap = ap->type; 427769Speter if (ap->value[ NL_ELABEL ] != 0) { 428769Speter /* the list already exists */ 429769Speter return( ap -> value[ NL_ELABEL ] ); 430769Speter } 431769Speter # ifdef OBJ 432769Speter oldlc = lc; 433769Speter put(2, O_TRA, lc); 434769Speter ap->value[ NL_ELABEL ] = lc; 435769Speter # endif OBJ 436769Speter # ifdef PC 437769Speter putprintf( " .data" , 0 ); 438769Speter putprintf( " .align 1" , 0 ); 439769Speter ap -> value[ NL_ELABEL ] = getlab(); 440769Speter putlab( ap -> value[ NL_ELABEL ] ); 441769Speter # endif PC 442769Speter /* number of scalars */ 443769Speter next = ap->type; 444769Speter len = next->range[1]-next->range[0]+1; 445769Speter # ifdef OBJ 446769Speter put(2, O_CASE2, len); 447769Speter # endif OBJ 448769Speter # ifdef PC 449769Speter putprintf( " .word %d" , 0 , len ); 450769Speter # endif PC 451769Speter /* offsets of each scalar name */ 452769Speter len = (len+1)*sizeof(short); 453769Speter # ifdef OBJ 454769Speter put(2, O_CASE2, len); 455769Speter # endif OBJ 456769Speter # ifdef PC 457769Speter putprintf( " .word %d" , 0 , len ); 458769Speter # endif PC 459769Speter next = ap->chain; 460769Speter do { 461769Speter for(strptr = next->symbol; *strptr++; len++) 462769Speter continue; 463769Speter len++; 464769Speter # ifdef OBJ 465769Speter put(2, O_CASE2, len); 466769Speter # endif OBJ 467769Speter # ifdef PC 468769Speter putprintf( " .word %d" , 0 , len ); 469769Speter # endif PC 470769Speter } while (next = next->chain); 471769Speter /* list of scalar names */ 472769Speter strptr = getnext(ap, &next); 473769Speter # ifdef OBJ 474769Speter do { 4753077Smckusic # ifdef DEC11 4763077Smckusic w = (unsigned) *strptr; 4773077Smckusic # else 4783077Smckusic w = *strptr << 8; 4793077Smckusic # endif DEC11 480769Speter if (!*strptr++) 481769Speter strptr = getnext(next, &next); 4823077Smckusic # ifdef DEC11 4833077Smckusic w |= *strptr << 8; 4843077Smckusic # else 4853077Smckusic w |= (unsigned) *strptr; 4863077Smckusic # endif DEC11 487769Speter if (!*strptr++) 488769Speter strptr = getnext(next, &next); 489769Speter word(w); 490769Speter } while (next); 491769Speter /* jump over the mess */ 492769Speter patch(oldlc); 493769Speter # endif OBJ 494769Speter # ifdef PC 495769Speter while ( next ) { 496769Speter while ( *strptr ) { 497769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 498769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 499769Speter putprintf( ",0%o" , 1 , *strptr++ ); 500769Speter } 501769Speter putprintf( "" , 0 ); 502769Speter } 503769Speter putprintf( " .byte 0" , 0 ); 504769Speter strptr = getnext( next , &next ); 505769Speter } 506769Speter putprintf( " .text" , 0 ); 507769Speter # endif PC 508769Speter return( ap -> value[ NL_ELABEL ] ); 509769Speter } 510769Speter 511769Speter getnext(next, new) 512769Speter 513769Speter struct nl *next, **new; 514769Speter { 515769Speter if (next != NIL) { 516769Speter next = next->chain; 517769Speter *new = next; 518769Speter } 519769Speter if (next == NIL) 520769Speter return(""); 521769Speter #ifdef OBJ 5223317Speter if (opt('k') && CGENNING ) 5233317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5242213Speter #endif OBJ 525769Speter return(next->symbol); 526769Speter } 527769Speter 528769Speter #ifdef OBJ 529769Speter /* 530769Speter * Putspace puts out a table 531769Speter * of nothing to leave space 532769Speter * for the case branch table e.g. 533769Speter */ 534769Speter putspace(n) 535769Speter int n; 536769Speter { 537769Speter register i; 538769Speter 5393317Speter if ( !CGENNING ) 540769Speter /* 541769Speter * code disabled - do nothing 542769Speter */ 543769Speter return(lc); 544769Speter #ifdef DEBUG 545769Speter if (opt('k')) 5463317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 547769Speter #endif 548769Speter for (i = even(n); i > 0; i -= 2) 549769Speter word(0); 550769Speter } 551769Speter 552769Speter putstr(sptr, padding) 553769Speter 554769Speter char *sptr; 555769Speter int padding; 556769Speter { 557769Speter register unsigned short w; 558769Speter register char *strptr = sptr; 559769Speter register int pad = padding; 560769Speter 5613317Speter if ( !CGENNING ) 562769Speter /* 563769Speter * code disabled - do nothing 564769Speter */ 565769Speter return(lc); 566769Speter #ifdef DEBUG 567769Speter if (opt('k')) 5683317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 569769Speter #endif 570769Speter if (pad == 0) { 571769Speter do { 5723077Smckusic # ifdef DEC11 5733077Smckusic w = (unsigned short) * strptr; 5743077Smckusic # else 5753077Smckusic w = (unsigned short)*strptr<<8; 5763077Smckusic # endif DEC11 577769Speter if (w) 5783077Smckusic # ifdef DEC11 5793077Smckusic w |= *++strptr << 8; 5803077Smckusic # else 5813077Smckusic w |= *++strptr; 5823077Smckusic # endif DEC11 583769Speter word(w); 584769Speter } while (*strptr++); 585769Speter } else { 5863077Smckusic # ifdef DEC11 5873077Smckusic do { 5883077Smckusic w = (unsigned short) * strptr; 5893077Smckusic if (w) { 5903077Smckusic if (*++strptr) 5913077Smckusic w |= *strptr << 8; 5923077Smckusic else { 5933077Smckusic w |= ' \0'; 5943077Smckusic pad--; 5953077Smckusic } 5963077Smckusic word(w); 5973077Smckusic } 5983077Smckusic } while (*strptr++); 5993077Smckusic # else 6003077Smckusic do { 6013077Smckusic w = (unsigned short)*strptr<<8; 6023077Smckusic if (w) { 6033077Smckusic if (*++strptr) 6043077Smckusic w |= *strptr; 6053077Smckusic else { 6063077Smckusic w |= ' '; 6073077Smckusic pad--; 6083077Smckusic } 6093077Smckusic word(w); 6103077Smckusic } 6113077Smckusic } while (*strptr++); 6123077Smckusic # endif DEC11 613769Speter while (pad > 1) { 614769Speter word(' '); 615769Speter pad -= 2; 616769Speter } 617769Speter if (pad == 1) 6183077Smckusic # ifdef DEC11 6193077Smckusic word(' '); 6203077Smckusic # else 6213077Smckusic word(' \0'); 6223077Smckusic # endif DEC11 623769Speter else 624769Speter word(0); 625769Speter } 626769Speter } 627769Speter #endif OBJ 628769Speter 629769Speter lenstr(sptr, padding) 630769Speter 631769Speter char *sptr; 632769Speter int padding; 633769Speter 634769Speter { 635769Speter register int cnt; 636769Speter register char *strptr = sptr; 637769Speter 638769Speter cnt = padding; 639769Speter do { 640769Speter cnt++; 641769Speter } while (*strptr++); 642769Speter return((++cnt) & ~1); 643769Speter } 644769Speter 645769Speter /* 646769Speter * Patch repairs the branch 647769Speter * at location loc to come 648769Speter * to the current location. 649769Speter * for PC, this puts down the label 650769Speter * and the branch just references that label. 651769Speter * lets here it for two pass assemblers. 652769Speter */ 653769Speter patch(loc) 654769Speter { 655769Speter 656769Speter # ifdef OBJ 6573077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 658769Speter # endif OBJ 659769Speter # ifdef PC 660769Speter putlab( loc ); 661769Speter # endif PC 662769Speter } 663769Speter 664769Speter #ifdef OBJ 665769Speter patch4(loc) 666769Speter { 6673077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 668769Speter } 669769Speter 670769Speter /* 6717921Smckusick * Patchfil makes loc+2 have jmploc 672769Speter * as its contents. 673769Speter */ 6747921Smckusick patchfil(loc, jmploc, words) 675769Speter PTR_DCL loc; 6767921Smckusick long jmploc; 6773077Smckusic int words; 678769Speter { 679769Speter register i; 6803077Smckusic int val; 681769Speter 6823317Speter if ( !CGENNING ) 683769Speter return; 684769Speter if (loc > (unsigned) lc) 685769Speter panic("patchfil"); 686769Speter #ifdef DEBUG 687769Speter if (opt('k')) 6887921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 689769Speter #endif 6907921Smckusick val = jmploc; 691769Speter do { 6923077Smckusic # ifndef DEC11 6933077Smckusic if (words > 1) 6947921Smckusick val = jmploc >> 16; 6953077Smckusic else 6967921Smckusick val = jmploc; 6973077Smckusic # endif DEC11 698769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 699769Speter if (i >= 0 && i < 1024) 7003077Smckusic obuf[i] = val; 701769Speter else { 702769Speter lseek(ofil, (long) loc+2, 0); 7033077Smckusic write(ofil, &val, 2); 704769Speter lseek(ofil, (long) 0, 2); 705769Speter } 706769Speter loc += 2; 7073077Smckusic # ifdef DEC11 7087921Smckusick val = jmploc >> 16; 7093077Smckusic # endif DEC11 710769Speter } while (--words); 711769Speter } 712769Speter 713769Speter /* 714769Speter * Put the word o into the code 715769Speter */ 716769Speter word(o) 717769Speter int o; 718769Speter { 719769Speter 720769Speter *obufp = o; 721769Speter obufp++; 722769Speter lc += 2; 723769Speter if (obufp >= obuf+512) 724769Speter pflush(); 725769Speter } 726769Speter 727769Speter extern char *obj; 728769Speter /* 729769Speter * Flush the code buffer 730769Speter */ 731769Speter pflush() 732769Speter { 733769Speter register i; 734769Speter 735769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 736769Speter if (i != 0 && write(ofil, obuf, i) != i) 737769Speter perror(obj), pexit(DIED); 738769Speter obufp = obuf; 739769Speter } 740769Speter #endif OBJ 741769Speter 742769Speter /* 743769Speter * Getlab - returns the location counter. 744769Speter * included here for the eventual code generator. 745769Speter * for PC, thank you! 746769Speter */ 747769Speter getlab() 748769Speter { 749769Speter # ifdef OBJ 750769Speter 751769Speter return (lc); 752769Speter # endif OBJ 753769Speter # ifdef PC 754769Speter static long lastlabel; 755769Speter 756769Speter return ( ++lastlabel ); 757769Speter # endif PC 758769Speter } 759769Speter 760769Speter /* 761769Speter * Putlab - lay down a label. 762769Speter * for PC, just print the label name with a colon after it. 763769Speter */ 764769Speter putlab(l) 765769Speter int l; 766769Speter { 767769Speter 768769Speter # ifdef PC 769769Speter putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l ); 770769Speter putprintf( ":" , 0 ); 771769Speter # endif PC 772769Speter return (l); 773769Speter } 774