util.c 4.3 KB

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