1*43222Sbostic /* 2*43222Sbostic * Copyright (c) 1980 Regents of the University of California. 3*43222Sbostic * All rights reserved. The Berkeley software License Agreement 4*43222Sbostic * specifies the terms and conditions for redistribution. 5*43222Sbostic */ 6*43222Sbostic 7*43222Sbostic #ifndef lint 8*43222Sbostic static char sccsid[] = "@(#)putpcc.c 5.1 (Berkeley) 6/7/85"; 9*43222Sbostic #endif not lint 10*43222Sbostic 11*43222Sbostic /* 12*43222Sbostic * putpcc.c 13*43222Sbostic * 14*43222Sbostic * Intermediate code generation for S. C. Johnson C compilers 15*43222Sbostic * New version using binary polish postfix intermediate 16*43222Sbostic * 17*43222Sbostic * University of Utah CS Dept modification history: 18*43222Sbostic * 19*43222Sbostic * $Header: putpcc.c,v 3.2 85/03/25 09:35:57 root Exp $ 20*43222Sbostic * $Log: putpcc.c,v $ 21*43222Sbostic * Revision 3.2 85/03/25 09:35:57 root 22*43222Sbostic * fseek return -1 on error. 23*43222Sbostic * 24*43222Sbostic * Revision 3.1 85/02/27 19:06:55 donn 25*43222Sbostic * Changed to use pcc.h instead of pccdefs.h. 26*43222Sbostic * 27*43222Sbostic * Revision 2.12 85/02/22 01:05:54 donn 28*43222Sbostic * putaddr() didn't know about intrinsic functions... 29*43222Sbostic * 30*43222Sbostic * Revision 2.11 84/11/28 21:28:49 donn 31*43222Sbostic * Hacked putop() to handle any character expression being converted to int, 32*43222Sbostic * not just function calls. Previously it bombed on concatenations. 33*43222Sbostic * 34*43222Sbostic * Revision 2.10 84/11/01 22:07:07 donn 35*43222Sbostic * Yet another try at getting putop() to work right. It appears that the 36*43222Sbostic * second pass can't abide certain explicit conversions (e.g. short to long) 37*43222Sbostic * so the conversion code in putop() tries to remove them. I think this 38*43222Sbostic * version (finally) works. 39*43222Sbostic * 40*43222Sbostic * Revision 2.9 84/10/29 02:30:57 donn 41*43222Sbostic * Earlier fix to putop() for conversions was insufficient -- we NEVER want to 42*43222Sbostic * see the type of the left operand of the thing left over from stripping off 43*43222Sbostic * conversions... 44*43222Sbostic * 45*43222Sbostic * Revision 2.8 84/09/18 03:09:21 donn 46*43222Sbostic * Fixed bug in putop() where the left operand of an addrblock was being 47*43222Sbostic * extracted... This caused an extremely obscure conversion error when 48*43222Sbostic * an array of longs was subscripted by a short. 49*43222Sbostic * 50*43222Sbostic * Revision 2.7 84/08/19 20:10:19 donn 51*43222Sbostic * Removed stuff in putbranch that treats STGARG parameters specially -- the 52*43222Sbostic * bug in the code generation pass that motivated it has been fixed. 53*43222Sbostic * 54*43222Sbostic * Revision 2.6 84/08/07 21:32:23 donn 55*43222Sbostic * Bumped the size of the buffer for the intermediate code file from 0.5K 56*43222Sbostic * to 4K on a VAX. 57*43222Sbostic * 58*43222Sbostic * Revision 2.5 84/08/04 20:26:43 donn 59*43222Sbostic * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of 60*43222Sbostic * mktemp(). Correction due to Jerry Berkman. 61*43222Sbostic * 62*43222Sbostic * Revision 2.4 84/07/24 19:07:15 donn 63*43222Sbostic * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed 64*43222Sbostic * that mkaltemp() returns tempblocks, and tried to free them with frtemp(). 65*43222Sbostic * 66*43222Sbostic * Revision 2.3 84/07/19 17:22:09 donn 67*43222Sbostic * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal. 68*43222Sbostic * 69*43222Sbostic * Revision 2.2 84/07/19 12:30:38 donn 70*43222Sbostic * Fixed a type clash in Bob Corbett's new putbranch(). 71*43222Sbostic * 72*43222Sbostic * Revision 2.1 84/07/19 12:04:27 donn 73*43222Sbostic * Changed comment headers for UofU. 74*43222Sbostic * 75*43222Sbostic * Revision 1.8 84/07/19 11:38:23 donn 76*43222Sbostic * Replaced putbranch() routine so that you can ASSIGN into argument variables. 77*43222Sbostic * The code is from Bob Corbett, donated by Jerry Berkman. 78*43222Sbostic * 79*43222Sbostic * Revision 1.7 84/05/31 00:48:32 donn 80*43222Sbostic * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1 81*43222Sbostic * expressions -- a foulup in the order of COMOP and the comparison caused 82*43222Sbostic * one operand of the comparison to be garbage. 83*43222Sbostic * 84*43222Sbostic * Revision 1.6 84/04/16 09:54:19 donn 85*43222Sbostic * Backed out earlier fix for bug where items in the argtemplist were 86*43222Sbostic * (incorrectly) being given away; this is now fixed in mkargtemp(). 87*43222Sbostic * 88*43222Sbostic * Revision 1.5 84/03/23 22:49:48 donn 89*43222Sbostic * Took out the initialization of the subroutine argument temporary list in 90*43222Sbostic * putcall() -- it needs to be done once per statement instead of once per call. 91*43222Sbostic * 92*43222Sbostic * Revision 1.4 84/03/01 06:48:05 donn 93*43222Sbostic * Fixed bug in Bob Corbett's code for argument temporaries that caused an 94*43222Sbostic * addrblock to get thrown out inadvertently when it was needed for recycling 95*43222Sbostic * purposes later on. 96*43222Sbostic * 97*43222Sbostic * Revision 1.3 84/02/26 06:32:38 donn 98*43222Sbostic * Added Berkeley changes to move data definitions around and reduce offsets. 99*43222Sbostic * 100*43222Sbostic * Revision 1.2 84/02/26 06:27:45 donn 101*43222Sbostic * Added code to catch TTEMP values passed to putx(). 102*43222Sbostic * 103*43222Sbostic */ 104*43222Sbostic 105*43222Sbostic #if FAMILY != PCC 106*43222Sbostic WRONG put FILE !!!! 107*43222Sbostic #endif 108*43222Sbostic 109*43222Sbostic #include "defs.h" 110*43222Sbostic #include <pcc.h> 111*43222Sbostic 112*43222Sbostic Addrp putcall(), putcxeq(), putcx1(), realpart(); 113*43222Sbostic expptr imagpart(); 114*43222Sbostic ftnint lencat(); 115*43222Sbostic 116*43222Sbostic #define FOUR 4 117*43222Sbostic extern int ops2[]; 118*43222Sbostic extern int types2[]; 119*43222Sbostic 120*43222Sbostic #if HERE==VAX || HERE == TAHOE 121*43222Sbostic #define PCC_BUFFMAX 1024 122*43222Sbostic #else 123*43222Sbostic #define PCC_BUFFMAX 128 124*43222Sbostic #endif 125*43222Sbostic static long int p2buff[PCC_BUFFMAX]; 126*43222Sbostic static long int *p2bufp = &p2buff[0]; 127*43222Sbostic static long int *p2bufend = &p2buff[PCC_BUFFMAX]; 128*43222Sbostic 129*43222Sbostic 130*43222Sbostic puthead(s, class) 131*43222Sbostic char *s; 132*43222Sbostic int class; 133*43222Sbostic { 134*43222Sbostic char buff[100]; 135*43222Sbostic #if TARGET == VAX || TARGET == TAHOE 136*43222Sbostic if(s) 137*43222Sbostic p2ps("\t.globl\t_%s", s); 138*43222Sbostic #endif 139*43222Sbostic /* put out fake copy of left bracket line, to be redone later */ 140*43222Sbostic if( ! headerdone ) 141*43222Sbostic { 142*43222Sbostic #if FAMILY == PCC 143*43222Sbostic p2flush(); 144*43222Sbostic #endif 145*43222Sbostic headoffset = ftell(textfile); 146*43222Sbostic prhead(textfile); 147*43222Sbostic headerdone = YES; 148*43222Sbostic p2triple(PCCF_FEXPR, (strlen(infname)+ALILONG-1)/ALILONG, 0); 149*43222Sbostic p2str(infname); 150*43222Sbostic #if TARGET == PDP11 151*43222Sbostic /* fake jump to start the optimizer */ 152*43222Sbostic if(class != CLBLOCK) 153*43222Sbostic putgoto( fudgelabel = newlabel() ); 154*43222Sbostic #endif 155*43222Sbostic 156*43222Sbostic #if TARGET == VAX || TARGET == TAHOE 157*43222Sbostic /* jump from top to bottom */ 158*43222Sbostic if(s!=CNULL && class!=CLBLOCK) 159*43222Sbostic { 160*43222Sbostic int proflab = newlabel(); 161*43222Sbostic p2pass("\t.align\t1"); 162*43222Sbostic p2ps("_%s:", s); 163*43222Sbostic p2pi("\t.word\tLWM%d", procno); 164*43222Sbostic prsave(proflab); 165*43222Sbostic #if TARGET == VAX 166*43222Sbostic p2pi("\tjbr\tL%d", 167*43222Sbostic #else 168*43222Sbostic putgoto( 169*43222Sbostic #endif 170*43222Sbostic fudgelabel = newlabel()); 171*43222Sbostic } 172*43222Sbostic #endif 173*43222Sbostic } 174*43222Sbostic } 175*43222Sbostic 176*43222Sbostic 177*43222Sbostic 178*43222Sbostic 179*43222Sbostic 180*43222Sbostic /* It is necessary to precede each procedure with a "left bracket" 181*43222Sbostic * line that tells pass 2 how many register variables and how 182*43222Sbostic * much automatic space is required for the function. This compiler 183*43222Sbostic * does not know how much automatic space is needed until the 184*43222Sbostic * entire procedure has been processed. Therefore, "puthead" 185*43222Sbostic * is called at the begining to record the current location in textfile, 186*43222Sbostic * then to put out a placeholder left bracket line. This procedure 187*43222Sbostic * repositions the file and rewrites that line, then puts the 188*43222Sbostic * file pointer back to the end of the file. 189*43222Sbostic */ 190*43222Sbostic 191*43222Sbostic putbracket() 192*43222Sbostic { 193*43222Sbostic long int hereoffset; 194*43222Sbostic 195*43222Sbostic #if FAMILY == PCC 196*43222Sbostic p2flush(); 197*43222Sbostic #endif 198*43222Sbostic hereoffset = ftell(textfile); 199*43222Sbostic if(fseek(textfile, headoffset, 0) == -1) 200*43222Sbostic fatal("fseek failed"); 201*43222Sbostic prhead(textfile); 202*43222Sbostic if(fseek(textfile, hereoffset, 0) == -1) 203*43222Sbostic fatal("fseek failed 2"); 204*43222Sbostic } 205*43222Sbostic 206*43222Sbostic 207*43222Sbostic 208*43222Sbostic 209*43222Sbostic putrbrack(k) 210*43222Sbostic int k; 211*43222Sbostic { 212*43222Sbostic p2op(PCCF_FRBRAC, k); 213*43222Sbostic } 214*43222Sbostic 215*43222Sbostic 216*43222Sbostic 217*43222Sbostic putnreg() 218*43222Sbostic { 219*43222Sbostic } 220*43222Sbostic 221*43222Sbostic 222*43222Sbostic 223*43222Sbostic 224*43222Sbostic 225*43222Sbostic 226*43222Sbostic puteof() 227*43222Sbostic { 228*43222Sbostic p2op(PCCF_FEOF, 0); 229*43222Sbostic p2flush(); 230*43222Sbostic } 231*43222Sbostic 232*43222Sbostic 233*43222Sbostic 234*43222Sbostic putstmt() 235*43222Sbostic { 236*43222Sbostic p2triple(PCCF_FEXPR, 0, lineno); 237*43222Sbostic } 238*43222Sbostic 239*43222Sbostic 240*43222Sbostic 241*43222Sbostic 242*43222Sbostic /* put out code for if( ! p) goto l */ 243*43222Sbostic putif(p,l) 244*43222Sbostic register expptr p; 245*43222Sbostic int l; 246*43222Sbostic { 247*43222Sbostic register int k; 248*43222Sbostic 249*43222Sbostic if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL) 250*43222Sbostic { 251*43222Sbostic if(k != TYERROR) 252*43222Sbostic err("non-logical expression in IF statement"); 253*43222Sbostic frexpr(p); 254*43222Sbostic } 255*43222Sbostic else 256*43222Sbostic { 257*43222Sbostic putex1(p); 258*43222Sbostic p2icon( (long int) l , PCCT_INT); 259*43222Sbostic p2op(PCC_CBRANCH, 0); 260*43222Sbostic putstmt(); 261*43222Sbostic } 262*43222Sbostic } 263*43222Sbostic 264*43222Sbostic 265*43222Sbostic 266*43222Sbostic 267*43222Sbostic 268*43222Sbostic /* put out code for goto l */ 269*43222Sbostic putgoto(label) 270*43222Sbostic int label; 271*43222Sbostic { 272*43222Sbostic p2triple(PCC_GOTO, 1, label); 273*43222Sbostic putstmt(); 274*43222Sbostic } 275*43222Sbostic 276*43222Sbostic 277*43222Sbostic /* branch to address constant or integer variable */ 278*43222Sbostic putbranch(p) 279*43222Sbostic register Addrp p; 280*43222Sbostic { 281*43222Sbostic putex1((expptr) p); 282*43222Sbostic p2op(PCC_GOTO, PCCT_INT); 283*43222Sbostic putstmt(); 284*43222Sbostic } 285*43222Sbostic 286*43222Sbostic 287*43222Sbostic 288*43222Sbostic /* put out label l: */ 289*43222Sbostic putlabel(label) 290*43222Sbostic int label; 291*43222Sbostic { 292*43222Sbostic p2op(PCCF_FLABEL, label); 293*43222Sbostic } 294*43222Sbostic 295*43222Sbostic 296*43222Sbostic 297*43222Sbostic 298*43222Sbostic putexpr(p) 299*43222Sbostic expptr p; 300*43222Sbostic { 301*43222Sbostic putex1(p); 302*43222Sbostic putstmt(); 303*43222Sbostic } 304*43222Sbostic 305*43222Sbostic 306*43222Sbostic 307*43222Sbostic 308*43222Sbostic putcmgo(index, nlab, labs) 309*43222Sbostic expptr index; 310*43222Sbostic int nlab; 311*43222Sbostic struct Labelblock *labs[]; 312*43222Sbostic { 313*43222Sbostic int i, labarray, skiplabel; 314*43222Sbostic 315*43222Sbostic if(! ISINT(index->headblock.vtype) ) 316*43222Sbostic { 317*43222Sbostic execerr("computed goto index must be integer", CNULL); 318*43222Sbostic return; 319*43222Sbostic } 320*43222Sbostic 321*43222Sbostic #if TARGET == VAX || TARGET == TAHOE 322*43222Sbostic /* use special case instruction */ 323*43222Sbostic casegoto(index, nlab, labs); 324*43222Sbostic #else 325*43222Sbostic labarray = newlabel(); 326*43222Sbostic preven(ALIADDR); 327*43222Sbostic prlabel(asmfile, labarray); 328*43222Sbostic prcona(asmfile, (ftnint) (skiplabel = newlabel()) ); 329*43222Sbostic for(i = 0 ; i < nlab ; ++i) 330*43222Sbostic if( labs[i] ) 331*43222Sbostic prcona(asmfile, (ftnint)(labs[i]->labelno) ); 332*43222Sbostic prcmgoto(index, nlab, skiplabel, labarray); 333*43222Sbostic putlabel(skiplabel); 334*43222Sbostic #endif 335*43222Sbostic } 336*43222Sbostic 337*43222Sbostic putx(p) 338*43222Sbostic expptr p; 339*43222Sbostic { 340*43222Sbostic char *memname(); 341*43222Sbostic int opc; 342*43222Sbostic int ncomma; 343*43222Sbostic int type, k; 344*43222Sbostic 345*43222Sbostic if (!p) 346*43222Sbostic return; 347*43222Sbostic 348*43222Sbostic switch(p->tag) 349*43222Sbostic { 350*43222Sbostic case TERROR: 351*43222Sbostic free( (charptr) p ); 352*43222Sbostic break; 353*43222Sbostic 354*43222Sbostic case TCONST: 355*43222Sbostic switch(type = p->constblock.vtype) 356*43222Sbostic { 357*43222Sbostic case TYLOGICAL: 358*43222Sbostic type = tyint; 359*43222Sbostic case TYLONG: 360*43222Sbostic case TYSHORT: 361*43222Sbostic p2icon(p->constblock.const.ci, types2[type]); 362*43222Sbostic free( (charptr) p ); 363*43222Sbostic break; 364*43222Sbostic 365*43222Sbostic case TYADDR: 366*43222Sbostic p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR); 367*43222Sbostic p2word(0L); 368*43222Sbostic p2name(memname(STGCONST, 369*43222Sbostic (int) p->constblock.const.ci) ); 370*43222Sbostic free( (charptr) p ); 371*43222Sbostic break; 372*43222Sbostic 373*43222Sbostic default: 374*43222Sbostic putx( putconst(p) ); 375*43222Sbostic break; 376*43222Sbostic } 377*43222Sbostic break; 378*43222Sbostic 379*43222Sbostic case TEXPR: 380*43222Sbostic switch(opc = p->exprblock.opcode) 381*43222Sbostic { 382*43222Sbostic case OPCALL: 383*43222Sbostic case OPCCALL: 384*43222Sbostic if( ISCOMPLEX(p->exprblock.vtype) ) 385*43222Sbostic putcxop(p); 386*43222Sbostic else putcall(p); 387*43222Sbostic break; 388*43222Sbostic 389*43222Sbostic case OPMIN: 390*43222Sbostic case OPMAX: 391*43222Sbostic putmnmx(p); 392*43222Sbostic break; 393*43222Sbostic 394*43222Sbostic 395*43222Sbostic case OPASSIGN: 396*43222Sbostic if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype) 397*43222Sbostic || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) 398*43222Sbostic frexpr( putcxeq(p) ); 399*43222Sbostic else if( ISCHAR(p) ) 400*43222Sbostic putcheq(p); 401*43222Sbostic else 402*43222Sbostic goto putopp; 403*43222Sbostic break; 404*43222Sbostic 405*43222Sbostic case OPEQ: 406*43222Sbostic case OPNE: 407*43222Sbostic if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) || 408*43222Sbostic ISCOMPLEX(p->exprblock.rightp->headblock.vtype) ) 409*43222Sbostic { 410*43222Sbostic putcxcmp(p); 411*43222Sbostic break; 412*43222Sbostic } 413*43222Sbostic case OPLT: 414*43222Sbostic case OPLE: 415*43222Sbostic case OPGT: 416*43222Sbostic case OPGE: 417*43222Sbostic if(ISCHAR(p->exprblock.leftp)) 418*43222Sbostic { 419*43222Sbostic putchcmp(p); 420*43222Sbostic break; 421*43222Sbostic } 422*43222Sbostic goto putopp; 423*43222Sbostic 424*43222Sbostic case OPPOWER: 425*43222Sbostic putpower(p); 426*43222Sbostic break; 427*43222Sbostic 428*43222Sbostic case OPSTAR: 429*43222Sbostic #if FAMILY == PCC 430*43222Sbostic /* m * (2**k) -> m<<k */ 431*43222Sbostic if(INT(p->exprblock.leftp->headblock.vtype) && 432*43222Sbostic ISICON(p->exprblock.rightp) && 433*43222Sbostic ( (k = log2(p->exprblock.rightp->constblock.const.ci))>0) ) 434*43222Sbostic { 435*43222Sbostic p->exprblock.opcode = OPLSHIFT; 436*43222Sbostic frexpr(p->exprblock.rightp); 437*43222Sbostic p->exprblock.rightp = ICON(k); 438*43222Sbostic goto putopp; 439*43222Sbostic } 440*43222Sbostic #endif 441*43222Sbostic 442*43222Sbostic case OPMOD: 443*43222Sbostic goto putopp; 444*43222Sbostic case OPPLUS: 445*43222Sbostic case OPMINUS: 446*43222Sbostic case OPSLASH: 447*43222Sbostic case OPNEG: 448*43222Sbostic if( ISCOMPLEX(p->exprblock.vtype) ) 449*43222Sbostic putcxop(p); 450*43222Sbostic else goto putopp; 451*43222Sbostic break; 452*43222Sbostic 453*43222Sbostic case OPCONV: 454*43222Sbostic if( ISCOMPLEX(p->exprblock.vtype) ) 455*43222Sbostic putcxop(p); 456*43222Sbostic else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ) 457*43222Sbostic { 458*43222Sbostic ncomma = 0; 459*43222Sbostic putx( mkconv(p->exprblock.vtype, 460*43222Sbostic realpart(putcx1(p->exprblock.leftp, 461*43222Sbostic &ncomma)))); 462*43222Sbostic putcomma(ncomma, p->exprblock.vtype, NO); 463*43222Sbostic free( (charptr) p ); 464*43222Sbostic } 465*43222Sbostic else goto putopp; 466*43222Sbostic break; 467*43222Sbostic 468*43222Sbostic case OPNOT: 469*43222Sbostic case OPOR: 470*43222Sbostic case OPAND: 471*43222Sbostic case OPEQV: 472*43222Sbostic case OPNEQV: 473*43222Sbostic case OPADDR: 474*43222Sbostic case OPPLUSEQ: 475*43222Sbostic case OPSTAREQ: 476*43222Sbostic case OPCOMMA: 477*43222Sbostic case OPQUEST: 478*43222Sbostic case OPCOLON: 479*43222Sbostic case OPBITOR: 480*43222Sbostic case OPBITAND: 481*43222Sbostic case OPBITXOR: 482*43222Sbostic case OPBITNOT: 483*43222Sbostic case OPLSHIFT: 484*43222Sbostic case OPRSHIFT: 485*43222Sbostic putopp: 486*43222Sbostic putop(p); 487*43222Sbostic break; 488*43222Sbostic 489*43222Sbostic case OPPAREN: 490*43222Sbostic putx (p->exprblock.leftp); 491*43222Sbostic break; 492*43222Sbostic default: 493*43222Sbostic badop("putx", opc); 494*43222Sbostic } 495*43222Sbostic break; 496*43222Sbostic 497*43222Sbostic case TADDR: 498*43222Sbostic putaddr(p, YES); 499*43222Sbostic break; 500*43222Sbostic 501*43222Sbostic case TTEMP: 502*43222Sbostic /* 503*43222Sbostic * This type is sometimes passed to putx when errors occur 504*43222Sbostic * upstream, I don't know why. 505*43222Sbostic */ 506*43222Sbostic frexpr(p); 507*43222Sbostic break; 508*43222Sbostic 509*43222Sbostic default: 510*43222Sbostic badtag("putx", p->tag); 511*43222Sbostic } 512*43222Sbostic } 513*43222Sbostic 514*43222Sbostic 515*43222Sbostic 516*43222Sbostic LOCAL putop(p) 517*43222Sbostic expptr p; 518*43222Sbostic { 519*43222Sbostic int k; 520*43222Sbostic expptr lp, tp; 521*43222Sbostic int pt, lt, tt; 522*43222Sbostic int comma; 523*43222Sbostic Addrp putch1(); 524*43222Sbostic 525*43222Sbostic switch(p->exprblock.opcode) /* check for special cases and rewrite */ 526*43222Sbostic { 527*43222Sbostic case OPCONV: 528*43222Sbostic tt = pt = p->exprblock.vtype; 529*43222Sbostic lp = p->exprblock.leftp; 530*43222Sbostic lt = lp->headblock.vtype; 531*43222Sbostic #if TARGET == VAX 532*43222Sbostic if (pt == TYREAL && lt == TYDREAL) 533*43222Sbostic { 534*43222Sbostic putx(lp); 535*43222Sbostic p2op(PCC_SCONV, PCCT_FLOAT); 536*43222Sbostic return; 537*43222Sbostic } 538*43222Sbostic #endif 539*43222Sbostic while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && ( 540*43222Sbostic #if TARGET != TAHOE 541*43222Sbostic (ISREAL(pt)&&ISREAL(lt)) || 542*43222Sbostic #endif 543*43222Sbostic (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) )) 544*43222Sbostic { 545*43222Sbostic #if SZINT < SZLONG 546*43222Sbostic if(lp->tag != TEXPR) 547*43222Sbostic { 548*43222Sbostic if(pt==TYINT && lt==TYLONG) 549*43222Sbostic break; 550*43222Sbostic if(lt==TYINT && pt==TYLONG) 551*43222Sbostic break; 552*43222Sbostic } 553*43222Sbostic #endif 554*43222Sbostic 555*43222Sbostic #if TARGET == VAX 556*43222Sbostic if(pt==TYDREAL && lt==TYREAL) 557*43222Sbostic { 558*43222Sbostic if(lp->tag==TEXPR && 559*43222Sbostic lp->exprblock.opcode==OPCONV && 560*43222Sbostic lp->exprblock.leftp->headblock.vtype==TYDREAL) 561*43222Sbostic { 562*43222Sbostic putx(lp->exprblock.leftp); 563*43222Sbostic p2op(PCC_SCONV, PCCT_FLOAT); 564*43222Sbostic p2op(PCC_SCONV, PCCT_DOUBLE); 565*43222Sbostic free( (charptr) p ); 566*43222Sbostic return; 567*43222Sbostic } 568*43222Sbostic else break; 569*43222Sbostic } 570*43222Sbostic #endif 571*43222Sbostic if(lt==TYCHAR && lp->tag==TEXPR) 572*43222Sbostic { 573*43222Sbostic int ncomma = 0; 574*43222Sbostic p->exprblock.leftp = (expptr) putch1(lp, &ncomma); 575*43222Sbostic putop(p); 576*43222Sbostic putcomma(ncomma, pt, NO); 577*43222Sbostic free( (charptr) p ); 578*43222Sbostic return; 579*43222Sbostic } 580*43222Sbostic free( (charptr) p ); 581*43222Sbostic p = lp; 582*43222Sbostic pt = lt; 583*43222Sbostic if (p->tag == TEXPR) 584*43222Sbostic { 585*43222Sbostic lp = p->exprblock.leftp; 586*43222Sbostic lt = lp->headblock.vtype; 587*43222Sbostic } 588*43222Sbostic } 589*43222Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONV) 590*43222Sbostic break; 591*43222Sbostic putx(p); 592*43222Sbostic if (types2[tt] != types2[pt] && 593*43222Sbostic ! ( (ISREAL(tt)&&ISREAL(pt)) || 594*43222Sbostic (INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) )) 595*43222Sbostic p2op(PCC_SCONV,types2[tt]); 596*43222Sbostic return; 597*43222Sbostic 598*43222Sbostic case OPADDR: 599*43222Sbostic comma = NO; 600*43222Sbostic lp = p->exprblock.leftp; 601*43222Sbostic if(lp->tag != TADDR) 602*43222Sbostic { 603*43222Sbostic tp = (expptr) mkaltemp 604*43222Sbostic (lp->headblock.vtype,lp->headblock.vleng); 605*43222Sbostic putx( mkexpr(OPASSIGN, cpexpr(tp), lp) ); 606*43222Sbostic lp = tp; 607*43222Sbostic comma = YES; 608*43222Sbostic } 609*43222Sbostic putaddr(lp, NO); 610*43222Sbostic if(comma) 611*43222Sbostic putcomma(1, TYINT, NO); 612*43222Sbostic free( (charptr) p ); 613*43222Sbostic return; 614*43222Sbostic #if TARGET == VAX || TARGET == TAHOE 615*43222Sbostic /* take advantage of a glitch in the code generator that does not check 616*43222Sbostic the type clash in an assignment or comparison of an integer zero and 617*43222Sbostic a floating left operand, and generates optimal code for the correct 618*43222Sbostic type. (The PCC has no floating-constant node to encode this correctly.) 619*43222Sbostic */ 620*43222Sbostic case OPASSIGN: 621*43222Sbostic case OPLT: 622*43222Sbostic case OPLE: 623*43222Sbostic case OPGT: 624*43222Sbostic case OPGE: 625*43222Sbostic case OPEQ: 626*43222Sbostic case OPNE: 627*43222Sbostic if(ISREAL(p->exprblock.leftp->headblock.vtype) && 628*43222Sbostic ISREAL(p->exprblock.rightp->headblock.vtype) && 629*43222Sbostic ISCONST(p->exprblock.rightp) && 630*43222Sbostic p->exprblock.rightp->constblock.const.cd[0]==0) 631*43222Sbostic { 632*43222Sbostic p->exprblock.rightp->constblock.vtype = TYINT; 633*43222Sbostic p->exprblock.rightp->constblock.const.ci = 0; 634*43222Sbostic } 635*43222Sbostic #endif 636*43222Sbostic } 637*43222Sbostic 638*43222Sbostic if( (k = ops2[p->exprblock.opcode]) <= 0) 639*43222Sbostic badop("putop", p->exprblock.opcode); 640*43222Sbostic putx(p->exprblock.leftp); 641*43222Sbostic if(p->exprblock.rightp) 642*43222Sbostic putx(p->exprblock.rightp); 643*43222Sbostic p2op(k, types2[p->exprblock.vtype]); 644*43222Sbostic 645*43222Sbostic if(p->exprblock.vleng) 646*43222Sbostic frexpr(p->exprblock.vleng); 647*43222Sbostic free( (charptr) p ); 648*43222Sbostic } 649*43222Sbostic 650*43222Sbostic putforce(t, p) 651*43222Sbostic int t; 652*43222Sbostic expptr p; 653*43222Sbostic { 654*43222Sbostic p = mkconv(t, fixtype(p)); 655*43222Sbostic putx(p); 656*43222Sbostic p2op(PCC_FORCE, 657*43222Sbostic #if TARGET == TAHOE 658*43222Sbostic (t==TYLONG ? PCCT_LONG : (t==TYREAL ? PCCT_FLOAT : PCCT_DOUBLE)) ); 659*43222Sbostic #else 660*43222Sbostic (t==TYSHORT ? PCCT_SHORT : (t==TYLONG ? PCCT_LONG : PCCT_DOUBLE)) ); 661*43222Sbostic #endif 662*43222Sbostic putstmt(); 663*43222Sbostic } 664*43222Sbostic 665*43222Sbostic 666*43222Sbostic 667*43222Sbostic LOCAL putpower(p) 668*43222Sbostic expptr p; 669*43222Sbostic { 670*43222Sbostic expptr base; 671*43222Sbostic Addrp t1, t2; 672*43222Sbostic ftnint k; 673*43222Sbostic int type; 674*43222Sbostic int ncomma; 675*43222Sbostic 676*43222Sbostic if(!ISICON(p->exprblock.rightp) || 677*43222Sbostic (k = p->exprblock.rightp->constblock.const.ci)<2) 678*43222Sbostic fatal("putpower: bad call"); 679*43222Sbostic base = p->exprblock.leftp; 680*43222Sbostic type = base->headblock.vtype; 681*43222Sbostic 682*43222Sbostic if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset)) 683*43222Sbostic { 684*43222Sbostic putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base))); 685*43222Sbostic 686*43222Sbostic return; 687*43222Sbostic } 688*43222Sbostic t1 = mkaltemp(type, PNULL); 689*43222Sbostic t2 = NULL; 690*43222Sbostic ncomma = 1; 691*43222Sbostic putassign(cpexpr(t1), cpexpr(base) ); 692*43222Sbostic 693*43222Sbostic for( ; (k&1)==0 && k>2 ; k>>=1 ) 694*43222Sbostic { 695*43222Sbostic ++ncomma; 696*43222Sbostic putsteq(t1, t1); 697*43222Sbostic } 698*43222Sbostic 699*43222Sbostic if(k == 2) 700*43222Sbostic putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ); 701*43222Sbostic else 702*43222Sbostic { 703*43222Sbostic t2 = mkaltemp(type, PNULL); 704*43222Sbostic ++ncomma; 705*43222Sbostic putassign(cpexpr(t2), cpexpr(t1)); 706*43222Sbostic 707*43222Sbostic for(k>>=1 ; k>1 ; k>>=1) 708*43222Sbostic { 709*43222Sbostic ++ncomma; 710*43222Sbostic putsteq(t1, t1); 711*43222Sbostic if(k & 1) 712*43222Sbostic { 713*43222Sbostic ++ncomma; 714*43222Sbostic putsteq(t2, t1); 715*43222Sbostic } 716*43222Sbostic } 717*43222Sbostic putx( mkexpr(OPSTAR, cpexpr(t2), 718*43222Sbostic mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) )); 719*43222Sbostic } 720*43222Sbostic putcomma(ncomma, type, NO); 721*43222Sbostic frexpr(t1); 722*43222Sbostic if(t2) 723*43222Sbostic frexpr(t2); 724*43222Sbostic frexpr(p); 725*43222Sbostic } 726*43222Sbostic 727*43222Sbostic 728*43222Sbostic 729*43222Sbostic 730*43222Sbostic LOCAL Addrp intdouble(p, ncommap) 731*43222Sbostic Addrp p; 732*43222Sbostic int *ncommap; 733*43222Sbostic { 734*43222Sbostic register Addrp t; 735*43222Sbostic 736*43222Sbostic t = mkaltemp(TYDREAL, PNULL); 737*43222Sbostic ++*ncommap; 738*43222Sbostic putassign(cpexpr(t), p); 739*43222Sbostic return(t); 740*43222Sbostic } 741*43222Sbostic 742*43222Sbostic 743*43222Sbostic 744*43222Sbostic 745*43222Sbostic 746*43222Sbostic LOCAL Addrp putcxeq(p) 747*43222Sbostic register expptr p; 748*43222Sbostic { 749*43222Sbostic register Addrp lp, rp; 750*43222Sbostic int ncomma; 751*43222Sbostic 752*43222Sbostic if(p->tag != TEXPR) 753*43222Sbostic badtag("putcxeq", p->tag); 754*43222Sbostic 755*43222Sbostic ncomma = 0; 756*43222Sbostic lp = putcx1(p->exprblock.leftp, &ncomma); 757*43222Sbostic rp = putcx1(p->exprblock.rightp, &ncomma); 758*43222Sbostic putassign(realpart(lp), realpart(rp)); 759*43222Sbostic if( ISCOMPLEX(p->exprblock.vtype) ) 760*43222Sbostic { 761*43222Sbostic ++ncomma; 762*43222Sbostic putassign(imagpart(lp), imagpart(rp)); 763*43222Sbostic } 764*43222Sbostic putcomma(ncomma, TYREAL, NO); 765*43222Sbostic frexpr(rp); 766*43222Sbostic free( (charptr) p ); 767*43222Sbostic return(lp); 768*43222Sbostic } 769*43222Sbostic 770*43222Sbostic 771*43222Sbostic 772*43222Sbostic LOCAL putcxop(p) 773*43222Sbostic expptr p; 774*43222Sbostic { 775*43222Sbostic Addrp putcx1(); 776*43222Sbostic int ncomma; 777*43222Sbostic 778*43222Sbostic ncomma = 0; 779*43222Sbostic putaddr( putcx1(p, &ncomma), NO); 780*43222Sbostic putcomma(ncomma, TYINT, NO); 781*43222Sbostic } 782*43222Sbostic 783*43222Sbostic 784*43222Sbostic 785*43222Sbostic LOCAL Addrp putcx1(p, ncommap) 786*43222Sbostic register expptr p; 787*43222Sbostic int *ncommap; 788*43222Sbostic { 789*43222Sbostic expptr q; 790*43222Sbostic Addrp lp, rp; 791*43222Sbostic register Addrp resp; 792*43222Sbostic int opcode; 793*43222Sbostic int ltype, rtype; 794*43222Sbostic expptr mkrealcon(); 795*43222Sbostic 796*43222Sbostic if(p == NULL) 797*43222Sbostic return(NULL); 798*43222Sbostic 799*43222Sbostic switch(p->tag) 800*43222Sbostic { 801*43222Sbostic case TCONST: 802*43222Sbostic if( ISCOMPLEX(p->constblock.vtype) ) 803*43222Sbostic p = (expptr) putconst(p); 804*43222Sbostic return( (Addrp) p ); 805*43222Sbostic 806*43222Sbostic case TADDR: 807*43222Sbostic if( ! addressable(p) ) 808*43222Sbostic { 809*43222Sbostic ++*ncommap; 810*43222Sbostic resp = mkaltemp(tyint, PNULL); 811*43222Sbostic putassign( cpexpr(resp), p->addrblock.memoffset ); 812*43222Sbostic p->addrblock.memoffset = (expptr)resp; 813*43222Sbostic } 814*43222Sbostic return( (Addrp) p ); 815*43222Sbostic 816*43222Sbostic case TEXPR: 817*43222Sbostic if( ISCOMPLEX(p->exprblock.vtype) ) 818*43222Sbostic break; 819*43222Sbostic ++*ncommap; 820*43222Sbostic resp = mkaltemp(TYDREAL, NO); 821*43222Sbostic putassign( cpexpr(resp), p); 822*43222Sbostic return(resp); 823*43222Sbostic 824*43222Sbostic default: 825*43222Sbostic badtag("putcx1", p->tag); 826*43222Sbostic } 827*43222Sbostic 828*43222Sbostic opcode = p->exprblock.opcode; 829*43222Sbostic if(opcode==OPCALL || opcode==OPCCALL) 830*43222Sbostic { 831*43222Sbostic ++*ncommap; 832*43222Sbostic return( putcall(p) ); 833*43222Sbostic } 834*43222Sbostic else if(opcode == OPASSIGN) 835*43222Sbostic { 836*43222Sbostic ++*ncommap; 837*43222Sbostic return( putcxeq(p) ); 838*43222Sbostic } 839*43222Sbostic resp = mkaltemp(p->exprblock.vtype, PNULL); 840*43222Sbostic if(lp = putcx1(p->exprblock.leftp, ncommap) ) 841*43222Sbostic ltype = lp->vtype; 842*43222Sbostic if(rp = putcx1(p->exprblock.rightp, ncommap) ) 843*43222Sbostic rtype = rp->vtype; 844*43222Sbostic 845*43222Sbostic switch(opcode) 846*43222Sbostic { 847*43222Sbostic case OPPAREN: 848*43222Sbostic frexpr (resp); 849*43222Sbostic resp = lp; 850*43222Sbostic lp = NULL; 851*43222Sbostic break; 852*43222Sbostic 853*43222Sbostic case OPCOMMA: 854*43222Sbostic frexpr(resp); 855*43222Sbostic resp = rp; 856*43222Sbostic rp = NULL; 857*43222Sbostic break; 858*43222Sbostic 859*43222Sbostic case OPNEG: 860*43222Sbostic putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) ); 861*43222Sbostic putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) ); 862*43222Sbostic *ncommap += 2; 863*43222Sbostic break; 864*43222Sbostic 865*43222Sbostic case OPPLUS: 866*43222Sbostic case OPMINUS: 867*43222Sbostic putassign( realpart(resp), 868*43222Sbostic mkexpr(opcode, realpart(lp), realpart(rp) )); 869*43222Sbostic if(rtype < TYCOMPLEX) 870*43222Sbostic putassign( imagpart(resp), imagpart(lp) ); 871*43222Sbostic else if(ltype < TYCOMPLEX) 872*43222Sbostic { 873*43222Sbostic if(opcode == OPPLUS) 874*43222Sbostic putassign( imagpart(resp), imagpart(rp) ); 875*43222Sbostic else putassign( imagpart(resp), 876*43222Sbostic mkexpr(OPNEG, imagpart(rp), ENULL) ); 877*43222Sbostic } 878*43222Sbostic else 879*43222Sbostic putassign( imagpart(resp), 880*43222Sbostic mkexpr(opcode, imagpart(lp), imagpart(rp) )); 881*43222Sbostic 882*43222Sbostic *ncommap += 2; 883*43222Sbostic break; 884*43222Sbostic 885*43222Sbostic case OPSTAR: 886*43222Sbostic if(ltype < TYCOMPLEX) 887*43222Sbostic { 888*43222Sbostic if( ISINT(ltype) ) 889*43222Sbostic lp = intdouble(lp, ncommap); 890*43222Sbostic putassign( realpart(resp), 891*43222Sbostic mkexpr(OPSTAR, cpexpr(lp), realpart(rp) )); 892*43222Sbostic putassign( imagpart(resp), 893*43222Sbostic mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) )); 894*43222Sbostic } 895*43222Sbostic else if(rtype < TYCOMPLEX) 896*43222Sbostic { 897*43222Sbostic if( ISINT(rtype) ) 898*43222Sbostic rp = intdouble(rp, ncommap); 899*43222Sbostic putassign( realpart(resp), 900*43222Sbostic mkexpr(OPSTAR, cpexpr(rp), realpart(lp) )); 901*43222Sbostic putassign( imagpart(resp), 902*43222Sbostic mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) )); 903*43222Sbostic } 904*43222Sbostic else { 905*43222Sbostic putassign( realpart(resp), mkexpr(OPMINUS, 906*43222Sbostic mkexpr(OPSTAR, realpart(lp), realpart(rp)), 907*43222Sbostic mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) )); 908*43222Sbostic putassign( imagpart(resp), mkexpr(OPPLUS, 909*43222Sbostic mkexpr(OPSTAR, realpart(lp), imagpart(rp)), 910*43222Sbostic mkexpr(OPSTAR, imagpart(lp), realpart(rp)) )); 911*43222Sbostic } 912*43222Sbostic *ncommap += 2; 913*43222Sbostic break; 914*43222Sbostic 915*43222Sbostic case OPSLASH: 916*43222Sbostic /* fixexpr has already replaced all divisions 917*43222Sbostic * by a complex by a function call 918*43222Sbostic */ 919*43222Sbostic if( ISINT(rtype) ) 920*43222Sbostic rp = intdouble(rp, ncommap); 921*43222Sbostic putassign( realpart(resp), 922*43222Sbostic mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) ); 923*43222Sbostic putassign( imagpart(resp), 924*43222Sbostic mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) ); 925*43222Sbostic *ncommap += 2; 926*43222Sbostic break; 927*43222Sbostic 928*43222Sbostic case OPCONV: 929*43222Sbostic putassign( realpart(resp), realpart(lp) ); 930*43222Sbostic if( ISCOMPLEX(lp->vtype) ) 931*43222Sbostic q = imagpart(lp); 932*43222Sbostic else if(rp != NULL) 933*43222Sbostic q = (expptr) realpart(rp); 934*43222Sbostic else 935*43222Sbostic q = mkrealcon(TYDREAL, 0.0); 936*43222Sbostic putassign( imagpart(resp), q); 937*43222Sbostic *ncommap += 2; 938*43222Sbostic break; 939*43222Sbostic 940*43222Sbostic default: 941*43222Sbostic badop("putcx1", opcode); 942*43222Sbostic } 943*43222Sbostic 944*43222Sbostic frexpr(lp); 945*43222Sbostic frexpr(rp); 946*43222Sbostic free( (charptr) p ); 947*43222Sbostic return(resp); 948*43222Sbostic } 949*43222Sbostic 950*43222Sbostic 951*43222Sbostic 952*43222Sbostic 953*43222Sbostic LOCAL putcxcmp(p) 954*43222Sbostic register expptr p; 955*43222Sbostic { 956*43222Sbostic int opcode; 957*43222Sbostic int ncomma; 958*43222Sbostic register Addrp lp, rp; 959*43222Sbostic expptr q; 960*43222Sbostic 961*43222Sbostic if(p->tag != TEXPR) 962*43222Sbostic badtag("putcxcmp", p->tag); 963*43222Sbostic 964*43222Sbostic ncomma = 0; 965*43222Sbostic opcode = p->exprblock.opcode; 966*43222Sbostic lp = putcx1(p->exprblock.leftp, &ncomma); 967*43222Sbostic rp = putcx1(p->exprblock.rightp, &ncomma); 968*43222Sbostic 969*43222Sbostic q = mkexpr( opcode==OPEQ ? OPAND : OPOR , 970*43222Sbostic mkexpr(opcode, realpart(lp), realpart(rp)), 971*43222Sbostic mkexpr(opcode, imagpart(lp), imagpart(rp)) ); 972*43222Sbostic putx( fixexpr(q) ); 973*43222Sbostic putcomma(ncomma, TYINT, NO); 974*43222Sbostic 975*43222Sbostic free( (charptr) lp); 976*43222Sbostic free( (charptr) rp); 977*43222Sbostic free( (charptr) p ); 978*43222Sbostic } 979*43222Sbostic 980*43222Sbostic LOCAL Addrp putch1(p, ncommap) 981*43222Sbostic register expptr p; 982*43222Sbostic int * ncommap; 983*43222Sbostic { 984*43222Sbostic register Addrp t; 985*43222Sbostic 986*43222Sbostic switch(p->tag) 987*43222Sbostic { 988*43222Sbostic case TCONST: 989*43222Sbostic return( putconst(p) ); 990*43222Sbostic 991*43222Sbostic case TADDR: 992*43222Sbostic return( (Addrp) p ); 993*43222Sbostic 994*43222Sbostic case TEXPR: 995*43222Sbostic ++*ncommap; 996*43222Sbostic 997*43222Sbostic switch(p->exprblock.opcode) 998*43222Sbostic { 999*43222Sbostic expptr q; 1000*43222Sbostic 1001*43222Sbostic case OPCALL: 1002*43222Sbostic case OPCCALL: 1003*43222Sbostic t = putcall(p); 1004*43222Sbostic break; 1005*43222Sbostic 1006*43222Sbostic case OPPAREN: 1007*43222Sbostic --*ncommap; 1008*43222Sbostic t = putch1(p->exprblock.leftp, ncommap); 1009*43222Sbostic break; 1010*43222Sbostic 1011*43222Sbostic case OPCONCAT: 1012*43222Sbostic t = mkaltemp(TYCHAR, ICON(lencat(p)) ); 1013*43222Sbostic q = (expptr) cpexpr(p->headblock.vleng); 1014*43222Sbostic putcat( cpexpr(t), p ); 1015*43222Sbostic /* put the correct length on the block */ 1016*43222Sbostic frexpr(t->vleng); 1017*43222Sbostic t->vleng = q; 1018*43222Sbostic 1019*43222Sbostic break; 1020*43222Sbostic 1021*43222Sbostic case OPCONV: 1022*43222Sbostic if(!ISICON(p->exprblock.vleng) 1023*43222Sbostic || p->exprblock.vleng->constblock.const.ci!=1 1024*43222Sbostic || ! INT(p->exprblock.leftp->headblock.vtype) ) 1025*43222Sbostic fatal("putch1: bad character conversion"); 1026*43222Sbostic t = mkaltemp(TYCHAR, ICON(1) ); 1027*43222Sbostic putop( mkexpr(OPASSIGN, cpexpr(t), p) ); 1028*43222Sbostic break; 1029*43222Sbostic default: 1030*43222Sbostic badop("putch1", p->exprblock.opcode); 1031*43222Sbostic } 1032*43222Sbostic return(t); 1033*43222Sbostic 1034*43222Sbostic default: 1035*43222Sbostic badtag("putch1", p->tag); 1036*43222Sbostic } 1037*43222Sbostic /* NOTREACHED */ 1038*43222Sbostic } 1039*43222Sbostic 1040*43222Sbostic 1041*43222Sbostic 1042*43222Sbostic 1043*43222Sbostic LOCAL putchop(p) 1044*43222Sbostic expptr p; 1045*43222Sbostic { 1046*43222Sbostic int ncomma; 1047*43222Sbostic 1048*43222Sbostic ncomma = 0; 1049*43222Sbostic putaddr( putch1(p, &ncomma) , NO ); 1050*43222Sbostic putcomma(ncomma, TYCHAR, YES); 1051*43222Sbostic } 1052*43222Sbostic 1053*43222Sbostic 1054*43222Sbostic 1055*43222Sbostic 1056*43222Sbostic LOCAL putcheq(p) 1057*43222Sbostic register expptr p; 1058*43222Sbostic { 1059*43222Sbostic int ncomma; 1060*43222Sbostic expptr lp, rp; 1061*43222Sbostic 1062*43222Sbostic if(p->tag != TEXPR) 1063*43222Sbostic badtag("putcheq", p->tag); 1064*43222Sbostic 1065*43222Sbostic ncomma = 0; 1066*43222Sbostic lp = p->exprblock.leftp; 1067*43222Sbostic rp = p->exprblock.rightp; 1068*43222Sbostic if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT ) 1069*43222Sbostic putcat(lp, rp); 1070*43222Sbostic else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) 1071*43222Sbostic { 1072*43222Sbostic putaddr( putch1(lp, &ncomma) , YES ); 1073*43222Sbostic putaddr( putch1(rp, &ncomma) , YES ); 1074*43222Sbostic putcomma(ncomma, TYINT, NO); 1075*43222Sbostic p2op(PCC_ASSIGN, PCCT_CHAR); 1076*43222Sbostic } 1077*43222Sbostic else 1078*43222Sbostic { 1079*43222Sbostic putx( call2(TYINT, "s_copy", lp, rp) ); 1080*43222Sbostic putcomma(ncomma, TYINT, NO); 1081*43222Sbostic } 1082*43222Sbostic 1083*43222Sbostic frexpr(p->exprblock.vleng); 1084*43222Sbostic free( (charptr) p ); 1085*43222Sbostic } 1086*43222Sbostic 1087*43222Sbostic 1088*43222Sbostic 1089*43222Sbostic 1090*43222Sbostic LOCAL putchcmp(p) 1091*43222Sbostic register expptr p; 1092*43222Sbostic { 1093*43222Sbostic int ncomma; 1094*43222Sbostic expptr lp, rp; 1095*43222Sbostic 1096*43222Sbostic if(p->tag != TEXPR) 1097*43222Sbostic badtag("putchcmp", p->tag); 1098*43222Sbostic 1099*43222Sbostic ncomma = 0; 1100*43222Sbostic lp = p->exprblock.leftp; 1101*43222Sbostic rp = p->exprblock.rightp; 1102*43222Sbostic 1103*43222Sbostic if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) ) 1104*43222Sbostic { 1105*43222Sbostic putaddr( putch1(lp, &ncomma) , YES ); 1106*43222Sbostic putcomma(ncomma, TYINT, NO); 1107*43222Sbostic ncomma = 0; 1108*43222Sbostic putaddr( putch1(rp, &ncomma) , YES ); 1109*43222Sbostic putcomma(ncomma, TYINT, NO); 1110*43222Sbostic p2op(ops2[p->exprblock.opcode], PCCT_CHAR); 1111*43222Sbostic free( (charptr) p ); 1112*43222Sbostic } 1113*43222Sbostic else 1114*43222Sbostic { 1115*43222Sbostic p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp); 1116*43222Sbostic p->exprblock.rightp = ICON(0); 1117*43222Sbostic putop(p); 1118*43222Sbostic } 1119*43222Sbostic } 1120*43222Sbostic 1121*43222Sbostic 1122*43222Sbostic 1123*43222Sbostic 1124*43222Sbostic 1125*43222Sbostic LOCAL putcat(lhs, rhs) 1126*43222Sbostic register Addrp lhs; 1127*43222Sbostic register expptr rhs; 1128*43222Sbostic { 1129*43222Sbostic int n, ncomma; 1130*43222Sbostic Addrp lp, cp; 1131*43222Sbostic 1132*43222Sbostic ncomma = 0; 1133*43222Sbostic n = ncat(rhs); 1134*43222Sbostic lp = mkaltmpn(n, TYLENG, PNULL); 1135*43222Sbostic cp = mkaltmpn(n, TYADDR, PNULL); 1136*43222Sbostic 1137*43222Sbostic n = 0; 1138*43222Sbostic putct1(rhs, lp, cp, &n, &ncomma); 1139*43222Sbostic 1140*43222Sbostic putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) ); 1141*43222Sbostic putcomma(ncomma, TYINT, NO); 1142*43222Sbostic } 1143*43222Sbostic 1144*43222Sbostic 1145*43222Sbostic 1146*43222Sbostic 1147*43222Sbostic 1148*43222Sbostic LOCAL putct1(q, lp, cp, ip, ncommap) 1149*43222Sbostic register expptr q; 1150*43222Sbostic register Addrp lp, cp; 1151*43222Sbostic int *ip, *ncommap; 1152*43222Sbostic { 1153*43222Sbostic int i; 1154*43222Sbostic Addrp lp1, cp1; 1155*43222Sbostic 1156*43222Sbostic if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT) 1157*43222Sbostic { 1158*43222Sbostic putct1(q->exprblock.leftp, lp, cp, ip, ncommap); 1159*43222Sbostic putct1(q->exprblock.rightp, lp, cp , ip, ncommap); 1160*43222Sbostic frexpr(q->exprblock.vleng); 1161*43222Sbostic free( (charptr) q ); 1162*43222Sbostic } 1163*43222Sbostic else 1164*43222Sbostic { 1165*43222Sbostic i = (*ip)++; 1166*43222Sbostic lp1 = (Addrp) cpexpr(lp); 1167*43222Sbostic lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG)); 1168*43222Sbostic cp1 = (Addrp) cpexpr(cp); 1169*43222Sbostic cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR)); 1170*43222Sbostic putassign( lp1, cpexpr(q->headblock.vleng) ); 1171*43222Sbostic putassign( cp1, addrof(putch1(q,ncommap)) ); 1172*43222Sbostic *ncommap += 2; 1173*43222Sbostic } 1174*43222Sbostic } 1175*43222Sbostic 1176*43222Sbostic LOCAL putaddr(p, indir) 1177*43222Sbostic register Addrp p; 1178*43222Sbostic int indir; 1179*43222Sbostic { 1180*43222Sbostic int type, type2, funct; 1181*43222Sbostic ftnint offset, simoffset(); 1182*43222Sbostic expptr offp, shorten(); 1183*43222Sbostic 1184*43222Sbostic if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) ) 1185*43222Sbostic { 1186*43222Sbostic frexpr(p); 1187*43222Sbostic return; 1188*43222Sbostic } 1189*43222Sbostic if (p->tag != TADDR) badtag ("putaddr",p->tag); 1190*43222Sbostic 1191*43222Sbostic type = p->vtype; 1192*43222Sbostic type2 = types2[type]; 1193*43222Sbostic funct = (p->vclass==CLPROC ? PCCTM_FTN<<2 : 0); 1194*43222Sbostic 1195*43222Sbostic offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL ); 1196*43222Sbostic 1197*43222Sbostic 1198*43222Sbostic #if (FUDGEOFFSET != 1) 1199*43222Sbostic if(offp) 1200*43222Sbostic offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp); 1201*43222Sbostic #endif 1202*43222Sbostic 1203*43222Sbostic offset = simoffset( &offp ); 1204*43222Sbostic #if SZINT < SZLONG 1205*43222Sbostic if(offp) 1206*43222Sbostic if(shortsubs) 1207*43222Sbostic offp = shorten(offp); 1208*43222Sbostic else 1209*43222Sbostic offp = mkconv(TYINT, offp); 1210*43222Sbostic #else 1211*43222Sbostic if(offp) 1212*43222Sbostic offp = mkconv(TYINT, offp); 1213*43222Sbostic #endif 1214*43222Sbostic 1215*43222Sbostic if (p->vclass == CLVAR 1216*43222Sbostic && (p->vstg == STGBSS || p->vstg == STGEQUIV) 1217*43222Sbostic && SMALLVAR(p->varsize) 1218*43222Sbostic && offset >= -32768 && offset <= 32767) 1219*43222Sbostic { 1220*43222Sbostic anylocals = YES; 1221*43222Sbostic if (indir && !offp) 1222*43222Sbostic p2ldisp(offset, memname(p->vstg, p->memno), type2); 1223*43222Sbostic else 1224*43222Sbostic { 1225*43222Sbostic p2reg(LVARREG, type2 | PCCTM_PTR); 1226*43222Sbostic p2triple(PCC_ICON, 1, PCCT_INT); 1227*43222Sbostic p2word(offset); 1228*43222Sbostic p2ndisp(memname(p->vstg, p->memno)); 1229*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1230*43222Sbostic if (offp) 1231*43222Sbostic { 1232*43222Sbostic putx(offp); 1233*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1234*43222Sbostic } 1235*43222Sbostic if (indir) 1236*43222Sbostic p2op(PCC_DEREF, type2); 1237*43222Sbostic } 1238*43222Sbostic frexpr((tagptr) p); 1239*43222Sbostic return; 1240*43222Sbostic } 1241*43222Sbostic 1242*43222Sbostic switch(p->vstg) 1243*43222Sbostic { 1244*43222Sbostic case STGAUTO: 1245*43222Sbostic if(indir && !offp) 1246*43222Sbostic { 1247*43222Sbostic p2oreg(offset, AUTOREG, type2); 1248*43222Sbostic break; 1249*43222Sbostic } 1250*43222Sbostic 1251*43222Sbostic if(!indir && !offp && !offset) 1252*43222Sbostic { 1253*43222Sbostic p2reg(AUTOREG, type2 | PCCTM_PTR); 1254*43222Sbostic break; 1255*43222Sbostic } 1256*43222Sbostic 1257*43222Sbostic p2reg(AUTOREG, type2 | PCCTM_PTR); 1258*43222Sbostic if(offp) 1259*43222Sbostic { 1260*43222Sbostic putx(offp); 1261*43222Sbostic if(offset) 1262*43222Sbostic p2icon(offset, PCCT_INT); 1263*43222Sbostic } 1264*43222Sbostic else 1265*43222Sbostic p2icon(offset, PCCT_INT); 1266*43222Sbostic if(offp && offset) 1267*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1268*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1269*43222Sbostic if(indir) 1270*43222Sbostic p2op(PCC_DEREF, type2); 1271*43222Sbostic break; 1272*43222Sbostic 1273*43222Sbostic case STGARG: 1274*43222Sbostic p2oreg( 1275*43222Sbostic #ifdef ARGOFFSET 1276*43222Sbostic ARGOFFSET + 1277*43222Sbostic #endif 1278*43222Sbostic (ftnint) (FUDGEOFFSET*p->memno), 1279*43222Sbostic ARGREG, type2 | PCCTM_PTR | funct ); 1280*43222Sbostic 1281*43222Sbostic based: 1282*43222Sbostic if(offset) 1283*43222Sbostic { 1284*43222Sbostic p2icon(offset, PCCT_INT); 1285*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1286*43222Sbostic } 1287*43222Sbostic if(offp) 1288*43222Sbostic { 1289*43222Sbostic putx(offp); 1290*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1291*43222Sbostic } 1292*43222Sbostic if(indir) 1293*43222Sbostic p2op(PCC_DEREF, type2); 1294*43222Sbostic break; 1295*43222Sbostic 1296*43222Sbostic case STGLENG: 1297*43222Sbostic if(indir) 1298*43222Sbostic { 1299*43222Sbostic p2oreg( 1300*43222Sbostic #ifdef ARGOFFSET 1301*43222Sbostic ARGOFFSET + 1302*43222Sbostic #endif 1303*43222Sbostic (ftnint) (FUDGEOFFSET*p->memno), 1304*43222Sbostic ARGREG, type2 ); 1305*43222Sbostic } 1306*43222Sbostic else { 1307*43222Sbostic p2reg(ARGREG, type2 | PCCTM_PTR ); 1308*43222Sbostic p2icon( 1309*43222Sbostic #ifdef ARGOFFSET 1310*43222Sbostic ARGOFFSET + 1311*43222Sbostic #endif 1312*43222Sbostic (ftnint) (FUDGEOFFSET*p->memno), PCCT_INT); 1313*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR ); 1314*43222Sbostic } 1315*43222Sbostic break; 1316*43222Sbostic 1317*43222Sbostic 1318*43222Sbostic case STGBSS: 1319*43222Sbostic case STGINIT: 1320*43222Sbostic case STGEXT: 1321*43222Sbostic case STGINTR: 1322*43222Sbostic case STGCOMMON: 1323*43222Sbostic case STGEQUIV: 1324*43222Sbostic case STGCONST: 1325*43222Sbostic if(offp) 1326*43222Sbostic { 1327*43222Sbostic putx(offp); 1328*43222Sbostic putmem(p, PCC_ICON, offset); 1329*43222Sbostic p2op(PCC_PLUS, type2 | PCCTM_PTR); 1330*43222Sbostic if(indir) 1331*43222Sbostic p2op(PCC_DEREF, type2); 1332*43222Sbostic } 1333*43222Sbostic else 1334*43222Sbostic putmem(p, (indir ? PCC_NAME : PCC_ICON), offset); 1335*43222Sbostic 1336*43222Sbostic break; 1337*43222Sbostic 1338*43222Sbostic case STGREG: 1339*43222Sbostic if(indir) 1340*43222Sbostic p2reg(p->memno, type2); 1341*43222Sbostic else 1342*43222Sbostic fatal("attempt to take address of a register"); 1343*43222Sbostic break; 1344*43222Sbostic 1345*43222Sbostic case STGPREG: 1346*43222Sbostic if(indir && !offp) 1347*43222Sbostic p2oreg(offset, p->memno, type2); 1348*43222Sbostic else 1349*43222Sbostic { 1350*43222Sbostic p2reg(p->memno, type2 | PCCTM_PTR); 1351*43222Sbostic goto based; 1352*43222Sbostic } 1353*43222Sbostic break; 1354*43222Sbostic 1355*43222Sbostic default: 1356*43222Sbostic badstg("putaddr", p->vstg); 1357*43222Sbostic } 1358*43222Sbostic frexpr(p); 1359*43222Sbostic } 1360*43222Sbostic 1361*43222Sbostic 1362*43222Sbostic 1363*43222Sbostic 1364*43222Sbostic LOCAL putmem(p, class, offset) 1365*43222Sbostic expptr p; 1366*43222Sbostic int class; 1367*43222Sbostic ftnint offset; 1368*43222Sbostic { 1369*43222Sbostic int type2; 1370*43222Sbostic int funct; 1371*43222Sbostic char *name, *memname(); 1372*43222Sbostic 1373*43222Sbostic funct = (p->headblock.vclass==CLPROC ? PCCTM_FTN<<2 : 0); 1374*43222Sbostic type2 = types2[p->headblock.vtype]; 1375*43222Sbostic if(p->headblock.vclass == CLPROC) 1376*43222Sbostic type2 |= (PCCTM_FTN<<2); 1377*43222Sbostic name = memname(p->addrblock.vstg, p->addrblock.memno); 1378*43222Sbostic if(class == PCC_ICON) 1379*43222Sbostic { 1380*43222Sbostic p2triple(PCC_ICON, name[0]!='\0', type2|PCCTM_PTR); 1381*43222Sbostic p2word(offset); 1382*43222Sbostic if(name[0]) 1383*43222Sbostic p2name(name); 1384*43222Sbostic } 1385*43222Sbostic else 1386*43222Sbostic { 1387*43222Sbostic p2triple(PCC_NAME, offset!=0, type2); 1388*43222Sbostic if(offset != 0) 1389*43222Sbostic p2word(offset); 1390*43222Sbostic p2name(name); 1391*43222Sbostic } 1392*43222Sbostic } 1393*43222Sbostic 1394*43222Sbostic 1395*43222Sbostic 1396*43222Sbostic LOCAL Addrp putcall(p) 1397*43222Sbostic register Exprp p; 1398*43222Sbostic { 1399*43222Sbostic chainp arglist, charsp, cp; 1400*43222Sbostic int n, first; 1401*43222Sbostic Addrp t; 1402*43222Sbostic register expptr q; 1403*43222Sbostic Addrp fval, mkargtemp(); 1404*43222Sbostic int type, type2, ctype, qtype, indir; 1405*43222Sbostic 1406*43222Sbostic type2 = types2[type = p->vtype]; 1407*43222Sbostic charsp = NULL; 1408*43222Sbostic indir = (p->opcode == OPCCALL); 1409*43222Sbostic n = 0; 1410*43222Sbostic first = YES; 1411*43222Sbostic 1412*43222Sbostic if(p->rightp) 1413*43222Sbostic { 1414*43222Sbostic arglist = p->rightp->listblock.listp; 1415*43222Sbostic free( (charptr) (p->rightp) ); 1416*43222Sbostic } 1417*43222Sbostic else 1418*43222Sbostic arglist = NULL; 1419*43222Sbostic 1420*43222Sbostic for(cp = arglist ; cp ; cp = cp->nextp) 1421*43222Sbostic { 1422*43222Sbostic q = (expptr) cp->datap; 1423*43222Sbostic if(indir) 1424*43222Sbostic ++n; 1425*43222Sbostic else { 1426*43222Sbostic q = (expptr) (cp->datap); 1427*43222Sbostic if( ISCONST(q) ) 1428*43222Sbostic { 1429*43222Sbostic q = (expptr) putconst(q); 1430*43222Sbostic cp->datap = (tagptr) q; 1431*43222Sbostic } 1432*43222Sbostic if( ISCHAR(q) && q->headblock.vclass!=CLPROC ) 1433*43222Sbostic { 1434*43222Sbostic charsp = hookup(charsp, 1435*43222Sbostic mkchain(cpexpr(q->headblock.vleng), 1436*43222Sbostic CHNULL)); 1437*43222Sbostic n += 2; 1438*43222Sbostic } 1439*43222Sbostic else 1440*43222Sbostic n += 1; 1441*43222Sbostic } 1442*43222Sbostic } 1443*43222Sbostic 1444*43222Sbostic if(type == TYCHAR) 1445*43222Sbostic { 1446*43222Sbostic if( ISICON(p->vleng) ) 1447*43222Sbostic { 1448*43222Sbostic fval = mkargtemp(TYCHAR, p->vleng); 1449*43222Sbostic n += 2; 1450*43222Sbostic } 1451*43222Sbostic else { 1452*43222Sbostic err("adjustable character function"); 1453*43222Sbostic return; 1454*43222Sbostic } 1455*43222Sbostic } 1456*43222Sbostic else if( ISCOMPLEX(type) ) 1457*43222Sbostic { 1458*43222Sbostic fval = mkargtemp(type, PNULL); 1459*43222Sbostic n += 1; 1460*43222Sbostic } 1461*43222Sbostic else 1462*43222Sbostic fval = NULL; 1463*43222Sbostic 1464*43222Sbostic ctype = (fval ? PCCT_INT : type2); 1465*43222Sbostic putaddr(p->leftp, NO); 1466*43222Sbostic 1467*43222Sbostic if(fval) 1468*43222Sbostic { 1469*43222Sbostic first = NO; 1470*43222Sbostic putaddr( cpexpr(fval), NO); 1471*43222Sbostic if(type==TYCHAR) 1472*43222Sbostic { 1473*43222Sbostic putx( mkconv(TYLENG,p->vleng) ); 1474*43222Sbostic p2op(PCC_CM, type2); 1475*43222Sbostic } 1476*43222Sbostic } 1477*43222Sbostic 1478*43222Sbostic for(cp = arglist ; cp ; cp = cp->nextp) 1479*43222Sbostic { 1480*43222Sbostic q = (expptr) (cp->datap); 1481*43222Sbostic if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) ) 1482*43222Sbostic putaddr(q, indir && q->addrblock.vtype!=TYCHAR); 1483*43222Sbostic else if( ISCOMPLEX(q->headblock.vtype) ) 1484*43222Sbostic putcxop(q); 1485*43222Sbostic else if (ISCHAR(q) ) 1486*43222Sbostic putchop(q); 1487*43222Sbostic else if( ! ISERROR(q) ) 1488*43222Sbostic { 1489*43222Sbostic if(indir) 1490*43222Sbostic putx(q); 1491*43222Sbostic else { 1492*43222Sbostic t = mkargtemp(qtype = q->headblock.vtype, 1493*43222Sbostic q->headblock.vleng); 1494*43222Sbostic putassign( cpexpr(t), q ); 1495*43222Sbostic putaddr(t, NO); 1496*43222Sbostic putcomma(1, qtype, YES); 1497*43222Sbostic } 1498*43222Sbostic } 1499*43222Sbostic if(first) 1500*43222Sbostic first = NO; 1501*43222Sbostic else 1502*43222Sbostic p2op(PCC_CM, type2); 1503*43222Sbostic } 1504*43222Sbostic 1505*43222Sbostic if(arglist) 1506*43222Sbostic frchain(&arglist); 1507*43222Sbostic for(cp = charsp ; cp ; cp = cp->nextp) 1508*43222Sbostic { 1509*43222Sbostic putx( mkconv(TYLENG,cp->datap) ); 1510*43222Sbostic p2op(PCC_CM, type2); 1511*43222Sbostic } 1512*43222Sbostic frchain(&charsp); 1513*43222Sbostic #if TARGET == TAHOE 1514*43222Sbostic if(indir && ctype==PCCT_FLOAT) /* function opcodes */ 1515*43222Sbostic p2op(PCC_FORTCALL, ctype); 1516*43222Sbostic else 1517*43222Sbostic #endif 1518*43222Sbostic p2op(n>0 ? PCC_CALL : PCC_UCALL , ctype); 1519*43222Sbostic free( (charptr) p ); 1520*43222Sbostic return(fval); 1521*43222Sbostic } 1522*43222Sbostic 1523*43222Sbostic 1524*43222Sbostic 1525*43222Sbostic LOCAL putmnmx(p) 1526*43222Sbostic register expptr p; 1527*43222Sbostic { 1528*43222Sbostic int op, type; 1529*43222Sbostic int ncomma; 1530*43222Sbostic expptr qp; 1531*43222Sbostic chainp p0, p1; 1532*43222Sbostic Addrp sp, tp; 1533*43222Sbostic 1534*43222Sbostic if(p->tag != TEXPR) 1535*43222Sbostic badtag("putmnmx", p->tag); 1536*43222Sbostic 1537*43222Sbostic type = p->exprblock.vtype; 1538*43222Sbostic op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT ); 1539*43222Sbostic p0 = p->exprblock.leftp->listblock.listp; 1540*43222Sbostic free( (charptr) (p->exprblock.leftp) ); 1541*43222Sbostic free( (charptr) p ); 1542*43222Sbostic 1543*43222Sbostic sp = mkaltemp(type, PNULL); 1544*43222Sbostic tp = mkaltemp(type, PNULL); 1545*43222Sbostic qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp)); 1546*43222Sbostic qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp); 1547*43222Sbostic qp = fixexpr(qp); 1548*43222Sbostic 1549*43222Sbostic ncomma = 1; 1550*43222Sbostic putassign( cpexpr(sp), p0->datap ); 1551*43222Sbostic 1552*43222Sbostic for(p1 = p0->nextp ; p1 ; p1 = p1->nextp) 1553*43222Sbostic { 1554*43222Sbostic ++ncomma; 1555*43222Sbostic putassign( cpexpr(tp), p1->datap ); 1556*43222Sbostic if(p1->nextp) 1557*43222Sbostic { 1558*43222Sbostic ++ncomma; 1559*43222Sbostic putassign( cpexpr(sp), cpexpr(qp) ); 1560*43222Sbostic } 1561*43222Sbostic else 1562*43222Sbostic putx(qp); 1563*43222Sbostic } 1564*43222Sbostic 1565*43222Sbostic putcomma(ncomma, type, NO); 1566*43222Sbostic frexpr(sp); 1567*43222Sbostic frexpr(tp); 1568*43222Sbostic frchain( &p0 ); 1569*43222Sbostic } 1570*43222Sbostic 1571*43222Sbostic 1572*43222Sbostic 1573*43222Sbostic 1574*43222Sbostic LOCAL putcomma(n, type, indir) 1575*43222Sbostic int n, type, indir; 1576*43222Sbostic { 1577*43222Sbostic type = types2[type]; 1578*43222Sbostic if(indir) 1579*43222Sbostic type |= PCCTM_PTR; 1580*43222Sbostic while(--n >= 0) 1581*43222Sbostic p2op(PCC_COMOP, type); 1582*43222Sbostic } 1583*43222Sbostic 1584*43222Sbostic 1585*43222Sbostic 1586*43222Sbostic 1587*43222Sbostic ftnint simoffset(p0) 1588*43222Sbostic expptr *p0; 1589*43222Sbostic { 1590*43222Sbostic ftnint offset, prod; 1591*43222Sbostic register expptr p, lp, rp; 1592*43222Sbostic 1593*43222Sbostic offset = 0; 1594*43222Sbostic p = *p0; 1595*43222Sbostic if(p == NULL) 1596*43222Sbostic return(0); 1597*43222Sbostic 1598*43222Sbostic if( ! ISINT(p->headblock.vtype) ) 1599*43222Sbostic return(0); 1600*43222Sbostic 1601*43222Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR) 1602*43222Sbostic { 1603*43222Sbostic lp = p->exprblock.leftp; 1604*43222Sbostic rp = p->exprblock.rightp; 1605*43222Sbostic if(ISICON(rp) && lp->tag==TEXPR && 1606*43222Sbostic lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp)) 1607*43222Sbostic { 1608*43222Sbostic p->exprblock.opcode = OPPLUS; 1609*43222Sbostic lp->exprblock.opcode = OPSTAR; 1610*43222Sbostic prod = rp->constblock.const.ci * 1611*43222Sbostic lp->exprblock.rightp->constblock.const.ci; 1612*43222Sbostic lp->exprblock.rightp->constblock.const.ci = rp->constblock.const.ci; 1613*43222Sbostic rp->constblock.const.ci = prod; 1614*43222Sbostic } 1615*43222Sbostic } 1616*43222Sbostic 1617*43222Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS && 1618*43222Sbostic ISICON(p->exprblock.rightp)) 1619*43222Sbostic { 1620*43222Sbostic rp = p->exprblock.rightp; 1621*43222Sbostic lp = p->exprblock.leftp; 1622*43222Sbostic offset += rp->constblock.const.ci; 1623*43222Sbostic frexpr(rp); 1624*43222Sbostic free( (charptr) p ); 1625*43222Sbostic *p0 = lp; 1626*43222Sbostic } 1627*43222Sbostic 1628*43222Sbostic if( ISCONST(p) ) 1629*43222Sbostic { 1630*43222Sbostic offset += p->constblock.const.ci; 1631*43222Sbostic frexpr(p); 1632*43222Sbostic *p0 = NULL; 1633*43222Sbostic } 1634*43222Sbostic 1635*43222Sbostic return(offset); 1636*43222Sbostic } 1637*43222Sbostic 1638*43222Sbostic 1639*43222Sbostic 1640*43222Sbostic 1641*43222Sbostic 1642*43222Sbostic p2op(op, type) 1643*43222Sbostic int op, type; 1644*43222Sbostic { 1645*43222Sbostic p2triple(op, 0, type); 1646*43222Sbostic } 1647*43222Sbostic 1648*43222Sbostic p2icon(offset, type) 1649*43222Sbostic ftnint offset; 1650*43222Sbostic int type; 1651*43222Sbostic { 1652*43222Sbostic p2triple(PCC_ICON, 0, type); 1653*43222Sbostic p2word(offset); 1654*43222Sbostic } 1655*43222Sbostic 1656*43222Sbostic 1657*43222Sbostic 1658*43222Sbostic 1659*43222Sbostic p2oreg(offset, reg, type) 1660*43222Sbostic ftnint offset; 1661*43222Sbostic int reg, type; 1662*43222Sbostic { 1663*43222Sbostic p2triple(PCC_OREG, reg, type); 1664*43222Sbostic p2word(offset); 1665*43222Sbostic p2name(""); 1666*43222Sbostic } 1667*43222Sbostic 1668*43222Sbostic 1669*43222Sbostic 1670*43222Sbostic 1671*43222Sbostic p2reg(reg, type) 1672*43222Sbostic int reg, type; 1673*43222Sbostic { 1674*43222Sbostic p2triple(PCC_REG, reg, type); 1675*43222Sbostic } 1676*43222Sbostic 1677*43222Sbostic 1678*43222Sbostic 1679*43222Sbostic p2pi(s, i) 1680*43222Sbostic char *s; 1681*43222Sbostic int i; 1682*43222Sbostic { 1683*43222Sbostic char buff[100]; 1684*43222Sbostic sprintf(buff, s, i); 1685*43222Sbostic p2pass(buff); 1686*43222Sbostic } 1687*43222Sbostic 1688*43222Sbostic 1689*43222Sbostic 1690*43222Sbostic p2pij(s, i, j) 1691*43222Sbostic char *s; 1692*43222Sbostic int i, j; 1693*43222Sbostic { 1694*43222Sbostic char buff[100]; 1695*43222Sbostic sprintf(buff, s, i, j); 1696*43222Sbostic p2pass(buff); 1697*43222Sbostic } 1698*43222Sbostic 1699*43222Sbostic 1700*43222Sbostic 1701*43222Sbostic 1702*43222Sbostic p2ps(s, t) 1703*43222Sbostic char *s, *t; 1704*43222Sbostic { 1705*43222Sbostic char buff[100]; 1706*43222Sbostic sprintf(buff, s, t); 1707*43222Sbostic p2pass(buff); 1708*43222Sbostic } 1709*43222Sbostic 1710*43222Sbostic 1711*43222Sbostic 1712*43222Sbostic 1713*43222Sbostic p2pass(s) 1714*43222Sbostic char *s; 1715*43222Sbostic { 1716*43222Sbostic p2triple(PCCF_FTEXT, (strlen(s) + ALILONG-1)/ALILONG, 0); 1717*43222Sbostic p2str(s); 1718*43222Sbostic } 1719*43222Sbostic 1720*43222Sbostic 1721*43222Sbostic 1722*43222Sbostic 1723*43222Sbostic p2str(s) 1724*43222Sbostic register char *s; 1725*43222Sbostic { 1726*43222Sbostic union { long int word; char str[SZLONG]; } u; 1727*43222Sbostic register int i; 1728*43222Sbostic 1729*43222Sbostic i = 0; 1730*43222Sbostic u.word = 0; 1731*43222Sbostic while(*s) 1732*43222Sbostic { 1733*43222Sbostic u.str[i++] = *s++; 1734*43222Sbostic if(i == SZLONG) 1735*43222Sbostic { 1736*43222Sbostic p2word(u.word); 1737*43222Sbostic u.word = 0; 1738*43222Sbostic i = 0; 1739*43222Sbostic } 1740*43222Sbostic } 1741*43222Sbostic if(i > 0) 1742*43222Sbostic p2word(u.word); 1743*43222Sbostic } 1744*43222Sbostic 1745*43222Sbostic 1746*43222Sbostic 1747*43222Sbostic 1748*43222Sbostic p2triple(op, var, type) 1749*43222Sbostic int op, var, type; 1750*43222Sbostic { 1751*43222Sbostic register long word; 1752*43222Sbostic word = PCCM_TRIPLE(op, var, type); 1753*43222Sbostic p2word(word); 1754*43222Sbostic } 1755*43222Sbostic 1756*43222Sbostic 1757*43222Sbostic 1758*43222Sbostic 1759*43222Sbostic 1760*43222Sbostic p2name(s) 1761*43222Sbostic register char *s; 1762*43222Sbostic { 1763*43222Sbostic register int i; 1764*43222Sbostic 1765*43222Sbostic #ifdef UCBPASS2 1766*43222Sbostic /* arbitrary length names, terminated by a null, 1767*43222Sbostic padded to a full word */ 1768*43222Sbostic 1769*43222Sbostic # define WL sizeof(long int) 1770*43222Sbostic union { long int word; char str[WL]; } w; 1771*43222Sbostic 1772*43222Sbostic w.word = 0; 1773*43222Sbostic i = 0; 1774*43222Sbostic while(w.str[i++] = *s++) 1775*43222Sbostic if(i == WL) 1776*43222Sbostic { 1777*43222Sbostic p2word(w.word); 1778*43222Sbostic w.word = 0; 1779*43222Sbostic i = 0; 1780*43222Sbostic } 1781*43222Sbostic if(i > 0) 1782*43222Sbostic p2word(w.word); 1783*43222Sbostic #else 1784*43222Sbostic /* standard intermediate, names are 8 characters long */ 1785*43222Sbostic 1786*43222Sbostic union { long int word[2]; char str[8]; } u; 1787*43222Sbostic 1788*43222Sbostic u.word[0] = u.word[1] = 0; 1789*43222Sbostic for(i = 0 ; i<8 && *s ; ++i) 1790*43222Sbostic u.str[i] = *s++; 1791*43222Sbostic p2word(u.word[0]); 1792*43222Sbostic p2word(u.word[1]); 1793*43222Sbostic 1794*43222Sbostic #endif 1795*43222Sbostic 1796*43222Sbostic } 1797*43222Sbostic 1798*43222Sbostic 1799*43222Sbostic 1800*43222Sbostic 1801*43222Sbostic p2word(w) 1802*43222Sbostic long int w; 1803*43222Sbostic { 1804*43222Sbostic *p2bufp++ = w; 1805*43222Sbostic if(p2bufp >= p2bufend) 1806*43222Sbostic p2flush(); 1807*43222Sbostic } 1808*43222Sbostic 1809*43222Sbostic 1810*43222Sbostic 1811*43222Sbostic p2flush() 1812*43222Sbostic { 1813*43222Sbostic if(p2bufp > p2buff) 1814*43222Sbostic write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int)); 1815*43222Sbostic p2bufp = p2buff; 1816*43222Sbostic } 1817*43222Sbostic 1818*43222Sbostic 1819*43222Sbostic 1820*43222Sbostic LOCAL 1821*43222Sbostic p2ldisp(offset, vname, type) 1822*43222Sbostic ftnint offset; 1823*43222Sbostic char *vname; 1824*43222Sbostic int type; 1825*43222Sbostic { 1826*43222Sbostic char buff[100]; 1827*43222Sbostic 1828*43222Sbostic sprintf(buff, "%s-v.%d", vname, bsslabel); 1829*43222Sbostic p2triple(PCC_OREG, LVARREG, type); 1830*43222Sbostic p2word(offset); 1831*43222Sbostic p2name(buff); 1832*43222Sbostic } 1833*43222Sbostic 1834*43222Sbostic 1835*43222Sbostic 1836*43222Sbostic p2ndisp(vname) 1837*43222Sbostic char *vname; 1838*43222Sbostic { 1839*43222Sbostic char buff[100]; 1840*43222Sbostic 1841*43222Sbostic sprintf(buff, "%s-v.%d", vname, bsslabel); 1842*43222Sbostic p2name(buff); 1843*43222Sbostic } 1844