1*43221Sbostic /* 2*43221Sbostic * Copyright (c) 1980 Regents of the University of California. 3*43221Sbostic * All rights reserved. The Berkeley software License Agreement 4*43221Sbostic * specifies the terms and conditions for redistribution. 5*43221Sbostic */ 6*43221Sbostic 7*43221Sbostic #ifndef lint 8*43221Sbostic static char sccsid[] = "@(#)put.c 5.1 (Berkeley) 6/7/85"; 9*43221Sbostic #endif not lint 10*43221Sbostic 11*43221Sbostic /* 12*43221Sbostic * put.c 13*43221Sbostic * 14*43221Sbostic * Intermediate code generation procedures common to both 15*43221Sbostic * Johnson (Portable) and Ritchie families of second passes 16*43221Sbostic * 17*43221Sbostic * University of Utah CS Dept modification history: 18*43221Sbostic * 19*43221Sbostic * $Log: put.c,v $ 20*43221Sbostic * Revision 3.2 85/05/04 15:41:24 mckusick 21*43221Sbostic * Fix alignment problem -- change code to match comment... 22*43221Sbostic * 23*43221Sbostic * Revision 3.2 85/04/29 21:36:07 donn 24*43221Sbostic * Fix alignment problem -- change code to match comment... 25*43221Sbostic * 26*43221Sbostic * Revision 3.1 85/02/27 19:12:04 donn 27*43221Sbostic * Changed to use pcc.h instead of pccdefs.h. 28*43221Sbostic * 29*43221Sbostic * Revision 2.1 84/07/19 12:04:21 donn 30*43221Sbostic * Changed comment headers for UofU. 31*43221Sbostic * 32*43221Sbostic * Revision 1.2 84/04/02 14:40:21 donn 33*43221Sbostic * Added fixes from Conrad Huang at UCSF for calculating the length of a 34*43221Sbostic * concatenation of strings correctly. 35*43221Sbostic * 36*43221Sbostic */ 37*43221Sbostic 38*43221Sbostic #include "defs.h" 39*43221Sbostic 40*43221Sbostic #if FAMILY == PCC 41*43221Sbostic # include <pcc.h> 42*43221Sbostic #else 43*43221Sbostic # include "dmrdefs.h" 44*43221Sbostic #endif 45*43221Sbostic 46*43221Sbostic /* 47*43221Sbostic char *ops [ ] = 48*43221Sbostic { 49*43221Sbostic "??", "+", "-", "*", "/", "**", "-", 50*43221Sbostic "OR", "AND", "EQV", "NEQV", "NOT", 51*43221Sbostic "CONCAT", 52*43221Sbostic "<", "==", ">", "<=", "!=", ">=", 53*43221Sbostic " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ", 54*43221Sbostic " , ", " ? ", " : " 55*43221Sbostic " abs ", " min ", " max ", " addr ", " indirect ", 56*43221Sbostic " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () " 57*43221Sbostic }; 58*43221Sbostic */ 59*43221Sbostic 60*43221Sbostic int ops2 [ ] = 61*43221Sbostic { 62*43221Sbostic PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS, 63*43221Sbostic PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT, 64*43221Sbostic PCC_ERROR, 65*43221Sbostic PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE, 66*43221Sbostic PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD, 67*43221Sbostic PCC_COMOP, PCC_QUEST, PCC_COLON, 68*43221Sbostic PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF, 69*43221Sbostic PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR 70*43221Sbostic }; 71*43221Sbostic 72*43221Sbostic 73*43221Sbostic int types2 [ ] = 74*43221Sbostic { 75*43221Sbostic PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE, 76*43221Sbostic #if TARGET == INTERDATA 77*43221Sbostic PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 78*43221Sbostic #else 79*43221Sbostic PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 80*43221Sbostic #endif 81*43221Sbostic }; 82*43221Sbostic 83*43221Sbostic 84*43221Sbostic setlog() 85*43221Sbostic { 86*43221Sbostic types2[TYLOGICAL] = types2[tylogical]; 87*43221Sbostic typesize[TYLOGICAL] = typesize[tylogical]; 88*43221Sbostic typealign[TYLOGICAL] = typealign[tylogical]; 89*43221Sbostic } 90*43221Sbostic 91*43221Sbostic 92*43221Sbostic putex1(p) 93*43221Sbostic expptr p; 94*43221Sbostic { 95*43221Sbostic putx( fixtype(p) ); 96*43221Sbostic 97*43221Sbostic if (!optimflag) 98*43221Sbostic { 99*43221Sbostic templist = hookup(templist, holdtemps); 100*43221Sbostic holdtemps = NULL; 101*43221Sbostic } 102*43221Sbostic } 103*43221Sbostic 104*43221Sbostic 105*43221Sbostic 106*43221Sbostic 107*43221Sbostic 108*43221Sbostic putassign(lp, rp) 109*43221Sbostic expptr lp, rp; 110*43221Sbostic { 111*43221Sbostic putx( fixexpr( mkexpr(OPASSIGN, lp, rp) )); 112*43221Sbostic } 113*43221Sbostic 114*43221Sbostic 115*43221Sbostic 116*43221Sbostic 117*43221Sbostic puteq(lp, rp) 118*43221Sbostic expptr lp, rp; 119*43221Sbostic { 120*43221Sbostic putexpr( mkexpr(OPASSIGN, lp, rp) ); 121*43221Sbostic } 122*43221Sbostic 123*43221Sbostic 124*43221Sbostic 125*43221Sbostic 126*43221Sbostic /* put code for a *= b */ 127*43221Sbostic 128*43221Sbostic putsteq(a, b) 129*43221Sbostic expptr a, b; 130*43221Sbostic { 131*43221Sbostic putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) )); 132*43221Sbostic } 133*43221Sbostic 134*43221Sbostic 135*43221Sbostic 136*43221Sbostic 137*43221Sbostic 138*43221Sbostic Addrp realpart(p) 139*43221Sbostic register Addrp p; 140*43221Sbostic { 141*43221Sbostic register Addrp q; 142*43221Sbostic 143*43221Sbostic q = (Addrp) cpexpr(p); 144*43221Sbostic if( ISCOMPLEX(p->vtype) ) 145*43221Sbostic q->vtype += (TYREAL-TYCOMPLEX); 146*43221Sbostic return(q); 147*43221Sbostic } 148*43221Sbostic 149*43221Sbostic 150*43221Sbostic 151*43221Sbostic 152*43221Sbostic expptr imagpart(p) 153*43221Sbostic register expptr p; 154*43221Sbostic { 155*43221Sbostic register Addrp q; 156*43221Sbostic expptr mkrealcon(); 157*43221Sbostic 158*43221Sbostic if (ISCONST(p)) 159*43221Sbostic { 160*43221Sbostic if (ISCOMPLEX(p->constblock.vtype)) 161*43221Sbostic return(mkrealcon(p->constblock.vtype == TYCOMPLEX ? 162*43221Sbostic TYREAL : TYDREAL, 163*43221Sbostic p->constblock.const.cd[1])); 164*43221Sbostic else if (p->constblock.vtype == TYDREAL) 165*43221Sbostic return(mkrealcon(TYDREAL, 0.0)); 166*43221Sbostic else 167*43221Sbostic return(mkrealcon(TYREAL, 0.0)); 168*43221Sbostic } 169*43221Sbostic else if (p->tag == TADDR) 170*43221Sbostic { 171*43221Sbostic if( ISCOMPLEX(p->addrblock.vtype) ) 172*43221Sbostic { 173*43221Sbostic q = (Addrp) cpexpr(p); 174*43221Sbostic q->vtype += (TYREAL-TYCOMPLEX); 175*43221Sbostic q->memoffset = mkexpr(OPPLUS, q->memoffset, 176*43221Sbostic ICON(typesize[q->vtype])); 177*43221Sbostic return( (expptr) q ); 178*43221Sbostic } 179*43221Sbostic else 180*43221Sbostic return( mkrealcon( ISINT(p->addrblock.vtype) ? 181*43221Sbostic TYDREAL : p->addrblock.vtype , 0.0)); 182*43221Sbostic } 183*43221Sbostic else 184*43221Sbostic badtag("imagpart", p->tag); 185*43221Sbostic } 186*43221Sbostic 187*43221Sbostic 188*43221Sbostic 189*43221Sbostic 190*43221Sbostic ncat(p) 191*43221Sbostic register expptr p; 192*43221Sbostic { 193*43221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 194*43221Sbostic return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) ); 195*43221Sbostic else return(1); 196*43221Sbostic } 197*43221Sbostic 198*43221Sbostic 199*43221Sbostic 200*43221Sbostic 201*43221Sbostic ftnint lencat(p) 202*43221Sbostic register expptr p; 203*43221Sbostic { 204*43221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 205*43221Sbostic return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) ); 206*43221Sbostic else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) ) 207*43221Sbostic return(p->headblock.vleng->constblock.const.ci); 208*43221Sbostic else if(p->tag==TADDR && p->addrblock.varleng!=0) 209*43221Sbostic return(p->addrblock.varleng); 210*43221Sbostic else if(p->tag==TTEMP && p->tempblock.varleng!=0) 211*43221Sbostic return(p->tempblock.varleng); 212*43221Sbostic else 213*43221Sbostic { 214*43221Sbostic err("impossible element in concatenation"); 215*43221Sbostic return(0); 216*43221Sbostic } 217*43221Sbostic } 218*43221Sbostic 219*43221Sbostic Addrp putconst(p) 220*43221Sbostic register Constp p; 221*43221Sbostic { 222*43221Sbostic register Addrp q; 223*43221Sbostic struct Literal *litp, *lastlit; 224*43221Sbostic int i, k, type; 225*43221Sbostic int litflavor; 226*43221Sbostic 227*43221Sbostic if( p->tag != TCONST ) 228*43221Sbostic badtag("putconst", p->tag); 229*43221Sbostic 230*43221Sbostic q = ALLOC(Addrblock); 231*43221Sbostic q->tag = TADDR; 232*43221Sbostic type = p->vtype; 233*43221Sbostic q->vtype = ( type==TYADDR ? TYINT : type ); 234*43221Sbostic q->vleng = (expptr) cpexpr(p->vleng); 235*43221Sbostic q->vstg = STGCONST; 236*43221Sbostic q->memno = newlabel(); 237*43221Sbostic q->memoffset = ICON(0); 238*43221Sbostic 239*43221Sbostic /* check for value in literal pool, and update pool if necessary */ 240*43221Sbostic 241*43221Sbostic switch(type = p->vtype) 242*43221Sbostic { 243*43221Sbostic case TYCHAR: 244*43221Sbostic if(p->vleng->constblock.const.ci > XL) 245*43221Sbostic break; /* too long for literal table */ 246*43221Sbostic litflavor = 1; 247*43221Sbostic goto loop; 248*43221Sbostic 249*43221Sbostic case TYREAL: 250*43221Sbostic case TYDREAL: 251*43221Sbostic litflavor = 2; 252*43221Sbostic goto loop; 253*43221Sbostic 254*43221Sbostic case TYLOGICAL: 255*43221Sbostic type = tylogical; 256*43221Sbostic case TYSHORT: 257*43221Sbostic case TYLONG: 258*43221Sbostic litflavor = 3; 259*43221Sbostic 260*43221Sbostic loop: 261*43221Sbostic lastlit = litpool + nliterals; 262*43221Sbostic for(litp = litpool ; litp<lastlit ; ++litp) 263*43221Sbostic if(type == litp->littype) switch(litflavor) 264*43221Sbostic { 265*43221Sbostic case 1: 266*43221Sbostic if(p->vleng->constblock.const.ci != litp->litval.litcval.litclen) 267*43221Sbostic break; 268*43221Sbostic if(! eqn( (int) p->vleng->constblock.const.ci, p->const.ccp, 269*43221Sbostic litp->litval.litcval.litcstr) ) 270*43221Sbostic break; 271*43221Sbostic 272*43221Sbostic ret: 273*43221Sbostic q->memno = litp->litnum; 274*43221Sbostic frexpr(p); 275*43221Sbostic return(q); 276*43221Sbostic 277*43221Sbostic case 2: 278*43221Sbostic if(p->const.cd[0] == litp->litval.litdval) 279*43221Sbostic goto ret; 280*43221Sbostic break; 281*43221Sbostic 282*43221Sbostic case 3: 283*43221Sbostic if(p->const.ci == litp->litval.litival) 284*43221Sbostic goto ret; 285*43221Sbostic break; 286*43221Sbostic } 287*43221Sbostic if(nliterals < MAXLITERALS) 288*43221Sbostic { 289*43221Sbostic ++nliterals; 290*43221Sbostic litp->littype = type; 291*43221Sbostic litp->litnum = q->memno; 292*43221Sbostic switch(litflavor) 293*43221Sbostic { 294*43221Sbostic case 1: 295*43221Sbostic litp->litval.litcval.litclen = 296*43221Sbostic p->vleng->constblock.const.ci; 297*43221Sbostic cpn( (int) litp->litval.litcval.litclen, 298*43221Sbostic p->const.ccp, 299*43221Sbostic litp->litval.litcval.litcstr); 300*43221Sbostic break; 301*43221Sbostic 302*43221Sbostic case 2: 303*43221Sbostic litp->litval.litdval = p->const.cd[0]; 304*43221Sbostic break; 305*43221Sbostic 306*43221Sbostic case 3: 307*43221Sbostic litp->litval.litival = p->const.ci; 308*43221Sbostic break; 309*43221Sbostic } 310*43221Sbostic } 311*43221Sbostic default: 312*43221Sbostic break; 313*43221Sbostic } 314*43221Sbostic 315*43221Sbostic preven(typealign[ type==TYCHAR ? TYLONG : type ]); 316*43221Sbostic prlabel(asmfile, q->memno); 317*43221Sbostic 318*43221Sbostic k = 1; 319*43221Sbostic switch(type) 320*43221Sbostic { 321*43221Sbostic case TYLOGICAL: 322*43221Sbostic case TYSHORT: 323*43221Sbostic case TYLONG: 324*43221Sbostic prconi(asmfile, type, p->const.ci); 325*43221Sbostic break; 326*43221Sbostic 327*43221Sbostic case TYCOMPLEX: 328*43221Sbostic k = 2; 329*43221Sbostic case TYREAL: 330*43221Sbostic type = TYREAL; 331*43221Sbostic goto flpt; 332*43221Sbostic 333*43221Sbostic case TYDCOMPLEX: 334*43221Sbostic k = 2; 335*43221Sbostic case TYDREAL: 336*43221Sbostic type = TYDREAL; 337*43221Sbostic 338*43221Sbostic flpt: 339*43221Sbostic for(i = 0 ; i < k ; ++i) 340*43221Sbostic prconr(asmfile, type, p->const.cd[i]); 341*43221Sbostic break; 342*43221Sbostic 343*43221Sbostic case TYCHAR: 344*43221Sbostic putstr(asmfile, p->const.ccp, 345*43221Sbostic (int) (p->vleng->constblock.const.ci) ); 346*43221Sbostic break; 347*43221Sbostic 348*43221Sbostic case TYADDR: 349*43221Sbostic prcona(asmfile, p->const.ci); 350*43221Sbostic break; 351*43221Sbostic 352*43221Sbostic default: 353*43221Sbostic badtype("putconst", p->vtype); 354*43221Sbostic } 355*43221Sbostic 356*43221Sbostic frexpr(p); 357*43221Sbostic return( q ); 358*43221Sbostic } 359*43221Sbostic 360*43221Sbostic /* 361*43221Sbostic * put out a character string constant. begin every one on 362*43221Sbostic * a long integer boundary, and pad with nulls 363*43221Sbostic */ 364*43221Sbostic putstr(fp, s, n) 365*43221Sbostic FILEP fp; 366*43221Sbostic register char *s; 367*43221Sbostic register int n; 368*43221Sbostic { 369*43221Sbostic int b[SZLONG]; 370*43221Sbostic register int i; 371*43221Sbostic 372*43221Sbostic i = 0; 373*43221Sbostic while(--n >= 0) 374*43221Sbostic { 375*43221Sbostic b[i++] = *s++; 376*43221Sbostic if(i == SZLONG) 377*43221Sbostic { 378*43221Sbostic prchars(fp, b); 379*43221Sbostic prchars(fp, b+SZSHORT); 380*43221Sbostic i = 0; 381*43221Sbostic } 382*43221Sbostic } 383*43221Sbostic 384*43221Sbostic while(i < SZLONG) 385*43221Sbostic b[i++] = '\0'; 386*43221Sbostic prchars(fp, b); 387*43221Sbostic prchars(fp, b+SZSHORT); 388*43221Sbostic } 389