home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / zc.lzh / ZC / ZCSRC.LZH / top / func.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-28  |  4.8 KB  |  226 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Tony Andrews
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11.  
  12. /*
  13.  * Changes for Amgia version by Jeff Lydiatt are marked by Jal.
  14.  */
  15.  
  16. #include "top.h"
  17.  
  18. #define strcmp stricmp    /* Jal - use case insensitive compare. */
  19. BLOCK    *fhead;        /* head of the current function */
  20.  
  21. /*
  22.  * dofunc() - process one function
  23.  *
  24.  * Returns FALSE on end of file
  25.  */
  26. bool
  27. dofunc()
  28. {
  29.     BLOCK    *getfunc();
  30.  
  31. #ifdef    DEBUG
  32.     if (debug)
  33.         fprintf(stderr, "dofunc() - calling getfunc()\n");
  34. #endif
  35.     if ((fhead = getfunc()) == NULL)
  36.         return FALSE;
  37.  
  38.     /*
  39.      * Process the function we just read
  40.      */
  41.     bopt(fhead);    /* perform branch optimization (must be done first) */
  42.  
  43.     if (do_dflow)
  44.         rhealth(fhead);    /* perform live/dead register analysis */
  45.  
  46.     if (do_peep)
  47.         peep(fhead);    /* peephole optimizations */
  48.  
  49.     /*
  50.      * Now dump out the modified tree
  51.      */
  52. #ifdef    DEBUG
  53.     if (debug)
  54.         fprintf(stderr, "dofunc() - calling putfunc()\n");
  55. #endif
  56.     putfunc(fhead);
  57.  
  58. #ifdef    DEBUG
  59.     if (debug)
  60.         fprintf(stderr, "dofunc() - calling freesym()\n");
  61. #endif
  62.     freesym();        /* free the symbol table */
  63.  
  64.     return TRUE;
  65. }
  66.  
  67. static    bool    saw_eof = FALSE;
  68.  
  69. /*
  70.  * getfunc() - get a function and return a pointer to its starting block
  71.  *
  72.  * Returns NULL on end of file.
  73.  */
  74. BLOCK *
  75. getfunc()
  76. {
  77.     register BLOCK    *head;    /* starting block for this function */
  78.     register BLOCK    *cb;    /* the block we're currently reading */
  79.     register BLOCK    *ob;    /* the last block we read */
  80.  
  81.     if (saw_eof)
  82.         return NULL;
  83.  
  84.     head = NULL;
  85.  
  86.     /*
  87.      * Starting a global function
  88.      */
  89.     if (strcmp(t_op, "PUBLIC") == 0) { /* Jal - was ".global" */
  90.         /*
  91.          * Enter the symbol and mark it global.
  92.          */
  93.         head = mksym(t_arg);
  94.         head->flags |= B_GLOBAL;
  95.     
  96.         readline();
  97.     }
  98.  
  99.     ob = NULL;
  100.  
  101.     for (;;) {
  102.         if (ob == NULL) {
  103.             if (t_lab[0] != '_') {
  104.                 fprintf(stderr, "top: expected function label\n");
  105.                 exit(1);
  106.             }
  107.             if (head == NULL)
  108.                 head = mksym(t_lab);
  109.  
  110.         } else if (t_lab[0] == '\0') {
  111.             fprintf(stderr, "top: expected block label\n");
  112.             exit(1);
  113.         }
  114.  
  115.         if ((cb = getsym(t_lab)) == NULL)
  116.             cb = mksym(t_lab);
  117.  
  118.         /*
  119.          * The last block falls through to this one.
  120.          */
  121.         if (ob != NULL) {
  122.             ob->chain = cb;
  123.             ob->next = cb;
  124.             ob->bfall = cb;
  125.         }
  126.  
  127.         t_lab[0] = '\0';
  128.  
  129.         /*
  130.          * Now read lines until we hit a new block or another
  131.          * function.
  132.          */
  133.         for (;;) {
  134.             /*
  135.              * If we see a global, we're done with the function
  136.              */
  137.             if (strcmp(t_op, "PUBLIC") == 0)
  138.                 return head;
  139.             /*
  140.              * If we see a function label, we're done too.
  141.              */
  142.             if (t_lab[0] == '_')
  143.                 return head;
  144.             /*
  145.              * If we see any other label, we're done with the block.
  146.              */
  147.             if (t_lab[0])
  148.                 break;
  149.  
  150.             addinst(cb, t_op, t_arg);
  151.  
  152.             /*
  153.              * If we're at EOF, note the we've hit the end of
  154.              * file, but return the function we just read.
  155.              */
  156.             if (!readline()) {
  157.                 saw_eof = TRUE;
  158.                 return head;
  159.             }
  160.         }
  161.         ob = cb;
  162.     }
  163. }
  164.  
  165. /*
  166.  * putfunc(sb) - print out the function starting at block 'sb'
  167.  *
  168.  * The 'next' pointers determine the order in which things are placed
  169.  * in the file. Branch instructions have been removed so they need to
  170.  * be replaced here on output. Conditional branches are generated if
  171.  * indicated (by non-null 'bcond'). Unconditional branches are generated
  172.  * at the end of a block if it's "fall through" block isn't going to
  173.  * be the next thing in the file.
  174.  */
  175.  
  176. putfunc(sb)
  177. register BLOCK    *sb;
  178. {
  179.     register BLOCK    *cb;
  180.     register INST    *ci;
  181.  
  182.     fprintf(ofp, "*\n");
  183.     fprintf(ofp, "* %s\n", sb->name);
  184.     fprintf(ofp, "*\n");
  185. /*
  186.  * Jal - output just one code section at the beginning.
  187.  *    fprintf(ofp, "\tCODE CODE\n");
  188.  */
  189.     for (cb = sb; cb != NULL ;cb = cb->next) {
  190.         if (cb->flags & B_GLOBAL) /* Jal - .global -> PUBLIC */
  191.             fprintf(ofp, "\tPUBLIC\t%s\n", cb->name);
  192.  
  193.         if (*cb->name == '_')
  194.             fprintf(ofp, "%s:\n", cb->name);
  195.  
  196.         else if (cb->flags & B_LABEL)
  197.             fprintf(ofp, "%s:\n", cb->name);
  198. #ifdef    DEBUG
  199.         if (debug) {
  200.             fprintf(ofp, "*\n");
  201.             fprintf(ofp, "* %s, ref:%04x  set:%04x\n",
  202.                 cb->name, cb->rref, cb->rset);
  203.             fprintf(ofp, "*\n");
  204.         }
  205. #endif
  206.  
  207.         for (ci = cb->first; ci != NULL ;ci = ci->next)
  208.             putinst(ci);
  209.         /*
  210.          * If there's a conditional branch, put out the
  211.          * appropriate instruction for it.
  212.          */
  213.         if (cb->bcond != NULL && cb->bcode >= 0)
  214.             fprintf(ofp, "\t%s\t%s\n",
  215.                 opnames[cb->bcode], cb->bcond->name);
  216.         /*
  217.          * If there's a "fall through" label, and the destination
  218.          * block doesn't come next, put out a branch.
  219.          */
  220.         if (cb->bfall != NULL && cb->bfall != cb->next) {
  221.             s_badd++;
  222.             fprintf(ofp, "\tbra\t%s\n", cb->bfall->name);
  223.         }
  224.     }
  225. }
  226.