xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 30035)
122180Sdist /*
222180Sdist  * Copyright (c) 1980 Regents of the University of California.
322180Sdist  * All rights reserved.  The Berkeley software License Agreement
422180Sdist  * specifies the terms and conditions for redistribution.
522180Sdist  */
6762Speter 
715953Smckusick #ifndef lint
8*30035Smckusick static char sccsid[] = "@(#)p2put.c	5.4 (Berkeley) 11/12/86";
923527Smckusick #endif not lint
1023527Smckusick 
11762Speter     /*
12762Speter      *	functions to help pi put out
13762Speter      *	polish postfix binary portable c compiler intermediate code
14762Speter      *	thereby becoming the portable pascal compiler
15762Speter      */
16762Speter 
17762Speter #include	"whoami.h"
18762Speter #ifdef PC
19762Speter #include	"0.h"
2010653Speter #include	"objfmt.h"
2118462Sralph #include	<pcc.h>
22762Speter #include	"pc.h"
2310653Speter #include	"align.h"
2411329Speter #include	"tmps.h"
25762Speter 
26762Speter     /*
27762Speter      *	emits an ftext operator and a string to the pcstream
28762Speter      */
29762Speter puttext( string )
30762Speter     char	*string;
31762Speter     {
32762Speter 	int	length = str4len( string );
33762Speter 
343316Speter 	if ( !CGENNING )
35762Speter 	    return;
3618462Sralph 	p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) );
37762Speter #	ifdef DEBUG
38762Speter 	    if ( opt( 'k' ) ) {
3918462Sralph 		fprintf( stdout , "PCCF_FTEXT | %3d | 0	" , length );
40762Speter 	    }
41762Speter #	endif
42762Speter 	p2string( string );
43762Speter     }
44762Speter 
45762Speter int
46762Speter str4len( string )
47762Speter     char	*string;
48762Speter     {
49762Speter 
50762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
51762Speter     }
52762Speter 
53762Speter     /*
54762Speter      *	put formatted text into a buffer for printing to the pcstream.
55762Speter      *	a call to putpflush actually puts out the text.
56762Speter      *	none of arg1 .. arg5 need be present.
57762Speter      *	and you can add more if you need them.
58762Speter      */
5915953Smckusick /* VARARGS */
60762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
61762Speter     char	*format;
62762Speter     int		incomplete;
63762Speter     {
64762Speter 	static char	ppbuffer[ BUFSIZ ];
65762Speter 	static char	*ppbufp = ppbuffer;
66762Speter 
673316Speter 	if ( !CGENNING )
68762Speter 	    return;
69762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
70762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
71762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
72762Speter 	    panic( "putprintf" );
73762Speter 	if ( ! incomplete ) {
74762Speter 	    puttext( ppbuffer );
75762Speter 	    ppbufp = ppbuffer;
76762Speter 	}
77762Speter     }
78762Speter 
79762Speter     /*
80762Speter      *	emit a left bracket operator to pcstream
81762Speter      *	with function number, the maximum temp register, and total local bytes
82762Speter      */
8311329Speter putlbracket(ftnno, sizesp)
8411329Speter     int		ftnno;
8511329Speter     struct om	*sizesp;
8611329Speter {
8711329Speter     int	maxtempreg;
8811329Speter     int	alignedframesize;
89762Speter 
90*30035Smckusick #   if defined(vax) || defined(tahoe)
9111329Speter 	maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL];
92*30035Smckusick #   endif vax || tahoe
9311329Speter #   ifdef mc68000
9411329Speter 	    /*
9514906Speter 	     *	this is how /lib/f1 wants it.
9611329Speter 	     */
9714906Speter 	maxtempreg =	(sizesp->curtmps.next_avail[REG_ADDR] << 4)
9814906Speter 		      | (sizesp->curtmps.next_avail[REG_DATA]);
9911329Speter #   endif mc68000
10015953Smckusick     alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off),
10115953Smckusick 	(long)(BITSPERBYTE * A_STACK));
10218462Sralph     p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) );
10311329Speter     p2word(alignedframesize);
10411329Speter #   ifdef DEBUG
10511329Speter 	if ( opt( 'k' ) ) {
10618462Sralph 	    fprintf(stdout, "PCCF_FLBRAC | %3d | %d	%d\n",
10711329Speter 		maxtempreg, ftnno, alignedframesize);
10811329Speter 	}
10911329Speter #   endif
11011329Speter }
111762Speter 
112762Speter     /*
113762Speter      *	emit a right bracket operator
11414906Speter      *	which for the binary interface
115762Speter      *	forces the stack allocate and register mask
116762Speter      */
117762Speter putrbracket( ftnno )
118762Speter     int	ftnno;
119762Speter     {
120762Speter 
12118462Sralph 	p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) );
122762Speter #	ifdef DEBUG
123762Speter 	    if ( opt( 'k' ) ) {
12418462Sralph 		fprintf( stdout , "PCCF_FRBRAC |   0 | %d\n" , ftnno );
125762Speter 	    }
126762Speter #	endif
127762Speter     }
128762Speter 
129762Speter     /*
130762Speter      *	emit an eof operator
131762Speter      */
132762Speter puteof()
133762Speter     {
134762Speter 
13518462Sralph 	p2word( PCCF_FEOF );
136762Speter #	ifdef DEBUG
137762Speter 	    if ( opt( 'k' ) ) {
13818462Sralph 		fprintf( stdout , "PCCF_FEOF\n" );
139762Speter 	    }
140762Speter #	endif
141762Speter     }
142762Speter 
143762Speter     /*
144762Speter      *	emit a dot operator,
145762Speter      *	with a source file line number and name
146762Speter      *	if line is negative, there was an error on that line, but who cares?
147762Speter      */
148762Speter putdot( filename , line )
149762Speter     char	*filename;
150762Speter     int		line;
151762Speter     {
152762Speter 	int	length = str4len( filename );
153762Speter 
154762Speter 	if ( line < 0 ) {
155762Speter 	    line = -line;
156762Speter 	}
15718462Sralph 	p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) );
158762Speter #	ifdef DEBUG
159762Speter 	    if ( opt( 'k' ) ) {
16018462Sralph 		fprintf( stdout , "PCCF_FEXPR | %3d | %d	" , length , line );
161762Speter 	    }
162762Speter #	endif
163762Speter 	p2string( filename );
164762Speter     }
165762Speter 
166762Speter     /*
167762Speter      *	put out a leaf node
168762Speter      */
169762Speter putleaf( op , lval , rval , type , name )
170762Speter     int		op;
171762Speter     int		lval;
172762Speter     int		rval;
173762Speter     int		type;
174762Speter     char	*name;
175762Speter     {
1763316Speter 	if ( !CGENNING )
177762Speter 	    return;
178762Speter 	switch ( op ) {
179762Speter 	    default:
180762Speter 		panic( "[putleaf]" );
18118462Sralph 	    case PCC_ICON:
18218462Sralph 		p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) );
183762Speter 		p2word( lval );
184762Speter #		ifdef DEBUG
185762Speter 		    if ( opt( 'k' ) ) {
18618462Sralph 			fprintf( stdout , "PCC_ICON | %3d | 0x%x	"
187762Speter 			       , name != NIL , type );
188762Speter 			fprintf( stdout , "%d\n" , lval );
189762Speter 		    }
190762Speter #		endif
191762Speter 		if ( name )
192762Speter 		    p2name( name );
193762Speter 		break;
19418462Sralph 	    case PCC_NAME:
19518462Sralph 		p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) );
196762Speter 		if ( lval )
197762Speter 		    p2word( lval );
198762Speter #		ifdef DEBUG
199762Speter 		    if ( opt( 'k' ) ) {
20018462Sralph 			fprintf( stdout , "PCC_NAME | %3d | 0x%x	"
201762Speter 			       , lval != 0 , type );
202762Speter 			if ( lval )
203762Speter 			    fprintf( stdout , "%d	" , lval );
204762Speter 		    }
205762Speter #		endif
206762Speter 		p2name( name );
207762Speter 		break;
20818462Sralph 	    case PCC_REG:
20918462Sralph 		p2word( PCCM_TRIPLE( PCC_REG , rval , type ) );
210762Speter #		ifdef DEBUG
211762Speter 		    if ( opt( 'k' ) ) {
21218462Sralph 			fprintf( stdout , "PCC_REG | %3d | 0x%x\n" ,
2132474Speter 				rval , type );
214762Speter 		    }
215762Speter #		endif
216762Speter 		break;
217762Speter 	}
218762Speter     }
219762Speter 
220762Speter     /*
221762Speter      *	rvalues are just lvalues with indirection, except
2223829Speter      *	special cases for registers and for named globals,
2233829Speter      *	whose names are their rvalues.
224762Speter      */
2257924Smckusick putRV( name , level , offset , other_flags , type )
226762Speter     char	*name;
227762Speter     int		level;
228762Speter     int		offset;
2297924Smckusick     char	other_flags;
230762Speter     int		type;
231762Speter     {
232762Speter 	char	extname[ BUFSIZ ];
233762Speter 	char	*printname;
234762Speter 
2353316Speter 	if ( !CGENNING )
236762Speter 	    return;
2377924Smckusick 	if ( other_flags & NREGVAR ) {
2383829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
2393829Speter 		panic( "putRV regvar" );
2403582Speter 	    }
24118462Sralph 	    putleaf( PCC_REG , 0 , offset , type , (char *) 0 );
2423277Smckusic 	    return;
2433277Smckusic 	}
24415953Smckusick 	if ( whereis( offset , other_flags ) == GLOBALVAR ) {
2453829Speter 	    if ( name != 0 ) {
2463829Speter 		if ( name[0] != '_' ) {
2473829Speter 			sprintf( extname , EXTFORMAT , name );
2483829Speter 			printname = extname;
2493829Speter 		} else {
2503829Speter 			printname = name;
2513829Speter 		}
25218462Sralph 		putleaf( PCC_NAME , offset , 0 , type , printname );
2533829Speter 		return;
254762Speter 	    } else {
2553829Speter 		panic( "putRV no name" );
256762Speter 	    }
257762Speter 	}
2587924Smckusick 	putLV( name , level , offset , other_flags , type );
25918462Sralph 	putop( PCCOM_UNARY PCC_MUL , type );
260762Speter     }
261762Speter 
262762Speter     /*
263762Speter      *	put out an lvalue
264762Speter      *	given a level and offset
265762Speter      *	special case for
266762Speter      *	    named globals, whose lvalues are just their names as constants.
267762Speter      */
2687924Smckusick putLV( name , level , offset , other_flags , type )
269762Speter     char	*name;
270762Speter     int		level;
271762Speter     int		offset;
2727924Smckusick     char	other_flags;
273762Speter     int		type;
2743277Smckusic {
2753277Smckusic     char		extname[ BUFSIZ ];
2763277Smckusic     char		*printname;
277762Speter 
2783316Speter     if ( !CGENNING )
2793277Smckusic 	return;
2807924Smckusick     if ( other_flags & NREGVAR ) {
2813829Speter 	panic( "putLV regvar" );
282762Speter     }
28315953Smckusick     switch ( whereis( offset , other_flags ) ) {
2843829Speter 	case GLOBALVAR:
2853829Speter 	    if ( ( name != 0 ) ) {
2863829Speter 		if ( name[0] != '_' ) {
2873829Speter 			sprintf( extname , EXTFORMAT , name );
2883829Speter 			printname = extname;
2893829Speter 		} else {
2903829Speter 			printname = name;
2913829Speter 		}
29218462Sralph 		putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR )
2933829Speter 			, printname );
2943829Speter 		return;
2953829Speter 	    } else {
2963829Speter 		panic( "putLV no name" );
2973829Speter 	    }
2983277Smckusic 	case PARAMVAR:
2993277Smckusic 	    if ( level == cbn ) {
30018462Sralph 		putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3013277Smckusic 	    } else {
30218462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_OFFSET
30318462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3049128Smckusick 		parts[ level ] |= NONLOCALVAR;
3053277Smckusic 	    }
30618462Sralph 	    putleaf( PCC_ICON , offset , 0 , PCCT_INT , (char *) 0 );
30718462Sralph 	    putop( PCC_PLUS , PCCTM_PTR | PCCT_CHAR );
3083277Smckusic 	    break;
3093277Smckusic 	case LOCALVAR:
3103277Smckusic 	    if ( level == cbn ) {
31118462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3123277Smckusic 	    } else {
31318462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
31418462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3159128Smckusick 		parts[ level ] |= NONLOCALVAR;
3163277Smckusic 	    }
31718462Sralph 	    putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 );
31818462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3193277Smckusic 	    break;
3209128Smckusick 	case NAMEDLOCALVAR:
3219128Smckusick 	    if ( level == cbn ) {
32218462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3239128Smckusick 	    } else {
32418462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
32518462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3269128Smckusick 		parts[ level ] |= NONLOCALVAR;
3279128Smckusick 	    }
32818462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name );
32918462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3309128Smckusick 	    break;
3313277Smckusic     }
3323277Smckusic     return;
3333277Smckusic }
334762Speter 
335762Speter     /*
336762Speter      *	put out a floating point constant leaf node
337762Speter      *	the constant is declared in aligned data space
33818462Sralph      *	and a PCC_NAME leaf put out for it
339762Speter      */
3407924Smckusick putCON8( val )
3417924Smckusick     double	val;
342762Speter     {
34315953Smckusick 	char	*label;
344762Speter 	char	name[ BUFSIZ ];
345762Speter 
3463316Speter 	if ( !CGENNING )
347762Speter 	    return;
34810653Speter 	label = getlab();
349762Speter 	putprintf( "	.data" , 0 );
35010653Speter 	aligndot(A_DOUBLE);
35115953Smckusick 	(void) putlab( label );
352*30035Smckusick #	if defined(vax) || defined(tahoe)
35310653Speter 	    putprintf( "	.double 0d%.20e" , 0 , val );
354*30035Smckusick #	endif vax || tahoe
35510653Speter #	ifdef mc68000
35610653Speter 	    putprintf( "	.long 	0x%x,0x%x", 0, val);
35710653Speter #	endif mc68000
358762Speter 	putprintf( "	.text" , 0 );
359762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
36018462Sralph 	putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name );
361762Speter     }
362762Speter 
363762Speter 	/*
364762Speter 	 * put out either an lvalue or an rvalue for a constant string.
365762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
366762Speter 	 * an rvalue (for parameters) is just the name.
367762Speter 	 */
368762Speter putCONG( string , length , required )
369762Speter     char	*string;
370762Speter     int		length;
371762Speter     int		required;
372762Speter     {
373762Speter 	char	name[ BUFSIZ ];
37415953Smckusick 	char	*label;
375762Speter 	char	*cp;
376762Speter 	int	pad;
377762Speter 	int	others;
378762Speter 
3793316Speter 	if ( !CGENNING )
380762Speter 	    return;
381762Speter 	putprintf( "	.data" , 0 );
38210653Speter 	aligndot(A_STRUCT);
383762Speter 	label = getlab();
38415953Smckusick 	(void) putlab( label );
385762Speter 	cp = string;
386762Speter 	while ( *cp ) {
387762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
388762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
389762Speter 		putprintf( ",0%o" , 1 , *cp++ );
390762Speter 	    }
391762Speter 	    putprintf( "" , 0 );
392762Speter 	}
393762Speter 	pad = length - strlen( string );
394762Speter 	while ( pad-- > 0 ) {
395762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
396762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
397762Speter 		putprintf( ",0%o" , 1 , ' ' );
398762Speter 	    }
399762Speter 	    putprintf( "" , 0 );
400762Speter 	}
401762Speter 	putprintf( "	.byte	0" , 0 );
402762Speter 	putprintf( "	.text"  , 0 );
403762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
404762Speter 	if ( required == RREQ ) {
40518462Sralph 	    putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name );
406762Speter 	} else {
40718462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name );
408762Speter 	}
409762Speter     }
410762Speter 
411762Speter     /*
412762Speter      *	map a pascal type to a c type
413762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
414762Speter      *	this is sort of like isa and lwidth
415762Speter      *	a note on the types used by the portable c compiler:
416762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
417762Speter      *	    and qualifications on those basic types (pointer, function, array).
418762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
419762Speter      *	    and the qualifications are arranged in two bit chunks, with the
420762Speter      *	    most significant on the right,
421762Speter      *	    and the least significant on the left
422762Speter      *		e.g. int *foo();
423762Speter      *			(a function returning a pointer to an integer)
424762Speter      *		is stored as
425762Speter      *		    <ptr><ftn><int>
426762Speter      *	so, we build types recursively
4271478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4281478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4291478Speter      *	through mutually recursive pointer types.
430762Speter      */
4311478Speter #define	MAXQUALS	6
432762Speter int
433762Speter p2type( np )
43415953Smckusick     struct nl	*np;
4351478Speter {
4361478Speter 
4371478Speter     return typerecur( np , 0 );
4381478Speter }
4391478Speter typerecur( np , quals )
4401478Speter     struct nl	*np;
4411478Speter     int		quals;
442762Speter     {
443762Speter 
4441478Speter 	if ( np == NIL || quals > MAXQUALS ) {
44518462Sralph 	    return PCCT_UNDEF;
4461478Speter 	}
447762Speter 	switch ( np -> class ) {
448762Speter 	    case SCAL :
449762Speter 	    case RANGE :
45015974Smckusick 	    case CRANGE :
451762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
45218462Sralph 		    return PCCT_DOUBLE;
453762Speter 		}
454762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
455762Speter 		    case 1:
45618462Sralph 			return PCCT_CHAR;
457762Speter 		    case 2:
45818462Sralph 			return PCCT_SHORT;
459762Speter 		    case 4:
46018462Sralph 			return PCCT_INT;
461762Speter 		    default:
462762Speter 			panic( "p2type int" );
46315953Smckusick 			/* NOTREACHED */
464762Speter 		}
465762Speter 	    case STR :
46618462Sralph 		return ( PCCTM_ARY | PCCT_CHAR );
467762Speter 	    case RECORD :
468762Speter 	    case SET :
46918462Sralph 		return PCCT_STRTY;
470762Speter 	    case FILET :
47118462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
472762Speter 	    case CONST :
473762Speter 	    case VAR :
474762Speter 	    case FIELD :
475762Speter 		return p2type( np -> type );
476762Speter 	    case TYPE :
477762Speter 		switch ( nloff( np ) ) {
478762Speter 		    case TNIL :
47918462Sralph 			return ( PCCTM_PTR | PCCT_UNDEF );
480762Speter 		    case TSTR :
48118462Sralph 			return ( PCCTM_ARY | PCCT_CHAR );
482762Speter 		    case TSET :
48318462Sralph 			return PCCT_STRTY;
484762Speter 		    default :
485762Speter 			return ( p2type( np -> type ) );
486762Speter 		}
487762Speter 	    case REF:
488762Speter 	    case WITHPTR:
489762Speter 	    case PTR :
49018462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR );
491762Speter 	    case ARRAY :
49218462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY );
493762Speter 	    case FUNC :
494762Speter 		    /*
495762Speter 		     * functions are really pointers to functions
496762Speter 		     * which return their underlying type.
497762Speter 		     */
49818462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) ,
49918462Sralph 					PCCTM_FTN ) , PCCTM_PTR );
500762Speter 	    case PROC :
501762Speter 		    /*
502762Speter 		     * procedures are pointers to functions
503762Speter 		     * which return integers (whether you look at them or not)
504762Speter 		     */
50518462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR );
5061197Speter 	    case FFUNC :
5071197Speter 	    case FPROC :
5081197Speter 		    /*
5091197Speter 		     *	formal procedures and functions are pointers
5101197Speter 		     *	to structures which describe their environment.
5111197Speter 		     */
51218462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
513762Speter 	    default :
514762Speter 		panic( "p2type" );
51515953Smckusick 		/* NOTREACHED */
516762Speter 	}
517762Speter     }
518762Speter 
519762Speter     /*
520762Speter      *	put a typed operator to the pcstream
521762Speter      */
522762Speter putop( op , type )
523762Speter     int		op;
524762Speter     int		type;
525762Speter     {
52618462Sralph 	extern char	*p2opname();
527762Speter 
5283316Speter 	if ( !CGENNING )
529762Speter 	    return;
53018462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
531762Speter #	ifdef DEBUG
532762Speter 	    if ( opt( 'k' ) ) {
5332474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
53418462Sralph 			, p2opname( op ) , op , type );
535762Speter 	    }
536762Speter #	endif
537762Speter     }
538762Speter 
539762Speter     /*
540762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
541762Speter      *	which looks just like a regular operator, only the size and
542762Speter      *	alignment go in the next consecutive words
543762Speter      */
544762Speter putstrop( op , type , size , alignment )
545762Speter     int	op;
546762Speter     int	type;
547762Speter     int	size;
548762Speter     int	alignment;
549762Speter     {
55018462Sralph 	extern char	*p2opname();
551762Speter 
5523316Speter 	if ( !CGENNING )
553762Speter 	    return;
55418462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
555762Speter 	p2word( size );
556762Speter 	p2word( alignment );
557762Speter #	ifdef DEBUG
558762Speter 	    if ( opt( 'k' ) ) {
5592474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
56018462Sralph 			, p2opname( op ) , op , type , size , alignment );
561762Speter 	    }
562762Speter #	endif
563762Speter     }
564762Speter 
565762Speter     /*
566762Speter      *	the string names of p2ops
567762Speter      */
56818462Sralph 
56918462Sralph struct p2op {
57018462Sralph     int op;
57118462Sralph     char *name;
57218462Sralph };
57318462Sralph 
57418462Sralph static struct p2op	p2opnames[] = {
57518462Sralph 	PCC_ERROR, "PCC_ERROR",
57618462Sralph 	PCC_NAME, "PCC_NAME",
57718462Sralph 	PCC_STRING, "PCC_STRING",
57818462Sralph 	PCC_ICON, "PCC_ICON",
57918462Sralph 	PCC_FCON, "PCC_FCON",
58018462Sralph 	PCC_PLUS, "PCC_PLUS",
58118462Sralph 	PCC_MINUS, "PCC_MINUS",
58218462Sralph 	PCC_UMINUS, "PCC_UMINUS",
58318462Sralph 	PCC_MUL, "PCC_MUL",
58418462Sralph 	PCC_DEREF, "PCC_DEREF",
58518462Sralph 	PCC_AND, "PCC_AND",
58618462Sralph 	PCC_ADDROF, "PCC_ADDROF",
58718462Sralph 	PCC_OR, "PCC_OR",
58818462Sralph 	PCC_ER, "PCC_ER",
58918462Sralph 	PCC_QUEST, "PCC_QUEST",
59018462Sralph 	PCC_COLON, "PCC_COLON",
59118462Sralph 	PCC_ANDAND, "PCC_ANDAND",
59218462Sralph 	PCC_OROR, "PCC_OROR",
59318462Sralph 	PCC_CM, "PCC_CM",
59418462Sralph 	PCC_ASSIGN, "PCC_ASSIGN",
59518462Sralph 	PCC_COMOP, "PCC_COMOP",
59618462Sralph 	PCC_DIV, "PCC_DIV",
59718462Sralph 	PCC_MOD, "PCC_MOD",
59818462Sralph 	PCC_LS, "PCC_LS",
59918462Sralph 	PCC_RS, "PCC_RS",
60018462Sralph 	PCC_DOT, "PCC_DOT",
60118462Sralph 	PCC_STREF, "PCC_STREF",
60218462Sralph 	PCC_CALL, "PCC_CALL",
60318462Sralph 	PCC_UCALL, "PCC_UCALL",
60418462Sralph 	PCC_FORTCALL, "PCC_FORTCALL",
60518462Sralph 	PCC_UFORTCALL, "PCC_UFORTCALL",
60618462Sralph 	PCC_NOT, "PCC_NOT",
60718462Sralph 	PCC_COMPL, "PCC_COMPL",
60818462Sralph 	PCC_INCR, "PCC_INCR",
60918462Sralph 	PCC_DECR, "PCC_DECR",
61018462Sralph 	PCC_EQ, "PCC_EQ",
61118462Sralph 	PCC_NE, "PCC_NE",
61218462Sralph 	PCC_LE, "PCC_LE",
61318462Sralph 	PCC_LT, "PCC_LT",
61418462Sralph 	PCC_GE, "PCC_GE",
61518462Sralph 	PCC_GT, "PCC_GT",
61618462Sralph 	PCC_ULE, "PCC_ULE",
61718462Sralph 	PCC_ULT, "PCC_ULT",
61818462Sralph 	PCC_UGE, "PCC_UGE",
61918462Sralph 	PCC_UGT, "PCC_UGT",
62018462Sralph 	PCC_REG, "PCC_REG",
62118462Sralph 	PCC_OREG, "PCC_OREG",
62218462Sralph 	PCC_CCODES, "PCC_CCODES",
62318462Sralph 	PCC_FREE, "PCC_FREE",
62418462Sralph 	PCC_STASG, "PCC_STASG",
62518462Sralph 	PCC_STARG, "PCC_STARG",
62618462Sralph 	PCC_STCALL, "PCC_STCALL",
62718462Sralph 	PCC_USTCALL, "PCC_USTCALL",
62818462Sralph 	PCC_FLD, "PCC_FLD",
62918462Sralph 	PCC_SCONV, "PCC_SCONV",
63018462Sralph 	PCC_PCONV, "PCC_PCONV",
63118462Sralph 	PCC_PMCONV, "PCC_PMCONV",
63218462Sralph 	PCC_PVCONV, "PCC_PVCONV",
63318462Sralph 	PCC_FORCE, "PCC_FORCE",
63418462Sralph 	PCC_CBRANCH, "PCC_CBRANCH",
63518462Sralph 	PCC_INIT, "PCC_INIT",
63618462Sralph 	PCC_CAST, "PCC_CAST",
63718462Sralph 	-1, ""
638762Speter     };
63918462Sralph 
64018462Sralph char *
64118462Sralph p2opname( op )
64218462Sralph     register int	op;
64318462Sralph     {
64418462Sralph 	static char		*p2map[PCC_MAXOP+1];
64518462Sralph 	static bool		mapready = FALSE;
64618462Sralph 	register struct p2op	*pp;
64718462Sralph 
64818462Sralph 	if ( mapready == FALSE ) {
64918462Sralph 	    for ( pp = p2opnames; pp->op >= 0; pp++ )
65018462Sralph 		p2map[ pp->op ] = pp->name;
65118462Sralph 	    mapready = TRUE;
65218462Sralph 	}
65318462Sralph 	return ( p2map[ op ] ? p2map[ op ] : "unknown" );
65418462Sralph     }
655762Speter 
656762Speter     /*
657762Speter      *	low level routines
658762Speter      */
659762Speter 
660762Speter     /*
661762Speter      *	puts a long word on the pcstream
662762Speter      */
663762Speter p2word( word )
66415953Smckusick     int		word;
665762Speter     {
666762Speter 
667762Speter 	putw( word , pcstream );
668762Speter     }
669762Speter 
670762Speter     /*
671762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
672762Speter      */
673762Speter p2string( string )
674762Speter     char	*string;
675762Speter     {
676762Speter 	int	slen = strlen( string );
677762Speter 	int	wlen = ( slen + 3 ) / 4;
678762Speter 	int	plen = ( wlen * 4 ) - slen;
679762Speter 	char	*cp;
680762Speter 	int	p;
681762Speter 
682762Speter 	for ( cp = string ; *cp ; cp++ )
683762Speter 	    putc( *cp , pcstream );
684762Speter 	for ( p = 1 ; p <= plen ; p++ )
685762Speter 	    putc( '\0' , pcstream );
686762Speter #	ifdef DEBUG
687762Speter 	    if ( opt( 'k' ) ) {
688762Speter 		fprintf( stdout , "\"%s" , string );
689762Speter 		for ( p = 1 ; p <= plen ; p++ )
690762Speter 		    fprintf( stdout , "\\0" );
691762Speter 		fprintf( stdout , "\"\n" );
692762Speter 	    }
693762Speter #	endif
694762Speter     }
695762Speter 
696762Speter     /*
697762Speter      *	puts a name on the pcstream
698762Speter      */
699762Speter p2name( name )
700762Speter     char	*name;
701762Speter     {
702762Speter 	int	pad;
703762Speter 
704762Speter 	fprintf( pcstream , NAMEFORMAT , name );
705762Speter 	pad = strlen( name ) % sizeof (long);
706762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
707762Speter 	    putc( '\0' , pcstream );
708762Speter 	}
709762Speter #	ifdef DEBUG
710762Speter 	    if ( opt( 'k' ) ) {
711762Speter 		fprintf( stdout , NAMEFORMAT , name );
712762Speter 		pad = strlen( name ) % sizeof (long);
713762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
714762Speter 		    fprintf( stdout , "\\0" );
715762Speter 		}
716762Speter 		fprintf( stdout , "\n" );
717762Speter 	    }
718762Speter #	endif
719762Speter     }
720762Speter 
721762Speter     /*
722762Speter      *	put out a jump to a label
723762Speter      */
724762Speter putjbr( label )
725762Speter     long	label;
726762Speter     {
727762Speter 
728762Speter 	printjbr( LABELPREFIX , label );
729762Speter     }
730762Speter 
731762Speter     /*
732762Speter      *	put out a jump to any kind of label
733762Speter      */
734762Speter printjbr( prefix , label )
735762Speter     char	*prefix;
736762Speter     long	label;
737762Speter     {
738762Speter 
739*30035Smckusick #	if defined(vax) || defined(tahoe)
74010653Speter 	    putprintf( "	jbr	" , 1 );
74110653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
742*30035Smckusick #	endif vax || tahoe
74310653Speter #	ifdef mc68000
74410653Speter 	    putprintf( "	jra	" , 1 );
74510653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
74610653Speter #	endif mc68000
747762Speter     }
748762Speter 
749762Speter     /*
750762Speter      *	another version of put to catch calls to put
751762Speter      */
75215953Smckusick /* VARARGS */
75315953Smckusick put()
754762Speter     {
755762Speter 
75610653Speter 	panic("put()");
757762Speter     }
758762Speter 
759762Speter #endif PC
760