util.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* M I S C E L L A N E O U S U T I L I T I E S */
  6. /* $Header$ */
  7. /* Code for the allocation and de-allocation of temporary variables,
  8. allowing re-use.
  9. */
  10. #include <em.h>
  11. #include <em_reg.h>
  12. #include <alloc.h>
  13. #include <em_mes.h>
  14. #include "util.h"
  15. #include "use_tmp.h"
  16. #include "regcount.h"
  17. #include "sizes.h"
  18. #include "align.h"
  19. #include "stack.h"
  20. #include "Lpars.h"
  21. #include "def.h"
  22. static struct localvar *FreeTmps;
  23. #ifdef USE_TMP
  24. static int loc_id;
  25. #endif USE_TMP
  26. #ifdef PEEPHOLE
  27. #undef REGCOUNTING
  28. #define REGCOUNTING 1
  29. #endif
  30. extern char options[];
  31. LocalInit()
  32. {
  33. #ifdef USE_TMP
  34. C_insertpart(loc_id = C_getid());
  35. #endif USE_TMP
  36. }
  37. arith
  38. LocalSpace(sz, al)
  39. arith sz;
  40. {
  41. register struct stack_level *stl = local_level;
  42. stl->sl_max_block = - align(sz - stl->sl_max_block, al);
  43. return stl->sl_max_block;
  44. }
  45. #define TABSIZ 32
  46. static struct localvar *regs[TABSIZ];
  47. arith
  48. NewLocal(sz, al, regtype, sc)
  49. arith sz;
  50. {
  51. register struct localvar *tmp = FreeTmps;
  52. struct localvar *prev = 0;
  53. register int index;
  54. while (tmp) {
  55. if (tmp->t_align >= al &&
  56. tmp->t_size >= sz &&
  57. tmp->t_sc == sc &&
  58. tmp->t_regtype == regtype) {
  59. if (prev) {
  60. prev->next = tmp->next;
  61. }
  62. else FreeTmps = tmp->next;
  63. break;
  64. }
  65. prev = tmp;
  66. tmp = tmp->next;
  67. }
  68. if (! tmp) {
  69. tmp = new_localvar();
  70. tmp->t_offset = LocalSpace(sz, al);
  71. tmp->t_align = al;
  72. tmp->t_size = sz;
  73. tmp->t_sc = sc;
  74. tmp->t_regtype = regtype;
  75. tmp->t_count = REG_DEFAULT;
  76. }
  77. index = (int) (tmp->t_offset >> 2) & (TABSIZ - 1);
  78. tmp->next = regs[index];
  79. regs[index] = tmp;
  80. return tmp->t_offset;
  81. }
  82. FreeLocal(off)
  83. arith off;
  84. {
  85. int index = (int) (off >> 2) & (TABSIZ - 1);
  86. register struct localvar *tmp = regs[index];
  87. struct localvar *prev = 0;
  88. while (tmp && tmp->t_offset != off) {
  89. prev = tmp;
  90. tmp = tmp->next;
  91. }
  92. if (tmp) {
  93. if (prev) prev->next = tmp->next;
  94. else regs[index] = tmp->next;
  95. tmp->next = FreeTmps;
  96. FreeTmps = tmp;
  97. }
  98. }
  99. LocalFinish()
  100. {
  101. register struct localvar *tmp, *tmp1;
  102. register int i;
  103. #ifdef USE_TMP
  104. C_beginpart(loc_id);
  105. #endif
  106. tmp = FreeTmps;
  107. while (tmp) {
  108. tmp1 = tmp;
  109. if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
  110. if (! options['n'] && tmp->t_regtype >= 0) {
  111. C_ms_reg(tmp->t_offset, tmp->t_size, tmp->t_regtype, tmp->t_count);
  112. }
  113. tmp = tmp->next;
  114. free_localvar(tmp1);
  115. }
  116. FreeTmps = 0;
  117. for (i = 0; i < TABSIZ; i++) {
  118. tmp = regs[i];
  119. while (tmp) {
  120. if (tmp->t_sc == REGISTER) tmp->t_count += REG_BONUS;
  121. tmp1 = tmp;
  122. if (! options['n'] && tmp->t_regtype >= 0) {
  123. C_ms_reg(tmp->t_offset,
  124. tmp->t_size,
  125. tmp->t_regtype,
  126. tmp->t_count);
  127. }
  128. tmp = tmp->next;
  129. free_localvar(tmp1);
  130. }
  131. regs[i] = 0;
  132. }
  133. if (! options['n']) {
  134. C_mes_begin(ms_reg);
  135. C_mes_end();
  136. }
  137. #ifdef USE_TMP
  138. C_endpart(loc_id);
  139. #endif
  140. }
  141. RegisterAccount(offset, size, regtype, sc)
  142. arith offset, size;
  143. {
  144. register struct localvar *p;
  145. int index;
  146. if (regtype < 0) return;
  147. p = new_localvar();
  148. index = (int) (offset >> 2) & (TABSIZ - 1);
  149. p->t_offset = offset;
  150. p->t_regtype = regtype;
  151. p->t_count = REG_DEFAULT;
  152. p->t_sc = sc;
  153. p->t_size = size;
  154. p->next = regs[index];
  155. regs[index] = p;
  156. }
  157. static struct localvar *
  158. find_reg(off)
  159. arith off;
  160. {
  161. register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)];
  162. while (p && p->t_offset != off) p = p->next;
  163. return p;
  164. }
  165. LoadLocal(off, sz)
  166. arith off, sz;
  167. {
  168. register struct localvar *p = find_reg(off);
  169. #ifdef USE_TMP
  170. #ifdef REGCOUNTING
  171. if (p) p->t_count++;
  172. #endif
  173. #endif
  174. if (sz == word_size) C_lol(off);
  175. else if (sz == dword_size) C_ldl(off);
  176. else {
  177. if (p) p->t_regtype = -1;
  178. C_lal(off);
  179. C_loi(sz);
  180. }
  181. }
  182. StoreLocal(off, sz)
  183. arith off, sz;
  184. {
  185. register struct localvar *p = find_reg(off);
  186. #ifdef USE_TMP
  187. #ifdef REGCOUNTING
  188. if (p) p->t_count++;
  189. #endif
  190. #endif
  191. if (sz == word_size) C_stl(off);
  192. else if (sz == dword_size) C_sdl(off);
  193. else {
  194. if (p) p->t_regtype = -1;
  195. C_lal(off);
  196. C_sti(sz);
  197. }
  198. }
  199. AddrLocal(off)
  200. arith off;
  201. {
  202. register struct localvar *p = find_reg(off);
  203. if (p) p->t_regtype = -1;
  204. C_lal(off);
  205. }