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. #include "cstoper.h"
  18. /* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */
  19. arith full_mask[MAXSIZE + 1];
  20. #ifndef NOCROSS
  21. arith max_int; /* maximum integer on target machine */
  22. arith max_unsigned; /* maximum unsigned on target machine */
  23. #endif /* NOCROSS */
  24. extern int ResultKnown;
  25. void cstbin(struct expr **expp, int oper, struct expr *expr)
  26. {
  27. /* The operation oper is performed on the constant
  28. expressions *expp(ld) and expr(ct), and the result restored in
  29. *expp.
  30. */
  31. arith o1 = (*expp)->VL_VALUE;
  32. arith o2 = expr->VL_VALUE;
  33. int uns = (*expp)->ex_type->tp_unsigned;
  34. ASSERT(is_ld_cst(*expp) && is_cp_cst(expr));
  35. switch (oper) {
  36. case '*':
  37. o1 *= o2;
  38. break;
  39. case '/':
  40. if (o2 == 0) {
  41. if (!ResultKnown)
  42. expr_error(expr, "division by 0");
  43. else
  44. expr_warning(expr, "division by 0");
  45. break;
  46. }
  47. if (uns) {
  48. #ifdef UNSIGNED_ARITH
  49. o1 /= (UNSIGNED_ARITH) o2;
  50. #else
  51. /* this is more of a problem than you might
  52. think on C compilers which do not have
  53. unsigned arith (== long (probably)).
  54. */
  55. if (o2 & arith_sign) {/* o2 > max_arith */
  56. o1 = ! (o1 >= 0 || o1 < o2);
  57. /* this is the unsigned test
  58. o1 < o2 for o2 > max_arith
  59. */
  60. }
  61. else { /* o2 <= max_arith */
  62. arith half, bit, hdiv, hrem, rem;
  63. half = (o1 >> 1) & ~arith_sign;
  64. bit = o1 & 01;
  65. /* now o1 == 2 * half + bit
  66. and half <= max_arith
  67. and bit <= max_arith
  68. */
  69. hdiv = half / o2;
  70. hrem = half % o2;
  71. rem = 2 * hrem + bit;
  72. o1 = 2 * hdiv + (rem < 0 || rem >= o2);
  73. /* that is the unsigned compare
  74. rem >= o2 for o2 <= max_arith
  75. */
  76. }
  77. #endif
  78. }
  79. else
  80. o1 /= o2;
  81. break;
  82. case '%':
  83. if (o2 == 0) {
  84. if (!ResultKnown)
  85. expr_error(expr, "modulo by 0");
  86. else
  87. expr_warning(expr, "modulo by 0");
  88. break;
  89. }
  90. if (uns) {
  91. #ifdef UNSIGNED_ARITH
  92. o1 %= (UNSIGNED_ARITH) o2;
  93. #else
  94. if (o2 & arith_sign) {/* o2 > max_arith */
  95. o1 = (o1 >= 0 || o1 < o2) ? o1 : o1 - o2;
  96. /* this is the unsigned test
  97. o1 < o2 for o2 > max_arith
  98. */
  99. }
  100. else { /* o2 <= max_arith */
  101. arith half, bit, hrem, rem;
  102. half = (o1 >> 1) & ~arith_sign;
  103. bit = o1 & 01;
  104. /* now o1 == 2 * half + bit
  105. and half <= max_arith
  106. and bit <= max_arith
  107. */
  108. hrem = half % o2;
  109. rem = 2 * hrem + bit;
  110. o1 = (rem < 0 || rem >= o2) ? rem - o2 : rem;
  111. }
  112. #endif
  113. }
  114. else
  115. o1 %= o2;
  116. break;
  117. case '+':
  118. o1 += o2;
  119. break;
  120. case '-':
  121. o1 -= o2;
  122. break;
  123. case LEFT:
  124. o1 <<= o2;
  125. break;
  126. case RIGHT:
  127. if (o2 == 0)
  128. break;
  129. if (uns) {
  130. o1 = (o1 >> 1) & ~arith_sign;
  131. o1 >>= (o2 - 1);
  132. }
  133. else o1 >>= o2;
  134. break;
  135. case '<':
  136. {
  137. arith tmp = o1;
  138. o1 = o2;
  139. o2 = tmp;
  140. }
  141. /* Fall through */
  142. case '>':
  143. if (uns) {
  144. #ifdef UNSIGNED_ARITH
  145. o1 = (UNSIGNED_ARITH) o1 > (UNSIGNED_ARITH) o2;
  146. #else
  147. o1 = (o1 & arith_sign ?
  148. (o2 & arith_sign ? o1 > o2 : 1) :
  149. (o2 & arith_sign ? 0 : o1 > o2)
  150. );
  151. #endif
  152. }
  153. else
  154. o1 = o1 > o2;
  155. break;
  156. case LESSEQ:
  157. {
  158. arith tmp = o1;
  159. o1 = o2;
  160. o2 = tmp;
  161. }
  162. /* Fall through */
  163. case GREATEREQ:
  164. if (uns) {
  165. #ifdef UNSIGNED_ARITH
  166. o1 = (UNSIGNED_ARITH) o1 >= (UNSIGNED_ARITH) o2;
  167. #else
  168. o1 = (o1 & arith_sign ?
  169. (o2 & arith_sign ? o1 >= o2 : 1) :
  170. (o2 & arith_sign ? 0 : o1 >= o2)
  171. );
  172. #endif
  173. }
  174. else
  175. o1 = o1 >= o2;
  176. break;
  177. case EQUAL:
  178. o1 = o1 == o2;
  179. break;
  180. case NOTEQUAL:
  181. o1 = o1 != o2;
  182. break;
  183. case '&':
  184. o1 &= o2;
  185. break;
  186. case '|':
  187. o1 |= o2;
  188. break;
  189. case '^':
  190. o1 ^= o2;
  191. break;
  192. }
  193. (*expp)->VL_VALUE = o1;
  194. cut_size(*expp);
  195. (*expp)->ex_flags |= expr->ex_flags;
  196. (*expp)->ex_flags &= ~EX_PARENS;
  197. free_expression(expr);
  198. }
  199. void cut_size(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. 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. void init_cst()
  232. {
  233. int i = 0;
  234. 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. }