home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / f2c / src / vax.c < prev    next >
C/C++ Source or Header  |  2000-06-23  |  8KB  |  327 lines

  1. /****************************************************************
  2. Copyright 1990, 1992 by AT&T Bell Laboratories and Bellcore.
  3.  
  4. Permission to use, copy, modify, and distribute this software
  5. and its documentation for any purpose and without fee is hereby
  6. granted, provided that the above copyright notice appear in all
  7. copies and that both that the copyright notice and this
  8. permission notice and warranty disclaimer appear in supporting
  9. documentation, and that the names of AT&T Bell Laboratories or
  10. Bellcore or any of their entities not be used in advertising or
  11. publicity pertaining to distribution of the software without
  12. specific, written prior permission.
  13.  
  14. AT&T and Bellcore disclaim all warranties with regard to this
  15. software, including all implied warranties of merchantability
  16. and fitness.  In no event shall AT&T or Bellcore be liable for
  17. any special, indirect or consequential damages or any damages
  18. whatsoever resulting from loss of use, data or profits, whether
  19. in an action of contract, negligence or other tortious action,
  20. arising out of or in connection with the use or performance of
  21. this software.
  22. ****************************************************************/
  23.  
  24. #include "defs.h"
  25. #include "pccdefs.h"
  26. #include "output.h"
  27.  
  28. int regnum[] =  {
  29.     11, 10, 9, 8, 7, 6 };
  30.  
  31. /* Put out a constant integer */
  32.  
  33. prconi(fp, n)
  34. FILEP fp;
  35. ftnint n;
  36. {
  37.     fprintf(fp, "\t%ld\n", n);
  38. }
  39.  
  40.  
  41.  
  42. /* Put out a constant address */
  43.  
  44. prcona(fp, a)
  45. FILEP fp;
  46. ftnint a;
  47. {
  48.     fprintf(fp, "\tL%ld\n", a);
  49. }
  50.  
  51.  
  52.  
  53. prconr(fp, x, k)
  54.  FILEP fp;
  55.  int k;
  56.  Constp x;
  57. {
  58.     char *x0, *x1;
  59.     char cdsbuf0[64], cdsbuf1[64];
  60.  
  61.     if (k > 1) {
  62.         if (x->vstg) {
  63.             x0 = x->Const.cds[0];
  64.             x1 = x->Const.cds[1];
  65.             }
  66.         else {
  67.             x0 = cds(dtos(x->Const.cd[0]), cdsbuf0);
  68.             x1 = cds(dtos(x->Const.cd[1]), cdsbuf1);
  69.             }
  70.         fprintf(fp, "\t%s %s\n", x0, x1);
  71.         }
  72.     else
  73.         fprintf(fp, "\t%s\n", x->vstg ? x->Const.cds[0]
  74.                 : cds(dtos(x->Const.cd[0]), cdsbuf0));
  75. }
  76.  
  77.  
  78. char *memname(stg, mem)
  79.  int stg;
  80.  long mem;
  81. {
  82.     static char s[20];
  83.  
  84.     switch(stg)
  85.     {
  86.     case STGCOMMON:
  87.     case STGEXT:
  88.         sprintf(s, "_%s", extsymtab[mem].cextname);
  89.         break;
  90.  
  91.     case STGBSS:
  92.     case STGINIT:
  93.         sprintf(s, "v.%ld", mem);
  94.         break;
  95.  
  96.     case STGCONST:
  97.         sprintf(s, "L%ld", mem);
  98.         break;
  99.  
  100.     case STGEQUIV:
  101.         sprintf(s, "q.%ld", mem+eqvstart);
  102.         break;
  103.  
  104.     default:
  105.         badstg("memname", stg);
  106.     }
  107.     return(s);
  108. }
  109.  
  110. /* make_int_expr -- takes an arbitrary expression, and replaces all
  111.    occurrences of arguments with indirection */
  112.  
  113. expptr make_int_expr (e)
  114. expptr e;
  115. {
  116.     if (e != ENULL)
  117.     switch (e -> tag) {
  118.         case TADDR:
  119.             if (e -> addrblock.vstg == STGARG
  120.          && !e->addrblock.isarray)
  121.             e = mkexpr (OPWHATSIN, e, ENULL);
  122.             break;
  123.         case TEXPR:
  124.             e -> exprblock.leftp = make_int_expr (e -> exprblock.leftp);
  125.             e -> exprblock.rightp = make_int_expr (e -> exprblock.rightp);
  126.             break;
  127.         default:
  128.             break;
  129.     } /* switch */
  130.  
  131.     return e;
  132. } /* make_int_expr */
  133.  
  134.  
  135.  
  136. /* prune_left_conv -- used in prolog() to strip type cast away from
  137.    left-hand side of parameter adjustments.  This is necessary to avoid
  138.    error messages from cktype() */
  139.  
  140. expptr prune_left_conv (e)
  141. expptr e;
  142. {
  143.     struct Exprblock *leftp;
  144.  
  145.     if (e && e -> tag == TEXPR && e -> exprblock.leftp &&
  146.         e -> exprblock.leftp -> tag == TEXPR) {
  147.     leftp = &(e -> exprblock.leftp -> exprblock);
  148.     if (leftp -> opcode == OPCONV) {
  149.         e -> exprblock.leftp = leftp -> leftp;
  150.         free ((charptr) leftp);
  151.     }
  152.     }
  153.  
  154.     return e;
  155. } /* prune_left_conv */
  156.  
  157.  
  158.  static int wrote_comment;
  159.  static FILE *comment_file;
  160.  
  161.  static void
  162. write_comment()
  163. {
  164.     if (!wrote_comment) {
  165.         wrote_comment = 1;
  166.         nice_printf (comment_file, "/* Parameter adjustments */\n");
  167.         }
  168.     }
  169.  
  170.  static int *
  171. count_args()
  172. {
  173.     register int *ac;
  174.     register chainp cp;
  175.     register struct Entrypoint *ep;
  176.     register Namep q;
  177.  
  178.     ac = (int *)ckalloc(nallargs*sizeof(int));
  179.  
  180.     for(ep = entries; ep; ep = ep->entnextp)
  181.         for(cp = ep->arglist; cp; cp = cp->nextp)
  182.             if (q = (Namep)cp->datap)
  183.                 ac[q->argno]++;
  184.     return ac;
  185.     }
  186.  
  187. prolog(outfile, p)
  188.  FILE *outfile;
  189.  register chainp p;
  190. {
  191.     int addif, addif0, i, nd, size;
  192.     int *ac;
  193.     register Namep q;
  194.     register struct Dimblock *dp;
  195.  
  196.     if(procclass == CLBLOCK)
  197.         return;
  198.     wrote_comment = 0;
  199.     comment_file = outfile;
  200.     ac = 0;
  201.  
  202. /* Compute the base addresses and offsets for the array parameters, and
  203.    assign these values to local variables */
  204.  
  205.     addif = addif0 = nentry > 1;
  206.     for(; p ; p = p->nextp)
  207.     {
  208.         q = (Namep) p->datap;
  209.         if(dp = q->vdim)    /* if this param is an array ... */
  210.         {
  211.         expptr Q, expr;
  212.  
  213.         /* See whether to protect the following with an if. */
  214.         /* This only happens when there are multiple entries. */
  215.  
  216.         nd = dp->ndim - 1;
  217.         if (addif0) {
  218.             if (!ac)
  219.                 ac = count_args();
  220.             if (ac[q->argno] == nentry)
  221.                 addif = 0;
  222.             else if (dp->basexpr
  223.                     || dp->baseoffset->constblock.Const.ci)
  224.                 addif = 1;
  225.             else for(addif = i = 0; i <= nd; i++)
  226.                 if (dp->dims[i].dimexpr
  227.                 && (i < nd || !q->vlastdim)) {
  228.                     addif = 1;
  229.                     break;
  230.                     }
  231.             if (addif) {
  232.                 write_comment();
  233.                 nice_printf(outfile, "if (%s) {\n", /*}*/
  234.                         q->cvarname);
  235.                 next_tab(outfile);
  236.                 }
  237.             }
  238.         for(i = 0 ; i <= nd; ++i)
  239.  
  240. /* Store the variable length of each dimension (which is fixed upon
  241.    runtime procedure entry) into a local variable */
  242.  
  243.             if ((Q = dp->dims[i].dimexpr)
  244.             && (i < nd || !q->vlastdim)) {
  245.             expr = (expptr)cpexpr(Q);
  246.             write_comment();
  247.             out_and_free_statement (outfile, mkexpr (OPASSIGN,
  248.                 fixtype(cpexpr(dp->dims[i].dimsize)), expr));
  249.             } /* if dp -> dims[i].dimexpr */
  250.  
  251. /* size   will equal the size of a single element, or -1 if the type is
  252.    variable length character type */
  253.  
  254.         size = typesize[ q->vtype ];
  255.         if(q->vtype == TYCHAR)
  256.             if( ISICON(q->vleng) )
  257.             size *= q->vleng->constblock.Const.ci;
  258.             else
  259.             size = -1;
  260.  
  261.         /* Fudge the argument pointers for arrays so subscripts
  262.          * are 0-based. Not done if array bounds are being checked.
  263.          */
  264.         if(dp->basexpr) {
  265.  
  266. /* Compute the base offset for this procedure */
  267.  
  268.             write_comment();
  269.             out_and_free_statement (outfile, mkexpr (OPASSIGN,
  270.                 cpexpr(fixtype(dp->baseoffset)),
  271.                 cpexpr(fixtype(dp->basexpr))));
  272.         } /* if dp -> basexpr */
  273.  
  274.         if(! checksubs) {
  275.             if(dp->basexpr) {
  276.             expptr tp;
  277.  
  278. /* If the base of this array has a variable adjustment ... */
  279.  
  280.             tp = (expptr) cpexpr (dp -> baseoffset);
  281.             if(size < 0 || q -> vtype == TYCHAR)
  282.                 tp = mkexpr (OPSTAR, tp, cpexpr (q -> vleng));
  283.  
  284.             write_comment();
  285.             tp = mkexpr (OPMINUSEQ,
  286.                 mkconv (TYADDR, (expptr)p->datap),
  287.                 mkconv(TYINT, fixtype
  288.                 (fixtype (tp))));
  289. /* Avoid type clash by removing the type conversion */
  290.             tp = prune_left_conv (tp);
  291.             out_and_free_statement (outfile, tp);
  292.             } else if(dp->baseoffset->constblock.Const.ci != 0) {
  293.  
  294. /* if the base of this array has a nonzero constant adjustment ... */
  295.  
  296.             expptr tp;
  297.  
  298.             write_comment();
  299.             if(size > 0 && q -> vtype != TYCHAR) {
  300.                 tp = prune_left_conv (mkexpr (OPMINUSEQ,
  301.                     mkconv (TYADDR, (expptr)p->datap),
  302.                     mkconv (TYINT, fixtype
  303.                     (cpexpr (dp->baseoffset)))));
  304.                 out_and_free_statement (outfile, tp);
  305.             } else {
  306.                 tp = prune_left_conv (mkexpr (OPMINUSEQ,
  307.                     mkconv (TYADDR, (expptr)p->datap),
  308.                     mkconv (TYINT, fixtype
  309.                     (mkexpr (OPSTAR, cpexpr (dp -> baseoffset),
  310.                     cpexpr (q -> vleng))))));
  311.                 out_and_free_statement (outfile, tp);
  312.             } /* else */
  313.             } /* if dp -> baseoffset -> const */
  314.         } /* if !checksubs */
  315.  
  316.         if (addif) {
  317.             nice_printf(outfile, /*{*/ "}\n");
  318.             prev_tab(outfile);
  319.             }
  320.         }
  321.     }
  322.     if (wrote_comment)
  323.         nice_printf (outfile, "\n/* Function Body */\n");
  324.     if (ac)
  325.         free((char *)ac);
  326. } /* prolog */
  327.