put.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990-1991, 1993-1994, 1996, 2000-2001 by AT&T, Lucent Technologies and Bellcore.
00003 
00004 Permission to use, copy, modify, and distribute this software
00005 and its documentation for any purpose and without fee is hereby
00006 granted, provided that the above copyright notice appear in all
00007 copies and that both that the copyright notice and this
00008 permission notice and warranty disclaimer appear in supporting
00009 documentation, and that the names of AT&T, Bell Laboratories,
00010 Lucent or Bellcore or any of their entities not be used in
00011 advertising or publicity pertaining to distribution of the
00012 software without specific, written prior permission.
00013 
00014 AT&T, Lucent and Bellcore disclaim all warranties with regard to
00015 this software, including all implied warranties of
00016 merchantability and fitness.  In no event shall AT&T, Lucent or
00017 Bellcore be liable for any special, indirect or consequential
00018 damages or any damages whatsoever resulting from loss of use,
00019 data or profits, whether in an action of contract, negligence or
00020 other tortious action, arising out of or in connection with the
00021 use or performance of this software.
00022 ****************************************************************/
00023 
00024 /*
00025  * INTERMEDIATE CODE GENERATION PROCEDURES COMMON TO BOTH
00026  * JOHNSON (PORTABLE) AND RITCHIE FAMILIES OF SECOND PASSES
00027 */
00028 
00029 #include "defs.h"
00030 #include "names.h"              /* For LOCAL_CONST_NAME */
00031 #include "pccdefs.h"
00032 #include "p1defs.h"
00033 
00034 /* Definitions for   putconst()   */
00035 
00036 #define LIT_CHAR 1
00037 #define LIT_FLOAT 2
00038 #define LIT_INT 3
00039 #define LIT_INTQ 4
00040 
00041 
00042 /*
00043 char *ops [ ] =
00044         {
00045         "??", "+", "-", "*", "/", "**", "-",
00046         "OR", "AND", "EQV", "NEQV", "NOT",
00047         "CONCAT",
00048         "<", "==", ">", "<=", "!=", ">=",
00049         " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
00050         " , ", " ? ", " : "
00051         " abs ", " min ", " max ", " addr ", " indirect ",
00052         " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ",
00053         };
00054 */
00055 
00056 /* Each of these values is defined in   pccdefs   */
00057 
00058 int ops2 [ ] =
00059 {
00060         P2BAD, P2PLUS, P2MINUS, P2STAR, P2SLASH, P2BAD, P2NEG,
00061         P2OROR, P2ANDAND, P2EQ, P2NE, P2NOT,
00062         P2BAD,
00063         P2LT, P2EQ, P2GT, P2LE, P2NE, P2GE,
00064         P2CALL, P2CALL, P2ASSIGN, P2PLUSEQ, P2STAREQ, P2CONV, P2LSHIFT, P2MOD,
00065         P2COMOP, P2QUEST, P2COLON,
00066         1, P2BAD, P2BAD, P2BAD, P2BAD,
00067         P2BITOR, P2BITAND, P2BITXOR, P2BITNOT, P2RSHIFT,
00068         P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD,
00069         P2BAD, P2BAD, P2BAD, P2BAD,
00070         1,1,1,1,1, /* OPNEG1, OPDMIN, OPDMAX, OPASSIGNI, OPIDENTITY */
00071         1,1,1,1,   /* OPCHARCAST, OPDABS, OPMIN2, OPMAX2 */
00072         1,1,1,1,1  /* OPBITTEST, OPBITCLR, OPBITSET, OPQBIT{CLR,SET} */
00073 };
00074 
00075 
00076  void
00077 #ifdef KR_headers
00078 putexpr(p)
00079         expptr p;
00080 #else
00081 putexpr(expptr p)
00082 #endif
00083 {
00084 /* Write the expression to the p1 file */
00085 
00086         p = (expptr) putx (fixtype (p));
00087         p1_expr (p);
00088 }
00089 
00090 
00091 
00092 
00093 
00094  expptr
00095 #ifdef KR_headers
00096 putassign(lp, rp)
00097         expptr lp;
00098         expptr rp;
00099 #else
00100 putassign(expptr lp, expptr rp)
00101 #endif
00102 {
00103         return putx(fixexpr((Exprp)mkexpr(OPASSIGN, lp, rp)));
00104 }
00105 
00106 
00107 
00108 
00109  void
00110 #ifdef KR_headers
00111 puteq(lp, rp)
00112         expptr lp;
00113         expptr rp;
00114 #else
00115 puteq(expptr lp, expptr rp)
00116 #endif
00117 {
00118         putexpr(mkexpr(OPASSIGN, lp, rp) );
00119 }
00120 
00121 
00122 
00123 
00124 /* put code for  a *= b */
00125 
00126  expptr
00127 #ifdef KR_headers
00128 putsteq(a, b)
00129         Addrp a;
00130         Addrp b;
00131 #else
00132 putsteq(Addrp a, Addrp b)
00133 #endif
00134 {
00135         return putx( fixexpr((Exprp)
00136                 mkexpr(OPSTAREQ, cpexpr((expptr)a), cpexpr((expptr)b))));
00137 }
00138 
00139 
00140 
00141 
00142  Addrp
00143 #ifdef KR_headers
00144 mkfield(res, f, ty)
00145         register Addrp res;
00146         char *f;
00147         int ty;
00148 #else
00149 mkfield(register Addrp res, char *f, int ty)
00150 #endif
00151 {
00152     res -> vtype = ty;
00153     res -> Field = f;
00154     return res;
00155 } /* mkfield */
00156 
00157 
00158  Addrp
00159 #ifdef KR_headers
00160 realpart(p)
00161         register Addrp p;
00162 #else
00163 realpart(register Addrp p)
00164 #endif
00165 {
00166         register Addrp q;
00167 
00168         if (p->tag == TADDR
00169          && p->uname_tag == UNAM_CONST
00170          && ISCOMPLEX (p->vtype))
00171                 return (Addrp)mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
00172                         p->user.kludge.vstg1 ? p->user.Const.cds[0]
00173                                 : cds(dtos(p->user.Const.cd[0]),CNULL));
00174 
00175         q = (Addrp) cpexpr((expptr) p);
00176         if( ISCOMPLEX(p->vtype) )
00177                 q = mkfield (q, "r", p -> vtype + TYREAL - TYCOMPLEX);
00178 
00179         return(q);
00180 }
00181 
00182 
00183 
00184 
00185  expptr
00186 #ifdef KR_headers
00187 imagpart(p)
00188         register Addrp p;
00189 #else
00190 imagpart(register Addrp p)
00191 #endif
00192 {
00193         register Addrp q;
00194 
00195         if( ISCOMPLEX(p->vtype) )
00196         {
00197                 if (p->tag == TADDR && p->uname_tag == UNAM_CONST)
00198                         return mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
00199                                 p->user.kludge.vstg1 ? p->user.Const.cds[1]
00200                                 : cds(dtos(p->user.Const.cd[1]),CNULL));
00201                 q = (Addrp) cpexpr((expptr) p);
00202                 q = mkfield (q, "i", p -> vtype + TYREAL - TYCOMPLEX);
00203                 return( (expptr) q );
00204         }
00205         else
00206 
00207 /* Cast an integer type onto a Double Real type */
00208 
00209                 return( mkrealcon( ISINT(p->vtype) ? TYDREAL : p->vtype , "0"));
00210 }
00211 
00212 
00213 
00214 
00215 
00216 /* ncat -- computes the number of adjacent concatenation operations */
00217 
00218  int
00219 #ifdef KR_headers
00220 ncat(p)
00221         register expptr p;
00222 #else
00223 ncat(register expptr p)
00224 #endif
00225 {
00226         if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
00227                 return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
00228         else    return(1);
00229 }
00230 
00231 
00232 
00233 
00234 /* lencat -- returns the length of the concatenated string.  Each
00235    substring must have a static (i.e. compile-time) fixed length */
00236 
00237  ftnint
00238 #ifdef KR_headers
00239 lencat(p)
00240         register expptr p;
00241 #else
00242 lencat(register expptr p)
00243 #endif
00244 {
00245         if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
00246                 return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
00247         else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
00248                 return(p->headblock.vleng->constblock.Const.ci);
00249         else if(p->tag==TADDR && p->addrblock.varleng!=0)
00250                 return(p->addrblock.varleng);
00251         else
00252         {
00253                 err("impossible element in concatenation");
00254                 return(0);
00255         }
00256 }
00257 
00258 /* putconst -- Creates a new Addrp value which maps onto the input
00259    constant value.  The Addrp doesn't retain the value of the constant,
00260    instead that value is copied into a table of constants (called
00261    litpool,   for pool of literal values).  The only way to retrieve the
00262    actual value of the constant is to look at the   memno   field of the
00263    Addrp result.  You know that the associated literal is the one referred
00264    to by   q   when   (q -> memno == litp -> litnum).
00265 */
00266 
00267  Addrp
00268 #ifdef KR_headers
00269 putconst(p)
00270         register Constp p;
00271 #else
00272 putconst(register Constp p)
00273 #endif
00274 {
00275         register Addrp q;
00276         struct Literal *litp, *lastlit;
00277         int k, len, type;
00278         int litflavor;
00279         double cd[2];
00280         ftnint nblanks;
00281         char *strp;
00282         char cdsbuf0[64], cdsbuf1[64], *ds[2];
00283 
00284         if (p->tag != TCONST)
00285                 badtag("putconst", p->tag);
00286 
00287         q = ALLOC(Addrblock);
00288         q->tag = TADDR;
00289         type = p->vtype;
00290         q->vtype = ( type==TYADDR ? tyint : type );
00291         q->vleng = (expptr) cpexpr(p->vleng);
00292         q->vstg = STGCONST;
00293 
00294 /* Create the new label for the constant.  This is wasteful of labels
00295    because when the constant value already exists in the literal pool,
00296    this label gets thrown away and is never reclaimed.  It might be
00297    cleaner to move this down past the first   switch()   statement below */
00298 
00299         q->memno = newlabel();
00300         q->memoffset = ICON(0);
00301         q -> uname_tag = UNAM_CONST;
00302 
00303 /* Copy the constant info into the Addrblock; do this by copying the
00304    largest storage elts */
00305 
00306         q -> user.Const = p -> Const;
00307         q->user.kludge.vstg1 = p->vstg; /* distinguish string from binary fp */
00308 
00309         /* check for value in literal pool, and update pool if necessary */
00310 
00311         k = 1;
00312         switch(type)
00313         {
00314         case TYCHAR:
00315                 if (halign) {
00316                         strp = p->Const.ccp;
00317                         nblanks = p->Const.ccp1.blanks;
00318                         len = (int)p->vleng->constblock.Const.ci;
00319                         litflavor = LIT_CHAR;
00320                         goto loop;
00321                         }
00322                 else
00323                         q->memno = BAD_MEMNO;
00324                 break;
00325         case TYCOMPLEX:
00326         case TYDCOMPLEX:
00327                 k = 2;
00328                 if (p->vstg)
00329                         cd[1] = atof(ds[1] = p->Const.cds[1]);
00330                 else
00331                         ds[1] = cds(dtos(cd[1] = p->Const.cd[1]), cdsbuf1);
00332         case TYREAL:
00333         case TYDREAL:
00334                 litflavor = LIT_FLOAT;
00335                 if (p->vstg)
00336                         cd[0] = atof(ds[0] = p->Const.cds[0]);
00337                 else
00338                         ds[0] = cds(dtos(cd[0] = p->Const.cd[0]), cdsbuf0);
00339                 goto loop;
00340 
00341 #ifndef NO_LONG_LONG
00342         case TYQUAD:
00343                 litflavor = LIT_INTQ;
00344                 goto loop;
00345 #endif
00346 
00347         case TYLOGICAL1:
00348         case TYLOGICAL2:
00349         case TYLOGICAL:
00350         case TYLONG:
00351         case TYSHORT:
00352         case TYINT1:
00353 #ifdef TYQUAD0
00354         case TYQUAD:
00355 #endif
00356                 litflavor = LIT_INT;
00357 
00358 /* Scan the literal pool for this constant value.  If this same constant
00359    has been assigned before, use the same label.  Note that this routine
00360    does NOT consider two differently-typed constants with the same bit
00361    pattern to be the same constant */
00362 
00363  loop:
00364                 lastlit = litpool + nliterals;
00365                 for(litp = litpool ; litp<lastlit ; ++litp)
00366 
00367 /* Remove this type checking to ensure that all bit patterns are reused */
00368 
00369                         if(type == litp->littype) switch(litflavor)
00370                         {
00371                         case LIT_CHAR:
00372                                 if (len == (int)litp->litval.litival2[0]
00373                                 && nblanks == litp->litval.litival2[1]
00374                                 && !memcmp(strp, litp->cds[0], len)) {
00375                                         q->memno = litp->litnum;
00376                                         frexpr((expptr)p);
00377                                         q->user.Const.ccp1.ccp0 = litp->cds[0];
00378                                         return(q);
00379                                         }
00380                                 break;
00381                         case LIT_FLOAT:
00382                                 if(cd[0] == litp->litval.litdval[0]
00383                                 && !strcmp(ds[0], litp->cds[0])
00384                                 && (k == 1 ||
00385                                     cd[1] == litp->litval.litdval[1]
00386                                     && !strcmp(ds[1], litp->cds[1]))) {
00387 ret:
00388                                         q->memno = litp->litnum;
00389                                         frexpr((expptr)p);
00390                                         return(q);
00391                                         }
00392                                 break;
00393 
00394                         case LIT_INT:
00395                                 if(p->Const.ci == litp->litval.litival)
00396                                         goto ret;
00397                                 break;
00398 #ifndef NO_LONG_LONG
00399                         case LIT_INTQ:
00400                                 if(p->Const.cq == litp->litval.litqval)
00401                                         goto ret;
00402                                 break;
00403 #endif
00404                         }
00405 
00406 /* If there's room in the literal pool, add this new value to the pool */
00407 
00408                 if(nliterals < maxliterals)
00409                 {
00410                         ++nliterals;
00411 
00412                         /* litp   now points to the next free elt */
00413 
00414                         litp->littype = type;
00415                         litp->litnum = q->memno;
00416                         switch(litflavor)
00417                         {
00418                         case LIT_CHAR:
00419                                 litp->litval.litival2[0] = len;
00420                                 litp->litval.litival2[1] = nblanks;
00421                                 q->user.Const.ccp = litp->cds[0] = (char*)
00422                                         memcpy(gmem(len,0), strp, len);
00423                                 break;
00424 
00425                         case LIT_FLOAT:
00426                                 litp->litval.litdval[0] = cd[0];
00427                                 litp->cds[0] = copys(ds[0]);
00428                                 if (k == 2) {
00429                                         litp->litval.litdval[1] = cd[1];
00430                                         litp->cds[1] = copys(ds[1]);
00431                                         }
00432                                 break;
00433 
00434                         case LIT_INT:
00435                                 litp->litval.litival = p->Const.ci;
00436                                 break;
00437 #ifndef NO_LONG_LONG
00438                         case LIT_INTQ:
00439                                 litp->litval.litqval = p->Const.cq;
00440                                 break;
00441 #endif
00442                         } /* switch (litflavor) */
00443                 }
00444                 else
00445                         many("literal constants", 'L', maxliterals);
00446 
00447                 break;
00448         case TYADDR:
00449             break;
00450         default:
00451                 badtype ("putconst", p -> vtype);
00452                 break;
00453         } /* switch */
00454 
00455         if (type != TYCHAR || halign)
00456             frexpr((expptr)p);
00457         return( q );
00458 }

Generated on Sun Mar 4 15:03:44 2007 for Scilab [trunk] by  doxygen 1.5.1