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