xref: /csrg-svn/usr.bin/f77/pass1.vax/putpcc.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622866Smckusick  */
722866Smckusick 
822866Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)putpcc.c	5.4 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122866Smckusick 
1222866Smckusick /*
1322866Smckusick  * putpcc.c
1422866Smckusick  *
1522866Smckusick  * Intermediate code generation for S. C. Johnson C compilers
1622866Smckusick  * New version using binary polish postfix intermediate
1722866Smckusick  *
1822866Smckusick  * University of Utah CS Dept modification history:
1922866Smckusick  *
2026513Sdonn  * $Header: putpcc.c,v 5.2 86/03/04 17:49:38 donn Exp $
2122866Smckusick  * $Log:	putpcc.c,v $
2226513Sdonn  * Revision 5.2  86/03/04  17:49:38  donn
2326513Sdonn  * Change putct1() to emit the memoffset before the vleng -- the memoffset
2426513Sdonn  * may define a temporary which is used by the vleng to avoid repeated
2526513Sdonn  * evaluation of an expression with side effects.
2626513Sdonn  *
2726513Sdonn  * Revision 5.1  85/08/10  03:49:26  donn
2826513Sdonn  * 4.3 alpha
2926513Sdonn  *
3022866Smckusick  * Revision 3.2  85/03/25  09:35:57  root
3122866Smckusick  * fseek return -1 on error.
3222866Smckusick  *
3322866Smckusick  * Revision 3.1  85/02/27  19:06:55  donn
3422866Smckusick  * Changed to use pcc.h instead of pccdefs.h.
3522866Smckusick  *
3622866Smckusick  * Revision 2.12  85/02/22  01:05:54  donn
3722866Smckusick  * putaddr() didn't know about intrinsic functions...
3822866Smckusick  *
3922866Smckusick  * Revision 2.11  84/11/28  21:28:49  donn
4022866Smckusick  * Hacked putop() to handle any character expression being converted to int,
4122866Smckusick  * not just function calls.  Previously it bombed on concatenations.
4222866Smckusick  *
4322866Smckusick  * Revision 2.10  84/11/01  22:07:07  donn
4422866Smckusick  * Yet another try at getting putop() to work right.  It appears that the
4522866Smckusick  * second pass can't abide certain explicit conversions (e.g. short to long)
4622866Smckusick  * so the conversion code in putop() tries to remove them.  I think this
4722866Smckusick  * version (finally) works.
4822866Smckusick  *
4922866Smckusick  * Revision 2.9  84/10/29  02:30:57  donn
5022866Smckusick  * Earlier fix to putop() for conversions was insufficient -- we NEVER want to
5122866Smckusick  * see the type of the left operand of the thing left over from stripping off
5222866Smckusick  * conversions...
5322866Smckusick  *
5422866Smckusick  * Revision 2.8  84/09/18  03:09:21  donn
5522866Smckusick  * Fixed bug in putop() where the left operand of an addrblock was being
5622866Smckusick  * extracted...  This caused an extremely obscure conversion error when
5722866Smckusick  * an array of longs was subscripted by a short.
5822866Smckusick  *
5922866Smckusick  * Revision 2.7  84/08/19  20:10:19  donn
6022866Smckusick  * Removed stuff in putbranch that treats STGARG parameters specially -- the
6122866Smckusick  * bug in the code generation pass that motivated it has been fixed.
6222866Smckusick  *
6322866Smckusick  * Revision 2.6  84/08/07  21:32:23  donn
6422866Smckusick  * Bumped the size of the buffer for the intermediate code file from 0.5K
6522866Smckusick  * to 4K on a VAX.
6622866Smckusick  *
6722866Smckusick  * Revision 2.5  84/08/04  20:26:43  donn
6822866Smckusick  * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of
6922866Smckusick  * mktemp().  Correction due to Jerry Berkman.
7022866Smckusick  *
7122866Smckusick  * Revision 2.4  84/07/24  19:07:15  donn
7222866Smckusick  * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed
7322866Smckusick  * that mkaltemp() returns tempblocks, and tried to free them with frtemp().
7422866Smckusick  *
7522866Smckusick  * Revision 2.3  84/07/19  17:22:09  donn
7622866Smckusick  * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal.
7722866Smckusick  *
7822866Smckusick  * Revision 2.2  84/07/19  12:30:38  donn
7922866Smckusick  * Fixed a type clash in Bob Corbett's new putbranch().
8022866Smckusick  *
8122866Smckusick  * Revision 2.1  84/07/19  12:04:27  donn
8222866Smckusick  * Changed comment headers for UofU.
8322866Smckusick  *
8422866Smckusick  * Revision 1.8  84/07/19  11:38:23  donn
8522866Smckusick  * Replaced putbranch() routine so that you can ASSIGN into argument variables.
8622866Smckusick  * The code is from Bob Corbett, donated by Jerry Berkman.
8722866Smckusick  *
8822866Smckusick  * Revision 1.7  84/05/31  00:48:32  donn
8922866Smckusick  * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1
9022866Smckusick  * expressions -- a foulup in the order of COMOP and the comparison caused
9122866Smckusick  * one operand of the comparison to be garbage.
9222866Smckusick  *
9322866Smckusick  * Revision 1.6  84/04/16  09:54:19  donn
9422866Smckusick  * Backed out earlier fix for bug where items in the argtemplist were
9522866Smckusick  * (incorrectly) being given away; this is now fixed in mkargtemp().
9622866Smckusick  *
9722866Smckusick  * Revision 1.5  84/03/23  22:49:48  donn
9822866Smckusick  * Took out the initialization of the subroutine argument temporary list in
9922866Smckusick  * putcall() -- it needs to be done once per statement instead of once per call.
10022866Smckusick  *
10122866Smckusick  * Revision 1.4  84/03/01  06:48:05  donn
10222866Smckusick  * Fixed bug in Bob Corbett's code for argument temporaries that caused an
10322866Smckusick  * addrblock to get thrown out inadvertently when it was needed for recycling
10422866Smckusick  * purposes later on.
10522866Smckusick  *
10622866Smckusick  * Revision 1.3  84/02/26  06:32:38  donn
10722866Smckusick  * Added Berkeley changes to move data definitions around and reduce offsets.
10822866Smckusick  *
10922866Smckusick  * Revision 1.2  84/02/26  06:27:45  donn
11022866Smckusick  * Added code to catch TTEMP values passed to putx().
11122866Smckusick  *
11222866Smckusick  */
11322866Smckusick 
11422866Smckusick #if FAMILY != PCC
11522866Smckusick 	WRONG put FILE !!!!
11622866Smckusick #endif
11722866Smckusick 
11822866Smckusick #include "defs.h"
11922866Smckusick #include <pcc.h>
12022866Smckusick 
12122866Smckusick Addrp putcall(), putcxeq(), putcx1(), realpart();
12222866Smckusick expptr imagpart();
12322866Smckusick ftnint lencat();
12422866Smckusick 
12522866Smckusick #define FOUR 4
12622866Smckusick extern int ops2[];
12722866Smckusick extern int types2[];
12822866Smckusick 
12922866Smckusick #if HERE==VAX
13022866Smckusick #define PCC_BUFFMAX 1024
13122866Smckusick #else
13222866Smckusick #define PCC_BUFFMAX 128
13322866Smckusick #endif
13422866Smckusick static long int p2buff[PCC_BUFFMAX];
13522866Smckusick static long int *p2bufp		= &p2buff[0];
13622866Smckusick static long int *p2bufend	= &p2buff[PCC_BUFFMAX];
13722866Smckusick 
13822866Smckusick 
puthead(s,class)13922866Smckusick puthead(s, class)
14022866Smckusick char *s;
14122866Smckusick int class;
14222866Smckusick {
14322866Smckusick char buff[100];
14422866Smckusick #if TARGET == VAX
14522866Smckusick 	if(s)
14622866Smckusick 		p2ps("\t.globl\t_%s", s);
14722866Smckusick #endif
14822866Smckusick /* put out fake copy of left bracket line, to be redone later */
14922866Smckusick if( ! headerdone )
15022866Smckusick 	{
15122866Smckusick #if FAMILY == PCC
15222866Smckusick 	p2flush();
15322866Smckusick #endif
15422866Smckusick 	headoffset = ftell(textfile);
15522866Smckusick 	prhead(textfile);
15622866Smckusick 	headerdone = YES;
15722866Smckusick 	p2triple(PCCF_FEXPR, (strlen(infname)+FOUR-1)/FOUR, 0);
15822866Smckusick 	p2str(infname);
15922866Smckusick #if TARGET == PDP11
16022866Smckusick 	/* fake jump to start the optimizer */
16122866Smckusick 	if(class != CLBLOCK)
16222866Smckusick 		putgoto( fudgelabel = newlabel() );
16322866Smckusick #endif
16422866Smckusick 
16522866Smckusick #if TARGET == VAX
16622866Smckusick 	/* jump from top to bottom */
16722866Smckusick 	if(s!=CNULL && class!=CLBLOCK)
16822866Smckusick 		{
16922866Smckusick 		int proflab = newlabel();
17022866Smckusick 		p2ps("_%s:", s);
17122866Smckusick 		p2pi("\t.word\tLWM%d", procno);
17222866Smckusick 		prsave(proflab);
17322866Smckusick 		p2pi("\tjbr\tL%d", fudgelabel = newlabel());
17422866Smckusick 		}
17522866Smckusick #endif
17622866Smckusick 	}
17722866Smckusick }
17822866Smckusick 
17922866Smckusick 
18022866Smckusick 
18122866Smckusick 
18222866Smckusick 
18322866Smckusick /* It is necessary to precede each procedure with a "left bracket"
18422866Smckusick  * line that tells pass 2 how many register variables and how
18522866Smckusick  * much automatic space is required for the function.  This compiler
18622866Smckusick  * does not know how much automatic space is needed until the
18722866Smckusick  * entire procedure has been processed.  Therefore, "puthead"
18822866Smckusick  * is called at the begining to record the current location in textfile,
18922866Smckusick  * then to put out a placeholder left bracket line.  This procedure
19022866Smckusick  * repositions the file and rewrites that line, then puts the
19122866Smckusick  * file pointer back to the end of the file.
19222866Smckusick  */
19322866Smckusick 
putbracket()19422866Smckusick putbracket()
19522866Smckusick {
19622866Smckusick long int hereoffset;
19722866Smckusick 
19822866Smckusick #if FAMILY == PCC
19922866Smckusick 	p2flush();
20022866Smckusick #endif
20122866Smckusick hereoffset = ftell(textfile);
20222866Smckusick if(fseek(textfile, headoffset, 0) == -1)
20322866Smckusick 	fatal("fseek failed");
20422866Smckusick prhead(textfile);
20522866Smckusick if(fseek(textfile, hereoffset, 0) == -1)
20622866Smckusick 	fatal("fseek failed 2");
20722866Smckusick }
20822866Smckusick 
20922866Smckusick 
21022866Smckusick 
21122866Smckusick 
putrbrack(k)21222866Smckusick putrbrack(k)
21322866Smckusick int k;
21422866Smckusick {
21522866Smckusick p2op(PCCF_FRBRAC, k);
21622866Smckusick }
21722866Smckusick 
21822866Smckusick 
21922866Smckusick 
putnreg()22022866Smckusick putnreg()
22122866Smckusick {
22222866Smckusick }
22322866Smckusick 
22422866Smckusick 
22522866Smckusick 
22622866Smckusick 
22722866Smckusick 
22822866Smckusick 
puteof()22922866Smckusick puteof()
23022866Smckusick {
23122866Smckusick p2op(PCCF_FEOF, 0);
23222866Smckusick p2flush();
23322866Smckusick }
23422866Smckusick 
23522866Smckusick 
23622866Smckusick 
putstmt()23722866Smckusick putstmt()
23822866Smckusick {
23922866Smckusick p2triple(PCCF_FEXPR, 0, lineno);
24022866Smckusick }
24122866Smckusick 
24222866Smckusick 
24322866Smckusick 
24422866Smckusick 
24522866Smckusick /* put out code for if( ! p) goto l  */
putif(p,l)24622866Smckusick putif(p,l)
24722866Smckusick register expptr p;
24822866Smckusick int l;
24922866Smckusick {
25022866Smckusick register int k;
25122866Smckusick 
25222866Smckusick if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
25322866Smckusick 	{
25422866Smckusick 	if(k != TYERROR)
25522866Smckusick 		err("non-logical expression in IF statement");
25622866Smckusick 	frexpr(p);
25722866Smckusick 	}
25822866Smckusick else
25922866Smckusick 	{
26022866Smckusick 	putex1(p);
26122866Smckusick 	p2icon( (long int) l , PCCT_INT);
26222866Smckusick 	p2op(PCC_CBRANCH, 0);
26322866Smckusick 	putstmt();
26422866Smckusick 	}
26522866Smckusick }
26622866Smckusick 
26722866Smckusick 
26822866Smckusick 
26922866Smckusick 
27022866Smckusick 
27122866Smckusick /* put out code for  goto l   */
putgoto(label)27222866Smckusick putgoto(label)
27322866Smckusick int label;
27422866Smckusick {
27522866Smckusick p2triple(PCC_GOTO, 1, label);
27622866Smckusick putstmt();
27722866Smckusick }
27822866Smckusick 
27922866Smckusick 
28022866Smckusick /* branch to address constant or integer variable */
putbranch(p)28122866Smckusick putbranch(p)
28222866Smckusick register Addrp p;
28322866Smckusick {
28422866Smckusick   putex1((expptr) p);
28522866Smckusick   p2op(PCC_GOTO, PCCT_INT);
28622866Smckusick   putstmt();
28722866Smckusick }
28822866Smckusick 
28922866Smckusick 
29022866Smckusick 
29122866Smckusick /* put out label  l:     */
putlabel(label)29222866Smckusick putlabel(label)
29322866Smckusick int label;
29422866Smckusick {
29522866Smckusick p2op(PCCF_FLABEL, label);
29622866Smckusick }
29722866Smckusick 
29822866Smckusick 
29922866Smckusick 
30022866Smckusick 
putexpr(p)30122866Smckusick putexpr(p)
30222866Smckusick expptr p;
30322866Smckusick {
30422866Smckusick putex1(p);
30522866Smckusick putstmt();
30622866Smckusick }
30722866Smckusick 
30822866Smckusick 
30922866Smckusick 
31022866Smckusick 
putcmgo(index,nlab,labs)31122866Smckusick putcmgo(index, nlab, labs)
31222866Smckusick expptr index;
31322866Smckusick int nlab;
31422866Smckusick struct Labelblock *labs[];
31522866Smckusick {
31622866Smckusick int i, labarray, skiplabel;
31722866Smckusick 
31822866Smckusick if(! ISINT(index->headblock.vtype) )
31922866Smckusick 	{
32022866Smckusick 	execerr("computed goto index must be integer", CNULL);
32122866Smckusick 	return;
32222866Smckusick 	}
32322866Smckusick 
32422866Smckusick #if TARGET == VAX
32522866Smckusick 	/* use special case instruction */
32622866Smckusick 	vaxgoto(index, nlab, labs);
32722866Smckusick #else
32822866Smckusick 	labarray = newlabel();
32922866Smckusick 	preven(ALIADDR);
33022866Smckusick 	prlabel(asmfile, labarray);
33122866Smckusick 	prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
33222866Smckusick 	for(i = 0 ; i < nlab ; ++i)
33322866Smckusick 		if( labs[i] )
33422866Smckusick 			prcona(asmfile, (ftnint)(labs[i]->labelno) );
33522866Smckusick 	prcmgoto(index, nlab, skiplabel, labarray);
33622866Smckusick 	putlabel(skiplabel);
33722866Smckusick #endif
33822866Smckusick }
33922866Smckusick 
putx(p)34022866Smckusick putx(p)
34122866Smckusick expptr p;
34222866Smckusick {
34322866Smckusick char *memname();
34422866Smckusick int opc;
34522866Smckusick int ncomma;
34622866Smckusick int type, k;
34722866Smckusick 
34822866Smckusick if (!p)
34922866Smckusick 	return;
35022866Smckusick 
35122866Smckusick switch(p->tag)
35222866Smckusick 	{
35322866Smckusick 	case TERROR:
35422866Smckusick 		free( (charptr) p );
35522866Smckusick 		break;
35622866Smckusick 
35722866Smckusick 	case TCONST:
35822866Smckusick 		switch(type = p->constblock.vtype)
35922866Smckusick 			{
36022866Smckusick 			case TYLOGICAL:
36122866Smckusick 				type = tyint;
36222866Smckusick 			case TYLONG:
36322866Smckusick 			case TYSHORT:
36433257Sbostic 				p2icon(p->constblock.constant.ci, types2[type]);
36522866Smckusick 				free( (charptr) p );
36622866Smckusick 				break;
36722866Smckusick 
36822866Smckusick 			case TYADDR:
36922866Smckusick 				p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR);
37022866Smckusick 				p2word(0L);
37122866Smckusick 				p2name(memname(STGCONST,
37233257Sbostic 					(int) p->constblock.constant.ci) );
37322866Smckusick 				free( (charptr) p );
37422866Smckusick 				break;
37522866Smckusick 
37622866Smckusick 			default:
37722866Smckusick 				putx( putconst(p) );
37822866Smckusick 				break;
37922866Smckusick 			}
38022866Smckusick 		break;
38122866Smckusick 
38222866Smckusick 	case TEXPR:
38322866Smckusick 		switch(opc = p->exprblock.opcode)
38422866Smckusick 			{
38522866Smckusick 			case OPCALL:
38622866Smckusick 			case OPCCALL:
38722866Smckusick 				if( ISCOMPLEX(p->exprblock.vtype) )
38822866Smckusick 					putcxop(p);
38922866Smckusick 				else	putcall(p);
39022866Smckusick 				break;
39122866Smckusick 
39222866Smckusick 			case OPMIN:
39322866Smckusick 			case OPMAX:
39422866Smckusick 				putmnmx(p);
39522866Smckusick 				break;
39622866Smckusick 
39722866Smckusick 
39822866Smckusick 			case OPASSIGN:
39922866Smckusick 				if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
40022866Smckusick 				|| ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
40122866Smckusick 					frexpr( putcxeq(p) );
40222866Smckusick 				else if( ISCHAR(p) )
40322866Smckusick 					putcheq(p);
40422866Smckusick 				else
40522866Smckusick 					goto putopp;
40622866Smckusick 				break;
40722866Smckusick 
40822866Smckusick 			case OPEQ:
40922866Smckusick 			case OPNE:
41022866Smckusick 				if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
41122866Smckusick 				    ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
41222866Smckusick 					{
41322866Smckusick 					putcxcmp(p);
41422866Smckusick 					break;
41522866Smckusick 					}
41622866Smckusick 			case OPLT:
41722866Smckusick 			case OPLE:
41822866Smckusick 			case OPGT:
41922866Smckusick 			case OPGE:
42022866Smckusick 				if(ISCHAR(p->exprblock.leftp))
42122866Smckusick 					{
42222866Smckusick 					putchcmp(p);
42322866Smckusick 					break;
42422866Smckusick 					}
42522866Smckusick 				goto putopp;
42622866Smckusick 
42722866Smckusick 			case OPPOWER:
42822866Smckusick 				putpower(p);
42922866Smckusick 				break;
43022866Smckusick 
43122866Smckusick 			case OPSTAR:
43222866Smckusick #if FAMILY == PCC
43322866Smckusick 				/*   m * (2**k) -> m<<k   */
43422866Smckusick 				if(INT(p->exprblock.leftp->headblock.vtype) &&
43522866Smckusick 				   ISICON(p->exprblock.rightp) &&
43633257Sbostic 				   ( (k = log2(p->exprblock.rightp->constblock.constant.ci))>0) )
43722866Smckusick 					{
43822866Smckusick 					p->exprblock.opcode = OPLSHIFT;
43922866Smckusick 					frexpr(p->exprblock.rightp);
44022866Smckusick 					p->exprblock.rightp = ICON(k);
44122866Smckusick 					goto putopp;
44222866Smckusick 					}
44322866Smckusick #endif
44422866Smckusick 
44522866Smckusick 			case OPMOD:
44622866Smckusick 				goto putopp;
44722866Smckusick 			case OPPLUS:
44822866Smckusick 			case OPMINUS:
44922866Smckusick 			case OPSLASH:
45022866Smckusick 			case OPNEG:
45122866Smckusick 				if( ISCOMPLEX(p->exprblock.vtype) )
45222866Smckusick 					putcxop(p);
45322866Smckusick 				else	goto putopp;
45422866Smckusick 				break;
45522866Smckusick 
45622866Smckusick 			case OPCONV:
45722866Smckusick 				if( ISCOMPLEX(p->exprblock.vtype) )
45822866Smckusick 					putcxop(p);
45922866Smckusick 				else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
46022866Smckusick 					{
46122866Smckusick 					ncomma = 0;
46222866Smckusick 					putx( mkconv(p->exprblock.vtype,
46322866Smckusick 						realpart(putcx1(p->exprblock.leftp,
46422866Smckusick 							&ncomma))));
46522866Smckusick 					putcomma(ncomma, p->exprblock.vtype, NO);
46622866Smckusick 					free( (charptr) p );
46722866Smckusick 					}
46822866Smckusick 				else	goto putopp;
46922866Smckusick 				break;
47022866Smckusick 
47122866Smckusick 			case OPNOT:
47222866Smckusick 			case OPOR:
47322866Smckusick 			case OPAND:
47422866Smckusick 			case OPEQV:
47522866Smckusick 			case OPNEQV:
47622866Smckusick 			case OPADDR:
47722866Smckusick 			case OPPLUSEQ:
47822866Smckusick 			case OPSTAREQ:
47922866Smckusick 			case OPCOMMA:
48022866Smckusick 			case OPQUEST:
48122866Smckusick 			case OPCOLON:
48222866Smckusick 			case OPBITOR:
48322866Smckusick 			case OPBITAND:
48422866Smckusick 			case OPBITXOR:
48522866Smckusick 			case OPBITNOT:
48622866Smckusick 			case OPLSHIFT:
48722866Smckusick 			case OPRSHIFT:
48822866Smckusick 		putopp:
48922866Smckusick 				putop(p);
49022866Smckusick 				break;
49122866Smckusick 
49222866Smckusick 			case OPPAREN:
49322866Smckusick 				putx (p->exprblock.leftp);
49422866Smckusick 				break;
49522866Smckusick 			default:
49622866Smckusick 				badop("putx", opc);
49722866Smckusick 			}
49822866Smckusick 		break;
49922866Smckusick 
50022866Smckusick 	case TADDR:
50122866Smckusick 		putaddr(p, YES);
50222866Smckusick 		break;
50322866Smckusick 
50422866Smckusick 	case TTEMP:
50522866Smckusick 		/*
50622866Smckusick 		 * This type is sometimes passed to putx when errors occur
50722866Smckusick 		 *	upstream, I don't know why.
50822866Smckusick 		 */
50922866Smckusick 		frexpr(p);
51022866Smckusick 		break;
51122866Smckusick 
51222866Smckusick 	default:
51322866Smckusick 		badtag("putx", p->tag);
51422866Smckusick 	}
51522866Smckusick }
51622866Smckusick 
51722866Smckusick 
51822866Smckusick 
putop(p)51922866Smckusick LOCAL putop(p)
52022866Smckusick expptr p;
52122866Smckusick {
52222866Smckusick int k;
52322866Smckusick expptr lp, tp;
52422866Smckusick int pt, lt, tt;
52522866Smckusick int comma;
52622866Smckusick Addrp putch1();
52722866Smckusick 
52822866Smckusick switch(p->exprblock.opcode)	/* check for special cases and rewrite */
52922866Smckusick 	{
53022866Smckusick 	case OPCONV:
53122866Smckusick 		tt = pt = p->exprblock.vtype;
53222866Smckusick 		lp = p->exprblock.leftp;
53322866Smckusick 		lt = lp->headblock.vtype;
53422866Smckusick 		if (pt == TYREAL && lt == TYDREAL)
53522866Smckusick 			{
53622866Smckusick 			putx(lp);
53722866Smckusick 			p2op(PCC_SCONV, PCCT_FLOAT);
53822866Smckusick 			return;
53922866Smckusick 			}
54022866Smckusick 		while(p->tag==TEXPR && p->exprblock.opcode==OPCONV &&
54122866Smckusick 		      ( (ISREAL(pt)&&ISREAL(lt)) ||
54222866Smckusick 			(INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
54322866Smckusick 			{
54422866Smckusick #if SZINT < SZLONG
54522866Smckusick 			if(lp->tag != TEXPR)
54622866Smckusick 				{
54722866Smckusick 				if(pt==TYINT && lt==TYLONG)
54822866Smckusick 					break;
54922866Smckusick 				if(lt==TYINT && pt==TYLONG)
55022866Smckusick 					break;
55122866Smckusick 				}
55222866Smckusick #endif
55322866Smckusick 
55422866Smckusick #if TARGET == VAX
55522866Smckusick 			if(pt==TYDREAL && lt==TYREAL)
55622866Smckusick 				{
55722866Smckusick 				if(lp->tag==TEXPR &&
55822866Smckusick 				   lp->exprblock.opcode==OPCONV &&
55922866Smckusick 				   lp->exprblock.leftp->headblock.vtype==TYDREAL)
56022866Smckusick 					{
56122866Smckusick 					putx(lp->exprblock.leftp);
56222866Smckusick 					p2op(PCC_SCONV, PCCT_FLOAT);
56322866Smckusick 					p2op(PCC_SCONV, PCCT_DOUBLE);
56422866Smckusick 					free( (charptr) p );
56522866Smckusick 					return;
56622866Smckusick 					}
56722866Smckusick 				else break;
56822866Smckusick 				}
56922866Smckusick #endif
57022866Smckusick 			if(lt==TYCHAR && lp->tag==TEXPR)
57122866Smckusick 				{
57222866Smckusick 				int ncomma = 0;
57322866Smckusick 				p->exprblock.leftp = (expptr) putch1(lp, &ncomma);
57422866Smckusick 				putop(p);
57522866Smckusick 				putcomma(ncomma, pt, NO);
57622866Smckusick 				free( (charptr) p );
57722866Smckusick 				return;
57822866Smckusick 				}
57922866Smckusick 			free( (charptr) p );
58022866Smckusick 			p = lp;
58122866Smckusick 			pt = lt;
58222866Smckusick 			if (p->tag == TEXPR)
58322866Smckusick 				{
58422866Smckusick 				lp = p->exprblock.leftp;
58522866Smckusick 				lt = lp->headblock.vtype;
58622866Smckusick 				}
58722866Smckusick 			}
58822866Smckusick 		if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
58922866Smckusick 			break;
59022866Smckusick 		putx(p);
59122866Smckusick 		if (types2[tt] != types2[pt] &&
59222866Smckusick 		    ! ( (ISREAL(tt)&&ISREAL(pt)) ||
59322866Smckusick 			(INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
59422866Smckusick 			p2op(PCC_SCONV,types2[tt]);
59522866Smckusick 		return;
59622866Smckusick 
59722866Smckusick 	case OPADDR:
59822866Smckusick 		comma = NO;
59922866Smckusick 		lp = p->exprblock.leftp;
60022866Smckusick 		if(lp->tag != TADDR)
60122866Smckusick 			{
60222866Smckusick 			tp = (expptr) mkaltemp
60322866Smckusick 				(lp->headblock.vtype,lp->headblock.vleng);
60422866Smckusick 			putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
60522866Smckusick 			lp = tp;
60622866Smckusick 			comma = YES;
60722866Smckusick 			}
60822866Smckusick 		putaddr(lp, NO);
60922866Smckusick 		if(comma)
61022866Smckusick 			putcomma(1, TYINT, NO);
61122866Smckusick 		free( (charptr) p );
61222866Smckusick 		return;
61322866Smckusick #if TARGET == VAX
61422866Smckusick /* take advantage of a glitch in the code generator that does not check
61522866Smckusick    the type clash in an assignment or comparison of an integer zero and
61622866Smckusick    a floating left operand, and generates optimal code for the correct
61722866Smckusick    type.  (The PCC has no floating-constant node to encode this correctly.)
61822866Smckusick */
61922866Smckusick 	case OPASSIGN:
62022866Smckusick 	case OPLT:
62122866Smckusick 	case OPLE:
62222866Smckusick 	case OPGT:
62322866Smckusick 	case OPGE:
62422866Smckusick 	case OPEQ:
62522866Smckusick 	case OPNE:
62622866Smckusick 		if(ISREAL(p->exprblock.leftp->headblock.vtype) &&
62722866Smckusick 		   ISREAL(p->exprblock.rightp->headblock.vtype) &&
62822866Smckusick 		   ISCONST(p->exprblock.rightp) &&
62933257Sbostic 		   p->exprblock.rightp->constblock.constant.cd[0]==0)
63022866Smckusick 			{
63122866Smckusick 			p->exprblock.rightp->constblock.vtype = TYINT;
63233257Sbostic 			p->exprblock.rightp->constblock.constant.ci = 0;
63322866Smckusick 			}
63422866Smckusick #endif
63522866Smckusick 	}
63622866Smckusick 
63722866Smckusick if( (k = ops2[p->exprblock.opcode]) <= 0)
63822866Smckusick 	badop("putop", p->exprblock.opcode);
63922866Smckusick putx(p->exprblock.leftp);
64022866Smckusick if(p->exprblock.rightp)
64122866Smckusick 	putx(p->exprblock.rightp);
64222866Smckusick p2op(k, types2[p->exprblock.vtype]);
64322866Smckusick 
64422866Smckusick if(p->exprblock.vleng)
64522866Smckusick 	frexpr(p->exprblock.vleng);
64622866Smckusick free( (charptr) p );
64722866Smckusick }
64822866Smckusick 
putforce(t,p)64922866Smckusick putforce(t, p)
65022866Smckusick int t;
65122866Smckusick expptr p;
65222866Smckusick {
65322866Smckusick p = mkconv(t, fixtype(p));
65422866Smckusick putx(p);
65522866Smckusick p2op(PCC_FORCE,
65622866Smckusick 	(t==TYSHORT ? PCCT_SHORT : (t==TYLONG ? PCCT_LONG : PCCT_DOUBLE)) );
65722866Smckusick putstmt();
65822866Smckusick }
65922866Smckusick 
66022866Smckusick 
66122866Smckusick 
putpower(p)66222866Smckusick LOCAL putpower(p)
66322866Smckusick expptr p;
66422866Smckusick {
66522866Smckusick expptr base;
66622866Smckusick Addrp t1, t2;
66722866Smckusick ftnint k;
66822866Smckusick int type;
66922866Smckusick int ncomma;
67022866Smckusick 
67122866Smckusick if(!ISICON(p->exprblock.rightp) ||
67233257Sbostic     (k = p->exprblock.rightp->constblock.constant.ci)<2)
67322866Smckusick 	fatal("putpower: bad call");
67422866Smckusick base = p->exprblock.leftp;
67522866Smckusick type = base->headblock.vtype;
67622866Smckusick 
67722866Smckusick if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset))
67822866Smckusick {
67922866Smckusick 	putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base)));
68022866Smckusick 
68122866Smckusick 	return;
68222866Smckusick }
68322866Smckusick t1 = mkaltemp(type, PNULL);
68422866Smckusick t2 = NULL;
68522866Smckusick ncomma = 1;
68622866Smckusick putassign(cpexpr(t1), cpexpr(base) );
68722866Smckusick 
68822866Smckusick for( ; (k&1)==0 && k>2 ; k>>=1 )
68922866Smckusick 	{
69022866Smckusick 	++ncomma;
69122866Smckusick 	putsteq(t1, t1);
69222866Smckusick 	}
69322866Smckusick 
69422866Smckusick if(k == 2)
69522866Smckusick 	putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
69622866Smckusick else
69722866Smckusick 	{
69822866Smckusick 	t2 = mkaltemp(type, PNULL);
69922866Smckusick 	++ncomma;
70022866Smckusick 	putassign(cpexpr(t2), cpexpr(t1));
70122866Smckusick 
70222866Smckusick 	for(k>>=1 ; k>1 ; k>>=1)
70322866Smckusick 		{
70422866Smckusick 		++ncomma;
70522866Smckusick 		putsteq(t1, t1);
70622866Smckusick 		if(k & 1)
70722866Smckusick 			{
70822866Smckusick 			++ncomma;
70922866Smckusick 			putsteq(t2, t1);
71022866Smckusick 			}
71122866Smckusick 		}
71222866Smckusick 	putx( mkexpr(OPSTAR, cpexpr(t2),
71322866Smckusick 		mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
71422866Smckusick 	}
71522866Smckusick putcomma(ncomma, type, NO);
71622866Smckusick frexpr(t1);
71722866Smckusick if(t2)
71822866Smckusick 	frexpr(t2);
71922866Smckusick frexpr(p);
72022866Smckusick }
72122866Smckusick 
72222866Smckusick 
72322866Smckusick 
72422866Smckusick 
intdouble(p,ncommap)72522866Smckusick LOCAL Addrp intdouble(p, ncommap)
72622866Smckusick Addrp p;
72722866Smckusick int *ncommap;
72822866Smckusick {
72922866Smckusick register Addrp t;
73022866Smckusick 
73122866Smckusick t = mkaltemp(TYDREAL, PNULL);
73222866Smckusick ++*ncommap;
73322866Smckusick putassign(cpexpr(t), p);
73422866Smckusick return(t);
73522866Smckusick }
73622866Smckusick 
73722866Smckusick 
73822866Smckusick 
73922866Smckusick 
74022866Smckusick 
putcxeq(p)74122866Smckusick LOCAL Addrp putcxeq(p)
74222866Smckusick register expptr p;
74322866Smckusick {
74422866Smckusick register Addrp lp, rp;
74522866Smckusick int ncomma;
74622866Smckusick 
74722866Smckusick if(p->tag != TEXPR)
74822866Smckusick 	badtag("putcxeq", p->tag);
74922866Smckusick 
75022866Smckusick ncomma = 0;
75122866Smckusick lp = putcx1(p->exprblock.leftp, &ncomma);
75222866Smckusick rp = putcx1(p->exprblock.rightp, &ncomma);
75322866Smckusick putassign(realpart(lp), realpart(rp));
75422866Smckusick if( ISCOMPLEX(p->exprblock.vtype) )
75522866Smckusick 	{
75622866Smckusick 	++ncomma;
75722866Smckusick 	putassign(imagpart(lp), imagpart(rp));
75822866Smckusick 	}
75922866Smckusick putcomma(ncomma, TYREAL, NO);
76022866Smckusick frexpr(rp);
76122866Smckusick free( (charptr) p );
76222866Smckusick return(lp);
76322866Smckusick }
76422866Smckusick 
76522866Smckusick 
76622866Smckusick 
putcxop(p)76722866Smckusick LOCAL putcxop(p)
76822866Smckusick expptr p;
76922866Smckusick {
77022866Smckusick Addrp putcx1();
77122866Smckusick int ncomma;
77222866Smckusick 
77322866Smckusick ncomma = 0;
77422866Smckusick putaddr( putcx1(p, &ncomma), NO);
77522866Smckusick putcomma(ncomma, TYINT, NO);
77622866Smckusick }
77722866Smckusick 
77822866Smckusick 
77922866Smckusick 
putcx1(p,ncommap)78022866Smckusick LOCAL Addrp putcx1(p, ncommap)
78122866Smckusick register expptr p;
78222866Smckusick int *ncommap;
78322866Smckusick {
78422866Smckusick expptr q;
78522866Smckusick Addrp lp, rp;
78622866Smckusick register Addrp resp;
78722866Smckusick int opcode;
78822866Smckusick int ltype, rtype;
78922866Smckusick expptr mkrealcon();
79022866Smckusick 
79122866Smckusick if(p == NULL)
79222866Smckusick 	return(NULL);
79322866Smckusick 
79422866Smckusick switch(p->tag)
79522866Smckusick 	{
79622866Smckusick 	case TCONST:
79722866Smckusick 		if( ISCOMPLEX(p->constblock.vtype) )
79822866Smckusick 			p = (expptr) putconst(p);
79922866Smckusick 		return( (Addrp) p );
80022866Smckusick 
80122866Smckusick 	case TADDR:
80222866Smckusick 		if( ! addressable(p) )
80322866Smckusick 			{
80422866Smckusick 			++*ncommap;
80522866Smckusick 			resp = mkaltemp(tyint, PNULL);
80622866Smckusick 			putassign( cpexpr(resp), p->addrblock.memoffset );
80722866Smckusick 			p->addrblock.memoffset = (expptr)resp;
80822866Smckusick 			}
80922866Smckusick 		return( (Addrp) p );
81022866Smckusick 
81122866Smckusick 	case TEXPR:
81222866Smckusick 		if( ISCOMPLEX(p->exprblock.vtype) )
81322866Smckusick 			break;
81422866Smckusick 		++*ncommap;
81522866Smckusick 		resp = mkaltemp(TYDREAL, NO);
81622866Smckusick 		putassign( cpexpr(resp), p);
81722866Smckusick 		return(resp);
81822866Smckusick 
81922866Smckusick 	default:
82022866Smckusick 		badtag("putcx1", p->tag);
82122866Smckusick 	}
82222866Smckusick 
82322866Smckusick opcode = p->exprblock.opcode;
82422866Smckusick if(opcode==OPCALL || opcode==OPCCALL)
82522866Smckusick 	{
82622866Smckusick 	++*ncommap;
82722866Smckusick 	return( putcall(p) );
82822866Smckusick 	}
82922866Smckusick else if(opcode == OPASSIGN)
83022866Smckusick 	{
83122866Smckusick 	++*ncommap;
83222866Smckusick 	return( putcxeq(p) );
83322866Smckusick 	}
83422866Smckusick resp = mkaltemp(p->exprblock.vtype, PNULL);
83522866Smckusick if(lp = putcx1(p->exprblock.leftp, ncommap) )
83622866Smckusick 	ltype = lp->vtype;
83722866Smckusick if(rp = putcx1(p->exprblock.rightp, ncommap) )
83822866Smckusick 	rtype = rp->vtype;
83922866Smckusick 
84022866Smckusick switch(opcode)
84122866Smckusick 	{
84222866Smckusick 	case OPPAREN:
84322866Smckusick 		frexpr (resp);
84422866Smckusick 		resp = lp;
84522866Smckusick 		lp = NULL;
84622866Smckusick 		break;
84722866Smckusick 
84822866Smckusick 	case OPCOMMA:
84922866Smckusick 		frexpr(resp);
85022866Smckusick 		resp = rp;
85122866Smckusick 		rp = NULL;
85222866Smckusick 		break;
85322866Smckusick 
85422866Smckusick 	case OPNEG:
85522866Smckusick 		putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) );
85622866Smckusick 		putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) );
85722866Smckusick 		*ncommap += 2;
85822866Smckusick 		break;
85922866Smckusick 
86022866Smckusick 	case OPPLUS:
86122866Smckusick 	case OPMINUS:
86222866Smckusick 		putassign( realpart(resp),
86322866Smckusick 			mkexpr(opcode, realpart(lp), realpart(rp) ));
86422866Smckusick 		if(rtype < TYCOMPLEX)
86522866Smckusick 			putassign( imagpart(resp), imagpart(lp) );
86622866Smckusick 		else if(ltype < TYCOMPLEX)
86722866Smckusick 			{
86822866Smckusick 			if(opcode == OPPLUS)
86922866Smckusick 				putassign( imagpart(resp), imagpart(rp) );
87022866Smckusick 			else	putassign( imagpart(resp),
87122866Smckusick 					mkexpr(OPNEG, imagpart(rp), ENULL) );
87222866Smckusick 			}
87322866Smckusick 		else
87422866Smckusick 			putassign( imagpart(resp),
87522866Smckusick 				mkexpr(opcode, imagpart(lp), imagpart(rp) ));
87622866Smckusick 
87722866Smckusick 		*ncommap += 2;
87822866Smckusick 		break;
87922866Smckusick 
88022866Smckusick 	case OPSTAR:
88122866Smckusick 		if(ltype < TYCOMPLEX)
88222866Smckusick 			{
88322866Smckusick 			if( ISINT(ltype) )
88422866Smckusick 				lp = intdouble(lp, ncommap);
88522866Smckusick 			putassign( realpart(resp),
88622866Smckusick 				mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
88722866Smckusick 			putassign( imagpart(resp),
88822866Smckusick 				mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
88922866Smckusick 			}
89022866Smckusick 		else if(rtype < TYCOMPLEX)
89122866Smckusick 			{
89222866Smckusick 			if( ISINT(rtype) )
89322866Smckusick 				rp = intdouble(rp, ncommap);
89422866Smckusick 			putassign( realpart(resp),
89522866Smckusick 				mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
89622866Smckusick 			putassign( imagpart(resp),
89722866Smckusick 				mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
89822866Smckusick 			}
89922866Smckusick 		else	{
90022866Smckusick 			putassign( realpart(resp), mkexpr(OPMINUS,
90122866Smckusick 				mkexpr(OPSTAR, realpart(lp), realpart(rp)),
90222866Smckusick 				mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
90322866Smckusick 			putassign( imagpart(resp), mkexpr(OPPLUS,
90422866Smckusick 				mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
90522866Smckusick 				mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
90622866Smckusick 			}
90722866Smckusick 		*ncommap += 2;
90822866Smckusick 		break;
90922866Smckusick 
91022866Smckusick 	case OPSLASH:
91122866Smckusick 		/* fixexpr has already replaced all divisions
91222866Smckusick 		 * by a complex by a function call
91322866Smckusick 		 */
91422866Smckusick 		if( ISINT(rtype) )
91522866Smckusick 			rp = intdouble(rp, ncommap);
91622866Smckusick 		putassign( realpart(resp),
91722866Smckusick 			mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
91822866Smckusick 		putassign( imagpart(resp),
91922866Smckusick 			mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
92022866Smckusick 		*ncommap += 2;
92122866Smckusick 		break;
92222866Smckusick 
92322866Smckusick 	case OPCONV:
92422866Smckusick 		putassign( realpart(resp), realpart(lp) );
92522866Smckusick 		if( ISCOMPLEX(lp->vtype) )
92622866Smckusick 			q = imagpart(lp);
92722866Smckusick 		else if(rp != NULL)
92822866Smckusick 			q = (expptr) realpart(rp);
92922866Smckusick 		else
93022866Smckusick 			q = mkrealcon(TYDREAL, 0.0);
93122866Smckusick 		putassign( imagpart(resp), q);
93222866Smckusick 		*ncommap += 2;
93322866Smckusick 		break;
93422866Smckusick 
93522866Smckusick 	default:
93622866Smckusick 		badop("putcx1", opcode);
93722866Smckusick 	}
93822866Smckusick 
93922866Smckusick frexpr(lp);
94022866Smckusick frexpr(rp);
94122866Smckusick free( (charptr) p );
94222866Smckusick return(resp);
94322866Smckusick }
94422866Smckusick 
94522866Smckusick 
94622866Smckusick 
94722866Smckusick 
putcxcmp(p)94822866Smckusick LOCAL putcxcmp(p)
94922866Smckusick register expptr p;
95022866Smckusick {
95122866Smckusick int opcode;
95222866Smckusick int ncomma;
95322866Smckusick register Addrp lp, rp;
95422866Smckusick expptr q;
95522866Smckusick 
95622866Smckusick if(p->tag != TEXPR)
95722866Smckusick 	badtag("putcxcmp", p->tag);
95822866Smckusick 
95922866Smckusick ncomma = 0;
96022866Smckusick opcode = p->exprblock.opcode;
96122866Smckusick lp = putcx1(p->exprblock.leftp, &ncomma);
96222866Smckusick rp = putcx1(p->exprblock.rightp, &ncomma);
96322866Smckusick 
96422866Smckusick q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
96522866Smckusick 	mkexpr(opcode, realpart(lp), realpart(rp)),
96622866Smckusick 	mkexpr(opcode, imagpart(lp), imagpart(rp)) );
96722866Smckusick putx( fixexpr(q) );
96822866Smckusick putcomma(ncomma, TYINT, NO);
96922866Smckusick 
97022866Smckusick free( (charptr) lp);
97122866Smckusick free( (charptr) rp);
97222866Smckusick free( (charptr) p );
97322866Smckusick }
97422866Smckusick 
putch1(p,ncommap)97522866Smckusick LOCAL Addrp putch1(p, ncommap)
97622866Smckusick register expptr p;
97722866Smckusick int * ncommap;
97822866Smckusick {
97922866Smckusick register Addrp t;
98022866Smckusick 
98122866Smckusick switch(p->tag)
98222866Smckusick 	{
98322866Smckusick 	case TCONST:
98422866Smckusick 		return( putconst(p) );
98522866Smckusick 
98622866Smckusick 	case TADDR:
98722866Smckusick 		return( (Addrp) p );
98822866Smckusick 
98922866Smckusick 	case TEXPR:
99022866Smckusick 		++*ncommap;
99122866Smckusick 
99222866Smckusick 		switch(p->exprblock.opcode)
99322866Smckusick 			{
99422866Smckusick 			expptr q;
99522866Smckusick 
99622866Smckusick 			case OPCALL:
99722866Smckusick 			case OPCCALL:
99822866Smckusick 				t = putcall(p);
99922866Smckusick 				break;
100022866Smckusick 
100122866Smckusick 			case OPPAREN:
100222866Smckusick 				--*ncommap;
100322866Smckusick 				t = putch1(p->exprblock.leftp, ncommap);
100422866Smckusick 				break;
100522866Smckusick 
100622866Smckusick 			case OPCONCAT:
100722866Smckusick 				t = mkaltemp(TYCHAR, ICON(lencat(p)) );
100822866Smckusick 				q = (expptr) cpexpr(p->headblock.vleng);
100922866Smckusick 				putcat( cpexpr(t), p );
101022866Smckusick 				/* put the correct length on the block */
101122866Smckusick 				frexpr(t->vleng);
101222866Smckusick 				t->vleng = q;
101322866Smckusick 
101422866Smckusick 				break;
101522866Smckusick 
101622866Smckusick 			case OPCONV:
101722866Smckusick 				if(!ISICON(p->exprblock.vleng)
101833257Sbostic 				   || p->exprblock.vleng->constblock.constant.ci!=1
101922866Smckusick 				   || ! INT(p->exprblock.leftp->headblock.vtype) )
102022866Smckusick 					fatal("putch1: bad character conversion");
102122866Smckusick 				t = mkaltemp(TYCHAR, ICON(1) );
102222866Smckusick 				putop( mkexpr(OPASSIGN, cpexpr(t), p) );
102322866Smckusick 				break;
102422866Smckusick 			default:
102522866Smckusick 				badop("putch1", p->exprblock.opcode);
102622866Smckusick 			}
102722866Smckusick 		return(t);
102822866Smckusick 
102922866Smckusick 	default:
103022866Smckusick 		badtag("putch1", p->tag);
103122866Smckusick 	}
103222866Smckusick /* NOTREACHED */
103322866Smckusick }
103422866Smckusick 
103522866Smckusick 
103622866Smckusick 
103722866Smckusick 
putchop(p)103822866Smckusick LOCAL putchop(p)
103922866Smckusick expptr p;
104022866Smckusick {
104122866Smckusick int ncomma;
104222866Smckusick 
104322866Smckusick ncomma = 0;
104422866Smckusick putaddr( putch1(p, &ncomma) , NO );
104522866Smckusick putcomma(ncomma, TYCHAR, YES);
104622866Smckusick }
104722866Smckusick 
104822866Smckusick 
104922866Smckusick 
105022866Smckusick 
putcheq(p)105122866Smckusick LOCAL putcheq(p)
105222866Smckusick register expptr p;
105322866Smckusick {
105422866Smckusick int ncomma;
105522866Smckusick expptr lp, rp;
105622866Smckusick 
105722866Smckusick if(p->tag != TEXPR)
105822866Smckusick 	badtag("putcheq", p->tag);
105922866Smckusick 
106022866Smckusick ncomma = 0;
106122866Smckusick lp = p->exprblock.leftp;
106222866Smckusick rp = p->exprblock.rightp;
106322866Smckusick if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
106422866Smckusick 	putcat(lp, rp);
106522866Smckusick else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
106622866Smckusick 	{
106722866Smckusick 	putaddr( putch1(lp, &ncomma) , YES );
106822866Smckusick 	putaddr( putch1(rp, &ncomma) , YES );
106922866Smckusick 	putcomma(ncomma, TYINT, NO);
107022866Smckusick 	p2op(PCC_ASSIGN, PCCT_CHAR);
107122866Smckusick 	}
107222866Smckusick else
107322866Smckusick 	{
107422866Smckusick 	putx( call2(TYINT, "s_copy", lp, rp) );
107522866Smckusick 	putcomma(ncomma, TYINT, NO);
107622866Smckusick 	}
107722866Smckusick 
107822866Smckusick frexpr(p->exprblock.vleng);
107922866Smckusick free( (charptr) p );
108022866Smckusick }
108122866Smckusick 
108222866Smckusick 
108322866Smckusick 
108422866Smckusick 
putchcmp(p)108522866Smckusick LOCAL putchcmp(p)
108622866Smckusick register expptr p;
108722866Smckusick {
108822866Smckusick int ncomma;
108922866Smckusick expptr lp, rp;
109022866Smckusick 
109122866Smckusick if(p->tag != TEXPR)
109222866Smckusick 	badtag("putchcmp", p->tag);
109322866Smckusick 
109422866Smckusick ncomma = 0;
109522866Smckusick lp = p->exprblock.leftp;
109622866Smckusick rp = p->exprblock.rightp;
109722866Smckusick 
109822866Smckusick if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
109922866Smckusick 	{
110022866Smckusick 	putaddr( putch1(lp, &ncomma) , YES );
110122866Smckusick 	putcomma(ncomma, TYINT, NO);
110222866Smckusick 	ncomma = 0;
110322866Smckusick 	putaddr( putch1(rp, &ncomma) , YES );
110422866Smckusick 	putcomma(ncomma, TYINT, NO);
110522866Smckusick 	p2op(ops2[p->exprblock.opcode], PCCT_CHAR);
110622866Smckusick 	free( (charptr) p );
110722866Smckusick 	}
110822866Smckusick else
110922866Smckusick 	{
111022866Smckusick 	p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp);
111122866Smckusick 	p->exprblock.rightp = ICON(0);
111222866Smckusick 	putop(p);
111322866Smckusick 	}
111422866Smckusick }
111522866Smckusick 
111622866Smckusick 
111722866Smckusick 
111822866Smckusick 
111922866Smckusick 
putcat(lhs,rhs)112022866Smckusick LOCAL putcat(lhs, rhs)
112122866Smckusick register Addrp lhs;
112222866Smckusick register expptr rhs;
112322866Smckusick {
112422866Smckusick int n, ncomma;
112522866Smckusick Addrp lp, cp;
112622866Smckusick 
112722866Smckusick ncomma = 0;
112822866Smckusick n = ncat(rhs);
112922866Smckusick lp = mkaltmpn(n, TYLENG, PNULL);
113022866Smckusick cp = mkaltmpn(n, TYADDR, PNULL);
113122866Smckusick 
113222866Smckusick n = 0;
113322866Smckusick putct1(rhs, lp, cp, &n, &ncomma);
113422866Smckusick 
113522866Smckusick putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
113622866Smckusick putcomma(ncomma, TYINT, NO);
113722866Smckusick }
113822866Smckusick 
113922866Smckusick 
114022866Smckusick 
114122866Smckusick 
114222866Smckusick 
putct1(q,lp,cp,ip,ncommap)114322866Smckusick LOCAL putct1(q, lp, cp, ip, ncommap)
114422866Smckusick register expptr q;
114522866Smckusick register Addrp lp, cp;
114622866Smckusick int *ip, *ncommap;
114722866Smckusick {
114822866Smckusick int i;
114922866Smckusick Addrp lp1, cp1;
115022866Smckusick 
115122866Smckusick if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
115222866Smckusick 	{
115322866Smckusick 	putct1(q->exprblock.leftp, lp, cp, ip, ncommap);
115422866Smckusick 	putct1(q->exprblock.rightp, lp, cp , ip, ncommap);
115522866Smckusick 	frexpr(q->exprblock.vleng);
115622866Smckusick 	free( (charptr) q );
115722866Smckusick 	}
115822866Smckusick else
115922866Smckusick 	{
116022866Smckusick 	i = (*ip)++;
116126513Sdonn 	cp1 = (Addrp) cpexpr(cp);
116226513Sdonn 	cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
116322866Smckusick 	lp1 = (Addrp) cpexpr(lp);
116422866Smckusick 	lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
116526513Sdonn 	putassign( cp1, addrof(putch1(cpexpr(q),ncommap)) );
116626513Sdonn 	putassign( lp1, q->headblock.vleng );
116726513Sdonn 	free( (charptr) q );
116822866Smckusick 	*ncommap += 2;
116922866Smckusick 	}
117022866Smckusick }
117122866Smckusick 
putaddr(p,indir)117222866Smckusick LOCAL putaddr(p, indir)
117322866Smckusick register Addrp p;
117422866Smckusick int indir;
117522866Smckusick {
117622866Smckusick int type, type2, funct;
117722866Smckusick ftnint offset, simoffset();
117822866Smckusick expptr offp, shorten();
117922866Smckusick 
118022866Smckusick if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
118122866Smckusick 	{
118222866Smckusick 	frexpr(p);
118322866Smckusick 	return;
118422866Smckusick 	}
118522866Smckusick if (p->tag != TADDR) badtag ("putaddr",p->tag);
118622866Smckusick 
118722866Smckusick type = p->vtype;
118822866Smckusick type2 = types2[type];
118922866Smckusick funct = (p->vclass==CLPROC ? PCCTM_FTN<<2 : 0);
119022866Smckusick 
119122866Smckusick offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL );
119222866Smckusick 
119322866Smckusick 
119422866Smckusick #if (FUDGEOFFSET != 1)
119522866Smckusick if(offp)
119622866Smckusick 	offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
119722866Smckusick #endif
119822866Smckusick 
119922866Smckusick offset = simoffset( &offp );
120022866Smckusick #if SZINT < SZLONG
120122866Smckusick 	if(offp)
120222866Smckusick 		if(shortsubs)
120322866Smckusick 			offp = shorten(offp);
120422866Smckusick 		else
120522866Smckusick 			offp = mkconv(TYINT, offp);
120622866Smckusick #else
120722866Smckusick 	if(offp)
120822866Smckusick 		offp = mkconv(TYINT, offp);
120922866Smckusick #endif
121022866Smckusick 
121122866Smckusick if (p->vclass == CLVAR
121222866Smckusick     && (p->vstg == STGBSS || p->vstg == STGEQUIV)
121322866Smckusick     && SMALLVAR(p->varsize)
121422866Smckusick     && offset >= -32768 && offset <= 32767)
121522866Smckusick   {
121622866Smckusick     anylocals = YES;
121722866Smckusick     if (indir && !offp)
121822866Smckusick       p2ldisp(offset, memname(p->vstg, p->memno), type2);
121922866Smckusick     else
122022866Smckusick       {
122122866Smckusick 	p2reg(11, type2 | PCCTM_PTR);
122222866Smckusick 	p2triple(PCC_ICON, 1, PCCT_INT);
122322866Smckusick 	p2word(offset);
122422866Smckusick 	p2ndisp(memname(p->vstg, p->memno));
122522866Smckusick 	p2op(PCC_PLUS, type2 | PCCTM_PTR);
122622866Smckusick 	if (offp)
122722866Smckusick 	  {
122822866Smckusick 	    putx(offp);
122922866Smckusick 	    p2op(PCC_PLUS, type2 | PCCTM_PTR);
123022866Smckusick 	  }
123122866Smckusick 	if (indir)
123222866Smckusick 	  p2op(PCC_DEREF, type2);
123322866Smckusick       }
123422866Smckusick     frexpr((tagptr) p);
123522866Smckusick     return;
123622866Smckusick   }
123722866Smckusick 
123822866Smckusick switch(p->vstg)
123922866Smckusick 	{
124022866Smckusick 	case STGAUTO:
124122866Smckusick 		if(indir && !offp)
124222866Smckusick 			{
124322866Smckusick 			p2oreg(offset, AUTOREG, type2);
124422866Smckusick 			break;
124522866Smckusick 			}
124622866Smckusick 
124722866Smckusick 		if(!indir && !offp && !offset)
124822866Smckusick 			{
124922866Smckusick 			p2reg(AUTOREG, type2 | PCCTM_PTR);
125022866Smckusick 			break;
125122866Smckusick 			}
125222866Smckusick 
125322866Smckusick 		p2reg(AUTOREG, type2 | PCCTM_PTR);
125422866Smckusick 		if(offp)
125522866Smckusick 			{
125622866Smckusick 			putx(offp);
125722866Smckusick 			if(offset)
125822866Smckusick 				p2icon(offset, PCCT_INT);
125922866Smckusick 			}
126022866Smckusick 		else
126122866Smckusick 			p2icon(offset, PCCT_INT);
126222866Smckusick 		if(offp && offset)
126322866Smckusick 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
126422866Smckusick 		p2op(PCC_PLUS, type2 | PCCTM_PTR);
126522866Smckusick 		if(indir)
126622866Smckusick 			p2op(PCC_DEREF, type2);
126722866Smckusick 		break;
126822866Smckusick 
126922866Smckusick 	case STGARG:
127022866Smckusick 		p2oreg(
127122866Smckusick #ifdef ARGOFFSET
127222866Smckusick 			ARGOFFSET +
127322866Smckusick #endif
127422866Smckusick 			(ftnint) (FUDGEOFFSET*p->memno),
127522866Smckusick 			ARGREG,   type2 | PCCTM_PTR | funct );
127622866Smckusick 
127722866Smckusick 	based:
127822866Smckusick 		if(offset)
127922866Smckusick 			{
128022866Smckusick 			p2icon(offset, PCCT_INT);
128122866Smckusick 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
128222866Smckusick 			}
128322866Smckusick 		if(offp)
128422866Smckusick 			{
128522866Smckusick 			putx(offp);
128622866Smckusick 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
128722866Smckusick 			}
128822866Smckusick 		if(indir)
128922866Smckusick 			p2op(PCC_DEREF, type2);
129022866Smckusick 		break;
129122866Smckusick 
129222866Smckusick 	case STGLENG:
129322866Smckusick 		if(indir)
129422866Smckusick 			{
129522866Smckusick 			p2oreg(
129622866Smckusick #ifdef ARGOFFSET
129722866Smckusick 				ARGOFFSET +
129822866Smckusick #endif
129922866Smckusick 				(ftnint) (FUDGEOFFSET*p->memno),
130022866Smckusick 				ARGREG,   type2 );
130122866Smckusick 			}
130222866Smckusick 		else	{
130322866Smckusick 			p2reg(ARGREG, type2 | PCCTM_PTR );
130422866Smckusick 			p2icon(
130522866Smckusick #ifdef ARGOFFSET
130622866Smckusick 				ARGOFFSET +
130722866Smckusick #endif
130822866Smckusick 				(ftnint) (FUDGEOFFSET*p->memno), PCCT_INT);
130922866Smckusick 			p2op(PCC_PLUS, type2 | PCCTM_PTR );
131022866Smckusick 			}
131122866Smckusick 		break;
131222866Smckusick 
131322866Smckusick 
131422866Smckusick 	case STGBSS:
131522866Smckusick 	case STGINIT:
131622866Smckusick 	case STGEXT:
131722866Smckusick 	case STGINTR:
131822866Smckusick 	case STGCOMMON:
131922866Smckusick 	case STGEQUIV:
132022866Smckusick 	case STGCONST:
132122866Smckusick 		if(offp)
132222866Smckusick 			{
132322866Smckusick 			putx(offp);
132422866Smckusick 			putmem(p, PCC_ICON, offset);
132522866Smckusick 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
132622866Smckusick 			if(indir)
132722866Smckusick 				p2op(PCC_DEREF, type2);
132822866Smckusick 			}
132922866Smckusick 		else
133022866Smckusick 			putmem(p, (indir ? PCC_NAME : PCC_ICON), offset);
133122866Smckusick 
133222866Smckusick 		break;
133322866Smckusick 
133422866Smckusick 	case STGREG:
133522866Smckusick 		if(indir)
133622866Smckusick 			p2reg(p->memno, type2);
133722866Smckusick 		else
133822866Smckusick 			fatal("attempt to take address of a register");
133922866Smckusick 		break;
134022866Smckusick 
134122866Smckusick 	case STGPREG:
134222866Smckusick 		if(indir && !offp)
134322866Smckusick 			p2oreg(offset, p->memno, type2);
134422866Smckusick 		else
134522866Smckusick 			{
134622866Smckusick 			p2reg(p->memno, type2 | PCCTM_PTR);
134722866Smckusick 			goto based;
134822866Smckusick 			}
134922866Smckusick 		break;
135022866Smckusick 
135122866Smckusick 	default:
135222866Smckusick 		badstg("putaddr", p->vstg);
135322866Smckusick 	}
135422866Smckusick frexpr(p);
135522866Smckusick }
135622866Smckusick 
135722866Smckusick 
135822866Smckusick 
135922866Smckusick 
putmem(p,class,offset)136022866Smckusick LOCAL putmem(p, class, offset)
136122866Smckusick expptr p;
136222866Smckusick int class;
136322866Smckusick ftnint offset;
136422866Smckusick {
136522866Smckusick int type2;
136622866Smckusick int funct;
136722866Smckusick char *name,  *memname();
136822866Smckusick 
136922866Smckusick funct = (p->headblock.vclass==CLPROC ? PCCTM_FTN<<2 : 0);
137022866Smckusick type2 = types2[p->headblock.vtype];
137122866Smckusick if(p->headblock.vclass == CLPROC)
137222866Smckusick 	type2 |= (PCCTM_FTN<<2);
137322866Smckusick name = memname(p->addrblock.vstg, p->addrblock.memno);
137422866Smckusick if(class == PCC_ICON)
137522866Smckusick 	{
137622866Smckusick 	p2triple(PCC_ICON, name[0]!='\0', type2|PCCTM_PTR);
137722866Smckusick 	p2word(offset);
137822866Smckusick 	if(name[0])
137922866Smckusick 		p2name(name);
138022866Smckusick 	}
138122866Smckusick else
138222866Smckusick 	{
138322866Smckusick 	p2triple(PCC_NAME, offset!=0, type2);
138422866Smckusick 	if(offset != 0)
138522866Smckusick 		p2word(offset);
138622866Smckusick 	p2name(name);
138722866Smckusick 	}
138822866Smckusick }
138922866Smckusick 
139022866Smckusick 
139122866Smckusick 
putcall(p)139222866Smckusick LOCAL Addrp putcall(p)
139322866Smckusick register Exprp p;
139422866Smckusick {
139522866Smckusick chainp arglist, charsp, cp;
139622866Smckusick int n, first;
139722866Smckusick Addrp t;
139822866Smckusick register expptr q;
139922866Smckusick Addrp fval, mkargtemp();
140022866Smckusick int type, type2, ctype, qtype, indir;
140122866Smckusick 
140222866Smckusick type2 = types2[type = p->vtype];
140322866Smckusick charsp = NULL;
140422866Smckusick indir =  (p->opcode == OPCCALL);
140522866Smckusick n = 0;
140622866Smckusick first = YES;
140722866Smckusick 
140822866Smckusick if(p->rightp)
140922866Smckusick 	{
141022866Smckusick 	arglist = p->rightp->listblock.listp;
141122866Smckusick 	free( (charptr) (p->rightp) );
141222866Smckusick 	}
141322866Smckusick else
141422866Smckusick 	arglist = NULL;
141522866Smckusick 
141622866Smckusick for(cp = arglist ; cp ; cp = cp->nextp)
141722866Smckusick 	{
141822866Smckusick 	q = (expptr) cp->datap;
141922866Smckusick 	if(indir)
142022866Smckusick 		++n;
142122866Smckusick 	else	{
142222866Smckusick 		q = (expptr) (cp->datap);
142322866Smckusick 		if( ISCONST(q) )
142422866Smckusick 			{
142522866Smckusick 			q = (expptr) putconst(q);
142622866Smckusick 			cp->datap = (tagptr) q;
142722866Smckusick 			}
142822866Smckusick 		if( ISCHAR(q) && q->headblock.vclass!=CLPROC )
142922866Smckusick 			{
143022866Smckusick 			charsp = hookup(charsp,
143122866Smckusick 					mkchain(cpexpr(q->headblock.vleng),
143222866Smckusick 						CHNULL));
143322866Smckusick 			n += 2;
143422866Smckusick 			}
143522866Smckusick 		else
143622866Smckusick 			n += 1;
143722866Smckusick 		}
143822866Smckusick 	}
143922866Smckusick 
144022866Smckusick if(type == TYCHAR)
144122866Smckusick 	{
144222866Smckusick 	if( ISICON(p->vleng) )
144322866Smckusick 		{
144422866Smckusick 		fval = mkargtemp(TYCHAR, p->vleng);
144522866Smckusick 		n += 2;
144622866Smckusick 		}
144722866Smckusick 	else	{
144822866Smckusick 		err("adjustable character function");
144922866Smckusick 		return;
145022866Smckusick 		}
145122866Smckusick 	}
145222866Smckusick else if( ISCOMPLEX(type) )
145322866Smckusick 	{
145422866Smckusick 	fval = mkargtemp(type, PNULL);
145522866Smckusick 	n += 1;
145622866Smckusick 	}
145722866Smckusick else
145822866Smckusick 	fval = NULL;
145922866Smckusick 
146022866Smckusick ctype = (fval ? PCCT_INT : type2);
146122866Smckusick putaddr(p->leftp, NO);
146222866Smckusick 
146322866Smckusick if(fval)
146422866Smckusick 	{
146522866Smckusick 	first = NO;
146622866Smckusick 	putaddr( cpexpr(fval), NO);
146722866Smckusick 	if(type==TYCHAR)
146822866Smckusick 		{
146922866Smckusick 		putx( mkconv(TYLENG,p->vleng) );
147022866Smckusick 		p2op(PCC_CM, type2);
147122866Smckusick 		}
147222866Smckusick 	}
147322866Smckusick 
147422866Smckusick for(cp = arglist ; cp ; cp = cp->nextp)
147522866Smckusick 	{
147622866Smckusick 	q = (expptr) (cp->datap);
147722866Smckusick 	if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) )
147822866Smckusick 		putaddr(q, indir && q->addrblock.vtype!=TYCHAR);
147922866Smckusick 	else if( ISCOMPLEX(q->headblock.vtype) )
148022866Smckusick 		putcxop(q);
148122866Smckusick 	else if (ISCHAR(q) )
148222866Smckusick 		putchop(q);
148322866Smckusick 	else if( ! ISERROR(q) )
148422866Smckusick 		{
148522866Smckusick 		if(indir)
148622866Smckusick 			putx(q);
148722866Smckusick 		else	{
148822866Smckusick 			t = mkargtemp(qtype = q->headblock.vtype,
148922866Smckusick 				q->headblock.vleng);
149022866Smckusick 			putassign( cpexpr(t), q );
149122866Smckusick 			putaddr(t, NO);
149222866Smckusick 			putcomma(1, qtype, YES);
149322866Smckusick 			}
149422866Smckusick 		}
149522866Smckusick 	if(first)
149622866Smckusick 		first = NO;
149722866Smckusick 	else
149822866Smckusick 		p2op(PCC_CM, type2);
149922866Smckusick 	}
150022866Smckusick 
150122866Smckusick if(arglist)
150222866Smckusick 	frchain(&arglist);
150322866Smckusick for(cp = charsp ; cp ; cp = cp->nextp)
150422866Smckusick 	{
150522866Smckusick 	putx( mkconv(TYLENG,cp->datap) );
150622866Smckusick 	p2op(PCC_CM, type2);
150722866Smckusick 	}
150822866Smckusick frchain(&charsp);
150922866Smckusick p2op(n>0 ? PCC_CALL : PCC_UCALL , ctype);
151022866Smckusick free( (charptr) p );
151122866Smckusick return(fval);
151222866Smckusick }
151322866Smckusick 
151422866Smckusick 
151522866Smckusick 
putmnmx(p)151622866Smckusick LOCAL putmnmx(p)
151722866Smckusick register expptr p;
151822866Smckusick {
151922866Smckusick int op, type;
152022866Smckusick int ncomma;
152122866Smckusick expptr qp;
152222866Smckusick chainp p0, p1;
152322866Smckusick Addrp sp, tp;
152422866Smckusick 
152522866Smckusick if(p->tag != TEXPR)
152622866Smckusick 	badtag("putmnmx", p->tag);
152722866Smckusick 
152822866Smckusick type = p->exprblock.vtype;
152922866Smckusick op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
153022866Smckusick p0 = p->exprblock.leftp->listblock.listp;
153122866Smckusick free( (charptr) (p->exprblock.leftp) );
153222866Smckusick free( (charptr) p );
153322866Smckusick 
153422866Smckusick sp = mkaltemp(type, PNULL);
153522866Smckusick tp = mkaltemp(type, PNULL);
153622866Smckusick qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
153722866Smckusick qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
153822866Smckusick qp = fixexpr(qp);
153922866Smckusick 
154022866Smckusick ncomma = 1;
154122866Smckusick putassign( cpexpr(sp), p0->datap );
154222866Smckusick 
154322866Smckusick for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
154422866Smckusick 	{
154522866Smckusick 	++ncomma;
154622866Smckusick 	putassign( cpexpr(tp), p1->datap );
154722866Smckusick 	if(p1->nextp)
154822866Smckusick 		{
154922866Smckusick 		++ncomma;
155022866Smckusick 		putassign( cpexpr(sp), cpexpr(qp) );
155122866Smckusick 		}
155222866Smckusick 	else
155322866Smckusick 		putx(qp);
155422866Smckusick 	}
155522866Smckusick 
155622866Smckusick putcomma(ncomma, type, NO);
155722866Smckusick frexpr(sp);
155822866Smckusick frexpr(tp);
155922866Smckusick frchain( &p0 );
156022866Smckusick }
156122866Smckusick 
156222866Smckusick 
156322866Smckusick 
156422866Smckusick 
putcomma(n,type,indir)156522866Smckusick LOCAL putcomma(n, type, indir)
156622866Smckusick int n, type, indir;
156722866Smckusick {
156822866Smckusick type = types2[type];
156922866Smckusick if(indir)
157022866Smckusick 	type |= PCCTM_PTR;
157122866Smckusick while(--n >= 0)
157222866Smckusick 	p2op(PCC_COMOP, type);
157322866Smckusick }
157422866Smckusick 
157522866Smckusick 
157622866Smckusick 
157722866Smckusick 
simoffset(p0)157822866Smckusick ftnint simoffset(p0)
157922866Smckusick expptr *p0;
158022866Smckusick {
158122866Smckusick ftnint offset, prod;
158222866Smckusick register expptr p, lp, rp;
158322866Smckusick 
158422866Smckusick offset = 0;
158522866Smckusick p = *p0;
158622866Smckusick if(p == NULL)
158722866Smckusick 	return(0);
158822866Smckusick 
158922866Smckusick if( ! ISINT(p->headblock.vtype) )
159022866Smckusick 	return(0);
159122866Smckusick 
159222866Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR)
159322866Smckusick 	{
159422866Smckusick 	lp = p->exprblock.leftp;
159522866Smckusick 	rp = p->exprblock.rightp;
159622866Smckusick 	if(ISICON(rp) && lp->tag==TEXPR &&
159722866Smckusick 	   lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp))
159822866Smckusick 		{
159922866Smckusick 		p->exprblock.opcode = OPPLUS;
160022866Smckusick 		lp->exprblock.opcode = OPSTAR;
160133257Sbostic 		prod = rp->constblock.constant.ci *
160233257Sbostic 			lp->exprblock.rightp->constblock.constant.ci;
160333257Sbostic 		lp->exprblock.rightp->constblock.constant.ci = rp->constblock.constant.ci;
160433257Sbostic 		rp->constblock.constant.ci = prod;
160522866Smckusick 		}
160622866Smckusick 	}
160722866Smckusick 
160822866Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS &&
160922866Smckusick     ISICON(p->exprblock.rightp))
161022866Smckusick 	{
161122866Smckusick 	rp = p->exprblock.rightp;
161222866Smckusick 	lp = p->exprblock.leftp;
161333257Sbostic 	offset += rp->constblock.constant.ci;
161422866Smckusick 	frexpr(rp);
161522866Smckusick 	free( (charptr) p );
161622866Smckusick 	*p0 = lp;
161722866Smckusick 	}
161822866Smckusick 
161922866Smckusick if( ISCONST(p) )
162022866Smckusick 	{
162133257Sbostic 	offset += p->constblock.constant.ci;
162222866Smckusick 	frexpr(p);
162322866Smckusick 	*p0 = NULL;
162422866Smckusick 	}
162522866Smckusick 
162622866Smckusick return(offset);
162722866Smckusick }
162822866Smckusick 
162922866Smckusick 
163022866Smckusick 
163122866Smckusick 
163222866Smckusick 
p2op(op,type)163322866Smckusick p2op(op, type)
163422866Smckusick int op, type;
163522866Smckusick {
163622866Smckusick p2triple(op, 0, type);
163722866Smckusick }
163822866Smckusick 
p2icon(offset,type)163922866Smckusick p2icon(offset, type)
164022866Smckusick ftnint offset;
164122866Smckusick int type;
164222866Smckusick {
164322866Smckusick p2triple(PCC_ICON, 0, type);
164422866Smckusick p2word(offset);
164522866Smckusick }
164622866Smckusick 
164722866Smckusick 
164822866Smckusick 
164922866Smckusick 
p2oreg(offset,reg,type)165022866Smckusick p2oreg(offset, reg, type)
165122866Smckusick ftnint offset;
165222866Smckusick int reg, type;
165322866Smckusick {
165422866Smckusick p2triple(PCC_OREG, reg, type);
165522866Smckusick p2word(offset);
165622866Smckusick p2name("");
165722866Smckusick }
165822866Smckusick 
165922866Smckusick 
166022866Smckusick 
166122866Smckusick 
p2reg(reg,type)166222866Smckusick p2reg(reg, type)
166322866Smckusick int reg, type;
166422866Smckusick {
166522866Smckusick p2triple(PCC_REG, reg, type);
166622866Smckusick }
166722866Smckusick 
166822866Smckusick 
166922866Smckusick 
p2pi(s,i)167022866Smckusick p2pi(s, i)
167122866Smckusick char *s;
167222866Smckusick int i;
167322866Smckusick {
167422866Smckusick char buff[100];
167522866Smckusick sprintf(buff, s, i);
167622866Smckusick p2pass(buff);
167722866Smckusick }
167822866Smckusick 
167922866Smckusick 
168022866Smckusick 
p2pij(s,i,j)168122866Smckusick p2pij(s, i, j)
168222866Smckusick char *s;
168322866Smckusick int i, j;
168422866Smckusick {
168522866Smckusick char buff[100];
168622866Smckusick sprintf(buff, s, i, j);
168722866Smckusick p2pass(buff);
168822866Smckusick }
168922866Smckusick 
169022866Smckusick 
169122866Smckusick 
169222866Smckusick 
p2ps(s,t)169322866Smckusick p2ps(s, t)
169422866Smckusick char *s, *t;
169522866Smckusick {
169622866Smckusick char buff[100];
169722866Smckusick sprintf(buff, s, t);
169822866Smckusick p2pass(buff);
169922866Smckusick }
170022866Smckusick 
170122866Smckusick 
170222866Smckusick 
170322866Smckusick 
p2pass(s)170422866Smckusick p2pass(s)
170522866Smckusick char *s;
170622866Smckusick {
170722866Smckusick p2triple(PCCF_FTEXT, (strlen(s) + FOUR-1)/FOUR, 0);
170822866Smckusick p2str(s);
170922866Smckusick }
171022866Smckusick 
171122866Smckusick 
171222866Smckusick 
171322866Smckusick 
p2str(s)171422866Smckusick p2str(s)
171522866Smckusick register char *s;
171622866Smckusick {
171722866Smckusick union { long int word; char str[FOUR]; } u;
171822866Smckusick register int i;
171922866Smckusick 
172022866Smckusick i = 0;
172122866Smckusick u.word = 0;
172222866Smckusick while(*s)
172322866Smckusick 	{
172422866Smckusick 	u.str[i++] = *s++;
172522866Smckusick 	if(i == FOUR)
172622866Smckusick 		{
172722866Smckusick 		p2word(u.word);
172822866Smckusick 		u.word = 0;
172922866Smckusick 		i = 0;
173022866Smckusick 		}
173122866Smckusick 	}
173222866Smckusick if(i > 0)
173322866Smckusick 	p2word(u.word);
173422866Smckusick }
173522866Smckusick 
173622866Smckusick 
173722866Smckusick 
173822866Smckusick 
p2triple(op,var,type)173922866Smckusick p2triple(op, var, type)
174022866Smckusick int op, var, type;
174122866Smckusick {
174222866Smckusick register long word;
174322866Smckusick word = PCCM_TRIPLE(op, var, type);
174422866Smckusick p2word(word);
174522866Smckusick }
174622866Smckusick 
174722866Smckusick 
174822866Smckusick 
174922866Smckusick 
175022866Smckusick 
p2name(s)175122866Smckusick p2name(s)
175222866Smckusick register char *s;
175322866Smckusick {
175422866Smckusick register int i;
175522866Smckusick 
175622866Smckusick #ifdef UCBPASS2
175722866Smckusick 	/* arbitrary length names, terminated by a null,
175822866Smckusick 	   padded to a full word */
175922866Smckusick 
176022866Smckusick #	define WL   sizeof(long int)
176122866Smckusick 	union { long int word; char str[WL]; } w;
176222866Smckusick 
176322866Smckusick 	w.word = 0;
176422866Smckusick 	i = 0;
176522866Smckusick 	while(w.str[i++] = *s++)
176622866Smckusick 		if(i == WL)
176722866Smckusick 			{
176822866Smckusick 			p2word(w.word);
176922866Smckusick 			w.word = 0;
177022866Smckusick 			i = 0;
177122866Smckusick 			}
177222866Smckusick 	if(i > 0)
177322866Smckusick 		p2word(w.word);
177422866Smckusick #else
177522866Smckusick 	/* standard intermediate, names are 8 characters long */
177622866Smckusick 
177722866Smckusick 	union  { long int word[2];  char str[8]; } u;
177822866Smckusick 
177922866Smckusick 	u.word[0] = u.word[1] = 0;
178022866Smckusick 	for(i = 0 ; i<8 && *s ; ++i)
178122866Smckusick 		u.str[i] = *s++;
178222866Smckusick 	p2word(u.word[0]);
178322866Smckusick 	p2word(u.word[1]);
178422866Smckusick 
178522866Smckusick #endif
178622866Smckusick 
178722866Smckusick }
178822866Smckusick 
178922866Smckusick 
179022866Smckusick 
179122866Smckusick 
p2word(w)179222866Smckusick p2word(w)
179322866Smckusick long int w;
179422866Smckusick {
179522866Smckusick *p2bufp++ = w;
179622866Smckusick if(p2bufp >= p2bufend)
179722866Smckusick 	p2flush();
179822866Smckusick }
179922866Smckusick 
180022866Smckusick 
180122866Smckusick 
p2flush()180222866Smckusick p2flush()
180322866Smckusick {
180422866Smckusick if(p2bufp > p2buff)
180522866Smckusick 	write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
180622866Smckusick p2bufp = p2buff;
180722866Smckusick }
180822866Smckusick 
180922866Smckusick 
181022866Smckusick 
181122866Smckusick LOCAL
p2ldisp(offset,vname,type)181222866Smckusick p2ldisp(offset, vname, type)
181322866Smckusick ftnint offset;
181422866Smckusick char *vname;
181522866Smckusick int type;
181622866Smckusick {
181722866Smckusick   char buff[100];
181822866Smckusick 
181922866Smckusick   sprintf(buff, "%s-v.%d", vname, bsslabel);
182022866Smckusick   p2triple(PCC_OREG, 11, type);
182122866Smckusick   p2word(offset);
182222866Smckusick   p2name(buff);
182322866Smckusick }
182422866Smckusick 
182522866Smckusick 
182622866Smckusick 
p2ndisp(vname)182722866Smckusick p2ndisp(vname)
182822866Smckusick char *vname;
182922866Smckusick {
183022866Smckusick   char buff[100];
183122866Smckusick 
183222866Smckusick   sprintf(buff, "%s-v.%d", vname, bsslabel);
183322866Smckusick   p2name(buff);
183422866Smckusick }
1835