REG68.C
上传用户:hlzzc88
上传日期:2007-01-06
资源大小:220k
文件大小:6k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. #include        <stdio.h>
  23. #include        "expr.h"
  24. #include        "c.h"
  25. #include        "gen68.h"
  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. extern int cf_freedata,cf_freeaddress,cf_freefloat,maxdata,maxaddress;
  35. AMODE    push[] = { {am_adec,7} },
  36.                 pop[] = { {am_ainc,7} };
  37. int             next_data, /* Next available */
  38.                 next_addr;
  39. int             max_data, /* Max available */
  40.                 max_addr;
  41. int next_float, max_float;
  42. long stackdepth,framedepth;
  43. char regstack[20],rsold[30],rsdepth = 0,rsodepth=0;
  44. char aregs[8],dregs[8],fregs[8];
  45. void regini(void)
  46. {
  47. int i;
  48. for (i=0; i < 8; i++) {
  49. aregs[0] = dregs[0] = fregs[0] = 0;
  50. }
  51. rsdepth = rsodepth = 0;
  52. }
  53. void gen_push(int reg, int rmode, int flag)
  54. /*
  55.  *      this routine generates code to push a register onto the stack
  56.  */
  57. {       AMODE    *ap1;
  58.         ap1 = xalloc(sizeof(AMODE));
  59.         ap1->preg = reg;
  60.         ap1->mode = rmode;
  61. if (rmode == am_freg) {
  62.           gen_code(op_fmove,10,ap1,push);
  63. stackdepth +=8;
  64. }
  65. else {
  66.           gen_code(op_move,4,ap1,push);
  67. stackdepth +=4;
  68. }
  69. }
  70. void gen_pop(int reg, int rmode, int flag)
  71. /*
  72.  *      generate code to pop the primary register in ap from the
  73.  *      stack.
  74.  */
  75. {       AMODE    *ap1;
  76.         ap1 = xalloc(sizeof(AMODE));
  77.         ap1->preg = reg;
  78.         ap1->mode = rmode;
  79. if (rmode == am_freg) {
  80.          gen_code(op_fmove,10,pop,ap1);
  81. stackdepth -=8;
  82. }
  83. else {
  84.          gen_code(op_move,4,pop,ap1);
  85. stackdepth -=4;
  86. }
  87. }
  88. void initstack(void)
  89. /*
  90.  *      this routine should be called before each expression is
  91.  *      evaluated to make sure the stack is balanced and all of
  92.  *      the registers are marked free.
  93.  */
  94. {
  95. int i;
  96. for (i=0; i < 8; i++) 
  97. aregs[0] = dregs[0] = fregs[0] = 0;
  98. rsdepth = rsodepth = 0;
  99.        next_data = 0;
  100.         next_addr = 0;
  101.         max_data = cf_freedata-1;
  102.         max_addr = cf_freeaddress-1;
  103. next_float = 0;
  104. max_float = cf_freefloat-1;
  105. }
  106. void mark(void)
  107. {
  108. rsold[rsodepth++] = rsdepth;
  109. }
  110. void release(void)
  111. {
  112. if (!rsodepth)
  113. return;
  114. rsodepth--;
  115. while (rsdepth > rsold[rsodepth]) {
  116. int data = regstack[--rsdepth];
  117. if (data <8) {
  118. gen_pop(data,am_dreg,0);
  119. dregs[data] = 1;
  120. }
  121. else
  122. if (data < 16) {
  123. gen_pop(data & 7,am_areg,0);
  124. aregs[data-8] = 1;
  125. }
  126. else {
  127. gen_pop(data & 7,am_freg,0);
  128. fregs[data-16] = 1;
  129. }
  130. }
  131.   max_addr = next_addr < cf_freeaddress ? cf_freeaddress-1 : next_addr-1;
  132. max_data = next_data < cf_freedata ? cf_freedata-1 : next_data-1;
  133. max_float = next_float < cf_freefloat ? cf_freefloat-1 : next_float-1;
  134. }
  135. AMODE    *temp_data(void)
  136. /*
  137.  *      allocate a temporary data register and return it's
  138.  *      addressing mode.
  139.  */
  140. {       AMODE    *ap;
  141.         ap = xalloc(sizeof(AMODE));
  142.         ap->mode = am_dreg;
  143.         ap->preg = next_data % cf_freedata;
  144.         if( next_data > max_data )
  145.                 {
  146.                 gen_push(ap->preg,am_dreg,0);
  147. dregs[ap->preg] = 1;
  148. regstack[rsdepth++] = ap->preg;
  149.                 max_data = next_data;
  150.                 }
  151.         ++next_data;
  152.         return ap;
  153. }
  154. AMODE    *temp_addr(void)
  155. /*
  156.  *      allocate a temporary address register and return it's
  157.  *      addressing mode.
  158.  */
  159. {       AMODE    *ap;
  160.         ap = xalloc(sizeof(AMODE));
  161.         ap->mode = am_areg;
  162.         ap->preg = next_addr % cf_freeaddress;
  163.         if( next_addr > max_addr )
  164.                 {
  165.                 gen_push(ap->preg,am_areg,0);
  166. aregs[ap->preg] = 1;
  167. regstack[rsdepth++] = ap->preg+8;
  168.                 max_addr = next_addr;
  169.                 }
  170.         ++next_addr;
  171.         return ap;
  172. }
  173. AMODE    *temp_float(void)
  174. /*
  175.  *      allocate a temporary address register and return it's
  176.  *      addressing mode.
  177.  */
  178. {       AMODE    *ap;
  179.         ap = xalloc(sizeof(AMODE));
  180.         ap->mode = am_freg;
  181.         ap->preg = next_float % cf_freefloat;
  182.         if( next_float > max_float )
  183.                 {
  184.                 gen_push(ap->preg,am_freg,0);
  185. fregs[ap->preg] = 1;
  186. regstack[rsdepth++] = ap->preg+16;
  187.                 max_addr = next_float;
  188.                 }
  189.         ++next_float;
  190.         return ap;
  191. }
  192. void freedata(int dreg)
  193. {
  194. if (dreg < cf_freedata && next_data > 0) {
  195. dregs[dreg] = 0;
  196. --next_data;
  197. }
  198. }
  199. void freeaddr(int areg)
  200. {
  201. if (areg < cf_freeaddress && next_addr > 0) {
  202. aregs[areg] = 0;
  203. --next_addr;
  204. }
  205. }
  206. void freeop(AMODE *ap)
  207. /*
  208.  *      release any temporary registers used in an addressing mode.
  209.  */
  210. {       if( ap->mode == am_immed || ap->mode == am_direct )
  211.                 return;         /* no registers used */
  212.         if( ap->mode == am_dreg)
  213. freedata(ap->preg);
  214.         else if( ap->mode == am_areg || ap->mode == am_ind || ap->mode == am_indx || ap->mode == am_adec || ap->mode == am_ainc)
  215. freeaddr(ap->preg);
  216.         else if( ap->mode == am_freg && ap->preg < cf_freefloat && next_float>0) {
  217. fregs[ap->preg] = 0;
  218.                  --next_float;
  219. }
  220. else if (ap->mode == am_baseindxdata) {
  221. freeaddr(ap->preg);
  222. freedata(ap->sreg);
  223. }
  224. else if (ap->mode == am_baseindxaddr) {
  225. freeaddr(ap->preg);
  226. freeaddr(ap->sreg);
  227. }
  228. }