ch3bin.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. /* EVALUATION OF BINARY OPERATORS */
  7. #include "Lpars.h"
  8. #include "arith.h"
  9. #define arith_sign (1L << (sizeof(arith)*8-1))
  10. ch3bin(pval, pis_uns, oper, val, is_uns)
  11. register arith *pval, val;
  12. int oper, is_uns, *pis_uns;
  13. {
  14. if (is_uns) *pis_uns = 1;
  15. switch (oper) {
  16. case '/':
  17. if (val == 0) {
  18. error("/ by 0");
  19. break;
  20. }
  21. if (*pis_uns) {
  22. #ifdef UNSIGNED_ARITH
  23. *pval /= (UNSIGNED_ARITH) val;
  24. #else
  25. /* this is more of a problem than you might
  26. think on C compilers which do not have
  27. unsigned arith (== long (probably)).
  28. */
  29. if (val & arith_sign) {/* val > max_arith */
  30. *pval = ! (*pval >= 0 || *pval < val);
  31. /* this is the unsigned test
  32. *pval < val for val > max_arith
  33. */
  34. }
  35. else { /* val <= max_arith */
  36. arith half, bit, hdiv, hrem, rem;
  37. half = (*pval >> 1) & ~arith_sign;
  38. bit = *pval & 01;
  39. /* now *pval == 2 * half + bit
  40. and half <= max_arith
  41. and bit <= max_arith
  42. */
  43. hdiv = half / val;
  44. hrem = half % val;
  45. rem = 2 * hrem + bit;
  46. *pval = 2 * hdiv + (rem < 0 || rem >= val);
  47. /* that is the unsigned compare
  48. rem >= val for val <= max_arith
  49. */
  50. }
  51. #endif
  52. }
  53. else {
  54. *pval = *pval / val;
  55. }
  56. break;
  57. case '%':
  58. if (val == 0) {
  59. error("%% by 0");
  60. break;
  61. }
  62. if (*pis_uns) {
  63. #ifdef UNSIGNED_ARITH
  64. *pval %= (UNSIGNED_ARITH) val;
  65. #else
  66. if (val & arith_sign) {/* val > max_arith */
  67. *pval = (*pval >= 0 || *pval < val) ? *pval : *pval - val;
  68. /* this is the unsigned test
  69. *pval < val for val > max_arith
  70. */
  71. }
  72. else { /* val <= max_arith */
  73. arith half, bit, hrem, rem;
  74. half = (*pval >> 1) & ~arith_sign;
  75. bit = *pval & 01;
  76. /* now *pval == 2 * half + bit
  77. and half <= max_arith
  78. and bit <= max_arith
  79. */
  80. hrem = half % val;
  81. rem = 2 * hrem + bit;
  82. *pval = (rem < 0 || rem >= val) ? rem - val : rem;
  83. }
  84. #endif
  85. }
  86. else {
  87. *pval = *pval % val;
  88. }
  89. break;
  90. case '*':
  91. *pval = *pval * val;
  92. break;
  93. case '+':
  94. *pval = *pval + val;
  95. break;
  96. case '-':
  97. *pval = *pval - val;
  98. break;
  99. case LEFT:
  100. *pval = *pval << val;
  101. break;
  102. case RIGHT:
  103. if (val == 0) break;
  104. if (*pis_uns) {
  105. *pval = (*pval >> 1) & ~arith_sign;
  106. *pval = *pval >> (val - 1);
  107. }
  108. else *pval = *pval >> val;
  109. break;
  110. case '<':
  111. { arith tmp = *pval; *pval = val; val = tmp; }
  112. /* fall through */
  113. case '>':
  114. if (*pis_uns) {
  115. #ifdef UNSIGNED_ARITH
  116. *pval = (UNSIGNED_ARITH) *pval > (UNSIGNED_ARITH) val;
  117. #else
  118. *pval = (*pval & arith_sign ?
  119. (val & arith_sign ? *pval > val : 1) :
  120. (val & arith_sign ? 0 : *pval > val)
  121. );
  122. #endif
  123. }
  124. else *pval = (*pval > val);
  125. break;
  126. case LESSEQ:
  127. { arith tmp = *pval; *pval = val; val = tmp; }
  128. /* fall through */
  129. case GREATEREQ:
  130. if (*pis_uns) {
  131. #ifdef UNSIGNED_ARITH
  132. *pval = (UNSIGNED_ARITH) *pval >= (UNSIGNED_ARITH) val;
  133. #else
  134. *pval = (*pval & arith_sign ?
  135. (val & arith_sign ? *pval >= val : 1) :
  136. (val & arith_sign ? 0 : *pval >= val)
  137. );
  138. #endif
  139. }
  140. else *pval = (*pval >= val);
  141. break;
  142. case EQUAL:
  143. *pval = (*pval == val);
  144. break;
  145. case NOTEQUAL:
  146. *pval = (*pval != val);
  147. break;
  148. case '&':
  149. *pval = *pval & val;
  150. break;
  151. case '^':
  152. *pval = *pval ^ val;
  153. break;
  154. case '|':
  155. *pval = *pval | val;
  156. break;
  157. case AND:
  158. *pval = (*pval && val);
  159. break;
  160. case OR:
  161. *pval = (*pval || val);
  162. break;
  163. case ',':
  164. *pis_uns = is_uns;
  165. *pval = val;
  166. break;
  167. }
  168. }