cs_getent.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. #include <em_mnem.h>
  7. #include "../share/types.h"
  8. #include "../share/aux.h"
  9. #include "../share/debug.h"
  10. #include "../share/global.h"
  11. #include "cs.h"
  12. #include "cs_aux.h"
  13. #include "cs_entity.h"
  14. #include "cs_stack.h"
  15. #define WS1 0
  16. #define WS2 1
  17. #define PS 2
  18. #define ARGW 3
  19. #define ARDESC3 4
  20. STATIC struct inf_entity {
  21. byte inf_instr; /* Key. */
  22. byte inf_used; /* Kind of entity used by key. */
  23. byte inf_size; /* Indication of the size. */
  24. } inf_table[] = {
  25. op_adp, ENAOFFSETTED, PS,
  26. op_dee, ENEXTERNAL, WS1,
  27. op_del, ENLOCAL, WS1,
  28. op_ine, ENEXTERNAL, WS1,
  29. op_inl, ENLOCAL, WS1,
  30. op_lae, ENAEXTERNAL, PS,
  31. op_lal, ENALOCAL, PS,
  32. op_lar, ENARRELEM, ARDESC3,
  33. op_ldc, ENCONST, WS2,
  34. op_lde, ENEXTERNAL, WS2,
  35. op_ldf, ENOFFSETTED, WS2,
  36. op_ldl, ENLOCAL, WS2,
  37. op_lil, ENINDIR, WS1,
  38. op_lim, ENIGNMASK, WS1,
  39. op_loc, ENCONST, WS1,
  40. op_loe, ENEXTERNAL, WS1,
  41. op_lof, ENOFFSETTED, WS1,
  42. op_loi, ENINDIR, ARGW,
  43. op_lol, ENLOCAL, WS1,
  44. op_lpi, ENPROC, PS,
  45. op_lxa, ENAARGBASE, PS,
  46. op_lxl, ENALOCBASE, PS,
  47. op_sar, ENARRELEM, ARDESC3,
  48. op_sde, ENEXTERNAL, WS2,
  49. op_sdf, ENOFFSETTED, WS2,
  50. op_sdl, ENLOCAL, WS2,
  51. op_sil, ENINDIR, WS1,
  52. op_sim, ENIGNMASK, WS1,
  53. op_ste, ENEXTERNAL, WS1,
  54. op_stf, ENOFFSETTED, WS1,
  55. op_sti, ENINDIR, ARGW,
  56. op_stl, ENLOCAL, WS1,
  57. op_zer, ENCONST, ARGW,
  58. op_zre, ENEXTERNAL, WS1,
  59. op_zrf, ENFZER, ARGW,
  60. op_zrl, ENLOCAL, WS1,
  61. op_nop /* Delimitor. */
  62. };
  63. #define INFKEY(ip) (ip->inf_instr & BMASK)
  64. #define ENKIND(ip) ip->inf_used
  65. #define SIZEINF(ip) ip->inf_size
  66. STATIC struct inf_entity *getinf(n)
  67. int n;
  68. {
  69. struct inf_entity *ip;
  70. for (ip = &inf_table[0]; INFKEY(ip) != op_nop; ip++) {
  71. if (INFKEY(ip) == n) return ip;
  72. }
  73. return (struct inf_entity *) 0;
  74. }
  75. entity_p getentity(lnp, l_out)
  76. line_p lnp, *l_out;
  77. {
  78. /* Build the entities where lnp refers to, and enter them.
  79. * If a token needs to be popped, the first line that pushed
  80. * it is stored in *l_out.
  81. * The main entity lnp refers to, is returned.
  82. */
  83. struct entity en;
  84. struct token tk;
  85. struct inf_entity *ip;
  86. valnum vn;
  87. offset indexsize;
  88. struct token adesc, index, arbase;
  89. *l_out = lnp;
  90. /* Lor is a special case. */
  91. if (INSTR(lnp) == op_lor) {
  92. offset off = off_set(lnp);
  93. en.en_static = FALSE;
  94. en.en_size = ps;
  95. switch ((int) off == off ? (int) off : 3) {
  96. default:
  97. assert(FALSE);
  98. break;
  99. case 0:
  100. en.en_kind = ENLOCBASE;
  101. break;
  102. case 1:
  103. return (entity_p) 0;
  104. case 2:
  105. en.en_kind = ENHEAPPTR;
  106. break;
  107. }
  108. return en_enter(&en);
  109. }
  110. if ( (ip = getinf(INSTR(lnp))) == (struct inf_entity *) 0)
  111. return (entity_p) 0; /* It does not refer to any entity. */
  112. /* Lil and sil refer to two entities. */
  113. if (INSTR(lnp) == op_lil || INSTR(lnp) == op_sil) {
  114. en.en_static = FALSE;
  115. en.en_kind = ENLOCAL;
  116. en.en_size = ps; /* Local must be a pointer. */
  117. en.en_loc = off_set(lnp);
  118. vn = en_enter(&en)->en_vn;
  119. }
  120. en.en_static = FALSE;
  121. en.en_kind = ENKIND(ip);
  122. /* Fill in the size of the entity. */
  123. switch (SIZEINF(ip)) {
  124. default:
  125. assert(FALSE);
  126. break;
  127. case WS1:
  128. en.en_size = ws;
  129. break;
  130. case WS2:
  131. en.en_size = 2*ws;
  132. break;
  133. case PS:
  134. en.en_size = ps;
  135. break;
  136. case ARGW:
  137. if (TYPE(lnp) != OPNO) {
  138. en.en_size = off_set(lnp);
  139. } else {
  140. Pop(&tk, (offset) ws);
  141. *l_out = tk.tk_lfirst;
  142. en.en_size = UNKNOWN_SIZE;
  143. }
  144. break;
  145. case ARDESC3:
  146. assert(en.en_kind == ENARRELEM);
  147. if (TYPE(lnp) != OPNO) {
  148. indexsize = off_set(lnp);
  149. } else {
  150. Pop(&tk, (offset) ws);
  151. indexsize = UNKNOWN_SIZE;
  152. }
  153. Pop(&adesc, (offset) ps);
  154. en.en_adesc = adesc.tk_vn;
  155. Pop(&index, indexsize);
  156. en.en_index = index.tk_vn;
  157. Pop(&arbase, (offset) ps);
  158. en.en_arbase = arbase.tk_vn;
  159. *l_out = arbase.tk_lfirst;
  160. en.en_size = array_elemsize(adesc.tk_vn);
  161. break;
  162. }
  163. /* Fill in additional information. */
  164. switch (en.en_kind) {
  165. case ENFZER:
  166. en.en_static = TRUE;
  167. break;
  168. case ENCONST:
  169. en.en_static = TRUE;
  170. en.en_val = off_set(lnp);
  171. break;
  172. case ENALOCAL:
  173. en.en_static = TRUE;
  174. case ENLOCAL:
  175. en.en_loc = off_set(lnp);
  176. break;
  177. case ENAEXTERNAL:
  178. en.en_static = TRUE;
  179. case ENEXTERNAL:
  180. en.en_ext = OBJ(lnp);
  181. break;
  182. case ENINDIR:
  183. if (INSTR(lnp) == op_loi || INSTR(lnp) == op_sti) {
  184. Pop(&tk, (offset) ps);
  185. *l_out = tk.tk_lfirst;
  186. vn = tk.tk_vn;
  187. }
  188. en.en_ind = vn;
  189. break;
  190. case ENAOFFSETTED:
  191. en.en_static = TRUE;
  192. case ENOFFSETTED:
  193. Pop(&tk, (offset) ps);
  194. *l_out = tk.tk_lfirst;
  195. en.en_base = tk.tk_vn;
  196. en.en_off = off_set(lnp);
  197. break;
  198. case ENALOCBASE:
  199. case ENAARGBASE:
  200. en.en_levels = off_set(lnp);
  201. if (en.en_levels == 0) {
  202. /* otherwise the program could change it */
  203. en.en_static = TRUE;
  204. }
  205. break;
  206. case ENPROC:
  207. en.en_pro = PROC(lnp);
  208. break;
  209. case ENARRELEM:
  210. /* We gathered the information in the previous switch.
  211. */
  212. break;
  213. }
  214. return en_enter(&en);
  215. }