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