home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / c68k_src / register.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-10  |  4.6 KB  |  163 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or question
  18. s
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. /*
  27.  *      this module handles the allocation and de-allocation of
  28.  *      temporary registers. when a temporary register is allocated
  29.  *      the stack depth is saved in the field deep of the address
  30.  *      mode structure. when validate is called on an address mode
  31.  *      structure the stack is popped until the register is restored
  32.  *      to it's pre-push value.
  33.  */
  34.  
  35. struct amode    push[] = { {am_adec,7} },
  36.                 pop[] = { {am_ainc,7} };
  37. int             next_data,
  38.                 next_addr;
  39. int             max_data,
  40.                 max_addr;
  41.  
  42. gen_push(reg,rmode)
  43. /*
  44.  *      this routine generates code to push a register onto the stack
  45.  */
  46. int     reg, rmode;
  47. {       struct amode    *ap1;
  48.         ap1 = xalloc(sizeof(struct amode));
  49.         ap1->preg = reg;
  50.         ap1->mode = rmode;
  51.         gen_code(op_move,4,ap1,push);
  52. }
  53.  
  54. gen_pop(reg,rmode)
  55. /*
  56.  *      generate code to pop the primary register in ap from the
  57.  *      stack.
  58.  */
  59. int     reg, rmode;
  60. {       struct amode    *ap1;
  61.         ap1 = xalloc(sizeof(struct amode));
  62.         ap1->preg = reg;
  63.         ap1->mode = rmode;
  64.         gen_code(op_move,4,pop,ap1);
  65. }
  66.  
  67. initstack()
  68. /*
  69.  *      this routine should be called before each expression is
  70.  *      evaluated to make sure the stack is balanced and all of
  71.  *      the registers are marked free.
  72.  */
  73. {       next_data = 0;
  74.         next_addr = 0;
  75.         max_data = 2;
  76.         max_addr = 1;
  77. }
  78.  
  79. validate(ap)
  80. /*
  81.  *      validate will make sure that if a register within an address
  82.  *      mode has been pushed onto the stack that it is popped back
  83.  *      at this time.
  84.  */
  85. struct amode    *ap;
  86. {       switch( ap->mode )
  87.                 {
  88.                 case am_direct:
  89.                 case am_immed:
  90.                         return;         /* no registers used */
  91.                 case am_dreg:
  92.                         if( ap->preg > 2 )
  93.                                 return; /* not a temporary */
  94.                         if( max_data - ap->deep >= 3 )
  95.                                 {
  96.                                 gen_pop(ap->preg,am_dreg);
  97.                                 --max_data;
  98.                                 }
  99.                         break;
  100.                 default:
  101.                         if( ap->preg > 1 )
  102.                                 return; /* not a temp register */
  103.                         if( max_addr - ap->deep >= 2 )
  104.                                 {
  105.                                 gen_pop(ap->preg,am_areg);
  106.                                 --max_addr;
  107.                                 }
  108.                         break;
  109.                 }
  110. }
  111.  
  112. struct amode    *temp_data()
  113. /*
  114.  *      allocate a temporary data register and return it's
  115.  *      addressing mode.
  116.  */
  117. {       struct amode    *ap;
  118.         ap = xalloc(sizeof(struct amode));
  119.         ap->mode = am_dreg;
  120.         ap->preg = next_data % 3;
  121.         ap->deep = next_data;
  122.         if( next_data > max_data )
  123.                 {
  124.                 gen_push(next_data % 3,am_dreg);
  125.                 max_data = next_data;
  126.                 }
  127.         ++next_data;
  128.         return ap;
  129. }
  130.  
  131. struct amode    *temp_addr()
  132. /*
  133.  *      allocate a temporary address register and return it's
  134.  *      addressing mode.
  135.  */
  136. {       struct amode    *ap;
  137.         ap = xalloc(sizeof(struct amode));
  138.         ap->mode = am_areg;
  139.         ap->preg = next_addr % 2;
  140.         ap->deep = next_addr;
  141.         if( next_addr > max_addr )
  142.                 {
  143.                 gen_push(next_addr % 2,am_areg);
  144.                 max_addr = next_addr;
  145.                 }
  146.         ++next_addr;
  147.         return ap;
  148. }
  149.  
  150. freeop(ap)
  151. /*
  152.  *      release any temporary registers used in an addressing mode.
  153.  */
  154. struct amode    *ap;
  155. {       if( ap->mode == am_immed || ap->mode == am_direct )
  156.                 return;         /* no registers used */
  157.         if( ap->mode == am_dreg && ap->preg < 3 )
  158.                 --next_data;
  159.         else if( ap->preg < 2 )
  160.                 --next_addr;
  161. }
  162.  
  163.