xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 10653)
1762Speter /* Copyright (c) 1979 Regents of the University of California */
2762Speter 
3*10653Speter static	char sccsid[] = "@(#)p2put.c 1.12 02/01/83";
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"
14*10653Speter #include	"objfmt.h"
15762Speter #include	"pcops.h"
16762Speter #include	"pc.h"
17*10653Speter #include	"align.h"
18762Speter 
19762Speter     /*
20762Speter      *	mash into f77's format
21762Speter      *	lovely, isn't it?
22762Speter      */
23762Speter #define		TOF77( fop,val,rest )	( ( ( (rest) & 0177777 ) << 16 ) \
24762Speter 					| ( ( (val) & 0377 ) << 8 )	 \
25762Speter 					| ( (fop) & 0377 ) )
26762Speter 
27762Speter     /*
28762Speter      *	emits an ftext operator and a string to the pcstream
29762Speter      */
30762Speter puttext( string )
31762Speter     char	*string;
32762Speter     {
33762Speter 	int	length = str4len( string );
34762Speter 
353316Speter 	if ( !CGENNING )
36762Speter 	    return;
37762Speter 	p2word( TOF77( P2FTEXT , length , 0 ) );
38762Speter #	ifdef DEBUG
39762Speter 	    if ( opt( 'k' ) ) {
40762Speter 		fprintf( stdout , "P2FTEXT | %3d | 0	" , length );
41762Speter 	    }
42762Speter #	endif
43762Speter 	p2string( string );
44762Speter     }
45762Speter 
46762Speter int
47762Speter str4len( string )
48762Speter     char	*string;
49762Speter     {
50762Speter 
51762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
52762Speter     }
53762Speter 
54762Speter     /*
55762Speter      *	put formatted text into a buffer for printing to the pcstream.
56762Speter      *	a call to putpflush actually puts out the text.
57762Speter      *	none of arg1 .. arg5 need be present.
58762Speter      *	and you can add more if you need them.
59762Speter      */
60762Speter     /* VARARGS */
61762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
62762Speter     char	*format;
63762Speter     int		incomplete;
64762Speter     {
65762Speter 	static char	ppbuffer[ BUFSIZ ];
66762Speter 	static char	*ppbufp = ppbuffer;
67762Speter 
683316Speter 	if ( !CGENNING )
69762Speter 	    return;
70762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
71762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
72762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
73762Speter 	    panic( "putprintf" );
74762Speter 	if ( ! incomplete ) {
75762Speter 	    puttext( ppbuffer );
76762Speter 	    ppbufp = ppbuffer;
77762Speter 	}
78762Speter     }
79762Speter 
80762Speter     /*
81762Speter      *	emit a left bracket operator to pcstream
82762Speter      *	with function number, the maximum temp register, and total local bytes
83762Speter      *	until i figure out how to use them, regs 0 .. 11 are free.
84762Speter      *	one idea for one reg is to save the display pointer on block entry
85762Speter      */
86762Speter putlbracket( ftnno , localbytes )
87762Speter     int	ftnno;
88762Speter     int	localbytes;
89762Speter     {
90762Speter #	define	MAXTP2REG	11
91762Speter 
92762Speter 	p2word( TOF77( P2FLBRAC , MAXTP2REG , ftnno ) );
93*10653Speter 	p2word( roundup(BITSPERBYTE * localbytes, BITSPERBYTE * A_STACK));
94762Speter #	ifdef DEBUG
95762Speter 	    if ( opt( 'k' ) ) {
96762Speter 		fprintf( stdout
97762Speter 			, "P2FLBRAC | %3d | %d	" , MAXTP2REG , ftnno );
98762Speter 		fprintf( stdout , "%d\n"
99762Speter 			, BITSPERBYTE * localbytes );
100762Speter 	    }
101762Speter #	endif
102762Speter     }
103762Speter 
104762Speter     /*
105762Speter      *	emit a right bracket operator
106762Speter      *	which for the binary (fortran) interface
107762Speter      *	forces the stack allocate and register mask
108762Speter      */
109762Speter putrbracket( ftnno )
110762Speter     int	ftnno;
111762Speter     {
112762Speter 
113762Speter 	p2word( TOF77( P2FRBRAC , 0 , ftnno ) );
114762Speter #	ifdef DEBUG
115762Speter 	    if ( opt( 'k' ) ) {
116762Speter 		fprintf( stdout , "P2FRBRAC |   0 | %d\n" , ftnno );
117762Speter 	    }
118762Speter #	endif
119762Speter     }
120762Speter 
121762Speter     /*
122762Speter      *	emit an eof operator
123762Speter      */
124762Speter puteof()
125762Speter     {
126762Speter 
127762Speter 	p2word( P2FEOF );
128762Speter #	ifdef DEBUG
129762Speter 	    if ( opt( 'k' ) ) {
130762Speter 		fprintf( stdout , "P2FEOF\n" );
131762Speter 	    }
132762Speter #	endif
133762Speter     }
134762Speter 
135762Speter     /*
136762Speter      *	emit a dot operator,
137762Speter      *	with a source file line number and name
138762Speter      *	if line is negative, there was an error on that line, but who cares?
139762Speter      */
140762Speter putdot( filename , line )
141762Speter     char	*filename;
142762Speter     int		line;
143762Speter     {
144762Speter 	int	length = str4len( filename );
145762Speter 
146762Speter 	if ( line < 0 ) {
147762Speter 	    line = -line;
148762Speter 	}
149762Speter 	p2word( TOF77( P2FEXPR , length , line ) );
150762Speter #	ifdef DEBUG
151762Speter 	    if ( opt( 'k' ) ) {
152762Speter 		fprintf( stdout , "P2FEXPR | %3d | %d	" , length , line );
153762Speter 	    }
154762Speter #	endif
155762Speter 	p2string( filename );
156762Speter     }
157762Speter 
158762Speter     /*
159762Speter      *	put out a leaf node
160762Speter      */
161762Speter putleaf( op , lval , rval , type , name )
162762Speter     int		op;
163762Speter     int		lval;
164762Speter     int		rval;
165762Speter     int		type;
166762Speter     char	*name;
167762Speter     {
1683316Speter 	if ( !CGENNING )
169762Speter 	    return;
170762Speter 	switch ( op ) {
171762Speter 	    default:
172762Speter 		panic( "[putleaf]" );
173762Speter 	    case P2ICON:
174762Speter 		p2word( TOF77( P2ICON , name != NIL , type ) );
175762Speter 		p2word( lval );
176762Speter #		ifdef DEBUG
177762Speter 		    if ( opt( 'k' ) ) {
1782474Speter 			fprintf( stdout , "P2ICON | %3d | 0x%x	"
179762Speter 			       , name != NIL , type );
180762Speter 			fprintf( stdout , "%d\n" , lval );
181762Speter 		    }
182762Speter #		endif
183762Speter 		if ( name )
184762Speter 		    p2name( name );
185762Speter 		break;
186762Speter 	    case P2NAME:
187762Speter 		p2word( TOF77( P2NAME , lval != 0 , type ) );
188762Speter 		if ( lval )
189762Speter 		    p2word( lval );
190762Speter #		ifdef DEBUG
191762Speter 		    if ( opt( 'k' ) ) {
1922474Speter 			fprintf( stdout , "P2NAME | %3d | 0x%x	"
193762Speter 			       , lval != 0 , type );
194762Speter 			if ( lval )
195762Speter 			    fprintf( stdout , "%d	" , lval );
196762Speter 		    }
197762Speter #		endif
198762Speter 		p2name( name );
199762Speter 		break;
200762Speter 	    case P2REG:
201762Speter 		p2word( TOF77( P2REG , rval , type ) );
202762Speter #		ifdef DEBUG
203762Speter 		    if ( opt( 'k' ) ) {
2042474Speter 			fprintf( stdout , "P2REG | %3d | 0x%x\n" ,
2052474Speter 				rval , type );
206762Speter 		    }
207762Speter #		endif
208762Speter 		break;
209762Speter 	}
210762Speter     }
211762Speter 
212762Speter     /*
213762Speter      *	rvalues are just lvalues with indirection, except
2143829Speter      *	special cases for registers and for named globals,
2153829Speter      *	whose names are their rvalues.
216762Speter      */
2177924Smckusick putRV( name , level , offset , other_flags , type )
218762Speter     char	*name;
219762Speter     int		level;
220762Speter     int		offset;
2217924Smckusick     char	other_flags;
222762Speter     int		type;
223762Speter     {
224762Speter 	char	extname[ BUFSIZ ];
225762Speter 	char	*printname;
2263582Speter 	int	regnumber;
227762Speter 
2283316Speter 	if ( !CGENNING )
229762Speter 	    return;
2307924Smckusick 	if ( other_flags & NREGVAR ) {
2313829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
2323829Speter 		panic( "putRV regvar" );
2333582Speter 	    }
2343829Speter 	    putleaf( P2REG , 0 , offset , type , 0 );
2353277Smckusic 	    return;
2363277Smckusic 	}
2377924Smckusick 	if ( whereis( level , offset , other_flags ) == GLOBALVAR ) {
2383829Speter 	    if ( name != 0 ) {
2393829Speter 		if ( name[0] != '_' ) {
2403829Speter 			sprintf( extname , EXTFORMAT , name );
2413829Speter 			printname = extname;
2423829Speter 		} else {
2433829Speter 			printname = name;
2443829Speter 		}
2453829Speter 		putleaf( P2NAME , offset , 0 , type , printname );
2463829Speter 		return;
247762Speter 	    } else {
2483829Speter 		panic( "putRV no name" );
249762Speter 	    }
250762Speter 	}
2517924Smckusick 	putLV( name , level , offset , other_flags , type );
252762Speter 	putop( P2UNARY P2MUL , type );
253762Speter     }
254762Speter 
255762Speter     /*
256762Speter      *	put out an lvalue
257762Speter      *	given a level and offset
258762Speter      *	special case for
259762Speter      *	    named globals, whose lvalues are just their names as constants.
260762Speter      */
2617924Smckusick putLV( name , level , offset , other_flags , type )
262762Speter     char	*name;
263762Speter     int		level;
264762Speter     int		offset;
2657924Smckusick     char	other_flags;
266762Speter     int		type;
2673277Smckusic {
2683277Smckusic     char		extname[ BUFSIZ ];
2693277Smckusic     char		*printname;
270762Speter 
2713316Speter     if ( !CGENNING )
2723277Smckusic 	return;
2737924Smckusick     if ( other_flags & NREGVAR ) {
2743829Speter 	panic( "putLV regvar" );
275762Speter     }
2767924Smckusick     switch ( whereis( level , offset , other_flags ) ) {
2773829Speter 	case GLOBALVAR:
2783829Speter 	    if ( ( name != 0 ) ) {
2793829Speter 		if ( name[0] != '_' ) {
2803829Speter 			sprintf( extname , EXTFORMAT , name );
2813829Speter 			printname = extname;
2823829Speter 		} else {
2833829Speter 			printname = name;
2843829Speter 		}
2853829Speter 		putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR )
2863829Speter 			, printname );
2873829Speter 		return;
2883829Speter 	    } else {
2893829Speter 		panic( "putLV no name" );
2903829Speter 	    }
2913277Smckusic 	case PARAMVAR:
2923277Smckusic 	    if ( level == cbn ) {
2933277Smckusic 		putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 );
2943277Smckusic 	    } else {
2953277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
2963277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
2979128Smckusick 		parts[ level ] |= NONLOCALVAR;
2983277Smckusic 	    }
2993277Smckusic 	    putleaf( P2ICON , offset , 0 , P2INT , 0 );
3003277Smckusic 	    putop( P2PLUS , P2PTR | P2CHAR );
3013277Smckusic 	    break;
3023277Smckusic 	case LOCALVAR:
3033277Smckusic 	    if ( level == cbn ) {
3043277Smckusic 		putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 );
3053277Smckusic 	    } else {
3063277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
3073277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3089128Smckusick 		parts[ level ] |= NONLOCALVAR;
3093277Smckusic 	    }
3103277Smckusic 	    putleaf( P2ICON , -offset , 0 , P2INT , 0 );
3113277Smckusic 	    putop( P2MINUS , P2PTR | P2CHAR );
3123277Smckusic 	    break;
3139128Smckusick 	case NAMEDLOCALVAR:
3149128Smckusick 	    if ( level == cbn ) {
3159128Smckusick 		putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 );
3169128Smckusick 	    } else {
3179128Smckusick 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
3189128Smckusick 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3199128Smckusick 		parts[ level ] |= NONLOCALVAR;
3209128Smckusick 	    }
3219128Smckusick 	    putleaf( P2ICON , 0 , 0 , P2INT , name );
3229128Smckusick 	    putop( P2MINUS , P2PTR | P2CHAR );
3239128Smckusick 	    break;
3243277Smckusic     }
3253277Smckusic     return;
3263277Smckusic }
327762Speter 
328762Speter     /*
329762Speter      *	put out a floating point constant leaf node
330762Speter      *	the constant is declared in aligned data space
331762Speter      *	and a P2NAME leaf put out for it
332762Speter      */
3337924Smckusick putCON8( val )
3347924Smckusick     double	val;
335762Speter     {
336762Speter 	int	label;
337762Speter 	char	name[ BUFSIZ ];
338762Speter 
3393316Speter 	if ( !CGENNING )
340762Speter 	    return;
341*10653Speter 	label = getlab();
342762Speter 	putprintf( "	.data" , 0 );
343*10653Speter 	aligndot(A_DOUBLE);
344762Speter 	putlab( label );
345*10653Speter #	ifdef vax
346*10653Speter 	    putprintf( "	.double 0d%.20e" , 0 , val );
347*10653Speter #	endif vax
348*10653Speter #	ifdef mc68000
349*10653Speter 	    putprintf( "	.long 	0x%x,0x%x", 0, val);
350*10653Speter #	endif mc68000
351762Speter 	putprintf( "	.text" , 0 );
352762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
353762Speter 	putleaf( P2NAME , 0 , 0 , P2DOUBLE , name );
354762Speter     }
355762Speter 
356762Speter 	/*
357762Speter 	 * put out either an lvalue or an rvalue for a constant string.
358762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
359762Speter 	 * an rvalue (for parameters) is just the name.
360762Speter 	 */
361762Speter putCONG( string , length , required )
362762Speter     char	*string;
363762Speter     int		length;
364762Speter     int		required;
365762Speter     {
366762Speter 	char	name[ BUFSIZ ];
367762Speter 	int	label;
368762Speter 	char	*cp;
369762Speter 	int	pad;
370762Speter 	int	others;
371762Speter 
3723316Speter 	if ( !CGENNING )
373762Speter 	    return;
374762Speter 	putprintf( "	.data" , 0 );
375*10653Speter 	aligndot(A_STRUCT);
376762Speter 	label = getlab();
377762Speter 	putlab( label );
378762Speter 	cp = string;
379762Speter 	while ( *cp ) {
380762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
381762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
382762Speter 		putprintf( ",0%o" , 1 , *cp++ );
383762Speter 	    }
384762Speter 	    putprintf( "" , 0 );
385762Speter 	}
386762Speter 	pad = length - strlen( string );
387762Speter 	while ( pad-- > 0 ) {
388762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
389762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
390762Speter 		putprintf( ",0%o" , 1 , ' ' );
391762Speter 	    }
392762Speter 	    putprintf( "" , 0 );
393762Speter 	}
394762Speter 	putprintf( "	.byte	0" , 0 );
395762Speter 	putprintf( "	.text"  , 0 );
396762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
397762Speter 	if ( required == RREQ ) {
398762Speter 	    putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name );
399762Speter 	} else {
400762Speter 	    putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name );
401762Speter 	}
402762Speter     }
403762Speter 
404762Speter     /*
405762Speter      *	map a pascal type to a c type
406762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
407762Speter      *	this is sort of like isa and lwidth
408762Speter      *	a note on the types used by the portable c compiler:
409762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
410762Speter      *	    and qualifications on those basic types (pointer, function, array).
411762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
412762Speter      *	    and the qualifications are arranged in two bit chunks, with the
413762Speter      *	    most significant on the right,
414762Speter      *	    and the least significant on the left
415762Speter      *		e.g. int *foo();
416762Speter      *			(a function returning a pointer to an integer)
417762Speter      *		is stored as
418762Speter      *		    <ptr><ftn><int>
419762Speter      *	so, we build types recursively
4201478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4211478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4221478Speter      *	through mutually recursive pointer types.
423762Speter      */
4241478Speter #define	MAXQUALS	6
425762Speter int
426762Speter p2type( np )
4271478Speter {
4281478Speter 
4291478Speter     return typerecur( np , 0 );
4301478Speter }
4311478Speter typerecur( np , quals )
4321478Speter     struct nl	*np;
4331478Speter     int		quals;
434762Speter     {
435762Speter 
4361478Speter 	if ( np == NIL || quals > MAXQUALS ) {
4371478Speter 	    return P2UNDEF;
4381478Speter 	}
439762Speter 	switch ( np -> class ) {
440762Speter 	    case SCAL :
441762Speter 	    case RANGE :
442762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
443762Speter 		    return P2DOUBLE;
444762Speter 		}
445762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
446762Speter 		    case 1:
447762Speter 			return P2CHAR;
448762Speter 		    case 2:
449762Speter 			return P2SHORT;
450762Speter 		    case 4:
451762Speter 			return P2INT;
452762Speter 		    default:
453762Speter 			panic( "p2type int" );
454762Speter 		}
455762Speter 	    case STR :
456762Speter 		return ( P2ARY | P2CHAR );
457762Speter 	    case RECORD :
458762Speter 	    case SET :
459762Speter 		return P2STRTY;
460762Speter 	    case FILET :
461762Speter 		return ( P2PTR | P2STRTY );
462762Speter 	    case CONST :
463762Speter 	    case VAR :
464762Speter 	    case FIELD :
465762Speter 		return p2type( np -> type );
466762Speter 	    case TYPE :
467762Speter 		switch ( nloff( np ) ) {
468762Speter 		    case TNIL :
4691478Speter 			return ( P2PTR | P2UNDEF );
470762Speter 		    case TSTR :
471762Speter 			return ( P2ARY | P2CHAR );
472762Speter 		    case TSET :
473762Speter 			return P2STRTY;
474762Speter 		    default :
475762Speter 			return ( p2type( np -> type ) );
476762Speter 		}
477762Speter 	    case REF:
478762Speter 	    case WITHPTR:
479762Speter 	    case PTR :
4801478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR );
481762Speter 	    case ARRAY :
4821478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY );
483762Speter 	    case FUNC :
484762Speter 		    /*
485762Speter 		     * functions are really pointers to functions
486762Speter 		     * which return their underlying type.
487762Speter 		     */
4881478Speter 		return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) ,
4891478Speter 					P2FTN ) , P2PTR );
490762Speter 	    case PROC :
491762Speter 		    /*
492762Speter 		     * procedures are pointers to functions
493762Speter 		     * which return integers (whether you look at them or not)
494762Speter 		     */
495762Speter 		return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR );
4961197Speter 	    case FFUNC :
4971197Speter 	    case FPROC :
4981197Speter 		    /*
4991197Speter 		     *	formal procedures and functions are pointers
5001197Speter 		     *	to structures which describe their environment.
5011197Speter 		     */
5022474Speter 		return ( P2PTR | P2STRTY );
503762Speter 	    default :
504762Speter 		panic( "p2type" );
505762Speter 	}
506762Speter     }
507762Speter 
508762Speter     /*
509762Speter      *	add a most significant type modifier to a type
510762Speter      */
511762Speter long
512762Speter addtype( underlying , mtype )
513762Speter     long	underlying;
514762Speter     long	mtype;
515762Speter     {
516762Speter 	return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT )
517762Speter 	       | mtype
518762Speter 	       | ( underlying & P2BASETYPE ) );
519762Speter     }
520762Speter 
521762Speter     /*
522762Speter      *	put a typed operator to the pcstream
523762Speter      */
524762Speter putop( op , type )
525762Speter     int		op;
526762Speter     int		type;
527762Speter     {
528762Speter 	extern char	*p2opnames[];
529762Speter 
5303316Speter 	if ( !CGENNING )
531762Speter 	    return;
532762Speter 	p2word( TOF77( op , 0 , type ) );
533762Speter #	ifdef DEBUG
534762Speter 	    if ( opt( 'k' ) ) {
5352474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
536762Speter 			, p2opnames[ op ] , op , type );
537762Speter 	    }
538762Speter #	endif
539762Speter     }
540762Speter 
541762Speter     /*
542762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
543762Speter      *	which looks just like a regular operator, only the size and
544762Speter      *	alignment go in the next consecutive words
545762Speter      */
546762Speter putstrop( op , type , size , alignment )
547762Speter     int	op;
548762Speter     int	type;
549762Speter     int	size;
550762Speter     int	alignment;
551762Speter     {
552762Speter 	extern char	*p2opnames[];
553762Speter 
5543316Speter 	if ( !CGENNING )
555762Speter 	    return;
556762Speter 	p2word( TOF77( op , 0 , type ) );
557762Speter 	p2word( size );
558762Speter 	p2word( alignment );
559762Speter #	ifdef DEBUG
560762Speter 	    if ( opt( 'k' ) ) {
5612474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
562762Speter 			, p2opnames[ op ] , op , type , size , alignment );
563762Speter 	    }
564762Speter #	endif
565762Speter     }
566762Speter 
567762Speter     /*
568762Speter      *	the string names of p2ops
569762Speter      */
570762Speter char	*p2opnames[] = {
571762Speter 	"",
572762Speter 	"P2UNDEFINED",		/* 1 */
573762Speter 	"P2NAME",		/* 2 */
574762Speter 	"P2STRING",		/* 3 */
575762Speter 	"P2ICON",		/* 4 */
576762Speter 	"P2FCON",		/* 5 */
577762Speter 	"P2PLUS",		/* 6 */
578762Speter 	"",
579762Speter 	"P2MINUS",		/* 8		also unary == P2NEG */
580762Speter 	"",
581762Speter 	"P2NEG",
582762Speter 	"P2MUL",		/* 11		also unary == P2INDIRECT */
583762Speter 	"",
584762Speter 	"P2INDIRECT",
585762Speter 	"P2AND",		/* 14		also unary == P2ADDROF */
586762Speter 	"",
587762Speter 	"P2ADDROF",
588762Speter 	"P2OR",			/* 17 */
589762Speter 	"",
590762Speter 	"P2ER",			/* 19 */
591762Speter 	"",
592762Speter 	"P2QUEST",		/* 21 */
593762Speter 	"P2COLON",		/* 22 */
594762Speter 	"P2ANDAND",		/* 23 */
595762Speter 	"P2OROR",		/* 24 */
596762Speter 	"",			/* 25 */
597762Speter 	"",			/* 26 */
598762Speter 	"",			/* 27 */
599762Speter 	"",			/* 28 */
600762Speter 	"",			/* 29 */
601762Speter 	"",			/* 30 */
602762Speter 	"",			/* 31 */
603762Speter 	"",			/* 32 */
604762Speter 	"",			/* 33 */
605762Speter 	"",			/* 34 */
606762Speter 	"",			/* 35 */
607762Speter 	"",			/* 36 */
608762Speter 	"",			/* 37 */
609762Speter 	"",			/* 38 */
610762Speter 	"",			/* 39 */
611762Speter 	"",			/* 40 */
612762Speter 	"",			/* 41 */
613762Speter 	"",			/* 42 */
614762Speter 	"",			/* 43 */
615762Speter 	"",			/* 44 */
616762Speter 	"",			/* 45 */
617762Speter 	"",			/* 46 */
618762Speter 	"",			/* 47 */
619762Speter 	"",			/* 48 */
620762Speter 	"",			/* 49 */
621762Speter 	"",			/* 50 */
622762Speter 	"",			/* 51 */
623762Speter 	"",			/* 52 */
624762Speter 	"",			/* 53 */
625762Speter 	"",			/* 54 */
626762Speter 	"",			/* 55 */
627762Speter 	"P2LISTOP",		/* 56 */
628762Speter 	"",
629762Speter 	"P2ASSIGN",		/* 58 */
630762Speter 	"P2COMOP",		/* 59 */
631762Speter 	"P2DIV",		/* 60 */
632762Speter 	"",
633762Speter 	"P2MOD",		/* 62 */
634762Speter 	"",
635762Speter 	"P2LS",			/* 64 */
636762Speter 	"",
637762Speter 	"P2RS",			/* 66 */
638762Speter 	"",
639762Speter 	"P2DOT",		/* 68 */
640762Speter 	"P2STREF",		/* 69 */
641762Speter 	"P2CALL",		/* 70		also unary */
642762Speter 	"",
643762Speter 	"P2UNARYCALL",
644762Speter 	"P2FORTCALL",		/* 73		also unary */
645762Speter 	"",
646762Speter 	"P2UNARYFORTCALL",
647762Speter 	"P2NOT",		/* 76 */
648762Speter 	"P2COMPL",		/* 77 */
649762Speter 	"P2INCR",		/* 78 */
650762Speter 	"P2DECR",		/* 79 */
651762Speter 	"P2EQ",			/* 80 */
652762Speter 	"P2NE",			/* 81 */
653762Speter 	"P2LE",			/* 82 */
654762Speter 	"P2LT",			/* 83 */
655762Speter 	"P2GE",			/* 84 */
656762Speter 	"P2GT",			/* 85 */
657762Speter 	"P2ULE",		/* 86 */
658762Speter 	"P2ULT",		/* 87 */
659762Speter 	"P2UGE",		/* 88 */
660762Speter 	"P2UGT",		/* 89 */
661762Speter 	"P2SETBIT",		/* 90 */
662762Speter 	"P2TESTBIT",		/* 91 */
663762Speter 	"P2RESETBIT",		/* 92 */
664762Speter 	"P2ARS",		/* 93 */
665762Speter 	"P2REG",		/* 94 */
666762Speter 	"P2OREG",		/* 95 */
667762Speter 	"P2CCODES",		/* 96 */
668762Speter 	"P2FREE",		/* 97 */
669762Speter 	"P2STASG",		/* 98 */
670762Speter 	"P2STARG",		/* 99 */
671762Speter 	"P2STCALL",		/* 100		also unary */
672762Speter 	"",
673762Speter 	"P2UNARYSTCALL",
674762Speter 	"P2FLD",		/* 103 */
675762Speter 	"P2SCONV",		/* 104 */
676762Speter 	"P2PCONV",		/* 105 */
677762Speter 	"P2PMCONV",		/* 106 */
678762Speter 	"P2PVCONV",		/* 107 */
679762Speter 	"P2FORCE",		/* 108 */
680762Speter 	"P2CBRANCH",		/* 109 */
681762Speter 	"P2INIT",		/* 110 */
682762Speter 	"P2CAST",		/* 111 */
683762Speter     };
684762Speter 
685762Speter     /*
686762Speter      *	low level routines
687762Speter      */
688762Speter 
689762Speter     /*
690762Speter      *	puts a long word on the pcstream
691762Speter      */
692762Speter p2word( word )
693762Speter     long	word;
694762Speter     {
695762Speter 
696762Speter 	putw( word , pcstream );
697762Speter     }
698762Speter 
699762Speter     /*
700762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
701762Speter      */
702762Speter p2string( string )
703762Speter     char	*string;
704762Speter     {
705762Speter 	int	slen = strlen( string );
706762Speter 	int	wlen = ( slen + 3 ) / 4;
707762Speter 	int	plen = ( wlen * 4 ) - slen;
708762Speter 	char	*cp;
709762Speter 	int	p;
710762Speter 
711762Speter 	for ( cp = string ; *cp ; cp++ )
712762Speter 	    putc( *cp , pcstream );
713762Speter 	for ( p = 1 ; p <= plen ; p++ )
714762Speter 	    putc( '\0' , pcstream );
715762Speter #	ifdef DEBUG
716762Speter 	    if ( opt( 'k' ) ) {
717762Speter 		fprintf( stdout , "\"%s" , string );
718762Speter 		for ( p = 1 ; p <= plen ; p++ )
719762Speter 		    fprintf( stdout , "\\0" );
720762Speter 		fprintf( stdout , "\"\n" );
721762Speter 	    }
722762Speter #	endif
723762Speter     }
724762Speter 
725762Speter     /*
726762Speter      *	puts a name on the pcstream
727762Speter      */
728762Speter p2name( name )
729762Speter     char	*name;
730762Speter     {
731762Speter 	int	pad;
732762Speter 
733762Speter 	fprintf( pcstream , NAMEFORMAT , name );
734762Speter 	pad = strlen( name ) % sizeof (long);
735762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
736762Speter 	    putc( '\0' , pcstream );
737762Speter 	}
738762Speter #	ifdef DEBUG
739762Speter 	    if ( opt( 'k' ) ) {
740762Speter 		fprintf( stdout , NAMEFORMAT , name );
741762Speter 		pad = strlen( name ) % sizeof (long);
742762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
743762Speter 		    fprintf( stdout , "\\0" );
744762Speter 		}
745762Speter 		fprintf( stdout , "\n" );
746762Speter 	    }
747762Speter #	endif
748762Speter     }
749762Speter 
750762Speter     /*
751762Speter      *	put out a jump to a label
752762Speter      */
753762Speter putjbr( label )
754762Speter     long	label;
755762Speter     {
756762Speter 
757762Speter 	printjbr( LABELPREFIX , label );
758762Speter     }
759762Speter 
760762Speter     /*
761762Speter      *	put out a jump to any kind of label
762762Speter      */
763762Speter printjbr( prefix , label )
764762Speter     char	*prefix;
765762Speter     long	label;
766762Speter     {
767762Speter 
768*10653Speter #	ifdef vax
769*10653Speter 	    putprintf( "	jbr	" , 1 );
770*10653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
771*10653Speter #	endif vax
772*10653Speter #	ifdef mc68000
773*10653Speter 	    putprintf( "	jra	" , 1 );
774*10653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
775*10653Speter #	endif mc68000
776762Speter     }
777762Speter 
778762Speter     /*
779762Speter      *	another version of put to catch calls to put
780762Speter      */
781762Speter put( arg1 , arg2 )
782762Speter     {
783762Speter 
784*10653Speter 	panic("put()");
785762Speter     }
786762Speter 
787762Speter #endif PC
788