xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 3829)
1762Speter /* Copyright (c) 1979 Regents of the University of California */
2762Speter 
3*3829Speter static	char sccsid[] = "@(#)p2put.c 1.9 06/01/81";
4762Speter 
5762Speter     /*
6762Speter      *	functions to help pi put out
7762Speter      *	polish postfix binary portable c compiler intermediate code
8762Speter      *	thereby becoming the portable pascal compiler
9762Speter      */
10762Speter 
11762Speter #include	"whoami.h"
12762Speter #ifdef PC
13762Speter #include	"0.h"
14762Speter #include	"pcops.h"
15762Speter #include	"pc.h"
16762Speter 
17762Speter     /*
18762Speter      *	mash into f77's format
19762Speter      *	lovely, isn't it?
20762Speter      */
21762Speter #define		TOF77( fop,val,rest )	( ( ( (rest) & 0177777 ) << 16 ) \
22762Speter 					| ( ( (val) & 0377 ) << 8 )	 \
23762Speter 					| ( (fop) & 0377 ) )
24762Speter 
25762Speter     /*
26762Speter      *	emits an ftext operator and a string to the pcstream
27762Speter      */
28762Speter puttext( string )
29762Speter     char	*string;
30762Speter     {
31762Speter 	int	length = str4len( string );
32762Speter 
333316Speter 	if ( !CGENNING )
34762Speter 	    return;
35762Speter 	p2word( TOF77( P2FTEXT , length , 0 ) );
36762Speter #	ifdef DEBUG
37762Speter 	    if ( opt( 'k' ) ) {
38762Speter 		fprintf( stdout , "P2FTEXT | %3d | 0	" , length );
39762Speter 	    }
40762Speter #	endif
41762Speter 	p2string( string );
42762Speter     }
43762Speter 
44762Speter int
45762Speter str4len( string )
46762Speter     char	*string;
47762Speter     {
48762Speter 
49762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
50762Speter     }
51762Speter 
52762Speter     /*
53762Speter      *	put formatted text into a buffer for printing to the pcstream.
54762Speter      *	a call to putpflush actually puts out the text.
55762Speter      *	none of arg1 .. arg5 need be present.
56762Speter      *	and you can add more if you need them.
57762Speter      */
58762Speter     /* VARARGS */
59762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
60762Speter     char	*format;
61762Speter     int		incomplete;
62762Speter     {
63762Speter 	static char	ppbuffer[ BUFSIZ ];
64762Speter 	static char	*ppbufp = ppbuffer;
65762Speter 
663316Speter 	if ( !CGENNING )
67762Speter 	    return;
68762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
69762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
70762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
71762Speter 	    panic( "putprintf" );
72762Speter 	if ( ! incomplete ) {
73762Speter 	    puttext( ppbuffer );
74762Speter 	    ppbufp = ppbuffer;
75762Speter 	}
76762Speter     }
77762Speter 
78762Speter     /*
79762Speter      *	emit a left bracket operator to pcstream
80762Speter      *	with function number, the maximum temp register, and total local bytes
81762Speter      *	until i figure out how to use them, regs 0 .. 11 are free.
82762Speter      *	one idea for one reg is to save the display pointer on block entry
83762Speter      */
84762Speter putlbracket( ftnno , localbytes )
85762Speter     int	ftnno;
86762Speter     int	localbytes;
87762Speter     {
88762Speter #	define	MAXTP2REG	11
89762Speter 
90762Speter 	p2word( TOF77( P2FLBRAC , MAXTP2REG , ftnno ) );
91762Speter 	p2word( BITSPERBYTE * localbytes );
92762Speter #	ifdef DEBUG
93762Speter 	    if ( opt( 'k' ) ) {
94762Speter 		fprintf( stdout
95762Speter 			, "P2FLBRAC | %3d | %d	" , MAXTP2REG , ftnno );
96762Speter 		fprintf( stdout , "%d\n"
97762Speter 			, BITSPERBYTE * localbytes );
98762Speter 	    }
99762Speter #	endif
100762Speter     }
101762Speter 
102762Speter     /*
103762Speter      *	emit a right bracket operator
104762Speter      *	which for the binary (fortran) interface
105762Speter      *	forces the stack allocate and register mask
106762Speter      */
107762Speter putrbracket( ftnno )
108762Speter     int	ftnno;
109762Speter     {
110762Speter 
111762Speter 	p2word( TOF77( P2FRBRAC , 0 , ftnno ) );
112762Speter #	ifdef DEBUG
113762Speter 	    if ( opt( 'k' ) ) {
114762Speter 		fprintf( stdout , "P2FRBRAC |   0 | %d\n" , ftnno );
115762Speter 	    }
116762Speter #	endif
117762Speter     }
118762Speter 
119762Speter     /*
120762Speter      *	emit an eof operator
121762Speter      */
122762Speter puteof()
123762Speter     {
124762Speter 
125762Speter 	p2word( P2FEOF );
126762Speter #	ifdef DEBUG
127762Speter 	    if ( opt( 'k' ) ) {
128762Speter 		fprintf( stdout , "P2FEOF\n" );
129762Speter 	    }
130762Speter #	endif
131762Speter     }
132762Speter 
133762Speter     /*
134762Speter      *	emit a dot operator,
135762Speter      *	with a source file line number and name
136762Speter      *	if line is negative, there was an error on that line, but who cares?
137762Speter      */
138762Speter putdot( filename , line )
139762Speter     char	*filename;
140762Speter     int		line;
141762Speter     {
142762Speter 	int	length = str4len( filename );
143762Speter 
144762Speter 	if ( line < 0 ) {
145762Speter 	    line = -line;
146762Speter 	}
147762Speter 	p2word( TOF77( P2FEXPR , length , line ) );
148762Speter #	ifdef DEBUG
149762Speter 	    if ( opt( 'k' ) ) {
150762Speter 		fprintf( stdout , "P2FEXPR | %3d | %d	" , length , line );
151762Speter 	    }
152762Speter #	endif
153762Speter 	p2string( filename );
154762Speter     }
155762Speter 
156762Speter     /*
157762Speter      *	put out a leaf node
158762Speter      */
159762Speter putleaf( op , lval , rval , type , name )
160762Speter     int		op;
161762Speter     int		lval;
162762Speter     int		rval;
163762Speter     int		type;
164762Speter     char	*name;
165762Speter     {
1663316Speter 	if ( !CGENNING )
167762Speter 	    return;
168762Speter 	switch ( op ) {
169762Speter 	    default:
170762Speter 		panic( "[putleaf]" );
171762Speter 	    case P2ICON:
172762Speter 		p2word( TOF77( P2ICON , name != NIL , type ) );
173762Speter 		p2word( lval );
174762Speter #		ifdef DEBUG
175762Speter 		    if ( opt( 'k' ) ) {
1762474Speter 			fprintf( stdout , "P2ICON | %3d | 0x%x	"
177762Speter 			       , name != NIL , type );
178762Speter 			fprintf( stdout , "%d\n" , lval );
179762Speter 		    }
180762Speter #		endif
181762Speter 		if ( name )
182762Speter 		    p2name( name );
183762Speter 		break;
184762Speter 	    case P2NAME:
185762Speter 		p2word( TOF77( P2NAME , lval != 0 , type ) );
186762Speter 		if ( lval )
187762Speter 		    p2word( lval );
188762Speter #		ifdef DEBUG
189762Speter 		    if ( opt( 'k' ) ) {
1902474Speter 			fprintf( stdout , "P2NAME | %3d | 0x%x	"
191762Speter 			       , lval != 0 , type );
192762Speter 			if ( lval )
193762Speter 			    fprintf( stdout , "%d	" , lval );
194762Speter 		    }
195762Speter #		endif
196762Speter 		p2name( name );
197762Speter 		break;
198762Speter 	    case P2REG:
199762Speter 		p2word( TOF77( P2REG , rval , type ) );
200762Speter #		ifdef DEBUG
201762Speter 		    if ( opt( 'k' ) ) {
2022474Speter 			fprintf( stdout , "P2REG | %3d | 0x%x\n" ,
2032474Speter 				rval , type );
204762Speter 		    }
205762Speter #		endif
206762Speter 		break;
207762Speter 	}
208762Speter     }
209762Speter 
210762Speter     /*
211762Speter      *	rvalues are just lvalues with indirection, except
212*3829Speter      *	special cases for registers and for named globals,
213*3829Speter      *	whose names are their rvalues.
214762Speter      */
215*3829Speter putRV( name , level , offset , extra_flags , type )
216762Speter     char	*name;
217762Speter     int		level;
218762Speter     int		offset;
219*3829Speter     char	extra_flags;
220762Speter     int		type;
221762Speter     {
222762Speter 	char	extname[ BUFSIZ ];
223762Speter 	char	*printname;
2243582Speter 	int	regnumber;
225762Speter 
2263316Speter 	if ( !CGENNING )
227762Speter 	    return;
228*3829Speter 	if ( extra_flags & NREGVAR ) {
229*3829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
230*3829Speter 		panic( "putRV regvar" );
2313582Speter 	    }
232*3829Speter 	    putleaf( P2REG , 0 , offset , type , 0 );
2333277Smckusic 	    return;
2343277Smckusic 	}
235*3829Speter 	if ( whereis( level , offset , extra_flags ) == GLOBALVAR ) {
236*3829Speter 	    if ( name != 0 ) {
237*3829Speter 		if ( name[0] != '_' ) {
238*3829Speter 			sprintf( extname , EXTFORMAT , name );
239*3829Speter 			printname = extname;
240*3829Speter 		} else {
241*3829Speter 			printname = name;
242*3829Speter 		}
243*3829Speter 		putleaf( P2NAME , offset , 0 , type , printname );
244*3829Speter 		return;
245762Speter 	    } else {
246*3829Speter 		panic( "putRV no name" );
247762Speter 	    }
248762Speter 	}
249*3829Speter 	putLV( name , level , offset , extra_flags , type );
250762Speter 	putop( P2UNARY P2MUL , type );
251762Speter     }
252762Speter 
253762Speter     /*
254762Speter      *	put out an lvalue
255762Speter      *	given a level and offset
256762Speter      *	special case for
257762Speter      *	    named globals, whose lvalues are just their names as constants.
258762Speter      */
259*3829Speter putLV( name , level , offset , extra_flags , type )
260762Speter     char	*name;
261762Speter     int		level;
262762Speter     int		offset;
263*3829Speter     char	extra_flags;
264762Speter     int		type;
2653277Smckusic {
2663277Smckusic     char		extname[ BUFSIZ ];
2673277Smckusic     char		*printname;
268762Speter 
2693316Speter     if ( !CGENNING )
2703277Smckusic 	return;
271*3829Speter     if ( extra_flags & NREGVAR ) {
272*3829Speter 	panic( "putLV regvar" );
273762Speter     }
274*3829Speter     switch ( whereis( level , offset , extra_flags ) ) {
275*3829Speter 	case GLOBALVAR:
276*3829Speter 	    if ( ( name != 0 ) ) {
277*3829Speter 		if ( name[0] != '_' ) {
278*3829Speter 			sprintf( extname , EXTFORMAT , name );
279*3829Speter 			printname = extname;
280*3829Speter 		} else {
281*3829Speter 			printname = name;
282*3829Speter 		}
283*3829Speter 		putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR )
284*3829Speter 			, printname );
285*3829Speter 		return;
286*3829Speter 	    } else {
287*3829Speter 		panic( "putLV no name" );
288*3829Speter 	    }
2893277Smckusic 	case PARAMVAR:
2903277Smckusic 	    if ( level == cbn ) {
2913277Smckusic 		putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 );
2923277Smckusic 	    } else {
2933277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
2943277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
2953277Smckusic 	    }
2963277Smckusic 	    putleaf( P2ICON , offset , 0 , P2INT , 0 );
2973277Smckusic 	    putop( P2PLUS , P2PTR | P2CHAR );
2983277Smckusic 	    break;
2993277Smckusic 	case LOCALVAR:
3003277Smckusic 	    if ( level == cbn ) {
3013277Smckusic 		putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 );
3023277Smckusic 	    } else {
3033277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
3043277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3053277Smckusic 	    }
3063277Smckusic 	    putleaf( P2ICON , -offset , 0 , P2INT , 0 );
3073277Smckusic 	    putop( P2MINUS , P2PTR | P2CHAR );
3083277Smckusic 	    break;
3093277Smckusic     }
3103277Smckusic     return;
3113277Smckusic }
312762Speter 
313762Speter     /*
314762Speter      *	put out a floating point constant leaf node
315762Speter      *	the constant is declared in aligned data space
316762Speter      *	and a P2NAME leaf put out for it
317762Speter      */
318762Speter putCON8( value )
319762Speter     double	value;
320762Speter     {
321762Speter 	int	label;
322762Speter 	char	name[ BUFSIZ ];
323762Speter 
3243316Speter 	if ( !CGENNING )
325762Speter 	    return;
326762Speter 	putprintf( "	.data" , 0 );
327762Speter 	putprintf( "	.align 2" , 0 );
328762Speter 	label = getlab();
329762Speter 	putlab( label );
330762Speter 	putprintf( "	.double 0d%.20e" , 0 , value );
331762Speter 	putprintf( "	.text" , 0 );
332762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
333762Speter 	putleaf( P2NAME , 0 , 0 , P2DOUBLE , name );
334762Speter     }
335762Speter 
336762Speter 	/*
337762Speter 	 * put out either an lvalue or an rvalue for a constant string.
338762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
339762Speter 	 * an rvalue (for parameters) is just the name.
340762Speter 	 */
341762Speter putCONG( string , length , required )
342762Speter     char	*string;
343762Speter     int		length;
344762Speter     int		required;
345762Speter     {
346762Speter 	char	name[ BUFSIZ ];
347762Speter 	int	label;
348762Speter 	char	*cp;
349762Speter 	int	pad;
350762Speter 	int	others;
351762Speter 
3523316Speter 	if ( !CGENNING )
353762Speter 	    return;
354762Speter 	putprintf( "	.data" , 0 );
355762Speter 	label = getlab();
356762Speter 	putlab( label );
357762Speter 	cp = string;
358762Speter 	while ( *cp ) {
359762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
360762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
361762Speter 		putprintf( ",0%o" , 1 , *cp++ );
362762Speter 	    }
363762Speter 	    putprintf( "" , 0 );
364762Speter 	}
365762Speter 	pad = length - strlen( string );
366762Speter 	while ( pad-- > 0 ) {
367762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
368762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
369762Speter 		putprintf( ",0%o" , 1 , ' ' );
370762Speter 	    }
371762Speter 	    putprintf( "" , 0 );
372762Speter 	}
373762Speter 	putprintf( "	.byte	0" , 0 );
374762Speter 	putprintf( "	.text"  , 0 );
375762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
376762Speter 	if ( required == RREQ ) {
377762Speter 	    putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name );
378762Speter 	} else {
379762Speter 	    putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name );
380762Speter 	}
381762Speter     }
382762Speter 
383762Speter     /*
384762Speter      *	map a pascal type to a c type
385762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
386762Speter      *	this is sort of like isa and lwidth
387762Speter      *	a note on the types used by the portable c compiler:
388762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
389762Speter      *	    and qualifications on those basic types (pointer, function, array).
390762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
391762Speter      *	    and the qualifications are arranged in two bit chunks, with the
392762Speter      *	    most significant on the right,
393762Speter      *	    and the least significant on the left
394762Speter      *		e.g. int *foo();
395762Speter      *			(a function returning a pointer to an integer)
396762Speter      *		is stored as
397762Speter      *		    <ptr><ftn><int>
398762Speter      *	so, we build types recursively
3991478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4001478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4011478Speter      *	through mutually recursive pointer types.
402762Speter      */
4031478Speter #define	MAXQUALS	6
404762Speter int
405762Speter p2type( np )
4061478Speter {
4071478Speter 
4081478Speter     return typerecur( np , 0 );
4091478Speter }
4101478Speter typerecur( np , quals )
4111478Speter     struct nl	*np;
4121478Speter     int		quals;
413762Speter     {
414762Speter 
4151478Speter 	if ( np == NIL || quals > MAXQUALS ) {
4161478Speter 	    return P2UNDEF;
4171478Speter 	}
418762Speter 	switch ( np -> class ) {
419762Speter 	    case SCAL :
420762Speter 	    case RANGE :
421762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
422762Speter 		    return P2DOUBLE;
423762Speter 		}
424762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
425762Speter 		    case 1:
426762Speter 			return P2CHAR;
427762Speter 		    case 2:
428762Speter 			return P2SHORT;
429762Speter 		    case 4:
430762Speter 			return P2INT;
431762Speter 		    default:
432762Speter 			panic( "p2type int" );
433762Speter 		}
434762Speter 	    case STR :
435762Speter 		return ( P2ARY | P2CHAR );
436762Speter 	    case RECORD :
437762Speter 	    case SET :
438762Speter 		return P2STRTY;
439762Speter 	    case FILET :
440762Speter 		return ( P2PTR | P2STRTY );
441762Speter 	    case CONST :
442762Speter 	    case VAR :
443762Speter 	    case FIELD :
444762Speter 		return p2type( np -> type );
445762Speter 	    case TYPE :
446762Speter 		switch ( nloff( np ) ) {
447762Speter 		    case TNIL :
4481478Speter 			return ( P2PTR | P2UNDEF );
449762Speter 		    case TSTR :
450762Speter 			return ( P2ARY | P2CHAR );
451762Speter 		    case TSET :
452762Speter 			return P2STRTY;
453762Speter 		    default :
454762Speter 			return ( p2type( np -> type ) );
455762Speter 		}
456762Speter 	    case REF:
457762Speter 	    case WITHPTR:
458762Speter 	    case PTR :
4591478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR );
460762Speter 	    case ARRAY :
4611478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY );
462762Speter 	    case FUNC :
463762Speter 		    /*
464762Speter 		     * functions are really pointers to functions
465762Speter 		     * which return their underlying type.
466762Speter 		     */
4671478Speter 		return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) ,
4681478Speter 					P2FTN ) , P2PTR );
469762Speter 	    case PROC :
470762Speter 		    /*
471762Speter 		     * procedures are pointers to functions
472762Speter 		     * which return integers (whether you look at them or not)
473762Speter 		     */
474762Speter 		return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR );
4751197Speter 	    case FFUNC :
4761197Speter 	    case FPROC :
4771197Speter 		    /*
4781197Speter 		     *	formal procedures and functions are pointers
4791197Speter 		     *	to structures which describe their environment.
4801197Speter 		     */
4812474Speter 		return ( P2PTR | P2STRTY );
482762Speter 	    default :
483762Speter 		panic( "p2type" );
484762Speter 	}
485762Speter     }
486762Speter 
487762Speter     /*
488762Speter      *	add a most significant type modifier to a type
489762Speter      */
490762Speter long
491762Speter addtype( underlying , mtype )
492762Speter     long	underlying;
493762Speter     long	mtype;
494762Speter     {
495762Speter 	return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT )
496762Speter 	       | mtype
497762Speter 	       | ( underlying & P2BASETYPE ) );
498762Speter     }
499762Speter 
500762Speter     /*
501762Speter      *	put a typed operator to the pcstream
502762Speter      */
503762Speter putop( op , type )
504762Speter     int		op;
505762Speter     int		type;
506762Speter     {
507762Speter 	extern char	*p2opnames[];
508762Speter 
5093316Speter 	if ( !CGENNING )
510762Speter 	    return;
511762Speter 	p2word( TOF77( op , 0 , type ) );
512762Speter #	ifdef DEBUG
513762Speter 	    if ( opt( 'k' ) ) {
5142474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
515762Speter 			, p2opnames[ op ] , op , type );
516762Speter 	    }
517762Speter #	endif
518762Speter     }
519762Speter 
520762Speter     /*
521762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
522762Speter      *	which looks just like a regular operator, only the size and
523762Speter      *	alignment go in the next consecutive words
524762Speter      */
525762Speter putstrop( op , type , size , alignment )
526762Speter     int	op;
527762Speter     int	type;
528762Speter     int	size;
529762Speter     int	alignment;
530762Speter     {
531762Speter 	extern char	*p2opnames[];
532762Speter 
5333316Speter 	if ( !CGENNING )
534762Speter 	    return;
535762Speter 	p2word( TOF77( op , 0 , type ) );
536762Speter 	p2word( size );
537762Speter 	p2word( alignment );
538762Speter #	ifdef DEBUG
539762Speter 	    if ( opt( 'k' ) ) {
5402474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
541762Speter 			, p2opnames[ op ] , op , type , size , alignment );
542762Speter 	    }
543762Speter #	endif
544762Speter     }
545762Speter 
546762Speter     /*
547762Speter      *	the string names of p2ops
548762Speter      */
549762Speter char	*p2opnames[] = {
550762Speter 	"",
551762Speter 	"P2UNDEFINED",		/* 1 */
552762Speter 	"P2NAME",		/* 2 */
553762Speter 	"P2STRING",		/* 3 */
554762Speter 	"P2ICON",		/* 4 */
555762Speter 	"P2FCON",		/* 5 */
556762Speter 	"P2PLUS",		/* 6 */
557762Speter 	"",
558762Speter 	"P2MINUS",		/* 8		also unary == P2NEG */
559762Speter 	"",
560762Speter 	"P2NEG",
561762Speter 	"P2MUL",		/* 11		also unary == P2INDIRECT */
562762Speter 	"",
563762Speter 	"P2INDIRECT",
564762Speter 	"P2AND",		/* 14		also unary == P2ADDROF */
565762Speter 	"",
566762Speter 	"P2ADDROF",
567762Speter 	"P2OR",			/* 17 */
568762Speter 	"",
569762Speter 	"P2ER",			/* 19 */
570762Speter 	"",
571762Speter 	"P2QUEST",		/* 21 */
572762Speter 	"P2COLON",		/* 22 */
573762Speter 	"P2ANDAND",		/* 23 */
574762Speter 	"P2OROR",		/* 24 */
575762Speter 	"",			/* 25 */
576762Speter 	"",			/* 26 */
577762Speter 	"",			/* 27 */
578762Speter 	"",			/* 28 */
579762Speter 	"",			/* 29 */
580762Speter 	"",			/* 30 */
581762Speter 	"",			/* 31 */
582762Speter 	"",			/* 32 */
583762Speter 	"",			/* 33 */
584762Speter 	"",			/* 34 */
585762Speter 	"",			/* 35 */
586762Speter 	"",			/* 36 */
587762Speter 	"",			/* 37 */
588762Speter 	"",			/* 38 */
589762Speter 	"",			/* 39 */
590762Speter 	"",			/* 40 */
591762Speter 	"",			/* 41 */
592762Speter 	"",			/* 42 */
593762Speter 	"",			/* 43 */
594762Speter 	"",			/* 44 */
595762Speter 	"",			/* 45 */
596762Speter 	"",			/* 46 */
597762Speter 	"",			/* 47 */
598762Speter 	"",			/* 48 */
599762Speter 	"",			/* 49 */
600762Speter 	"",			/* 50 */
601762Speter 	"",			/* 51 */
602762Speter 	"",			/* 52 */
603762Speter 	"",			/* 53 */
604762Speter 	"",			/* 54 */
605762Speter 	"",			/* 55 */
606762Speter 	"P2LISTOP",		/* 56 */
607762Speter 	"",
608762Speter 	"P2ASSIGN",		/* 58 */
609762Speter 	"P2COMOP",		/* 59 */
610762Speter 	"P2DIV",		/* 60 */
611762Speter 	"",
612762Speter 	"P2MOD",		/* 62 */
613762Speter 	"",
614762Speter 	"P2LS",			/* 64 */
615762Speter 	"",
616762Speter 	"P2RS",			/* 66 */
617762Speter 	"",
618762Speter 	"P2DOT",		/* 68 */
619762Speter 	"P2STREF",		/* 69 */
620762Speter 	"P2CALL",		/* 70		also unary */
621762Speter 	"",
622762Speter 	"P2UNARYCALL",
623762Speter 	"P2FORTCALL",		/* 73		also unary */
624762Speter 	"",
625762Speter 	"P2UNARYFORTCALL",
626762Speter 	"P2NOT",		/* 76 */
627762Speter 	"P2COMPL",		/* 77 */
628762Speter 	"P2INCR",		/* 78 */
629762Speter 	"P2DECR",		/* 79 */
630762Speter 	"P2EQ",			/* 80 */
631762Speter 	"P2NE",			/* 81 */
632762Speter 	"P2LE",			/* 82 */
633762Speter 	"P2LT",			/* 83 */
634762Speter 	"P2GE",			/* 84 */
635762Speter 	"P2GT",			/* 85 */
636762Speter 	"P2ULE",		/* 86 */
637762Speter 	"P2ULT",		/* 87 */
638762Speter 	"P2UGE",		/* 88 */
639762Speter 	"P2UGT",		/* 89 */
640762Speter 	"P2SETBIT",		/* 90 */
641762Speter 	"P2TESTBIT",		/* 91 */
642762Speter 	"P2RESETBIT",		/* 92 */
643762Speter 	"P2ARS",		/* 93 */
644762Speter 	"P2REG",		/* 94 */
645762Speter 	"P2OREG",		/* 95 */
646762Speter 	"P2CCODES",		/* 96 */
647762Speter 	"P2FREE",		/* 97 */
648762Speter 	"P2STASG",		/* 98 */
649762Speter 	"P2STARG",		/* 99 */
650762Speter 	"P2STCALL",		/* 100		also unary */
651762Speter 	"",
652762Speter 	"P2UNARYSTCALL",
653762Speter 	"P2FLD",		/* 103 */
654762Speter 	"P2SCONV",		/* 104 */
655762Speter 	"P2PCONV",		/* 105 */
656762Speter 	"P2PMCONV",		/* 106 */
657762Speter 	"P2PVCONV",		/* 107 */
658762Speter 	"P2FORCE",		/* 108 */
659762Speter 	"P2CBRANCH",		/* 109 */
660762Speter 	"P2INIT",		/* 110 */
661762Speter 	"P2CAST",		/* 111 */
662762Speter     };
663762Speter 
664762Speter     /*
665762Speter      *	low level routines
666762Speter      */
667762Speter 
668762Speter     /*
669762Speter      *	puts a long word on the pcstream
670762Speter      */
671762Speter p2word( word )
672762Speter     long	word;
673762Speter     {
674762Speter 
675762Speter 	putw( word , pcstream );
676762Speter     }
677762Speter 
678762Speter     /*
679762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
680762Speter      */
681762Speter p2string( string )
682762Speter     char	*string;
683762Speter     {
684762Speter 	int	slen = strlen( string );
685762Speter 	int	wlen = ( slen + 3 ) / 4;
686762Speter 	int	plen = ( wlen * 4 ) - slen;
687762Speter 	char	*cp;
688762Speter 	int	p;
689762Speter 
690762Speter 	for ( cp = string ; *cp ; cp++ )
691762Speter 	    putc( *cp , pcstream );
692762Speter 	for ( p = 1 ; p <= plen ; p++ )
693762Speter 	    putc( '\0' , pcstream );
694762Speter #	ifdef DEBUG
695762Speter 	    if ( opt( 'k' ) ) {
696762Speter 		fprintf( stdout , "\"%s" , string );
697762Speter 		for ( p = 1 ; p <= plen ; p++ )
698762Speter 		    fprintf( stdout , "\\0" );
699762Speter 		fprintf( stdout , "\"\n" );
700762Speter 	    }
701762Speter #	endif
702762Speter     }
703762Speter 
704762Speter     /*
705762Speter      *	puts a name on the pcstream
706762Speter      */
707762Speter p2name( name )
708762Speter     char	*name;
709762Speter     {
710762Speter 	int	pad;
711762Speter 
712762Speter 	fprintf( pcstream , NAMEFORMAT , name );
713762Speter 	pad = strlen( name ) % sizeof (long);
714762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
715762Speter 	    putc( '\0' , pcstream );
716762Speter 	}
717762Speter #	ifdef DEBUG
718762Speter 	    if ( opt( 'k' ) ) {
719762Speter 		fprintf( stdout , NAMEFORMAT , name );
720762Speter 		pad = strlen( name ) % sizeof (long);
721762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
722762Speter 		    fprintf( stdout , "\\0" );
723762Speter 		}
724762Speter 		fprintf( stdout , "\n" );
725762Speter 	    }
726762Speter #	endif
727762Speter     }
728762Speter 
729762Speter     /*
730762Speter      *	put out a jump to a label
731762Speter      */
732762Speter putjbr( label )
733762Speter     long	label;
734762Speter     {
735762Speter 
736762Speter 	printjbr( LABELPREFIX , label );
737762Speter     }
738762Speter 
739762Speter     /*
740762Speter      *	put out a jump to any kind of label
741762Speter      */
742762Speter printjbr( prefix , label )
743762Speter     char	*prefix;
744762Speter     long	label;
745762Speter     {
746762Speter 
747762Speter 	putprintf( "	jbr	" , 1 );
748762Speter 	putprintf( PREFIXFORMAT , 0 , prefix , label );
749762Speter     }
750762Speter 
751762Speter     /*
752762Speter      *	another version of put to catch calls to put
753762Speter      */
754762Speter put( arg1 , arg2 )
755762Speter     {
756762Speter 
757762Speter 	putprintf( "#	PUT CALLED!: arg1 = %d arg2 = 0%o" , 0 , arg1 , arg2 );
758762Speter     }
759762Speter 
760762Speter #endif PC
761