143221Sbostic /* 243221Sbostic * Copyright (c) 1980 Regents of the University of California. 343221Sbostic * All rights reserved. The Berkeley software License Agreement 443221Sbostic * specifies the terms and conditions for redistribution. 543221Sbostic */ 643221Sbostic 743221Sbostic #ifndef lint 843221Sbostic static char sccsid[] = "@(#)put.c 5.1 (Berkeley) 6/7/85"; 943221Sbostic #endif not lint 1043221Sbostic 1143221Sbostic /* 1243221Sbostic * put.c 1343221Sbostic * 1443221Sbostic * Intermediate code generation procedures common to both 1543221Sbostic * Johnson (Portable) and Ritchie families of second passes 1643221Sbostic * 1743221Sbostic * University of Utah CS Dept modification history: 1843221Sbostic * 1943221Sbostic * $Log: put.c,v $ 2043221Sbostic * Revision 3.2 85/05/04 15:41:24 mckusick 2143221Sbostic * Fix alignment problem -- change code to match comment... 2243221Sbostic * 2343221Sbostic * Revision 3.2 85/04/29 21:36:07 donn 2443221Sbostic * Fix alignment problem -- change code to match comment... 2543221Sbostic * 2643221Sbostic * Revision 3.1 85/02/27 19:12:04 donn 2743221Sbostic * Changed to use pcc.h instead of pccdefs.h. 2843221Sbostic * 2943221Sbostic * Revision 2.1 84/07/19 12:04:21 donn 3043221Sbostic * Changed comment headers for UofU. 3143221Sbostic * 3243221Sbostic * Revision 1.2 84/04/02 14:40:21 donn 3343221Sbostic * Added fixes from Conrad Huang at UCSF for calculating the length of a 3443221Sbostic * concatenation of strings correctly. 3543221Sbostic * 3643221Sbostic */ 3743221Sbostic 3843221Sbostic #include "defs.h" 3943221Sbostic 4043221Sbostic #if FAMILY == PCC 4143221Sbostic # include <pcc.h> 4243221Sbostic #else 4343221Sbostic # include "dmrdefs.h" 4443221Sbostic #endif 4543221Sbostic 4643221Sbostic /* 4743221Sbostic char *ops [ ] = 4843221Sbostic { 4943221Sbostic "??", "+", "-", "*", "/", "**", "-", 5043221Sbostic "OR", "AND", "EQV", "NEQV", "NOT", 5143221Sbostic "CONCAT", 5243221Sbostic "<", "==", ">", "<=", "!=", ">=", 5343221Sbostic " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ", 5443221Sbostic " , ", " ? ", " : " 5543221Sbostic " abs ", " min ", " max ", " addr ", " indirect ", 5643221Sbostic " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () " 5743221Sbostic }; 5843221Sbostic */ 5943221Sbostic 6043221Sbostic int ops2 [ ] = 6143221Sbostic { 6243221Sbostic PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS, 6343221Sbostic PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT, 6443221Sbostic PCC_ERROR, 6543221Sbostic PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE, 6643221Sbostic PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD, 6743221Sbostic PCC_COMOP, PCC_QUEST, PCC_COLON, 6843221Sbostic PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF, 6943221Sbostic PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR 7043221Sbostic }; 7143221Sbostic 7243221Sbostic 7343221Sbostic int types2 [ ] = 7443221Sbostic { 7543221Sbostic PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE, 7643221Sbostic #if TARGET == INTERDATA 7743221Sbostic PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 7843221Sbostic #else 7943221Sbostic PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 8043221Sbostic #endif 8143221Sbostic }; 8243221Sbostic 8343221Sbostic 8443221Sbostic setlog() 8543221Sbostic { 8643221Sbostic types2[TYLOGICAL] = types2[tylogical]; 8743221Sbostic typesize[TYLOGICAL] = typesize[tylogical]; 8843221Sbostic typealign[TYLOGICAL] = typealign[tylogical]; 8943221Sbostic } 9043221Sbostic 9143221Sbostic 9243221Sbostic putex1(p) 9343221Sbostic expptr p; 9443221Sbostic { 9543221Sbostic putx( fixtype(p) ); 9643221Sbostic 9743221Sbostic if (!optimflag) 9843221Sbostic { 9943221Sbostic templist = hookup(templist, holdtemps); 10043221Sbostic holdtemps = NULL; 10143221Sbostic } 10243221Sbostic } 10343221Sbostic 10443221Sbostic 10543221Sbostic 10643221Sbostic 10743221Sbostic 10843221Sbostic putassign(lp, rp) 10943221Sbostic expptr lp, rp; 11043221Sbostic { 11143221Sbostic putx( fixexpr( mkexpr(OPASSIGN, lp, rp) )); 11243221Sbostic } 11343221Sbostic 11443221Sbostic 11543221Sbostic 11643221Sbostic 11743221Sbostic puteq(lp, rp) 11843221Sbostic expptr lp, rp; 11943221Sbostic { 12043221Sbostic putexpr( mkexpr(OPASSIGN, lp, rp) ); 12143221Sbostic } 12243221Sbostic 12343221Sbostic 12443221Sbostic 12543221Sbostic 12643221Sbostic /* put code for a *= b */ 12743221Sbostic 12843221Sbostic putsteq(a, b) 12943221Sbostic expptr a, b; 13043221Sbostic { 13143221Sbostic putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) )); 13243221Sbostic } 13343221Sbostic 13443221Sbostic 13543221Sbostic 13643221Sbostic 13743221Sbostic 13843221Sbostic Addrp realpart(p) 13943221Sbostic register Addrp p; 14043221Sbostic { 14143221Sbostic register Addrp q; 14243221Sbostic 14343221Sbostic q = (Addrp) cpexpr(p); 14443221Sbostic if( ISCOMPLEX(p->vtype) ) 14543221Sbostic q->vtype += (TYREAL-TYCOMPLEX); 14643221Sbostic return(q); 14743221Sbostic } 14843221Sbostic 14943221Sbostic 15043221Sbostic 15143221Sbostic 15243221Sbostic expptr imagpart(p) 15343221Sbostic register expptr p; 15443221Sbostic { 15543221Sbostic register Addrp q; 15643221Sbostic expptr mkrealcon(); 15743221Sbostic 15843221Sbostic if (ISCONST(p)) 15943221Sbostic { 16043221Sbostic if (ISCOMPLEX(p->constblock.vtype)) 16143221Sbostic return(mkrealcon(p->constblock.vtype == TYCOMPLEX ? 16243221Sbostic TYREAL : TYDREAL, 163*46306Sbostic p->constblock.constant.cd[1])); 16443221Sbostic else if (p->constblock.vtype == TYDREAL) 16543221Sbostic return(mkrealcon(TYDREAL, 0.0)); 16643221Sbostic else 16743221Sbostic return(mkrealcon(TYREAL, 0.0)); 16843221Sbostic } 16943221Sbostic else if (p->tag == TADDR) 17043221Sbostic { 17143221Sbostic if( ISCOMPLEX(p->addrblock.vtype) ) 17243221Sbostic { 17343221Sbostic q = (Addrp) cpexpr(p); 17443221Sbostic q->vtype += (TYREAL-TYCOMPLEX); 17543221Sbostic q->memoffset = mkexpr(OPPLUS, q->memoffset, 17643221Sbostic ICON(typesize[q->vtype])); 17743221Sbostic return( (expptr) q ); 17843221Sbostic } 17943221Sbostic else 18043221Sbostic return( mkrealcon( ISINT(p->addrblock.vtype) ? 18143221Sbostic TYDREAL : p->addrblock.vtype , 0.0)); 18243221Sbostic } 18343221Sbostic else 18443221Sbostic badtag("imagpart", p->tag); 18543221Sbostic } 18643221Sbostic 18743221Sbostic 18843221Sbostic 18943221Sbostic 19043221Sbostic ncat(p) 19143221Sbostic register expptr p; 19243221Sbostic { 19343221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 19443221Sbostic return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) ); 19543221Sbostic else return(1); 19643221Sbostic } 19743221Sbostic 19843221Sbostic 19943221Sbostic 20043221Sbostic 20143221Sbostic ftnint lencat(p) 20243221Sbostic register expptr p; 20343221Sbostic { 20443221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 20543221Sbostic return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) ); 20643221Sbostic else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) ) 207*46306Sbostic return(p->headblock.vleng->constblock.constant.ci); 20843221Sbostic else if(p->tag==TADDR && p->addrblock.varleng!=0) 20943221Sbostic return(p->addrblock.varleng); 21043221Sbostic else if(p->tag==TTEMP && p->tempblock.varleng!=0) 21143221Sbostic return(p->tempblock.varleng); 21243221Sbostic else 21343221Sbostic { 21443221Sbostic err("impossible element in concatenation"); 21543221Sbostic return(0); 21643221Sbostic } 21743221Sbostic } 21843221Sbostic 21943221Sbostic Addrp putconst(p) 22043221Sbostic register Constp p; 22143221Sbostic { 22243221Sbostic register Addrp q; 22343221Sbostic struct Literal *litp, *lastlit; 22443221Sbostic int i, k, type; 22543221Sbostic int litflavor; 22643221Sbostic 22743221Sbostic if( p->tag != TCONST ) 22843221Sbostic badtag("putconst", p->tag); 22943221Sbostic 23043221Sbostic q = ALLOC(Addrblock); 23143221Sbostic q->tag = TADDR; 23243221Sbostic type = p->vtype; 23343221Sbostic q->vtype = ( type==TYADDR ? TYINT : type ); 23443221Sbostic q->vleng = (expptr) cpexpr(p->vleng); 23543221Sbostic q->vstg = STGCONST; 23643221Sbostic q->memno = newlabel(); 23743221Sbostic q->memoffset = ICON(0); 23843221Sbostic 23943221Sbostic /* check for value in literal pool, and update pool if necessary */ 24043221Sbostic 24143221Sbostic switch(type = p->vtype) 24243221Sbostic { 24343221Sbostic case TYCHAR: 244*46306Sbostic if(p->vleng->constblock.constant.ci > XL) 24543221Sbostic break; /* too long for literal table */ 24643221Sbostic litflavor = 1; 24743221Sbostic goto loop; 24843221Sbostic 24943221Sbostic case TYREAL: 25043221Sbostic case TYDREAL: 25143221Sbostic litflavor = 2; 25243221Sbostic goto loop; 25343221Sbostic 25443221Sbostic case TYLOGICAL: 25543221Sbostic type = tylogical; 25643221Sbostic case TYSHORT: 25743221Sbostic case TYLONG: 25843221Sbostic litflavor = 3; 25943221Sbostic 26043221Sbostic loop: 26143221Sbostic lastlit = litpool + nliterals; 26243221Sbostic for(litp = litpool ; litp<lastlit ; ++litp) 26343221Sbostic if(type == litp->littype) switch(litflavor) 26443221Sbostic { 26543221Sbostic case 1: 266*46306Sbostic if(p->vleng->constblock.constant.ci != litp->litval.litcval.litclen) 26743221Sbostic break; 268*46306Sbostic if(! eqn( (int) p->vleng->constblock.constant.ci, p->constant.ccp, 26943221Sbostic litp->litval.litcval.litcstr) ) 27043221Sbostic break; 27143221Sbostic 27243221Sbostic ret: 27343221Sbostic q->memno = litp->litnum; 27443221Sbostic frexpr(p); 27543221Sbostic return(q); 27643221Sbostic 27743221Sbostic case 2: 278*46306Sbostic if(p->constant.cd[0] == litp->litval.litdval) 27943221Sbostic goto ret; 28043221Sbostic break; 28143221Sbostic 28243221Sbostic case 3: 283*46306Sbostic if(p->constant.ci == litp->litval.litival) 28443221Sbostic goto ret; 28543221Sbostic break; 28643221Sbostic } 28743221Sbostic if(nliterals < MAXLITERALS) 28843221Sbostic { 28943221Sbostic ++nliterals; 29043221Sbostic litp->littype = type; 29143221Sbostic litp->litnum = q->memno; 29243221Sbostic switch(litflavor) 29343221Sbostic { 29443221Sbostic case 1: 29543221Sbostic litp->litval.litcval.litclen = 296*46306Sbostic p->vleng->constblock.constant.ci; 29743221Sbostic cpn( (int) litp->litval.litcval.litclen, 298*46306Sbostic p->constant.ccp, 29943221Sbostic litp->litval.litcval.litcstr); 30043221Sbostic break; 30143221Sbostic 30243221Sbostic case 2: 303*46306Sbostic litp->litval.litdval = p->constant.cd[0]; 30443221Sbostic break; 30543221Sbostic 30643221Sbostic case 3: 307*46306Sbostic litp->litval.litival = p->constant.ci; 30843221Sbostic break; 30943221Sbostic } 31043221Sbostic } 31143221Sbostic default: 31243221Sbostic break; 31343221Sbostic } 31443221Sbostic 31543221Sbostic preven(typealign[ type==TYCHAR ? TYLONG : type ]); 31643221Sbostic prlabel(asmfile, q->memno); 31743221Sbostic 31843221Sbostic k = 1; 31943221Sbostic switch(type) 32043221Sbostic { 32143221Sbostic case TYLOGICAL: 32243221Sbostic case TYSHORT: 32343221Sbostic case TYLONG: 324*46306Sbostic prconi(asmfile, type, p->constant.ci); 32543221Sbostic break; 32643221Sbostic 32743221Sbostic case TYCOMPLEX: 32843221Sbostic k = 2; 32943221Sbostic case TYREAL: 33043221Sbostic type = TYREAL; 33143221Sbostic goto flpt; 33243221Sbostic 33343221Sbostic case TYDCOMPLEX: 33443221Sbostic k = 2; 33543221Sbostic case TYDREAL: 33643221Sbostic type = TYDREAL; 33743221Sbostic 33843221Sbostic flpt: 33943221Sbostic for(i = 0 ; i < k ; ++i) 340*46306Sbostic prconr(asmfile, type, p->constant.cd[i]); 34143221Sbostic break; 34243221Sbostic 34343221Sbostic case TYCHAR: 344*46306Sbostic putstr(asmfile, p->constant.ccp, 345*46306Sbostic (int) (p->vleng->constblock.constant.ci) ); 34643221Sbostic break; 34743221Sbostic 34843221Sbostic case TYADDR: 349*46306Sbostic prcona(asmfile, p->constant.ci); 35043221Sbostic break; 35143221Sbostic 35243221Sbostic default: 35343221Sbostic badtype("putconst", p->vtype); 35443221Sbostic } 35543221Sbostic 35643221Sbostic frexpr(p); 35743221Sbostic return( q ); 35843221Sbostic } 35943221Sbostic 36043221Sbostic /* 36143221Sbostic * put out a character string constant. begin every one on 36243221Sbostic * a long integer boundary, and pad with nulls 36343221Sbostic */ 36443221Sbostic putstr(fp, s, n) 36543221Sbostic FILEP fp; 36643221Sbostic register char *s; 36743221Sbostic register int n; 36843221Sbostic { 36943221Sbostic int b[SZLONG]; 37043221Sbostic register int i; 37143221Sbostic 37243221Sbostic i = 0; 37343221Sbostic while(--n >= 0) 37443221Sbostic { 37543221Sbostic b[i++] = *s++; 37643221Sbostic if(i == SZLONG) 37743221Sbostic { 37843221Sbostic prchars(fp, b); 37943221Sbostic prchars(fp, b+SZSHORT); 38043221Sbostic i = 0; 38143221Sbostic } 38243221Sbostic } 38343221Sbostic 38443221Sbostic while(i < SZLONG) 38543221Sbostic b[i++] = '\0'; 38643221Sbostic prchars(fp, b); 38743221Sbostic prchars(fp, b+SZSHORT); 38843221Sbostic } 389