122864Smckusick /* 222864Smckusick * Copyright (c) 1980 Regents of the University of California. 322864Smckusick * All rights reserved. The Berkeley software License Agreement 422864Smckusick * specifies the terms and conditions for redistribution. 522864Smckusick */ 622864Smckusick 722864Smckusick #ifndef lint 8*33257Sbostic static char sccsid[] = "@(#)put.c 5.2 (Berkeley) 01/03/88"; 922864Smckusick #endif not lint 1022864Smckusick 1122864Smckusick /* 1222864Smckusick * put.c 1322864Smckusick * 1422864Smckusick * Intermediate code generation procedures common to both 1522864Smckusick * Johnson (Portable) and Ritchie families of second passes 1622864Smckusick * 1722864Smckusick * University of Utah CS Dept modification history: 1822864Smckusick * 1922864Smckusick * $Log: put.c,v $ 2022864Smckusick * Revision 3.2 85/05/04 15:41:24 mckusick 2122864Smckusick * Fix alignment problem -- change code to match comment... 2222864Smckusick * 2322864Smckusick * Revision 3.2 85/04/29 21:36:07 donn 2422864Smckusick * Fix alignment problem -- change code to match comment... 2522864Smckusick * 2622864Smckusick * Revision 3.1 85/02/27 19:12:04 donn 2722864Smckusick * Changed to use pcc.h instead of pccdefs.h. 2822864Smckusick * 2922864Smckusick * Revision 2.1 84/07/19 12:04:21 donn 3022864Smckusick * Changed comment headers for UofU. 3122864Smckusick * 3222864Smckusick * Revision 1.2 84/04/02 14:40:21 donn 3322864Smckusick * Added fixes from Conrad Huang at UCSF for calculating the length of a 3422864Smckusick * concatenation of strings correctly. 3522864Smckusick * 3622864Smckusick */ 3722864Smckusick 3822864Smckusick #include "defs.h" 3922864Smckusick 4022864Smckusick #if FAMILY == PCC 4122864Smckusick # include <pcc.h> 4222864Smckusick #else 4322864Smckusick # include "dmrdefs.h" 4422864Smckusick #endif 4522864Smckusick 4622864Smckusick /* 4722864Smckusick char *ops [ ] = 4822864Smckusick { 4922864Smckusick "??", "+", "-", "*", "/", "**", "-", 5022864Smckusick "OR", "AND", "EQV", "NEQV", "NOT", 5122864Smckusick "CONCAT", 5222864Smckusick "<", "==", ">", "<=", "!=", ">=", 5322864Smckusick " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ", 5422864Smckusick " , ", " ? ", " : " 5522864Smckusick " abs ", " min ", " max ", " addr ", " indirect ", 5622864Smckusick " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () " 5722864Smckusick }; 5822864Smckusick */ 5922864Smckusick 6022864Smckusick int ops2 [ ] = 6122864Smckusick { 6222864Smckusick PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS, 6322864Smckusick PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT, 6422864Smckusick PCC_ERROR, 6522864Smckusick PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE, 6622864Smckusick PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD, 6722864Smckusick PCC_COMOP, PCC_QUEST, PCC_COLON, 6822864Smckusick PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF, 6922864Smckusick PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR 7022864Smckusick }; 7122864Smckusick 7222864Smckusick 7322864Smckusick int types2 [ ] = 7422864Smckusick { 7522864Smckusick PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE, 7622864Smckusick #if TARGET == INTERDATA 7722864Smckusick PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 7822864Smckusick #else 7922864Smckusick PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR 8022864Smckusick #endif 8122864Smckusick }; 8222864Smckusick 8322864Smckusick 8422864Smckusick setlog() 8522864Smckusick { 8622864Smckusick types2[TYLOGICAL] = types2[tylogical]; 8722864Smckusick typesize[TYLOGICAL] = typesize[tylogical]; 8822864Smckusick typealign[TYLOGICAL] = typealign[tylogical]; 8922864Smckusick } 9022864Smckusick 9122864Smckusick 9222864Smckusick putex1(p) 9322864Smckusick expptr p; 9422864Smckusick { 9522864Smckusick putx( fixtype(p) ); 9622864Smckusick 9722864Smckusick if (!optimflag) 9822864Smckusick { 9922864Smckusick templist = hookup(templist, holdtemps); 10022864Smckusick holdtemps = NULL; 10122864Smckusick } 10222864Smckusick } 10322864Smckusick 10422864Smckusick 10522864Smckusick 10622864Smckusick 10722864Smckusick 10822864Smckusick putassign(lp, rp) 10922864Smckusick expptr lp, rp; 11022864Smckusick { 11122864Smckusick putx( fixexpr( mkexpr(OPASSIGN, lp, rp) )); 11222864Smckusick } 11322864Smckusick 11422864Smckusick 11522864Smckusick 11622864Smckusick 11722864Smckusick puteq(lp, rp) 11822864Smckusick expptr lp, rp; 11922864Smckusick { 12022864Smckusick putexpr( mkexpr(OPASSIGN, lp, rp) ); 12122864Smckusick } 12222864Smckusick 12322864Smckusick 12422864Smckusick 12522864Smckusick 12622864Smckusick /* put code for a *= b */ 12722864Smckusick 12822864Smckusick putsteq(a, b) 12922864Smckusick expptr a, b; 13022864Smckusick { 13122864Smckusick putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) )); 13222864Smckusick } 13322864Smckusick 13422864Smckusick 13522864Smckusick 13622864Smckusick 13722864Smckusick 13822864Smckusick Addrp realpart(p) 13922864Smckusick register Addrp p; 14022864Smckusick { 14122864Smckusick register Addrp q; 14222864Smckusick 14322864Smckusick q = (Addrp) cpexpr(p); 14422864Smckusick if( ISCOMPLEX(p->vtype) ) 14522864Smckusick q->vtype += (TYREAL-TYCOMPLEX); 14622864Smckusick return(q); 14722864Smckusick } 14822864Smckusick 14922864Smckusick 15022864Smckusick 15122864Smckusick 15222864Smckusick expptr imagpart(p) 15322864Smckusick register expptr p; 15422864Smckusick { 15522864Smckusick register Addrp q; 15622864Smckusick expptr mkrealcon(); 15722864Smckusick 15822864Smckusick if (ISCONST(p)) 15922864Smckusick { 16022864Smckusick if (ISCOMPLEX(p->constblock.vtype)) 16122864Smckusick return(mkrealcon(p->constblock.vtype == TYCOMPLEX ? 16222864Smckusick TYREAL : TYDREAL, 163*33257Sbostic p->constblock.constant.cd[1])); 16422864Smckusick else if (p->constblock.vtype == TYDREAL) 16522864Smckusick return(mkrealcon(TYDREAL, 0.0)); 16622864Smckusick else 16722864Smckusick return(mkrealcon(TYREAL, 0.0)); 16822864Smckusick } 16922864Smckusick else if (p->tag == TADDR) 17022864Smckusick { 17122864Smckusick if( ISCOMPLEX(p->addrblock.vtype) ) 17222864Smckusick { 17322864Smckusick q = (Addrp) cpexpr(p); 17422864Smckusick q->vtype += (TYREAL-TYCOMPLEX); 17522864Smckusick q->memoffset = mkexpr(OPPLUS, q->memoffset, 17622864Smckusick ICON(typesize[q->vtype])); 17722864Smckusick return( (expptr) q ); 17822864Smckusick } 17922864Smckusick else 18022864Smckusick return( mkrealcon( ISINT(p->addrblock.vtype) ? 18122864Smckusick TYDREAL : p->addrblock.vtype , 0.0)); 18222864Smckusick } 18322864Smckusick else 18422864Smckusick badtag("imagpart", p->tag); 18522864Smckusick } 18622864Smckusick 18722864Smckusick 18822864Smckusick 18922864Smckusick 19022864Smckusick ncat(p) 19122864Smckusick register expptr p; 19222864Smckusick { 19322864Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 19422864Smckusick return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) ); 19522864Smckusick else return(1); 19622864Smckusick } 19722864Smckusick 19822864Smckusick 19922864Smckusick 20022864Smckusick 20122864Smckusick ftnint lencat(p) 20222864Smckusick register expptr p; 20322864Smckusick { 20422864Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT) 20522864Smckusick return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) ); 20622864Smckusick else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) ) 207*33257Sbostic return(p->headblock.vleng->constblock.constant.ci); 20822864Smckusick else if(p->tag==TADDR && p->addrblock.varleng!=0) 20922864Smckusick return(p->addrblock.varleng); 21022864Smckusick else if(p->tag==TTEMP && p->tempblock.varleng!=0) 21122864Smckusick return(p->tempblock.varleng); 21222864Smckusick else 21322864Smckusick { 21422864Smckusick err("impossible element in concatenation"); 21522864Smckusick return(0); 21622864Smckusick } 21722864Smckusick } 21822864Smckusick 21922864Smckusick Addrp putconst(p) 22022864Smckusick register Constp p; 22122864Smckusick { 22222864Smckusick register Addrp q; 22322864Smckusick struct Literal *litp, *lastlit; 22422864Smckusick int i, k, type; 22522864Smckusick int litflavor; 22622864Smckusick 22722864Smckusick if( p->tag != TCONST ) 22822864Smckusick badtag("putconst", p->tag); 22922864Smckusick 23022864Smckusick q = ALLOC(Addrblock); 23122864Smckusick q->tag = TADDR; 23222864Smckusick type = p->vtype; 23322864Smckusick q->vtype = ( type==TYADDR ? TYINT : type ); 23422864Smckusick q->vleng = (expptr) cpexpr(p->vleng); 23522864Smckusick q->vstg = STGCONST; 23622864Smckusick q->memno = newlabel(); 23722864Smckusick q->memoffset = ICON(0); 23822864Smckusick 23922864Smckusick /* check for value in literal pool, and update pool if necessary */ 24022864Smckusick 24122864Smckusick switch(type = p->vtype) 24222864Smckusick { 24322864Smckusick case TYCHAR: 244*33257Sbostic if(p->vleng->constblock.constant.ci > XL) 24522864Smckusick break; /* too long for literal table */ 24622864Smckusick litflavor = 1; 24722864Smckusick goto loop; 24822864Smckusick 24922864Smckusick case TYREAL: 25022864Smckusick case TYDREAL: 25122864Smckusick litflavor = 2; 25222864Smckusick goto loop; 25322864Smckusick 25422864Smckusick case TYLOGICAL: 25522864Smckusick type = tylogical; 25622864Smckusick case TYSHORT: 25722864Smckusick case TYLONG: 25822864Smckusick litflavor = 3; 25922864Smckusick 26022864Smckusick loop: 26122864Smckusick lastlit = litpool + nliterals; 26222864Smckusick for(litp = litpool ; litp<lastlit ; ++litp) 26322864Smckusick if(type == litp->littype) switch(litflavor) 26422864Smckusick { 26522864Smckusick case 1: 266*33257Sbostic if(p->vleng->constblock.constant.ci != litp->litval.litcval.litclen) 26722864Smckusick break; 268*33257Sbostic if(! eqn( (int) p->vleng->constblock.constant.ci, p->constant.ccp, 26922864Smckusick litp->litval.litcval.litcstr) ) 27022864Smckusick break; 27122864Smckusick 27222864Smckusick ret: 27322864Smckusick q->memno = litp->litnum; 27422864Smckusick frexpr(p); 27522864Smckusick return(q); 27622864Smckusick 27722864Smckusick case 2: 278*33257Sbostic if(p->constant.cd[0] == litp->litval.litdval) 27922864Smckusick goto ret; 28022864Smckusick break; 28122864Smckusick 28222864Smckusick case 3: 283*33257Sbostic if(p->constant.ci == litp->litval.litival) 28422864Smckusick goto ret; 28522864Smckusick break; 28622864Smckusick } 28722864Smckusick if(nliterals < MAXLITERALS) 28822864Smckusick { 28922864Smckusick ++nliterals; 29022864Smckusick litp->littype = type; 29122864Smckusick litp->litnum = q->memno; 29222864Smckusick switch(litflavor) 29322864Smckusick { 29422864Smckusick case 1: 29522864Smckusick litp->litval.litcval.litclen = 296*33257Sbostic p->vleng->constblock.constant.ci; 29722864Smckusick cpn( (int) litp->litval.litcval.litclen, 298*33257Sbostic p->constant.ccp, 29922864Smckusick litp->litval.litcval.litcstr); 30022864Smckusick break; 30122864Smckusick 30222864Smckusick case 2: 303*33257Sbostic litp->litval.litdval = p->constant.cd[0]; 30422864Smckusick break; 30522864Smckusick 30622864Smckusick case 3: 307*33257Sbostic litp->litval.litival = p->constant.ci; 30822864Smckusick break; 30922864Smckusick } 31022864Smckusick } 31122864Smckusick default: 31222864Smckusick break; 31322864Smckusick } 31422864Smckusick 31522864Smckusick preven(typealign[ type==TYCHAR ? TYLONG : type ]); 31622864Smckusick prlabel(asmfile, q->memno); 31722864Smckusick 31822864Smckusick k = 1; 31922864Smckusick switch(type) 32022864Smckusick { 32122864Smckusick case TYLOGICAL: 32222864Smckusick case TYSHORT: 32322864Smckusick case TYLONG: 324*33257Sbostic prconi(asmfile, type, p->constant.ci); 32522864Smckusick break; 32622864Smckusick 32722864Smckusick case TYCOMPLEX: 32822864Smckusick k = 2; 32922864Smckusick case TYREAL: 33022864Smckusick type = TYREAL; 33122864Smckusick goto flpt; 33222864Smckusick 33322864Smckusick case TYDCOMPLEX: 33422864Smckusick k = 2; 33522864Smckusick case TYDREAL: 33622864Smckusick type = TYDREAL; 33722864Smckusick 33822864Smckusick flpt: 33922864Smckusick for(i = 0 ; i < k ; ++i) 340*33257Sbostic prconr(asmfile, type, p->constant.cd[i]); 34122864Smckusick break; 34222864Smckusick 34322864Smckusick case TYCHAR: 344*33257Sbostic putstr(asmfile, p->constant.ccp, 345*33257Sbostic (int) (p->vleng->constblock.constant.ci) ); 34622864Smckusick break; 34722864Smckusick 34822864Smckusick case TYADDR: 349*33257Sbostic prcona(asmfile, p->constant.ci); 35022864Smckusick break; 35122864Smckusick 35222864Smckusick default: 35322864Smckusick badtype("putconst", p->vtype); 35422864Smckusick } 35522864Smckusick 35622864Smckusick frexpr(p); 35722864Smckusick return( q ); 35822864Smckusick } 35922864Smckusick 36022864Smckusick /* 36122864Smckusick * put out a character string constant. begin every one on 36222864Smckusick * a long integer boundary, and pad with nulls 36322864Smckusick */ 36422864Smckusick putstr(fp, s, n) 36522864Smckusick FILEP fp; 36622864Smckusick register char *s; 36722864Smckusick register int n; 36822864Smckusick { 36922864Smckusick int b[SZLONG]; 37022864Smckusick register int i; 37122864Smckusick 37222864Smckusick i = 0; 37322864Smckusick while(--n >= 0) 37422864Smckusick { 37522864Smckusick b[i++] = *s++; 37622864Smckusick if(i == SZLONG) 37722864Smckusick { 37822864Smckusick prchars(fp, b); 37922864Smckusick prchars(fp, b+SZSHORT); 38022864Smckusick i = 0; 38122864Smckusick } 38222864Smckusick } 38322864Smckusick 38422864Smckusick while(i < SZLONG) 38522864Smckusick b[i++] = '\0'; 38622864Smckusick prchars(fp, b); 38722864Smckusick prchars(fp, b+SZSHORT); 38822864Smckusick } 389