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