1769Speter /* Copyright (c) 1979 Regents of the University of California */ 2769Speter 3*15208Sthien #ifndef lint 4*15208Sthien static char sccsid[] = "@(#)put.c 1.24 8/19/83"; 5*15208Sthien #endif 6769Speter 7769Speter #include "whoami.h" 8769Speter #include "opcode.h" 9769Speter #include "0.h" 10769Speter #include "objfmt.h" 11769Speter #ifdef PC 12769Speter # include "pc.h" 1310656Speter # include "align.h" 14*15208Sthien #else 15*15208Sthien short *obufp = obuf; 16*15208Sthien #endif 17769Speter 18769Speter /* 19769Speter * If DEBUG is defined, include the table 20769Speter * of the printing opcode names. 21769Speter */ 22769Speter #ifdef DEBUG 23769Speter #include "OPnames.h" 24769Speter #endif 25769Speter 26769Speter #ifdef OBJ 27769Speter /* 28769Speter * Put is responsible for the interpreter equivalent of code 29769Speter * generation. Since the interpreter is specifically designed 30769Speter * for Pascal, little work is required here. 31769Speter */ 32*15208Sthien /*VARARGS*/ 33769Speter put(a) 34769Speter { 35769Speter register int *p, i; 36769Speter register char *cp; 373077Smckusic register short *sp; 383077Smckusic register long *lp; 39*15208Sthien int n, subop, suboppr, op, oldlc; 40769Speter char *string; 41769Speter static int casewrd; 42769Speter 43769Speter /* 44769Speter * It would be nice to do some more 45769Speter * optimizations here. The work 46769Speter * done to collapse offsets in lval 47769Speter * should be done here, the IFEQ etc 48769Speter * relational operators could be used 49769Speter * etc. 50769Speter */ 51*15208Sthien oldlc = (int) lc; /* its either this or change put to return a char * */ 523317Speter if ( !CGENNING ) 53769Speter /* 54769Speter * code disabled - do nothing 55769Speter */ 56769Speter return (oldlc); 57769Speter p = &a; 58769Speter n = *p++; 593077Smckusic suboppr = subop = (*p >> 8) & 0377; 60769Speter op = *p & 0377; 61769Speter string = 0; 62769Speter #ifdef DEBUG 63769Speter if ((cp = otext[op]) == NIL) { 64769Speter printf("op= %o\n", op); 65769Speter panic("put"); 66769Speter } 67769Speter #endif 68769Speter switch (op) { 69769Speter case O_ABORT: 70769Speter cp = "*"; 71769Speter break; 722221Smckusic case O_AS: 732221Smckusic switch(p[1]) { 746594Smckusick case 0: 756594Smckusick break; 762221Smckusic case 2: 772221Smckusic op = O_AS2; 786594Smckusick n = 1; 792221Smckusic break; 802221Smckusic case 4: 812221Smckusic op = O_AS4; 826594Smckusick n = 1; 832221Smckusic break; 842221Smckusic case 8: 852221Smckusic op = O_AS8; 866594Smckusick n = 1; 872221Smckusic break; 882221Smckusic default: 892221Smckusic goto pack; 902221Smckusic } 913077Smckusic # ifdef DEBUG 923077Smckusic cp = otext[op]; 933077Smckusic # endif DEBUG 942221Smckusic break; 9510791Smckusick case O_FOR1U: 9610791Smckusick case O_FOR2U: 9710791Smckusick case O_FOR4U: 9810791Smckusick case O_FOR1D: 9910791Smckusick case O_FOR2D: 10010791Smckusick case O_FOR4D: 10110791Smckusick /* relative addressing */ 10210791Smckusick p[1] -= ( unsigned ) lc + sizeof(short); 10310791Smckusick /* try to pack the jump */ 10410791Smckusick if (p[1] <= 127 && p[1] >= -128) { 10510791Smckusick suboppr = subop = p[1]; 10610791Smckusick p++; 10710791Smckusick n--; 10810791Smckusick } else { 10910791Smckusick /* have to allow for extra displacement */ 11010791Smckusick p[1] -= sizeof(short); 11110791Smckusick } 11210791Smckusick break; 1133077Smckusic case O_CONG: 1143077Smckusic case O_LVCON: 1153077Smckusic case O_CON: 116769Speter case O_LINO: 117769Speter case O_NEW: 118769Speter case O_DISPOSE: 1197965Smckusick case O_DFDISP: 120769Speter case O_IND: 121769Speter case O_OFF: 122769Speter case O_INX2: 123769Speter case O_INX4: 124769Speter case O_CARD: 125769Speter case O_ADDT: 126769Speter case O_SUBT: 127769Speter case O_MULT: 128769Speter case O_IN: 129769Speter case O_CASE1OP: 130769Speter case O_CASE2OP: 131769Speter case O_CASE4OP: 1321199Speter case O_FRTN: 133769Speter case O_WRITES: 1343173Smckusic case O_WRITEC: 135769Speter case O_WRITEF: 136769Speter case O_MAX: 137769Speter case O_MIN: 138769Speter case O_ARGV: 139769Speter case O_CTTOT: 140769Speter case O_INCT: 141769Speter case O_RANG2: 142769Speter case O_RSNG2: 143769Speter case O_RANG42: 144769Speter case O_RSNG42: 1452105Smckusic case O_SUCC2: 1462105Smckusic case O_SUCC24: 1472105Smckusic case O_PRED2: 1482105Smckusic case O_PRED24: 149769Speter if (p[1] == 0) 150769Speter break; 151769Speter case O_CON2: 152769Speter case O_CON24: 1532221Smckusic pack: 15410791Smckusick if (p[1] <= 127 && p[1] >= -128) { 155769Speter suboppr = subop = p[1]; 156769Speter p++; 157769Speter n--; 158769Speter if (op == O_CON2) { 159769Speter op = O_CON1; 1603077Smckusic # ifdef DEBUG 1613077Smckusic cp = otext[O_CON1]; 1623077Smckusic # endif DEBUG 163769Speter } 164769Speter if (op == O_CON24) { 165769Speter op = O_CON14; 1663077Smckusic # ifdef DEBUG 1673077Smckusic cp = otext[O_CON14]; 1683077Smckusic # endif DEBUG 169769Speter } 170769Speter } 171769Speter break; 172769Speter case O_CON8: 173769Speter { 174*15208Sthien short *sp = (short *) (&p[1]); 175769Speter 176769Speter #ifdef DEBUG 177769Speter if ( opt( 'k' ) ) 1783317Speter printf ( "%5d\tCON8\t%22.14e\n" , 179769Speter lc - HEADER_BYTES , 180769Speter * ( ( double * ) &p[1] ) ); 181769Speter #endif 1823077Smckusic # ifdef DEC11 1833077Smckusic word(op); 1843077Smckusic # else 1853077Smckusic word(op << 8); 1863077Smckusic # endif DEC11 187769Speter for ( i = 1 ; i <= 4 ; i ++ ) 188769Speter word ( *sp ++ ); 189769Speter return ( oldlc ); 190769Speter } 191769Speter default: 192769Speter if (op >= O_REL2 && op <= O_REL84) { 1931883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 194769Speter i -= 30; 195769Speter else 196769Speter i += 2; 197769Speter #ifdef DEBUG 198769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 199769Speter #endif 200769Speter suboppr = 0; 201769Speter } 202769Speter break; 203769Speter case O_IF: 204769Speter case O_TRA: 205769Speter /***** 206769Speter codeline = 0; 207769Speter *****/ 2082184Smckusic /* relative addressing */ 2092184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 2102184Smckusic break; 211769Speter case O_CONC: 212769Speter #ifdef DEBUG 213769Speter (string = "'x'")[1] = p[1]; 214769Speter #endif 215769Speter suboppr = 0; 216769Speter op = O_CON1; 2173077Smckusic # ifdef DEBUG 2183077Smckusic cp = otext[O_CON1]; 2193077Smckusic # endif DEBUG 220769Speter subop = p[1]; 221769Speter goto around; 222769Speter case O_CONC4: 223769Speter #ifdef DEBUG 224769Speter (string = "'x'")[1] = p[1]; 225769Speter #endif 226769Speter suboppr = 0; 227769Speter op = O_CON14; 228769Speter subop = p[1]; 229769Speter goto around; 230769Speter case O_CON1: 231769Speter case O_CON14: 232769Speter suboppr = subop = p[1]; 233769Speter around: 234769Speter n--; 235769Speter break; 236769Speter case O_CASEBEG: 237769Speter casewrd = 0; 238769Speter return (oldlc); 239769Speter case O_CASEEND: 240769Speter if ((unsigned) lc & 1) { 241769Speter lc--; 242769Speter word(casewrd); 243769Speter } 244769Speter return (oldlc); 245769Speter case O_CASE1: 246769Speter #ifdef DEBUG 247769Speter if (opt('k')) 2483317Speter printf("%5d\tCASE1\t%d\n" 2493077Smckusic , lc - HEADER_BYTES, p[1]); 250769Speter #endif 251769Speter /* 252769Speter * this to build a byte size case table 253769Speter * saving bytes across calls in casewrd 254769Speter * so they can be put out by word() 255769Speter */ 256769Speter lc++; 257769Speter if ((unsigned) lc & 1) 2583077Smckusic # ifdef DEC11 2593077Smckusic casewrd = p[1] & 0377; 2603077Smckusic # else 2613077Smckusic casewrd = (p[1] & 0377) << 8; 2623077Smckusic # endif DEC11 263769Speter else { 264769Speter lc -= 2; 2653077Smckusic # ifdef DEC11 2663077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2673077Smckusic # else 2683077Smckusic word((p[1] & 0377) | casewrd); 2693077Smckusic # endif DEC11 270769Speter } 271769Speter return (oldlc); 272769Speter case O_CASE2: 273769Speter #ifdef DEBUG 274769Speter if (opt('k')) 2753317Speter printf("%5d\tCASE2\t%d\n" 2763077Smckusic , lc - HEADER_BYTES , p[1]); 277769Speter #endif 2783077Smckusic word(p[1]); 279769Speter return (oldlc); 280769Speter case O_PUSH: 2813077Smckusic lp = (long *)&p[1]; 2823077Smckusic if (*lp == 0) 283769Speter return (oldlc); 2844025Smckusic /* and fall through */ 2854025Smckusic case O_RANG4: 2864025Smckusic case O_RANG24: 2874025Smckusic case O_RSNG4: 2884025Smckusic case O_RSNG24: 2894025Smckusic case O_SUCC4: 2904025Smckusic case O_PRED4: 2914025Smckusic /* sub opcode optimization */ 2924025Smckusic lp = (long *)&p[1]; 2934025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 2943077Smckusic suboppr = subop = *lp; 2954025Smckusic p += (sizeof(long) / sizeof(int)); 296769Speter n--; 297769Speter } 298769Speter goto longgen; 299769Speter case O_TRA4: 300769Speter case O_CALL: 3011199Speter case O_FSAV: 302769Speter case O_GOTO: 303769Speter case O_NAM: 304769Speter case O_READE: 305769Speter /* absolute long addressing */ 3063077Smckusic lp = (long *)&p[1]; 3073077Smckusic *lp -= HEADER_BYTES; 308769Speter goto longgen; 309769Speter case O_RV1: 310769Speter case O_RV14: 311769Speter case O_RV2: 312769Speter case O_RV24: 313769Speter case O_RV4: 314769Speter case O_RV8: 315769Speter case O_RV: 316769Speter case O_LV: 3172105Smckusic /* 3182105Smckusic * positive offsets represent arguments 3192105Smckusic * and must use "ap" display entry rather 3202105Smckusic * than the "fp" entry 3212105Smckusic */ 3222105Smckusic if (p[1] >= 0) { 3232105Smckusic subop++; 3242105Smckusic suboppr++; 3252105Smckusic } 3263077Smckusic # ifdef PDP11 3273077Smckusic break; 3283077Smckusic # else 3293077Smckusic /* 3303077Smckusic * offsets out of range of word addressing 3313077Smckusic * must use long offset opcodes 3323077Smckusic */ 3333077Smckusic if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) 3343077Smckusic break; 3353077Smckusic else { 336769Speter op += O_LRV - O_RV; 3373077Smckusic # ifdef DEBUG 3383077Smckusic cp = otext[op]; 3393077Smckusic # endif DEBUG 3403077Smckusic } 3413077Smckusic /* and fall through */ 3423077Smckusic # endif PDP11 343769Speter case O_BEG: 344769Speter case O_NODUMP: 345769Speter case O_CON4: 346769Speter case O_CASE4: 347769Speter longgen: 348769Speter n = (n << 1) - 1; 34910791Smckusick if ( op == O_LRV ) { 350769Speter n--; 35110562Smckusick # if defined(ADDR32) && !defined(DEC11) 35210562Smckusick p[n / 2] <<= 16; 35310562Smckusick # endif 35410562Smckusick } 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; 417*15208Sthien #ifdef OBJ 418*15208Sthien register int oldlc; 419*15208Sthien #endif 420*15208Sthien register int len; 421769Speter register unsigned w; 422769Speter register char *strptr; 423769Speter 4243317Speter if ( !CGENNING ) 425769Speter /* code is off - do nothing */ 426769Speter return(NIL); 427769Speter if (ap->class != TYPE) 428769Speter ap = ap->type; 429769Speter if (ap->value[ NL_ELABEL ] != 0) { 430769Speter /* the list already exists */ 431769Speter return( ap -> value[ NL_ELABEL ] ); 432769Speter } 433769Speter # ifdef OBJ 434*15208Sthien oldlc = (int) lc; /* same problem as put */ 435*15208Sthien (void) put(2, O_TRA, lc); 436*15208Sthien ap->value[ NL_ELABEL ] = (int) lc; 437769Speter # endif OBJ 438769Speter # ifdef PC 43910656Speter putprintf(" .data", 0); 44010656Speter aligndot(A_STRUCT); 441*15208Sthien ap -> value[ NL_ELABEL ] = (int) getlab(); 442*15208Sthien (void) putlab((char *) ap -> value[ NL_ELABEL ] ); 443769Speter # endif PC 444769Speter /* number of scalars */ 445769Speter next = ap->type; 446769Speter len = next->range[1]-next->range[0]+1; 447769Speter # ifdef OBJ 448*15208Sthien (void) put(2, O_CASE2, len); 449769Speter # endif OBJ 450769Speter # ifdef PC 451769Speter putprintf( " .word %d" , 0 , len ); 452769Speter # endif PC 453769Speter /* offsets of each scalar name */ 454769Speter len = (len+1)*sizeof(short); 455769Speter # ifdef OBJ 456*15208Sthien (void) put(2, O_CASE2, len); 457769Speter # endif OBJ 458769Speter # ifdef PC 459769Speter putprintf( " .word %d" , 0 , len ); 460769Speter # endif PC 461769Speter next = ap->chain; 462769Speter do { 463769Speter for(strptr = next->symbol; *strptr++; len++) 464769Speter continue; 465769Speter len++; 466769Speter # ifdef OBJ 467*15208Sthien (void) put(2, O_CASE2, len); 468769Speter # endif OBJ 469769Speter # ifdef PC 470769Speter putprintf( " .word %d" , 0 , len ); 471769Speter # endif PC 472769Speter } while (next = next->chain); 473769Speter /* list of scalar names */ 474769Speter strptr = getnext(ap, &next); 475769Speter # ifdef OBJ 476769Speter do { 4773077Smckusic # ifdef DEC11 4783077Smckusic w = (unsigned) *strptr; 4793077Smckusic # else 4803077Smckusic w = *strptr << 8; 4813077Smckusic # endif DEC11 482769Speter if (!*strptr++) 483769Speter strptr = getnext(next, &next); 4843077Smckusic # ifdef DEC11 4853077Smckusic w |= *strptr << 8; 4863077Smckusic # else 4873077Smckusic w |= (unsigned) *strptr; 4883077Smckusic # endif DEC11 489769Speter if (!*strptr++) 490769Speter strptr = getnext(next, &next); 491*15208Sthien word((int) w); 492769Speter } while (next); 493769Speter /* jump over the mess */ 494*15208Sthien patch((PTR_DCL) oldlc); 495769Speter # endif OBJ 496769Speter # ifdef PC 497769Speter while ( next ) { 498769Speter while ( *strptr ) { 499769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 500769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 501769Speter putprintf( ",0%o" , 1 , *strptr++ ); 502769Speter } 503769Speter putprintf( "" , 0 ); 504769Speter } 505769Speter putprintf( " .byte 0" , 0 ); 506769Speter strptr = getnext( next , &next ); 507769Speter } 508769Speter putprintf( " .text" , 0 ); 509769Speter # endif PC 510769Speter return( ap -> value[ NL_ELABEL ] ); 511769Speter } 512769Speter 513*15208Sthien char * 514769Speter getnext(next, new) 515769Speter 516769Speter struct nl *next, **new; 517769Speter { 518769Speter if (next != NIL) { 519769Speter next = next->chain; 520769Speter *new = next; 521769Speter } 522*15208Sthien if (next == NLNIL) 523769Speter return(""); 524769Speter #ifdef OBJ 5253317Speter if (opt('k') && CGENNING ) 5263317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5272213Speter #endif OBJ 528769Speter return(next->symbol); 529769Speter } 530769Speter 531769Speter #ifdef OBJ 532769Speter /* 533769Speter * Putspace puts out a table 534769Speter * of nothing to leave space 535769Speter * for the case branch table e.g. 536769Speter */ 537769Speter putspace(n) 538769Speter int n; 539769Speter { 540769Speter register i; 541769Speter 5423317Speter if ( !CGENNING ) 543769Speter /* 544769Speter * code disabled - do nothing 545769Speter */ 546*15208Sthien return; 547769Speter #ifdef DEBUG 548769Speter if (opt('k')) 5493317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 550769Speter #endif 551769Speter for (i = even(n); i > 0; i -= 2) 552769Speter word(0); 553769Speter } 554769Speter 555769Speter putstr(sptr, padding) 556769Speter 557769Speter char *sptr; 558769Speter int padding; 559769Speter { 560769Speter register unsigned short w; 561769Speter register char *strptr = sptr; 562769Speter register int pad = padding; 563769Speter 5643317Speter if ( !CGENNING ) 565769Speter /* 566769Speter * code disabled - do nothing 567769Speter */ 568*15208Sthien return; 569769Speter #ifdef DEBUG 570769Speter if (opt('k')) 5713317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 572769Speter #endif 573769Speter if (pad == 0) { 574769Speter do { 5753077Smckusic # ifdef DEC11 5763077Smckusic w = (unsigned short) * strptr; 5773077Smckusic # else 5783077Smckusic w = (unsigned short)*strptr<<8; 5793077Smckusic # endif DEC11 580769Speter if (w) 5813077Smckusic # ifdef DEC11 5823077Smckusic w |= *++strptr << 8; 5833077Smckusic # else 5843077Smckusic w |= *++strptr; 5853077Smckusic # endif DEC11 586*15208Sthien word((int) w); 587769Speter } while (*strptr++); 588769Speter } else { 5893077Smckusic # ifdef DEC11 5903077Smckusic do { 5913077Smckusic w = (unsigned short) * strptr; 5923077Smckusic if (w) { 5933077Smckusic if (*++strptr) 5943077Smckusic w |= *strptr << 8; 5953077Smckusic else { 59611885Smckusick w |= ' ' << 8; 5973077Smckusic pad--; 5983077Smckusic } 599*15208Sthien word((int) w); 6003077Smckusic } 6013077Smckusic } while (*strptr++); 6023077Smckusic # else 6033077Smckusic do { 6043077Smckusic w = (unsigned short)*strptr<<8; 6053077Smckusic if (w) { 6063077Smckusic if (*++strptr) 6073077Smckusic w |= *strptr; 6083077Smckusic else { 6093077Smckusic w |= ' '; 6103077Smckusic pad--; 6113077Smckusic } 6123077Smckusic word(w); 6133077Smckusic } 6143077Smckusic } while (*strptr++); 6153077Smckusic # endif DEC11 616769Speter while (pad > 1) { 61711885Smckusick # ifdef DEC11 61811885Smckusick word(' ' | (' ' << 8)); 61911885Smckusick # else 62011885Smckusick word((' ' << 8) | ' '); 62111885Smckusick # endif DEC11 622769Speter pad -= 2; 623769Speter } 624769Speter if (pad == 1) 6253077Smckusic # ifdef DEC11 6263077Smckusic word(' '); 6273077Smckusic # else 62811885Smckusick word(' ' << 8); 6293077Smckusic # endif DEC11 630769Speter else 631769Speter word(0); 632769Speter } 633769Speter } 634769Speter #endif OBJ 635769Speter 636*15208Sthien #ifndef PC 637769Speter lenstr(sptr, padding) 638769Speter 639769Speter char *sptr; 640769Speter int padding; 641769Speter 642769Speter { 643769Speter register int cnt; 644769Speter register char *strptr = sptr; 645769Speter 646769Speter cnt = padding; 647769Speter do { 648769Speter cnt++; 649769Speter } while (*strptr++); 650769Speter return((++cnt) & ~1); 651769Speter } 652*15208Sthien #endif 653769Speter 654769Speter /* 655769Speter * Patch repairs the branch 656769Speter * at location loc to come 657769Speter * to the current location. 658769Speter * for PC, this puts down the label 659769Speter * and the branch just references that label. 660769Speter * lets here it for two pass assemblers. 661769Speter */ 662769Speter patch(loc) 663*15208Sthien PTR_DCL loc; 664769Speter { 665769Speter 666769Speter # ifdef OBJ 6673077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 668769Speter # endif OBJ 669769Speter # ifdef PC 670*15208Sthien (void) putlab((char *) loc ); 671769Speter # endif PC 672769Speter } 673769Speter 674769Speter #ifdef OBJ 675769Speter patch4(loc) 676*15208Sthien PTR_DCL loc; 677769Speter { 6783077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 679769Speter } 680769Speter 681769Speter /* 6827921Smckusick * Patchfil makes loc+2 have jmploc 683769Speter * as its contents. 684769Speter */ 6857921Smckusick patchfil(loc, jmploc, words) 686769Speter PTR_DCL loc; 6877921Smckusick long jmploc; 6883077Smckusic int words; 689769Speter { 690769Speter register i; 691*15208Sthien extern long lseek(); 69210562Smckusick short val; 693769Speter 6943317Speter if ( !CGENNING ) 695769Speter return; 696769Speter if (loc > (unsigned) lc) 697769Speter panic("patchfil"); 698769Speter #ifdef DEBUG 699769Speter if (opt('k')) 7007921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 701769Speter #endif 7027921Smckusick val = jmploc; 703769Speter do { 7043077Smckusic # ifndef DEC11 7053077Smckusic if (words > 1) 7067921Smckusick val = jmploc >> 16; 7073077Smckusic else 7087921Smckusick val = jmploc; 7093077Smckusic # endif DEC11 710769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 71110562Smckusick if (i >= 0 && i < 1024) { 7123077Smckusic obuf[i] = val; 71310562Smckusick } else { 714*15208Sthien (void) lseek(ofil, (long) loc+2, 0); 715*15208Sthien write(ofil, (char *) (&val), 2); 716*15208Sthien (void) lseek(ofil, (long) 0, 2); 717769Speter } 718769Speter loc += 2; 7193077Smckusic # ifdef DEC11 7207921Smckusick val = jmploc >> 16; 7213077Smckusic # endif DEC11 722769Speter } while (--words); 723769Speter } 724769Speter 725769Speter /* 726769Speter * Put the word o into the code 727769Speter */ 728769Speter word(o) 729769Speter int o; 730769Speter { 731769Speter 732769Speter *obufp = o; 733769Speter obufp++; 734769Speter lc += 2; 735769Speter if (obufp >= obuf+512) 736769Speter pflush(); 737769Speter } 738769Speter 739769Speter extern char *obj; 740769Speter /* 741769Speter * Flush the code buffer 742769Speter */ 743769Speter pflush() 744769Speter { 745769Speter register i; 746769Speter 747769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 748*15208Sthien if (i != 0 && write(ofil, (char *) obuf, i) != i) 749769Speter perror(obj), pexit(DIED); 750769Speter obufp = obuf; 751769Speter } 752769Speter #endif OBJ 753769Speter 754769Speter /* 755769Speter * Getlab - returns the location counter. 756769Speter * included here for the eventual code generator. 757769Speter * for PC, thank you! 758769Speter */ 759*15208Sthien char * 760769Speter getlab() 761769Speter { 762769Speter # ifdef OBJ 763769Speter 764769Speter return (lc); 765769Speter # endif OBJ 766769Speter # ifdef PC 767769Speter static long lastlabel; 768769Speter 769*15208Sthien return ( (char *) ++lastlabel ); 770769Speter # endif PC 771769Speter } 772769Speter 773769Speter /* 774769Speter * Putlab - lay down a label. 775769Speter * for PC, just print the label name with a colon after it. 776769Speter */ 777*15208Sthien char * 778769Speter putlab(l) 779*15208Sthien char *l; 780769Speter { 781769Speter 782769Speter # ifdef PC 783*15208Sthien putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l ); 784769Speter putprintf( ":" , 0 ); 785769Speter # endif PC 786769Speter return (l); 787769Speter } 788