1*47951Sbostic /*-
2*47951Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic  * All rights reserved.
4*47951Sbostic  *
5*47951Sbostic  * %sccs.include.proprietary.c%
643222Sbostic  */
743222Sbostic 
843222Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)putpcc.c	5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
1143222Sbostic 
1243222Sbostic /*
1343222Sbostic  * putpcc.c
1443222Sbostic  *
1543222Sbostic  * Intermediate code generation for S. C. Johnson C compilers
1643222Sbostic  * New version using binary polish postfix intermediate
1743222Sbostic  *
1843222Sbostic  * University of Utah CS Dept modification history:
1943222Sbostic  *
2043222Sbostic  * $Header: putpcc.c,v 3.2 85/03/25 09:35:57 root Exp $
2143222Sbostic  * $Log:	putpcc.c,v $
2243222Sbostic  * Revision 3.2  85/03/25  09:35:57  root
2343222Sbostic  * fseek return -1 on error.
2443222Sbostic  *
2543222Sbostic  * Revision 3.1  85/02/27  19:06:55  donn
2643222Sbostic  * Changed to use pcc.h instead of pccdefs.h.
2743222Sbostic  *
2843222Sbostic  * Revision 2.12  85/02/22  01:05:54  donn
2943222Sbostic  * putaddr() didn't know about intrinsic functions...
3043222Sbostic  *
3143222Sbostic  * Revision 2.11  84/11/28  21:28:49  donn
3243222Sbostic  * Hacked putop() to handle any character expression being converted to int,
3343222Sbostic  * not just function calls.  Previously it bombed on concatenations.
3443222Sbostic  *
3543222Sbostic  * Revision 2.10  84/11/01  22:07:07  donn
3643222Sbostic  * Yet another try at getting putop() to work right.  It appears that the
3743222Sbostic  * second pass can't abide certain explicit conversions (e.g. short to long)
3843222Sbostic  * so the conversion code in putop() tries to remove them.  I think this
3943222Sbostic  * version (finally) works.
4043222Sbostic  *
4143222Sbostic  * Revision 2.9  84/10/29  02:30:57  donn
4243222Sbostic  * Earlier fix to putop() for conversions was insufficient -- we NEVER want to
4343222Sbostic  * see the type of the left operand of the thing left over from stripping off
4443222Sbostic  * conversions...
4543222Sbostic  *
4643222Sbostic  * Revision 2.8  84/09/18  03:09:21  donn
4743222Sbostic  * Fixed bug in putop() where the left operand of an addrblock was being
4843222Sbostic  * extracted...  This caused an extremely obscure conversion error when
4943222Sbostic  * an array of longs was subscripted by a short.
5043222Sbostic  *
5143222Sbostic  * Revision 2.7  84/08/19  20:10:19  donn
5243222Sbostic  * Removed stuff in putbranch that treats STGARG parameters specially -- the
5343222Sbostic  * bug in the code generation pass that motivated it has been fixed.
5443222Sbostic  *
5543222Sbostic  * Revision 2.6  84/08/07  21:32:23  donn
5643222Sbostic  * Bumped the size of the buffer for the intermediate code file from 0.5K
5743222Sbostic  * to 4K on a VAX.
5843222Sbostic  *
5943222Sbostic  * Revision 2.5  84/08/04  20:26:43  donn
6043222Sbostic  * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of
6143222Sbostic  * mktemp().  Correction due to Jerry Berkman.
6243222Sbostic  *
6343222Sbostic  * Revision 2.4  84/07/24  19:07:15  donn
6443222Sbostic  * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed
6543222Sbostic  * that mkaltemp() returns tempblocks, and tried to free them with frtemp().
6643222Sbostic  *
6743222Sbostic  * Revision 2.3  84/07/19  17:22:09  donn
6843222Sbostic  * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal.
6943222Sbostic  *
7043222Sbostic  * Revision 2.2  84/07/19  12:30:38  donn
7143222Sbostic  * Fixed a type clash in Bob Corbett's new putbranch().
7243222Sbostic  *
7343222Sbostic  * Revision 2.1  84/07/19  12:04:27  donn
7443222Sbostic  * Changed comment headers for UofU.
7543222Sbostic  *
7643222Sbostic  * Revision 1.8  84/07/19  11:38:23  donn
7743222Sbostic  * Replaced putbranch() routine so that you can ASSIGN into argument variables.
7843222Sbostic  * The code is from Bob Corbett, donated by Jerry Berkman.
7943222Sbostic  *
8043222Sbostic  * Revision 1.7  84/05/31  00:48:32  donn
8143222Sbostic  * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1
8243222Sbostic  * expressions -- a foulup in the order of COMOP and the comparison caused
8343222Sbostic  * one operand of the comparison to be garbage.
8443222Sbostic  *
8543222Sbostic  * Revision 1.6  84/04/16  09:54:19  donn
8643222Sbostic  * Backed out earlier fix for bug where items in the argtemplist were
8743222Sbostic  * (incorrectly) being given away; this is now fixed in mkargtemp().
8843222Sbostic  *
8943222Sbostic  * Revision 1.5  84/03/23  22:49:48  donn
9043222Sbostic  * Took out the initialization of the subroutine argument temporary list in
9143222Sbostic  * putcall() -- it needs to be done once per statement instead of once per call.
9243222Sbostic  *
9343222Sbostic  * Revision 1.4  84/03/01  06:48:05  donn
9443222Sbostic  * Fixed bug in Bob Corbett's code for argument temporaries that caused an
9543222Sbostic  * addrblock to get thrown out inadvertently when it was needed for recycling
9643222Sbostic  * purposes later on.
9743222Sbostic  *
9843222Sbostic  * Revision 1.3  84/02/26  06:32:38  donn
9943222Sbostic  * Added Berkeley changes to move data definitions around and reduce offsets.
10043222Sbostic  *
10143222Sbostic  * Revision 1.2  84/02/26  06:27:45  donn
10243222Sbostic  * Added code to catch TTEMP values passed to putx().
10343222Sbostic  *
10443222Sbostic  */
10543222Sbostic 
10643222Sbostic #if FAMILY != PCC
10743222Sbostic 	WRONG put FILE !!!!
10843222Sbostic #endif
10943222Sbostic 
11043222Sbostic #include "defs.h"
11143222Sbostic #include <pcc.h>
11243222Sbostic 
11343222Sbostic Addrp putcall(), putcxeq(), putcx1(), realpart();
11443222Sbostic expptr imagpart();
11543222Sbostic ftnint lencat();
11643222Sbostic 
11743222Sbostic #define FOUR 4
11843222Sbostic extern int ops2[];
11943222Sbostic extern int types2[];
12043222Sbostic 
12143222Sbostic #if HERE==VAX || HERE == TAHOE
12243222Sbostic #define PCC_BUFFMAX 1024
12343222Sbostic #else
12443222Sbostic #define PCC_BUFFMAX 128
12543222Sbostic #endif
12643222Sbostic static long int p2buff[PCC_BUFFMAX];
12743222Sbostic static long int *p2bufp		= &p2buff[0];
12843222Sbostic static long int *p2bufend	= &p2buff[PCC_BUFFMAX];
12943222Sbostic 
13043222Sbostic 
puthead(s,class)13143222Sbostic puthead(s, class)
13243222Sbostic char *s;
13343222Sbostic int class;
13443222Sbostic {
13543222Sbostic char buff[100];
13643222Sbostic #if TARGET == VAX || TARGET == TAHOE
13743222Sbostic 	if(s)
13843222Sbostic 		p2ps("\t.globl\t_%s", s);
13943222Sbostic #endif
14043222Sbostic /* put out fake copy of left bracket line, to be redone later */
14143222Sbostic if( ! headerdone )
14243222Sbostic 	{
14343222Sbostic #if FAMILY == PCC
14443222Sbostic 	p2flush();
14543222Sbostic #endif
14643222Sbostic 	headoffset = ftell(textfile);
14743222Sbostic 	prhead(textfile);
14843222Sbostic 	headerdone = YES;
14943222Sbostic 	p2triple(PCCF_FEXPR, (strlen(infname)+ALILONG-1)/ALILONG, 0);
15043222Sbostic 	p2str(infname);
15143222Sbostic #if TARGET == PDP11
15243222Sbostic 	/* fake jump to start the optimizer */
15343222Sbostic 	if(class != CLBLOCK)
15443222Sbostic 		putgoto( fudgelabel = newlabel() );
15543222Sbostic #endif
15643222Sbostic 
15743222Sbostic #if TARGET == VAX || TARGET == TAHOE
15843222Sbostic 	/* jump from top to bottom */
15943222Sbostic 	if(s!=CNULL && class!=CLBLOCK)
16043222Sbostic 		{
16143222Sbostic 		int proflab = newlabel();
16243222Sbostic 		p2pass("\t.align\t1");
16343222Sbostic 		p2ps("_%s:", s);
16443222Sbostic 		p2pi("\t.word\tLWM%d", procno);
16543222Sbostic 		prsave(proflab);
16643222Sbostic #if TARGET == VAX
16743222Sbostic 		p2pi("\tjbr\tL%d",
16843222Sbostic #else
16943222Sbostic 		putgoto(
17043222Sbostic #endif
17143222Sbostic 		 fudgelabel = newlabel());
17243222Sbostic 		}
17343222Sbostic #endif
17443222Sbostic 	}
17543222Sbostic }
17643222Sbostic 
17743222Sbostic 
17843222Sbostic 
17943222Sbostic 
18043222Sbostic 
18143222Sbostic /* It is necessary to precede each procedure with a "left bracket"
18243222Sbostic  * line that tells pass 2 how many register variables and how
18343222Sbostic  * much automatic space is required for the function.  This compiler
18443222Sbostic  * does not know how much automatic space is needed until the
18543222Sbostic  * entire procedure has been processed.  Therefore, "puthead"
18643222Sbostic  * is called at the begining to record the current location in textfile,
18743222Sbostic  * then to put out a placeholder left bracket line.  This procedure
18843222Sbostic  * repositions the file and rewrites that line, then puts the
18943222Sbostic  * file pointer back to the end of the file.
19043222Sbostic  */
19143222Sbostic 
putbracket()19243222Sbostic putbracket()
19343222Sbostic {
19443222Sbostic long int hereoffset;
19543222Sbostic 
19643222Sbostic #if FAMILY == PCC
19743222Sbostic 	p2flush();
19843222Sbostic #endif
19943222Sbostic hereoffset = ftell(textfile);
20043222Sbostic if(fseek(textfile, headoffset, 0) == -1)
20143222Sbostic 	fatal("fseek failed");
20243222Sbostic prhead(textfile);
20343222Sbostic if(fseek(textfile, hereoffset, 0) == -1)
20443222Sbostic 	fatal("fseek failed 2");
20543222Sbostic }
20643222Sbostic 
20743222Sbostic 
20843222Sbostic 
20943222Sbostic 
putrbrack(k)21043222Sbostic putrbrack(k)
21143222Sbostic int k;
21243222Sbostic {
21343222Sbostic p2op(PCCF_FRBRAC, k);
21443222Sbostic }
21543222Sbostic 
21643222Sbostic 
21743222Sbostic 
putnreg()21843222Sbostic putnreg()
21943222Sbostic {
22043222Sbostic }
22143222Sbostic 
22243222Sbostic 
22343222Sbostic 
22443222Sbostic 
22543222Sbostic 
22643222Sbostic 
puteof()22743222Sbostic puteof()
22843222Sbostic {
22943222Sbostic p2op(PCCF_FEOF, 0);
23043222Sbostic p2flush();
23143222Sbostic }
23243222Sbostic 
23343222Sbostic 
23443222Sbostic 
putstmt()23543222Sbostic putstmt()
23643222Sbostic {
23743222Sbostic p2triple(PCCF_FEXPR, 0, lineno);
23843222Sbostic }
23943222Sbostic 
24043222Sbostic 
24143222Sbostic 
24243222Sbostic 
24343222Sbostic /* put out code for if( ! p) goto l  */
putif(p,l)24443222Sbostic putif(p,l)
24543222Sbostic register expptr p;
24643222Sbostic int l;
24743222Sbostic {
24843222Sbostic register int k;
24943222Sbostic 
25043222Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
25143222Sbostic 	{
25243222Sbostic 	if(k != TYERROR)
25343222Sbostic 		err("non-logical expression in IF statement");
25443222Sbostic 	frexpr(p);
25543222Sbostic 	}
25643222Sbostic else
25743222Sbostic 	{
25843222Sbostic 	putex1(p);
25943222Sbostic 	p2icon( (long int) l , PCCT_INT);
26043222Sbostic 	p2op(PCC_CBRANCH, 0);
26143222Sbostic 	putstmt();
26243222Sbostic 	}
26343222Sbostic }
26443222Sbostic 
26543222Sbostic 
26643222Sbostic 
26743222Sbostic 
26843222Sbostic 
26943222Sbostic /* put out code for  goto l   */
putgoto(label)27043222Sbostic putgoto(label)
27143222Sbostic int label;
27243222Sbostic {
27343222Sbostic p2triple(PCC_GOTO, 1, label);
27443222Sbostic putstmt();
27543222Sbostic }
27643222Sbostic 
27743222Sbostic 
27843222Sbostic /* branch to address constant or integer variable */
putbranch(p)27943222Sbostic putbranch(p)
28043222Sbostic register Addrp p;
28143222Sbostic {
28243222Sbostic   putex1((expptr) p);
28343222Sbostic   p2op(PCC_GOTO, PCCT_INT);
28443222Sbostic   putstmt();
28543222Sbostic }
28643222Sbostic 
28743222Sbostic 
28843222Sbostic 
28943222Sbostic /* put out label  l:     */
putlabel(label)29043222Sbostic putlabel(label)
29143222Sbostic int label;
29243222Sbostic {
29343222Sbostic p2op(PCCF_FLABEL, label);
29443222Sbostic }
29543222Sbostic 
29643222Sbostic 
29743222Sbostic 
29843222Sbostic 
putexpr(p)29943222Sbostic putexpr(p)
30043222Sbostic expptr p;
30143222Sbostic {
30243222Sbostic putex1(p);
30343222Sbostic putstmt();
30443222Sbostic }
30543222Sbostic 
30643222Sbostic 
30743222Sbostic 
30843222Sbostic 
putcmgo(index,nlab,labs)30943222Sbostic putcmgo(index, nlab, labs)
31043222Sbostic expptr index;
31143222Sbostic int nlab;
31243222Sbostic struct Labelblock *labs[];
31343222Sbostic {
31443222Sbostic int i, labarray, skiplabel;
31543222Sbostic 
31643222Sbostic if(! ISINT(index->headblock.vtype) )
31743222Sbostic 	{
31843222Sbostic 	execerr("computed goto index must be integer", CNULL);
31943222Sbostic 	return;
32043222Sbostic 	}
32143222Sbostic 
32243222Sbostic #if TARGET == VAX || TARGET == TAHOE
32343222Sbostic 	/* use special case instruction */
32443222Sbostic 	casegoto(index, nlab, labs);
32543222Sbostic #else
32643222Sbostic 	labarray = newlabel();
32743222Sbostic 	preven(ALIADDR);
32843222Sbostic 	prlabel(asmfile, labarray);
32943222Sbostic 	prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
33043222Sbostic 	for(i = 0 ; i < nlab ; ++i)
33143222Sbostic 		if( labs[i] )
33243222Sbostic 			prcona(asmfile, (ftnint)(labs[i]->labelno) );
33343222Sbostic 	prcmgoto(index, nlab, skiplabel, labarray);
33443222Sbostic 	putlabel(skiplabel);
33543222Sbostic #endif
33643222Sbostic }
33743222Sbostic 
putx(p)33843222Sbostic putx(p)
33943222Sbostic expptr p;
34043222Sbostic {
34143222Sbostic char *memname();
34243222Sbostic int opc;
34343222Sbostic int ncomma;
34443222Sbostic int type, k;
34543222Sbostic 
34643222Sbostic if (!p)
34743222Sbostic 	return;
34843222Sbostic 
34943222Sbostic switch(p->tag)
35043222Sbostic 	{
35143222Sbostic 	case TERROR:
35243222Sbostic 		free( (charptr) p );
35343222Sbostic 		break;
35443222Sbostic 
35543222Sbostic 	case TCONST:
35643222Sbostic 		switch(type = p->constblock.vtype)
35743222Sbostic 			{
35843222Sbostic 			case TYLOGICAL:
35943222Sbostic 				type = tyint;
36043222Sbostic 			case TYLONG:
36143222Sbostic 			case TYSHORT:
36246306Sbostic 				p2icon(p->constblock.constant.ci, types2[type]);
36343222Sbostic 				free( (charptr) p );
36443222Sbostic 				break;
36543222Sbostic 
36643222Sbostic 			case TYADDR:
36743222Sbostic 				p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR);
36843222Sbostic 				p2word(0L);
36943222Sbostic 				p2name(memname(STGCONST,
37046306Sbostic 					(int) p->constblock.constant.ci) );
37143222Sbostic 				free( (charptr) p );
37243222Sbostic 				break;
37343222Sbostic 
37443222Sbostic 			default:
37543222Sbostic 				putx( putconst(p) );
37643222Sbostic 				break;
37743222Sbostic 			}
37843222Sbostic 		break;
37943222Sbostic 
38043222Sbostic 	case TEXPR:
38143222Sbostic 		switch(opc = p->exprblock.opcode)
38243222Sbostic 			{
38343222Sbostic 			case OPCALL:
38443222Sbostic 			case OPCCALL:
38543222Sbostic 				if( ISCOMPLEX(p->exprblock.vtype) )
38643222Sbostic 					putcxop(p);
38743222Sbostic 				else	putcall(p);
38843222Sbostic 				break;
38943222Sbostic 
39043222Sbostic 			case OPMIN:
39143222Sbostic 			case OPMAX:
39243222Sbostic 				putmnmx(p);
39343222Sbostic 				break;
39443222Sbostic 
39543222Sbostic 
39643222Sbostic 			case OPASSIGN:
39743222Sbostic 				if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
39843222Sbostic 				|| ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
39943222Sbostic 					frexpr( putcxeq(p) );
40043222Sbostic 				else if( ISCHAR(p) )
40143222Sbostic 					putcheq(p);
40243222Sbostic 				else
40343222Sbostic 					goto putopp;
40443222Sbostic 				break;
40543222Sbostic 
40643222Sbostic 			case OPEQ:
40743222Sbostic 			case OPNE:
40843222Sbostic 				if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
40943222Sbostic 				    ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
41043222Sbostic 					{
41143222Sbostic 					putcxcmp(p);
41243222Sbostic 					break;
41343222Sbostic 					}
41443222Sbostic 			case OPLT:
41543222Sbostic 			case OPLE:
41643222Sbostic 			case OPGT:
41743222Sbostic 			case OPGE:
41843222Sbostic 				if(ISCHAR(p->exprblock.leftp))
41943222Sbostic 					{
42043222Sbostic 					putchcmp(p);
42143222Sbostic 					break;
42243222Sbostic 					}
42343222Sbostic 				goto putopp;
42443222Sbostic 
42543222Sbostic 			case OPPOWER:
42643222Sbostic 				putpower(p);
42743222Sbostic 				break;
42843222Sbostic 
42943222Sbostic 			case OPSTAR:
43043222Sbostic #if FAMILY == PCC
43143222Sbostic 				/*   m * (2**k) -> m<<k   */
43243222Sbostic 				if(INT(p->exprblock.leftp->headblock.vtype) &&
43343222Sbostic 				   ISICON(p->exprblock.rightp) &&
43446306Sbostic 				   ( (k = log2(p->exprblock.rightp->constblock.constant.ci))>0) )
43543222Sbostic 					{
43643222Sbostic 					p->exprblock.opcode = OPLSHIFT;
43743222Sbostic 					frexpr(p->exprblock.rightp);
43843222Sbostic 					p->exprblock.rightp = ICON(k);
43943222Sbostic 					goto putopp;
44043222Sbostic 					}
44143222Sbostic #endif
44243222Sbostic 
44343222Sbostic 			case OPMOD:
44443222Sbostic 				goto putopp;
44543222Sbostic 			case OPPLUS:
44643222Sbostic 			case OPMINUS:
44743222Sbostic 			case OPSLASH:
44843222Sbostic 			case OPNEG:
44943222Sbostic 				if( ISCOMPLEX(p->exprblock.vtype) )
45043222Sbostic 					putcxop(p);
45143222Sbostic 				else	goto putopp;
45243222Sbostic 				break;
45343222Sbostic 
45443222Sbostic 			case OPCONV:
45543222Sbostic 				if( ISCOMPLEX(p->exprblock.vtype) )
45643222Sbostic 					putcxop(p);
45743222Sbostic 				else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
45843222Sbostic 					{
45943222Sbostic 					ncomma = 0;
46043222Sbostic 					putx( mkconv(p->exprblock.vtype,
46143222Sbostic 						realpart(putcx1(p->exprblock.leftp,
46243222Sbostic 							&ncomma))));
46343222Sbostic 					putcomma(ncomma, p->exprblock.vtype, NO);
46443222Sbostic 					free( (charptr) p );
46543222Sbostic 					}
46643222Sbostic 				else	goto putopp;
46743222Sbostic 				break;
46843222Sbostic 
46943222Sbostic 			case OPNOT:
47043222Sbostic 			case OPOR:
47143222Sbostic 			case OPAND:
47243222Sbostic 			case OPEQV:
47343222Sbostic 			case OPNEQV:
47443222Sbostic 			case OPADDR:
47543222Sbostic 			case OPPLUSEQ:
47643222Sbostic 			case OPSTAREQ:
47743222Sbostic 			case OPCOMMA:
47843222Sbostic 			case OPQUEST:
47943222Sbostic 			case OPCOLON:
48043222Sbostic 			case OPBITOR:
48143222Sbostic 			case OPBITAND:
48243222Sbostic 			case OPBITXOR:
48343222Sbostic 			case OPBITNOT:
48443222Sbostic 			case OPLSHIFT:
48543222Sbostic 			case OPRSHIFT:
48643222Sbostic 		putopp:
48743222Sbostic 				putop(p);
48843222Sbostic 				break;
48943222Sbostic 
49043222Sbostic 			case OPPAREN:
49143222Sbostic 				putx (p->exprblock.leftp);
49243222Sbostic 				break;
49343222Sbostic 			default:
49443222Sbostic 				badop("putx", opc);
49543222Sbostic 			}
49643222Sbostic 		break;
49743222Sbostic 
49843222Sbostic 	case TADDR:
49943222Sbostic 		putaddr(p, YES);
50043222Sbostic 		break;
50143222Sbostic 
50243222Sbostic 	case TTEMP:
50343222Sbostic 		/*
50443222Sbostic 		 * This type is sometimes passed to putx when errors occur
50543222Sbostic 		 *	upstream, I don't know why.
50643222Sbostic 		 */
50743222Sbostic 		frexpr(p);
50843222Sbostic 		break;
50943222Sbostic 
51043222Sbostic 	default:
51143222Sbostic 		badtag("putx", p->tag);
51243222Sbostic 	}
51343222Sbostic }
51443222Sbostic 
51543222Sbostic 
51643222Sbostic 
putop(p)51743222Sbostic LOCAL putop(p)
51843222Sbostic expptr p;
51943222Sbostic {
52043222Sbostic int k;
52143222Sbostic expptr lp, tp;
52243222Sbostic int pt, lt, tt;
52343222Sbostic int comma;
52443222Sbostic Addrp putch1();
52543222Sbostic 
52643222Sbostic switch(p->exprblock.opcode)	/* check for special cases and rewrite */
52743222Sbostic 	{
52843222Sbostic 	case OPCONV:
52943222Sbostic 		tt = pt = p->exprblock.vtype;
53043222Sbostic 		lp = p->exprblock.leftp;
53143222Sbostic 		lt = lp->headblock.vtype;
53243222Sbostic #if TARGET == VAX
53343222Sbostic 		if (pt == TYREAL && lt == TYDREAL)
53443222Sbostic 			{
53543222Sbostic 			putx(lp);
53643222Sbostic 			p2op(PCC_SCONV, PCCT_FLOAT);
53743222Sbostic 			return;
53843222Sbostic 			}
53943222Sbostic #endif
54043222Sbostic 		while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && (
54143222Sbostic #if TARGET != TAHOE
54243222Sbostic 		       (ISREAL(pt)&&ISREAL(lt)) ||
54343222Sbostic #endif
54443222Sbostic 			(INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
54543222Sbostic 			{
54643222Sbostic #if SZINT < SZLONG
54743222Sbostic 			if(lp->tag != TEXPR)
54843222Sbostic 				{
54943222Sbostic 				if(pt==TYINT && lt==TYLONG)
55043222Sbostic 					break;
55143222Sbostic 				if(lt==TYINT && pt==TYLONG)
55243222Sbostic 					break;
55343222Sbostic 				}
55443222Sbostic #endif
55543222Sbostic 
55643222Sbostic #if TARGET == VAX
55743222Sbostic 			if(pt==TYDREAL && lt==TYREAL)
55843222Sbostic 				{
55943222Sbostic 				if(lp->tag==TEXPR &&
56043222Sbostic 				   lp->exprblock.opcode==OPCONV &&
56143222Sbostic 				   lp->exprblock.leftp->headblock.vtype==TYDREAL)
56243222Sbostic 					{
56343222Sbostic 					putx(lp->exprblock.leftp);
56443222Sbostic 					p2op(PCC_SCONV, PCCT_FLOAT);
56543222Sbostic 					p2op(PCC_SCONV, PCCT_DOUBLE);
56643222Sbostic 					free( (charptr) p );
56743222Sbostic 					return;
56843222Sbostic 					}
56943222Sbostic 				else break;
57043222Sbostic 				}
57143222Sbostic #endif
57243222Sbostic 			if(lt==TYCHAR && lp->tag==TEXPR)
57343222Sbostic 				{
57443222Sbostic 				int ncomma = 0;
57543222Sbostic 				p->exprblock.leftp = (expptr) putch1(lp, &ncomma);
57643222Sbostic 				putop(p);
57743222Sbostic 				putcomma(ncomma, pt, NO);
57843222Sbostic 				free( (charptr) p );
57943222Sbostic 				return;
58043222Sbostic 				}
58143222Sbostic 			free( (charptr) p );
58243222Sbostic 			p = lp;
58343222Sbostic 			pt = lt;
58443222Sbostic 			if (p->tag == TEXPR)
58543222Sbostic 				{
58643222Sbostic 				lp = p->exprblock.leftp;
58743222Sbostic 				lt = lp->headblock.vtype;
58843222Sbostic 				}
58943222Sbostic 			}
59043222Sbostic 		if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
59143222Sbostic 			break;
59243222Sbostic 		putx(p);
59343222Sbostic 		if (types2[tt] != types2[pt] &&
59443222Sbostic 		    ! ( (ISREAL(tt)&&ISREAL(pt)) ||
59543222Sbostic 			(INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
59643222Sbostic 			p2op(PCC_SCONV,types2[tt]);
59743222Sbostic 		return;
59843222Sbostic 
59943222Sbostic 	case OPADDR:
60043222Sbostic 		comma = NO;
60143222Sbostic 		lp = p->exprblock.leftp;
60243222Sbostic 		if(lp->tag != TADDR)
60343222Sbostic 			{
60443222Sbostic 			tp = (expptr) mkaltemp
60543222Sbostic 				(lp->headblock.vtype,lp->headblock.vleng);
60643222Sbostic 			putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
60743222Sbostic 			lp = tp;
60843222Sbostic 			comma = YES;
60943222Sbostic 			}
61043222Sbostic 		putaddr(lp, NO);
61143222Sbostic 		if(comma)
61243222Sbostic 			putcomma(1, TYINT, NO);
61343222Sbostic 		free( (charptr) p );
61443222Sbostic 		return;
61543222Sbostic #if TARGET == VAX || TARGET == TAHOE
61643222Sbostic /* take advantage of a glitch in the code generator that does not check
61743222Sbostic    the type clash in an assignment or comparison of an integer zero and
61843222Sbostic    a floating left operand, and generates optimal code for the correct
61943222Sbostic    type.  (The PCC has no floating-constant node to encode this correctly.)
62043222Sbostic */
62143222Sbostic 	case OPASSIGN:
62243222Sbostic 	case OPLT:
62343222Sbostic 	case OPLE:
62443222Sbostic 	case OPGT:
62543222Sbostic 	case OPGE:
62643222Sbostic 	case OPEQ:
62743222Sbostic 	case OPNE:
62843222Sbostic 		if(ISREAL(p->exprblock.leftp->headblock.vtype) &&
62943222Sbostic 		   ISREAL(p->exprblock.rightp->headblock.vtype) &&
63043222Sbostic 		   ISCONST(p->exprblock.rightp) &&
63146306Sbostic 		   p->exprblock.rightp->constblock.constant.cd[0]==0)
63243222Sbostic 			{
63343222Sbostic 			p->exprblock.rightp->constblock.vtype = TYINT;
63446306Sbostic 			p->exprblock.rightp->constblock.constant.ci = 0;
63543222Sbostic 			}
63643222Sbostic #endif
63743222Sbostic 	}
63843222Sbostic 
63943222Sbostic if( (k = ops2[p->exprblock.opcode]) <= 0)
64043222Sbostic 	badop("putop", p->exprblock.opcode);
64143222Sbostic putx(p->exprblock.leftp);
64243222Sbostic if(p->exprblock.rightp)
64343222Sbostic 	putx(p->exprblock.rightp);
64443222Sbostic p2op(k, types2[p->exprblock.vtype]);
64543222Sbostic 
64643222Sbostic if(p->exprblock.vleng)
64743222Sbostic 	frexpr(p->exprblock.vleng);
64843222Sbostic free( (charptr) p );
64943222Sbostic }
65043222Sbostic 
putforce(t,p)65143222Sbostic putforce(t, p)
65243222Sbostic int t;
65343222Sbostic expptr p;
65443222Sbostic {
65543222Sbostic p = mkconv(t, fixtype(p));
65643222Sbostic putx(p);
65743222Sbostic p2op(PCC_FORCE,
65843222Sbostic #if TARGET == TAHOE
65943222Sbostic 	(t==TYLONG ? PCCT_LONG : (t==TYREAL ? PCCT_FLOAT : PCCT_DOUBLE)) );
66043222Sbostic #else
66143222Sbostic 	(t==TYSHORT ? PCCT_SHORT : (t==TYLONG ? PCCT_LONG : PCCT_DOUBLE)) );
66243222Sbostic #endif
66343222Sbostic putstmt();
66443222Sbostic }
66543222Sbostic 
66643222Sbostic 
66743222Sbostic 
putpower(p)66843222Sbostic LOCAL putpower(p)
66943222Sbostic expptr p;
67043222Sbostic {
67143222Sbostic expptr base;
67243222Sbostic Addrp t1, t2;
67343222Sbostic ftnint k;
67443222Sbostic int type;
67543222Sbostic int ncomma;
67643222Sbostic 
67743222Sbostic if(!ISICON(p->exprblock.rightp) ||
67846306Sbostic     (k = p->exprblock.rightp->constblock.constant.ci)<2)
67943222Sbostic 	fatal("putpower: bad call");
68043222Sbostic base = p->exprblock.leftp;
68143222Sbostic type = base->headblock.vtype;
68243222Sbostic 
68343222Sbostic if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset))
68443222Sbostic {
68543222Sbostic 	putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base)));
68643222Sbostic 
68743222Sbostic 	return;
68843222Sbostic }
68943222Sbostic t1 = mkaltemp(type, PNULL);
69043222Sbostic t2 = NULL;
69143222Sbostic ncomma = 1;
69243222Sbostic putassign(cpexpr(t1), cpexpr(base) );
69343222Sbostic 
69443222Sbostic for( ; (k&1)==0 && k>2 ; k>>=1 )
69543222Sbostic 	{
69643222Sbostic 	++ncomma;
69743222Sbostic 	putsteq(t1, t1);
69843222Sbostic 	}
69943222Sbostic 
70043222Sbostic if(k == 2)
70143222Sbostic 	putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
70243222Sbostic else
70343222Sbostic 	{
70443222Sbostic 	t2 = mkaltemp(type, PNULL);
70543222Sbostic 	++ncomma;
70643222Sbostic 	putassign(cpexpr(t2), cpexpr(t1));
70743222Sbostic 
70843222Sbostic 	for(k>>=1 ; k>1 ; k>>=1)
70943222Sbostic 		{
71043222Sbostic 		++ncomma;
71143222Sbostic 		putsteq(t1, t1);
71243222Sbostic 		if(k & 1)
71343222Sbostic 			{
71443222Sbostic 			++ncomma;
71543222Sbostic 			putsteq(t2, t1);
71643222Sbostic 			}
71743222Sbostic 		}
71843222Sbostic 	putx( mkexpr(OPSTAR, cpexpr(t2),
71943222Sbostic 		mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
72043222Sbostic 	}
72143222Sbostic putcomma(ncomma, type, NO);
72243222Sbostic frexpr(t1);
72343222Sbostic if(t2)
72443222Sbostic 	frexpr(t2);
72543222Sbostic frexpr(p);
72643222Sbostic }
72743222Sbostic 
72843222Sbostic 
72943222Sbostic 
73043222Sbostic 
intdouble(p,ncommap)73143222Sbostic LOCAL Addrp intdouble(p, ncommap)
73243222Sbostic Addrp p;
73343222Sbostic int *ncommap;
73443222Sbostic {
73543222Sbostic register Addrp t;
73643222Sbostic 
73743222Sbostic t = mkaltemp(TYDREAL, PNULL);
73843222Sbostic ++*ncommap;
73943222Sbostic putassign(cpexpr(t), p);
74043222Sbostic return(t);
74143222Sbostic }
74243222Sbostic 
74343222Sbostic 
74443222Sbostic 
74543222Sbostic 
74643222Sbostic 
putcxeq(p)74743222Sbostic LOCAL Addrp putcxeq(p)
74843222Sbostic register expptr p;
74943222Sbostic {
75043222Sbostic register Addrp lp, rp;
75143222Sbostic int ncomma;
75243222Sbostic 
75343222Sbostic if(p->tag != TEXPR)
75443222Sbostic 	badtag("putcxeq", p->tag);
75543222Sbostic 
75643222Sbostic ncomma = 0;
75743222Sbostic lp = putcx1(p->exprblock.leftp, &ncomma);
75843222Sbostic rp = putcx1(p->exprblock.rightp, &ncomma);
75943222Sbostic putassign(realpart(lp), realpart(rp));
76043222Sbostic if( ISCOMPLEX(p->exprblock.vtype) )
76143222Sbostic 	{
76243222Sbostic 	++ncomma;
76343222Sbostic 	putassign(imagpart(lp), imagpart(rp));
76443222Sbostic 	}
76543222Sbostic putcomma(ncomma, TYREAL, NO);
76643222Sbostic frexpr(rp);
76743222Sbostic free( (charptr) p );
76843222Sbostic return(lp);
76943222Sbostic }
77043222Sbostic 
77143222Sbostic 
77243222Sbostic 
putcxop(p)77343222Sbostic LOCAL putcxop(p)
77443222Sbostic expptr p;
77543222Sbostic {
77643222Sbostic Addrp putcx1();
77743222Sbostic int ncomma;
77843222Sbostic 
77943222Sbostic ncomma = 0;
78043222Sbostic putaddr( putcx1(p, &ncomma), NO);
78143222Sbostic putcomma(ncomma, TYINT, NO);
78243222Sbostic }
78343222Sbostic 
78443222Sbostic 
78543222Sbostic 
putcx1(p,ncommap)78643222Sbostic LOCAL Addrp putcx1(p, ncommap)
78743222Sbostic register expptr p;
78843222Sbostic int *ncommap;
78943222Sbostic {
79043222Sbostic expptr q;
79143222Sbostic Addrp lp, rp;
79243222Sbostic register Addrp resp;
79343222Sbostic int opcode;
79443222Sbostic int ltype, rtype;
79543222Sbostic expptr mkrealcon();
79643222Sbostic 
79743222Sbostic if(p == NULL)
79843222Sbostic 	return(NULL);
79943222Sbostic 
80043222Sbostic switch(p->tag)
80143222Sbostic 	{
80243222Sbostic 	case TCONST:
80343222Sbostic 		if( ISCOMPLEX(p->constblock.vtype) )
80443222Sbostic 			p = (expptr) putconst(p);
80543222Sbostic 		return( (Addrp) p );
80643222Sbostic 
80743222Sbostic 	case TADDR:
80843222Sbostic 		if( ! addressable(p) )
80943222Sbostic 			{
81043222Sbostic 			++*ncommap;
81143222Sbostic 			resp = mkaltemp(tyint, PNULL);
81243222Sbostic 			putassign( cpexpr(resp), p->addrblock.memoffset );
81343222Sbostic 			p->addrblock.memoffset = (expptr)resp;
81443222Sbostic 			}
81543222Sbostic 		return( (Addrp) p );
81643222Sbostic 
81743222Sbostic 	case TEXPR:
81843222Sbostic 		if( ISCOMPLEX(p->exprblock.vtype) )
81943222Sbostic 			break;
82043222Sbostic 		++*ncommap;
82143222Sbostic 		resp = mkaltemp(TYDREAL, NO);
82243222Sbostic 		putassign( cpexpr(resp), p);
82343222Sbostic 		return(resp);
82443222Sbostic 
82543222Sbostic 	default:
82643222Sbostic 		badtag("putcx1", p->tag);
82743222Sbostic 	}
82843222Sbostic 
82943222Sbostic opcode = p->exprblock.opcode;
83043222Sbostic if(opcode==OPCALL || opcode==OPCCALL)
83143222Sbostic 	{
83243222Sbostic 	++*ncommap;
83343222Sbostic 	return( putcall(p) );
83443222Sbostic 	}
83543222Sbostic else if(opcode == OPASSIGN)
83643222Sbostic 	{
83743222Sbostic 	++*ncommap;
83843222Sbostic 	return( putcxeq(p) );
83943222Sbostic 	}
84043222Sbostic resp = mkaltemp(p->exprblock.vtype, PNULL);
84143222Sbostic if(lp = putcx1(p->exprblock.leftp, ncommap) )
84243222Sbostic 	ltype = lp->vtype;
84343222Sbostic if(rp = putcx1(p->exprblock.rightp, ncommap) )
84443222Sbostic 	rtype = rp->vtype;
84543222Sbostic 
84643222Sbostic switch(opcode)
84743222Sbostic 	{
84843222Sbostic 	case OPPAREN:
84943222Sbostic 		frexpr (resp);
85043222Sbostic 		resp = lp;
85143222Sbostic 		lp = NULL;
85243222Sbostic 		break;
85343222Sbostic 
85443222Sbostic 	case OPCOMMA:
85543222Sbostic 		frexpr(resp);
85643222Sbostic 		resp = rp;
85743222Sbostic 		rp = NULL;
85843222Sbostic 		break;
85943222Sbostic 
86043222Sbostic 	case OPNEG:
86143222Sbostic 		putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) );
86243222Sbostic 		putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) );
86343222Sbostic 		*ncommap += 2;
86443222Sbostic 		break;
86543222Sbostic 
86643222Sbostic 	case OPPLUS:
86743222Sbostic 	case OPMINUS:
86843222Sbostic 		putassign( realpart(resp),
86943222Sbostic 			mkexpr(opcode, realpart(lp), realpart(rp) ));
87043222Sbostic 		if(rtype < TYCOMPLEX)
87143222Sbostic 			putassign( imagpart(resp), imagpart(lp) );
87243222Sbostic 		else if(ltype < TYCOMPLEX)
87343222Sbostic 			{
87443222Sbostic 			if(opcode == OPPLUS)
87543222Sbostic 				putassign( imagpart(resp), imagpart(rp) );
87643222Sbostic 			else	putassign( imagpart(resp),
87743222Sbostic 					mkexpr(OPNEG, imagpart(rp), ENULL) );
87843222Sbostic 			}
87943222Sbostic 		else
88043222Sbostic 			putassign( imagpart(resp),
88143222Sbostic 				mkexpr(opcode, imagpart(lp), imagpart(rp) ));
88243222Sbostic 
88343222Sbostic 		*ncommap += 2;
88443222Sbostic 		break;
88543222Sbostic 
88643222Sbostic 	case OPSTAR:
88743222Sbostic 		if(ltype < TYCOMPLEX)
88843222Sbostic 			{
88943222Sbostic 			if( ISINT(ltype) )
89043222Sbostic 				lp = intdouble(lp, ncommap);
89143222Sbostic 			putassign( realpart(resp),
89243222Sbostic 				mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
89343222Sbostic 			putassign( imagpart(resp),
89443222Sbostic 				mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
89543222Sbostic 			}
89643222Sbostic 		else if(rtype < TYCOMPLEX)
89743222Sbostic 			{
89843222Sbostic 			if( ISINT(rtype) )
89943222Sbostic 				rp = intdouble(rp, ncommap);
90043222Sbostic 			putassign( realpart(resp),
90143222Sbostic 				mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
90243222Sbostic 			putassign( imagpart(resp),
90343222Sbostic 				mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
90443222Sbostic 			}
90543222Sbostic 		else	{
90643222Sbostic 			putassign( realpart(resp), mkexpr(OPMINUS,
90743222Sbostic 				mkexpr(OPSTAR, realpart(lp), realpart(rp)),
90843222Sbostic 				mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
90943222Sbostic 			putassign( imagpart(resp), mkexpr(OPPLUS,
91043222Sbostic 				mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
91143222Sbostic 				mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
91243222Sbostic 			}
91343222Sbostic 		*ncommap += 2;
91443222Sbostic 		break;
91543222Sbostic 
91643222Sbostic 	case OPSLASH:
91743222Sbostic 		/* fixexpr has already replaced all divisions
91843222Sbostic 		 * by a complex by a function call
91943222Sbostic 		 */
92043222Sbostic 		if( ISINT(rtype) )
92143222Sbostic 			rp = intdouble(rp, ncommap);
92243222Sbostic 		putassign( realpart(resp),
92343222Sbostic 			mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
92443222Sbostic 		putassign( imagpart(resp),
92543222Sbostic 			mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
92643222Sbostic 		*ncommap += 2;
92743222Sbostic 		break;
92843222Sbostic 
92943222Sbostic 	case OPCONV:
93043222Sbostic 		putassign( realpart(resp), realpart(lp) );
93143222Sbostic 		if( ISCOMPLEX(lp->vtype) )
93243222Sbostic 			q = imagpart(lp);
93343222Sbostic 		else if(rp != NULL)
93443222Sbostic 			q = (expptr) realpart(rp);
93543222Sbostic 		else
93643222Sbostic 			q = mkrealcon(TYDREAL, 0.0);
93743222Sbostic 		putassign( imagpart(resp), q);
93843222Sbostic 		*ncommap += 2;
93943222Sbostic 		break;
94043222Sbostic 
94143222Sbostic 	default:
94243222Sbostic 		badop("putcx1", opcode);
94343222Sbostic 	}
94443222Sbostic 
94543222Sbostic frexpr(lp);
94643222Sbostic frexpr(rp);
94743222Sbostic free( (charptr) p );
94843222Sbostic return(resp);
94943222Sbostic }
95043222Sbostic 
95143222Sbostic 
95243222Sbostic 
95343222Sbostic 
putcxcmp(p)95443222Sbostic LOCAL putcxcmp(p)
95543222Sbostic register expptr p;
95643222Sbostic {
95743222Sbostic int opcode;
95843222Sbostic int ncomma;
95943222Sbostic register Addrp lp, rp;
96043222Sbostic expptr q;
96143222Sbostic 
96243222Sbostic if(p->tag != TEXPR)
96343222Sbostic 	badtag("putcxcmp", p->tag);
96443222Sbostic 
96543222Sbostic ncomma = 0;
96643222Sbostic opcode = p->exprblock.opcode;
96743222Sbostic lp = putcx1(p->exprblock.leftp, &ncomma);
96843222Sbostic rp = putcx1(p->exprblock.rightp, &ncomma);
96943222Sbostic 
97043222Sbostic q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
97143222Sbostic 	mkexpr(opcode, realpart(lp), realpart(rp)),
97243222Sbostic 	mkexpr(opcode, imagpart(lp), imagpart(rp)) );
97343222Sbostic putx( fixexpr(q) );
97443222Sbostic putcomma(ncomma, TYINT, NO);
97543222Sbostic 
97643222Sbostic free( (charptr) lp);
97743222Sbostic free( (charptr) rp);
97843222Sbostic free( (charptr) p );
97943222Sbostic }
98043222Sbostic 
putch1(p,ncommap)98143222Sbostic LOCAL Addrp putch1(p, ncommap)
98243222Sbostic register expptr p;
98343222Sbostic int * ncommap;
98443222Sbostic {
98543222Sbostic register Addrp t;
98643222Sbostic 
98743222Sbostic switch(p->tag)
98843222Sbostic 	{
98943222Sbostic 	case TCONST:
99043222Sbostic 		return( putconst(p) );
99143222Sbostic 
99243222Sbostic 	case TADDR:
99343222Sbostic 		return( (Addrp) p );
99443222Sbostic 
99543222Sbostic 	case TEXPR:
99643222Sbostic 		++*ncommap;
99743222Sbostic 
99843222Sbostic 		switch(p->exprblock.opcode)
99943222Sbostic 			{
100043222Sbostic 			expptr q;
100143222Sbostic 
100243222Sbostic 			case OPCALL:
100343222Sbostic 			case OPCCALL:
100443222Sbostic 				t = putcall(p);
100543222Sbostic 				break;
100643222Sbostic 
100743222Sbostic 			case OPPAREN:
100843222Sbostic 				--*ncommap;
100943222Sbostic 				t = putch1(p->exprblock.leftp, ncommap);
101043222Sbostic 				break;
101143222Sbostic 
101243222Sbostic 			case OPCONCAT:
101343222Sbostic 				t = mkaltemp(TYCHAR, ICON(lencat(p)) );
101443222Sbostic 				q = (expptr) cpexpr(p->headblock.vleng);
101543222Sbostic 				putcat( cpexpr(t), p );
101643222Sbostic 				/* put the correct length on the block */
101743222Sbostic 				frexpr(t->vleng);
101843222Sbostic 				t->vleng = q;
101943222Sbostic 
102043222Sbostic 				break;
102143222Sbostic 
102243222Sbostic 			case OPCONV:
102343222Sbostic 				if(!ISICON(p->exprblock.vleng)
102446306Sbostic 				   || p->exprblock.vleng->constblock.constant.ci!=1
102543222Sbostic 				   || ! INT(p->exprblock.leftp->headblock.vtype) )
102643222Sbostic 					fatal("putch1: bad character conversion");
102743222Sbostic 				t = mkaltemp(TYCHAR, ICON(1) );
102843222Sbostic 				putop( mkexpr(OPASSIGN, cpexpr(t), p) );
102943222Sbostic 				break;
103043222Sbostic 			default:
103143222Sbostic 				badop("putch1", p->exprblock.opcode);
103243222Sbostic 			}
103343222Sbostic 		return(t);
103443222Sbostic 
103543222Sbostic 	default:
103643222Sbostic 		badtag("putch1", p->tag);
103743222Sbostic 	}
103843222Sbostic /* NOTREACHED */
103943222Sbostic }
104043222Sbostic 
104143222Sbostic 
104243222Sbostic 
104343222Sbostic 
putchop(p)104443222Sbostic LOCAL putchop(p)
104543222Sbostic expptr p;
104643222Sbostic {
104743222Sbostic int ncomma;
104843222Sbostic 
104943222Sbostic ncomma = 0;
105043222Sbostic putaddr( putch1(p, &ncomma) , NO );
105143222Sbostic putcomma(ncomma, TYCHAR, YES);
105243222Sbostic }
105343222Sbostic 
105443222Sbostic 
105543222Sbostic 
105643222Sbostic 
putcheq(p)105743222Sbostic LOCAL putcheq(p)
105843222Sbostic register expptr p;
105943222Sbostic {
106043222Sbostic int ncomma;
106143222Sbostic expptr lp, rp;
106243222Sbostic 
106343222Sbostic if(p->tag != TEXPR)
106443222Sbostic 	badtag("putcheq", p->tag);
106543222Sbostic 
106643222Sbostic ncomma = 0;
106743222Sbostic lp = p->exprblock.leftp;
106843222Sbostic rp = p->exprblock.rightp;
106943222Sbostic if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
107043222Sbostic 	putcat(lp, rp);
107143222Sbostic else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
107243222Sbostic 	{
107343222Sbostic 	putaddr( putch1(lp, &ncomma) , YES );
107443222Sbostic 	putaddr( putch1(rp, &ncomma) , YES );
107543222Sbostic 	putcomma(ncomma, TYINT, NO);
107643222Sbostic 	p2op(PCC_ASSIGN, PCCT_CHAR);
107743222Sbostic 	}
107843222Sbostic else
107943222Sbostic 	{
108043222Sbostic 	putx( call2(TYINT, "s_copy", lp, rp) );
108143222Sbostic 	putcomma(ncomma, TYINT, NO);
108243222Sbostic 	}
108343222Sbostic 
108443222Sbostic frexpr(p->exprblock.vleng);
108543222Sbostic free( (charptr) p );
108643222Sbostic }
108743222Sbostic 
108843222Sbostic 
108943222Sbostic 
109043222Sbostic 
putchcmp(p)109143222Sbostic LOCAL putchcmp(p)
109243222Sbostic register expptr p;
109343222Sbostic {
109443222Sbostic int ncomma;
109543222Sbostic expptr lp, rp;
109643222Sbostic 
109743222Sbostic if(p->tag != TEXPR)
109843222Sbostic 	badtag("putchcmp", p->tag);
109943222Sbostic 
110043222Sbostic ncomma = 0;
110143222Sbostic lp = p->exprblock.leftp;
110243222Sbostic rp = p->exprblock.rightp;
110343222Sbostic 
110443222Sbostic if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
110543222Sbostic 	{
110643222Sbostic 	putaddr( putch1(lp, &ncomma) , YES );
110743222Sbostic 	putcomma(ncomma, TYINT, NO);
110843222Sbostic 	ncomma = 0;
110943222Sbostic 	putaddr( putch1(rp, &ncomma) , YES );
111043222Sbostic 	putcomma(ncomma, TYINT, NO);
111143222Sbostic 	p2op(ops2[p->exprblock.opcode], PCCT_CHAR);
111243222Sbostic 	free( (charptr) p );
111343222Sbostic 	}
111443222Sbostic else
111543222Sbostic 	{
111643222Sbostic 	p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp);
111743222Sbostic 	p->exprblock.rightp = ICON(0);
111843222Sbostic 	putop(p);
111943222Sbostic 	}
112043222Sbostic }
112143222Sbostic 
112243222Sbostic 
112343222Sbostic 
112443222Sbostic 
112543222Sbostic 
putcat(lhs,rhs)112643222Sbostic LOCAL putcat(lhs, rhs)
112743222Sbostic register Addrp lhs;
112843222Sbostic register expptr rhs;
112943222Sbostic {
113043222Sbostic int n, ncomma;
113143222Sbostic Addrp lp, cp;
113243222Sbostic 
113343222Sbostic ncomma = 0;
113443222Sbostic n = ncat(rhs);
113543222Sbostic lp = mkaltmpn(n, TYLENG, PNULL);
113643222Sbostic cp = mkaltmpn(n, TYADDR, PNULL);
113743222Sbostic 
113843222Sbostic n = 0;
113943222Sbostic putct1(rhs, lp, cp, &n, &ncomma);
114043222Sbostic 
114143222Sbostic putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
114243222Sbostic putcomma(ncomma, TYINT, NO);
114343222Sbostic }
114443222Sbostic 
114543222Sbostic 
114643222Sbostic 
114743222Sbostic 
114843222Sbostic 
putct1(q,lp,cp,ip,ncommap)114943222Sbostic LOCAL putct1(q, lp, cp, ip, ncommap)
115043222Sbostic register expptr q;
115143222Sbostic register Addrp lp, cp;
115243222Sbostic int *ip, *ncommap;
115343222Sbostic {
115443222Sbostic int i;
115543222Sbostic Addrp lp1, cp1;
115643222Sbostic 
115743222Sbostic if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
115843222Sbostic 	{
115943222Sbostic 	putct1(q->exprblock.leftp, lp, cp, ip, ncommap);
116043222Sbostic 	putct1(q->exprblock.rightp, lp, cp , ip, ncommap);
116143222Sbostic 	frexpr(q->exprblock.vleng);
116243222Sbostic 	free( (charptr) q );
116343222Sbostic 	}
116443222Sbostic else
116543222Sbostic 	{
116643222Sbostic 	i = (*ip)++;
116743222Sbostic 	lp1 = (Addrp) cpexpr(lp);
116843222Sbostic 	lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
116943222Sbostic 	cp1 = (Addrp) cpexpr(cp);
117043222Sbostic 	cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
117143222Sbostic 	putassign( lp1, cpexpr(q->headblock.vleng) );
117243222Sbostic 	putassign( cp1, addrof(putch1(q,ncommap)) );
117343222Sbostic 	*ncommap += 2;
117443222Sbostic 	}
117543222Sbostic }
117643222Sbostic 
putaddr(p,indir)117743222Sbostic LOCAL putaddr(p, indir)
117843222Sbostic register Addrp p;
117943222Sbostic int indir;
118043222Sbostic {
118143222Sbostic int type, type2, funct;
118243222Sbostic ftnint offset, simoffset();
118343222Sbostic expptr offp, shorten();
118443222Sbostic 
118543222Sbostic if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
118643222Sbostic 	{
118743222Sbostic 	frexpr(p);
118843222Sbostic 	return;
118943222Sbostic 	}
119043222Sbostic if (p->tag != TADDR) badtag ("putaddr",p->tag);
119143222Sbostic 
119243222Sbostic type = p->vtype;
119343222Sbostic type2 = types2[type];
119443222Sbostic funct = (p->vclass==CLPROC ? PCCTM_FTN<<2 : 0);
119543222Sbostic 
119643222Sbostic offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL );
119743222Sbostic 
119843222Sbostic 
119943222Sbostic #if (FUDGEOFFSET != 1)
120043222Sbostic if(offp)
120143222Sbostic 	offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
120243222Sbostic #endif
120343222Sbostic 
120443222Sbostic offset = simoffset( &offp );
120543222Sbostic #if SZINT < SZLONG
120643222Sbostic 	if(offp)
120743222Sbostic 		if(shortsubs)
120843222Sbostic 			offp = shorten(offp);
120943222Sbostic 		else
121043222Sbostic 			offp = mkconv(TYINT, offp);
121143222Sbostic #else
121243222Sbostic 	if(offp)
121343222Sbostic 		offp = mkconv(TYINT, offp);
121443222Sbostic #endif
121543222Sbostic 
121643222Sbostic if (p->vclass == CLVAR
121743222Sbostic     && (p->vstg == STGBSS || p->vstg == STGEQUIV)
121843222Sbostic     && SMALLVAR(p->varsize)
121943222Sbostic     && offset >= -32768 && offset <= 32767)
122043222Sbostic   {
122143222Sbostic     anylocals = YES;
122243222Sbostic     if (indir && !offp)
122343222Sbostic       p2ldisp(offset, memname(p->vstg, p->memno), type2);
122443222Sbostic     else
122543222Sbostic       {
122643222Sbostic 	p2reg(LVARREG, type2 | PCCTM_PTR);
122743222Sbostic 	p2triple(PCC_ICON, 1, PCCT_INT);
122843222Sbostic 	p2word(offset);
122943222Sbostic 	p2ndisp(memname(p->vstg, p->memno));
123043222Sbostic 	p2op(PCC_PLUS, type2 | PCCTM_PTR);
123143222Sbostic 	if (offp)
123243222Sbostic 	  {
123343222Sbostic 	    putx(offp);
123443222Sbostic 	    p2op(PCC_PLUS, type2 | PCCTM_PTR);
123543222Sbostic 	  }
123643222Sbostic 	if (indir)
123743222Sbostic 	  p2op(PCC_DEREF, type2);
123843222Sbostic       }
123943222Sbostic     frexpr((tagptr) p);
124043222Sbostic     return;
124143222Sbostic   }
124243222Sbostic 
124343222Sbostic switch(p->vstg)
124443222Sbostic 	{
124543222Sbostic 	case STGAUTO:
124643222Sbostic 		if(indir && !offp)
124743222Sbostic 			{
124843222Sbostic 			p2oreg(offset, AUTOREG, type2);
124943222Sbostic 			break;
125043222Sbostic 			}
125143222Sbostic 
125243222Sbostic 		if(!indir && !offp && !offset)
125343222Sbostic 			{
125443222Sbostic 			p2reg(AUTOREG, type2 | PCCTM_PTR);
125543222Sbostic 			break;
125643222Sbostic 			}
125743222Sbostic 
125843222Sbostic 		p2reg(AUTOREG, type2 | PCCTM_PTR);
125943222Sbostic 		if(offp)
126043222Sbostic 			{
126143222Sbostic 			putx(offp);
126243222Sbostic 			if(offset)
126343222Sbostic 				p2icon(offset, PCCT_INT);
126443222Sbostic 			}
126543222Sbostic 		else
126643222Sbostic 			p2icon(offset, PCCT_INT);
126743222Sbostic 		if(offp && offset)
126843222Sbostic 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
126943222Sbostic 		p2op(PCC_PLUS, type2 | PCCTM_PTR);
127043222Sbostic 		if(indir)
127143222Sbostic 			p2op(PCC_DEREF, type2);
127243222Sbostic 		break;
127343222Sbostic 
127443222Sbostic 	case STGARG:
127543222Sbostic 		p2oreg(
127643222Sbostic #ifdef ARGOFFSET
127743222Sbostic 			ARGOFFSET +
127843222Sbostic #endif
127943222Sbostic 			(ftnint) (FUDGEOFFSET*p->memno),
128043222Sbostic 			ARGREG,   type2 | PCCTM_PTR | funct );
128143222Sbostic 
128243222Sbostic 	based:
128343222Sbostic 		if(offset)
128443222Sbostic 			{
128543222Sbostic 			p2icon(offset, PCCT_INT);
128643222Sbostic 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
128743222Sbostic 			}
128843222Sbostic 		if(offp)
128943222Sbostic 			{
129043222Sbostic 			putx(offp);
129143222Sbostic 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
129243222Sbostic 			}
129343222Sbostic 		if(indir)
129443222Sbostic 			p2op(PCC_DEREF, type2);
129543222Sbostic 		break;
129643222Sbostic 
129743222Sbostic 	case STGLENG:
129843222Sbostic 		if(indir)
129943222Sbostic 			{
130043222Sbostic 			p2oreg(
130143222Sbostic #ifdef ARGOFFSET
130243222Sbostic 				ARGOFFSET +
130343222Sbostic #endif
130443222Sbostic 				(ftnint) (FUDGEOFFSET*p->memno),
130543222Sbostic 				ARGREG,   type2 );
130643222Sbostic 			}
130743222Sbostic 		else	{
130843222Sbostic 			p2reg(ARGREG, type2 | PCCTM_PTR );
130943222Sbostic 			p2icon(
131043222Sbostic #ifdef ARGOFFSET
131143222Sbostic 				ARGOFFSET +
131243222Sbostic #endif
131343222Sbostic 				(ftnint) (FUDGEOFFSET*p->memno), PCCT_INT);
131443222Sbostic 			p2op(PCC_PLUS, type2 | PCCTM_PTR );
131543222Sbostic 			}
131643222Sbostic 		break;
131743222Sbostic 
131843222Sbostic 
131943222Sbostic 	case STGBSS:
132043222Sbostic 	case STGINIT:
132143222Sbostic 	case STGEXT:
132243222Sbostic 	case STGINTR:
132343222Sbostic 	case STGCOMMON:
132443222Sbostic 	case STGEQUIV:
132543222Sbostic 	case STGCONST:
132643222Sbostic 		if(offp)
132743222Sbostic 			{
132843222Sbostic 			putx(offp);
132943222Sbostic 			putmem(p, PCC_ICON, offset);
133043222Sbostic 			p2op(PCC_PLUS, type2 | PCCTM_PTR);
133143222Sbostic 			if(indir)
133243222Sbostic 				p2op(PCC_DEREF, type2);
133343222Sbostic 			}
133443222Sbostic 		else
133543222Sbostic 			putmem(p, (indir ? PCC_NAME : PCC_ICON), offset);
133643222Sbostic 
133743222Sbostic 		break;
133843222Sbostic 
133943222Sbostic 	case STGREG:
134043222Sbostic 		if(indir)
134143222Sbostic 			p2reg(p->memno, type2);
134243222Sbostic 		else
134343222Sbostic 			fatal("attempt to take address of a register");
134443222Sbostic 		break;
134543222Sbostic 
134643222Sbostic 	case STGPREG:
134743222Sbostic 		if(indir && !offp)
134843222Sbostic 			p2oreg(offset, p->memno, type2);
134943222Sbostic 		else
135043222Sbostic 			{
135143222Sbostic 			p2reg(p->memno, type2 | PCCTM_PTR);
135243222Sbostic 			goto based;
135343222Sbostic 			}
135443222Sbostic 		break;
135543222Sbostic 
135643222Sbostic 	default:
135743222Sbostic 		badstg("putaddr", p->vstg);
135843222Sbostic 	}
135943222Sbostic frexpr(p);
136043222Sbostic }
136143222Sbostic 
136243222Sbostic 
136343222Sbostic 
136443222Sbostic 
putmem(p,class,offset)136543222Sbostic LOCAL putmem(p, class, offset)
136643222Sbostic expptr p;
136743222Sbostic int class;
136843222Sbostic ftnint offset;
136943222Sbostic {
137043222Sbostic int type2;
137143222Sbostic int funct;
137243222Sbostic char *name,  *memname();
137343222Sbostic 
137443222Sbostic funct = (p->headblock.vclass==CLPROC ? PCCTM_FTN<<2 : 0);
137543222Sbostic type2 = types2[p->headblock.vtype];
137643222Sbostic if(p->headblock.vclass == CLPROC)
137743222Sbostic 	type2 |= (PCCTM_FTN<<2);
137843222Sbostic name = memname(p->addrblock.vstg, p->addrblock.memno);
137943222Sbostic if(class == PCC_ICON)
138043222Sbostic 	{
138143222Sbostic 	p2triple(PCC_ICON, name[0]!='\0', type2|PCCTM_PTR);
138243222Sbostic 	p2word(offset);
138343222Sbostic 	if(name[0])
138443222Sbostic 		p2name(name);
138543222Sbostic 	}
138643222Sbostic else
138743222Sbostic 	{
138843222Sbostic 	p2triple(PCC_NAME, offset!=0, type2);
138943222Sbostic 	if(offset != 0)
139043222Sbostic 		p2word(offset);
139143222Sbostic 	p2name(name);
139243222Sbostic 	}
139343222Sbostic }
139443222Sbostic 
139543222Sbostic 
139643222Sbostic 
putcall(p)139743222Sbostic LOCAL Addrp putcall(p)
139843222Sbostic register Exprp p;
139943222Sbostic {
140043222Sbostic chainp arglist, charsp, cp;
140143222Sbostic int n, first;
140243222Sbostic Addrp t;
140343222Sbostic register expptr q;
140443222Sbostic Addrp fval, mkargtemp();
140543222Sbostic int type, type2, ctype, qtype, indir;
140643222Sbostic 
140743222Sbostic type2 = types2[type = p->vtype];
140843222Sbostic charsp = NULL;
140943222Sbostic indir =  (p->opcode == OPCCALL);
141043222Sbostic n = 0;
141143222Sbostic first = YES;
141243222Sbostic 
141343222Sbostic if(p->rightp)
141443222Sbostic 	{
141543222Sbostic 	arglist = p->rightp->listblock.listp;
141643222Sbostic 	free( (charptr) (p->rightp) );
141743222Sbostic 	}
141843222Sbostic else
141943222Sbostic 	arglist = NULL;
142043222Sbostic 
142143222Sbostic for(cp = arglist ; cp ; cp = cp->nextp)
142243222Sbostic 	{
142343222Sbostic 	q = (expptr) cp->datap;
142443222Sbostic 	if(indir)
142543222Sbostic 		++n;
142643222Sbostic 	else	{
142743222Sbostic 		q = (expptr) (cp->datap);
142843222Sbostic 		if( ISCONST(q) )
142943222Sbostic 			{
143043222Sbostic 			q = (expptr) putconst(q);
143143222Sbostic 			cp->datap = (tagptr) q;
143243222Sbostic 			}
143343222Sbostic 		if( ISCHAR(q) && q->headblock.vclass!=CLPROC )
143443222Sbostic 			{
143543222Sbostic 			charsp = hookup(charsp,
143643222Sbostic 					mkchain(cpexpr(q->headblock.vleng),
143743222Sbostic 						CHNULL));
143843222Sbostic 			n += 2;
143943222Sbostic 			}
144043222Sbostic 		else
144143222Sbostic 			n += 1;
144243222Sbostic 		}
144343222Sbostic 	}
144443222Sbostic 
144543222Sbostic if(type == TYCHAR)
144643222Sbostic 	{
144743222Sbostic 	if( ISICON(p->vleng) )
144843222Sbostic 		{
144943222Sbostic 		fval = mkargtemp(TYCHAR, p->vleng);
145043222Sbostic 		n += 2;
145143222Sbostic 		}
145243222Sbostic 	else	{
145343222Sbostic 		err("adjustable character function");
145443222Sbostic 		return;
145543222Sbostic 		}
145643222Sbostic 	}
145743222Sbostic else if( ISCOMPLEX(type) )
145843222Sbostic 	{
145943222Sbostic 	fval = mkargtemp(type, PNULL);
146043222Sbostic 	n += 1;
146143222Sbostic 	}
146243222Sbostic else
146343222Sbostic 	fval = NULL;
146443222Sbostic 
146543222Sbostic ctype = (fval ? PCCT_INT : type2);
146643222Sbostic putaddr(p->leftp, NO);
146743222Sbostic 
146843222Sbostic if(fval)
146943222Sbostic 	{
147043222Sbostic 	first = NO;
147143222Sbostic 	putaddr( cpexpr(fval), NO);
147243222Sbostic 	if(type==TYCHAR)
147343222Sbostic 		{
147443222Sbostic 		putx( mkconv(TYLENG,p->vleng) );
147543222Sbostic 		p2op(PCC_CM, type2);
147643222Sbostic 		}
147743222Sbostic 	}
147843222Sbostic 
147943222Sbostic for(cp = arglist ; cp ; cp = cp->nextp)
148043222Sbostic 	{
148143222Sbostic 	q = (expptr) (cp->datap);
148243222Sbostic 	if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) )
148343222Sbostic 		putaddr(q, indir && q->addrblock.vtype!=TYCHAR);
148443222Sbostic 	else if( ISCOMPLEX(q->headblock.vtype) )
148543222Sbostic 		putcxop(q);
148643222Sbostic 	else if (ISCHAR(q) )
148743222Sbostic 		putchop(q);
148843222Sbostic 	else if( ! ISERROR(q) )
148943222Sbostic 		{
149043222Sbostic 		if(indir)
149143222Sbostic 			putx(q);
149243222Sbostic 		else	{
149343222Sbostic 			t = mkargtemp(qtype = q->headblock.vtype,
149443222Sbostic 				q->headblock.vleng);
149543222Sbostic 			putassign( cpexpr(t), q );
149643222Sbostic 			putaddr(t, NO);
149743222Sbostic 			putcomma(1, qtype, YES);
149843222Sbostic 			}
149943222Sbostic 		}
150043222Sbostic 	if(first)
150143222Sbostic 		first = NO;
150243222Sbostic 	else
150343222Sbostic 		p2op(PCC_CM, type2);
150443222Sbostic 	}
150543222Sbostic 
150643222Sbostic if(arglist)
150743222Sbostic 	frchain(&arglist);
150843222Sbostic for(cp = charsp ; cp ; cp = cp->nextp)
150943222Sbostic 	{
151043222Sbostic 	putx( mkconv(TYLENG,cp->datap) );
151143222Sbostic 	p2op(PCC_CM, type2);
151243222Sbostic 	}
151343222Sbostic frchain(&charsp);
151443222Sbostic #if TARGET == TAHOE
151543222Sbostic if(indir && ctype==PCCT_FLOAT)	/* function opcodes */
151643222Sbostic 	p2op(PCC_FORTCALL, ctype);
151743222Sbostic else
151843222Sbostic #endif
151943222Sbostic p2op(n>0 ? PCC_CALL : PCC_UCALL , ctype);
152043222Sbostic free( (charptr) p );
152143222Sbostic return(fval);
152243222Sbostic }
152343222Sbostic 
152443222Sbostic 
152543222Sbostic 
putmnmx(p)152643222Sbostic LOCAL putmnmx(p)
152743222Sbostic register expptr p;
152843222Sbostic {
152943222Sbostic int op, type;
153043222Sbostic int ncomma;
153143222Sbostic expptr qp;
153243222Sbostic chainp p0, p1;
153343222Sbostic Addrp sp, tp;
153443222Sbostic 
153543222Sbostic if(p->tag != TEXPR)
153643222Sbostic 	badtag("putmnmx", p->tag);
153743222Sbostic 
153843222Sbostic type = p->exprblock.vtype;
153943222Sbostic op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
154043222Sbostic p0 = p->exprblock.leftp->listblock.listp;
154143222Sbostic free( (charptr) (p->exprblock.leftp) );
154243222Sbostic free( (charptr) p );
154343222Sbostic 
154443222Sbostic sp = mkaltemp(type, PNULL);
154543222Sbostic tp = mkaltemp(type, PNULL);
154643222Sbostic qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
154743222Sbostic qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
154843222Sbostic qp = fixexpr(qp);
154943222Sbostic 
155043222Sbostic ncomma = 1;
155143222Sbostic putassign( cpexpr(sp), p0->datap );
155243222Sbostic 
155343222Sbostic for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
155443222Sbostic 	{
155543222Sbostic 	++ncomma;
155643222Sbostic 	putassign( cpexpr(tp), p1->datap );
155743222Sbostic 	if(p1->nextp)
155843222Sbostic 		{
155943222Sbostic 		++ncomma;
156043222Sbostic 		putassign( cpexpr(sp), cpexpr(qp) );
156143222Sbostic 		}
156243222Sbostic 	else
156343222Sbostic 		putx(qp);
156443222Sbostic 	}
156543222Sbostic 
156643222Sbostic putcomma(ncomma, type, NO);
156743222Sbostic frexpr(sp);
156843222Sbostic frexpr(tp);
156943222Sbostic frchain( &p0 );
157043222Sbostic }
157143222Sbostic 
157243222Sbostic 
157343222Sbostic 
157443222Sbostic 
putcomma(n,type,indir)157543222Sbostic LOCAL putcomma(n, type, indir)
157643222Sbostic int n, type, indir;
157743222Sbostic {
157843222Sbostic type = types2[type];
157943222Sbostic if(indir)
158043222Sbostic 	type |= PCCTM_PTR;
158143222Sbostic while(--n >= 0)
158243222Sbostic 	p2op(PCC_COMOP, type);
158343222Sbostic }
158443222Sbostic 
158543222Sbostic 
158643222Sbostic 
158743222Sbostic 
simoffset(p0)158843222Sbostic ftnint simoffset(p0)
158943222Sbostic expptr *p0;
159043222Sbostic {
159143222Sbostic ftnint offset, prod;
159243222Sbostic register expptr p, lp, rp;
159343222Sbostic 
159443222Sbostic offset = 0;
159543222Sbostic p = *p0;
159643222Sbostic if(p == NULL)
159743222Sbostic 	return(0);
159843222Sbostic 
159943222Sbostic if( ! ISINT(p->headblock.vtype) )
160043222Sbostic 	return(0);
160143222Sbostic 
160243222Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR)
160343222Sbostic 	{
160443222Sbostic 	lp = p->exprblock.leftp;
160543222Sbostic 	rp = p->exprblock.rightp;
160643222Sbostic 	if(ISICON(rp) && lp->tag==TEXPR &&
160743222Sbostic 	   lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp))
160843222Sbostic 		{
160943222Sbostic 		p->exprblock.opcode = OPPLUS;
161043222Sbostic 		lp->exprblock.opcode = OPSTAR;
161146306Sbostic 		prod = rp->constblock.constant.ci *
161246306Sbostic 			lp->exprblock.rightp->constblock.constant.ci;
161346306Sbostic 		lp->exprblock.rightp->constblock.constant.ci = rp->constblock.constant.ci;
161446306Sbostic 		rp->constblock.constant.ci = prod;
161543222Sbostic 		}
161643222Sbostic 	}
161743222Sbostic 
161843222Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS &&
161943222Sbostic     ISICON(p->exprblock.rightp))
162043222Sbostic 	{
162143222Sbostic 	rp = p->exprblock.rightp;
162243222Sbostic 	lp = p->exprblock.leftp;
162346306Sbostic 	offset += rp->constblock.constant.ci;
162443222Sbostic 	frexpr(rp);
162543222Sbostic 	free( (charptr) p );
162643222Sbostic 	*p0 = lp;
162743222Sbostic 	}
162843222Sbostic 
162943222Sbostic if( ISCONST(p) )
163043222Sbostic 	{
163146306Sbostic 	offset += p->constblock.constant.ci;
163243222Sbostic 	frexpr(p);
163343222Sbostic 	*p0 = NULL;
163443222Sbostic 	}
163543222Sbostic 
163643222Sbostic return(offset);
163743222Sbostic }
163843222Sbostic 
163943222Sbostic 
164043222Sbostic 
164143222Sbostic 
164243222Sbostic 
p2op(op,type)164343222Sbostic p2op(op, type)
164443222Sbostic int op, type;
164543222Sbostic {
164643222Sbostic p2triple(op, 0, type);
164743222Sbostic }
164843222Sbostic 
p2icon(offset,type)164943222Sbostic p2icon(offset, type)
165043222Sbostic ftnint offset;
165143222Sbostic int type;
165243222Sbostic {
165343222Sbostic p2triple(PCC_ICON, 0, type);
165443222Sbostic p2word(offset);
165543222Sbostic }
165643222Sbostic 
165743222Sbostic 
165843222Sbostic 
165943222Sbostic 
p2oreg(offset,reg,type)166043222Sbostic p2oreg(offset, reg, type)
166143222Sbostic ftnint offset;
166243222Sbostic int reg, type;
166343222Sbostic {
166443222Sbostic p2triple(PCC_OREG, reg, type);
166543222Sbostic p2word(offset);
166643222Sbostic p2name("");
166743222Sbostic }
166843222Sbostic 
166943222Sbostic 
167043222Sbostic 
167143222Sbostic 
p2reg(reg,type)167243222Sbostic p2reg(reg, type)
167343222Sbostic int reg, type;
167443222Sbostic {
167543222Sbostic p2triple(PCC_REG, reg, type);
167643222Sbostic }
167743222Sbostic 
167843222Sbostic 
167943222Sbostic 
p2pi(s,i)168043222Sbostic p2pi(s, i)
168143222Sbostic char *s;
168243222Sbostic int i;
168343222Sbostic {
168443222Sbostic char buff[100];
168543222Sbostic sprintf(buff, s, i);
168643222Sbostic p2pass(buff);
168743222Sbostic }
168843222Sbostic 
168943222Sbostic 
169043222Sbostic 
p2pij(s,i,j)169143222Sbostic p2pij(s, i, j)
169243222Sbostic char *s;
169343222Sbostic int i, j;
169443222Sbostic {
169543222Sbostic char buff[100];
169643222Sbostic sprintf(buff, s, i, j);
169743222Sbostic p2pass(buff);
169843222Sbostic }
169943222Sbostic 
170043222Sbostic 
170143222Sbostic 
170243222Sbostic 
p2ps(s,t)170343222Sbostic p2ps(s, t)
170443222Sbostic char *s, *t;
170543222Sbostic {
170643222Sbostic char buff[100];
170743222Sbostic sprintf(buff, s, t);
170843222Sbostic p2pass(buff);
170943222Sbostic }
171043222Sbostic 
171143222Sbostic 
171243222Sbostic 
171343222Sbostic 
p2pass(s)171443222Sbostic p2pass(s)
171543222Sbostic char *s;
171643222Sbostic {
171743222Sbostic p2triple(PCCF_FTEXT, (strlen(s) + ALILONG-1)/ALILONG, 0);
171843222Sbostic p2str(s);
171943222Sbostic }
172043222Sbostic 
172143222Sbostic 
172243222Sbostic 
172343222Sbostic 
p2str(s)172443222Sbostic p2str(s)
172543222Sbostic register char *s;
172643222Sbostic {
172743222Sbostic union { long int word; char str[SZLONG]; } u;
172843222Sbostic register int i;
172943222Sbostic 
173043222Sbostic i = 0;
173143222Sbostic u.word = 0;
173243222Sbostic while(*s)
173343222Sbostic 	{
173443222Sbostic 	u.str[i++] = *s++;
173543222Sbostic 	if(i == SZLONG)
173643222Sbostic 		{
173743222Sbostic 		p2word(u.word);
173843222Sbostic 		u.word = 0;
173943222Sbostic 		i = 0;
174043222Sbostic 		}
174143222Sbostic 	}
174243222Sbostic if(i > 0)
174343222Sbostic 	p2word(u.word);
174443222Sbostic }
174543222Sbostic 
174643222Sbostic 
174743222Sbostic 
174843222Sbostic 
p2triple(op,var,type)174943222Sbostic p2triple(op, var, type)
175043222Sbostic int op, var, type;
175143222Sbostic {
175243222Sbostic register long word;
175343222Sbostic word = PCCM_TRIPLE(op, var, type);
175443222Sbostic p2word(word);
175543222Sbostic }
175643222Sbostic 
175743222Sbostic 
175843222Sbostic 
175943222Sbostic 
176043222Sbostic 
p2name(s)176143222Sbostic p2name(s)
176243222Sbostic register char *s;
176343222Sbostic {
176443222Sbostic register int i;
176543222Sbostic 
176643222Sbostic #ifdef UCBPASS2
176743222Sbostic 	/* arbitrary length names, terminated by a null,
176843222Sbostic 	   padded to a full word */
176943222Sbostic 
177043222Sbostic #	define WL   sizeof(long int)
177143222Sbostic 	union { long int word; char str[WL]; } w;
177243222Sbostic 
177343222Sbostic 	w.word = 0;
177443222Sbostic 	i = 0;
177543222Sbostic 	while(w.str[i++] = *s++)
177643222Sbostic 		if(i == WL)
177743222Sbostic 			{
177843222Sbostic 			p2word(w.word);
177943222Sbostic 			w.word = 0;
178043222Sbostic 			i = 0;
178143222Sbostic 			}
178243222Sbostic 	if(i > 0)
178343222Sbostic 		p2word(w.word);
178443222Sbostic #else
178543222Sbostic 	/* standard intermediate, names are 8 characters long */
178643222Sbostic 
178743222Sbostic 	union  { long int word[2];  char str[8]; } u;
178843222Sbostic 
178943222Sbostic 	u.word[0] = u.word[1] = 0;
179043222Sbostic 	for(i = 0 ; i<8 && *s ; ++i)
179143222Sbostic 		u.str[i] = *s++;
179243222Sbostic 	p2word(u.word[0]);
179343222Sbostic 	p2word(u.word[1]);
179443222Sbostic 
179543222Sbostic #endif
179643222Sbostic 
179743222Sbostic }
179843222Sbostic 
179943222Sbostic 
180043222Sbostic 
180143222Sbostic 
p2word(w)180243222Sbostic p2word(w)
180343222Sbostic long int w;
180443222Sbostic {
180543222Sbostic *p2bufp++ = w;
180643222Sbostic if(p2bufp >= p2bufend)
180743222Sbostic 	p2flush();
180843222Sbostic }
180943222Sbostic 
181043222Sbostic 
181143222Sbostic 
p2flush()181243222Sbostic p2flush()
181343222Sbostic {
181443222Sbostic if(p2bufp > p2buff)
181543222Sbostic 	write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
181643222Sbostic p2bufp = p2buff;
181743222Sbostic }
181843222Sbostic 
181943222Sbostic 
182043222Sbostic 
182143222Sbostic LOCAL
p2ldisp(offset,vname,type)182243222Sbostic p2ldisp(offset, vname, type)
182343222Sbostic ftnint offset;
182443222Sbostic char *vname;
182543222Sbostic int type;
182643222Sbostic {
182743222Sbostic   char buff[100];
182843222Sbostic 
182943222Sbostic   sprintf(buff, "%s-v.%d", vname, bsslabel);
183043222Sbostic   p2triple(PCC_OREG, LVARREG, type);
183143222Sbostic   p2word(offset);
183243222Sbostic   p2name(buff);
183343222Sbostic }
183443222Sbostic 
183543222Sbostic 
183643222Sbostic 
p2ndisp(vname)183743222Sbostic p2ndisp(vname)
183843222Sbostic char *vname;
183943222Sbostic {
184043222Sbostic   char buff[100];
184143222Sbostic 
184243222Sbostic   sprintf(buff, "%s-v.%d", vname, bsslabel);
184343222Sbostic   p2name(buff);
184443222Sbostic }
1845