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