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

编译器/解释器

开发平台:

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. #include  "diag.h"
  27. /* pc-relative expressions not optimized */
  28. extern int linkreg,basereg;
  29. extern AMODE    push[], pop[];
  30. extern OCODE    *peep_tail;
  31. extern SYM *currentfunc;
  32. extern int prm_stackcheck,prm_phiform,prm_linkreg,prm_rel, prm_smalldata;
  33. extern int floatregs,dataregs,addrregs;
  34. extern long framedepth,stackdepth;
  35. extern int cf_maxfloat, cf_maxaddress,cf_maxdata;
  36. extern int cf_freedata,cf_freeaddress;
  37. extern CSE       *olist;         /* list of optimizable expressions */
  38. long lc_maxauto;
  39. int save_mask, fsave_mask;
  40. void reserveregs(int *datareg, int *addreg, int *floatreg)
  41. /*
  42.  * Reserve regs goes through and reserves a register for variables with
  43.  * the REGISTER keyword.  Note that it currently does register allocation
  44.  * backwards...
  45.  */
  46. {
  47. CSE *csp = olist;
  48. while (csp) {
  49. switch (csp->exp->nodetype) {
  50. case en_floatref:
  51. case en_doubleref:
  52. case en_longdoubleref:
  53.                 case en_b_ref:
  54.                 case en_w_ref:
  55.                 case en_l_ref:
  56.                 case en_ub_ref:
  57.                 case en_uw_ref:
  58. case en_ul_ref:
  59. if (csp->exp->v.p[0]->nodetype != en_autoreg)
  60. break;
  61.    if (csp->exp->nodetype == en_floatref || csp->exp->nodetype == en_doubleref 
  62. || csp->exp->nodetype == en_longdoubleref) {
  63. if (*floatreg <cf_maxfloat && floatregs)
  64. csp->reg = (*floatreg)++;
  65. }
  66.                 else if( (*datareg < cf_maxdata) && (csp->duses <= csp->uses/4) && dataregs)
  67.                         csp->reg = (*datareg)++;
  68.                  else if(!(csp->size == 1 || csp->size == -1) && (*addreg < cf_maxaddress) &&addrregs)
  69.                         csp->reg = (*addreg)++;
  70. if (csp->reg != -1) {
  71. ((SYM *)csp->exp->v.p[0]->v.p[0])->inreg = TRUE;
  72. ((SYM *)csp->exp->v.p[0]->v.p[0])->value.i = -csp->reg;
  73. }
  74. break;
  75. }
  76. csp = csp->next;
  77. }
  78. }
  79. void allocate(int datareg, int addreg, int floatreg, SNODE *block )
  80. /*
  81.  *      allocate will allocate registers for the expressions that have
  82.  *      a high enough desirability.
  83.  */
  84. {       CSE      *csp;
  85.         ENODE    *exptr;
  86.         unsigned      mask, rmask,i,fmask,frmask,size;
  87.         AMODE    *ap, *ap2;
  88. framedepth = 4+lc_maxauto;
  89.         mask = 0;
  90. rmask = 0;
  91. fmask = frmask = 0;
  92. for (i=cf_freedata; i < datareg; i++) {
  93. framedepth+=4;
  94. rmask = rmask | (1 << (15 - i));
  95.                         mask = mask | (1 << i);
  96. }
  97. for (i=cf_freeaddress+16; i < addreg; i++) {
  98. framedepth+=4;
  99. rmask = rmask | (1 << (23 - i));
  100.                         mask = mask | (1 << (i-8));
  101. }
  102.         while( bsort(&olist) );         /* sort the expression list */
  103.         csp = olist;
  104.         while( csp != 0 ) {
  105. if (csp->reg == -1 && !(csp->exp->cflags & DF_VOL) && !csp->voidf) {
  106.                 if( desire(csp) < 3 )
  107.                         csp->reg = -1;
  108. else {
  109. if (csp->exp->nodetype == en_rcon || csp->exp->nodetype == en_fcon || csp->exp->nodetype == en_lrcon
  110.    || csp->exp->nodetype == en_floatref || csp->exp->nodetype ==en_doubleref
  111. || csp->exp->nodetype == en_longdoubleref) {
  112. if (floatreg <24 && floatregs)
  113. csp->reg = floatreg++;
  114. }
  115.             else if( (datareg < cf_maxdata) && (csp->duses <= csp->uses/4) && dataregs)
  116.                     csp->reg = (datareg)++;
  117.               else if( !(csp->size == 1 || csp->size == -1) && (addreg < cf_maxaddress) &&addrregs)
  118.                    csp->reg = (addreg)++;
  119. }
  120. }
  121.             if( csp->reg != -1 )
  122. {
  123. if (lvalue(csp->exp) && !((SYM *)csp->exp->v.p[0]->v.p[0])->funcparm) {
  124. ((SYM *)csp->exp->v.p[0]->v.p[0])->inreg = TRUE;
  125. ((SYM *)csp->exp->v.p[0]->v.p[0])->value.i = -csp->reg;
  126. }
  127. if (csp->reg < 16) {
  128. framedepth+=4;
  129. rmask = rmask | (1 << (15 - csp->reg));
  130.                         mask = mask | (1 << csp->reg);
  131. }
  132. else if (csp->reg < 32) {
  133. framedepth+=4;
  134. rmask = rmask | (1 << (23 - csp->reg));
  135.                         mask = mask | (1 << (csp->reg-8));
  136. }
  137. else {
  138. framedepth+=12;
  139. frmask = frmask | (1 << (39 - csp->reg));
  140.               fmask = fmask | (1 << (csp->reg-32));
  141. }
  142. }
  143.                 csp = csp->next;
  144.                 }
  145. allocstack(); /* Allocate stack space for the local vars */
  146. if (currentfunc->tp->lst.head !=0 && currentfunc->tp->lst.head != (SYM *)-1) {
  147. if (prm_phiform || currentfunc->intflag) {
  148. mask |= (1 << (linkreg +8));
  149. rmask |= (1 << (15 - linkreg -8));
  150. framedepth+=4;
  151. }
  152. if (currentfunc->intflag) {
  153. mask |= 0xffff;
  154. rmask |= 0xffff;
  155. framedepth = lc_maxauto;
  156. }
  157. }
  158. if (prm_linkreg && !currentfunc->intflag && (currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1 || lc_maxauto)) {
  159. gen_code(op_link,0,makeareg(linkreg),make_immed(-lc_maxauto));
  160. }
  161.   if( mask != 0 ) 
  162.               gen_code(op_movem,4,make_mask(rmask,0,0),push);
  163.         save_mask = mask;
  164. if (fmask!=0)
  165.                 gen_code(op_fmovem,10,make_mask(frmask,0,1),push);
  166. fsave_mask = fmask;
  167. if ((prm_phiform || currentfunc->intflag) && currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *) -1) {
  168. gen_code(op_move,4,makeareg(0), makeareg(linkreg));
  169. }
  170. if ((!prm_linkreg || currentfunc->intflag) && lc_maxauto) {
  171. AMODE *ap = xalloc(sizeof(AMODE)); 
  172. ap->mode = am_indx;
  173. ap->offset = makenode(en_icon,(char *)-lc_maxauto,0);
  174. ap->preg = 7;
  175.           gen_code(op_lea,0,ap,makeareg(7));
  176. }
  177. if (prm_stackcheck) {
  178. AMODE *ap1;
  179. ap = set_symbol("_stackerror",1);
  180. ap1 = set_symbol("_stackbottom",0);
  181. if (prm_rel) {
  182. ap1->mode = am_indx;
  183. ap1->preg = basereg;
  184. }
  185. else {
  186. ap1->mode = am_adirect;
  187. if (prm_smalldata)
  188. ap1->preg = 2;
  189. else
  190. ap1->preg = 4;
  191. }
  192. gen_code(op_cmp,4,ap1,makeareg(7));
  193. gen_code(op_bhi,0,ap,0);
  194. }
  195. }
  196. void loadregs(void)
  197. /*
  198.  * Initailze allocated regs
  199.  *
  200.  */
  201. {       CSE      *csp;
  202.         ENODE    *exptr;
  203.         unsigned      mask, rmask,i,fmask,frmask,size;
  204.         AMODE    *ap, *ap2;
  205.         csp = olist;
  206.         while( csp != 0 ) {
  207. int sz;
  208.                 if( csp->reg != -1 )
  209.                         {               /* see if preload needed */
  210.                         exptr = csp->exp;
  211.                         if( !lvalue(exptr) || ((SYM *)exptr->v.p[0]->v.p[0])->funcparm )
  212.                                 {
  213. exptr = csp->exp;
  214.                                 initstack();
  215. sz = csp->size;
  216.                                 ap = gen_expr(exptr,F_ALL,sz);
  217.                   if (sz == 0 && ap->mode == am_immed)
  218. sz = 4;
  219.                                 if( csp->reg < 16 ) {
  220.                    if (sz == 0 && ap->mode == am_immed)
  221. sz = 4;
  222. if (ap->mode == am_dreg)
  223. peep_tail->oper2->preg = csp->reg;
  224. else {
  225.                                         ap2 = makedreg(csp->reg);
  226.                                  gen_code(op_move,sz,ap,ap2);
  227. do_extend(ap2,sz,4,F_DREG);
  228. }
  229. }
  230.                                 else
  231. if (csp->reg < 32) {
  232.                    if (sz == 0 && ap->mode == am_immed)
  233. sz = 4;
  234. if (ap->mode == am_areg)
  235. peep_tail->oper2->preg = csp->reg - 16;
  236. else {
  237.                                          ap2 = makeareg(csp->reg - 16);
  238.                                   gen_code(op_move,4,ap,ap2);
  239. }
  240. }
  241. else {
  242.                   if (sz == 0 && ap->mode == am_immed)
  243. sz = 8;
  244. if (ap->mode == am_freg)
  245. peep_tail->oper2->preg = csp->reg - 32;
  246. else {
  247.                                          ap2 = makefreg(csp->reg - 32);
  248. size = 8;
  249. if (exptr->nodetype == en_floatref)
  250. size = 6;
  251.                                   gen_code(op_fmove,size,ap,ap2);
  252. }
  253. }
  254.                                 freeop(ap);
  255. if (lvalue(exptr) && ((SYM *)exptr->v.p[0]->v.p[0])->funcparm) {
  256. ((SYM *)exptr->v.p[0]->v.p[0])->inreg = TRUE;
  257. ((SYM *)exptr->v.p[0]->v.p[0])->value.i = -csp->reg;
  258. }
  259.                                 }
  260.                         }
  261.                 csp = csp->next;
  262.                 }
  263. }
  264. void voidfloat(SNODE *block)
  265. {
  266. }
  267. void asm_scan(OCODE *cd)
  268. {
  269. }
  270. void asm_repcse(OCODE *cd)
  271. {
  272. }