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