148116Sbostic /*-
262215Sbostic * Copyright (c) 1980, 1993
362215Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
623528Smckusick */
7769Speter
815208Sthien #ifndef lint
9*67239Smckusick static char sccsid[] = "@(#)put.c 8.2 (Berkeley) 05/24/94";
1048116Sbostic #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*/
put(a)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 */
listnames(ap)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 *
getnext(next,new)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 */
putspace(n)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
putstr(sptr,padding)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
lenstr(sptr,padding)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 */
patch(loc)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
patch4(loc)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 */
patchfil(loc,jmploc,words)6947921Smckusick patchfil(loc, jmploc, words)
695769Speter PTR_DCL loc;
6967921Smckusick long jmploc;
6973077Smckusic int words;
698769Speter {
699769Speter register i;
70010562Smckusick short val;
701769Speter
7023317Speter if ( !CGENNING )
703769Speter return;
704769Speter if (loc > (unsigned) lc)
705769Speter panic("patchfil");
706769Speter #ifdef DEBUG
707769Speter if (opt('k'))
7087921Smckusick printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc);
709769Speter #endif
7107921Smckusick val = jmploc;
711769Speter do {
7123077Smckusic # ifndef DEC11
7133077Smckusic if (words > 1)
7147921Smckusick val = jmploc >> 16;
7153077Smckusic else
7167921Smckusick val = jmploc;
7173077Smckusic # endif DEC11
718769Speter i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
71910562Smckusick if (i >= 0 && i < 1024) {
7203077Smckusic obuf[i] = val;
72110562Smckusick } else {
722*67239Smckusick if (lseek(ofil, (off_t) loc+2, 0) == -1)
723*67239Smckusick perror("patchfil: lseek1"), panic("patchfil");
724*67239Smckusick if (write(ofil, (char *) (&val), 2) != 2)
725*67239Smckusick perror("patchfil: write"), panic("patchfil");
726*67239Smckusick if (lseek(ofil, (off_t) 0, 2) == -1)
727*67239Smckusick perror("patchfil: lseek2"), panic("patchfil");
728769Speter }
729769Speter loc += 2;
7303077Smckusic # ifdef DEC11
7317921Smckusick val = jmploc >> 16;
7323077Smckusic # endif DEC11
733769Speter } while (--words);
734769Speter }
735769Speter
736769Speter /*
737769Speter * Put the word o into the code
738769Speter */
word(o)739769Speter word(o)
740769Speter int o;
741769Speter {
742769Speter
743769Speter *obufp = o;
744769Speter obufp++;
745769Speter lc += 2;
746769Speter if (obufp >= obuf+512)
747769Speter pflush();
748769Speter }
749769Speter
750769Speter extern char *obj;
751769Speter /*
752769Speter * Flush the code buffer
753769Speter */
pflush()754769Speter pflush()
755769Speter {
756769Speter register i;
757769Speter
758769Speter i = (obufp - ( ( short * ) obuf ) ) * 2;
75915208Sthien if (i != 0 && write(ofil, (char *) obuf, i) != i)
760769Speter perror(obj), pexit(DIED);
761769Speter obufp = obuf;
762769Speter }
763769Speter #endif OBJ
764769Speter
765769Speter /*
766769Speter * Getlab - returns the location counter.
767769Speter * included here for the eventual code generator.
768769Speter * for PC, thank you!
769769Speter */
77015208Sthien char *
getlab()771769Speter getlab()
772769Speter {
773769Speter # ifdef OBJ
774769Speter
775769Speter return (lc);
776769Speter # endif OBJ
777769Speter # ifdef PC
778769Speter static long lastlabel;
779769Speter
78015208Sthien return ( (char *) ++lastlabel );
781769Speter # endif PC
782769Speter }
783769Speter
784769Speter /*
785769Speter * Putlab - lay down a label.
786769Speter * for PC, just print the label name with a colon after it.
787769Speter */
78815208Sthien char *
putlab(l)789769Speter putlab(l)
79015208Sthien char *l;
791769Speter {
792769Speter
793769Speter # ifdef PC
79415208Sthien putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l );
795769Speter putprintf( ":" , 0 );
796769Speter # endif PC
797769Speter return (l);
798769Speter }
799