xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 18462)
1762Speter /* Copyright (c) 1979 Regents of the University of California */
2762Speter 
315953Smckusick #ifndef lint
4*18462Sralph static	char sccsid[] = "@(#)p2put.c 2.2 03/20/85";
515953Smckusick #endif
6762Speter 
7762Speter     /*
8762Speter      *	functions to help pi put out
9762Speter      *	polish postfix binary portable c compiler intermediate code
10762Speter      *	thereby becoming the portable pascal compiler
11762Speter      */
12762Speter 
13762Speter #include	"whoami.h"
14762Speter #ifdef PC
15762Speter #include	"0.h"
1610653Speter #include	"objfmt.h"
17*18462Sralph #include	<pcc.h>
18762Speter #include	"pc.h"
1910653Speter #include	"align.h"
2011329Speter #include	"tmps.h"
21762Speter 
22762Speter     /*
23762Speter      *	emits an ftext operator and a string to the pcstream
24762Speter      */
25762Speter puttext( string )
26762Speter     char	*string;
27762Speter     {
28762Speter 	int	length = str4len( string );
29762Speter 
303316Speter 	if ( !CGENNING )
31762Speter 	    return;
32*18462Sralph 	p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) );
33762Speter #	ifdef DEBUG
34762Speter 	    if ( opt( 'k' ) ) {
35*18462Sralph 		fprintf( stdout , "PCCF_FTEXT | %3d | 0	" , length );
36762Speter 	    }
37762Speter #	endif
38762Speter 	p2string( string );
39762Speter     }
40762Speter 
41762Speter int
42762Speter str4len( string )
43762Speter     char	*string;
44762Speter     {
45762Speter 
46762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
47762Speter     }
48762Speter 
49762Speter     /*
50762Speter      *	put formatted text into a buffer for printing to the pcstream.
51762Speter      *	a call to putpflush actually puts out the text.
52762Speter      *	none of arg1 .. arg5 need be present.
53762Speter      *	and you can add more if you need them.
54762Speter      */
5515953Smckusick /* VARARGS */
56762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
57762Speter     char	*format;
58762Speter     int		incomplete;
59762Speter     {
60762Speter 	static char	ppbuffer[ BUFSIZ ];
61762Speter 	static char	*ppbufp = ppbuffer;
62762Speter 
633316Speter 	if ( !CGENNING )
64762Speter 	    return;
65762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
66762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
67762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
68762Speter 	    panic( "putprintf" );
69762Speter 	if ( ! incomplete ) {
70762Speter 	    puttext( ppbuffer );
71762Speter 	    ppbufp = ppbuffer;
72762Speter 	}
73762Speter     }
74762Speter 
75762Speter     /*
76762Speter      *	emit a left bracket operator to pcstream
77762Speter      *	with function number, the maximum temp register, and total local bytes
78762Speter      */
7911329Speter putlbracket(ftnno, sizesp)
8011329Speter     int		ftnno;
8111329Speter     struct om	*sizesp;
8211329Speter {
8311329Speter     int	maxtempreg;
8411329Speter     int	alignedframesize;
85762Speter 
8611329Speter #   ifdef vax
8711329Speter 	maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL];
8811329Speter #   endif vax
8911329Speter #   ifdef mc68000
9011329Speter 	    /*
9114906Speter 	     *	this is how /lib/f1 wants it.
9211329Speter 	     */
9314906Speter 	maxtempreg =	(sizesp->curtmps.next_avail[REG_ADDR] << 4)
9414906Speter 		      | (sizesp->curtmps.next_avail[REG_DATA]);
9511329Speter #   endif mc68000
9615953Smckusick     alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off),
9715953Smckusick 	(long)(BITSPERBYTE * A_STACK));
98*18462Sralph     p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) );
9911329Speter     p2word(alignedframesize);
10011329Speter #   ifdef DEBUG
10111329Speter 	if ( opt( 'k' ) ) {
102*18462Sralph 	    fprintf(stdout, "PCCF_FLBRAC | %3d | %d	%d\n",
10311329Speter 		maxtempreg, ftnno, alignedframesize);
10411329Speter 	}
10511329Speter #   endif
10611329Speter }
107762Speter 
108762Speter     /*
109762Speter      *	emit a right bracket operator
11014906Speter      *	which for the binary interface
111762Speter      *	forces the stack allocate and register mask
112762Speter      */
113762Speter putrbracket( ftnno )
114762Speter     int	ftnno;
115762Speter     {
116762Speter 
117*18462Sralph 	p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) );
118762Speter #	ifdef DEBUG
119762Speter 	    if ( opt( 'k' ) ) {
120*18462Sralph 		fprintf( stdout , "PCCF_FRBRAC |   0 | %d\n" , ftnno );
121762Speter 	    }
122762Speter #	endif
123762Speter     }
124762Speter 
125762Speter     /*
126762Speter      *	emit an eof operator
127762Speter      */
128762Speter puteof()
129762Speter     {
130762Speter 
131*18462Sralph 	p2word( PCCF_FEOF );
132762Speter #	ifdef DEBUG
133762Speter 	    if ( opt( 'k' ) ) {
134*18462Sralph 		fprintf( stdout , "PCCF_FEOF\n" );
135762Speter 	    }
136762Speter #	endif
137762Speter     }
138762Speter 
139762Speter     /*
140762Speter      *	emit a dot operator,
141762Speter      *	with a source file line number and name
142762Speter      *	if line is negative, there was an error on that line, but who cares?
143762Speter      */
144762Speter putdot( filename , line )
145762Speter     char	*filename;
146762Speter     int		line;
147762Speter     {
148762Speter 	int	length = str4len( filename );
149762Speter 
150762Speter 	if ( line < 0 ) {
151762Speter 	    line = -line;
152762Speter 	}
153*18462Sralph 	p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) );
154762Speter #	ifdef DEBUG
155762Speter 	    if ( opt( 'k' ) ) {
156*18462Sralph 		fprintf( stdout , "PCCF_FEXPR | %3d | %d	" , length , line );
157762Speter 	    }
158762Speter #	endif
159762Speter 	p2string( filename );
160762Speter     }
161762Speter 
162762Speter     /*
163762Speter      *	put out a leaf node
164762Speter      */
165762Speter putleaf( op , lval , rval , type , name )
166762Speter     int		op;
167762Speter     int		lval;
168762Speter     int		rval;
169762Speter     int		type;
170762Speter     char	*name;
171762Speter     {
1723316Speter 	if ( !CGENNING )
173762Speter 	    return;
174762Speter 	switch ( op ) {
175762Speter 	    default:
176762Speter 		panic( "[putleaf]" );
177*18462Sralph 	    case PCC_ICON:
178*18462Sralph 		p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) );
179762Speter 		p2word( lval );
180762Speter #		ifdef DEBUG
181762Speter 		    if ( opt( 'k' ) ) {
182*18462Sralph 			fprintf( stdout , "PCC_ICON | %3d | 0x%x	"
183762Speter 			       , name != NIL , type );
184762Speter 			fprintf( stdout , "%d\n" , lval );
185762Speter 		    }
186762Speter #		endif
187762Speter 		if ( name )
188762Speter 		    p2name( name );
189762Speter 		break;
190*18462Sralph 	    case PCC_NAME:
191*18462Sralph 		p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) );
192762Speter 		if ( lval )
193762Speter 		    p2word( lval );
194762Speter #		ifdef DEBUG
195762Speter 		    if ( opt( 'k' ) ) {
196*18462Sralph 			fprintf( stdout , "PCC_NAME | %3d | 0x%x	"
197762Speter 			       , lval != 0 , type );
198762Speter 			if ( lval )
199762Speter 			    fprintf( stdout , "%d	" , lval );
200762Speter 		    }
201762Speter #		endif
202762Speter 		p2name( name );
203762Speter 		break;
204*18462Sralph 	    case PCC_REG:
205*18462Sralph 		p2word( PCCM_TRIPLE( PCC_REG , rval , type ) );
206762Speter #		ifdef DEBUG
207762Speter 		    if ( opt( 'k' ) ) {
208*18462Sralph 			fprintf( stdout , "PCC_REG | %3d | 0x%x\n" ,
2092474Speter 				rval , type );
210762Speter 		    }
211762Speter #		endif
212762Speter 		break;
213762Speter 	}
214762Speter     }
215762Speter 
216762Speter     /*
217762Speter      *	rvalues are just lvalues with indirection, except
2183829Speter      *	special cases for registers and for named globals,
2193829Speter      *	whose names are their rvalues.
220762Speter      */
2217924Smckusick putRV( name , level , offset , other_flags , type )
222762Speter     char	*name;
223762Speter     int		level;
224762Speter     int		offset;
2257924Smckusick     char	other_flags;
226762Speter     int		type;
227762Speter     {
228762Speter 	char	extname[ BUFSIZ ];
229762Speter 	char	*printname;
230762Speter 
2313316Speter 	if ( !CGENNING )
232762Speter 	    return;
2337924Smckusick 	if ( other_flags & NREGVAR ) {
2343829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
2353829Speter 		panic( "putRV regvar" );
2363582Speter 	    }
237*18462Sralph 	    putleaf( PCC_REG , 0 , offset , type , (char *) 0 );
2383277Smckusic 	    return;
2393277Smckusic 	}
24015953Smckusick 	if ( whereis( offset , other_flags ) == GLOBALVAR ) {
2413829Speter 	    if ( name != 0 ) {
2423829Speter 		if ( name[0] != '_' ) {
2433829Speter 			sprintf( extname , EXTFORMAT , name );
2443829Speter 			printname = extname;
2453829Speter 		} else {
2463829Speter 			printname = name;
2473829Speter 		}
248*18462Sralph 		putleaf( PCC_NAME , offset , 0 , type , printname );
2493829Speter 		return;
250762Speter 	    } else {
2513829Speter 		panic( "putRV no name" );
252762Speter 	    }
253762Speter 	}
2547924Smckusick 	putLV( name , level , offset , other_flags , type );
255*18462Sralph 	putop( PCCOM_UNARY PCC_MUL , type );
256762Speter     }
257762Speter 
258762Speter     /*
259762Speter      *	put out an lvalue
260762Speter      *	given a level and offset
261762Speter      *	special case for
262762Speter      *	    named globals, whose lvalues are just their names as constants.
263762Speter      */
2647924Smckusick putLV( name , level , offset , other_flags , type )
265762Speter     char	*name;
266762Speter     int		level;
267762Speter     int		offset;
2687924Smckusick     char	other_flags;
269762Speter     int		type;
2703277Smckusic {
2713277Smckusic     char		extname[ BUFSIZ ];
2723277Smckusic     char		*printname;
273762Speter 
2743316Speter     if ( !CGENNING )
2753277Smckusic 	return;
2767924Smckusick     if ( other_flags & NREGVAR ) {
2773829Speter 	panic( "putLV regvar" );
278762Speter     }
27915953Smckusick     switch ( whereis( offset , other_flags ) ) {
2803829Speter 	case GLOBALVAR:
2813829Speter 	    if ( ( name != 0 ) ) {
2823829Speter 		if ( name[0] != '_' ) {
2833829Speter 			sprintf( extname , EXTFORMAT , name );
2843829Speter 			printname = extname;
2853829Speter 		} else {
2863829Speter 			printname = name;
2873829Speter 		}
288*18462Sralph 		putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR )
2893829Speter 			, printname );
2903829Speter 		return;
2913829Speter 	    } else {
2923829Speter 		panic( "putLV no name" );
2933829Speter 	    }
2943277Smckusic 	case PARAMVAR:
2953277Smckusic 	    if ( level == cbn ) {
296*18462Sralph 		putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
2973277Smckusic 	    } else {
298*18462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
299*18462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3009128Smckusick 		parts[ level ] |= NONLOCALVAR;
3013277Smckusic 	    }
302*18462Sralph 	    putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 );
303*18462Sralph 	    putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR );
3043277Smckusic 	    break;
3053277Smckusic 	case LOCALVAR:
3063277Smckusic 	    if ( level == cbn ) {
307*18462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3083277Smckusic 	    } else {
309*18462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
310*18462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3119128Smckusick 		parts[ level ] |= NONLOCALVAR;
3123277Smckusic 	    }
313*18462Sralph 	    putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 );
314*18462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3153277Smckusic 	    break;
3169128Smckusick 	case NAMEDLOCALVAR:
3179128Smckusick 	    if ( level == cbn ) {
318*18462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3199128Smckusick 	    } else {
320*18462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
321*18462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3229128Smckusick 		parts[ level ] |= NONLOCALVAR;
3239128Smckusick 	    }
324*18462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name );
325*18462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3269128Smckusick 	    break;
3273277Smckusic     }
3283277Smckusic     return;
3293277Smckusic }
330762Speter 
331762Speter     /*
332762Speter      *	put out a floating point constant leaf node
333762Speter      *	the constant is declared in aligned data space
334*18462Sralph      *	and a PCC_NAME leaf put out for it
335762Speter      */
3367924Smckusick putCON8( val )
3377924Smckusick     double	val;
338762Speter     {
33915953Smckusick 	char	*label;
340762Speter 	char	name[ BUFSIZ ];
341762Speter 
3423316Speter 	if ( !CGENNING )
343762Speter 	    return;
34410653Speter 	label = getlab();
345762Speter 	putprintf( "	.data" , 0 );
34610653Speter 	aligndot(A_DOUBLE);
34715953Smckusick 	(void) putlab( label );
34810653Speter #	ifdef vax
34910653Speter 	    putprintf( "	.double 0d%.20e" , 0 , val );
35010653Speter #	endif vax
35110653Speter #	ifdef mc68000
35210653Speter 	    putprintf( "	.long 	0x%x,0x%x", 0, val);
35310653Speter #	endif mc68000
354762Speter 	putprintf( "	.text" , 0 );
355762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
356*18462Sralph 	putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name );
357762Speter     }
358762Speter 
359762Speter 	/*
360762Speter 	 * put out either an lvalue or an rvalue for a constant string.
361762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
362762Speter 	 * an rvalue (for parameters) is just the name.
363762Speter 	 */
364762Speter putCONG( string , length , required )
365762Speter     char	*string;
366762Speter     int		length;
367762Speter     int		required;
368762Speter     {
369762Speter 	char	name[ BUFSIZ ];
37015953Smckusick 	char	*label;
371762Speter 	char	*cp;
372762Speter 	int	pad;
373762Speter 	int	others;
374762Speter 
3753316Speter 	if ( !CGENNING )
376762Speter 	    return;
377762Speter 	putprintf( "	.data" , 0 );
37810653Speter 	aligndot(A_STRUCT);
379762Speter 	label = getlab();
38015953Smckusick 	(void) putlab( label );
381762Speter 	cp = string;
382762Speter 	while ( *cp ) {
383762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
384762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
385762Speter 		putprintf( ",0%o" , 1 , *cp++ );
386762Speter 	    }
387762Speter 	    putprintf( "" , 0 );
388762Speter 	}
389762Speter 	pad = length - strlen( string );
390762Speter 	while ( pad-- > 0 ) {
391762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
392762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
393762Speter 		putprintf( ",0%o" , 1 , ' ' );
394762Speter 	    }
395762Speter 	    putprintf( "" , 0 );
396762Speter 	}
397762Speter 	putprintf( "	.byte	0" , 0 );
398762Speter 	putprintf( "	.text"  , 0 );
399762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
400762Speter 	if ( required == RREQ ) {
401*18462Sralph 	    putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name );
402762Speter 	} else {
403*18462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name );
404762Speter 	}
405762Speter     }
406762Speter 
407762Speter     /*
408762Speter      *	map a pascal type to a c type
409762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
410762Speter      *	this is sort of like isa and lwidth
411762Speter      *	a note on the types used by the portable c compiler:
412762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
413762Speter      *	    and qualifications on those basic types (pointer, function, array).
414762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
415762Speter      *	    and the qualifications are arranged in two bit chunks, with the
416762Speter      *	    most significant on the right,
417762Speter      *	    and the least significant on the left
418762Speter      *		e.g. int *foo();
419762Speter      *			(a function returning a pointer to an integer)
420762Speter      *		is stored as
421762Speter      *		    <ptr><ftn><int>
422762Speter      *	so, we build types recursively
4231478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4241478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4251478Speter      *	through mutually recursive pointer types.
426762Speter      */
4271478Speter #define	MAXQUALS	6
428762Speter int
429762Speter p2type( np )
43015953Smckusick     struct nl	*np;
4311478Speter {
4321478Speter 
4331478Speter     return typerecur( np , 0 );
4341478Speter }
4351478Speter typerecur( np , quals )
4361478Speter     struct nl	*np;
4371478Speter     int		quals;
438762Speter     {
439762Speter 
4401478Speter 	if ( np == NIL || quals > MAXQUALS ) {
441*18462Sralph 	    return PCCT_UNDEF;
4421478Speter 	}
443762Speter 	switch ( np -> class ) {
444762Speter 	    case SCAL :
445762Speter 	    case RANGE :
44615974Smckusick 	    case CRANGE :
447762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
448*18462Sralph 		    return PCCT_DOUBLE;
449762Speter 		}
450762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
451762Speter 		    case 1:
452*18462Sralph 			return PCCT_CHAR;
453762Speter 		    case 2:
454*18462Sralph 			return PCCT_SHORT;
455762Speter 		    case 4:
456*18462Sralph 			return PCCT_INT;
457762Speter 		    default:
458762Speter 			panic( "p2type int" );
45915953Smckusick 			/* NOTREACHED */
460762Speter 		}
461762Speter 	    case STR :
462*18462Sralph 		return ( PCCTM_ARY | PCCT_CHAR );
463762Speter 	    case RECORD :
464762Speter 	    case SET :
465*18462Sralph 		return PCCT_STRTY;
466762Speter 	    case FILET :
467*18462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
468762Speter 	    case CONST :
469762Speter 	    case VAR :
470762Speter 	    case FIELD :
471762Speter 		return p2type( np -> type );
472762Speter 	    case TYPE :
473762Speter 		switch ( nloff( np ) ) {
474762Speter 		    case TNIL :
475*18462Sralph 			return ( PCCTM_PTR | PCCT_UNDEF );
476762Speter 		    case TSTR :
477*18462Sralph 			return ( PCCTM_ARY | PCCT_CHAR );
478762Speter 		    case TSET :
479*18462Sralph 			return PCCT_STRTY;
480762Speter 		    default :
481762Speter 			return ( p2type( np -> type ) );
482762Speter 		}
483762Speter 	    case REF:
484762Speter 	    case WITHPTR:
485762Speter 	    case PTR :
486*18462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR );
487762Speter 	    case ARRAY :
488*18462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY );
489762Speter 	    case FUNC :
490762Speter 		    /*
491762Speter 		     * functions are really pointers to functions
492762Speter 		     * which return their underlying type.
493762Speter 		     */
494*18462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) ,
495*18462Sralph 					PCCTM_FTN ) , PCCTM_PTR );
496762Speter 	    case PROC :
497762Speter 		    /*
498762Speter 		     * procedures are pointers to functions
499762Speter 		     * which return integers (whether you look at them or not)
500762Speter 		     */
501*18462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR );
5021197Speter 	    case FFUNC :
5031197Speter 	    case FPROC :
5041197Speter 		    /*
5051197Speter 		     *	formal procedures and functions are pointers
5061197Speter 		     *	to structures which describe their environment.
5071197Speter 		     */
508*18462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
509762Speter 	    default :
510762Speter 		panic( "p2type" );
51115953Smckusick 		/* NOTREACHED */
512762Speter 	}
513762Speter     }
514762Speter 
515762Speter     /*
516762Speter      *	put a typed operator to the pcstream
517762Speter      */
518762Speter putop( op , type )
519762Speter     int		op;
520762Speter     int		type;
521762Speter     {
522*18462Sralph 	extern char	*p2opname();
523762Speter 
5243316Speter 	if ( !CGENNING )
525762Speter 	    return;
526*18462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
527762Speter #	ifdef DEBUG
528762Speter 	    if ( opt( 'k' ) ) {
5292474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
530*18462Sralph 			, p2opname( op ) , op , type );
531762Speter 	    }
532762Speter #	endif
533762Speter     }
534762Speter 
535762Speter     /*
536762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
537762Speter      *	which looks just like a regular operator, only the size and
538762Speter      *	alignment go in the next consecutive words
539762Speter      */
540762Speter putstrop( op , type , size , alignment )
541762Speter     int	op;
542762Speter     int	type;
543762Speter     int	size;
544762Speter     int	alignment;
545762Speter     {
546*18462Sralph 	extern char	*p2opname();
547762Speter 
5483316Speter 	if ( !CGENNING )
549762Speter 	    return;
550*18462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
551762Speter 	p2word( size );
552762Speter 	p2word( alignment );
553762Speter #	ifdef DEBUG
554762Speter 	    if ( opt( 'k' ) ) {
5552474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
556*18462Sralph 			, p2opname( op ) , op , type , size , alignment );
557762Speter 	    }
558762Speter #	endif
559762Speter     }
560762Speter 
561762Speter     /*
562762Speter      *	the string names of p2ops
563762Speter      */
564*18462Sralph 
565*18462Sralph struct p2op {
566*18462Sralph     int op;
567*18462Sralph     char *name;
568*18462Sralph };
569*18462Sralph 
570*18462Sralph static struct p2op	p2opnames[] = {
571*18462Sralph 	PCC_ERROR, "PCC_ERROR",
572*18462Sralph 	PCC_NAME, "PCC_NAME",
573*18462Sralph 	PCC_STRING, "PCC_STRING",
574*18462Sralph 	PCC_ICON, "PCC_ICON",
575*18462Sralph 	PCC_FCON, "PCC_FCON",
576*18462Sralph 	PCC_PLUS, "PCC_PLUS",
577*18462Sralph 	PCC_MINUS, "PCC_MINUS",
578*18462Sralph 	PCC_UMINUS, "PCC_UMINUS",
579*18462Sralph 	PCC_MUL, "PCC_MUL",
580*18462Sralph 	PCC_DEREF, "PCC_DEREF",
581*18462Sralph 	PCC_AND, "PCC_AND",
582*18462Sralph 	PCC_ADDROF, "PCC_ADDROF",
583*18462Sralph 	PCC_OR, "PCC_OR",
584*18462Sralph 	PCC_ER, "PCC_ER",
585*18462Sralph 	PCC_QUEST, "PCC_QUEST",
586*18462Sralph 	PCC_COLON, "PCC_COLON",
587*18462Sralph 	PCC_ANDAND, "PCC_ANDAND",
588*18462Sralph 	PCC_OROR, "PCC_OROR",
589*18462Sralph 	PCC_CM, "PCC_CM",
590*18462Sralph 	PCC_ASSIGN, "PCC_ASSIGN",
591*18462Sralph 	PCC_COMOP, "PCC_COMOP",
592*18462Sralph 	PCC_DIV, "PCC_DIV",
593*18462Sralph 	PCC_MOD, "PCC_MOD",
594*18462Sralph 	PCC_LS, "PCC_LS",
595*18462Sralph 	PCC_RS, "PCC_RS",
596*18462Sralph 	PCC_DOT, "PCC_DOT",
597*18462Sralph 	PCC_STREF, "PCC_STREF",
598*18462Sralph 	PCC_CALL, "PCC_CALL",
599*18462Sralph 	PCC_UCALL, "PCC_UCALL",
600*18462Sralph 	PCC_FORTCALL, "PCC_FORTCALL",
601*18462Sralph 	PCC_UFORTCALL, "PCC_UFORTCALL",
602*18462Sralph 	PCC_NOT, "PCC_NOT",
603*18462Sralph 	PCC_COMPL, "PCC_COMPL",
604*18462Sralph 	PCC_INCR, "PCC_INCR",
605*18462Sralph 	PCC_DECR, "PCC_DECR",
606*18462Sralph 	PCC_EQ, "PCC_EQ",
607*18462Sralph 	PCC_NE, "PCC_NE",
608*18462Sralph 	PCC_LE, "PCC_LE",
609*18462Sralph 	PCC_LT, "PCC_LT",
610*18462Sralph 	PCC_GE, "PCC_GE",
611*18462Sralph 	PCC_GT, "PCC_GT",
612*18462Sralph 	PCC_ULE, "PCC_ULE",
613*18462Sralph 	PCC_ULT, "PCC_ULT",
614*18462Sralph 	PCC_UGE, "PCC_UGE",
615*18462Sralph 	PCC_UGT, "PCC_UGT",
616*18462Sralph 	PCC_REG, "PCC_REG",
617*18462Sralph 	PCC_OREG, "PCC_OREG",
618*18462Sralph 	PCC_CCODES, "PCC_CCODES",
619*18462Sralph 	PCC_FREE, "PCC_FREE",
620*18462Sralph 	PCC_STASG, "PCC_STASG",
621*18462Sralph 	PCC_STARG, "PCC_STARG",
622*18462Sralph 	PCC_STCALL, "PCC_STCALL",
623*18462Sralph 	PCC_USTCALL, "PCC_USTCALL",
624*18462Sralph 	PCC_FLD, "PCC_FLD",
625*18462Sralph 	PCC_SCONV, "PCC_SCONV",
626*18462Sralph 	PCC_PCONV, "PCC_PCONV",
627*18462Sralph 	PCC_PMCONV, "PCC_PMCONV",
628*18462Sralph 	PCC_PVCONV, "PCC_PVCONV",
629*18462Sralph 	PCC_FORCE, "PCC_FORCE",
630*18462Sralph 	PCC_CBRANCH, "PCC_CBRANCH",
631*18462Sralph 	PCC_INIT, "PCC_INIT",
632*18462Sralph 	PCC_CAST, "PCC_CAST",
633*18462Sralph 	-1, ""
634762Speter     };
635*18462Sralph 
636*18462Sralph char *
637*18462Sralph p2opname( op )
638*18462Sralph     register int	op;
639*18462Sralph     {
640*18462Sralph 	static char		*p2map[PCC_MAXOP+1];
641*18462Sralph 	static bool		mapready = FALSE;
642*18462Sralph 	register struct p2op	*pp;
643*18462Sralph 
644*18462Sralph 	if ( mapready == FALSE ) {
645*18462Sralph 	    for ( pp = p2opnames; pp->op >= 0; pp++ )
646*18462Sralph 		p2map[ pp->op ] = pp->name;
647*18462Sralph 	    mapready = TRUE;
648*18462Sralph 	}
649*18462Sralph 	return ( p2map[ op ] ? p2map[ op ] : "unknown" );
650*18462Sralph     }
651762Speter 
652762Speter     /*
653762Speter      *	low level routines
654762Speter      */
655762Speter 
656762Speter     /*
657762Speter      *	puts a long word on the pcstream
658762Speter      */
659762Speter p2word( word )
66015953Smckusick     int		word;
661762Speter     {
662762Speter 
663762Speter 	putw( word , pcstream );
664762Speter     }
665762Speter 
666762Speter     /*
667762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
668762Speter      */
669762Speter p2string( string )
670762Speter     char	*string;
671762Speter     {
672762Speter 	int	slen = strlen( string );
673762Speter 	int	wlen = ( slen + 3 ) / 4;
674762Speter 	int	plen = ( wlen * 4 ) - slen;
675762Speter 	char	*cp;
676762Speter 	int	p;
677762Speter 
678762Speter 	for ( cp = string ; *cp ; cp++ )
679762Speter 	    putc( *cp , pcstream );
680762Speter 	for ( p = 1 ; p <= plen ; p++ )
681762Speter 	    putc( '\0' , pcstream );
682762Speter #	ifdef DEBUG
683762Speter 	    if ( opt( 'k' ) ) {
684762Speter 		fprintf( stdout , "\"%s" , string );
685762Speter 		for ( p = 1 ; p <= plen ; p++ )
686762Speter 		    fprintf( stdout , "\\0" );
687762Speter 		fprintf( stdout , "\"\n" );
688762Speter 	    }
689762Speter #	endif
690762Speter     }
691762Speter 
692762Speter     /*
693762Speter      *	puts a name on the pcstream
694762Speter      */
695762Speter p2name( name )
696762Speter     char	*name;
697762Speter     {
698762Speter 	int	pad;
699762Speter 
700762Speter 	fprintf( pcstream , NAMEFORMAT , name );
701762Speter 	pad = strlen( name ) % sizeof (long);
702762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
703762Speter 	    putc( '\0' , pcstream );
704762Speter 	}
705762Speter #	ifdef DEBUG
706762Speter 	    if ( opt( 'k' ) ) {
707762Speter 		fprintf( stdout , NAMEFORMAT , name );
708762Speter 		pad = strlen( name ) % sizeof (long);
709762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
710762Speter 		    fprintf( stdout , "\\0" );
711762Speter 		}
712762Speter 		fprintf( stdout , "\n" );
713762Speter 	    }
714762Speter #	endif
715762Speter     }
716762Speter 
717762Speter     /*
718762Speter      *	put out a jump to a label
719762Speter      */
720762Speter putjbr( label )
721762Speter     long	label;
722762Speter     {
723762Speter 
724762Speter 	printjbr( LABELPREFIX , label );
725762Speter     }
726762Speter 
727762Speter     /*
728762Speter      *	put out a jump to any kind of label
729762Speter      */
730762Speter printjbr( prefix , label )
731762Speter     char	*prefix;
732762Speter     long	label;
733762Speter     {
734762Speter 
73510653Speter #	ifdef vax
73610653Speter 	    putprintf( "	jbr	" , 1 );
73710653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
73810653Speter #	endif vax
73910653Speter #	ifdef mc68000
74010653Speter 	    putprintf( "	jra	" , 1 );
74110653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
74210653Speter #	endif mc68000
743762Speter     }
744762Speter 
745762Speter     /*
746762Speter      *	another version of put to catch calls to put
747762Speter      */
74815953Smckusick /* VARARGS */
74915953Smckusick put()
750762Speter     {
751762Speter 
75210653Speter 	panic("put()");
753762Speter     }
754762Speter 
755762Speter #endif PC
756