xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 14906)
1762Speter /* Copyright (c) 1979 Regents of the University of California */
2762Speter 
3*14906Speter static	char sccsid[] = "@(#)p2put.c 1.14 09/05/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"
1410653Speter #include	"objfmt.h"
15762Speter #include	"pcops.h"
16762Speter #include	"pc.h"
1710653Speter #include	"align.h"
1811329Speter #include	"tmps.h"
19762Speter 
20762Speter     /*
21762Speter      *	mash into f77's format
22762Speter      *	lovely, isn't it?
23762Speter      */
24762Speter #define		TOF77( fop,val,rest )	( ( ( (rest) & 0177777 ) << 16 ) \
25762Speter 					| ( ( (val) & 0377 ) << 8 )	 \
26762Speter 					| ( (fop) & 0377 ) )
27762Speter 
28762Speter     /*
29762Speter      *	emits an ftext operator and a string to the pcstream
30762Speter      */
31762Speter puttext( string )
32762Speter     char	*string;
33762Speter     {
34762Speter 	int	length = str4len( string );
35762Speter 
363316Speter 	if ( !CGENNING )
37762Speter 	    return;
38762Speter 	p2word( TOF77( P2FTEXT , length , 0 ) );
39762Speter #	ifdef DEBUG
40762Speter 	    if ( opt( 'k' ) ) {
41762Speter 		fprintf( stdout , "P2FTEXT | %3d | 0	" , length );
42762Speter 	    }
43762Speter #	endif
44762Speter 	p2string( string );
45762Speter     }
46762Speter 
47762Speter int
48762Speter str4len( string )
49762Speter     char	*string;
50762Speter     {
51762Speter 
52762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
53762Speter     }
54762Speter 
55762Speter     /*
56762Speter      *	put formatted text into a buffer for printing to the pcstream.
57762Speter      *	a call to putpflush actually puts out the text.
58762Speter      *	none of arg1 .. arg5 need be present.
59762Speter      *	and you can add more if you need them.
60762Speter      */
61762Speter     /* VARARGS */
62762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
63762Speter     char	*format;
64762Speter     int		incomplete;
65762Speter     {
66762Speter 	static char	ppbuffer[ BUFSIZ ];
67762Speter 	static char	*ppbufp = ppbuffer;
68762Speter 
693316Speter 	if ( !CGENNING )
70762Speter 	    return;
71762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
72762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
73762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
74762Speter 	    panic( "putprintf" );
75762Speter 	if ( ! incomplete ) {
76762Speter 	    puttext( ppbuffer );
77762Speter 	    ppbufp = ppbuffer;
78762Speter 	}
79762Speter     }
80762Speter 
81762Speter     /*
82762Speter      *	emit a left bracket operator to pcstream
83762Speter      *	with function number, the maximum temp register, and total local bytes
84762Speter      */
8511329Speter putlbracket(ftnno, sizesp)
8611329Speter     int		ftnno;
8711329Speter     struct om	*sizesp;
8811329Speter {
8911329Speter     int	maxtempreg;
9011329Speter     int	alignedframesize;
91762Speter 
9211329Speter #   ifdef vax
9311329Speter 	maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL];
9411329Speter #   endif vax
9511329Speter #   ifdef mc68000
9611329Speter 	    /*
97*14906Speter 	     *	this is how /lib/f1 wants it.
9811329Speter 	     */
99*14906Speter 	maxtempreg =	(sizesp->curtmps.next_avail[REG_ADDR] << 4)
100*14906Speter 		      | (sizesp->curtmps.next_avail[REG_DATA]);
10111329Speter #   endif mc68000
10211329Speter     alignedframesize =
10311329Speter 	roundup(BITSPERBYTE * -sizesp->curtmps.om_off, BITSPERBYTE * A_STACK);
10411329Speter     p2word( TOF77( P2FLBRAC , maxtempreg , ftnno ) );
10511329Speter     p2word(alignedframesize);
10611329Speter #   ifdef DEBUG
10711329Speter 	if ( opt( 'k' ) ) {
10811329Speter 	    fprintf(stdout, "P2FLBRAC | %3d | %d	%d\n",
10911329Speter 		maxtempreg, ftnno, alignedframesize);
11011329Speter 	}
11111329Speter #   endif
11211329Speter }
113762Speter 
114762Speter     /*
115762Speter      *	emit a right bracket operator
116*14906Speter      *	which for the binary interface
117762Speter      *	forces the stack allocate and register mask
118762Speter      */
119762Speter putrbracket( ftnno )
120762Speter     int	ftnno;
121762Speter     {
122762Speter 
123762Speter 	p2word( TOF77( P2FRBRAC , 0 , ftnno ) );
124762Speter #	ifdef DEBUG
125762Speter 	    if ( opt( 'k' ) ) {
126762Speter 		fprintf( stdout , "P2FRBRAC |   0 | %d\n" , ftnno );
127762Speter 	    }
128762Speter #	endif
129762Speter     }
130762Speter 
131762Speter     /*
132762Speter      *	emit an eof operator
133762Speter      */
134762Speter puteof()
135762Speter     {
136762Speter 
137762Speter 	p2word( P2FEOF );
138762Speter #	ifdef DEBUG
139762Speter 	    if ( opt( 'k' ) ) {
140762Speter 		fprintf( stdout , "P2FEOF\n" );
141762Speter 	    }
142762Speter #	endif
143762Speter     }
144762Speter 
145762Speter     /*
146762Speter      *	emit a dot operator,
147762Speter      *	with a source file line number and name
148762Speter      *	if line is negative, there was an error on that line, but who cares?
149762Speter      */
150762Speter putdot( filename , line )
151762Speter     char	*filename;
152762Speter     int		line;
153762Speter     {
154762Speter 	int	length = str4len( filename );
155762Speter 
156762Speter 	if ( line < 0 ) {
157762Speter 	    line = -line;
158762Speter 	}
159762Speter 	p2word( TOF77( P2FEXPR , length , line ) );
160762Speter #	ifdef DEBUG
161762Speter 	    if ( opt( 'k' ) ) {
162762Speter 		fprintf( stdout , "P2FEXPR | %3d | %d	" , length , line );
163762Speter 	    }
164762Speter #	endif
165762Speter 	p2string( filename );
166762Speter     }
167762Speter 
168762Speter     /*
169762Speter      *	put out a leaf node
170762Speter      */
171762Speter putleaf( op , lval , rval , type , name )
172762Speter     int		op;
173762Speter     int		lval;
174762Speter     int		rval;
175762Speter     int		type;
176762Speter     char	*name;
177762Speter     {
1783316Speter 	if ( !CGENNING )
179762Speter 	    return;
180762Speter 	switch ( op ) {
181762Speter 	    default:
182762Speter 		panic( "[putleaf]" );
183762Speter 	    case P2ICON:
184762Speter 		p2word( TOF77( P2ICON , name != NIL , type ) );
185762Speter 		p2word( lval );
186762Speter #		ifdef DEBUG
187762Speter 		    if ( opt( 'k' ) ) {
1882474Speter 			fprintf( stdout , "P2ICON | %3d | 0x%x	"
189762Speter 			       , name != NIL , type );
190762Speter 			fprintf( stdout , "%d\n" , lval );
191762Speter 		    }
192762Speter #		endif
193762Speter 		if ( name )
194762Speter 		    p2name( name );
195762Speter 		break;
196762Speter 	    case P2NAME:
197762Speter 		p2word( TOF77( P2NAME , lval != 0 , type ) );
198762Speter 		if ( lval )
199762Speter 		    p2word( lval );
200762Speter #		ifdef DEBUG
201762Speter 		    if ( opt( 'k' ) ) {
2022474Speter 			fprintf( stdout , "P2NAME | %3d | 0x%x	"
203762Speter 			       , lval != 0 , type );
204762Speter 			if ( lval )
205762Speter 			    fprintf( stdout , "%d	" , lval );
206762Speter 		    }
207762Speter #		endif
208762Speter 		p2name( name );
209762Speter 		break;
210762Speter 	    case P2REG:
211762Speter 		p2word( TOF77( P2REG , rval , type ) );
212762Speter #		ifdef DEBUG
213762Speter 		    if ( opt( 'k' ) ) {
2142474Speter 			fprintf( stdout , "P2REG | %3d | 0x%x\n" ,
2152474Speter 				rval , type );
216762Speter 		    }
217762Speter #		endif
218762Speter 		break;
219762Speter 	}
220762Speter     }
221762Speter 
222762Speter     /*
223762Speter      *	rvalues are just lvalues with indirection, except
2243829Speter      *	special cases for registers and for named globals,
2253829Speter      *	whose names are their rvalues.
226762Speter      */
2277924Smckusick putRV( name , level , offset , other_flags , type )
228762Speter     char	*name;
229762Speter     int		level;
230762Speter     int		offset;
2317924Smckusick     char	other_flags;
232762Speter     int		type;
233762Speter     {
234762Speter 	char	extname[ BUFSIZ ];
235762Speter 	char	*printname;
2363582Speter 	int	regnumber;
237762Speter 
2383316Speter 	if ( !CGENNING )
239762Speter 	    return;
2407924Smckusick 	if ( other_flags & NREGVAR ) {
2413829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
2423829Speter 		panic( "putRV regvar" );
2433582Speter 	    }
2443829Speter 	    putleaf( P2REG , 0 , offset , type , 0 );
2453277Smckusic 	    return;
2463277Smckusic 	}
2477924Smckusick 	if ( whereis( level , offset , other_flags ) == GLOBALVAR ) {
2483829Speter 	    if ( name != 0 ) {
2493829Speter 		if ( name[0] != '_' ) {
2503829Speter 			sprintf( extname , EXTFORMAT , name );
2513829Speter 			printname = extname;
2523829Speter 		} else {
2533829Speter 			printname = name;
2543829Speter 		}
2553829Speter 		putleaf( P2NAME , offset , 0 , type , printname );
2563829Speter 		return;
257762Speter 	    } else {
2583829Speter 		panic( "putRV no name" );
259762Speter 	    }
260762Speter 	}
2617924Smckusick 	putLV( name , level , offset , other_flags , type );
262762Speter 	putop( P2UNARY P2MUL , type );
263762Speter     }
264762Speter 
265762Speter     /*
266762Speter      *	put out an lvalue
267762Speter      *	given a level and offset
268762Speter      *	special case for
269762Speter      *	    named globals, whose lvalues are just their names as constants.
270762Speter      */
2717924Smckusick putLV( name , level , offset , other_flags , type )
272762Speter     char	*name;
273762Speter     int		level;
274762Speter     int		offset;
2757924Smckusick     char	other_flags;
276762Speter     int		type;
2773277Smckusic {
2783277Smckusic     char		extname[ BUFSIZ ];
2793277Smckusic     char		*printname;
280762Speter 
2813316Speter     if ( !CGENNING )
2823277Smckusic 	return;
2837924Smckusick     if ( other_flags & NREGVAR ) {
2843829Speter 	panic( "putLV regvar" );
285762Speter     }
2867924Smckusick     switch ( whereis( level , offset , other_flags ) ) {
2873829Speter 	case GLOBALVAR:
2883829Speter 	    if ( ( name != 0 ) ) {
2893829Speter 		if ( name[0] != '_' ) {
2903829Speter 			sprintf( extname , EXTFORMAT , name );
2913829Speter 			printname = extname;
2923829Speter 		} else {
2933829Speter 			printname = name;
2943829Speter 		}
2953829Speter 		putleaf( P2ICON , offset , 0 , ADDTYPE( type , P2PTR )
2963829Speter 			, printname );
2973829Speter 		return;
2983829Speter 	    } else {
2993829Speter 		panic( "putLV no name" );
3003829Speter 	    }
3013277Smckusic 	case PARAMVAR:
3023277Smckusic 	    if ( level == cbn ) {
3033277Smckusic 		putleaf( P2REG , 0 , P2AP , ADDTYPE( type , P2PTR ) , 0 );
3043277Smckusic 	    } else {
3053277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
3063277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3079128Smckusick 		parts[ level ] |= NONLOCALVAR;
3083277Smckusic 	    }
3093277Smckusic 	    putleaf( P2ICON , offset , 0 , P2INT , 0 );
3103277Smckusic 	    putop( P2PLUS , P2PTR | P2CHAR );
3113277Smckusic 	    break;
3123277Smckusic 	case LOCALVAR:
3133277Smckusic 	    if ( level == cbn ) {
3143277Smckusic 		putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 );
3153277Smckusic 	    } else {
3163277Smckusic 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
3173277Smckusic 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3189128Smckusick 		parts[ level ] |= NONLOCALVAR;
3193277Smckusic 	    }
3203277Smckusic 	    putleaf( P2ICON , -offset , 0 , P2INT , 0 );
3213277Smckusic 	    putop( P2MINUS , P2PTR | P2CHAR );
3223277Smckusic 	    break;
3239128Smckusick 	case NAMEDLOCALVAR:
3249128Smckusick 	    if ( level == cbn ) {
3259128Smckusick 		putleaf( P2REG , 0 , P2FP , ADDTYPE( type , P2PTR ) , 0 );
3269128Smckusick 	    } else {
3279128Smckusick 		putleaf( P2NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
3289128Smckusick 		    , 0 , P2PTR | P2CHAR , DISPLAYNAME );
3299128Smckusick 		parts[ level ] |= NONLOCALVAR;
3309128Smckusick 	    }
3319128Smckusick 	    putleaf( P2ICON , 0 , 0 , P2INT , name );
3329128Smckusick 	    putop( P2MINUS , P2PTR | P2CHAR );
3339128Smckusick 	    break;
3343277Smckusic     }
3353277Smckusic     return;
3363277Smckusic }
337762Speter 
338762Speter     /*
339762Speter      *	put out a floating point constant leaf node
340762Speter      *	the constant is declared in aligned data space
341762Speter      *	and a P2NAME leaf put out for it
342762Speter      */
3437924Smckusick putCON8( val )
3447924Smckusick     double	val;
345762Speter     {
346762Speter 	int	label;
347762Speter 	char	name[ BUFSIZ ];
348762Speter 
3493316Speter 	if ( !CGENNING )
350762Speter 	    return;
35110653Speter 	label = getlab();
352762Speter 	putprintf( "	.data" , 0 );
35310653Speter 	aligndot(A_DOUBLE);
354762Speter 	putlab( label );
35510653Speter #	ifdef vax
35610653Speter 	    putprintf( "	.double 0d%.20e" , 0 , val );
35710653Speter #	endif vax
35810653Speter #	ifdef mc68000
35910653Speter 	    putprintf( "	.long 	0x%x,0x%x", 0, val);
36010653Speter #	endif mc68000
361762Speter 	putprintf( "	.text" , 0 );
362762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
363762Speter 	putleaf( P2NAME , 0 , 0 , P2DOUBLE , name );
364762Speter     }
365762Speter 
366762Speter 	/*
367762Speter 	 * put out either an lvalue or an rvalue for a constant string.
368762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
369762Speter 	 * an rvalue (for parameters) is just the name.
370762Speter 	 */
371762Speter putCONG( string , length , required )
372762Speter     char	*string;
373762Speter     int		length;
374762Speter     int		required;
375762Speter     {
376762Speter 	char	name[ BUFSIZ ];
377762Speter 	int	label;
378762Speter 	char	*cp;
379762Speter 	int	pad;
380762Speter 	int	others;
381762Speter 
3823316Speter 	if ( !CGENNING )
383762Speter 	    return;
384762Speter 	putprintf( "	.data" , 0 );
38510653Speter 	aligndot(A_STRUCT);
386762Speter 	label = getlab();
387762Speter 	putlab( label );
388762Speter 	cp = string;
389762Speter 	while ( *cp ) {
390762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
391762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
392762Speter 		putprintf( ",0%o" , 1 , *cp++ );
393762Speter 	    }
394762Speter 	    putprintf( "" , 0 );
395762Speter 	}
396762Speter 	pad = length - strlen( string );
397762Speter 	while ( pad-- > 0 ) {
398762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
399762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
400762Speter 		putprintf( ",0%o" , 1 , ' ' );
401762Speter 	    }
402762Speter 	    putprintf( "" , 0 );
403762Speter 	}
404762Speter 	putprintf( "	.byte	0" , 0 );
405762Speter 	putprintf( "	.text"  , 0 );
406762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
407762Speter 	if ( required == RREQ ) {
408762Speter 	    putleaf( P2NAME , 0 , 0 , P2ARY | P2CHAR , name );
409762Speter 	} else {
410762Speter 	    putleaf( P2ICON , 0 , 0 , P2PTR | P2CHAR , name );
411762Speter 	}
412762Speter     }
413762Speter 
414762Speter     /*
415762Speter      *	map a pascal type to a c type
416762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
417762Speter      *	this is sort of like isa and lwidth
418762Speter      *	a note on the types used by the portable c compiler:
419762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
420762Speter      *	    and qualifications on those basic types (pointer, function, array).
421762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
422762Speter      *	    and the qualifications are arranged in two bit chunks, with the
423762Speter      *	    most significant on the right,
424762Speter      *	    and the least significant on the left
425762Speter      *		e.g. int *foo();
426762Speter      *			(a function returning a pointer to an integer)
427762Speter      *		is stored as
428762Speter      *		    <ptr><ftn><int>
429762Speter      *	so, we build types recursively
4301478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4311478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4321478Speter      *	through mutually recursive pointer types.
433762Speter      */
4341478Speter #define	MAXQUALS	6
435762Speter int
436762Speter p2type( np )
4371478Speter {
4381478Speter 
4391478Speter     return typerecur( np , 0 );
4401478Speter }
4411478Speter typerecur( np , quals )
4421478Speter     struct nl	*np;
4431478Speter     int		quals;
444762Speter     {
445762Speter 
4461478Speter 	if ( np == NIL || quals > MAXQUALS ) {
4471478Speter 	    return P2UNDEF;
4481478Speter 	}
449762Speter 	switch ( np -> class ) {
450762Speter 	    case SCAL :
451762Speter 	    case RANGE :
452762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
453762Speter 		    return P2DOUBLE;
454762Speter 		}
455762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
456762Speter 		    case 1:
457762Speter 			return P2CHAR;
458762Speter 		    case 2:
459762Speter 			return P2SHORT;
460762Speter 		    case 4:
461762Speter 			return P2INT;
462762Speter 		    default:
463762Speter 			panic( "p2type int" );
464762Speter 		}
465762Speter 	    case STR :
466762Speter 		return ( P2ARY | P2CHAR );
467762Speter 	    case RECORD :
468762Speter 	    case SET :
469762Speter 		return P2STRTY;
470762Speter 	    case FILET :
471762Speter 		return ( P2PTR | P2STRTY );
472762Speter 	    case CONST :
473762Speter 	    case VAR :
474762Speter 	    case FIELD :
475762Speter 		return p2type( np -> type );
476762Speter 	    case TYPE :
477762Speter 		switch ( nloff( np ) ) {
478762Speter 		    case TNIL :
4791478Speter 			return ( P2PTR | P2UNDEF );
480762Speter 		    case TSTR :
481762Speter 			return ( P2ARY | P2CHAR );
482762Speter 		    case TSET :
483762Speter 			return P2STRTY;
484762Speter 		    default :
485762Speter 			return ( p2type( np -> type ) );
486762Speter 		}
487762Speter 	    case REF:
488762Speter 	    case WITHPTR:
489762Speter 	    case PTR :
4901478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2PTR );
491762Speter 	    case ARRAY :
4921478Speter 		return ADDTYPE( typerecur( np -> type , quals + 1 ) , P2ARY );
493762Speter 	    case FUNC :
494762Speter 		    /*
495762Speter 		     * functions are really pointers to functions
496762Speter 		     * which return their underlying type.
497762Speter 		     */
4981478Speter 		return ADDTYPE( ADDTYPE( typerecur( np -> type , quals + 2 ) ,
4991478Speter 					P2FTN ) , P2PTR );
500762Speter 	    case PROC :
501762Speter 		    /*
502762Speter 		     * procedures are pointers to functions
503762Speter 		     * which return integers (whether you look at them or not)
504762Speter 		     */
505762Speter 		return ADDTYPE( ADDTYPE( P2INT , P2FTN ) , P2PTR );
5061197Speter 	    case FFUNC :
5071197Speter 	    case FPROC :
5081197Speter 		    /*
5091197Speter 		     *	formal procedures and functions are pointers
5101197Speter 		     *	to structures which describe their environment.
5111197Speter 		     */
5122474Speter 		return ( P2PTR | P2STRTY );
513762Speter 	    default :
514762Speter 		panic( "p2type" );
515762Speter 	}
516762Speter     }
517762Speter 
518762Speter     /*
519762Speter      *	add a most significant type modifier to a type
520762Speter      */
521762Speter long
522762Speter addtype( underlying , mtype )
523762Speter     long	underlying;
524762Speter     long	mtype;
525762Speter     {
526762Speter 	return ( ( ( underlying & ~P2BASETYPE ) << P2TYPESHIFT )
527762Speter 	       | mtype
528762Speter 	       | ( underlying & P2BASETYPE ) );
529762Speter     }
530762Speter 
531762Speter     /*
532762Speter      *	put a typed operator to the pcstream
533762Speter      */
534762Speter putop( op , type )
535762Speter     int		op;
536762Speter     int		type;
537762Speter     {
538762Speter 	extern char	*p2opnames[];
539762Speter 
5403316Speter 	if ( !CGENNING )
541762Speter 	    return;
542762Speter 	p2word( TOF77( op , 0 , type ) );
543762Speter #	ifdef DEBUG
544762Speter 	    if ( opt( 'k' ) ) {
5452474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
546762Speter 			, p2opnames[ op ] , op , type );
547762Speter 	    }
548762Speter #	endif
549762Speter     }
550762Speter 
551762Speter     /*
552762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
553762Speter      *	which looks just like a regular operator, only the size and
554762Speter      *	alignment go in the next consecutive words
555762Speter      */
556762Speter putstrop( op , type , size , alignment )
557762Speter     int	op;
558762Speter     int	type;
559762Speter     int	size;
560762Speter     int	alignment;
561762Speter     {
562762Speter 	extern char	*p2opnames[];
563762Speter 
5643316Speter 	if ( !CGENNING )
565762Speter 	    return;
566762Speter 	p2word( TOF77( op , 0 , type ) );
567762Speter 	p2word( size );
568762Speter 	p2word( alignment );
569762Speter #	ifdef DEBUG
570762Speter 	    if ( opt( 'k' ) ) {
5712474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
572762Speter 			, p2opnames[ op ] , op , type , size , alignment );
573762Speter 	    }
574762Speter #	endif
575762Speter     }
576762Speter 
577762Speter     /*
578762Speter      *	the string names of p2ops
579762Speter      */
580762Speter char	*p2opnames[] = {
581762Speter 	"",
582762Speter 	"P2UNDEFINED",		/* 1 */
583762Speter 	"P2NAME",		/* 2 */
584762Speter 	"P2STRING",		/* 3 */
585762Speter 	"P2ICON",		/* 4 */
586762Speter 	"P2FCON",		/* 5 */
587762Speter 	"P2PLUS",		/* 6 */
588762Speter 	"",
589762Speter 	"P2MINUS",		/* 8		also unary == P2NEG */
590762Speter 	"",
591762Speter 	"P2NEG",
592762Speter 	"P2MUL",		/* 11		also unary == P2INDIRECT */
593762Speter 	"",
594762Speter 	"P2INDIRECT",
595762Speter 	"P2AND",		/* 14		also unary == P2ADDROF */
596762Speter 	"",
597762Speter 	"P2ADDROF",
598762Speter 	"P2OR",			/* 17 */
599762Speter 	"",
600762Speter 	"P2ER",			/* 19 */
601762Speter 	"",
602762Speter 	"P2QUEST",		/* 21 */
603762Speter 	"P2COLON",		/* 22 */
604762Speter 	"P2ANDAND",		/* 23 */
605762Speter 	"P2OROR",		/* 24 */
606762Speter 	"",			/* 25 */
607762Speter 	"",			/* 26 */
608762Speter 	"",			/* 27 */
609762Speter 	"",			/* 28 */
610762Speter 	"",			/* 29 */
611762Speter 	"",			/* 30 */
612762Speter 	"",			/* 31 */
613762Speter 	"",			/* 32 */
614762Speter 	"",			/* 33 */
615762Speter 	"",			/* 34 */
616762Speter 	"",			/* 35 */
617762Speter 	"",			/* 36 */
618762Speter 	"",			/* 37 */
619762Speter 	"",			/* 38 */
620762Speter 	"",			/* 39 */
621762Speter 	"",			/* 40 */
622762Speter 	"",			/* 41 */
623762Speter 	"",			/* 42 */
624762Speter 	"",			/* 43 */
625762Speter 	"",			/* 44 */
626762Speter 	"",			/* 45 */
627762Speter 	"",			/* 46 */
628762Speter 	"",			/* 47 */
629762Speter 	"",			/* 48 */
630762Speter 	"",			/* 49 */
631762Speter 	"",			/* 50 */
632762Speter 	"",			/* 51 */
633762Speter 	"",			/* 52 */
634762Speter 	"",			/* 53 */
635762Speter 	"",			/* 54 */
636762Speter 	"",			/* 55 */
637762Speter 	"P2LISTOP",		/* 56 */
638762Speter 	"",
639762Speter 	"P2ASSIGN",		/* 58 */
640762Speter 	"P2COMOP",		/* 59 */
641762Speter 	"P2DIV",		/* 60 */
642762Speter 	"",
643762Speter 	"P2MOD",		/* 62 */
644762Speter 	"",
645762Speter 	"P2LS",			/* 64 */
646762Speter 	"",
647762Speter 	"P2RS",			/* 66 */
648762Speter 	"",
649762Speter 	"P2DOT",		/* 68 */
650762Speter 	"P2STREF",		/* 69 */
651762Speter 	"P2CALL",		/* 70		also unary */
652762Speter 	"",
653762Speter 	"P2UNARYCALL",
654762Speter 	"P2FORTCALL",		/* 73		also unary */
655762Speter 	"",
656762Speter 	"P2UNARYFORTCALL",
657762Speter 	"P2NOT",		/* 76 */
658762Speter 	"P2COMPL",		/* 77 */
659762Speter 	"P2INCR",		/* 78 */
660762Speter 	"P2DECR",		/* 79 */
661762Speter 	"P2EQ",			/* 80 */
662762Speter 	"P2NE",			/* 81 */
663762Speter 	"P2LE",			/* 82 */
664762Speter 	"P2LT",			/* 83 */
665762Speter 	"P2GE",			/* 84 */
666762Speter 	"P2GT",			/* 85 */
667762Speter 	"P2ULE",		/* 86 */
668762Speter 	"P2ULT",		/* 87 */
669762Speter 	"P2UGE",		/* 88 */
670762Speter 	"P2UGT",		/* 89 */
671762Speter 	"P2SETBIT",		/* 90 */
672762Speter 	"P2TESTBIT",		/* 91 */
673762Speter 	"P2RESETBIT",		/* 92 */
674762Speter 	"P2ARS",		/* 93 */
675762Speter 	"P2REG",		/* 94 */
676762Speter 	"P2OREG",		/* 95 */
677762Speter 	"P2CCODES",		/* 96 */
678762Speter 	"P2FREE",		/* 97 */
679762Speter 	"P2STASG",		/* 98 */
680762Speter 	"P2STARG",		/* 99 */
681762Speter 	"P2STCALL",		/* 100		also unary */
682762Speter 	"",
683762Speter 	"P2UNARYSTCALL",
684762Speter 	"P2FLD",		/* 103 */
685762Speter 	"P2SCONV",		/* 104 */
686762Speter 	"P2PCONV",		/* 105 */
687762Speter 	"P2PMCONV",		/* 106 */
688762Speter 	"P2PVCONV",		/* 107 */
689762Speter 	"P2FORCE",		/* 108 */
690762Speter 	"P2CBRANCH",		/* 109 */
691762Speter 	"P2INIT",		/* 110 */
692762Speter 	"P2CAST",		/* 111 */
693762Speter     };
694762Speter 
695762Speter     /*
696762Speter      *	low level routines
697762Speter      */
698762Speter 
699762Speter     /*
700762Speter      *	puts a long word on the pcstream
701762Speter      */
702762Speter p2word( word )
703762Speter     long	word;
704762Speter     {
705762Speter 
706762Speter 	putw( word , pcstream );
707762Speter     }
708762Speter 
709762Speter     /*
710762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
711762Speter      */
712762Speter p2string( string )
713762Speter     char	*string;
714762Speter     {
715762Speter 	int	slen = strlen( string );
716762Speter 	int	wlen = ( slen + 3 ) / 4;
717762Speter 	int	plen = ( wlen * 4 ) - slen;
718762Speter 	char	*cp;
719762Speter 	int	p;
720762Speter 
721762Speter 	for ( cp = string ; *cp ; cp++ )
722762Speter 	    putc( *cp , pcstream );
723762Speter 	for ( p = 1 ; p <= plen ; p++ )
724762Speter 	    putc( '\0' , pcstream );
725762Speter #	ifdef DEBUG
726762Speter 	    if ( opt( 'k' ) ) {
727762Speter 		fprintf( stdout , "\"%s" , string );
728762Speter 		for ( p = 1 ; p <= plen ; p++ )
729762Speter 		    fprintf( stdout , "\\0" );
730762Speter 		fprintf( stdout , "\"\n" );
731762Speter 	    }
732762Speter #	endif
733762Speter     }
734762Speter 
735762Speter     /*
736762Speter      *	puts a name on the pcstream
737762Speter      */
738762Speter p2name( name )
739762Speter     char	*name;
740762Speter     {
741762Speter 	int	pad;
742762Speter 
743762Speter 	fprintf( pcstream , NAMEFORMAT , name );
744762Speter 	pad = strlen( name ) % sizeof (long);
745762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
746762Speter 	    putc( '\0' , pcstream );
747762Speter 	}
748762Speter #	ifdef DEBUG
749762Speter 	    if ( opt( 'k' ) ) {
750762Speter 		fprintf( stdout , NAMEFORMAT , name );
751762Speter 		pad = strlen( name ) % sizeof (long);
752762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
753762Speter 		    fprintf( stdout , "\\0" );
754762Speter 		}
755762Speter 		fprintf( stdout , "\n" );
756762Speter 	    }
757762Speter #	endif
758762Speter     }
759762Speter 
760762Speter     /*
761762Speter      *	put out a jump to a label
762762Speter      */
763762Speter putjbr( label )
764762Speter     long	label;
765762Speter     {
766762Speter 
767762Speter 	printjbr( LABELPREFIX , label );
768762Speter     }
769762Speter 
770762Speter     /*
771762Speter      *	put out a jump to any kind of label
772762Speter      */
773762Speter printjbr( prefix , label )
774762Speter     char	*prefix;
775762Speter     long	label;
776762Speter     {
777762Speter 
77810653Speter #	ifdef vax
77910653Speter 	    putprintf( "	jbr	" , 1 );
78010653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
78110653Speter #	endif vax
78210653Speter #	ifdef mc68000
78310653Speter 	    putprintf( "	jra	" , 1 );
78410653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
78510653Speter #	endif mc68000
786762Speter     }
787762Speter 
788762Speter     /*
789762Speter      *	another version of put to catch calls to put
790762Speter      */
791762Speter put( arg1 , arg2 )
792762Speter     {
793762Speter 
79410653Speter 	panic("put()");
795762Speter     }
796762Speter 
797762Speter #endif PC
798