xref: /csrg-svn/usr.bin/pascal/src/p2put.c (revision 23527)
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*23527Smckusick static char sccsid[] = "@(#)p2put.c	5.2 (Berkeley) 06/18/85";
9*23527Smckusick #endif not lint
10*23527Smckusick 
11*23527Smckusick /*
12*23527Smckusick  * Copyright (c) 1980 Regents of the University of California.
13*23527Smckusick  * All rights reserved.  The Berkeley software License Agreement
14*23527Smckusick  * specifies the terms and conditions for redistribution.
15*23527Smckusick  */
16*23527Smckusick 
17*23527Smckusick #ifndef lint
1822180Sdist char copyright[] =
1922180Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
2022180Sdist  All rights reserved.\n";
2122180Sdist #endif not lint
22762Speter     /*
23762Speter      *	functions to help pi put out
24762Speter      *	polish postfix binary portable c compiler intermediate code
25762Speter      *	thereby becoming the portable pascal compiler
26762Speter      */
27762Speter 
28762Speter #include	"whoami.h"
29762Speter #ifdef PC
30762Speter #include	"0.h"
3110653Speter #include	"objfmt.h"
3218462Sralph #include	<pcc.h>
33762Speter #include	"pc.h"
3410653Speter #include	"align.h"
3511329Speter #include	"tmps.h"
36762Speter 
37762Speter     /*
38762Speter      *	emits an ftext operator and a string to the pcstream
39762Speter      */
40762Speter puttext( string )
41762Speter     char	*string;
42762Speter     {
43762Speter 	int	length = str4len( string );
44762Speter 
453316Speter 	if ( !CGENNING )
46762Speter 	    return;
4718462Sralph 	p2word( PCCM_TRIPLE( PCCF_FTEXT , length , 0 ) );
48762Speter #	ifdef DEBUG
49762Speter 	    if ( opt( 'k' ) ) {
5018462Sralph 		fprintf( stdout , "PCCF_FTEXT | %3d | 0	" , length );
51762Speter 	    }
52762Speter #	endif
53762Speter 	p2string( string );
54762Speter     }
55762Speter 
56762Speter int
57762Speter str4len( string )
58762Speter     char	*string;
59762Speter     {
60762Speter 
61762Speter 	return ( ( strlen( string ) + 3 ) / 4 );
62762Speter     }
63762Speter 
64762Speter     /*
65762Speter      *	put formatted text into a buffer for printing to the pcstream.
66762Speter      *	a call to putpflush actually puts out the text.
67762Speter      *	none of arg1 .. arg5 need be present.
68762Speter      *	and you can add more if you need them.
69762Speter      */
7015953Smckusick /* VARARGS */
71762Speter putprintf( format , incomplete , arg1 , arg2 , arg3 , arg4 , arg5 )
72762Speter     char	*format;
73762Speter     int		incomplete;
74762Speter     {
75762Speter 	static char	ppbuffer[ BUFSIZ ];
76762Speter 	static char	*ppbufp = ppbuffer;
77762Speter 
783316Speter 	if ( !CGENNING )
79762Speter 	    return;
80762Speter 	sprintf( ppbufp , format , arg1 , arg2 , arg3 , arg4 , arg5 );
81762Speter 	ppbufp = &( ppbuffer[ strlen( ppbuffer ) ] );
82762Speter 	if ( ppbufp >= &( ppbuffer[ BUFSIZ ] ) )
83762Speter 	    panic( "putprintf" );
84762Speter 	if ( ! incomplete ) {
85762Speter 	    puttext( ppbuffer );
86762Speter 	    ppbufp = ppbuffer;
87762Speter 	}
88762Speter     }
89762Speter 
90762Speter     /*
91762Speter      *	emit a left bracket operator to pcstream
92762Speter      *	with function number, the maximum temp register, and total local bytes
93762Speter      */
9411329Speter putlbracket(ftnno, sizesp)
9511329Speter     int		ftnno;
9611329Speter     struct om	*sizesp;
9711329Speter {
9811329Speter     int	maxtempreg;
9911329Speter     int	alignedframesize;
100762Speter 
10111329Speter #   ifdef vax
10211329Speter 	maxtempreg = sizesp->curtmps.next_avail[REG_GENERAL];
10311329Speter #   endif vax
10411329Speter #   ifdef mc68000
10511329Speter 	    /*
10614906Speter 	     *	this is how /lib/f1 wants it.
10711329Speter 	     */
10814906Speter 	maxtempreg =	(sizesp->curtmps.next_avail[REG_ADDR] << 4)
10914906Speter 		      | (sizesp->curtmps.next_avail[REG_DATA]);
11011329Speter #   endif mc68000
11115953Smckusick     alignedframesize = roundup((int)(BITSPERBYTE * -sizesp->curtmps.om_off),
11215953Smckusick 	(long)(BITSPERBYTE * A_STACK));
11318462Sralph     p2word( PCCM_TRIPLE( PCCF_FLBRAC , maxtempreg , ftnno ) );
11411329Speter     p2word(alignedframesize);
11511329Speter #   ifdef DEBUG
11611329Speter 	if ( opt( 'k' ) ) {
11718462Sralph 	    fprintf(stdout, "PCCF_FLBRAC | %3d | %d	%d\n",
11811329Speter 		maxtempreg, ftnno, alignedframesize);
11911329Speter 	}
12011329Speter #   endif
12111329Speter }
122762Speter 
123762Speter     /*
124762Speter      *	emit a right bracket operator
12514906Speter      *	which for the binary interface
126762Speter      *	forces the stack allocate and register mask
127762Speter      */
128762Speter putrbracket( ftnno )
129762Speter     int	ftnno;
130762Speter     {
131762Speter 
13218462Sralph 	p2word( PCCM_TRIPLE( PCCF_FRBRAC , 0 , ftnno ) );
133762Speter #	ifdef DEBUG
134762Speter 	    if ( opt( 'k' ) ) {
13518462Sralph 		fprintf( stdout , "PCCF_FRBRAC |   0 | %d\n" , ftnno );
136762Speter 	    }
137762Speter #	endif
138762Speter     }
139762Speter 
140762Speter     /*
141762Speter      *	emit an eof operator
142762Speter      */
143762Speter puteof()
144762Speter     {
145762Speter 
14618462Sralph 	p2word( PCCF_FEOF );
147762Speter #	ifdef DEBUG
148762Speter 	    if ( opt( 'k' ) ) {
14918462Sralph 		fprintf( stdout , "PCCF_FEOF\n" );
150762Speter 	    }
151762Speter #	endif
152762Speter     }
153762Speter 
154762Speter     /*
155762Speter      *	emit a dot operator,
156762Speter      *	with a source file line number and name
157762Speter      *	if line is negative, there was an error on that line, but who cares?
158762Speter      */
159762Speter putdot( filename , line )
160762Speter     char	*filename;
161762Speter     int		line;
162762Speter     {
163762Speter 	int	length = str4len( filename );
164762Speter 
165762Speter 	if ( line < 0 ) {
166762Speter 	    line = -line;
167762Speter 	}
16818462Sralph 	p2word( PCCM_TRIPLE( PCCF_FEXPR , length , line ) );
169762Speter #	ifdef DEBUG
170762Speter 	    if ( opt( 'k' ) ) {
17118462Sralph 		fprintf( stdout , "PCCF_FEXPR | %3d | %d	" , length , line );
172762Speter 	    }
173762Speter #	endif
174762Speter 	p2string( filename );
175762Speter     }
176762Speter 
177762Speter     /*
178762Speter      *	put out a leaf node
179762Speter      */
180762Speter putleaf( op , lval , rval , type , name )
181762Speter     int		op;
182762Speter     int		lval;
183762Speter     int		rval;
184762Speter     int		type;
185762Speter     char	*name;
186762Speter     {
1873316Speter 	if ( !CGENNING )
188762Speter 	    return;
189762Speter 	switch ( op ) {
190762Speter 	    default:
191762Speter 		panic( "[putleaf]" );
19218462Sralph 	    case PCC_ICON:
19318462Sralph 		p2word( PCCM_TRIPLE( PCC_ICON , name != NIL , type ) );
194762Speter 		p2word( lval );
195762Speter #		ifdef DEBUG
196762Speter 		    if ( opt( 'k' ) ) {
19718462Sralph 			fprintf( stdout , "PCC_ICON | %3d | 0x%x	"
198762Speter 			       , name != NIL , type );
199762Speter 			fprintf( stdout , "%d\n" , lval );
200762Speter 		    }
201762Speter #		endif
202762Speter 		if ( name )
203762Speter 		    p2name( name );
204762Speter 		break;
20518462Sralph 	    case PCC_NAME:
20618462Sralph 		p2word( PCCM_TRIPLE( PCC_NAME , lval != 0 , type ) );
207762Speter 		if ( lval )
208762Speter 		    p2word( lval );
209762Speter #		ifdef DEBUG
210762Speter 		    if ( opt( 'k' ) ) {
21118462Sralph 			fprintf( stdout , "PCC_NAME | %3d | 0x%x	"
212762Speter 			       , lval != 0 , type );
213762Speter 			if ( lval )
214762Speter 			    fprintf( stdout , "%d	" , lval );
215762Speter 		    }
216762Speter #		endif
217762Speter 		p2name( name );
218762Speter 		break;
21918462Sralph 	    case PCC_REG:
22018462Sralph 		p2word( PCCM_TRIPLE( PCC_REG , rval , type ) );
221762Speter #		ifdef DEBUG
222762Speter 		    if ( opt( 'k' ) ) {
22318462Sralph 			fprintf( stdout , "PCC_REG | %3d | 0x%x\n" ,
2242474Speter 				rval , type );
225762Speter 		    }
226762Speter #		endif
227762Speter 		break;
228762Speter 	}
229762Speter     }
230762Speter 
231762Speter     /*
232762Speter      *	rvalues are just lvalues with indirection, except
2333829Speter      *	special cases for registers and for named globals,
2343829Speter      *	whose names are their rvalues.
235762Speter      */
2367924Smckusick putRV( name , level , offset , other_flags , type )
237762Speter     char	*name;
238762Speter     int		level;
239762Speter     int		offset;
2407924Smckusick     char	other_flags;
241762Speter     int		type;
242762Speter     {
243762Speter 	char	extname[ BUFSIZ ];
244762Speter 	char	*printname;
245762Speter 
2463316Speter 	if ( !CGENNING )
247762Speter 	    return;
2487924Smckusick 	if ( other_flags & NREGVAR ) {
2493829Speter 	    if ( ( offset < 0 ) || ( offset > P2FP ) ) {
2503829Speter 		panic( "putRV regvar" );
2513582Speter 	    }
25218462Sralph 	    putleaf( PCC_REG , 0 , offset , type , (char *) 0 );
2533277Smckusic 	    return;
2543277Smckusic 	}
25515953Smckusick 	if ( whereis( offset , other_flags ) == GLOBALVAR ) {
2563829Speter 	    if ( name != 0 ) {
2573829Speter 		if ( name[0] != '_' ) {
2583829Speter 			sprintf( extname , EXTFORMAT , name );
2593829Speter 			printname = extname;
2603829Speter 		} else {
2613829Speter 			printname = name;
2623829Speter 		}
26318462Sralph 		putleaf( PCC_NAME , offset , 0 , type , printname );
2643829Speter 		return;
265762Speter 	    } else {
2663829Speter 		panic( "putRV no name" );
267762Speter 	    }
268762Speter 	}
2697924Smckusick 	putLV( name , level , offset , other_flags , type );
27018462Sralph 	putop( PCCOM_UNARY PCC_MUL , type );
271762Speter     }
272762Speter 
273762Speter     /*
274762Speter      *	put out an lvalue
275762Speter      *	given a level and offset
276762Speter      *	special case for
277762Speter      *	    named globals, whose lvalues are just their names as constants.
278762Speter      */
2797924Smckusick putLV( name , level , offset , other_flags , type )
280762Speter     char	*name;
281762Speter     int		level;
282762Speter     int		offset;
2837924Smckusick     char	other_flags;
284762Speter     int		type;
2853277Smckusic {
2863277Smckusic     char		extname[ BUFSIZ ];
2873277Smckusic     char		*printname;
288762Speter 
2893316Speter     if ( !CGENNING )
2903277Smckusic 	return;
2917924Smckusick     if ( other_flags & NREGVAR ) {
2923829Speter 	panic( "putLV regvar" );
293762Speter     }
29415953Smckusick     switch ( whereis( offset , other_flags ) ) {
2953829Speter 	case GLOBALVAR:
2963829Speter 	    if ( ( name != 0 ) ) {
2973829Speter 		if ( name[0] != '_' ) {
2983829Speter 			sprintf( extname , EXTFORMAT , name );
2993829Speter 			printname = extname;
3003829Speter 		} else {
3013829Speter 			printname = name;
3023829Speter 		}
30318462Sralph 		putleaf( PCC_ICON , offset , 0 , PCCM_ADDTYPE( type , PCCTM_PTR )
3043829Speter 			, printname );
3053829Speter 		return;
3063829Speter 	    } else {
3073829Speter 		panic( "putLV no name" );
3083829Speter 	    }
3093277Smckusic 	case PARAMVAR:
3103277Smckusic 	    if ( level == cbn ) {
31118462Sralph 		putleaf( PCC_REG, 0, P2AP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3123277Smckusic 	    } else {
31318462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + AP_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_PLUS , PCCTM_PTR | PCCT_CHAR );
3193277Smckusic 	    break;
3203277Smckusic 	case LOCALVAR:
3213277Smckusic 	    if ( level == cbn ) {
32218462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3233277Smckusic 	    } else {
32418462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
32518462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3269128Smckusick 		parts[ level ] |= NONLOCALVAR;
3273277Smckusic 	    }
32818462Sralph 	    putleaf( PCC_ICON , -offset , 0 , PCCT_INT , (char *) 0 );
32918462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3303277Smckusic 	    break;
3319128Smckusick 	case NAMEDLOCALVAR:
3329128Smckusick 	    if ( level == cbn ) {
33318462Sralph 		putleaf( PCC_REG, 0, P2FP, PCCM_ADDTYPE( type , PCCTM_PTR ), (char *) 0 );
3349128Smckusick 	    } else {
33518462Sralph 		putleaf( PCC_NAME , (level * sizeof(struct dispsave)) + FP_OFFSET
33618462Sralph 		    , 0 , PCCTM_PTR | PCCT_CHAR , DISPLAYNAME );
3379128Smckusick 		parts[ level ] |= NONLOCALVAR;
3389128Smckusick 	    }
33918462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCT_INT , name );
34018462Sralph 	    putop( PCC_MINUS , PCCTM_PTR | PCCT_CHAR );
3419128Smckusick 	    break;
3423277Smckusic     }
3433277Smckusic     return;
3443277Smckusic }
345762Speter 
346762Speter     /*
347762Speter      *	put out a floating point constant leaf node
348762Speter      *	the constant is declared in aligned data space
34918462Sralph      *	and a PCC_NAME leaf put out for it
350762Speter      */
3517924Smckusick putCON8( val )
3527924Smckusick     double	val;
353762Speter     {
35415953Smckusick 	char	*label;
355762Speter 	char	name[ BUFSIZ ];
356762Speter 
3573316Speter 	if ( !CGENNING )
358762Speter 	    return;
35910653Speter 	label = getlab();
360762Speter 	putprintf( "	.data" , 0 );
36110653Speter 	aligndot(A_DOUBLE);
36215953Smckusick 	(void) putlab( label );
36310653Speter #	ifdef vax
36410653Speter 	    putprintf( "	.double 0d%.20e" , 0 , val );
36510653Speter #	endif vax
36610653Speter #	ifdef mc68000
36710653Speter 	    putprintf( "	.long 	0x%x,0x%x", 0, val);
36810653Speter #	endif mc68000
369762Speter 	putprintf( "	.text" , 0 );
370762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
37118462Sralph 	putleaf( PCC_NAME , 0 , 0 , PCCT_DOUBLE , name );
372762Speter     }
373762Speter 
374762Speter 	/*
375762Speter 	 * put out either an lvalue or an rvalue for a constant string.
376762Speter 	 * an lvalue (for assignment rhs's) is the name as a constant,
377762Speter 	 * an rvalue (for parameters) is just the name.
378762Speter 	 */
379762Speter putCONG( string , length , required )
380762Speter     char	*string;
381762Speter     int		length;
382762Speter     int		required;
383762Speter     {
384762Speter 	char	name[ BUFSIZ ];
38515953Smckusick 	char	*label;
386762Speter 	char	*cp;
387762Speter 	int	pad;
388762Speter 	int	others;
389762Speter 
3903316Speter 	if ( !CGENNING )
391762Speter 	    return;
392762Speter 	putprintf( "	.data" , 0 );
39310653Speter 	aligndot(A_STRUCT);
394762Speter 	label = getlab();
39515953Smckusick 	(void) putlab( label );
396762Speter 	cp = string;
397762Speter 	while ( *cp ) {
398762Speter 	    putprintf( "	.byte	0%o" , 1 , *cp ++ );
399762Speter 	    for ( others = 2 ; ( others <= 8 ) && *cp ; others ++ ) {
400762Speter 		putprintf( ",0%o" , 1 , *cp++ );
401762Speter 	    }
402762Speter 	    putprintf( "" , 0 );
403762Speter 	}
404762Speter 	pad = length - strlen( string );
405762Speter 	while ( pad-- > 0 ) {
406762Speter 	    putprintf( "	.byte	0%o" , 1 , ' ' );
407762Speter 	    for ( others = 2 ; ( others <= 8 ) && ( pad-- > 0 ) ; others++ ) {
408762Speter 		putprintf( ",0%o" , 1 , ' ' );
409762Speter 	    }
410762Speter 	    putprintf( "" , 0 );
411762Speter 	}
412762Speter 	putprintf( "	.byte	0" , 0 );
413762Speter 	putprintf( "	.text"  , 0 );
414762Speter 	sprintf( name , PREFIXFORMAT , LABELPREFIX , label );
415762Speter 	if ( required == RREQ ) {
41618462Sralph 	    putleaf( PCC_NAME , 0 , 0 , PCCTM_ARY | PCCT_CHAR , name );
417762Speter 	} else {
41818462Sralph 	    putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR | PCCT_CHAR , name );
419762Speter 	}
420762Speter     }
421762Speter 
422762Speter     /*
423762Speter      *	map a pascal type to a c type
424762Speter      *	this would be tail recursive, but i unfolded it into a for (;;).
425762Speter      *	this is sort of like isa and lwidth
426762Speter      *	a note on the types used by the portable c compiler:
427762Speter      *	    they are divided into a basic type (char, short, int, long, etc.)
428762Speter      *	    and qualifications on those basic types (pointer, function, array).
429762Speter      *	    the basic type is kept in the low 4 bits of the type descriptor,
430762Speter      *	    and the qualifications are arranged in two bit chunks, with the
431762Speter      *	    most significant on the right,
432762Speter      *	    and the least significant on the left
433762Speter      *		e.g. int *foo();
434762Speter      *			(a function returning a pointer to an integer)
435762Speter      *		is stored as
436762Speter      *		    <ptr><ftn><int>
437762Speter      *	so, we build types recursively
4381478Speter      *	also, we know that /lib/f1 can only deal with 6 qualifications
4391478Speter      *	so we stop the recursion there.  this stops infinite type recursion
4401478Speter      *	through mutually recursive pointer types.
441762Speter      */
4421478Speter #define	MAXQUALS	6
443762Speter int
444762Speter p2type( np )
44515953Smckusick     struct nl	*np;
4461478Speter {
4471478Speter 
4481478Speter     return typerecur( np , 0 );
4491478Speter }
4501478Speter typerecur( np , quals )
4511478Speter     struct nl	*np;
4521478Speter     int		quals;
453762Speter     {
454762Speter 
4551478Speter 	if ( np == NIL || quals > MAXQUALS ) {
45618462Sralph 	    return PCCT_UNDEF;
4571478Speter 	}
458762Speter 	switch ( np -> class ) {
459762Speter 	    case SCAL :
460762Speter 	    case RANGE :
46115974Smckusick 	    case CRANGE :
462762Speter 		if ( np -> type == ( nl + TDOUBLE ) ) {
46318462Sralph 		    return PCCT_DOUBLE;
464762Speter 		}
465762Speter 		switch ( bytes( np -> range[0] , np -> range[1] ) ) {
466762Speter 		    case 1:
46718462Sralph 			return PCCT_CHAR;
468762Speter 		    case 2:
46918462Sralph 			return PCCT_SHORT;
470762Speter 		    case 4:
47118462Sralph 			return PCCT_INT;
472762Speter 		    default:
473762Speter 			panic( "p2type int" );
47415953Smckusick 			/* NOTREACHED */
475762Speter 		}
476762Speter 	    case STR :
47718462Sralph 		return ( PCCTM_ARY | PCCT_CHAR );
478762Speter 	    case RECORD :
479762Speter 	    case SET :
48018462Sralph 		return PCCT_STRTY;
481762Speter 	    case FILET :
48218462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
483762Speter 	    case CONST :
484762Speter 	    case VAR :
485762Speter 	    case FIELD :
486762Speter 		return p2type( np -> type );
487762Speter 	    case TYPE :
488762Speter 		switch ( nloff( np ) ) {
489762Speter 		    case TNIL :
49018462Sralph 			return ( PCCTM_PTR | PCCT_UNDEF );
491762Speter 		    case TSTR :
49218462Sralph 			return ( PCCTM_ARY | PCCT_CHAR );
493762Speter 		    case TSET :
49418462Sralph 			return PCCT_STRTY;
495762Speter 		    default :
496762Speter 			return ( p2type( np -> type ) );
497762Speter 		}
498762Speter 	    case REF:
499762Speter 	    case WITHPTR:
500762Speter 	    case PTR :
50118462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_PTR );
502762Speter 	    case ARRAY :
50318462Sralph 		return PCCM_ADDTYPE( typerecur( np -> type , quals + 1 ) , PCCTM_ARY );
504762Speter 	    case FUNC :
505762Speter 		    /*
506762Speter 		     * functions are really pointers to functions
507762Speter 		     * which return their underlying type.
508762Speter 		     */
50918462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( typerecur( np -> type , quals + 2 ) ,
51018462Sralph 					PCCTM_FTN ) , PCCTM_PTR );
511762Speter 	    case PROC :
512762Speter 		    /*
513762Speter 		     * procedures are pointers to functions
514762Speter 		     * which return integers (whether you look at them or not)
515762Speter 		     */
51618462Sralph 		return PCCM_ADDTYPE( PCCM_ADDTYPE( PCCT_INT , PCCTM_FTN ) , PCCTM_PTR );
5171197Speter 	    case FFUNC :
5181197Speter 	    case FPROC :
5191197Speter 		    /*
5201197Speter 		     *	formal procedures and functions are pointers
5211197Speter 		     *	to structures which describe their environment.
5221197Speter 		     */
52318462Sralph 		return ( PCCTM_PTR | PCCT_STRTY );
524762Speter 	    default :
525762Speter 		panic( "p2type" );
52615953Smckusick 		/* NOTREACHED */
527762Speter 	}
528762Speter     }
529762Speter 
530762Speter     /*
531762Speter      *	put a typed operator to the pcstream
532762Speter      */
533762Speter putop( op , type )
534762Speter     int		op;
535762Speter     int		type;
536762Speter     {
53718462Sralph 	extern char	*p2opname();
538762Speter 
5393316Speter 	if ( !CGENNING )
540762Speter 	    return;
54118462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
542762Speter #	ifdef DEBUG
543762Speter 	    if ( opt( 'k' ) ) {
5442474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x\n"
54518462Sralph 			, p2opname( op ) , op , type );
546762Speter 	    }
547762Speter #	endif
548762Speter     }
549762Speter 
550762Speter     /*
551762Speter      *	put out a structure operator (STASG, STARG, STCALL, UNARY STCALL )
552762Speter      *	which looks just like a regular operator, only the size and
553762Speter      *	alignment go in the next consecutive words
554762Speter      */
555762Speter putstrop( op , type , size , alignment )
556762Speter     int	op;
557762Speter     int	type;
558762Speter     int	size;
559762Speter     int	alignment;
560762Speter     {
56118462Sralph 	extern char	*p2opname();
562762Speter 
5633316Speter 	if ( !CGENNING )
564762Speter 	    return;
56518462Sralph 	p2word( PCCM_TRIPLE( op , 0 , type ) );
566762Speter 	p2word( size );
567762Speter 	p2word( alignment );
568762Speter #	ifdef DEBUG
569762Speter 	    if ( opt( 'k' ) ) {
5702474Speter 		fprintf( stdout , "%s (%d) |   0 | 0x%x	%d %d\n"
57118462Sralph 			, p2opname( op ) , op , type , size , alignment );
572762Speter 	    }
573762Speter #	endif
574762Speter     }
575762Speter 
576762Speter     /*
577762Speter      *	the string names of p2ops
578762Speter      */
57918462Sralph 
58018462Sralph struct p2op {
58118462Sralph     int op;
58218462Sralph     char *name;
58318462Sralph };
58418462Sralph 
58518462Sralph static struct p2op	p2opnames[] = {
58618462Sralph 	PCC_ERROR, "PCC_ERROR",
58718462Sralph 	PCC_NAME, "PCC_NAME",
58818462Sralph 	PCC_STRING, "PCC_STRING",
58918462Sralph 	PCC_ICON, "PCC_ICON",
59018462Sralph 	PCC_FCON, "PCC_FCON",
59118462Sralph 	PCC_PLUS, "PCC_PLUS",
59218462Sralph 	PCC_MINUS, "PCC_MINUS",
59318462Sralph 	PCC_UMINUS, "PCC_UMINUS",
59418462Sralph 	PCC_MUL, "PCC_MUL",
59518462Sralph 	PCC_DEREF, "PCC_DEREF",
59618462Sralph 	PCC_AND, "PCC_AND",
59718462Sralph 	PCC_ADDROF, "PCC_ADDROF",
59818462Sralph 	PCC_OR, "PCC_OR",
59918462Sralph 	PCC_ER, "PCC_ER",
60018462Sralph 	PCC_QUEST, "PCC_QUEST",
60118462Sralph 	PCC_COLON, "PCC_COLON",
60218462Sralph 	PCC_ANDAND, "PCC_ANDAND",
60318462Sralph 	PCC_OROR, "PCC_OROR",
60418462Sralph 	PCC_CM, "PCC_CM",
60518462Sralph 	PCC_ASSIGN, "PCC_ASSIGN",
60618462Sralph 	PCC_COMOP, "PCC_COMOP",
60718462Sralph 	PCC_DIV, "PCC_DIV",
60818462Sralph 	PCC_MOD, "PCC_MOD",
60918462Sralph 	PCC_LS, "PCC_LS",
61018462Sralph 	PCC_RS, "PCC_RS",
61118462Sralph 	PCC_DOT, "PCC_DOT",
61218462Sralph 	PCC_STREF, "PCC_STREF",
61318462Sralph 	PCC_CALL, "PCC_CALL",
61418462Sralph 	PCC_UCALL, "PCC_UCALL",
61518462Sralph 	PCC_FORTCALL, "PCC_FORTCALL",
61618462Sralph 	PCC_UFORTCALL, "PCC_UFORTCALL",
61718462Sralph 	PCC_NOT, "PCC_NOT",
61818462Sralph 	PCC_COMPL, "PCC_COMPL",
61918462Sralph 	PCC_INCR, "PCC_INCR",
62018462Sralph 	PCC_DECR, "PCC_DECR",
62118462Sralph 	PCC_EQ, "PCC_EQ",
62218462Sralph 	PCC_NE, "PCC_NE",
62318462Sralph 	PCC_LE, "PCC_LE",
62418462Sralph 	PCC_LT, "PCC_LT",
62518462Sralph 	PCC_GE, "PCC_GE",
62618462Sralph 	PCC_GT, "PCC_GT",
62718462Sralph 	PCC_ULE, "PCC_ULE",
62818462Sralph 	PCC_ULT, "PCC_ULT",
62918462Sralph 	PCC_UGE, "PCC_UGE",
63018462Sralph 	PCC_UGT, "PCC_UGT",
63118462Sralph 	PCC_REG, "PCC_REG",
63218462Sralph 	PCC_OREG, "PCC_OREG",
63318462Sralph 	PCC_CCODES, "PCC_CCODES",
63418462Sralph 	PCC_FREE, "PCC_FREE",
63518462Sralph 	PCC_STASG, "PCC_STASG",
63618462Sralph 	PCC_STARG, "PCC_STARG",
63718462Sralph 	PCC_STCALL, "PCC_STCALL",
63818462Sralph 	PCC_USTCALL, "PCC_USTCALL",
63918462Sralph 	PCC_FLD, "PCC_FLD",
64018462Sralph 	PCC_SCONV, "PCC_SCONV",
64118462Sralph 	PCC_PCONV, "PCC_PCONV",
64218462Sralph 	PCC_PMCONV, "PCC_PMCONV",
64318462Sralph 	PCC_PVCONV, "PCC_PVCONV",
64418462Sralph 	PCC_FORCE, "PCC_FORCE",
64518462Sralph 	PCC_CBRANCH, "PCC_CBRANCH",
64618462Sralph 	PCC_INIT, "PCC_INIT",
64718462Sralph 	PCC_CAST, "PCC_CAST",
64818462Sralph 	-1, ""
649762Speter     };
65018462Sralph 
65118462Sralph char *
65218462Sralph p2opname( op )
65318462Sralph     register int	op;
65418462Sralph     {
65518462Sralph 	static char		*p2map[PCC_MAXOP+1];
65618462Sralph 	static bool		mapready = FALSE;
65718462Sralph 	register struct p2op	*pp;
65818462Sralph 
65918462Sralph 	if ( mapready == FALSE ) {
66018462Sralph 	    for ( pp = p2opnames; pp->op >= 0; pp++ )
66118462Sralph 		p2map[ pp->op ] = pp->name;
66218462Sralph 	    mapready = TRUE;
66318462Sralph 	}
66418462Sralph 	return ( p2map[ op ] ? p2map[ op ] : "unknown" );
66518462Sralph     }
666762Speter 
667762Speter     /*
668762Speter      *	low level routines
669762Speter      */
670762Speter 
671762Speter     /*
672762Speter      *	puts a long word on the pcstream
673762Speter      */
674762Speter p2word( word )
67515953Smckusick     int		word;
676762Speter     {
677762Speter 
678762Speter 	putw( word , pcstream );
679762Speter     }
680762Speter 
681762Speter     /*
682762Speter      *	put a length 0 mod 4 null padded string onto the pcstream
683762Speter      */
684762Speter p2string( string )
685762Speter     char	*string;
686762Speter     {
687762Speter 	int	slen = strlen( string );
688762Speter 	int	wlen = ( slen + 3 ) / 4;
689762Speter 	int	plen = ( wlen * 4 ) - slen;
690762Speter 	char	*cp;
691762Speter 	int	p;
692762Speter 
693762Speter 	for ( cp = string ; *cp ; cp++ )
694762Speter 	    putc( *cp , pcstream );
695762Speter 	for ( p = 1 ; p <= plen ; p++ )
696762Speter 	    putc( '\0' , pcstream );
697762Speter #	ifdef DEBUG
698762Speter 	    if ( opt( 'k' ) ) {
699762Speter 		fprintf( stdout , "\"%s" , string );
700762Speter 		for ( p = 1 ; p <= plen ; p++ )
701762Speter 		    fprintf( stdout , "\\0" );
702762Speter 		fprintf( stdout , "\"\n" );
703762Speter 	    }
704762Speter #	endif
705762Speter     }
706762Speter 
707762Speter     /*
708762Speter      *	puts a name on the pcstream
709762Speter      */
710762Speter p2name( name )
711762Speter     char	*name;
712762Speter     {
713762Speter 	int	pad;
714762Speter 
715762Speter 	fprintf( pcstream , NAMEFORMAT , name );
716762Speter 	pad = strlen( name ) % sizeof (long);
717762Speter 	for ( ; pad < sizeof (long) ; pad++ ) {
718762Speter 	    putc( '\0' , pcstream );
719762Speter 	}
720762Speter #	ifdef DEBUG
721762Speter 	    if ( opt( 'k' ) ) {
722762Speter 		fprintf( stdout , NAMEFORMAT , name );
723762Speter 		pad = strlen( name ) % sizeof (long);
724762Speter 		for ( ; pad < sizeof (long) ; pad++ ) {
725762Speter 		    fprintf( stdout , "\\0" );
726762Speter 		}
727762Speter 		fprintf( stdout , "\n" );
728762Speter 	    }
729762Speter #	endif
730762Speter     }
731762Speter 
732762Speter     /*
733762Speter      *	put out a jump to a label
734762Speter      */
735762Speter putjbr( label )
736762Speter     long	label;
737762Speter     {
738762Speter 
739762Speter 	printjbr( LABELPREFIX , label );
740762Speter     }
741762Speter 
742762Speter     /*
743762Speter      *	put out a jump to any kind of label
744762Speter      */
745762Speter printjbr( prefix , label )
746762Speter     char	*prefix;
747762Speter     long	label;
748762Speter     {
749762Speter 
75010653Speter #	ifdef vax
75110653Speter 	    putprintf( "	jbr	" , 1 );
75210653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
75310653Speter #	endif vax
75410653Speter #	ifdef mc68000
75510653Speter 	    putprintf( "	jra	" , 1 );
75610653Speter 	    putprintf( PREFIXFORMAT , 0 , prefix , label );
75710653Speter #	endif mc68000
758762Speter     }
759762Speter 
760762Speter     /*
761762Speter      *	another version of put to catch calls to put
762762Speter      */
76315953Smckusick /* VARARGS */
76415953Smckusick put()
765762Speter     {
766762Speter 
76710653Speter 	panic("put()");
768762Speter     }
769762Speter 
770762Speter #endif PC
771