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