tes.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef NORCSID
  2. static char rcsid[] = "$Id$";
  3. #endif
  4. /*
  5. * This file contains the main part of the top element size computation phase.
  6. *
  7. * Author: Hans van Eck.
  8. */
  9. #include <stdio.h>
  10. #include <em_spec.h>
  11. #include <em_mnem.h>
  12. #include <em_pseu.h>
  13. #include "param.h"
  14. #include "assert.h"
  15. #include "types.h"
  16. #include "tes.h"
  17. #include "alloc.h"
  18. #include "proinf.h"
  19. #include "line.h"
  20. #include "ext.h"
  21. #include "pop_push.h"
  22. extern char *pop_push[];
  23. extern char flow_tab[];
  24. #define NON_CONTINUABLE(i) (flow_tab[i]&JUMP)
  25. #define ISABRANCH(i) (flow_tab[i]&HASLABEL)
  26. #define ISCONDBRANCH(i) (flow_tab[i]&CONDBRA)
  27. #define INSTR(lnp) (lnp->l_instr & BMASK)
  28. #define TYPE(lnp) lnp->l_optyp
  29. #define SHORT(lnp) lnp->l_a.la_short
  30. #define MINI(lnp) ((lnp->l_optyp & BMASK) - Z_OPMINI)
  31. #define IS_MINI(lnp) (lnp->l_optyp >= OPMINI)
  32. #define IS_LOC(l) (l!=(line_p) 0 && INSTR(l)==op_loc && IS_MINI(l))
  33. int state;
  34. static int stacktop = 0;
  35. init_state()
  36. {
  37. stacktop = 0;
  38. state = KNOWN;
  39. }
  40. tes_pseudos()
  41. {
  42. register line_p lp;
  43. for (lp = pseudos; lp != (line_p)0; lp = lp->l_next) {
  44. switch(INSTR(lp)) {
  45. case ps_con:
  46. case ps_rom:
  47. if (lp->l_optyp == OPLIST) {
  48. register arg_p ap = lp->l_a.la_arg;
  49. while (ap != (arg_p) 0) {
  50. if (ap->a_typ == ARGNUM) {
  51. assign_label(ap->a_a.a_np->n_repl);
  52. }
  53. ap = ap->a_next;
  54. }
  55. } else if (lp->l_optyp == OPNUMLAB)
  56. assign_label(lp->l_a.la_np->n_repl);
  57. }
  58. }
  59. }
  60. tes_instr(lnp, x, y)
  61. line_p lnp, x, y;
  62. {
  63. char *s;
  64. register instr = INSTR(lnp);
  65. register int arg, argdef;
  66. int neg = 0;
  67. if (instr == op_lab) {
  68. do_inst_label(lnp);
  69. return;
  70. }
  71. if (instr < sp_fmnem || instr > sp_lmnem) {
  72. return;
  73. }
  74. if (state == NOTREACHED) return; /* What else ? */
  75. s = pop_push[instr];
  76. if (*s != '0') {
  77. while (*s != '\0') {
  78. neg = (*s++ == '-');
  79. if (TYPE(lnp) == OPSHORT) {
  80. arg = SHORT(lnp);
  81. if (arg < wordsize) arg = wordsize;
  82. argdef = TRUE;
  83. } else if (IS_MINI(lnp)) {
  84. arg = MINI(lnp);
  85. if (arg > 0 && arg < wordsize) arg = wordsize;
  86. if (arg < 0 && -arg < wordsize) arg = -wordsize;
  87. argdef = TRUE;
  88. } else {
  89. argdef = FALSE;
  90. }
  91. switch (*s++) {
  92. case 'w': stacktop = wordsize; break;
  93. case 'd': stacktop = wordsize * 2; break;
  94. case 'p': stacktop = pointersize; break;
  95. case 'a':
  96. if (argdef == FALSE || instr == op_ass) {
  97. stacktop = 0;
  98. } else {
  99. stacktop = arg;
  100. }
  101. break;
  102. case 'x':
  103. if (IS_LOC(x)) {
  104. arg = MINI(x);
  105. if (arg < wordsize) arg = wordsize;
  106. stacktop = arg;
  107. } else {
  108. stacktop = 0;
  109. }
  110. break;
  111. case 'y':
  112. if (IS_LOC(y)) {
  113. arg = MINI(y);
  114. if (arg < wordsize) arg = wordsize;
  115. stacktop = arg;
  116. } else {
  117. stacktop = 0;
  118. }
  119. break;
  120. case '?':
  121. stacktop = 0;
  122. break;
  123. default:
  124. assert(FALSE);
  125. }
  126. }
  127. /*
  128. * When the last argument was negative, the element size
  129. * must be negated. This is to catch 'asp -4'.
  130. */
  131. if (neg) stacktop = -stacktop;
  132. }
  133. if (stacktop < 0) stacktop = 0;
  134. if (ISABRANCH(instr)) do_inst_label(lnp);
  135. if (NON_CONTINUABLE(instr)) {
  136. state = NOTREACHED;
  137. stacktop = 0;
  138. }
  139. }
  140. assign_label(label)
  141. register num_p label;
  142. {
  143. if (label->n_flags & NUMSET) {
  144. if (state == NOTREACHED || stacktop > label->n_size) {
  145. stacktop = label->n_size;
  146. } else if ( stacktop < label->n_size) {
  147. label->n_size = stacktop;
  148. }
  149. } else {
  150. label->n_size = stacktop;
  151. label->n_flags |= NUMSET;
  152. }
  153. }
  154. do_inst_label(lnp) /* (re-)install a label */
  155. line_p lnp;
  156. {
  157. num_p label = lnp->l_a.la_np->n_repl;
  158. int instr = INSTR(lnp);
  159. assign_label(label);
  160. if (instr == op_lab) {
  161. if (state == NOTREACHED) {
  162. } else {
  163. label->n_flags |= NUMFALLTHROUGH;
  164. }
  165. } else if (ISCONDBRANCH(instr)) { /* conditional branch */
  166. label->n_flags |= NUMCOND;
  167. }
  168. state = KNOWN;
  169. }