xref: /csrg-svn/usr.bin/pascal/src/put.c (revision 10656)
1769Speter /* Copyright (c) 1979 Regents of the University of California */
2769Speter 
3*10656Speter static char sccsid[] = "@(#)put.c 1.21 02/01/83";
4769Speter 
5769Speter #include "whoami.h"
6769Speter #include "opcode.h"
7769Speter #include "0.h"
8769Speter #include "objfmt.h"
9769Speter #ifdef PC
10769Speter #   include	"pc.h"
11*10656Speter #   include	"align.h"
12769Speter #endif PC
13769Speter 
14769Speter short	*obufp	= obuf;
15769Speter 
16769Speter /*
17769Speter  * If DEBUG is defined, include the table
18769Speter  * of the printing opcode names.
19769Speter  */
20769Speter #ifdef DEBUG
21769Speter #include "OPnames.h"
22769Speter #endif
23769Speter 
24769Speter #ifdef OBJ
25769Speter /*
26769Speter  * Put is responsible for the interpreter equivalent of code
27769Speter  * generation.  Since the interpreter is specifically designed
28769Speter  * for Pascal, little work is required here.
29769Speter  */
30769Speter put(a)
31769Speter {
32769Speter 	register int *p, i;
33769Speter 	register char *cp;
343077Smckusic 	register short *sp;
353077Smckusic 	register long *lp;
36769Speter 	int n, subop, suboppr, op, oldlc, w;
37769Speter 	char *string;
38769Speter 	static int casewrd;
39769Speter 
40769Speter 	/*
41769Speter 	 * It would be nice to do some more
42769Speter 	 * optimizations here.  The work
43769Speter 	 * done to collapse offsets in lval
44769Speter 	 * should be done here, the IFEQ etc
45769Speter 	 * relational operators could be used
46769Speter 	 * etc.
47769Speter 	 */
48769Speter 	oldlc = lc;
493317Speter 	if ( !CGENNING )
50769Speter 		/*
51769Speter 		 * code disabled - do nothing
52769Speter 		 */
53769Speter 		return (oldlc);
54769Speter 	p = &a;
55769Speter 	n = *p++;
563077Smckusic 	suboppr = subop = (*p >> 8) & 0377;
57769Speter 	op = *p & 0377;
58769Speter 	string = 0;
59769Speter #ifdef DEBUG
60769Speter 	if ((cp = otext[op]) == NIL) {
61769Speter 		printf("op= %o\n", op);
62769Speter 		panic("put");
63769Speter 	}
64769Speter #endif
65769Speter 	switch (op) {
66769Speter 		case O_ABORT:
67769Speter 			cp = "*";
68769Speter 			break;
692221Smckusic 		case O_AS:
702221Smckusic 			switch(p[1]) {
716594Smckusick 			case 0:
726594Smckusick 				break;
732221Smckusic 			case 2:
742221Smckusic 				op = O_AS2;
756594Smckusick 				n = 1;
762221Smckusic 				break;
772221Smckusic 			case 4:
782221Smckusic 				op = O_AS4;
796594Smckusick 				n = 1;
802221Smckusic 				break;
812221Smckusic 			case 8:
822221Smckusic 				op = O_AS8;
836594Smckusick 				n = 1;
842221Smckusic 				break;
852221Smckusic 			default:
862221Smckusic 				goto pack;
872221Smckusic 			}
883077Smckusic #			ifdef DEBUG
893077Smckusic 				cp = otext[op];
903077Smckusic #			endif DEBUG
912221Smckusic 			break;
923077Smckusic 		case O_CONG:
933077Smckusic 		case O_LVCON:
943077Smckusic 		case O_CON:
95769Speter 		case O_LINO:
96769Speter 		case O_NEW:
97769Speter 		case O_DISPOSE:
987965Smckusick 		case O_DFDISP:
99769Speter 		case O_IND:
100769Speter 		case O_OFF:
101769Speter 		case O_INX2:
102769Speter 		case O_INX4:
103769Speter 		case O_CARD:
104769Speter 		case O_ADDT:
105769Speter 		case O_SUBT:
106769Speter 		case O_MULT:
107769Speter 		case O_IN:
108769Speter 		case O_CASE1OP:
109769Speter 		case O_CASE2OP:
110769Speter 		case O_CASE4OP:
1111199Speter 		case O_FRTN:
112769Speter 		case O_WRITES:
1133173Smckusic 		case O_WRITEC:
114769Speter 		case O_WRITEF:
115769Speter 		case O_MAX:
116769Speter 		case O_MIN:
117769Speter 		case O_ARGV:
118769Speter 		case O_CTTOT:
119769Speter 		case O_INCT:
120769Speter 		case O_RANG2:
121769Speter 		case O_RSNG2:
122769Speter 		case O_RANG42:
123769Speter 		case O_RSNG42:
1242105Smckusic 		case O_SUCC2:
1252105Smckusic 		case O_SUCC24:
1262105Smckusic 		case O_PRED2:
1272105Smckusic 		case O_PRED24:
128769Speter 			if (p[1] == 0)
129769Speter 				break;
130769Speter 		case O_CON2:
131769Speter 		case O_CON24:
1322221Smckusic 		pack:
133769Speter 			if (p[1] < 128 && p[1] >= -128) {
134769Speter 				suboppr = subop = p[1];
135769Speter 				p++;
136769Speter 				n--;
137769Speter 				if (op == O_CON2) {
138769Speter 					op = O_CON1;
1393077Smckusic #					ifdef DEBUG
1403077Smckusic 						cp = otext[O_CON1];
1413077Smckusic #					endif DEBUG
142769Speter 				}
143769Speter 				if (op == O_CON24) {
144769Speter 					op = O_CON14;
1453077Smckusic #					ifdef DEBUG
1463077Smckusic 						cp = otext[O_CON14];
1473077Smckusic #					endif DEBUG
148769Speter 				}
149769Speter 			}
150769Speter 			break;
151769Speter 		case O_CON8:
152769Speter 		    {
153769Speter 			short	*sp = &p[1];
154769Speter 
155769Speter #ifdef	DEBUG
156769Speter 			if ( opt( 'k' ) )
1573317Speter 			    printf ( "%5d\tCON8\t%22.14e\n" ,
158769Speter 					lc - HEADER_BYTES ,
159769Speter 					* ( ( double * ) &p[1] ) );
160769Speter #endif
1613077Smckusic #			ifdef DEC11
1623077Smckusic 			    word(op);
1633077Smckusic #			else
1643077Smckusic 			    word(op << 8);
1653077Smckusic #			endif DEC11
166769Speter 			for ( i = 1 ; i <= 4 ; i ++ )
167769Speter 			    word ( *sp ++ );
168769Speter 			return ( oldlc );
169769Speter 		    }
170769Speter 		default:
171769Speter 			if (op >= O_REL2 && op <= O_REL84) {
1721883Smckusic 				if ((i = (subop >> INDX) * 5 ) >= 30)
173769Speter 					i -= 30;
174769Speter 				else
175769Speter 					i += 2;
176769Speter #ifdef DEBUG
177769Speter 				string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
178769Speter #endif
179769Speter 				suboppr = 0;
180769Speter 			}
181769Speter 			break;
182769Speter 		case O_IF:
183769Speter 		case O_TRA:
184769Speter /*****
185769Speter 			codeline = 0;
186769Speter *****/
1872184Smckusic 			/* relative addressing */
1882184Smckusic 			p[1] -= ( unsigned ) lc + sizeof(short);
1892184Smckusic 			break;
190769Speter 		case O_FOR1U:
191769Speter 		case O_FOR2U:
192769Speter 		case O_FOR1D:
193769Speter 		case O_FOR2D:
1944025Smckusic 			/* sub opcode optimization */
1954025Smckusic 			if (p[1] < 128 && p[1] >= -128 && p[1] != 0) {
1964025Smckusic 				suboppr = subop = p[1];
1974025Smckusic 				p++;
1984025Smckusic 				n--;
1994025Smckusic 			}
200769Speter 			/* relative addressing */
2014025Smckusic 			p[n - 1] -= ( unsigned ) lc + (n - 1) * sizeof(short);
202769Speter 			break;
203769Speter 		case O_CONC:
204769Speter #ifdef DEBUG
205769Speter 			(string = "'x'")[1] = p[1];
206769Speter #endif
207769Speter 			suboppr = 0;
208769Speter 			op = O_CON1;
2093077Smckusic #			ifdef DEBUG
2103077Smckusic 				cp = otext[O_CON1];
2113077Smckusic #			endif DEBUG
212769Speter 			subop = p[1];
213769Speter 			goto around;
214769Speter 		case O_CONC4:
215769Speter #ifdef DEBUG
216769Speter 			(string = "'x'")[1] = p[1];
217769Speter #endif
218769Speter 			suboppr = 0;
219769Speter 			op = O_CON14;
220769Speter 			subop = p[1];
221769Speter 			goto around;
222769Speter 		case O_CON1:
223769Speter 		case O_CON14:
224769Speter 			suboppr = subop = p[1];
225769Speter around:
226769Speter 			n--;
227769Speter 			break;
228769Speter 		case O_CASEBEG:
229769Speter 			casewrd = 0;
230769Speter 			return (oldlc);
231769Speter 		case O_CASEEND:
232769Speter 			if ((unsigned) lc & 1) {
233769Speter 				lc--;
234769Speter 				word(casewrd);
235769Speter 			}
236769Speter 			return (oldlc);
237769Speter 		case O_CASE1:
238769Speter #ifdef DEBUG
239769Speter 			if (opt('k'))
2403317Speter 				printf("%5d\tCASE1\t%d\n"
2413077Smckusic 					, lc - HEADER_BYTES, p[1]);
242769Speter #endif
243769Speter 			/*
244769Speter 			 * this to build a byte size case table
245769Speter 			 * saving bytes across calls in casewrd
246769Speter 			 * so they can be put out by word()
247769Speter 			 */
248769Speter 			lc++;
249769Speter 			if ((unsigned) lc & 1)
2503077Smckusic #				ifdef DEC11
2513077Smckusic 				    casewrd = p[1] & 0377;
2523077Smckusic #				else
2533077Smckusic 				    casewrd = (p[1] & 0377) << 8;
2543077Smckusic #				endif DEC11
255769Speter 			else {
256769Speter 				lc -= 2;
2573077Smckusic #				ifdef DEC11
2583077Smckusic 				    word(((p[1] & 0377) << 8) | casewrd);
2593077Smckusic #				else
2603077Smckusic 				    word((p[1] & 0377) | casewrd);
2613077Smckusic #				endif DEC11
262769Speter 			}
263769Speter 			return (oldlc);
264769Speter 		case O_CASE2:
265769Speter #ifdef DEBUG
266769Speter 			if (opt('k'))
2673317Speter 				printf("%5d\tCASE2\t%d\n"
2683077Smckusic 					, lc - HEADER_BYTES , p[1]);
269769Speter #endif
2703077Smckusic 			word(p[1]);
271769Speter 			return (oldlc);
2724025Smckusic 		case O_FOR4U:
2734025Smckusic 		case O_FOR4D:
2744025Smckusic 			/* sub opcode optimization */
2754025Smckusic 			lp = (long *)&p[1];
2764025Smckusic 			if (*lp < 128 && *lp >= -128 && *lp != 0) {
2774025Smckusic 				suboppr = subop = *lp;
2784025Smckusic 				p += (sizeof(long) / sizeof(int));
2794025Smckusic 				n--;
2804025Smckusic 			}
2814025Smckusic 			/* relative addressing */
2824025Smckusic 			p[1 + (n - 2) * (sizeof(long) / sizeof(int))] -=
2834025Smckusic 			    (unsigned)lc + (sizeof(short) +
2844025Smckusic 			    (n - 2) * sizeof(long));
2854025Smckusic 			goto longgen;
286769Speter 		case O_PUSH:
2873077Smckusic 			lp = (long *)&p[1];
2883077Smckusic 			if (*lp == 0)
289769Speter 				return (oldlc);
2904025Smckusic 			/* and fall through */
2914025Smckusic 		case O_RANG4:
2924025Smckusic 		case O_RANG24:
2934025Smckusic 		case O_RSNG4:
2944025Smckusic 		case O_RSNG24:
2954025Smckusic 		case O_SUCC4:
2964025Smckusic 		case O_PRED4:
2974025Smckusic 			/* sub opcode optimization */
2984025Smckusic 			lp = (long *)&p[1];
2994025Smckusic 			if (*lp < 128 && *lp >= -128 && *lp != 0) {
3003077Smckusic 				suboppr = subop = *lp;
3014025Smckusic 				p += (sizeof(long) / sizeof(int));
302769Speter 				n--;
303769Speter 			}
304769Speter 			goto longgen;
305769Speter 		case O_TRA4:
306769Speter 		case O_CALL:
3071199Speter 		case O_FSAV:
308769Speter 		case O_GOTO:
309769Speter 		case O_NAM:
310769Speter 		case O_READE:
311769Speter 			/* absolute long addressing */
3123077Smckusic 			lp = (long *)&p[1];
3133077Smckusic 			*lp -= HEADER_BYTES;
314769Speter 			goto longgen;
315769Speter 		case O_RV1:
316769Speter 		case O_RV14:
317769Speter 		case O_RV2:
318769Speter 		case O_RV24:
319769Speter 		case O_RV4:
320769Speter 		case O_RV8:
321769Speter 		case O_RV:
322769Speter 		case O_LV:
3232105Smckusic 			/*
3242105Smckusic 			 * positive offsets represent arguments
3252105Smckusic 			 * and must use "ap" display entry rather
3262105Smckusic 			 * than the "fp" entry
3272105Smckusic 			 */
3282105Smckusic 			if (p[1] >= 0) {
3292105Smckusic 				subop++;
3302105Smckusic 				suboppr++;
3312105Smckusic 			}
3323077Smckusic #			ifdef PDP11
3333077Smckusic 			    break;
3343077Smckusic #			else
3353077Smckusic 			    /*
3363077Smckusic 			     * offsets out of range of word addressing
3373077Smckusic 			     * must use long offset opcodes
3383077Smckusic 			     */
3393077Smckusic 			    if (p[1] < SHORTADDR && p[1] >= -SHORTADDR)
3403077Smckusic 				    break;
3413077Smckusic 			    else {
342769Speter 				op += O_LRV - O_RV;
3433077Smckusic #				ifdef DEBUG
3443077Smckusic 				    cp = otext[op];
3453077Smckusic #				endif DEBUG
3463077Smckusic 			    }
3473077Smckusic 			    /* and fall through */
3483077Smckusic #			endif PDP11
349769Speter 		case O_BEG:
350769Speter 		case O_NODUMP:
351769Speter 		case O_CON4:
352769Speter 		case O_CASE4:
353769Speter 		longgen:
354769Speter 			n = (n << 1) - 1;
35510562Smckusick 			if ( op == O_LRV || op == O_FOR4U || op == O_FOR4D) {
356769Speter 				n--;
35710562Smckusick #				if defined(ADDR32) && !defined(DEC11)
35810562Smckusick 				    p[n / 2] <<= 16;
35910562Smckusick #				endif
36010562Smckusick 			}
361769Speter #ifdef DEBUG
3623077Smckusic 			if (opt('k')) {
3633317Speter 				printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
364769Speter 				if (suboppr)
3653077Smckusic 					printf(":%d", suboppr);
3663077Smckusic 				for ( i = 2, lp = (long *)&p[1]; i < n
367769Speter 				    ; i += sizeof ( long )/sizeof ( short ) )
368769Speter 					printf( "\t%D " , *lp ++ );
3693377Speter 				if (i == n) {
3703377Speter 					sp = (short *)lp;
3713377Speter 					printf( "\t%d ", *sp );
3723377Speter 				}
373769Speter 				pchr ( '\n' );
3743077Smckusic 			}
375769Speter #endif
376769Speter 			if ( op != O_CASE4 )
3773077Smckusic #				ifdef DEC11
3783077Smckusic 			    	    word((op & 0377) | subop << 8);
3793077Smckusic #				else
3803077Smckusic 				    word(op << 8 | (subop & 0377));
3813077Smckusic #				endif DEC11
3823077Smckusic 			for ( i = 1, sp = (short *)&p[1]; i < n; i++)
3833077Smckusic 				word ( *sp ++ );
384769Speter 			return ( oldlc );
385769Speter 	}
386769Speter #ifdef DEBUG
387769Speter 	if (opt('k')) {
3883317Speter 		printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
389769Speter 		if (suboppr)
390769Speter 			printf(":%d", suboppr);
391769Speter 		if (string)
392769Speter 			printf("\t%s",string);
393769Speter 		if (n > 1)
394769Speter 			pchr('\t');
395769Speter 		for (i=1; i<n; i++)
3963077Smckusic 			printf("%d ", p[i]);
397769Speter 		pchr('\n');
398769Speter 	}
399769Speter #endif
400769Speter 	if (op != NIL)
4013077Smckusic #		ifdef DEC11
4023077Smckusic 		    word((op & 0377) | subop << 8);
4033077Smckusic #		else
4043077Smckusic 		    word(op << 8 | (subop & 0377));
4053077Smckusic #		endif DEC11
406769Speter 	for (i=1; i<n; i++)
407769Speter 		word(p[i]);
408769Speter 	return (oldlc);
409769Speter }
410769Speter #endif OBJ
411769Speter 
412769Speter /*
413769Speter  * listnames outputs a list of enumerated type names which
414769Speter  * can then be selected from to output a TSCAL
415769Speter  * a pointer to the address in the code of the namelist
416769Speter  * is kept in value[ NL_ELABEL ].
417769Speter  */
418769Speter listnames(ap)
419769Speter 
420769Speter 	register struct nl *ap;
421769Speter {
422769Speter 	struct nl *next;
423769Speter 	register int oldlc, len;
424769Speter 	register unsigned w;
425769Speter 	register char *strptr;
426769Speter 
4273317Speter 	if ( !CGENNING )
428769Speter 		/* code is off - do nothing */
429769Speter 		return(NIL);
430769Speter 	if (ap->class != TYPE)
431769Speter 		ap = ap->type;
432769Speter 	if (ap->value[ NL_ELABEL ] != 0) {
433769Speter 		/* the list already exists */
434769Speter 		return( ap -> value[ NL_ELABEL ] );
435769Speter 	}
436769Speter #	ifdef OBJ
437769Speter 	    oldlc = lc;
438769Speter 	    put(2, O_TRA, lc);
439769Speter 	    ap->value[ NL_ELABEL ] = lc;
440769Speter #	endif OBJ
441769Speter #	ifdef PC
442*10656Speter 	    putprintf("	.data", 0);
443*10656Speter 	    aligndot(A_STRUCT);
444769Speter 	    ap -> value[ NL_ELABEL ] = getlab();
445769Speter 	    putlab( ap -> value[ NL_ELABEL ] );
446769Speter #	endif PC
447769Speter 	/* number of scalars */
448769Speter 	next = ap->type;
449769Speter 	len = next->range[1]-next->range[0]+1;
450769Speter #	ifdef OBJ
451769Speter 	    put(2, O_CASE2, len);
452769Speter #	endif OBJ
453769Speter #	ifdef PC
454769Speter 	    putprintf( "	.word %d" , 0 , len );
455769Speter #	endif PC
456769Speter 	/* offsets of each scalar name */
457769Speter 	len = (len+1)*sizeof(short);
458769Speter #	ifdef OBJ
459769Speter 	    put(2, O_CASE2, len);
460769Speter #	endif OBJ
461769Speter #	ifdef PC
462769Speter 	    putprintf( "	.word %d" , 0 , len );
463769Speter #	endif PC
464769Speter 	next = ap->chain;
465769Speter 	do	{
466769Speter 		for(strptr = next->symbol;  *strptr++;  len++)
467769Speter 			continue;
468769Speter 		len++;
469769Speter #		ifdef OBJ
470769Speter 		    put(2, O_CASE2, len);
471769Speter #		endif OBJ
472769Speter #		ifdef PC
473769Speter 		    putprintf( "	.word %d" , 0 , len );
474769Speter #		endif PC
475769Speter 	} while (next = next->chain);
476769Speter 	/* list of scalar names */
477769Speter 	strptr = getnext(ap, &next);
478769Speter #	ifdef OBJ
479769Speter 	    do	{
4803077Smckusic #		    ifdef DEC11
4813077Smckusic 			w = (unsigned) *strptr;
4823077Smckusic #		    else
4833077Smckusic 			w = *strptr << 8;
4843077Smckusic #		    endif DEC11
485769Speter 		    if (!*strptr++)
486769Speter 			    strptr = getnext(next, &next);
4873077Smckusic #		    ifdef DEC11
4883077Smckusic 			w |= *strptr << 8;
4893077Smckusic #		    else
4903077Smckusic 			w |= (unsigned) *strptr;
4913077Smckusic #		    endif DEC11
492769Speter 		    if (!*strptr++)
493769Speter 			    strptr = getnext(next, &next);
494769Speter 		    word(w);
495769Speter 	    } while (next);
496769Speter 	    /* jump over the mess */
497769Speter 	    patch(oldlc);
498769Speter #	endif OBJ
499769Speter #	ifdef PC
500769Speter 	    while ( next ) {
501769Speter 		while ( *strptr ) {
502769Speter 		    putprintf( "	.byte	0%o" , 1 , *strptr++ );
503769Speter 		    for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) {
504769Speter 			putprintf( ",0%o" , 1 , *strptr++ );
505769Speter 		    }
506769Speter 		    putprintf( "" , 0 );
507769Speter 		}
508769Speter 		putprintf( "	.byte	0" , 0 );
509769Speter 		strptr = getnext( next , &next );
510769Speter 	    }
511769Speter 	    putprintf( "	.text" , 0 );
512769Speter #	endif PC
513769Speter 	return( ap -> value[ NL_ELABEL ] );
514769Speter }
515769Speter 
516769Speter getnext(next, new)
517769Speter 
518769Speter 	struct nl *next, **new;
519769Speter {
520769Speter 	if (next != NIL) {
521769Speter 		next = next->chain;
522769Speter 		*new = next;
523769Speter 	}
524769Speter 	if (next == NIL)
525769Speter 		return("");
526769Speter #ifdef OBJ
5273317Speter 	if (opt('k') && CGENNING )
5283317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol);
5292213Speter #endif OBJ
530769Speter 	return(next->symbol);
531769Speter }
532769Speter 
533769Speter #ifdef OBJ
534769Speter /*
535769Speter  * Putspace puts out a table
536769Speter  * of nothing to leave space
537769Speter  * for the case branch table e.g.
538769Speter  */
539769Speter putspace(n)
540769Speter 	int n;
541769Speter {
542769Speter 	register i;
543769Speter 
5443317Speter 	if ( !CGENNING )
545769Speter 		/*
546769Speter 		 * code disabled - do nothing
547769Speter 		 */
548769Speter 		return(lc);
549769Speter #ifdef DEBUG
550769Speter 	if (opt('k'))
5513317Speter 		printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n);
552769Speter #endif
553769Speter 	for (i = even(n); i > 0; i -= 2)
554769Speter 		word(0);
555769Speter }
556769Speter 
557769Speter putstr(sptr, padding)
558769Speter 
559769Speter 	char *sptr;
560769Speter 	int padding;
561769Speter {
562769Speter 	register unsigned short w;
563769Speter 	register char *strptr = sptr;
564769Speter 	register int pad = padding;
565769Speter 
5663317Speter 	if ( !CGENNING )
567769Speter 		/*
568769Speter 		 * code disabled - do nothing
569769Speter 		 */
570769Speter 		return(lc);
571769Speter #ifdef DEBUG
572769Speter 	if (opt('k'))
5733317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr);
574769Speter #endif
575769Speter 	if (pad == 0) {
576769Speter 		do	{
5773077Smckusic #			ifdef DEC11
5783077Smckusic 			    w = (unsigned short) * strptr;
5793077Smckusic #			else
5803077Smckusic 			    w = (unsigned short)*strptr<<8;
5813077Smckusic #			endif DEC11
582769Speter 			if (w)
5833077Smckusic #				ifdef DEC11
5843077Smckusic 				    w |= *++strptr << 8;
5853077Smckusic #				else
5863077Smckusic 				    w |= *++strptr;
5873077Smckusic #				endif DEC11
588769Speter 			word(w);
589769Speter 		} while (*strptr++);
590769Speter 	} else {
5913077Smckusic #		ifdef DEC11
5923077Smckusic 		    do 	{
5933077Smckusic 			    w = (unsigned short) * strptr;
5943077Smckusic 			    if (w) {
5953077Smckusic 				    if (*++strptr)
5963077Smckusic 					    w |= *strptr << 8;
5973077Smckusic 				    else {
5983077Smckusic 					    w |= ' \0';
5993077Smckusic 					    pad--;
6003077Smckusic 				    }
6013077Smckusic 				    word(w);
6023077Smckusic 			    }
6033077Smckusic 		    } while (*strptr++);
6043077Smckusic #		else
6053077Smckusic 		    do 	{
6063077Smckusic 			    w = (unsigned short)*strptr<<8;
6073077Smckusic 			    if (w) {
6083077Smckusic 				    if (*++strptr)
6093077Smckusic 					    w |= *strptr;
6103077Smckusic 				    else {
6113077Smckusic 					    w |= ' ';
6123077Smckusic 					    pad--;
6133077Smckusic 				    }
6143077Smckusic 				    word(w);
6153077Smckusic 			    }
6163077Smckusic 		    } while (*strptr++);
6173077Smckusic #		endif DEC11
618769Speter 		while (pad > 1) {
619769Speter 			word('  ');
620769Speter 			pad -= 2;
621769Speter 		}
622769Speter 		if (pad == 1)
6233077Smckusic #			ifdef DEC11
6243077Smckusic 			    word(' ');
6253077Smckusic #			else
6263077Smckusic 			    word(' \0');
6273077Smckusic #			endif DEC11
628769Speter 		else
629769Speter 			word(0);
630769Speter 	}
631769Speter }
632769Speter #endif OBJ
633769Speter 
634769Speter lenstr(sptr, padding)
635769Speter 
636769Speter 	char *sptr;
637769Speter 	int padding;
638769Speter 
639769Speter {
640769Speter 	register int cnt;
641769Speter 	register char *strptr = sptr;
642769Speter 
643769Speter 	cnt = padding;
644769Speter 	do	{
645769Speter 		cnt++;
646769Speter 	} while (*strptr++);
647769Speter 	return((++cnt) & ~1);
648769Speter }
649769Speter 
650769Speter /*
651769Speter  * Patch repairs the branch
652769Speter  * at location loc to come
653769Speter  * to the current location.
654769Speter  *	for PC, this puts down the label
655769Speter  *	and the branch just references that label.
656769Speter  *	lets here it for two pass assemblers.
657769Speter  */
658769Speter patch(loc)
659769Speter {
660769Speter 
661769Speter #	ifdef OBJ
6623077Smckusic 	    patchfil(loc, (long)(lc-loc-2), 1);
663769Speter #	endif OBJ
664769Speter #	ifdef PC
665769Speter 	    putlab( loc );
666769Speter #	endif PC
667769Speter }
668769Speter 
669769Speter #ifdef OBJ
670769Speter patch4(loc)
671769Speter {
6723077Smckusic 	patchfil(loc, (long)(lc - HEADER_BYTES), 2);
673769Speter }
674769Speter 
675769Speter /*
6767921Smckusick  * Patchfil makes loc+2 have jmploc
677769Speter  * as its contents.
678769Speter  */
6797921Smckusick patchfil(loc, jmploc, words)
680769Speter 	PTR_DCL loc;
6817921Smckusick 	long jmploc;
6823077Smckusic 	int words;
683769Speter {
684769Speter 	register i;
68510562Smckusick 	short val;
686769Speter 
6873317Speter 	if ( !CGENNING )
688769Speter 		return;
689769Speter 	if (loc > (unsigned) lc)
690769Speter 		panic("patchfil");
691769Speter #ifdef DEBUG
692769Speter 	if (opt('k'))
6937921Smckusick 		printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc);
694769Speter #endif
6957921Smckusick 	val = jmploc;
696769Speter 	do {
6973077Smckusic #		ifndef DEC11
6983077Smckusic 		    if (words > 1)
6997921Smckusick 			    val = jmploc >> 16;
7003077Smckusic 		    else
7017921Smckusick 			    val = jmploc;
7023077Smckusic #		endif DEC11
703769Speter 		i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
70410562Smckusick 		if (i >= 0 && i < 1024) {
7053077Smckusic 			obuf[i] = val;
70610562Smckusick 		} else {
707769Speter 			lseek(ofil, (long) loc+2, 0);
7083077Smckusic 			write(ofil, &val, 2);
709769Speter 			lseek(ofil, (long) 0, 2);
710769Speter 		}
711769Speter 		loc += 2;
7123077Smckusic #		ifdef DEC11
7137921Smckusick 		    val = jmploc >> 16;
7143077Smckusic #		endif DEC11
715769Speter 	} while (--words);
716769Speter }
717769Speter 
718769Speter /*
719769Speter  * Put the word o into the code
720769Speter  */
721769Speter word(o)
722769Speter 	int o;
723769Speter {
724769Speter 
725769Speter 	*obufp = o;
726769Speter 	obufp++;
727769Speter 	lc += 2;
728769Speter 	if (obufp >= obuf+512)
729769Speter 		pflush();
730769Speter }
731769Speter 
732769Speter extern char	*obj;
733769Speter /*
734769Speter  * Flush the code buffer
735769Speter  */
736769Speter pflush()
737769Speter {
738769Speter 	register i;
739769Speter 
740769Speter 	i = (obufp - ( ( short * ) obuf ) ) * 2;
741769Speter 	if (i != 0 && write(ofil, obuf, i) != i)
742769Speter 		perror(obj), pexit(DIED);
743769Speter 	obufp = obuf;
744769Speter }
745769Speter #endif OBJ
746769Speter 
747769Speter /*
748769Speter  * Getlab - returns the location counter.
749769Speter  * included here for the eventual code generator.
750769Speter  *	for PC, thank you!
751769Speter  */
752769Speter getlab()
753769Speter {
754769Speter #	ifdef OBJ
755769Speter 
756769Speter 	    return (lc);
757769Speter #	endif OBJ
758769Speter #	ifdef PC
759769Speter 	    static long	lastlabel;
760769Speter 
761769Speter 	    return ( ++lastlabel );
762769Speter #	endif PC
763769Speter }
764769Speter 
765769Speter /*
766769Speter  * Putlab - lay down a label.
767769Speter  *	for PC, just print the label name with a colon after it.
768769Speter  */
769769Speter putlab(l)
770769Speter 	int l;
771769Speter {
772769Speter 
773769Speter #	ifdef PC
774769Speter 	    putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l );
775769Speter 	    putprintf( ":" , 0 );
776769Speter #	endif PC
777769Speter 	return (l);
778769Speter }
779