switch.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. /* $Header$ */
  6. /* S W I T C H - S T A T E M E N T A D M I N I S T R A T I O N */
  7. #include "nofloat.h"
  8. #include <em.h>
  9. #include "debug.h"
  10. #include "botch_free.h"
  11. #include <alloc.h>
  12. #include "density.h"
  13. #include "Lpars.h"
  14. #include "idf.h"
  15. #include "label.h"
  16. #include "arith.h"
  17. #include "switch.h"
  18. #include "code.h"
  19. #include "assert.h"
  20. #include "expr.h"
  21. #include "type.h"
  22. #include "noRoption.h"
  23. extern char options[];
  24. #define compact(nr, low, up) (nr != 0 && (up - low) / nr <= (DENSITY - 1))
  25. static struct switch_hdr *switch_stack = 0;
  26. /* (EB 86.05.20) The following rules hold for switch statements:
  27. - the expression E in "switch(E)" is cast to 'int' (RM 9.7)
  28. - the expression E in "case E:" must be 'int' (RM 9.7)
  29. - the values in the CSA/CSB tables are words (EM 7.4)
  30. For simplicity, we suppose int_size == word_size.
  31. */
  32. code_startswitch(expp)
  33. struct expr **expp;
  34. {
  35. /* Check the expression, stack a new case header and
  36. fill in the necessary fields.
  37. */
  38. register label l_table = text_label();
  39. register label l_break = text_label();
  40. register struct switch_hdr *sh = new_switch_hdr();
  41. int fund = any2arith(expp, SWITCH); /* INT, LONG or DOUBLE */
  42. switch (fund) {
  43. case LONG:
  44. #ifndef NOROPTION
  45. if (options['R'])
  46. warning("long in switch (cast to int)");
  47. #endif
  48. int2int(expp, int_type);
  49. break;
  50. #ifndef NOFLOAT
  51. case DOUBLE:
  52. error("float/double in switch");
  53. erroneous2int(expp);
  54. break;
  55. #endif NOFLOAT
  56. }
  57. stack_stmt(l_break, NO_LABEL);
  58. sh->sh_break = l_break;
  59. sh->sh_default = 0;
  60. sh->sh_table = l_table;
  61. sh->sh_nrofentries = 0;
  62. sh->sh_type = (*expp)->ex_type; /* the expression switched */
  63. sh->sh_lowerbd = sh->sh_upperbd = (arith)0; /* immaterial ??? */
  64. sh->sh_entries = (struct case_entry *) 0; /* case-entry list */
  65. sh->next = switch_stack; /* push onto switch-stack */
  66. switch_stack = sh;
  67. /* evaluate the switch expr. */
  68. code_expr(*expp, RVAL, TRUE, NO_LABEL, NO_LABEL);
  69. C_bra(l_table); /* goto start of switch_table */
  70. }
  71. code_endswitch()
  72. {
  73. register struct switch_hdr *sh = switch_stack;
  74. register label tablabel;
  75. register struct case_entry *ce;
  76. if (sh->sh_default == 0) /* no default occurred yet */
  77. sh->sh_default = sh->sh_break;
  78. C_bra(sh->sh_break); /* skip the switch table now */
  79. C_df_ilb(sh->sh_table); /* switch table entry */
  80. tablabel = data_label(); /* the rom must have a label */
  81. C_df_dlb(tablabel);
  82. C_rom_ilb(sh->sh_default);
  83. if (compact(sh->sh_nrofentries, sh->sh_lowerbd, sh->sh_upperbd)) {
  84. /* CSA */
  85. register arith val;
  86. C_rom_cst(sh->sh_lowerbd);
  87. C_rom_cst(sh->sh_upperbd - sh->sh_lowerbd);
  88. ce = sh->sh_entries;
  89. for (val = sh->sh_lowerbd; val <= sh->sh_upperbd; val++) {
  90. ASSERT(ce);
  91. if (val == ce->ce_value) {
  92. C_rom_ilb(ce->ce_label);
  93. ce = ce->next;
  94. }
  95. else
  96. C_rom_ilb(sh->sh_default);
  97. }
  98. C_lae_dlb(tablabel, (arith)0); /* perform the switch */
  99. C_csa(sh->sh_type->tp_size);
  100. }
  101. else { /* CSB */
  102. C_rom_cst((arith)sh->sh_nrofentries);
  103. for (ce = sh->sh_entries; ce; ce = ce->next) {
  104. /* generate the entries: value + prog.label */
  105. C_rom_cst(ce->ce_value);
  106. C_rom_ilb(ce->ce_label);
  107. }
  108. C_lae_dlb(tablabel, (arith)0); /* perform the switch */
  109. C_csb(sh->sh_type->tp_size);
  110. }
  111. C_df_ilb(sh->sh_break);
  112. switch_stack = sh->next; /* unstack the switch descriptor */
  113. for (ce = sh->sh_entries; ce;) { /* free allocated switch structure */
  114. register struct case_entry *tmp = ce->next;
  115. free_case_entry(ce);
  116. ce = tmp;
  117. }
  118. free_switch_hdr(sh);
  119. unstack_stmt();
  120. }
  121. code_case(expr)
  122. struct expr *expr;
  123. {
  124. register arith val;
  125. register struct case_entry *ce;
  126. register struct switch_hdr *sh = switch_stack;
  127. ASSERT(is_cp_cst(expr));
  128. if (sh == 0) {
  129. error("case statement not in switch");
  130. return;
  131. }
  132. if (expr->ex_flags & EX_ERROR) /* is probably 0 anyway */
  133. return;
  134. ch7cast(&expr, SWITCH, sh->sh_type);
  135. ce = new_case_entry();
  136. C_df_ilb(ce->ce_label = text_label());
  137. ce->ce_value = val = expr->VL_VALUE;
  138. if (sh->sh_entries == 0) { /* first case entry */
  139. ce->next = (struct case_entry *) 0;
  140. sh->sh_entries = ce;
  141. sh->sh_lowerbd = sh->sh_upperbd = val;
  142. sh->sh_nrofentries = 1;
  143. }
  144. else { /* second etc. case entry; put ce into proper place */
  145. register struct case_entry *c1 = sh->sh_entries, *c2 = 0;
  146. if (val < sh->sh_lowerbd)
  147. sh->sh_lowerbd = val;
  148. else
  149. if (val > sh->sh_upperbd)
  150. sh->sh_upperbd = val;
  151. while (c1 && c1->ce_value < ce->ce_value) {
  152. c2 = c1;
  153. c1 = c1->next;
  154. }
  155. /* At this point three cases are possible:
  156. 1: c1 != 0 && c2 != 0: insert ce somewhere in the middle
  157. 2: c1 != 0 && c2 == 0: insert ce right after the head
  158. 3: c1 == 0 && c2 != 0: append ce to last element
  159. The case c1 == 0 && c2 == 0 cannot occur, since
  160. the list is guaranteed to be non-empty.
  161. */
  162. if (c1) {
  163. if (c1->ce_value == ce->ce_value) {
  164. error("multiple case entry for value %ld",
  165. ce->ce_value);
  166. free_case_entry(ce);
  167. return;
  168. }
  169. if (c2) {
  170. ce->next = c2->next;
  171. c2->next = ce;
  172. }
  173. else {
  174. ce->next = sh->sh_entries;
  175. sh->sh_entries = ce;
  176. }
  177. }
  178. else {
  179. ASSERT(c2);
  180. ce->next = (struct case_entry *) 0;
  181. c2->next = ce;
  182. }
  183. (sh->sh_nrofentries)++;
  184. }
  185. }
  186. code_default()
  187. {
  188. register struct switch_hdr *sh = switch_stack;
  189. if (sh == 0)
  190. error("default not in switch");
  191. else
  192. if (sh->sh_default != 0)
  193. error("multiple entry for default in switch");
  194. else
  195. C_df_ilb(sh->sh_default = text_label());
  196. }