xref: /csrg-svn/usr.bin/pascal/src/put.c (revision 10562)
1769Speter /* Copyright (c) 1979 Regents of the University of California */
2769Speter 
3*10562Smckusick static char sccsid[] = "@(#)put.c 1.20 01/21/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"
11769Speter #endif PC
12769Speter 
13769Speter short	*obufp	= obuf;
14769Speter 
15769Speter /*
16769Speter  * If DEBUG is defined, include the table
17769Speter  * of the printing opcode names.
18769Speter  */
19769Speter #ifdef DEBUG
20769Speter #include "OPnames.h"
21769Speter #endif
22769Speter 
23769Speter #ifdef OBJ
24769Speter /*
25769Speter  * Put is responsible for the interpreter equivalent of code
26769Speter  * generation.  Since the interpreter is specifically designed
27769Speter  * for Pascal, little work is required here.
28769Speter  */
29769Speter put(a)
30769Speter {
31769Speter 	register int *p, i;
32769Speter 	register char *cp;
333077Smckusic 	register short *sp;
343077Smckusic 	register long *lp;
35769Speter 	int n, subop, suboppr, op, oldlc, w;
36769Speter 	char *string;
37769Speter 	static int casewrd;
38769Speter 
39769Speter 	/*
40769Speter 	 * It would be nice to do some more
41769Speter 	 * optimizations here.  The work
42769Speter 	 * done to collapse offsets in lval
43769Speter 	 * should be done here, the IFEQ etc
44769Speter 	 * relational operators could be used
45769Speter 	 * etc.
46769Speter 	 */
47769Speter 	oldlc = lc;
483317Speter 	if ( !CGENNING )
49769Speter 		/*
50769Speter 		 * code disabled - do nothing
51769Speter 		 */
52769Speter 		return (oldlc);
53769Speter 	p = &a;
54769Speter 	n = *p++;
553077Smckusic 	suboppr = subop = (*p >> 8) & 0377;
56769Speter 	op = *p & 0377;
57769Speter 	string = 0;
58769Speter #ifdef DEBUG
59769Speter 	if ((cp = otext[op]) == NIL) {
60769Speter 		printf("op= %o\n", op);
61769Speter 		panic("put");
62769Speter 	}
63769Speter #endif
64769Speter 	switch (op) {
65769Speter 		case O_ABORT:
66769Speter 			cp = "*";
67769Speter 			break;
682221Smckusic 		case O_AS:
692221Smckusic 			switch(p[1]) {
706594Smckusick 			case 0:
716594Smckusick 				break;
722221Smckusic 			case 2:
732221Smckusic 				op = O_AS2;
746594Smckusick 				n = 1;
752221Smckusic 				break;
762221Smckusic 			case 4:
772221Smckusic 				op = O_AS4;
786594Smckusick 				n = 1;
792221Smckusic 				break;
802221Smckusic 			case 8:
812221Smckusic 				op = O_AS8;
826594Smckusick 				n = 1;
832221Smckusic 				break;
842221Smckusic 			default:
852221Smckusic 				goto pack;
862221Smckusic 			}
873077Smckusic #			ifdef DEBUG
883077Smckusic 				cp = otext[op];
893077Smckusic #			endif DEBUG
902221Smckusic 			break;
913077Smckusic 		case O_CONG:
923077Smckusic 		case O_LVCON:
933077Smckusic 		case O_CON:
94769Speter 		case O_LINO:
95769Speter 		case O_NEW:
96769Speter 		case O_DISPOSE:
977965Smckusick 		case O_DFDISP:
98769Speter 		case O_IND:
99769Speter 		case O_OFF:
100769Speter 		case O_INX2:
101769Speter 		case O_INX4:
102769Speter 		case O_CARD:
103769Speter 		case O_ADDT:
104769Speter 		case O_SUBT:
105769Speter 		case O_MULT:
106769Speter 		case O_IN:
107769Speter 		case O_CASE1OP:
108769Speter 		case O_CASE2OP:
109769Speter 		case O_CASE4OP:
1101199Speter 		case O_FRTN:
111769Speter 		case O_WRITES:
1123173Smckusic 		case O_WRITEC:
113769Speter 		case O_WRITEF:
114769Speter 		case O_MAX:
115769Speter 		case O_MIN:
116769Speter 		case O_ARGV:
117769Speter 		case O_CTTOT:
118769Speter 		case O_INCT:
119769Speter 		case O_RANG2:
120769Speter 		case O_RSNG2:
121769Speter 		case O_RANG42:
122769Speter 		case O_RSNG42:
1232105Smckusic 		case O_SUCC2:
1242105Smckusic 		case O_SUCC24:
1252105Smckusic 		case O_PRED2:
1262105Smckusic 		case O_PRED24:
127769Speter 			if (p[1] == 0)
128769Speter 				break;
129769Speter 		case O_CON2:
130769Speter 		case O_CON24:
1312221Smckusic 		pack:
132769Speter 			if (p[1] < 128 && p[1] >= -128) {
133769Speter 				suboppr = subop = p[1];
134769Speter 				p++;
135769Speter 				n--;
136769Speter 				if (op == O_CON2) {
137769Speter 					op = O_CON1;
1383077Smckusic #					ifdef DEBUG
1393077Smckusic 						cp = otext[O_CON1];
1403077Smckusic #					endif DEBUG
141769Speter 				}
142769Speter 				if (op == O_CON24) {
143769Speter 					op = O_CON14;
1443077Smckusic #					ifdef DEBUG
1453077Smckusic 						cp = otext[O_CON14];
1463077Smckusic #					endif DEBUG
147769Speter 				}
148769Speter 			}
149769Speter 			break;
150769Speter 		case O_CON8:
151769Speter 		    {
152769Speter 			short	*sp = &p[1];
153769Speter 
154769Speter #ifdef	DEBUG
155769Speter 			if ( opt( 'k' ) )
1563317Speter 			    printf ( "%5d\tCON8\t%22.14e\n" ,
157769Speter 					lc - HEADER_BYTES ,
158769Speter 					* ( ( double * ) &p[1] ) );
159769Speter #endif
1603077Smckusic #			ifdef DEC11
1613077Smckusic 			    word(op);
1623077Smckusic #			else
1633077Smckusic 			    word(op << 8);
1643077Smckusic #			endif DEC11
165769Speter 			for ( i = 1 ; i <= 4 ; i ++ )
166769Speter 			    word ( *sp ++ );
167769Speter 			return ( oldlc );
168769Speter 		    }
169769Speter 		default:
170769Speter 			if (op >= O_REL2 && op <= O_REL84) {
1711883Smckusic 				if ((i = (subop >> INDX) * 5 ) >= 30)
172769Speter 					i -= 30;
173769Speter 				else
174769Speter 					i += 2;
175769Speter #ifdef DEBUG
176769Speter 				string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
177769Speter #endif
178769Speter 				suboppr = 0;
179769Speter 			}
180769Speter 			break;
181769Speter 		case O_IF:
182769Speter 		case O_TRA:
183769Speter /*****
184769Speter 			codeline = 0;
185769Speter *****/
1862184Smckusic 			/* relative addressing */
1872184Smckusic 			p[1] -= ( unsigned ) lc + sizeof(short);
1882184Smckusic 			break;
189769Speter 		case O_FOR1U:
190769Speter 		case O_FOR2U:
191769Speter 		case O_FOR1D:
192769Speter 		case O_FOR2D:
1934025Smckusic 			/* sub opcode optimization */
1944025Smckusic 			if (p[1] < 128 && p[1] >= -128 && p[1] != 0) {
1954025Smckusic 				suboppr = subop = p[1];
1964025Smckusic 				p++;
1974025Smckusic 				n--;
1984025Smckusic 			}
199769Speter 			/* relative addressing */
2004025Smckusic 			p[n - 1] -= ( unsigned ) lc + (n - 1) * sizeof(short);
201769Speter 			break;
202769Speter 		case O_CONC:
203769Speter #ifdef DEBUG
204769Speter 			(string = "'x'")[1] = p[1];
205769Speter #endif
206769Speter 			suboppr = 0;
207769Speter 			op = O_CON1;
2083077Smckusic #			ifdef DEBUG
2093077Smckusic 				cp = otext[O_CON1];
2103077Smckusic #			endif DEBUG
211769Speter 			subop = p[1];
212769Speter 			goto around;
213769Speter 		case O_CONC4:
214769Speter #ifdef DEBUG
215769Speter 			(string = "'x'")[1] = p[1];
216769Speter #endif
217769Speter 			suboppr = 0;
218769Speter 			op = O_CON14;
219769Speter 			subop = p[1];
220769Speter 			goto around;
221769Speter 		case O_CON1:
222769Speter 		case O_CON14:
223769Speter 			suboppr = subop = p[1];
224769Speter around:
225769Speter 			n--;
226769Speter 			break;
227769Speter 		case O_CASEBEG:
228769Speter 			casewrd = 0;
229769Speter 			return (oldlc);
230769Speter 		case O_CASEEND:
231769Speter 			if ((unsigned) lc & 1) {
232769Speter 				lc--;
233769Speter 				word(casewrd);
234769Speter 			}
235769Speter 			return (oldlc);
236769Speter 		case O_CASE1:
237769Speter #ifdef DEBUG
238769Speter 			if (opt('k'))
2393317Speter 				printf("%5d\tCASE1\t%d\n"
2403077Smckusic 					, lc - HEADER_BYTES, p[1]);
241769Speter #endif
242769Speter 			/*
243769Speter 			 * this to build a byte size case table
244769Speter 			 * saving bytes across calls in casewrd
245769Speter 			 * so they can be put out by word()
246769Speter 			 */
247769Speter 			lc++;
248769Speter 			if ((unsigned) lc & 1)
2493077Smckusic #				ifdef DEC11
2503077Smckusic 				    casewrd = p[1] & 0377;
2513077Smckusic #				else
2523077Smckusic 				    casewrd = (p[1] & 0377) << 8;
2533077Smckusic #				endif DEC11
254769Speter 			else {
255769Speter 				lc -= 2;
2563077Smckusic #				ifdef DEC11
2573077Smckusic 				    word(((p[1] & 0377) << 8) | casewrd);
2583077Smckusic #				else
2593077Smckusic 				    word((p[1] & 0377) | casewrd);
2603077Smckusic #				endif DEC11
261769Speter 			}
262769Speter 			return (oldlc);
263769Speter 		case O_CASE2:
264769Speter #ifdef DEBUG
265769Speter 			if (opt('k'))
2663317Speter 				printf("%5d\tCASE2\t%d\n"
2673077Smckusic 					, lc - HEADER_BYTES , p[1]);
268769Speter #endif
2693077Smckusic 			word(p[1]);
270769Speter 			return (oldlc);
2714025Smckusic 		case O_FOR4U:
2724025Smckusic 		case O_FOR4D:
2734025Smckusic 			/* sub opcode optimization */
2744025Smckusic 			lp = (long *)&p[1];
2754025Smckusic 			if (*lp < 128 && *lp >= -128 && *lp != 0) {
2764025Smckusic 				suboppr = subop = *lp;
2774025Smckusic 				p += (sizeof(long) / sizeof(int));
2784025Smckusic 				n--;
2794025Smckusic 			}
2804025Smckusic 			/* relative addressing */
2814025Smckusic 			p[1 + (n - 2) * (sizeof(long) / sizeof(int))] -=
2824025Smckusic 			    (unsigned)lc + (sizeof(short) +
2834025Smckusic 			    (n - 2) * sizeof(long));
2844025Smckusic 			goto longgen;
285769Speter 		case O_PUSH:
2863077Smckusic 			lp = (long *)&p[1];
2873077Smckusic 			if (*lp == 0)
288769Speter 				return (oldlc);
2894025Smckusic 			/* and fall through */
2904025Smckusic 		case O_RANG4:
2914025Smckusic 		case O_RANG24:
2924025Smckusic 		case O_RSNG4:
2934025Smckusic 		case O_RSNG24:
2944025Smckusic 		case O_SUCC4:
2954025Smckusic 		case O_PRED4:
2964025Smckusic 			/* sub opcode optimization */
2974025Smckusic 			lp = (long *)&p[1];
2984025Smckusic 			if (*lp < 128 && *lp >= -128 && *lp != 0) {
2993077Smckusic 				suboppr = subop = *lp;
3004025Smckusic 				p += (sizeof(long) / sizeof(int));
301769Speter 				n--;
302769Speter 			}
303769Speter 			goto longgen;
304769Speter 		case O_TRA4:
305769Speter 		case O_CALL:
3061199Speter 		case O_FSAV:
307769Speter 		case O_GOTO:
308769Speter 		case O_NAM:
309769Speter 		case O_READE:
310769Speter 			/* absolute long addressing */
3113077Smckusic 			lp = (long *)&p[1];
3123077Smckusic 			*lp -= HEADER_BYTES;
313769Speter 			goto longgen;
314769Speter 		case O_RV1:
315769Speter 		case O_RV14:
316769Speter 		case O_RV2:
317769Speter 		case O_RV24:
318769Speter 		case O_RV4:
319769Speter 		case O_RV8:
320769Speter 		case O_RV:
321769Speter 		case O_LV:
3222105Smckusic 			/*
3232105Smckusic 			 * positive offsets represent arguments
3242105Smckusic 			 * and must use "ap" display entry rather
3252105Smckusic 			 * than the "fp" entry
3262105Smckusic 			 */
3272105Smckusic 			if (p[1] >= 0) {
3282105Smckusic 				subop++;
3292105Smckusic 				suboppr++;
3302105Smckusic 			}
3313077Smckusic #			ifdef PDP11
3323077Smckusic 			    break;
3333077Smckusic #			else
3343077Smckusic 			    /*
3353077Smckusic 			     * offsets out of range of word addressing
3363077Smckusic 			     * must use long offset opcodes
3373077Smckusic 			     */
3383077Smckusic 			    if (p[1] < SHORTADDR && p[1] >= -SHORTADDR)
3393077Smckusic 				    break;
3403077Smckusic 			    else {
341769Speter 				op += O_LRV - O_RV;
3423077Smckusic #				ifdef DEBUG
3433077Smckusic 				    cp = otext[op];
3443077Smckusic #				endif DEBUG
3453077Smckusic 			    }
3463077Smckusic 			    /* and fall through */
3473077Smckusic #			endif PDP11
348769Speter 		case O_BEG:
349769Speter 		case O_NODUMP:
350769Speter 		case O_CON4:
351769Speter 		case O_CASE4:
352769Speter 		longgen:
353769Speter 			n = (n << 1) - 1;
354*10562Smckusick 			if ( op == O_LRV || op == O_FOR4U || op == O_FOR4D) {
355769Speter 				n--;
356*10562Smckusick #				if defined(ADDR32) && !defined(DEC11)
357*10562Smckusick 				    p[n / 2] <<= 16;
358*10562Smckusick #				endif
359*10562Smckusick 			}
360769Speter #ifdef DEBUG
3613077Smckusic 			if (opt('k')) {
3623317Speter 				printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
363769Speter 				if (suboppr)
3643077Smckusic 					printf(":%d", suboppr);
3653077Smckusic 				for ( i = 2, lp = (long *)&p[1]; i < n
366769Speter 				    ; i += sizeof ( long )/sizeof ( short ) )
367769Speter 					printf( "\t%D " , *lp ++ );
3683377Speter 				if (i == n) {
3693377Speter 					sp = (short *)lp;
3703377Speter 					printf( "\t%d ", *sp );
3713377Speter 				}
372769Speter 				pchr ( '\n' );
3733077Smckusic 			}
374769Speter #endif
375769Speter 			if ( op != O_CASE4 )
3763077Smckusic #				ifdef DEC11
3773077Smckusic 			    	    word((op & 0377) | subop << 8);
3783077Smckusic #				else
3793077Smckusic 				    word(op << 8 | (subop & 0377));
3803077Smckusic #				endif DEC11
3813077Smckusic 			for ( i = 1, sp = (short *)&p[1]; i < n; i++)
3823077Smckusic 				word ( *sp ++ );
383769Speter 			return ( oldlc );
384769Speter 	}
385769Speter #ifdef DEBUG
386769Speter 	if (opt('k')) {
3873317Speter 		printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
388769Speter 		if (suboppr)
389769Speter 			printf(":%d", suboppr);
390769Speter 		if (string)
391769Speter 			printf("\t%s",string);
392769Speter 		if (n > 1)
393769Speter 			pchr('\t');
394769Speter 		for (i=1; i<n; i++)
3953077Smckusic 			printf("%d ", p[i]);
396769Speter 		pchr('\n');
397769Speter 	}
398769Speter #endif
399769Speter 	if (op != NIL)
4003077Smckusic #		ifdef DEC11
4013077Smckusic 		    word((op & 0377) | subop << 8);
4023077Smckusic #		else
4033077Smckusic 		    word(op << 8 | (subop & 0377));
4043077Smckusic #		endif DEC11
405769Speter 	for (i=1; i<n; i++)
406769Speter 		word(p[i]);
407769Speter 	return (oldlc);
408769Speter }
409769Speter #endif OBJ
410769Speter 
411769Speter /*
412769Speter  * listnames outputs a list of enumerated type names which
413769Speter  * can then be selected from to output a TSCAL
414769Speter  * a pointer to the address in the code of the namelist
415769Speter  * is kept in value[ NL_ELABEL ].
416769Speter  */
417769Speter listnames(ap)
418769Speter 
419769Speter 	register struct nl *ap;
420769Speter {
421769Speter 	struct nl *next;
422769Speter 	register int oldlc, len;
423769Speter 	register unsigned w;
424769Speter 	register char *strptr;
425769Speter 
4263317Speter 	if ( !CGENNING )
427769Speter 		/* code is off - do nothing */
428769Speter 		return(NIL);
429769Speter 	if (ap->class != TYPE)
430769Speter 		ap = ap->type;
431769Speter 	if (ap->value[ NL_ELABEL ] != 0) {
432769Speter 		/* the list already exists */
433769Speter 		return( ap -> value[ NL_ELABEL ] );
434769Speter 	}
435769Speter #	ifdef OBJ
436769Speter 	    oldlc = lc;
437769Speter 	    put(2, O_TRA, lc);
438769Speter 	    ap->value[ NL_ELABEL ] = lc;
439769Speter #	endif OBJ
440769Speter #	ifdef PC
44110254Speter #	    ifdef vax
44210254Speter 		putprintf("	.data", 0);
44310254Speter 		putprintf("	.align 1", 0);
44410254Speter #	    endif vax
44510254Speter #	    ifdef mc68000
44610254Speter 		putprintf("	.data", 0);
44710254Speter 		putprintf("	.even", 0);
44810254Speter #	    endif mc68000
449769Speter 	    ap -> value[ NL_ELABEL ] = getlab();
450769Speter 	    putlab( ap -> value[ NL_ELABEL ] );
451769Speter #	endif PC
452769Speter 	/* number of scalars */
453769Speter 	next = ap->type;
454769Speter 	len = next->range[1]-next->range[0]+1;
455769Speter #	ifdef OBJ
456769Speter 	    put(2, O_CASE2, len);
457769Speter #	endif OBJ
458769Speter #	ifdef PC
459769Speter 	    putprintf( "	.word %d" , 0 , len );
460769Speter #	endif PC
461769Speter 	/* offsets of each scalar name */
462769Speter 	len = (len+1)*sizeof(short);
463769Speter #	ifdef OBJ
464769Speter 	    put(2, O_CASE2, len);
465769Speter #	endif OBJ
466769Speter #	ifdef PC
467769Speter 	    putprintf( "	.word %d" , 0 , len );
468769Speter #	endif PC
469769Speter 	next = ap->chain;
470769Speter 	do	{
471769Speter 		for(strptr = next->symbol;  *strptr++;  len++)
472769Speter 			continue;
473769Speter 		len++;
474769Speter #		ifdef OBJ
475769Speter 		    put(2, O_CASE2, len);
476769Speter #		endif OBJ
477769Speter #		ifdef PC
478769Speter 		    putprintf( "	.word %d" , 0 , len );
479769Speter #		endif PC
480769Speter 	} while (next = next->chain);
481769Speter 	/* list of scalar names */
482769Speter 	strptr = getnext(ap, &next);
483769Speter #	ifdef OBJ
484769Speter 	    do	{
4853077Smckusic #		    ifdef DEC11
4863077Smckusic 			w = (unsigned) *strptr;
4873077Smckusic #		    else
4883077Smckusic 			w = *strptr << 8;
4893077Smckusic #		    endif DEC11
490769Speter 		    if (!*strptr++)
491769Speter 			    strptr = getnext(next, &next);
4923077Smckusic #		    ifdef DEC11
4933077Smckusic 			w |= *strptr << 8;
4943077Smckusic #		    else
4953077Smckusic 			w |= (unsigned) *strptr;
4963077Smckusic #		    endif DEC11
497769Speter 		    if (!*strptr++)
498769Speter 			    strptr = getnext(next, &next);
499769Speter 		    word(w);
500769Speter 	    } while (next);
501769Speter 	    /* jump over the mess */
502769Speter 	    patch(oldlc);
503769Speter #	endif OBJ
504769Speter #	ifdef PC
505769Speter 	    while ( next ) {
506769Speter 		while ( *strptr ) {
507769Speter 		    putprintf( "	.byte	0%o" , 1 , *strptr++ );
508769Speter 		    for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) {
509769Speter 			putprintf( ",0%o" , 1 , *strptr++ );
510769Speter 		    }
511769Speter 		    putprintf( "" , 0 );
512769Speter 		}
513769Speter 		putprintf( "	.byte	0" , 0 );
514769Speter 		strptr = getnext( next , &next );
515769Speter 	    }
516769Speter 	    putprintf( "	.text" , 0 );
517769Speter #	endif PC
518769Speter 	return( ap -> value[ NL_ELABEL ] );
519769Speter }
520769Speter 
521769Speter getnext(next, new)
522769Speter 
523769Speter 	struct nl *next, **new;
524769Speter {
525769Speter 	if (next != NIL) {
526769Speter 		next = next->chain;
527769Speter 		*new = next;
528769Speter 	}
529769Speter 	if (next == NIL)
530769Speter 		return("");
531769Speter #ifdef OBJ
5323317Speter 	if (opt('k') && CGENNING )
5333317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol);
5342213Speter #endif OBJ
535769Speter 	return(next->symbol);
536769Speter }
537769Speter 
538769Speter #ifdef OBJ
539769Speter /*
540769Speter  * Putspace puts out a table
541769Speter  * of nothing to leave space
542769Speter  * for the case branch table e.g.
543769Speter  */
544769Speter putspace(n)
545769Speter 	int n;
546769Speter {
547769Speter 	register i;
548769Speter 
5493317Speter 	if ( !CGENNING )
550769Speter 		/*
551769Speter 		 * code disabled - do nothing
552769Speter 		 */
553769Speter 		return(lc);
554769Speter #ifdef DEBUG
555769Speter 	if (opt('k'))
5563317Speter 		printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n);
557769Speter #endif
558769Speter 	for (i = even(n); i > 0; i -= 2)
559769Speter 		word(0);
560769Speter }
561769Speter 
562769Speter putstr(sptr, padding)
563769Speter 
564769Speter 	char *sptr;
565769Speter 	int padding;
566769Speter {
567769Speter 	register unsigned short w;
568769Speter 	register char *strptr = sptr;
569769Speter 	register int pad = padding;
570769Speter 
5713317Speter 	if ( !CGENNING )
572769Speter 		/*
573769Speter 		 * code disabled - do nothing
574769Speter 		 */
575769Speter 		return(lc);
576769Speter #ifdef DEBUG
577769Speter 	if (opt('k'))
5783317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr);
579769Speter #endif
580769Speter 	if (pad == 0) {
581769Speter 		do	{
5823077Smckusic #			ifdef DEC11
5833077Smckusic 			    w = (unsigned short) * strptr;
5843077Smckusic #			else
5853077Smckusic 			    w = (unsigned short)*strptr<<8;
5863077Smckusic #			endif DEC11
587769Speter 			if (w)
5883077Smckusic #				ifdef DEC11
5893077Smckusic 				    w |= *++strptr << 8;
5903077Smckusic #				else
5913077Smckusic 				    w |= *++strptr;
5923077Smckusic #				endif DEC11
593769Speter 			word(w);
594769Speter 		} while (*strptr++);
595769Speter 	} else {
5963077Smckusic #		ifdef DEC11
5973077Smckusic 		    do 	{
5983077Smckusic 			    w = (unsigned short) * strptr;
5993077Smckusic 			    if (w) {
6003077Smckusic 				    if (*++strptr)
6013077Smckusic 					    w |= *strptr << 8;
6023077Smckusic 				    else {
6033077Smckusic 					    w |= ' \0';
6043077Smckusic 					    pad--;
6053077Smckusic 				    }
6063077Smckusic 				    word(w);
6073077Smckusic 			    }
6083077Smckusic 		    } while (*strptr++);
6093077Smckusic #		else
6103077Smckusic 		    do 	{
6113077Smckusic 			    w = (unsigned short)*strptr<<8;
6123077Smckusic 			    if (w) {
6133077Smckusic 				    if (*++strptr)
6143077Smckusic 					    w |= *strptr;
6153077Smckusic 				    else {
6163077Smckusic 					    w |= ' ';
6173077Smckusic 					    pad--;
6183077Smckusic 				    }
6193077Smckusic 				    word(w);
6203077Smckusic 			    }
6213077Smckusic 		    } while (*strptr++);
6223077Smckusic #		endif DEC11
623769Speter 		while (pad > 1) {
624769Speter 			word('  ');
625769Speter 			pad -= 2;
626769Speter 		}
627769Speter 		if (pad == 1)
6283077Smckusic #			ifdef DEC11
6293077Smckusic 			    word(' ');
6303077Smckusic #			else
6313077Smckusic 			    word(' \0');
6323077Smckusic #			endif DEC11
633769Speter 		else
634769Speter 			word(0);
635769Speter 	}
636769Speter }
637769Speter #endif OBJ
638769Speter 
639769Speter lenstr(sptr, padding)
640769Speter 
641769Speter 	char *sptr;
642769Speter 	int padding;
643769Speter 
644769Speter {
645769Speter 	register int cnt;
646769Speter 	register char *strptr = sptr;
647769Speter 
648769Speter 	cnt = padding;
649769Speter 	do	{
650769Speter 		cnt++;
651769Speter 	} while (*strptr++);
652769Speter 	return((++cnt) & ~1);
653769Speter }
654769Speter 
655769Speter /*
656769Speter  * Patch repairs the branch
657769Speter  * at location loc to come
658769Speter  * to the current location.
659769Speter  *	for PC, this puts down the label
660769Speter  *	and the branch just references that label.
661769Speter  *	lets here it for two pass assemblers.
662769Speter  */
663769Speter patch(loc)
664769Speter {
665769Speter 
666769Speter #	ifdef OBJ
6673077Smckusic 	    patchfil(loc, (long)(lc-loc-2), 1);
668769Speter #	endif OBJ
669769Speter #	ifdef PC
670769Speter 	    putlab( loc );
671769Speter #	endif PC
672769Speter }
673769Speter 
674769Speter #ifdef OBJ
675769Speter patch4(loc)
676769Speter {
6773077Smckusic 	patchfil(loc, (long)(lc - HEADER_BYTES), 2);
678769Speter }
679769Speter 
680769Speter /*
6817921Smckusick  * Patchfil makes loc+2 have jmploc
682769Speter  * as its contents.
683769Speter  */
6847921Smckusick patchfil(loc, jmploc, words)
685769Speter 	PTR_DCL loc;
6867921Smckusick 	long jmploc;
6873077Smckusic 	int words;
688769Speter {
689769Speter 	register i;
690*10562Smckusick 	short val;
691769Speter 
6923317Speter 	if ( !CGENNING )
693769Speter 		return;
694769Speter 	if (loc > (unsigned) lc)
695769Speter 		panic("patchfil");
696769Speter #ifdef DEBUG
697769Speter 	if (opt('k'))
6987921Smckusick 		printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc);
699769Speter #endif
7007921Smckusick 	val = jmploc;
701769Speter 	do {
7023077Smckusic #		ifndef DEC11
7033077Smckusic 		    if (words > 1)
7047921Smckusick 			    val = jmploc >> 16;
7053077Smckusic 		    else
7067921Smckusick 			    val = jmploc;
7073077Smckusic #		endif DEC11
708769Speter 		i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
709*10562Smckusick 		if (i >= 0 && i < 1024) {
7103077Smckusic 			obuf[i] = val;
711*10562Smckusick 		} else {
712769Speter 			lseek(ofil, (long) loc+2, 0);
7133077Smckusic 			write(ofil, &val, 2);
714769Speter 			lseek(ofil, (long) 0, 2);
715769Speter 		}
716769Speter 		loc += 2;
7173077Smckusic #		ifdef DEC11
7187921Smckusick 		    val = jmploc >> 16;
7193077Smckusic #		endif DEC11
720769Speter 	} while (--words);
721769Speter }
722769Speter 
723769Speter /*
724769Speter  * Put the word o into the code
725769Speter  */
726769Speter word(o)
727769Speter 	int o;
728769Speter {
729769Speter 
730769Speter 	*obufp = o;
731769Speter 	obufp++;
732769Speter 	lc += 2;
733769Speter 	if (obufp >= obuf+512)
734769Speter 		pflush();
735769Speter }
736769Speter 
737769Speter extern char	*obj;
738769Speter /*
739769Speter  * Flush the code buffer
740769Speter  */
741769Speter pflush()
742769Speter {
743769Speter 	register i;
744769Speter 
745769Speter 	i = (obufp - ( ( short * ) obuf ) ) * 2;
746769Speter 	if (i != 0 && write(ofil, obuf, i) != i)
747769Speter 		perror(obj), pexit(DIED);
748769Speter 	obufp = obuf;
749769Speter }
750769Speter #endif OBJ
751769Speter 
752769Speter /*
753769Speter  * Getlab - returns the location counter.
754769Speter  * included here for the eventual code generator.
755769Speter  *	for PC, thank you!
756769Speter  */
757769Speter getlab()
758769Speter {
759769Speter #	ifdef OBJ
760769Speter 
761769Speter 	    return (lc);
762769Speter #	endif OBJ
763769Speter #	ifdef PC
764769Speter 	    static long	lastlabel;
765769Speter 
766769Speter 	    return ( ++lastlabel );
767769Speter #	endif PC
768769Speter }
769769Speter 
770769Speter /*
771769Speter  * Putlab - lay down a label.
772769Speter  *	for PC, just print the label name with a colon after it.
773769Speter  */
774769Speter putlab(l)
775769Speter 	int l;
776769Speter {
777769Speter 
778769Speter #	ifdef PC
779769Speter 	    putprintf( PREFIXFORMAT , 1 , LABELPREFIX , l );
780769Speter 	    putprintf( ":" , 0 );
781769Speter #	endif PC
782769Speter 	return (l);
783769Speter }
784