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