home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / sozobon / scsrc20 / top / func.c < prev    next >
C/C++ Source or Header  |  1991-02-22  |  5KB  |  214 lines

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