xref: /csrg-svn/usr.bin/pascal/src/put.c (revision 67239)
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