1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 623528Smckusick */ 7769Speter 815208Sthien #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)put.c 5.4 (Berkeley) 04/16/91"; 10*48116Sbostic #endif /* not lint */ 11769Speter 12769Speter #include "whoami.h" 13769Speter #include "opcode.h" 14769Speter #include "0.h" 15769Speter #include "objfmt.h" 16769Speter #ifdef PC 17769Speter # include "pc.h" 1810656Speter # include "align.h" 1915208Sthien #else 2015208Sthien short *obufp = obuf; 2115208Sthien #endif 22769Speter 23769Speter /* 24769Speter * If DEBUG is defined, include the table 25769Speter * of the printing opcode names. 26769Speter */ 27769Speter #ifdef DEBUG 28769Speter #include "OPnames.h" 29769Speter #endif 30769Speter 3136536Smckusick char showit[] = "'x'"; 3236536Smckusick 33769Speter #ifdef OBJ 34769Speter /* 35769Speter * Put is responsible for the interpreter equivalent of code 36769Speter * generation. Since the interpreter is specifically designed 37769Speter * for Pascal, little work is required here. 3836536Smckusick * 3936536Smckusick * FIXME, this should be converted to use <varargs.h> or <stdarg.h>. 40769Speter */ 4115208Sthien /*VARARGS*/ 42769Speter put(a) 43769Speter { 44769Speter register int *p, i; 45769Speter register char *cp; 463077Smckusic register short *sp; 473077Smckusic register long *lp; 4815208Sthien int n, subop, suboppr, op, oldlc; 49769Speter char *string; 50769Speter static int casewrd; 51769Speter 52769Speter /* 53769Speter * It would be nice to do some more 54769Speter * optimizations here. The work 55769Speter * done to collapse offsets in lval 56769Speter * should be done here, the IFEQ etc 57769Speter * relational operators could be used 58769Speter * etc. 59769Speter */ 6015208Sthien oldlc = (int) lc; /* its either this or change put to return a char * */ 613317Speter if ( !CGENNING ) 62769Speter /* 63769Speter * code disabled - do nothing 64769Speter */ 65769Speter return (oldlc); 66769Speter p = &a; 67769Speter n = *p++; 683077Smckusic suboppr = subop = (*p >> 8) & 0377; 69769Speter op = *p & 0377; 70769Speter string = 0; 71769Speter #ifdef DEBUG 72769Speter if ((cp = otext[op]) == NIL) { 73769Speter printf("op= %o\n", op); 74769Speter panic("put"); 75769Speter } 76769Speter #endif 77769Speter switch (op) { 78769Speter case O_ABORT: 79769Speter cp = "*"; 80769Speter break; 812221Smckusic case O_AS: 822221Smckusic switch(p[1]) { 836594Smckusick case 0: 846594Smckusick break; 852221Smckusic case 2: 862221Smckusic op = O_AS2; 876594Smckusick n = 1; 882221Smckusic break; 892221Smckusic case 4: 902221Smckusic op = O_AS4; 916594Smckusick n = 1; 922221Smckusic break; 932221Smckusic case 8: 942221Smckusic op = O_AS8; 956594Smckusick n = 1; 962221Smckusic break; 972221Smckusic default: 982221Smckusic goto pack; 992221Smckusic } 1003077Smckusic # ifdef DEBUG 1013077Smckusic cp = otext[op]; 1023077Smckusic # endif DEBUG 1032221Smckusic break; 10410791Smckusick case O_FOR1U: 10510791Smckusick case O_FOR2U: 10610791Smckusick case O_FOR4U: 10710791Smckusick case O_FOR1D: 10810791Smckusick case O_FOR2D: 10910791Smckusick case O_FOR4D: 11010791Smckusick /* relative addressing */ 11110791Smckusick p[1] -= ( unsigned ) lc + sizeof(short); 11210791Smckusick /* try to pack the jump */ 11310791Smckusick if (p[1] <= 127 && p[1] >= -128) { 11410791Smckusick suboppr = subop = p[1]; 11510791Smckusick p++; 11610791Smckusick n--; 11710791Smckusick } else { 11810791Smckusick /* have to allow for extra displacement */ 11910791Smckusick p[1] -= sizeof(short); 12010791Smckusick } 12110791Smckusick break; 1223077Smckusic case O_CONG: 1233077Smckusic case O_LVCON: 1243077Smckusic case O_CON: 125769Speter case O_LINO: 126769Speter case O_NEW: 127769Speter case O_DISPOSE: 1287965Smckusick case O_DFDISP: 129769Speter case O_IND: 130769Speter case O_OFF: 131769Speter case O_INX2: 132769Speter case O_INX4: 133769Speter case O_CARD: 134769Speter case O_ADDT: 135769Speter case O_SUBT: 136769Speter case O_MULT: 137769Speter case O_IN: 138769Speter case O_CASE1OP: 139769Speter case O_CASE2OP: 140769Speter case O_CASE4OP: 1411199Speter case O_FRTN: 142769Speter case O_WRITES: 1433173Smckusic case O_WRITEC: 144769Speter case O_WRITEF: 145769Speter case O_MAX: 146769Speter case O_MIN: 147769Speter case O_ARGV: 148769Speter case O_CTTOT: 149769Speter case O_INCT: 150769Speter case O_RANG2: 151769Speter case O_RSNG2: 152769Speter case O_RANG42: 153769Speter case O_RSNG42: 1542105Smckusic case O_SUCC2: 1552105Smckusic case O_SUCC24: 1562105Smckusic case O_PRED2: 1572105Smckusic case O_PRED24: 158769Speter if (p[1] == 0) 159769Speter break; 160769Speter case O_CON2: 161769Speter case O_CON24: 1622221Smckusic pack: 16310791Smckusick if (p[1] <= 127 && p[1] >= -128) { 164769Speter suboppr = subop = p[1]; 165769Speter p++; 166769Speter n--; 167769Speter if (op == O_CON2) { 168769Speter op = O_CON1; 1693077Smckusic # ifdef DEBUG 1703077Smckusic cp = otext[O_CON1]; 1713077Smckusic # endif DEBUG 172769Speter } 173769Speter if (op == O_CON24) { 174769Speter op = O_CON14; 1753077Smckusic # ifdef DEBUG 1763077Smckusic cp = otext[O_CON14]; 1773077Smckusic # endif DEBUG 178769Speter } 179769Speter } 180769Speter break; 181769Speter case O_CON8: 182769Speter { 18315208Sthien short *sp = (short *) (&p[1]); 184769Speter 185769Speter #ifdef DEBUG 186769Speter if ( opt( 'k' ) ) 1873317Speter printf ( "%5d\tCON8\t%22.14e\n" , 188769Speter lc - HEADER_BYTES , 189769Speter * ( ( double * ) &p[1] ) ); 190769Speter #endif 1913077Smckusic # ifdef DEC11 1923077Smckusic word(op); 1933077Smckusic # else 1943077Smckusic word(op << 8); 1953077Smckusic # endif DEC11 196769Speter for ( i = 1 ; i <= 4 ; i ++ ) 197769Speter word ( *sp ++ ); 198769Speter return ( oldlc ); 199769Speter } 200769Speter default: 201769Speter if (op >= O_REL2 && op <= O_REL84) { 2021883Smckusic if ((i = (subop >> INDX) * 5 ) >= 30) 203769Speter i -= 30; 204769Speter else 205769Speter i += 2; 206769Speter #ifdef DEBUG 207769Speter string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i]; 208769Speter #endif 209769Speter suboppr = 0; 210769Speter } 211769Speter break; 212769Speter case O_IF: 213769Speter case O_TRA: 214769Speter /***** 215769Speter codeline = 0; 216769Speter *****/ 2172184Smckusic /* relative addressing */ 2182184Smckusic p[1] -= ( unsigned ) lc + sizeof(short); 2192184Smckusic break; 220769Speter case O_CONC: 221769Speter #ifdef DEBUG 22236536Smckusick (string = showit)[1] = p[1]; 223769Speter #endif 224769Speter suboppr = 0; 225769Speter op = O_CON1; 2263077Smckusic # ifdef DEBUG 2273077Smckusic cp = otext[O_CON1]; 2283077Smckusic # endif DEBUG 229769Speter subop = p[1]; 230769Speter goto around; 231769Speter case O_CONC4: 232769Speter #ifdef DEBUG 23336536Smckusick (string = showit)[1] = p[1]; 234769Speter #endif 235769Speter suboppr = 0; 236769Speter op = O_CON14; 237769Speter subop = p[1]; 238769Speter goto around; 239769Speter case O_CON1: 240769Speter case O_CON14: 241769Speter suboppr = subop = p[1]; 242769Speter around: 243769Speter n--; 244769Speter break; 245769Speter case O_CASEBEG: 246769Speter casewrd = 0; 247769Speter return (oldlc); 248769Speter case O_CASEEND: 249769Speter if ((unsigned) lc & 1) { 250769Speter lc--; 251769Speter word(casewrd); 252769Speter } 253769Speter return (oldlc); 254769Speter case O_CASE1: 255769Speter #ifdef DEBUG 256769Speter if (opt('k')) 2573317Speter printf("%5d\tCASE1\t%d\n" 2583077Smckusic , lc - HEADER_BYTES, p[1]); 259769Speter #endif 260769Speter /* 261769Speter * this to build a byte size case table 262769Speter * saving bytes across calls in casewrd 263769Speter * so they can be put out by word() 264769Speter */ 265769Speter lc++; 266769Speter if ((unsigned) lc & 1) 2673077Smckusic # ifdef DEC11 2683077Smckusic casewrd = p[1] & 0377; 2693077Smckusic # else 2703077Smckusic casewrd = (p[1] & 0377) << 8; 2713077Smckusic # endif DEC11 272769Speter else { 273769Speter lc -= 2; 2743077Smckusic # ifdef DEC11 2753077Smckusic word(((p[1] & 0377) << 8) | casewrd); 2763077Smckusic # else 2773077Smckusic word((p[1] & 0377) | casewrd); 2783077Smckusic # endif DEC11 279769Speter } 280769Speter return (oldlc); 281769Speter case O_CASE2: 282769Speter #ifdef DEBUG 283769Speter if (opt('k')) 2843317Speter printf("%5d\tCASE2\t%d\n" 2853077Smckusic , lc - HEADER_BYTES , p[1]); 286769Speter #endif 2873077Smckusic word(p[1]); 288769Speter return (oldlc); 289769Speter case O_PUSH: 2903077Smckusic lp = (long *)&p[1]; 2913077Smckusic if (*lp == 0) 292769Speter return (oldlc); 2934025Smckusic /* and fall through */ 2944025Smckusic case O_RANG4: 2954025Smckusic case O_RANG24: 2964025Smckusic case O_RSNG4: 2974025Smckusic case O_RSNG24: 2984025Smckusic case O_SUCC4: 2994025Smckusic case O_PRED4: 3004025Smckusic /* sub opcode optimization */ 3014025Smckusic lp = (long *)&p[1]; 3024025Smckusic if (*lp < 128 && *lp >= -128 && *lp != 0) { 3033077Smckusic suboppr = subop = *lp; 3044025Smckusic p += (sizeof(long) / sizeof(int)); 305769Speter n--; 306769Speter } 307769Speter goto longgen; 308769Speter case O_TRA4: 309769Speter case O_CALL: 3101199Speter case O_FSAV: 311769Speter case O_GOTO: 312769Speter case O_NAM: 313769Speter case O_READE: 314769Speter /* absolute long addressing */ 3153077Smckusic lp = (long *)&p[1]; 3163077Smckusic *lp -= HEADER_BYTES; 317769Speter goto longgen; 318769Speter case O_RV1: 319769Speter case O_RV14: 320769Speter case O_RV2: 321769Speter case O_RV24: 322769Speter case O_RV4: 323769Speter case O_RV8: 324769Speter case O_RV: 325769Speter case O_LV: 3262105Smckusic /* 3272105Smckusic * positive offsets represent arguments 3282105Smckusic * and must use "ap" display entry rather 3292105Smckusic * than the "fp" entry 3302105Smckusic */ 3312105Smckusic if (p[1] >= 0) { 3322105Smckusic subop++; 3332105Smckusic suboppr++; 3342105Smckusic } 3353077Smckusic # ifdef PDP11 3363077Smckusic break; 3373077Smckusic # else 3383077Smckusic /* 3393077Smckusic * offsets out of range of word addressing 3403077Smckusic * must use long offset opcodes 3413077Smckusic */ 3423077Smckusic if (p[1] < SHORTADDR && p[1] >= -SHORTADDR) 3433077Smckusic break; 3443077Smckusic else { 345769Speter op += O_LRV - O_RV; 3463077Smckusic # ifdef DEBUG 3473077Smckusic cp = otext[op]; 3483077Smckusic # endif DEBUG 3493077Smckusic } 3503077Smckusic /* and fall through */ 3513077Smckusic # endif PDP11 352769Speter case O_BEG: 353769Speter case O_NODUMP: 354769Speter case O_CON4: 355769Speter case O_CASE4: 356769Speter longgen: 357769Speter n = (n << 1) - 1; 35810791Smckusick if ( op == O_LRV ) { 359769Speter n--; 36010562Smckusick # if defined(ADDR32) && !defined(DEC11) 36110562Smckusick p[n / 2] <<= 16; 36210562Smckusick # endif 36310562Smckusick } 364769Speter #ifdef DEBUG 3653077Smckusic if (opt('k')) { 3663317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 367769Speter if (suboppr) 3683077Smckusic printf(":%d", suboppr); 3693077Smckusic for ( i = 2, lp = (long *)&p[1]; i < n 370769Speter ; i += sizeof ( long )/sizeof ( short ) ) 371769Speter printf( "\t%D " , *lp ++ ); 3723377Speter if (i == n) { 3733377Speter sp = (short *)lp; 3743377Speter printf( "\t%d ", *sp ); 3753377Speter } 376769Speter pchr ( '\n' ); 3773077Smckusic } 378769Speter #endif 379769Speter if ( op != O_CASE4 ) 3803077Smckusic # ifdef DEC11 3813077Smckusic word((op & 0377) | subop << 8); 3823077Smckusic # else 3833077Smckusic word(op << 8 | (subop & 0377)); 3843077Smckusic # endif DEC11 3853077Smckusic for ( i = 1, sp = (short *)&p[1]; i < n; i++) 3863077Smckusic word ( *sp ++ ); 387769Speter return ( oldlc ); 388769Speter } 389769Speter #ifdef DEBUG 390769Speter if (opt('k')) { 3913317Speter printf("%5d\t%s", lc - HEADER_BYTES, cp+1); 392769Speter if (suboppr) 393769Speter printf(":%d", suboppr); 394769Speter if (string) 395769Speter printf("\t%s",string); 396769Speter if (n > 1) 397769Speter pchr('\t'); 398769Speter for (i=1; i<n; i++) 3993077Smckusic printf("%d ", p[i]); 400769Speter pchr('\n'); 401769Speter } 402769Speter #endif 403769Speter if (op != NIL) 4043077Smckusic # ifdef DEC11 4053077Smckusic word((op & 0377) | subop << 8); 4063077Smckusic # else 4073077Smckusic word(op << 8 | (subop & 0377)); 4083077Smckusic # endif DEC11 409769Speter for (i=1; i<n; i++) 410769Speter word(p[i]); 411769Speter return (oldlc); 412769Speter } 413769Speter #endif OBJ 414769Speter 415769Speter /* 416769Speter * listnames outputs a list of enumerated type names which 417769Speter * can then be selected from to output a TSCAL 418769Speter * a pointer to the address in the code of the namelist 419769Speter * is kept in value[ NL_ELABEL ]. 420769Speter */ 421769Speter listnames(ap) 422769Speter 423769Speter register struct nl *ap; 424769Speter { 425769Speter struct nl *next; 42615208Sthien #ifdef OBJ 42715208Sthien register int oldlc; 42815208Sthien #endif 42915208Sthien register int len; 430769Speter register unsigned w; 431769Speter register char *strptr; 432769Speter 4333317Speter if ( !CGENNING ) 434769Speter /* code is off - do nothing */ 435769Speter return(NIL); 436769Speter if (ap->class != TYPE) 437769Speter ap = ap->type; 438769Speter if (ap->value[ NL_ELABEL ] != 0) { 439769Speter /* the list already exists */ 440769Speter return( ap -> value[ NL_ELABEL ] ); 441769Speter } 442769Speter # ifdef OBJ 44315208Sthien oldlc = (int) lc; /* same problem as put */ 44415208Sthien (void) put(2, O_TRA, lc); 44515208Sthien ap->value[ NL_ELABEL ] = (int) lc; 446769Speter # endif OBJ 447769Speter # ifdef PC 44810656Speter putprintf(" .data", 0); 44910656Speter aligndot(A_STRUCT); 45015208Sthien ap -> value[ NL_ELABEL ] = (int) getlab(); 45115208Sthien (void) putlab((char *) ap -> value[ NL_ELABEL ] ); 452769Speter # endif PC 453769Speter /* number of scalars */ 454769Speter next = ap->type; 455769Speter len = next->range[1]-next->range[0]+1; 456769Speter # ifdef OBJ 45715208Sthien (void) put(2, O_CASE2, len); 458769Speter # endif OBJ 459769Speter # ifdef PC 460769Speter putprintf( " .word %d" , 0 , len ); 461769Speter # endif PC 462769Speter /* offsets of each scalar name */ 463769Speter len = (len+1)*sizeof(short); 464769Speter # ifdef OBJ 46515208Sthien (void) put(2, O_CASE2, len); 466769Speter # endif OBJ 467769Speter # ifdef PC 468769Speter putprintf( " .word %d" , 0 , len ); 469769Speter # endif PC 470769Speter next = ap->chain; 471769Speter do { 472769Speter for(strptr = next->symbol; *strptr++; len++) 473769Speter continue; 474769Speter len++; 475769Speter # ifdef OBJ 47615208Sthien (void) put(2, O_CASE2, len); 477769Speter # endif OBJ 478769Speter # ifdef PC 479769Speter putprintf( " .word %d" , 0 , len ); 480769Speter # endif PC 481769Speter } while (next = next->chain); 482769Speter /* list of scalar names */ 483769Speter strptr = getnext(ap, &next); 484769Speter # ifdef OBJ 485769Speter do { 4863077Smckusic # ifdef DEC11 4873077Smckusic w = (unsigned) *strptr; 4883077Smckusic # else 4893077Smckusic w = *strptr << 8; 4903077Smckusic # endif DEC11 491769Speter if (!*strptr++) 492769Speter strptr = getnext(next, &next); 4933077Smckusic # ifdef DEC11 4943077Smckusic w |= *strptr << 8; 4953077Smckusic # else 4963077Smckusic w |= (unsigned) *strptr; 4973077Smckusic # endif DEC11 498769Speter if (!*strptr++) 499769Speter strptr = getnext(next, &next); 50015208Sthien word((int) w); 501769Speter } while (next); 502769Speter /* jump over the mess */ 50315208Sthien patch((PTR_DCL) oldlc); 504769Speter # endif OBJ 505769Speter # ifdef PC 506769Speter while ( next ) { 507769Speter while ( *strptr ) { 508769Speter putprintf( " .byte 0%o" , 1 , *strptr++ ); 509769Speter for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) { 510769Speter putprintf( ",0%o" , 1 , *strptr++ ); 511769Speter } 512769Speter putprintf( "" , 0 ); 513769Speter } 514769Speter putprintf( " .byte 0" , 0 ); 515769Speter strptr = getnext( next , &next ); 516769Speter } 517769Speter putprintf( " .text" , 0 ); 518769Speter # endif PC 519769Speter return( ap -> value[ NL_ELABEL ] ); 520769Speter } 521769Speter 52215208Sthien char * 523769Speter getnext(next, new) 524769Speter 525769Speter struct nl *next, **new; 526769Speter { 527769Speter if (next != NIL) { 528769Speter next = next->chain; 529769Speter *new = next; 530769Speter } 53115208Sthien if (next == NLNIL) 532769Speter return(""); 533769Speter #ifdef OBJ 5343317Speter if (opt('k') && CGENNING ) 5353317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol); 5362213Speter #endif OBJ 537769Speter return(next->symbol); 538769Speter } 539769Speter 540769Speter #ifdef OBJ 541769Speter /* 542769Speter * Putspace puts out a table 543769Speter * of nothing to leave space 544769Speter * for the case branch table e.g. 545769Speter */ 546769Speter putspace(n) 547769Speter int n; 548769Speter { 549769Speter register i; 550769Speter 5513317Speter if ( !CGENNING ) 552769Speter /* 553769Speter * code disabled - do nothing 554769Speter */ 55515208Sthien return; 556769Speter #ifdef DEBUG 557769Speter if (opt('k')) 5583317Speter printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n); 559769Speter #endif 56030036Smckusick for (i = n; i > 0; i -= 2) 561769Speter word(0); 562769Speter } 563769Speter 564769Speter putstr(sptr, padding) 565769Speter 566769Speter char *sptr; 567769Speter int padding; 568769Speter { 569769Speter register unsigned short w; 570769Speter register char *strptr = sptr; 571769Speter register int pad = padding; 572769Speter 5733317Speter if ( !CGENNING ) 574769Speter /* 575769Speter * code disabled - do nothing 576769Speter */ 57715208Sthien return; 578769Speter #ifdef DEBUG 579769Speter if (opt('k')) 5803317Speter printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr); 581769Speter #endif 582769Speter if (pad == 0) { 583769Speter do { 5843077Smckusic # ifdef DEC11 5853077Smckusic w = (unsigned short) * strptr; 5863077Smckusic # else 5873077Smckusic w = (unsigned short)*strptr<<8; 5883077Smckusic # endif DEC11 589769Speter if (w) 5903077Smckusic # ifdef DEC11 5913077Smckusic w |= *++strptr << 8; 5923077Smckusic # else 5933077Smckusic w |= *++strptr; 5943077Smckusic # endif DEC11 59515208Sthien word((int) w); 596769Speter } while (*strptr++); 597769Speter } else { 5983077Smckusic # ifdef DEC11 5993077Smckusic do { 6003077Smckusic w = (unsigned short) * strptr; 6013077Smckusic if (w) { 6023077Smckusic if (*++strptr) 6033077Smckusic w |= *strptr << 8; 6043077Smckusic else { 60511885Smckusick w |= ' ' << 8; 6063077Smckusic pad--; 6073077Smckusic } 60815208Sthien word((int) w); 6093077Smckusic } 6103077Smckusic } while (*strptr++); 6113077Smckusic # else 6123077Smckusic do { 6133077Smckusic w = (unsigned short)*strptr<<8; 6143077Smckusic if (w) { 6153077Smckusic if (*++strptr) 6163077Smckusic w |= *strptr; 6173077Smckusic else { 6183077Smckusic w |= ' '; 6193077Smckusic pad--; 6203077Smckusic } 6213077Smckusic word(w); 6223077Smckusic } 6233077Smckusic } while (*strptr++); 6243077Smckusic # endif DEC11 625769Speter while (pad > 1) { 62611885Smckusick # ifdef DEC11 62711885Smckusick word(' ' | (' ' << 8)); 62811885Smckusick # else 62911885Smckusick word((' ' << 8) | ' '); 63011885Smckusick # endif DEC11 631769Speter pad -= 2; 632769Speter } 633769Speter if (pad == 1) 6343077Smckusic # ifdef DEC11 6353077Smckusic word(' '); 6363077Smckusic # else 63711885Smckusick word(' ' << 8); 6383077Smckusic # endif DEC11 639769Speter else 640769Speter word(0); 641769Speter } 642769Speter } 643769Speter #endif OBJ 644769Speter 64515208Sthien #ifndef PC 646769Speter lenstr(sptr, padding) 647769Speter 648769Speter char *sptr; 649769Speter int padding; 650769Speter 651769Speter { 652769Speter register int cnt; 653769Speter register char *strptr = sptr; 654769Speter 655769Speter cnt = padding; 656769Speter do { 657769Speter cnt++; 658769Speter } while (*strptr++); 659769Speter return((++cnt) & ~1); 660769Speter } 66115208Sthien #endif 662769Speter 663769Speter /* 664769Speter * Patch repairs the branch 665769Speter * at location loc to come 666769Speter * to the current location. 667769Speter * for PC, this puts down the label 668769Speter * and the branch just references that label. 669769Speter * lets here it for two pass assemblers. 670769Speter */ 671769Speter patch(loc) 67215208Sthien PTR_DCL loc; 673769Speter { 674769Speter 675769Speter # ifdef OBJ 6763077Smckusic patchfil(loc, (long)(lc-loc-2), 1); 677769Speter # endif OBJ 678769Speter # ifdef PC 67915208Sthien (void) putlab((char *) loc ); 680769Speter # endif PC 681769Speter } 682769Speter 683769Speter #ifdef OBJ 684769Speter patch4(loc) 68515208Sthien PTR_DCL loc; 686769Speter { 6873077Smckusic patchfil(loc, (long)(lc - HEADER_BYTES), 2); 688769Speter } 689769Speter 690769Speter /* 6917921Smckusick * Patchfil makes loc+2 have jmploc 692769Speter * as its contents. 693769Speter */ 6947921Smckusick patchfil(loc, jmploc, words) 695769Speter PTR_DCL loc; 6967921Smckusick long jmploc; 6973077Smckusic int words; 698769Speter { 699769Speter register i; 70015208Sthien extern long lseek(); 70110562Smckusick short val; 702769Speter 7033317Speter if ( !CGENNING ) 704769Speter return; 705769Speter if (loc > (unsigned) lc) 706769Speter panic("patchfil"); 707769Speter #ifdef DEBUG 708769Speter if (opt('k')) 7097921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc); 710769Speter #endif 7117921Smckusick val = jmploc; 712769Speter do { 7133077Smckusic # ifndef DEC11 7143077Smckusic if (words > 1) 7157921Smckusick val = jmploc >> 16; 7163077Smckusic else 7177921Smckusick val = jmploc; 7183077Smckusic # endif DEC11 719769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2; 72010562Smckusick if (i >= 0 && i < 1024) { 7213077Smckusic obuf[i] = val; 72210562Smckusick } else { 72315208Sthien (void) lseek(ofil, (long) loc+2, 0); 72415208Sthien write(ofil, (char *) (&val), 2); 72515208Sthien (void) lseek(ofil, (long) 0, 2); 726769Speter } 727769Speter loc += 2; 7283077Smckusic # ifdef DEC11 7297921Smckusick val = jmploc >> 16; 7303077Smckusic # endif DEC11 731769Speter } while (--words); 732769Speter } 733769Speter 734769Speter /* 735769Speter * Put the word o into the code 736769Speter */ 737769Speter word(o) 738769Speter int o; 739769Speter { 740769Speter 741769Speter *obufp = o; 742769Speter obufp++; 743769Speter lc += 2; 744769Speter if (obufp >= obuf+512) 745769Speter pflush(); 746769Speter } 747769Speter 748769Speter extern char *obj; 749769Speter /* 750769Speter * Flush the code buffer 751769Speter */ 752769Speter pflush() 753769Speter { 754769Speter register i; 755769Speter 756769Speter i = (obufp - ( ( short * ) obuf ) ) * 2; 75715208Sthien if (i != 0 && write(ofil, (char *) obuf, i) != i) 758769Speter perror(obj), pexit(DIED); 759769Speter obufp = obuf; 760769Speter } 761769Speter #endif OBJ 762769Speter 763769Speter /* 764769Speter * Getlab - returns the location counter. 765769Speter * included here for the eventual code generator. 766769Speter * for PC, thank you! 767769Speter */ 76815208Sthien char * 769769Speter getlab() 770769Speter { 771769Speter # ifdef OBJ 772769Speter 773769Speter return (lc); 774769Speter # endif OBJ 775769Speter # ifdef PC 776769Speter static long lastlabel; 777769Speter 77815208Sthien return ( (char *) ++lastlabel ); 779769Speter # endif PC 780769Speter } 781769Speter 782769Speter /* 783769Speter * Putlab - lay down a label. 784769Speter * for PC, just print the label name with a colon after it. 785769Speter */ 78615208Sthien char * 787769Speter putlab(l) 78815208Sthien char *l; 789769Speter { 790769Speter 791769Speter # ifdef PC 79215208Sthien putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l ); 793769Speter putprintf( ":" , 0 ); 794769Speter # endif PC 795769Speter return (l); 796769Speter } 797