xref: /csrg-svn/usr.bin/pascal/src/put.c (revision 30036)
123528Smckusick /*
223528Smckusick  * Copyright (c) 1980 Regents of the University of California.
323528Smckusick  * All rights reserved.  The Berkeley software License Agreement
423528Smckusick  * specifies the terms and conditions for redistribution.
523528Smckusick  */
6769Speter 
715208Sthien #ifndef lint
8*30036Smckusick static char sccsid[] = "@(#)put.c	5.2 (Berkeley) 11/12/86";
923528Smckusick #endif not lint
10769Speter 
11769Speter #include "whoami.h"
12769Speter #include "opcode.h"
13769Speter #include "0.h"
14769Speter #include "objfmt.h"
15769Speter #ifdef PC
16769Speter #   include	"pc.h"
1710656Speter #   include	"align.h"
1815208Sthien #else
1915208Sthien     short	*obufp	= obuf;
2015208Sthien #endif
21769Speter 
22769Speter /*
23769Speter  * If DEBUG is defined, include the table
24769Speter  * of the printing opcode names.
25769Speter  */
26769Speter #ifdef DEBUG
27769Speter #include "OPnames.h"
28769Speter #endif
29769Speter 
30769Speter #ifdef OBJ
31769Speter /*
32769Speter  * Put is responsible for the interpreter equivalent of code
33769Speter  * generation.  Since the interpreter is specifically designed
34769Speter  * for Pascal, little work is required here.
35769Speter  */
3615208Sthien /*VARARGS*/
37769Speter put(a)
38769Speter {
39769Speter 	register int *p, i;
40769Speter 	register char *cp;
413077Smckusic 	register short *sp;
423077Smckusic 	register long *lp;
4315208Sthien 	int n, subop, suboppr, op, oldlc;
44769Speter 	char *string;
45769Speter 	static int casewrd;
46769Speter 
47769Speter 	/*
48769Speter 	 * It would be nice to do some more
49769Speter 	 * optimizations here.  The work
50769Speter 	 * done to collapse offsets in lval
51769Speter 	 * should be done here, the IFEQ etc
52769Speter 	 * relational operators could be used
53769Speter 	 * etc.
54769Speter 	 */
5515208Sthien 	oldlc = (int) lc; /* its either this or change put to return a char * */
563317Speter 	if ( !CGENNING )
57769Speter 		/*
58769Speter 		 * code disabled - do nothing
59769Speter 		 */
60769Speter 		return (oldlc);
61769Speter 	p = &a;
62769Speter 	n = *p++;
633077Smckusic 	suboppr = subop = (*p >> 8) & 0377;
64769Speter 	op = *p & 0377;
65769Speter 	string = 0;
66769Speter #ifdef DEBUG
67769Speter 	if ((cp = otext[op]) == NIL) {
68769Speter 		printf("op= %o\n", op);
69769Speter 		panic("put");
70769Speter 	}
71769Speter #endif
72769Speter 	switch (op) {
73769Speter 		case O_ABORT:
74769Speter 			cp = "*";
75769Speter 			break;
762221Smckusic 		case O_AS:
772221Smckusic 			switch(p[1]) {
786594Smckusick 			case 0:
796594Smckusick 				break;
802221Smckusic 			case 2:
812221Smckusic 				op = O_AS2;
826594Smckusick 				n = 1;
832221Smckusic 				break;
842221Smckusic 			case 4:
852221Smckusic 				op = O_AS4;
866594Smckusick 				n = 1;
872221Smckusic 				break;
882221Smckusic 			case 8:
892221Smckusic 				op = O_AS8;
906594Smckusick 				n = 1;
912221Smckusic 				break;
922221Smckusic 			default:
932221Smckusic 				goto pack;
942221Smckusic 			}
953077Smckusic #			ifdef DEBUG
963077Smckusic 				cp = otext[op];
973077Smckusic #			endif DEBUG
982221Smckusic 			break;
9910791Smckusick 		case O_FOR1U:
10010791Smckusick 		case O_FOR2U:
10110791Smckusick 		case O_FOR4U:
10210791Smckusick 		case O_FOR1D:
10310791Smckusick 		case O_FOR2D:
10410791Smckusick 		case O_FOR4D:
10510791Smckusick 			/* relative addressing */
10610791Smckusick 			p[1] -= ( unsigned ) lc + sizeof(short);
10710791Smckusick 			/* try to pack the jump */
10810791Smckusick 			if (p[1] <= 127 && p[1] >= -128) {
10910791Smckusick 				suboppr = subop = p[1];
11010791Smckusick 				p++;
11110791Smckusick 				n--;
11210791Smckusick 			} else {
11310791Smckusick 				/* have to allow for extra displacement */
11410791Smckusick 				p[1] -= sizeof(short);
11510791Smckusick 			}
11610791Smckusick 			break;
1173077Smckusic 		case O_CONG:
1183077Smckusic 		case O_LVCON:
1193077Smckusic 		case O_CON:
120769Speter 		case O_LINO:
121769Speter 		case O_NEW:
122769Speter 		case O_DISPOSE:
1237965Smckusick 		case O_DFDISP:
124769Speter 		case O_IND:
125769Speter 		case O_OFF:
126769Speter 		case O_INX2:
127769Speter 		case O_INX4:
128769Speter 		case O_CARD:
129769Speter 		case O_ADDT:
130769Speter 		case O_SUBT:
131769Speter 		case O_MULT:
132769Speter 		case O_IN:
133769Speter 		case O_CASE1OP:
134769Speter 		case O_CASE2OP:
135769Speter 		case O_CASE4OP:
1361199Speter 		case O_FRTN:
137769Speter 		case O_WRITES:
1383173Smckusic 		case O_WRITEC:
139769Speter 		case O_WRITEF:
140769Speter 		case O_MAX:
141769Speter 		case O_MIN:
142769Speter 		case O_ARGV:
143769Speter 		case O_CTTOT:
144769Speter 		case O_INCT:
145769Speter 		case O_RANG2:
146769Speter 		case O_RSNG2:
147769Speter 		case O_RANG42:
148769Speter 		case O_RSNG42:
1492105Smckusic 		case O_SUCC2:
1502105Smckusic 		case O_SUCC24:
1512105Smckusic 		case O_PRED2:
1522105Smckusic 		case O_PRED24:
153769Speter 			if (p[1] == 0)
154769Speter 				break;
155769Speter 		case O_CON2:
156769Speter 		case O_CON24:
1572221Smckusic 		pack:
15810791Smckusick 			if (p[1] <= 127 && p[1] >= -128) {
159769Speter 				suboppr = subop = p[1];
160769Speter 				p++;
161769Speter 				n--;
162769Speter 				if (op == O_CON2) {
163769Speter 					op = O_CON1;
1643077Smckusic #					ifdef DEBUG
1653077Smckusic 						cp = otext[O_CON1];
1663077Smckusic #					endif DEBUG
167769Speter 				}
168769Speter 				if (op == O_CON24) {
169769Speter 					op = O_CON14;
1703077Smckusic #					ifdef DEBUG
1713077Smckusic 						cp = otext[O_CON14];
1723077Smckusic #					endif DEBUG
173769Speter 				}
174769Speter 			}
175769Speter 			break;
176769Speter 		case O_CON8:
177769Speter 		    {
17815208Sthien 			short	*sp = (short *) (&p[1]);
179769Speter 
180769Speter #ifdef	DEBUG
181769Speter 			if ( opt( 'k' ) )
1823317Speter 			    printf ( "%5d\tCON8\t%22.14e\n" ,
183769Speter 					lc - HEADER_BYTES ,
184769Speter 					* ( ( double * ) &p[1] ) );
185769Speter #endif
1863077Smckusic #			ifdef DEC11
1873077Smckusic 			    word(op);
1883077Smckusic #			else
1893077Smckusic 			    word(op << 8);
1903077Smckusic #			endif DEC11
191769Speter 			for ( i = 1 ; i <= 4 ; i ++ )
192769Speter 			    word ( *sp ++ );
193769Speter 			return ( oldlc );
194769Speter 		    }
195769Speter 		default:
196769Speter 			if (op >= O_REL2 && op <= O_REL84) {
1971883Smckusic 				if ((i = (subop >> INDX) * 5 ) >= 30)
198769Speter 					i -= 30;
199769Speter 				else
200769Speter 					i += 2;
201769Speter #ifdef DEBUG
202769Speter 				string = &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i];
203769Speter #endif
204769Speter 				suboppr = 0;
205769Speter 			}
206769Speter 			break;
207769Speter 		case O_IF:
208769Speter 		case O_TRA:
209769Speter /*****
210769Speter 			codeline = 0;
211769Speter *****/
2122184Smckusic 			/* relative addressing */
2132184Smckusic 			p[1] -= ( unsigned ) lc + sizeof(short);
2142184Smckusic 			break;
215769Speter 		case O_CONC:
216769Speter #ifdef DEBUG
217769Speter 			(string = "'x'")[1] = p[1];
218769Speter #endif
219769Speter 			suboppr = 0;
220769Speter 			op = O_CON1;
2213077Smckusic #			ifdef DEBUG
2223077Smckusic 				cp = otext[O_CON1];
2233077Smckusic #			endif DEBUG
224769Speter 			subop = p[1];
225769Speter 			goto around;
226769Speter 		case O_CONC4:
227769Speter #ifdef DEBUG
228769Speter 			(string = "'x'")[1] = p[1];
229769Speter #endif
230769Speter 			suboppr = 0;
231769Speter 			op = O_CON14;
232769Speter 			subop = p[1];
233769Speter 			goto around;
234769Speter 		case O_CON1:
235769Speter 		case O_CON14:
236769Speter 			suboppr = subop = p[1];
237769Speter around:
238769Speter 			n--;
239769Speter 			break;
240769Speter 		case O_CASEBEG:
241769Speter 			casewrd = 0;
242769Speter 			return (oldlc);
243769Speter 		case O_CASEEND:
244769Speter 			if ((unsigned) lc & 1) {
245769Speter 				lc--;
246769Speter 				word(casewrd);
247769Speter 			}
248769Speter 			return (oldlc);
249769Speter 		case O_CASE1:
250769Speter #ifdef DEBUG
251769Speter 			if (opt('k'))
2523317Speter 				printf("%5d\tCASE1\t%d\n"
2533077Smckusic 					, lc - HEADER_BYTES, p[1]);
254769Speter #endif
255769Speter 			/*
256769Speter 			 * this to build a byte size case table
257769Speter 			 * saving bytes across calls in casewrd
258769Speter 			 * so they can be put out by word()
259769Speter 			 */
260769Speter 			lc++;
261769Speter 			if ((unsigned) lc & 1)
2623077Smckusic #				ifdef DEC11
2633077Smckusic 				    casewrd = p[1] & 0377;
2643077Smckusic #				else
2653077Smckusic 				    casewrd = (p[1] & 0377) << 8;
2663077Smckusic #				endif DEC11
267769Speter 			else {
268769Speter 				lc -= 2;
2693077Smckusic #				ifdef DEC11
2703077Smckusic 				    word(((p[1] & 0377) << 8) | casewrd);
2713077Smckusic #				else
2723077Smckusic 				    word((p[1] & 0377) | casewrd);
2733077Smckusic #				endif DEC11
274769Speter 			}
275769Speter 			return (oldlc);
276769Speter 		case O_CASE2:
277769Speter #ifdef DEBUG
278769Speter 			if (opt('k'))
2793317Speter 				printf("%5d\tCASE2\t%d\n"
2803077Smckusic 					, lc - HEADER_BYTES , p[1]);
281769Speter #endif
2823077Smckusic 			word(p[1]);
283769Speter 			return (oldlc);
284769Speter 		case O_PUSH:
2853077Smckusic 			lp = (long *)&p[1];
2863077Smckusic 			if (*lp == 0)
287769Speter 				return (oldlc);
2884025Smckusic 			/* and fall through */
2894025Smckusic 		case O_RANG4:
2904025Smckusic 		case O_RANG24:
2914025Smckusic 		case O_RSNG4:
2924025Smckusic 		case O_RSNG24:
2934025Smckusic 		case O_SUCC4:
2944025Smckusic 		case O_PRED4:
2954025Smckusic 			/* sub opcode optimization */
2964025Smckusic 			lp = (long *)&p[1];
2974025Smckusic 			if (*lp < 128 && *lp >= -128 && *lp != 0) {
2983077Smckusic 				suboppr = subop = *lp;
2994025Smckusic 				p += (sizeof(long) / sizeof(int));
300769Speter 				n--;
301769Speter 			}
302769Speter 			goto longgen;
303769Speter 		case O_TRA4:
304769Speter 		case O_CALL:
3051199Speter 		case O_FSAV:
306769Speter 		case O_GOTO:
307769Speter 		case O_NAM:
308769Speter 		case O_READE:
309769Speter 			/* absolute long addressing */
3103077Smckusic 			lp = (long *)&p[1];
3113077Smckusic 			*lp -= HEADER_BYTES;
312769Speter 			goto longgen;
313769Speter 		case O_RV1:
314769Speter 		case O_RV14:
315769Speter 		case O_RV2:
316769Speter 		case O_RV24:
317769Speter 		case O_RV4:
318769Speter 		case O_RV8:
319769Speter 		case O_RV:
320769Speter 		case O_LV:
3212105Smckusic 			/*
3222105Smckusic 			 * positive offsets represent arguments
3232105Smckusic 			 * and must use "ap" display entry rather
3242105Smckusic 			 * than the "fp" entry
3252105Smckusic 			 */
3262105Smckusic 			if (p[1] >= 0) {
3272105Smckusic 				subop++;
3282105Smckusic 				suboppr++;
3292105Smckusic 			}
3303077Smckusic #			ifdef PDP11
3313077Smckusic 			    break;
3323077Smckusic #			else
3333077Smckusic 			    /*
3343077Smckusic 			     * offsets out of range of word addressing
3353077Smckusic 			     * must use long offset opcodes
3363077Smckusic 			     */
3373077Smckusic 			    if (p[1] < SHORTADDR && p[1] >= -SHORTADDR)
3383077Smckusic 				    break;
3393077Smckusic 			    else {
340769Speter 				op += O_LRV - O_RV;
3413077Smckusic #				ifdef DEBUG
3423077Smckusic 				    cp = otext[op];
3433077Smckusic #				endif DEBUG
3443077Smckusic 			    }
3453077Smckusic 			    /* and fall through */
3463077Smckusic #			endif PDP11
347769Speter 		case O_BEG:
348769Speter 		case O_NODUMP:
349769Speter 		case O_CON4:
350769Speter 		case O_CASE4:
351769Speter 		longgen:
352769Speter 			n = (n << 1) - 1;
35310791Smckusick 			if ( op == O_LRV ) {
354769Speter 				n--;
35510562Smckusick #				if defined(ADDR32) && !defined(DEC11)
35610562Smckusick 				    p[n / 2] <<= 16;
35710562Smckusick #				endif
35810562Smckusick 			}
359769Speter #ifdef DEBUG
3603077Smckusic 			if (opt('k')) {
3613317Speter 				printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
362769Speter 				if (suboppr)
3633077Smckusic 					printf(":%d", suboppr);
3643077Smckusic 				for ( i = 2, lp = (long *)&p[1]; i < n
365769Speter 				    ; i += sizeof ( long )/sizeof ( short ) )
366769Speter 					printf( "\t%D " , *lp ++ );
3673377Speter 				if (i == n) {
3683377Speter 					sp = (short *)lp;
3693377Speter 					printf( "\t%d ", *sp );
3703377Speter 				}
371769Speter 				pchr ( '\n' );
3723077Smckusic 			}
373769Speter #endif
374769Speter 			if ( op != O_CASE4 )
3753077Smckusic #				ifdef DEC11
3763077Smckusic 			    	    word((op & 0377) | subop << 8);
3773077Smckusic #				else
3783077Smckusic 				    word(op << 8 | (subop & 0377));
3793077Smckusic #				endif DEC11
3803077Smckusic 			for ( i = 1, sp = (short *)&p[1]; i < n; i++)
3813077Smckusic 				word ( *sp ++ );
382769Speter 			return ( oldlc );
383769Speter 	}
384769Speter #ifdef DEBUG
385769Speter 	if (opt('k')) {
3863317Speter 		printf("%5d\t%s", lc - HEADER_BYTES, cp+1);
387769Speter 		if (suboppr)
388769Speter 			printf(":%d", suboppr);
389769Speter 		if (string)
390769Speter 			printf("\t%s",string);
391769Speter 		if (n > 1)
392769Speter 			pchr('\t');
393769Speter 		for (i=1; i<n; i++)
3943077Smckusic 			printf("%d ", p[i]);
395769Speter 		pchr('\n');
396769Speter 	}
397769Speter #endif
398769Speter 	if (op != NIL)
3993077Smckusic #		ifdef DEC11
4003077Smckusic 		    word((op & 0377) | subop << 8);
4013077Smckusic #		else
4023077Smckusic 		    word(op << 8 | (subop & 0377));
4033077Smckusic #		endif DEC11
404769Speter 	for (i=1; i<n; i++)
405769Speter 		word(p[i]);
406769Speter 	return (oldlc);
407769Speter }
408769Speter #endif OBJ
409769Speter 
410769Speter /*
411769Speter  * listnames outputs a list of enumerated type names which
412769Speter  * can then be selected from to output a TSCAL
413769Speter  * a pointer to the address in the code of the namelist
414769Speter  * is kept in value[ NL_ELABEL ].
415769Speter  */
416769Speter listnames(ap)
417769Speter 
418769Speter 	register struct nl *ap;
419769Speter {
420769Speter 	struct nl *next;
42115208Sthien #ifdef OBJ
42215208Sthien 	register int oldlc;
42315208Sthien #endif
42415208Sthien 	register int len;
425769Speter 	register unsigned w;
426769Speter 	register char *strptr;
427769Speter 
4283317Speter 	if ( !CGENNING )
429769Speter 		/* code is off - do nothing */
430769Speter 		return(NIL);
431769Speter 	if (ap->class != TYPE)
432769Speter 		ap = ap->type;
433769Speter 	if (ap->value[ NL_ELABEL ] != 0) {
434769Speter 		/* the list already exists */
435769Speter 		return( ap -> value[ NL_ELABEL ] );
436769Speter 	}
437769Speter #	ifdef OBJ
43815208Sthien 	    oldlc = (int) lc; /* same problem as put */
43915208Sthien 	    (void) put(2, O_TRA, lc);
44015208Sthien 	    ap->value[ NL_ELABEL ] = (int) lc;
441769Speter #	endif OBJ
442769Speter #	ifdef PC
44310656Speter 	    putprintf("	.data", 0);
44410656Speter 	    aligndot(A_STRUCT);
44515208Sthien 	    ap -> value[ NL_ELABEL ] = (int) getlab();
44615208Sthien 	    (void) putlab((char *) ap -> value[ NL_ELABEL ] );
447769Speter #	endif PC
448769Speter 	/* number of scalars */
449769Speter 	next = ap->type;
450769Speter 	len = next->range[1]-next->range[0]+1;
451769Speter #	ifdef OBJ
45215208Sthien 	    (void) put(2, O_CASE2, len);
453769Speter #	endif OBJ
454769Speter #	ifdef PC
455769Speter 	    putprintf( "	.word %d" , 0 , len );
456769Speter #	endif PC
457769Speter 	/* offsets of each scalar name */
458769Speter 	len = (len+1)*sizeof(short);
459769Speter #	ifdef OBJ
46015208Sthien 	    (void) put(2, O_CASE2, len);
461769Speter #	endif OBJ
462769Speter #	ifdef PC
463769Speter 	    putprintf( "	.word %d" , 0 , len );
464769Speter #	endif PC
465769Speter 	next = ap->chain;
466769Speter 	do	{
467769Speter 		for(strptr = next->symbol;  *strptr++;  len++)
468769Speter 			continue;
469769Speter 		len++;
470769Speter #		ifdef OBJ
47115208Sthien 		    (void) put(2, O_CASE2, len);
472769Speter #		endif OBJ
473769Speter #		ifdef PC
474769Speter 		    putprintf( "	.word %d" , 0 , len );
475769Speter #		endif PC
476769Speter 	} while (next = next->chain);
477769Speter 	/* list of scalar names */
478769Speter 	strptr = getnext(ap, &next);
479769Speter #	ifdef OBJ
480769Speter 	    do	{
4813077Smckusic #		    ifdef DEC11
4823077Smckusic 			w = (unsigned) *strptr;
4833077Smckusic #		    else
4843077Smckusic 			w = *strptr << 8;
4853077Smckusic #		    endif DEC11
486769Speter 		    if (!*strptr++)
487769Speter 			    strptr = getnext(next, &next);
4883077Smckusic #		    ifdef DEC11
4893077Smckusic 			w |= *strptr << 8;
4903077Smckusic #		    else
4913077Smckusic 			w |= (unsigned) *strptr;
4923077Smckusic #		    endif DEC11
493769Speter 		    if (!*strptr++)
494769Speter 			    strptr = getnext(next, &next);
49515208Sthien 		    word((int) w);
496769Speter 	    } while (next);
497769Speter 	    /* jump over the mess */
49815208Sthien 	    patch((PTR_DCL) oldlc);
499769Speter #	endif OBJ
500769Speter #	ifdef PC
501769Speter 	    while ( next ) {
502769Speter 		while ( *strptr ) {
503769Speter 		    putprintf( "	.byte	0%o" , 1 , *strptr++ );
504769Speter 		    for ( w = 2 ; ( w <= 8 ) && *strptr ; w ++ ) {
505769Speter 			putprintf( ",0%o" , 1 , *strptr++ );
506769Speter 		    }
507769Speter 		    putprintf( "" , 0 );
508769Speter 		}
509769Speter 		putprintf( "	.byte	0" , 0 );
510769Speter 		strptr = getnext( next , &next );
511769Speter 	    }
512769Speter 	    putprintf( "	.text" , 0 );
513769Speter #	endif PC
514769Speter 	return( ap -> value[ NL_ELABEL ] );
515769Speter }
516769Speter 
51715208Sthien char *
518769Speter getnext(next, new)
519769Speter 
520769Speter 	struct nl *next, **new;
521769Speter {
522769Speter 	if (next != NIL) {
523769Speter 		next = next->chain;
524769Speter 		*new = next;
525769Speter 	}
52615208Sthien 	if (next == NLNIL)
527769Speter 		return("");
528769Speter #ifdef OBJ
5293317Speter 	if (opt('k') && CGENNING )
5303317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, next->symbol);
5312213Speter #endif OBJ
532769Speter 	return(next->symbol);
533769Speter }
534769Speter 
535769Speter #ifdef OBJ
536769Speter /*
537769Speter  * Putspace puts out a table
538769Speter  * of nothing to leave space
539769Speter  * for the case branch table e.g.
540769Speter  */
541769Speter putspace(n)
542769Speter 	int n;
543769Speter {
544769Speter 	register i;
545769Speter 
5463317Speter 	if ( !CGENNING )
547769Speter 		/*
548769Speter 		 * code disabled - do nothing
549769Speter 		 */
55015208Sthien 		return;
551769Speter #ifdef DEBUG
552769Speter 	if (opt('k'))
5533317Speter 		printf("%5d\t.=.+%d\n", lc - HEADER_BYTES, n);
554769Speter #endif
555*30036Smckusick 	for (i = n; i > 0; i -= 2)
556769Speter 		word(0);
557769Speter }
558769Speter 
559769Speter putstr(sptr, padding)
560769Speter 
561769Speter 	char *sptr;
562769Speter 	int padding;
563769Speter {
564769Speter 	register unsigned short w;
565769Speter 	register char *strptr = sptr;
566769Speter 	register int pad = padding;
567769Speter 
5683317Speter 	if ( !CGENNING )
569769Speter 		/*
570769Speter 		 * code disabled - do nothing
571769Speter 		 */
57215208Sthien 		return;
573769Speter #ifdef DEBUG
574769Speter 	if (opt('k'))
5753317Speter 		printf("%5d\t\t\"%s\"\n", lc-HEADER_BYTES, strptr);
576769Speter #endif
577769Speter 	if (pad == 0) {
578769Speter 		do	{
5793077Smckusic #			ifdef DEC11
5803077Smckusic 			    w = (unsigned short) * strptr;
5813077Smckusic #			else
5823077Smckusic 			    w = (unsigned short)*strptr<<8;
5833077Smckusic #			endif DEC11
584769Speter 			if (w)
5853077Smckusic #				ifdef DEC11
5863077Smckusic 				    w |= *++strptr << 8;
5873077Smckusic #				else
5883077Smckusic 				    w |= *++strptr;
5893077Smckusic #				endif DEC11
59015208Sthien 			word((int) w);
591769Speter 		} while (*strptr++);
592769Speter 	} else {
5933077Smckusic #		ifdef DEC11
5943077Smckusic 		    do 	{
5953077Smckusic 			    w = (unsigned short) * strptr;
5963077Smckusic 			    if (w) {
5973077Smckusic 				    if (*++strptr)
5983077Smckusic 					    w |= *strptr << 8;
5993077Smckusic 				    else {
60011885Smckusick 					    w |= ' ' << 8;
6013077Smckusic 					    pad--;
6023077Smckusic 				    }
60315208Sthien 				    word((int) w);
6043077Smckusic 			    }
6053077Smckusic 		    } while (*strptr++);
6063077Smckusic #		else
6073077Smckusic 		    do 	{
6083077Smckusic 			    w = (unsigned short)*strptr<<8;
6093077Smckusic 			    if (w) {
6103077Smckusic 				    if (*++strptr)
6113077Smckusic 					    w |= *strptr;
6123077Smckusic 				    else {
6133077Smckusic 					    w |= ' ';
6143077Smckusic 					    pad--;
6153077Smckusic 				    }
6163077Smckusic 				    word(w);
6173077Smckusic 			    }
6183077Smckusic 		    } while (*strptr++);
6193077Smckusic #		endif DEC11
620769Speter 		while (pad > 1) {
62111885Smckusick #			ifdef DEC11
62211885Smckusick 			    word(' ' | (' ' << 8));
62311885Smckusick #			else
62411885Smckusick 			    word((' ' << 8) | ' ');
62511885Smckusick #			endif DEC11
626769Speter 			pad -= 2;
627769Speter 		}
628769Speter 		if (pad == 1)
6293077Smckusic #			ifdef DEC11
6303077Smckusic 			    word(' ');
6313077Smckusic #			else
63211885Smckusick 			    word(' ' << 8);
6333077Smckusic #			endif DEC11
634769Speter 		else
635769Speter 			word(0);
636769Speter 	}
637769Speter }
638769Speter #endif OBJ
639769Speter 
64015208Sthien #ifndef PC
641769Speter lenstr(sptr, padding)
642769Speter 
643769Speter 	char *sptr;
644769Speter 	int padding;
645769Speter 
646769Speter {
647769Speter 	register int cnt;
648769Speter 	register char *strptr = sptr;
649769Speter 
650769Speter 	cnt = padding;
651769Speter 	do	{
652769Speter 		cnt++;
653769Speter 	} while (*strptr++);
654769Speter 	return((++cnt) & ~1);
655769Speter }
65615208Sthien #endif
657769Speter 
658769Speter /*
659769Speter  * Patch repairs the branch
660769Speter  * at location loc to come
661769Speter  * to the current location.
662769Speter  *	for PC, this puts down the label
663769Speter  *	and the branch just references that label.
664769Speter  *	lets here it for two pass assemblers.
665769Speter  */
666769Speter patch(loc)
66715208Sthien     PTR_DCL loc;
668769Speter {
669769Speter 
670769Speter #	ifdef OBJ
6713077Smckusic 	    patchfil(loc, (long)(lc-loc-2), 1);
672769Speter #	endif OBJ
673769Speter #	ifdef PC
67415208Sthien 	    (void) putlab((char *) loc );
675769Speter #	endif PC
676769Speter }
677769Speter 
678769Speter #ifdef OBJ
679769Speter patch4(loc)
68015208Sthien PTR_DCL loc;
681769Speter {
6823077Smckusic 	patchfil(loc, (long)(lc - HEADER_BYTES), 2);
683769Speter }
684769Speter 
685769Speter /*
6867921Smckusick  * Patchfil makes loc+2 have jmploc
687769Speter  * as its contents.
688769Speter  */
6897921Smckusick patchfil(loc, jmploc, words)
690769Speter 	PTR_DCL loc;
6917921Smckusick 	long jmploc;
6923077Smckusic 	int words;
693769Speter {
694769Speter 	register i;
69515208Sthien 	extern long lseek();
69610562Smckusick 	short val;
697769Speter 
6983317Speter 	if ( !CGENNING )
699769Speter 		return;
700769Speter 	if (loc > (unsigned) lc)
701769Speter 		panic("patchfil");
702769Speter #ifdef DEBUG
703769Speter 	if (opt('k'))
7047921Smckusick 		printf("\tpatch %u %D\n", loc - HEADER_BYTES, jmploc);
705769Speter #endif
7067921Smckusick 	val = jmploc;
707769Speter 	do {
7083077Smckusic #		ifndef DEC11
7093077Smckusic 		    if (words > 1)
7107921Smckusick 			    val = jmploc >> 16;
7113077Smckusic 		    else
7127921Smckusick 			    val = jmploc;
7133077Smckusic #		endif DEC11
714769Speter 		i = ((unsigned) loc + 2 - ((unsigned) lc & ~01777))/2;
71510562Smckusick 		if (i >= 0 && i < 1024) {
7163077Smckusic 			obuf[i] = val;
71710562Smckusick 		} else {
71815208Sthien 			(void) lseek(ofil, (long) loc+2, 0);
71915208Sthien 			write(ofil, (char *) (&val), 2);
72015208Sthien 			(void) lseek(ofil, (long) 0, 2);
721769Speter 		}
722769Speter 		loc += 2;
7233077Smckusic #		ifdef DEC11
7247921Smckusick 		    val = jmploc >> 16;
7253077Smckusic #		endif DEC11
726769Speter 	} while (--words);
727769Speter }
728769Speter 
729769Speter /*
730769Speter  * Put the word o into the code
731769Speter  */
732769Speter word(o)
733769Speter 	int o;
734769Speter {
735769Speter 
736769Speter 	*obufp = o;
737769Speter 	obufp++;
738769Speter 	lc += 2;
739769Speter 	if (obufp >= obuf+512)
740769Speter 		pflush();
741769Speter }
742769Speter 
743769Speter extern char	*obj;
744769Speter /*
745769Speter  * Flush the code buffer
746769Speter  */
747769Speter pflush()
748769Speter {
749769Speter 	register i;
750769Speter 
751769Speter 	i = (obufp - ( ( short * ) obuf ) ) * 2;
75215208Sthien 	if (i != 0 && write(ofil, (char *) obuf, i) != i)
753769Speter 		perror(obj), pexit(DIED);
754769Speter 	obufp = obuf;
755769Speter }
756769Speter #endif OBJ
757769Speter 
758769Speter /*
759769Speter  * Getlab - returns the location counter.
760769Speter  * included here for the eventual code generator.
761769Speter  *	for PC, thank you!
762769Speter  */
76315208Sthien char *
764769Speter getlab()
765769Speter {
766769Speter #	ifdef OBJ
767769Speter 
768769Speter 	    return (lc);
769769Speter #	endif OBJ
770769Speter #	ifdef PC
771769Speter 	    static long	lastlabel;
772769Speter 
77315208Sthien 	    return ( (char *) ++lastlabel );
774769Speter #	endif PC
775769Speter }
776769Speter 
777769Speter /*
778769Speter  * Putlab - lay down a label.
779769Speter  *	for PC, just print the label name with a colon after it.
780769Speter  */
78115208Sthien char *
782769Speter putlab(l)
78315208Sthien 	char *l;
784769Speter {
785769Speter 
786769Speter #	ifdef PC
78715208Sthien 	    putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , (int) l );
788769Speter 	    putprintf( ":" , 0 );
789769Speter #	endif PC
790769Speter 	return (l);
791769Speter }
792