cstoper.c 5.3 KB

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