vax.c

Go to the documentation of this file.
00001 /****************************************************************
00002 Copyright 1990, 1992-1994, 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 #include "defs.h"
00025 #include "pccdefs.h"
00026 #include "output.h"
00027 
00028 int regnum[] =  {
00029         11, 10, 9, 8, 7, 6 };
00030 
00031 /* Put out a constant integer */
00032 
00033  void
00034 #ifdef KR_headers
00035 prconi(fp, n)
00036         FILEP fp;
00037         ftnint n;
00038 #else
00039 prconi(FILEP fp, ftnint n)
00040 #endif
00041 {
00042         fprintf(fp, "\t%ld\n", n);
00043 }
00044 
00045 #ifndef NO_LONG_LONG
00046  void
00047 #ifdef KR_headers
00048 prconq(fp, n) FILEP fp; Llong n;
00049 #else
00050 prconq(FILEP fp, Llong n)
00051 #endif
00052 {
00053         fprintf(fp, "\t%lld\n", n);
00054         }
00055 #endif
00056 
00057 
00058 /* Put out a constant address */
00059 
00060  void
00061 #ifdef KR_headers
00062 prcona(fp, a)
00063         FILEP fp;
00064         ftnint a;
00065 #else
00066 prcona(FILEP fp, ftnint a)
00067 #endif
00068 {
00069         fprintf(fp, "\tL%ld\n", a);
00070 }
00071 
00072 
00073  void
00074 #ifdef KR_headers
00075 prconr(fp, x, k)
00076         FILEP fp;
00077         Constp x;
00078         int k;
00079 #else
00080 prconr(FILEP fp, Constp x, int k)
00081 #endif
00082 {
00083         char *x0, *x1;
00084         char cdsbuf0[64], cdsbuf1[64];
00085 
00086         if (k > 1) {
00087                 if (x->vstg) {
00088                         x0 = x->Const.cds[0];
00089                         x1 = x->Const.cds[1];
00090                         }
00091                 else {
00092                         x0 = cds(dtos(x->Const.cd[0]), cdsbuf0);
00093                         x1 = cds(dtos(x->Const.cd[1]), cdsbuf1);
00094                         }
00095                 fprintf(fp, "\t%s %s\n", x0, x1);
00096                 }
00097         else
00098                 fprintf(fp, "\t%s\n", x->vstg ? x->Const.cds[0]
00099                                 : cds(dtos(x->Const.cd[0]), cdsbuf0));
00100 }
00101 
00102 
00103  char *
00104 #ifdef KR_headers
00105 memname(stg, mem)
00106         int stg;
00107         long mem;
00108 #else
00109 memname(int stg, long mem)
00110 #endif
00111 {
00112         static char s[20];
00113 
00114         switch(stg)
00115         {
00116         case STGCOMMON:
00117         case STGEXT:
00118                 sprintf(s, "_%s", extsymtab[mem].cextname);
00119                 break;
00120 
00121         case STGBSS:
00122         case STGINIT:
00123                 sprintf(s, "v.%ld", mem);
00124                 break;
00125 
00126         case STGCONST:
00127                 sprintf(s, "L%ld", mem);
00128                 break;
00129 
00130         case STGEQUIV:
00131                 sprintf(s, "q.%ld", mem+eqvstart);
00132                 break;
00133 
00134         default:
00135                 badstg("memname", stg);
00136         }
00137         return(s);
00138 }
00139 
00140 extern void addrlit Argdcl((Addrp));
00141 
00142 /* make_int_expr -- takes an arbitrary expression, and replaces all
00143    occurrences of arguments with indirection */
00144 
00145  expptr
00146 #ifdef KR_headers
00147 make_int_expr(e)
00148         expptr e;
00149 #else
00150 make_int_expr(expptr e)
00151 #endif
00152 {
00153     chainp listp;
00154     Addrp ap;
00155     expptr e1;
00156 
00157     if (e != ENULL)
00158         switch (e -> tag) {
00159             case TADDR:
00160                 if (e->addrblock.isarray) {
00161                         if (e1 = e->addrblock.memoffset)
00162                                 e->addrblock.memoffset = make_int_expr(e1);
00163                         }
00164                 else if (e->addrblock.vstg == STGARG
00165                         || e->addrblock.vstg == STGCOMMON
00166                                 && e->addrblock.uname_tag == UNAM_NAME
00167                                 && e->addrblock.user.name->vcommequiv)
00168                         e = mkexpr(OPWHATSIN, e, ENULL);
00169                 break;
00170             case TEXPR:
00171                 e -> exprblock.leftp = make_int_expr (e -> exprblock.leftp);
00172                 e -> exprblock.rightp = make_int_expr (e -> exprblock.rightp);
00173                 break;
00174             case TLIST:
00175                 for(listp = e->listblock.listp; listp; listp = listp->nextp)
00176                         if ((ap = (Addrp)listp->datap)
00177                          && ap->tag == TADDR
00178                          && ap->uname_tag == UNAM_CONST)
00179                                 addrlit(ap);
00180                 break;
00181             default:
00182                 break;
00183         } /* switch */
00184 
00185     return e;
00186 } /* make_int_expr */
00187 
00188 
00189 
00190 /* prune_left_conv -- used in prolog() to strip type cast away from
00191    left-hand side of parameter adjustments.  This is necessary to avoid
00192    error messages from cktype() */
00193 
00194  expptr
00195 #ifdef KR_headers
00196 prune_left_conv(e)
00197         expptr e;
00198 #else
00199 prune_left_conv(expptr e)
00200 #endif
00201 {
00202     struct Exprblock *leftp;
00203 
00204     if (e && e -> tag == TEXPR && e -> exprblock.leftp &&
00205             e -> exprblock.leftp -> tag == TEXPR) {
00206         leftp = &(e -> exprblock.leftp -> exprblock);
00207         if (leftp -> opcode == OPCONV) {
00208             e -> exprblock.leftp = leftp -> leftp;
00209             free ((charptr) leftp);
00210         }
00211     }
00212 
00213     return e;
00214 } /* prune_left_conv */
00215 
00216 
00217  static int wrote_comment;
00218  static FILE *comment_file;
00219 
00220  static void
00221 write_comment(Void)
00222 {
00223         if (!wrote_comment) {
00224                 wrote_comment = 1;
00225                 nice_printf (comment_file, "/* Parameter adjustments */\n");
00226                 }
00227         }
00228 
00229  static int *
00230 count_args(Void)
00231 {
00232         register int *ac;
00233         register chainp cp;
00234         register struct Entrypoint *ep;
00235         register Namep q;
00236 
00237         ac = (int *)ckalloc(nallargs*sizeof(int));
00238 
00239         for(ep = entries; ep; ep = ep->entnextp)
00240                 for(cp = ep->arglist; cp; cp = cp->nextp)
00241                         if (q = (Namep)cp->datap)
00242                                 ac[q->argno]++;
00243         return ac;
00244         }
00245 
00246  static int nu, *refs, *used;
00247  static void awalk Argdcl((expptr));
00248 
00249  static void
00250 #ifdef KR_headers
00251 aawalk(P)
00252         struct Primblock *P;
00253 #else
00254 aawalk(struct Primblock *P)
00255 #endif
00256 {
00257         chainp p;
00258         expptr q;
00259 
00260         if (P->argsp)
00261                 for(p = P->argsp->listp; p; p = p->nextp) {
00262                         q = (expptr)p->datap;
00263                         if (q->tag != TCONST)
00264                                 awalk(q);
00265                         }
00266         if (P->namep->vtype == TYCHAR) {
00267                 if (q = P->fcharp)
00268                         awalk(q);
00269                 if (q = P->lcharp)
00270                         awalk(q);
00271                 }
00272         }
00273 
00274  static void
00275 #ifdef KR_headers
00276 afwalk(P)
00277         struct Primblock *P;
00278 #else
00279 afwalk(struct Primblock *P)
00280 #endif
00281 {
00282         chainp p;
00283         expptr q;
00284         Namep np;
00285 
00286         for(p = P->argsp->listp; p; p = p->nextp) {
00287                 q = (expptr)p->datap;
00288                 switch(q->tag) {
00289                   case TPRIM:
00290                         np = q->primblock.namep;
00291                         if (np->vknownarg)
00292                                 if (!refs[np->argno]++)
00293                                         used[nu++] = np->argno;
00294                         if (q->primblock.argsp == 0) {
00295                                 if (q->primblock.namep->vclass == CLPROC
00296                                  && q->primblock.namep->vprocclass
00297                                                 != PTHISPROC
00298                                  || q->primblock.namep->vdim != NULL)
00299                                         continue;
00300                                 }
00301                   default:
00302                         awalk(q);
00303                         /* no break */
00304                   case TCONST:
00305                         continue;
00306                   }
00307                 }
00308         }
00309 
00310  static void
00311 #ifdef KR_headers
00312 awalk(e)
00313         expptr e;
00314 #else
00315 awalk(expptr e)
00316 #endif
00317 {
00318         Namep np;
00319  top:
00320         if (!e)
00321                 return;
00322         switch(e->tag) {
00323           default:
00324                 badtag("awalk", e->tag);
00325           case TCONST:
00326           case TERROR:
00327           case TLIST:
00328                 return;
00329           case TADDR:
00330                 if (e->addrblock.uname_tag == UNAM_NAME) {
00331                         np = e->addrblock.user.name;
00332                         if (np->vknownarg && !refs[np->argno]++)
00333                                 used[nu++] = np->argno;
00334                         }
00335                 e = e->addrblock.memoffset;
00336                 goto top;
00337           case TPRIM:
00338                 np = e->primblock.namep;
00339                 if (np->vknownarg && !refs[np->argno]++)
00340                         used[nu++] = np->argno;
00341                 if (e->primblock.argsp && np->vclass != CLVAR)
00342                         afwalk((struct Primblock *)e);
00343                 else
00344                         aawalk((struct Primblock *)e);
00345                 return;
00346           case TEXPR:
00347                 awalk(e->exprblock.rightp);
00348                 e = e->exprblock.leftp;
00349                 goto top;
00350           }
00351         }
00352 
00353  static chainp
00354 #ifdef KR_headers
00355 argsort(p0)
00356         chainp p0;
00357 #else
00358 argsort(chainp p0)
00359 #endif
00360 {
00361         Namep *args, q, *stack;
00362         int i, nargs, nout, nst;
00363         chainp *d, *da, p, rv, *rvp;
00364         struct Dimblock *dp;
00365 
00366         if (!p0)
00367                 return p0;
00368         for(nargs = 0, p = p0; p; p = p->nextp)
00369                 nargs++;
00370         args = (Namep *)ckalloc(i = nargs*(sizeof(Namep) + 2*sizeof(chainp)
00371                         + 2*sizeof(int)));
00372         memset((char *)args, 0, i);
00373         stack = args + nargs;
00374         d = (chainp *)(stack + nargs);
00375         refs = (int *)(d + nargs);
00376         used = refs + nargs;
00377 
00378         for(p = p0; p; p = p->nextp) {
00379                 q = (Namep) p->datap;
00380                 args[q->argno] = q;
00381                 }
00382         for(p = p0; p; p = p->nextp) {
00383                 q = (Namep) p->datap;
00384                 if (!(dp = q->vdim))
00385                         continue;
00386                 i = dp->ndim;
00387                 while(--i >= 0)
00388                         awalk(dp->dims[i].dimexpr);
00389                 awalk(dp->basexpr);
00390                 while(nu > 0) {
00391                         refs[i = used[--nu]] = 0;
00392                         d[i] = mkchain((char *)q, d[i]);
00393                         }
00394                 }
00395         for(i = nst = 0; i < nargs; i++)
00396                 for(p = d[i]; p; p = p->nextp)
00397                         refs[((Namep)p->datap)->argno]++;
00398         while(--i >= 0)
00399                 if (!refs[i])
00400                         stack[nst++] = args[i];
00401         if (nst == nargs) {
00402                 rv = p0;
00403                 goto done;
00404                 }
00405         nout = 0;
00406         rv = 0;
00407         rvp = &rv;
00408         while(nst > 0) {
00409                 nout++;
00410                 q = stack[--nst];
00411                 *rvp = p = mkchain((char *)q, CHNULL);
00412                 rvp = &p->nextp;
00413                 da = d + q->argno;
00414                 for(p = *da; p; p = p->nextp)
00415                         if (!--refs[(q = (Namep)p->datap)->argno])
00416                                 stack[nst++] = q;
00417                 frchain(da);
00418                 }
00419         if (nout < nargs)
00420                 for(i = 0; i < nargs; i++)
00421                         if (refs[i]) {
00422                                 q = args[i];
00423                                 errstr("Can't adjust %.38s correctly\n\
00424         due to dependencies among arguments.",
00425                                         q->fvarname);
00426                                 *rvp = p = mkchain((char *)q, CHNULL);
00427                                 rvp = &p->nextp;
00428                                 frchain(d+i);
00429                                 }
00430  done:
00431         free((char *)args);
00432         return rv;
00433         }
00434 
00435  void
00436 #ifdef KR_headers
00437 prolog(outfile, p)
00438         FILE *outfile;
00439         register chainp p;
00440 #else
00441 prolog(FILE *outfile, register chainp p)
00442 #endif
00443 {
00444         int addif, addif0, i, nd;
00445         ftnint size;
00446         int *ac;
00447         register Namep q;
00448         register struct Dimblock *dp;
00449         chainp p0, p1;
00450 
00451         if(procclass == CLBLOCK)
00452                 return;
00453         p0 = p;
00454         p1 = p = argsort(p);
00455         wrote_comment = 0;
00456         comment_file = outfile;
00457         ac = 0;
00458 
00459 /* Compute the base addresses and offsets for the array parameters, and
00460    assign these values to local variables */
00461 
00462         addif = addif0 = nentry > 1;
00463         for(; p ; p = p->nextp)
00464         {
00465             q = (Namep) p->datap;
00466             if(dp = q->vdim)    /* if this param is an array ... */
00467             {
00468                 expptr Q, expr;
00469 
00470                 /* See whether to protect the following with an if. */
00471                 /* This only happens when there are multiple entries. */
00472 
00473                 nd = dp->ndim - 1;
00474                 if (addif0) {
00475                         if (!ac)
00476                                 ac = count_args();
00477                         if (ac[q->argno] == nentry)
00478                                 addif = 0;
00479                         else if (dp->basexpr
00480                                     || dp->baseoffset->constblock.Const.ci)
00481                                 addif = 1;
00482                         else for(addif = i = 0; i <= nd; i++)
00483                                 if (dp->dims[i].dimexpr
00484                                 && (i < nd || !q->vlastdim)) {
00485                                         addif = 1;
00486                                         break;
00487                                         }
00488                         if (addif) {
00489                                 write_comment();
00490                                 nice_printf(outfile, "if (%s) {\n", /*}*/
00491                                                 q->cvarname);
00492                                 next_tab(outfile);
00493                                 }
00494                         }
00495                 for(i = 0 ; i <= nd; ++i)
00496 
00497 /* Store the variable length of each dimension (which is fixed upon
00498    runtime procedure entry) into a local variable */
00499 
00500                     if ((Q = dp->dims[i].dimexpr)
00501                         && (i < nd || !q->vlastdim)) {
00502                         expr = (expptr)cpexpr(Q);
00503                         write_comment();
00504                         out_and_free_statement (outfile, mkexpr (OPASSIGN,
00505                                 fixtype(cpexpr(dp->dims[i].dimsize)), expr));
00506                     } /* if dp -> dims[i].dimexpr */
00507 
00508 /* size   will equal the size of a single element, or -1 if the type is
00509    variable length character type */
00510 
00511                 size = typesize[ q->vtype ];
00512                 if(q->vtype == TYCHAR)
00513                     if( ISICON(q->vleng) )
00514                         size *= q->vleng->constblock.Const.ci;
00515                     else
00516                         size = -1;
00517 
00518                 /* Fudge the argument pointers for arrays so subscripts
00519                  * are 0-based. Not done if array bounds are being checked.
00520                  */
00521                 if(dp->basexpr) {
00522 
00523 /* Compute the base offset for this procedure */
00524 
00525                     write_comment();
00526                     out_and_free_statement (outfile, mkexpr (OPASSIGN,
00527                             cpexpr(fixtype(dp->baseoffset)),
00528                             cpexpr(fixtype(dp->basexpr))));
00529                 } /* if dp -> basexpr */
00530 
00531                 if(! checksubs) {
00532                     if(dp->basexpr) {
00533                         expptr tp;
00534 
00535 /* If the base of this array has a variable adjustment ... */
00536 
00537                         tp = (expptr) cpexpr (dp -> baseoffset);
00538                         if(size < 0 || q -> vtype == TYCHAR)
00539                             tp = mkexpr (OPSTAR, tp, cpexpr (q -> vleng));
00540 
00541                         write_comment();
00542                         tp = mkexpr (OPMINUSEQ,
00543                                 mkconv (TYADDR, (expptr)p->datap),
00544                                 mkconv(TYINT, fixtype
00545                                 (fixtype (tp))));
00546 /* Avoid type clash by removing the type conversion */
00547                         tp = prune_left_conv (tp);
00548                         out_and_free_statement (outfile, tp);
00549                     } else if(dp->baseoffset->constblock.Const.ci != 0) {
00550 
00551 /* if the base of this array has a nonzero constant adjustment ... */
00552 
00553                         expptr tp;
00554 
00555                         write_comment();
00556                         if(size > 0 && q -> vtype != TYCHAR) {
00557                             tp = prune_left_conv (mkexpr (OPMINUSEQ,
00558                                     mkconv (TYADDR, (expptr)p->datap),
00559                                     mkconv (TYINT, fixtype
00560                                     (cpexpr (dp->baseoffset)))));
00561                             out_and_free_statement (outfile, tp);
00562                         } else {
00563                             tp = prune_left_conv (mkexpr (OPMINUSEQ,
00564                                     mkconv (TYADDR, (expptr)p->datap),
00565                                     mkconv (TYINT, fixtype
00566                                     (mkexpr (OPSTAR, cpexpr (dp -> baseoffset),
00567                                     cpexpr (q -> vleng))))));
00568                             out_and_free_statement (outfile, tp);
00569                         } /* else */
00570                     } /* if dp -> baseoffset -> const */
00571                 } /* if !checksubs */
00572 
00573                 if (addif) {
00574                         nice_printf(outfile, /*{*/ "}\n");
00575                         prev_tab(outfile);
00576                         }
00577             }
00578         }
00579         if (wrote_comment)
00580             nice_printf (outfile, "\n/* Function Body */\n");
00581         if (ac)
00582                 free((char *)ac);
00583         if (p0 != p1)
00584                 frchain(&p1);
00585 } /* prolog */

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