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

编译器/解释器

开发平台:

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. /*
  23.  * Register analysis
  24.  */
  25. #include        <stdio.h>
  26. #include        "expr.h"
  27. #include        "c.h"
  28. #include        "gen386.h"
  29. #include  "diag.h"
  30. /* pc-relative expressions not optimized */
  31. extern AMODE    push[], pop[];
  32. extern OCODE    *peep_tail;
  33. extern SYM *currentfunc;
  34. extern int prm_stackcheck,prm_linkreg;
  35. extern int floatregs,dataregs,addrregs;
  36. extern long framedepth,stackdepth;
  37. extern int cf_maxfloat, cf_maxaddress,cf_maxdata,cf_freeaddress,cf_freedata,cf_freefloat;
  38. extern CSE       *olist;         /* list of optimizable expressions */
  39. long lc_maxauto;
  40. int  fsave_mask,save_mask;
  41. void reserveregs(int *datareg, int *addreg, int *floatreg)
  42. /*
  43.  * Reserve regs goes through and reserves a register for variables with
  44.  * the REGISTER keyword.  Note that it currently does register allocation
  45.  * backwards...  NOT the standard I suspect.
  46.  */
  47. {
  48. CSE *csp = olist;
  49. while (csp) {
  50. switch (csp->exp->nodetype) {
  51. case en_floatref:
  52. case en_doubleref:
  53. case en_longdoubleref:
  54. break;
  55.                 case en_b_ref:
  56.                 case en_w_ref:
  57.                 case en_l_ref:
  58.                 case en_ub_ref:
  59.                 case en_uw_ref:
  60. case en_ul_ref:
  61. if (csp->exp->v.p[0]->nodetype != en_autoreg)
  62. break;
  63.    if (csp->exp->nodetype == en_floatref || csp->exp->nodetype == en_doubleref 
  64. || csp->exp->nodetype == en_longdoubleref) {
  65. }
  66.                  else if( (csp->duses <= csp->uses / 4) && (*datareg < cf_maxdata) &&dataregs)
  67.                         csp->reg = (*datareg)++;
  68.                 else if(!(csp->size ==-1 || csp->size ==1) && (*addreg < cf_maxaddress) && addrregs) {
  69.                         csp->reg = (*addreg)++;
  70. }
  71. if (csp->reg != -1) {
  72. ((SYM *)csp->exp->v.p[0]->v.p[0])->inreg = TRUE;
  73. ((SYM *)csp->exp->v.p[0]->v.p[0])->value.i = -csp->reg;
  74. }
  75. break;
  76. }
  77. csp = csp->next;
  78. }
  79. }
  80. void allocate(int datareg, int addreg, int floatreg, SNODE *block )
  81. /*
  82.  *      allocate will allocate registers for the expressions that have
  83.  *      a high enough desirability.  It also puts the function
  84.  * header, consisting of saved registers and stack decrments for local
  85.  * variables
  86.  */
  87. {       CSE      *csp;
  88.         ENODE    *exptr;
  89.         unsigned      mask, rmask,i,fmask,frmask,size;
  90.         AMODE    *ap, *ap2;
  91. framedepth = 4;
  92.         mask = 0;
  93. rmask = 0;
  94. fmask = frmask = 0;
  95. for (i=cf_freedata; i < datareg; i++) {
  96. rmask = rmask | (1 << (15 - i));
  97.                         mask = mask | (1 << i);
  98. }
  99. for (i=cf_freeaddress+16; i < addreg; i++) {
  100. rmask = rmask | (1 << (23 - i));
  101.                         mask = mask | (1 << (i-8));
  102. }
  103.         while( bsort(&olist) );         /* sort the expression list */
  104.         csp = olist;
  105.         while( csp != 0 ) {
  106. if (csp->reg == -1 && !(csp->exp->cflags & DF_VOL) && !csp->voidf) {
  107.                 if( desire(csp) < 3 )
  108.                         csp->reg = -1;
  109. else {
  110. if (csp->exp->nodetype == en_rcon || csp->exp->nodetype == en_fcon || csp->exp->nodetype == en_lrcon
  111.    || csp->exp->nodetype == en_floatref || csp->exp->nodetype ==en_doubleref
  112. || csp->exp->nodetype == en_longdoubleref) {
  113. }
  114.              else if( (csp->duses <= csp->uses / 4) && (datareg < cf_maxdata) &&dataregs)
  115.                    csp->reg = (datareg)++;
  116.                 else if( (!(csp->size == 1 || csp->size == -1) || csp->exp->nodetype == en_icon) && (addreg < cf_maxaddress) && addrregs) {
  117.                    csp->reg = (addreg)++;
  118. }
  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. rmask = rmask | (1 << (15 - csp->reg));
  129.                         mask = mask | (1 << csp->reg);
  130. }
  131. if (csp->reg < 32) {
  132. rmask = rmask | (1 << (23 - csp->reg));
  133.                         mask = mask | (1 << (csp->reg-8));
  134. }
  135. else {
  136. frmask = frmask | (1 << (39 - csp->reg));
  137.               fmask = fmask | (1 << (csp->reg-32));
  138. }
  139. }
  140.                 csp = csp->next;
  141.                 }
  142. allocstack(); /* Allocate stack space for the local vars */
  143. if (prm_linkreg && (lc_maxauto || currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM *)-1)) {
  144. gen_code(op_enter,4,make_immed(lc_maxauto),make_immed(0));
  145. }
  146. if (currentfunc->intflag) {
  147. gen_code(op_pushad,0,0,0);
  148. stackdepth = 4*8;
  149. }
  150.         else
  151.   if( mask != 0 ) 
  152. pushregs(rmask);
  153.         save_mask = mask;
  154. if (fmask!=0)
  155. fsave_mask = fmask;
  156. if (!prm_linkreg && lc_maxauto) {
  157. gen_code(op_sub,4,makedreg(ESP), make_immed(lc_maxauto));
  158. }
  159. stackdepth +=lc_maxauto;
  160. framedepth +=stackdepth;
  161. stackdepth = 0;
  162. if (prm_stackcheck) {
  163. AMODE *ap1;
  164. ap = set_symbol("_stackerror",1);
  165. ap1 = set_symbol("_stackbottom",0);
  166. ap1->mode = am_direct;
  167. gen_code(op_cmp,4,makedreg(ESP),ap1);
  168. gen_code(op_jb,0,ap,0);
  169. }
  170. }
  171. void loadregs(void)
  172. /*
  173.  * initialize allocated registers
  174.  */
  175. {       CSE      *csp;
  176.         ENODE    *exptr;
  177.         unsigned      mask, rmask,i,fmask,frmask,size;
  178.         AMODE    *ap, *ap2;
  179.         csp = olist;
  180.         while( csp != 0 ) {
  181. int sz;
  182.                 if( csp->reg != -1 )
  183.                         {               /* see if preload needed */
  184.                         exptr = csp->exp;
  185.                         if( !lvalue(exptr) || ((SYM *)exptr->v.p[0]->v.p[0])->funcparm )
  186.                                 {
  187. exptr = csp->exp;
  188.                                 initstack();
  189. sz = csp->size;
  190.                                 ap = gen_expr(exptr,F_ALL,sz);
  191.                                 if( csp->reg < 16 ) {
  192. if (ap->mode == am_dreg)
  193. peep_tail->oper1->preg = csp->reg;
  194. else {
  195.                                         ap2 = makedreg(csp->reg);
  196. if (ap->mode == am_immed || sz == 4 || sz == -4)
  197.                                  gen_code(op_mov,4,ap2,ap);
  198. else
  199. if (sz < 0)
  200. gen_code2(op_movsx,-4,sz,ap2,ap);
  201. else
  202. gen_code2(op_movzx,4,sz,ap2,ap);
  203. }
  204. }
  205.                                 else
  206. if (csp->reg < 32) {
  207. if (ap->mode == am_dreg)
  208. peep_tail->oper1->preg = csp->reg - 12;
  209. else {
  210.                                          ap2 = makedreg(csp->reg - 12);
  211. if (ap->mode == am_immed || sz == 4 || sz == -4)
  212.                                   gen_code(op_mov,4,ap2,ap);
  213. else
  214. if (sz < 0)
  215. gen_code2(op_movsx,-4,sz,ap2,ap);
  216. else
  217. gen_code2(op_movzx,4,sz,ap2,ap);
  218. }
  219. }
  220. else {
  221. /* Should never get here */
  222. DIAG("float reg assigned in analyze");
  223. }
  224.                                 freeop(ap);
  225. if (lvalue(exptr) && ((SYM *)exptr->v.p[0]->v.p[0])->funcparm) {
  226. ((SYM *)exptr->v.p[0]->v.p[0])->inreg = TRUE;
  227. ((SYM *)exptr->v.p[0]->v.p[0])->value.i = -csp->reg;
  228. }
  229.                                 }
  230.                         }
  231.                 csp = csp->next;
  232.                 }
  233. }
  234. void asm_scannode (ENODE *node)
  235. {
  236. CSE *csp;
  237. if (node->nodetype == en_add) {
  238. asm_scannode(node->v.p[0]);
  239. asm_scannode(node->v.p[1]);
  240. }
  241. else {
  242. switch (node->nodetype) {
  243.                 case en_icon:
  244. case en_lcon:
  245. case en_iucon:
  246. case en_lucon:
  247. case en_ccon:
  248.                         break;
  249.                 case en_napccon:
  250.                 case en_nacon:
  251. case en_absacon:
  252.                 case en_autocon:
  253.                 case en_autoreg:
  254. csp = enternode(node,0,0);
  255. csp->voidf = TRUE;
  256.                         break;
  257. case en_labcon: case en_nalabcon:
  258. break;
  259. default:
  260. DIAG("Invalid node in assembler line");
  261. break;
  262. }
  263. }
  264. }
  265. void asm_scan1(AMODE *ap)
  266. {
  267. if (!ap || !ap->offset)
  268. return;
  269. asm_scannode(ap->offset);
  270. }
  271. void asm_scan(OCODE *cd)
  272. {
  273. asm_scan1(cd->oper1);
  274. asm_scan1(cd->oper2);
  275. asm_scan1(cd->oper3);
  276. }
  277. void asm_repnode(ENODE **node)
  278. {
  279. if ((*node)->nodetype == en_add) {
  280. asm_repnode(&(*node)->v.p[0]);
  281. asm_repnode(&(*node)->v.p[1]);
  282. }
  283. else
  284.         if( (*node)->nodetype == en_autocon  || (*node)->nodetype == en_autoreg)
  285.                 {
  286. if (prm_linkreg) {
  287.             *node = makenode(en_icon,(char *)((SYM *)(*node)->v.p[0])->value.i,0);
  288. }
  289. else if (((SYM *)(*node)->v.p[0])->funcparm)
  290.                  *node = makenode(en_icon,(char *)(((SYM *)(*node)->v.p[0])->value.i+framedepth+stackdepth),0);
  291.                 else
  292. *node = makenode(en_icon,(char *)(((SYM *)(*node)->v.p[0])->value.i+stackdepth+lc_maxauto),0);
  293.                 }
  294.         else if( (*node)->nodetype == en_nacon || (*node)->nodetype == en_napccon)
  295.                 {
  296.                 *node = makenode((*node)->nodetype,(char *)((SYM *)(*node)->v.p[0])->name,0);
  297.                 }
  298.         else if( (*node)->nodetype == en_nalabcon)
  299.                 {
  300.                 *node = makenode((*node)->nodetype,(char *)(*node)->v.i,0);
  301.                 }
  302.         else if( (*node)->nodetype == en_labcon)
  303.                 {
  304.                 *node = makenode((*node)->nodetype,(char *)(*node)->v.i,0);
  305.                 }
  306. else if ((*node)->nodetype == en_absacon) {
  307. *node = makenode(en_absacon,(char *)((SYM *)(*node)->v.p[0])->value.i,0);
  308. }
  309. }
  310. int voidexpr(ENODE *node)
  311. {       CSE      *csp;
  312.         if( node == 0 )
  313.                 return 0;
  314.         switch( node->nodetype ) {
  315.                 case en_rcon: case en_lrcon: case en_fcon:
  316. return 1;
  317.                 case en_icon:
  318. case en_lcon:
  319. case en_iucon:
  320. case en_lucon:
  321. case en_ccon:
  322.                 case en_nacon:
  323.                 case en_napccon:
  324. case en_absacon:
  325.                 case en_autocon:
  326. case en_autoreg:
  327. return 0;
  328. case en_floatref:
  329. case en_doubleref:
  330. case en_longdoubleref:
  331. return 1;
  332.                 case en_ub_ref:
  333.                 case en_uw_ref:
  334.                 case en_b_ref:
  335.                 case en_w_ref:
  336.                 case en_l_ref:
  337.                 case en_ul_ref:
  338. return 0;
  339.                 case en_uminus: case en_bits:
  340.                 case en_not:    case en_compl:
  341.                 case en_ainc:   case en_adec:
  342.                         return voidexpr(node->v.p[0]);
  343. case en_cb: case en_cub:
  344. case en_cw: case en_cuw:
  345. case en_cl: case en_cul:
  346. case en_cf: case en_cd: case en_cp: case en_cld:
  347.                         return voidexpr(node->v.p[0]);
  348.                 case en_add:    case en_sub:
  349.                 case en_umul:    case en_udiv: case en_umod:
  350.                 case en_mul:    case en_div:
  351.                 case en_mod:    case en_lsh:
  352. case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  353.                 case en_rsh:    case en_and:
  354.                 case en_or:     case en_xor:
  355.                 case en_land:   case en_lor:
  356.                 case en_eq:     case en_ne:
  357.                 case en_lt:     case en_le:
  358. case en_ugt: case en_uge: case en_ult: case en_ule:
  359.                 case en_gt:     case en_ge:
  360.                 case en_cond:   case en_void:
  361. case en_pmul:
  362.                 case en_fcall: case en_trapcall: case en_pdiv:
  363. case en_pfcall: case en_pfcallb:
  364.                 case en_intcall: case en_fcallb:
  365.                 case en_moveblock: case en_stackblock: case en_callblock:
  366. case en_pcallblock:
  367.                         return voidexpr(node->v.p[0]) || voidexpr(node->v.p[1]);
  368.                 case en_asadd:  case en_assub:
  369.                 case en_asmul:  case en_asdiv:
  370.                 case en_asor:   case en_asand:   case en_asxor:
  371.                 case en_asmod:  case en_aslsh:
  372. case en_asumod: case en_asudiv: case en_asumul:
  373.                 case en_asrsh: case en_assign: case en_refassign:
  374. if (voidexpr(node->v.p[1])) {
  375. csp = searchnode(node->v.p[0]);
  376. if (csp)
  377. csp->voidf = 1;
  378. }
  379. return voidexpr(node->v.p[0]);
  380. default:
  381. return 0;
  382.                 }
  383. }
  384. void voidfloat(SNODE *block)
  385. /*
  386.  * Scan through a block and void all CSEs which do asadd, asmul, asmodiv
  387.  * of float to int
  388.  */
  389. {       while( block != 0 ) {
  390.                 switch( block->stype ) {
  391.                         case st_return:
  392.                         case st_expr:
  393.                                 voidexpr(block->exp);
  394.                                 break;
  395.                         case st_while:
  396.                         case st_do:
  397.                                 voidexpr(block->exp);
  398.                                 voidfloat(block->s1);
  399.                                 break;
  400.                         case st_for:
  401.                                 voidexpr(block->label);
  402.                                 voidexpr(block->exp);
  403.                                 voidfloat(block->s1);
  404.                                 voidexpr(block->s2);
  405.                                 break;
  406.                         case st_if:
  407.                                 voidexpr(block->exp);
  408.                                 voidfloat(block->s1);
  409.                                 voidfloat(block->s2);
  410.                                 break;
  411.                         case st_switch:
  412.                                 voidexpr(block->exp);
  413.                                 voidfloat(block->s1);
  414.                                 break;
  415.                         case st_case:
  416.                                 voidfloat(block->s1);
  417.                                 break;
  418. case st_block:
  419. voidfloat(block->exp);
  420. break;
  421.                         }
  422.                 block = block->next;
  423.                 }
  424. }
  425. void asm_repcse1(AMODE *ap)
  426. {
  427. if (!ap || !ap->offset)
  428. return;
  429. asm_repnode(&ap->offset);
  430. }
  431. void asm_repcse(OCODE *cd)
  432. {
  433. asm_repcse1(cd->oper1);
  434. asm_repcse1(cd->oper2);
  435. asm_repcse1(cd->oper3);
  436. }