cstoper.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  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. /* $Id$ */
  6. /* C O N S T A N T E X P R E S S I O N H A N D L I N G */
  7. #include "trgt_sizes.h"
  8. #include "idf.h"
  9. #include <flt_arith.h>
  10. #include "arith.h"
  11. #include "type.h"
  12. #include "label.h"
  13. #include "expr.h"
  14. #include "sizes.h"
  15. #include "Lpars.h"
  16. #include "assert.h"
  17. arith full_mask[MAXSIZE];/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
  18. #ifndef NOCROSS
  19. arith max_int; /* maximum integer on target machine */
  20. arith max_unsigned; /* maximum unsigned on target machine */
  21. #endif /* NOCROSS */
  22. extern int ResultKnown;
  23. cstbin(expp, oper, expr)
  24. register struct expr **expp, *expr;
  25. {
  26. /* The operation oper is performed on the constant
  27. expressions *expp(ld) and expr(ct), and the result restored in
  28. *expp.
  29. */
  30. register arith o1 = (*expp)->VL_VALUE;
  31. register arith o2 = expr->VL_VALUE;
  32. int uns = (*expp)->ex_type->tp_unsigned;
  33. ASSERT(is_ld_cst(*expp) && is_cp_cst(expr));
  34. switch (oper) {
  35. case '*':
  36. o1 *= o2;
  37. break;
  38. case '/':
  39. if (o2 == 0) {
  40. if (!ResultKnown)
  41. expr_error(expr, "division by 0");
  42. else
  43. expr_warning(expr, "division by 0");
  44. break;
  45. }
  46. if (uns) {
  47. #ifdef UNSIGNED_ARITH
  48. o1 /= (UNSIGNED_ARITH) o2;
  49. #else
  50. /* this is more of a problem than you might
  51. think on C compilers which do not have
  52. unsigned arith (== long (probably)).
  53. */
  54. if (o2 & arith_sign) {/* o2 > max_arith */
  55. o1 = ! (o1 >= 0 || o1 < o2);
  56. /* this is the unsigned test
  57. o1 < o2 for o2 > max_arith
  58. */
  59. }
  60. else { /* o2 <= max_arith */
  61. arith half, bit, hdiv, hrem, rem;
  62. half = (o1 >> 1) & ~arith_sign;
  63. bit = o1 & 01;
  64. /* now o1 == 2 * half + bit
  65. and half <= max_arith
  66. and bit <= max_arith
  67. */
  68. hdiv = half / o2;
  69. hrem = half % o2;
  70. rem = 2 * hrem + bit;
  71. o1 = 2 * hdiv + (rem < 0 || rem >= o2);
  72. /* that is the unsigned compare
  73. rem >= o2 for o2 <= max_arith
  74. */
  75. }
  76. #endif
  77. }
  78. else
  79. o1 /= o2;
  80. break;
  81. case '%':
  82. if (o2 == 0) {
  83. if (!ResultKnown)
  84. expr_error(expr, "modulo by 0");
  85. else
  86. expr_warning(expr, "modulo by 0");
  87. break;
  88. }
  89. if (uns) {
  90. #ifdef UNSIGNED_ARITH
  91. o1 %= (UNSIGNED_ARITH) o2;
  92. #else
  93. if (o2 & arith_sign) {/* o2 > max_arith */
  94. o1 = (o1 >= 0 || o1 < o2) ? o1 : o1 - o2;
  95. /* this is the unsigned test
  96. o1 < o2 for o2 > max_arith
  97. */
  98. }
  99. else { /* o2 <= max_arith */
  100. arith half, bit, hrem, rem;
  101. half = (o1 >> 1) & ~arith_sign;
  102. bit = o1 & 01;
  103. /* now o1 == 2 * half + bit
  104. and half <= max_arith
  105. and bit <= max_arith
  106. */
  107. hrem = half % o2;
  108. rem = 2 * hrem + bit;
  109. o1 = (rem < 0 || rem >= o2) ? rem - o2 : rem;
  110. }
  111. #endif
  112. }
  113. else
  114. o1 %= o2;
  115. break;
  116. case '+':
  117. o1 += o2;
  118. break;
  119. case '-':
  120. o1 -= o2;
  121. break;
  122. case LEFT:
  123. o1 <<= o2;
  124. break;
  125. case RIGHT:
  126. if (o2 == 0)
  127. break;
  128. if (uns) {
  129. o1 = (o1 >> 1) & ~arith_sign;
  130. o1 >>= (o2 - 1);
  131. }
  132. else o1 >>= o2;
  133. break;
  134. case '<':
  135. {
  136. arith tmp = o1;
  137. o1 = o2;
  138. o2 = tmp;
  139. }
  140. /* Fall through */
  141. case '>':
  142. if (uns) {
  143. #ifdef UNSIGNED_ARITH
  144. o1 = (UNSIGNED_ARITH) o1 > (UNSIGNED_ARITH) o2;
  145. #else
  146. o1 = (o1 & arith_sign ?
  147. (o2 & arith_sign ? o1 > o2 : 1) :
  148. (o2 & arith_sign ? 0 : o1 > o2)
  149. );
  150. #endif
  151. }
  152. else
  153. o1 = o1 > o2;
  154. break;
  155. case LESSEQ:
  156. {
  157. arith tmp = o1;
  158. o1 = o2;
  159. o2 = tmp;
  160. }
  161. /* Fall through */
  162. case GREATEREQ:
  163. if (uns) {
  164. #ifdef UNSIGNED_ARITH
  165. o1 = (UNSIGNED_ARITH) o1 >= (UNSIGNED_ARITH) o2;
  166. #else
  167. o1 = (o1 & arith_sign ?
  168. (o2 & arith_sign ? o1 >= o2 : 1) :
  169. (o2 & arith_sign ? 0 : o1 >= o2)
  170. );
  171. #endif
  172. }
  173. else
  174. o1 = o1 >= o2;
  175. break;
  176. case EQUAL:
  177. o1 = o1 == o2;
  178. break;
  179. case NOTEQUAL:
  180. o1 = o1 != o2;
  181. break;
  182. case '&':
  183. o1 &= o2;
  184. break;
  185. case '|':
  186. o1 |= o2;
  187. break;
  188. case '^':
  189. o1 ^= o2;
  190. break;
  191. }
  192. (*expp)->VL_VALUE = o1;
  193. cut_size(*expp);
  194. (*expp)->ex_flags |= expr->ex_flags;
  195. (*expp)->ex_flags &= ~EX_PARENS;
  196. free_expression(expr);
  197. }
  198. cut_size(expr)
  199. register struct expr *expr;
  200. {
  201. /* The constant value of the expression expr is made to
  202. conform to the size of the type of the expression.
  203. */
  204. register arith o1 = expr->VL_VALUE;
  205. int uns = expr->ex_type->tp_unsigned;
  206. int size = (int) expr->ex_type->tp_size;
  207. ASSERT(expr->ex_class == Value);
  208. if (expr->ex_type->tp_fund == POINTER) {
  209. /* why warn on "ptr-3" ?
  210. This quick hack fixes it
  211. */
  212. uns = 0;
  213. }
  214. if (uns) {
  215. if (o1 & ~full_mask[size])
  216. if (!ResultKnown)
  217. expr_warning(expr,
  218. "overflow in unsigned constant expression");
  219. o1 &= full_mask[size];
  220. }
  221. else {
  222. int nbits = (int) (arith_size - size) * 8;
  223. arith remainder = o1 & ~full_mask[size];
  224. if (remainder != 0 && remainder != ~full_mask[size])
  225. if (!ResultKnown)
  226. expr_warning(expr,"overflow in constant expression");
  227. o1 = (o1 << nbits) >> nbits; /* ??? */
  228. }
  229. expr->VL_VALUE = o1;
  230. }
  231. init_cst()
  232. {
  233. register int i = 0;
  234. register arith bt = (arith)0;
  235. while (!(bt < 0)) {
  236. bt = (bt << 8) + 0377, i++;
  237. if (i == MAXSIZE)
  238. fatal("array full_mask too small for this machine");
  239. full_mask[i] = bt;
  240. }
  241. if ((int)long_size > arith_size)
  242. fatal("sizeof (arith) insufficient on this machine");
  243. #ifndef NOCROSS
  244. max_int = full_mask[(int)int_size] & ~(1L << ((int)int_size * 8 - 1));
  245. max_unsigned = full_mask[(int)int_size];
  246. #endif /* NOCROSS */
  247. }