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