123528Smckusick /* 223528Smckusick * Copyright (c) 1980 Regents of the University of California. 323528Smckusick * All rights reserved. The Berkeley software License Agreement 423528Smckusick * specifies the terms and conditions for redistribution. 523528Smckusick */ 6769Speter 715208Sthien #ifndef lint 8*30036Smckusick static char sccsid[] = "@(#)put.c 5.2 (Berkeley) 11/12/86"; 923528Smckusick #endif not lint 10769Speter 11769Speter #include "whoami.h" 12769Speter #include "opcode.h" 13769Speter #include "0.h" 14769Speter #include "objfmt.h" 15769Speter #ifdef PC 16769Speter # include "pc.h" 1710656Speter # include "align.h" 1815208Sthien #else 1915208Sthien short *obufp = obuf; 2015208Sthien #endif 21769Speter 22769Speter /* 23769Speter * If DEBUG is defined, include the table 24769Speter * of the printing opcode names. 25769Speter */ 26769Speter #ifdef DEBUG 27769Speter #include "OPnames.h" 28769Speter #endif 29769Speter 30769Speter #ifdef OBJ 31769Speter /* 32769Speter * Put is responsible for the interpreter equivalent of code 33769Speter * generation. Since the interpreter is specifically designed 34769Speter * for Pascal, little work is required here. 35769Speter */ 3615208Sthien /*VARARGS*/ 37769Speter put(a) 38769Speter { 39769Speter register int *p, i; 40769Speter register char *cp; 413077Smckusic register short *sp; 423077Smckusic register long *lp; 4315208Sthien int n, subop, suboppr, op, oldlc; 44769Speter char *string; 45769Speter static int casewrd; 46769Speter 47769Speter /* 48769Speter * It would be nice to do some more 49769Speter * optimizations here. The work 50769Speter * done to collapse offsets in lval 51769Speter * should be done here, the IFEQ etc 52769Speter * relational operators could be used 53769Speter * etc. 54769Speter */ 5515208Sthien oldlc = (int) lc; /* its either this or change put to return a char * */ 563317Speter if ( !CGENNING ) 57769Speter /* 58769Speter * code disabled - do nothing 59769Speter */ 60769Speter return (oldlc); 61769Speter p = &a; 62769Speter n = *p++; 633077Smckusic suboppr = subop = (*p >> 8) & 0377; 64769Speter op = *p & 0377; 65769Speter string = 0; 66769Speter #ifdef DEBUG 67769Speter if ((cp = otext[op]) == NIL) { 68769Speter printf("op= %o\n", op); 69769Speter panic("put"); 70769Speter } 71769Speter #endif 72769Speter switch (op) { 73769Speter case O_ABORT: 74769Speter cp = "*"; 75769Speter break; 762221Smckusic case O_AS: 772221Smckusic switch(p[1]) { 786594Smckusick case 0: 796594Smckusick break; 802221Smckusic case 2: 812221Smckusic op = O_AS2; 826594Smckusick n = 1; 832221Smckusic break; 842221Smckusic case 4: 852221Smckusic op = O_AS4; 866594Smckusick n = 1; 872221Smckusic break; 882221Smckusic case 8: 892221Smckusic op = O_AS8; 906594Smckusick n = 1; 912221Smckusic break; 922221Smckusic default: 932221Smckusic goto pack; 942221Smckusic } 953077Smckusic # ifdef DEBUG 963077Smckusic cp = otext[op]; 973077Smckusic # endif DEBUG 982221Smckusic break; 9910791Smckusick case O_FOR1U: 10010791Smckusick case O_FOR2U: 10110791Smckusick case O_FOR4U: 10210791Smckusick case O_FOR1D: 10310791Smckusick case O_FOR2D: 10410791Smckusick case O_FOR4D: 10510791Smckusick /* relative addressing */ 10610791Smckusick p[1] -= ( unsigned ) lc + sizeof(short); 10710791Smckusick /* try to pack the jump */ 10810791Smckusick if (p[1] <= 127 && p[1] >= -128) { 10910791Smckusick suboppr = subop = p[1]; 11010791Smckusick p++; 11110791Smckusick n--; 11210791Smckusick } else { 11310791Smckusick /* have to allow for extra displacement */ 11410791Smckusick p[1] -= sizeof(short); 11510791Smckusick } 11610791Smckusick break; 1173077Smckusic case O_CONG: 1183077Smckusic case O_LVCON: 1193077Smckusic case O_CON: 120769Speter case O_LINO: 121769Speter case O_NEW: 122769Speter case O_DISPOSE: 1237965Smckusick case O_DFDISP: 124769Speter case O_IND: 125769Speter case O_OFF: 126769Speter case O_INX2: 127769Speter case O_INX4: 128769Speter case O_CARD: 129769Speter case O_ADDT: 130769Speter case O_SUBT: 131769Speter case O_MULT: 132769Speter case O_IN: 133769Speter case O_CASE1OP: 134769Speter case O_CASE2OP: 135769Speter case O_CASE4OP: 1361199Speter case O_FRTN: 137769Speter case O_WRITES: 1383173Smckusic case O_WRITEC: 139769Speter case O_WRITEF: 140769Speter case O_MAX: 141769Speter case O_MIN: 142769Speter case O_ARGV: 143769Speter case O_CTTOT: 144769Speter case O_INCT: 145769Speter case O_RANG2: 146769Speter case O_RSNG2: 147769Speter case O_RANG42: 148769Speter case O_RSNG42: 1492105Smckusic case O_SUCC2: 1502105Smckusic case O_SUCC24: 1512105Smckusic case O_PRED2: 1522105Smckusic case O_PRED24: 153769Speter if (p[1] == 0) 154769Speter break; 155769Speter case O_CON2: 156769Speter case O_CON24: 1572221Smckusic pack: 15810791Smckusick if (p[1] <= 127 && p[1] >= -128) { 159769Speter suboppr = subop = p[1]; 160769Speter p++; 161769Speter n--; 162769Speter if (op == O_CON2) { 163769Speter op = O_CON1; 1643077Smckusic # ifdef DEBUG 1653077Smckusic cp = otext[O_CON1]; 1663077Smckusic # endif DEBUG 167769Speter } 168769Speter if (op == O_CON24) { 169769Speter op = O_CON14; 1703077Smckusic # ifdef DEBUG 1713077Smckusic cp = otext[O_CON14]; 1723077Smckusic # endif DEBUG 173769Speter } 174769Speter } 175769Speter break; 176769Speter case O_CON8: 177769Speter { 17815208Sthien short *sp = (short *) (&p[1]); 179769Speter 180769Speter #ifdef DEBUG 181769Speter if ( opt( 'k' ) ) 1823317Speter printf ( "%5d\tCON8\t%22.14e\n" , 183769Speter lc - HEADER_BYTES , 184769Speter * ( ( double * ) &p[1] ) ); 185769Speter #endif 1863077Smckusic # ifdef DEC11 1873077Smckusic word(op); 1883077Smckusic # else 1893077Smckusic word(op << 8); 1903077Smckusic # endif DEC11 191769Speter for ( i = 1 ; i <= 4 ; i ++ ) 192769Speter word ( *sp ++ ); 193769Speter return ( oldlc ); 194769Speter } 195769Speter default: 196769Speter if (op >= O_REL2 && op <= O_REL84) { 1971883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 198769Speter i -= 30; 199769Speter else 200769Speter i += 2; 201769Speter #ifdef DEBUG 202769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 203769Speter #endif 204769Speter suboppr = 0; 205769Speter } 206769Speter break; 207769Speter case O_IF: 208769Speter case O_TRA: 209769Speter /***** 210769Speter codeline = 0; 211769Speter *****/ 2122184Smckusic /* relative addressing */ 2132184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 2142184Smckusic break; 215769Speter case O_CONC: 216769Speter #ifdef DEBUG 217769Speter (string = "'x'")[1] = p[1]; 218769Speter #endif 219769Speter suboppr = 0; 220769Speter op = O_CON1; 2213077Smckusic # ifdef DEBUG 2223077Smckusic cp = otext[O_CON1]; 2233077Smckusic # endif DEBUG 224769Speter subop = p[1]; 225769Speter goto around; 226769Speter case O_CONC4: 227769Speter #ifdef DEBUG 228769Speter (string = "'x'")[1] = p[1]; 229769Speter #endif 230769Speter suboppr = 0; 231769Speter op = O_CON14; 232769Speter subop = p[1]; 233769Speter goto around; 234769Speter case O_CON1: 235769Speter case O_CON14: 236769Speter suboppr = subop = p[1]; 237769Speter around: 238769Speter n--; 239769Speter break; 240769Speter case O_CASEBEG: 241769Speter casewrd = 0; 242769Speter return (oldlc); 243769Speter case O_CASEEND: 244769Speter if ((unsigned) lc & 1) { 245769Speter lc--; 246769Speter word(casewrd); 247769Speter } 248769Speter return (oldlc); 249769Speter case O_CASE1: 250769Speter #ifdef DEBUG 251769Speter if (opt('k')) 2523317Speter printf("%5d\tCASE1\t%d\n" 2533077Smckusic , lc - HEADER_BYTES, p[1]); 254769Speter #endif 255769Speter /* 256769Speter * this to build a byte size case table 257769Speter * saving bytes across calls in casewrd 258769Speter * so they can be put out by word() 259769Speter */ 260769Speter lc++; 261769Speter if ((unsigned) lc & 1) 2623077Smckusic # ifdef DEC11 2633077Smckusic casewrd = p[1] & 0377; 2643077Smckusic # else 2653077Smckusic casewrd = (p[1] & 0377) << 8; 2663077Smckusic # endif DEC11 267769Speter else { 268769Speter lc -= 2; 2693077Smckusic # ifdef DEC11 2703077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2713077Smckusic # else 2723077Smckusic word((p[1] & 0377) | casewrd); 2733077Smckusic # endif DEC11 274769Speter } 275769Speter return (oldlc); 276769Speter case O_CASE2: 277769Speter #ifdef DEBUG 278769Speter if (opt('k')) 2793317Speter printf("%5d\tCASE2\t%d\n" 2803077Smckusic , lc - HEADER_BYTES , p[1]); 281769Speter #endif 2823077Smckusic word(p[1]); 283769Speter return (oldlc); 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; 35310791Smckusick if ( op == O_LRV ) { 354769Speter n--; 35510562Smckusick # if defined(ADDR32) && !defined(DEC11) 35610562Smckusick p[n / 2] <<= 16; 35710562Smckusick # endif 35810562Smckusick } 359769Speter #ifdef DEBUG 3603077Smckusic if (opt('k')) { 3613317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 362769Speter if (suboppr) 3633077Smckusic printf(":%d", suboppr); 3643077Smckusic for ( i = 2, lp = (long *)&p[1]; i < n 365769Speter ; i += sizeof ( long )/sizeof ( short ) ) 366769Speter printf( "\t%D " , *lp ++ ); 3673377Speter if (i == n) { 3683377Speter sp = (short *)lp; 3693377Speter printf( "\t%d ", *sp ); 3703377Speter } 371769Speter pchr ( '\n' ); 3723077Smckusic } 373769Speter #endif 374769Speter if ( op != O_CASE4 ) 3753077Smckusic # ifdef DEC11 3763077Smckusic word((op & 0377) | subop << 8); 3773077Smckusic # else 3783077Smckusic word(op << 8 | (subop & 0377)); 3793077Smckusic # endif DEC11 3803077Smckusic for ( i = 1, sp = (short *)&p[1]; i < n; i++) 3813077Smckusic word ( *sp ++ ); 382769Speter return ( oldlc ); 383769Speter } 384769Speter #ifdef DEBUG 385769Speter if (opt('k')) { 3863317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 387769Speter if (suboppr) 388769Speter printf(":%d", suboppr); 389769Speter if (string) 390769Speter printf("\t%s",string); 391769Speter if (n > 1) 392769Speter pchr('\t'); 393769Speter for (i=1; i<n; i++) 3943077Smckusic printf("%d ", p[i]); 395769Speter pchr('\n'); 396769Speter } 397769Speter #endif 398769Speter if (op != NIL) 3993077Smckusic # ifdef DEC11 4003077Smckusic word((op & 0377) | subop << 8); 4013077Smckusic # else 4023077Smckusic word(op << 8 | (subop & 0377)); 4033077Smckusic # endif DEC11 404769Speter for (i=1; i<n; i++) 405769Speter word(p[i]); 406769Speter return (oldlc); 407769Speter } 408769Speter #endif OBJ 409769Speter 410769Speter /* 411769Speter * listnames outputs a list of enumerated type names which 412769Speter * can then be selected from to output a TSCAL 413769Speter * a pointer to the address in the code of the namelist 414769Speter * is kept in value[ NL_ELABEL ]. 415769Speter */ 416769Speter listnames(ap) 417769Speter 418769Speter register struct nl *ap; 419769Speter { 420769Speter struct nl *next; 42115208Sthien #ifdef OBJ 42215208Sthien register int oldlc; 42315208Sthien #endif 42415208Sthien register int len; 425769Speter register unsigned w; 426769Speter register char *strptr; 427769Speter 4283317Speter if ( !CGENNING ) 429769Speter /* code is off - do nothing */ 430769Speter return(NIL); 431769Speter if (ap->class != TYPE) 432769Speter ap = ap->type; 433769Speter if (ap->value[ NL_ELABEL ] != 0) { 434769Speter /* the list already exists */ 435769Speter return( ap -> value[ NL_ELABEL ] ); 436769Speter } 437769Speter # ifdef OBJ 43815208Sthien oldlc = (int) lc; /* same problem as put */ 43915208Sthien (void) put(2, O_TRA, lc); 44015208Sthien ap->value[ NL_ELABEL ] = (int) lc; 441769Speter # endif OBJ 442769Speter # ifdef PC 44310656Speter putprintf(" .data", 0); 44410656Speter aligndot(A_STRUCT); 44515208Sthien ap -> value[ NL_ELABEL ] = (int) getlab(); 44615208Sthien (void) putlab((char *) ap -> value[ NL_ELABEL ] ); 447769Speter # endif PC 448769Speter /* number of scalars */ 449769Speter next = ap->type; 450769Speter len = next->range[1]-next->range[0]+1; 451769Speter # ifdef OBJ 45215208Sthien (void) put(2, O_CASE2, len); 453769Speter # endif OBJ 454769Speter # ifdef PC 455769Speter putprintf( " .word %d" , 0 , len ); 456769Speter # endif PC 457769Speter /* offsets of each scalar name */ 458769Speter len = (len+1)*sizeof(short); 459769Speter # ifdef OBJ 46015208Sthien (void) put(2, O_CASE2, len); 461769Speter # endif OBJ 462769Speter # ifdef PC 463769Speter putprintf( " .word %d" , 0 , len ); 464769Speter # endif PC 465769Speter next = ap->chain; 466769Speter do { 467769Speter for(strptr = next->symbol; *strptr++; len++) 468769Speter continue; 469769Speter len++; 470769Speter # ifdef OBJ 47115208Sthien (void) put(2, O_CASE2, len); 472769Speter # endif OBJ 473769Speter # ifdef PC 474769Speter putprintf( " .word %d" , 0 , len ); 475769Speter # endif PC 476769Speter } while (next = next->chain); 477769Speter /* list of scalar names */ 478769Speter strptr = getnext(ap, &next); 479769Speter # ifdef OBJ 480769Speter do { 4813077Smckusic # ifdef DEC11 4823077Smckusic w = (unsigned) *strptr; 4833077Smckusic # else 4843077Smckusic w = *strptr << 8; 4853077Smckusic # endif DEC11 486769Speter if (!*strptr++) 487769Speter strptr = getnext(next, &next); 4883077Smckusic # ifdef DEC11 4893077Smckusic w |= *strptr << 8; 4903077Smckusic # else 4913077Smckusic w |= (unsigned) *strptr; 4923077Smckusic # endif DEC11 493769Speter if (!*strptr++) 494769Speter strptr = getnext(next, &next); 49515208Sthien word((int) w); 496769Speter } while (next); 497769Speter /* jump over the mess */ 49815208Sthien patch((PTR_DCL) oldlc); 499769Speter # endif OBJ 500769Speter # ifdef PC 501769Speter while ( next ) { 502769Speter while ( *strptr ) { 503769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 504769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 505769Speter putprintf( ",0%o" , 1 , *strptr++ ); 506769Speter } 507769Speter putprintf( "" , 0 ); 508769Speter } 509769Speter putprintf( " .byte 0" , 0 ); 510769Speter strptr = getnext( next , &next ); 511769Speter } 512769Speter putprintf( " .text" , 0 ); 513769Speter # endif PC 514769Speter return( ap -> value[ NL_ELABEL ] ); 515769Speter } 516769Speter 51715208Sthien char * 518769Speter getnext(next, new) 519769Speter 520769Speter struct nl *next, **new; 521769Speter { 522769Speter if (next != NIL) { 523769Speter next = next->chain; 524769Speter *new = next; 525769Speter } 52615208Sthien if (next == NLNIL) 527769Speter return(""); 528769Speter #ifdef OBJ 5293317Speter if (opt('k') && CGENNING ) 5303317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5312213Speter #endif OBJ 532769Speter return(next->symbol); 533769Speter } 534769Speter 535769Speter #ifdef OBJ 536769Speter /* 537769Speter * Putspace puts out a table 538769Speter * of nothing to leave space 539769Speter * for the case branch table e.g. 540769Speter */ 541769Speter putspace(n) 542769Speter int n; 543769Speter { 544769Speter register i; 545769Speter 5463317Speter if ( !CGENNING ) 547769Speter /* 548769Speter * code disabled - do nothing 549769Speter */ 55015208Sthien return; 551769Speter #ifdef DEBUG 552769Speter if (opt('k')) 5533317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 554769Speter #endif 555*30036Smckusick for (i = n; i > 0; i -= 2) 556769Speter word(0); 557769Speter } 558769Speter 559769Speter putstr(sptr, padding) 560769Speter 561769Speter char *sptr; 562769Speter int padding; 563769Speter { 564769Speter register unsigned short w; 565769Speter register char *strptr = sptr; 566769Speter register int pad = padding; 567769Speter 5683317Speter if ( !CGENNING ) 569769Speter /* 570769Speter * code disabled - do nothing 571769Speter */ 57215208Sthien return; 573769Speter #ifdef DEBUG 574769Speter if (opt('k')) 5753317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 576769Speter #endif 577769Speter if (pad == 0) { 578769Speter do { 5793077Smckusic # ifdef DEC11 5803077Smckusic w = (unsigned short) * strptr; 5813077Smckusic # else 5823077Smckusic w = (unsigned short)*strptr<<8; 5833077Smckusic # endif DEC11 584769Speter if (w) 5853077Smckusic # ifdef DEC11 5863077Smckusic w |= *++strptr << 8; 5873077Smckusic # else 5883077Smckusic w |= *++strptr; 5893077Smckusic # endif DEC11 59015208Sthien word((int) w); 591769Speter } while (*strptr++); 592769Speter } else { 5933077Smckusic # ifdef DEC11 5943077Smckusic do { 5953077Smckusic w = (unsigned short) * strptr; 5963077Smckusic if (w) { 5973077Smckusic if (*++strptr) 5983077Smckusic w |= *strptr << 8; 5993077Smckusic else { 60011885Smckusick w |= ' ' << 8; 6013077Smckusic pad--; 6023077Smckusic } 60315208Sthien word((int) w); 6043077Smckusic } 6053077Smckusic } while (*strptr++); 6063077Smckusic # else 6073077Smckusic do { 6083077Smckusic w = (unsigned short)*strptr<<8; 6093077Smckusic if (w) { 6103077Smckusic if (*++strptr) 6113077Smckusic w |= *strptr; 6123077Smckusic else { 6133077Smckusic w |= ' '; 6143077Smckusic pad--; 6153077Smckusic } 6163077Smckusic word(w); 6173077Smckusic } 6183077Smckusic } while (*strptr++); 6193077Smckusic # endif DEC11 620769Speter while (pad > 1) { 62111885Smckusick # ifdef DEC11 62211885Smckusick word(' ' | (' ' << 8)); 62311885Smckusick # else 62411885Smckusick word((' ' << 8) | ' '); 62511885Smckusick # endif DEC11 626769Speter pad -= 2; 627769Speter } 628769Speter if (pad == 1) 6293077Smckusic # ifdef DEC11 6303077Smckusic word(' '); 6313077Smckusic # else 63211885Smckusick word(' ' << 8); 6333077Smckusic # endif DEC11 634769Speter else 635769Speter word(0); 636769Speter } 637769Speter } 638769Speter #endif OBJ 639769Speter 64015208Sthien #ifndef PC 641769Speter lenstr(sptr, padding) 642769Speter 643769Speter char *sptr; 644769Speter int padding; 645769Speter 646769Speter { 647769Speter register int cnt; 648769Speter register char *strptr = sptr; 649769Speter 650769Speter cnt = padding; 651769Speter do { 652769Speter cnt++; 653769Speter } while (*strptr++); 654769Speter return((++cnt) & ~1); 655769Speter } 65615208Sthien #endif 657769Speter 658769Speter /* 659769Speter * Patch repairs the branch 660769Speter * at location loc to come 661769Speter * to the current location. 662769Speter * for PC, this puts down the label 663769Speter * and the branch just references that label. 664769Speter * lets here it for two pass assemblers. 665769Speter */ 666769Speter patch(loc) 66715208Sthien PTR_DCL loc; 668769Speter { 669769Speter 670769Speter # ifdef OBJ 6713077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 672769Speter # endif OBJ 673769Speter # ifdef PC 67415208Sthien (void) putlab((char *) loc ); 675769Speter # endif PC 676769Speter } 677769Speter 678769Speter #ifdef OBJ 679769Speter patch4(loc) 68015208Sthien PTR_DCL loc; 681769Speter { 6823077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 683769Speter } 684769Speter 685769Speter /* 6867921Smckusick * Patchfil makes loc+2 have jmploc 687769Speter * as its contents. 688769Speter */ 6897921Smckusick patchfil(loc, jmploc, words) 690769Speter PTR_DCL loc; 6917921Smckusick long jmploc; 6923077Smckusic int words; 693769Speter { 694769Speter register i; 69515208Sthien extern long lseek(); 69610562Smckusick short val; 697769Speter 6983317Speter if ( !CGENNING ) 699769Speter return; 700769Speter if (loc > (unsigned) lc) 701769Speter panic("patchfil"); 702769Speter #ifdef DEBUG 703769Speter if (opt('k')) 7047921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 705769Speter #endif 7067921Smckusick val = jmploc; 707769Speter do { 7083077Smckusic # ifndef DEC11 7093077Smckusic if (words > 1) 7107921Smckusick val = jmploc >> 16; 7113077Smckusic else 7127921Smckusick val = jmploc; 7133077Smckusic # endif DEC11 714769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 71510562Smckusick if (i >= 0 && i < 1024) { 7163077Smckusic obuf[i] = val; 71710562Smckusick } else { 71815208Sthien (void) lseek(ofil, (long) loc+2, 0); 71915208Sthien write(ofil, (char *) (&val), 2); 72015208Sthien (void) lseek(ofil, (long) 0, 2); 721769Speter } 722769Speter loc += 2; 7233077Smckusic # ifdef DEC11 7247921Smckusick val = jmploc >> 16; 7253077Smckusic # endif DEC11 726769Speter } while (--words); 727769Speter } 728769Speter 729769Speter /* 730769Speter * Put the word o into the code 731769Speter */ 732769Speter word(o) 733769Speter int o; 734769Speter { 735769Speter 736769Speter *obufp = o; 737769Speter obufp++; 738769Speter lc += 2; 739769Speter if (obufp >= obuf+512) 740769Speter pflush(); 741769Speter } 742769Speter 743769Speter extern char *obj; 744769Speter /* 745769Speter * Flush the code buffer 746769Speter */ 747769Speter pflush() 748769Speter { 749769Speter register i; 750769Speter 751769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 75215208Sthien if (i != 0 && write(ofil, (char *) obuf, i) != i) 753769Speter perror(obj), pexit(DIED); 754769Speter obufp = obuf; 755769Speter } 756769Speter #endif OBJ 757769Speter 758769Speter /* 759769Speter * Getlab - returns the location counter. 760769Speter * included here for the eventual code generator. 761769Speter * for PC, thank you! 762769Speter */ 76315208Sthien char * 764769Speter getlab() 765769Speter { 766769Speter # ifdef OBJ 767769Speter 768769Speter return (lc); 769769Speter # endif OBJ 770769Speter # ifdef PC 771769Speter static long lastlabel; 772769Speter 77315208Sthien return ( (char *) ++lastlabel ); 774769Speter # endif PC 775769Speter } 776769Speter 777769Speter /* 778769Speter * Putlab - lay down a label. 779769Speter * for PC, just print the label name with a colon after it. 780769Speter */ 78115208Sthien char * 782769Speter putlab(l) 78315208Sthien char *l; 784769Speter { 785769Speter 786769Speter # ifdef PC 78715208Sthien putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l ); 788769Speter putprintf( ":" , 0 ); 789769Speter # endif PC 790769Speter return (l); 791769Speter } 792