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".
5 * Author: Ceriel J.H. Jacobs
8 /* 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 */
10 /* $Id: cstoper.c,v 1.57 1996/08/14 07:42:31 ceriel Exp $ */
13 #include "target_sizes.h"
14 #include "uns_arith.h"
26 #include "standards.h"
29 extern char *symbol2str();
31 #define arith_sign ((arith) (1L << (sizeof(arith) * 8 - 1)))
34 arith full_mask[MAXSIZE+1];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */
35 arith max_int[MAXSIZE+1]; /* max_int[1] == 0x7F, max_int[2] == 0x7FFF, .. */
36 arith min_int[MAXSIZE+1]; /* min_int[1] == 0xFFFFFF80, min_int[2] = 0xFFFF8000,
39 unsigned int wrd_bits; /* number of bits in a word */
41 arith full_mask[] = { 0L, 0xFFL, 0xFFFFL, 0L, 0xFFFFFFFFL };
42 arith max_int[] = { 0L, 0x7FL, 0x7FFFL, 0L, 0x7FFFFFFFL };
43 arith min_int[] = { 0L, -128L, -32768L, 0L, -2147483647L-1 };
46 extern char options[];
51 if (expp->nd_type != address_type) {
52 node_warning(expp, W_ORDINARY, "overflow in constant expression");
60 register t_node *exp = *expp;
61 t_type *tp = exp->nd_type;
62 register t_node *right = exp->nd_RIGHT;
73 /* The unary operation in "expp" is performed on the constant
74 expression below it, and the result restored in expp.
76 register t_node *exp = *expp;
77 register t_node *right = exp->nd_RIGHT;
78 register arith o1 = right->nd_INT;
80 switch(exp->nd_symb) {
81 /* Should not get here
88 o1 == min_int[(int)(right->nd_type->tp_size)]) {
104 (*expp)->nd_INT = o1;
112 /* Unsigned divide *pdiv by *prem, and store result in *pdiv,
115 register arith o1 = *pdiv;
116 register arith o2 = *prem;
118 #ifndef UNSIGNED_ARITH
119 /* this is more of a problem than you might
120 think on C compilers which do not have
123 if (o2 & arith_sign) {/* o2 > max_arith */
124 if (! (o1 >= 0 || o1 < o2)) {
125 /* this is the unsigned test
126 o1 < o2 for o2 > max_arith
135 else { /* o2 <= max_arith */
136 arith half, bit, hdiv, hrem, rem;
138 half = (o1 >> 1) & ~arith_sign;
140 /* now o1 == 2 * half + bit
141 and half <= max_arith
146 rem = 2 * hrem + bit;
149 if (rem < 0 || rem >= o2) {
150 /* that is the unsigned compare
151 rem >= o2 for o2 <= max_arith
158 *pdiv = (UNSIGNED_ARITH) o1 / (UNSIGNED_ARITH) o2;
159 *prem = (UNSIGNED_ARITH) o1 % (UNSIGNED_ARITH) o2;
166 /* The binary operation in "expp" is performed on the constant
167 expressions below it, and the result restored in expp.
168 This version is for INTEGER expressions.
170 register t_node *exp = *expp;
171 register arith o1 = exp->nd_LEFT->nd_INT;
172 register arith o2 = exp->nd_RIGHT->nd_INT;
173 register int sz = exp->nd_type->tp_size;
175 assert(exp->nd_class == Oper);
176 assert(exp->nd_LEFT->nd_class == Value);
177 assert(exp->nd_RIGHT->nd_class == Value);
179 switch (exp->nd_symb) {
183 if (max_int[sz] / o1 < o2) overflow(exp);
185 else if (min_int[sz] / o1 > o2) overflow(exp);
189 if (o1 == min_int[sz] || o2 == min_int[sz] ||
190 max_int[sz] / (-o1) < (-o2)) overflow(exp);
193 if (min_int[sz] / o2 > o1) overflow(exp);
202 node_error(exp, exp->nd_symb == DIV ?
207 if ((o1 < 0) != (o2 < 0)) {
208 if (o1 < 0) o1 = -o1;
210 if (exp->nd_symb == DIV) o1 = -((o1+o2-1)/o2);
211 else o1 = ((o1+o2-1)/o2) * o2 - o1;
214 if (exp->nd_symb == DIV) o1 /= o2;
220 if ( (o1 > 0 && o2 > 0 && max_int[sz] - o1 < o2)
221 || (o1 < 0 && o2 < 0 && min_int[sz] - o1 > o2)
227 if ( (o1 >= 0 && o2 < 0 && max_int[sz] + o2 < o1)
228 || (o1 < 0 && o2 >= 0 && min_int[sz] + o2 > o1)
262 (*expp)->nd_INT = o1;
269 /* The binary operation in "expp" is performed on the constant
270 expressions below it, and the result restored in expp.
271 This version is for REAL expressions.
273 register t_node *exp = *expp;
274 register struct real *p = exp->nd_LEFT->nd_REAL;
275 register flt_arith *o1 = &p->r_val;
276 register flt_arith *o2 = &exp->nd_RIGHT->nd_RVAL;
280 assert(exp->nd_class == Oper);
281 assert(exp->nd_LEFT->nd_class == Value);
282 assert(exp->nd_RIGHT->nd_class == Value);
284 switch (exp->nd_symb) {
308 cmpval = flt_cmp(o1, o2);
309 switch(exp->nd_symb) {
310 case '<': cmpval = (cmpval < 0); break;
311 case '>': cmpval = (cmpval > 0); break;
312 case LESSEQUAL: cmpval = (cmpval <= 0); break;
313 case GREATEREQUAL: cmpval = (cmpval >= 0); break;
314 case '=': cmpval = (cmpval == 0); break;
315 case '#': cmpval = (cmpval != 0); break;
317 if (exp->nd_RIGHT->nd_RSTR) free(exp->nd_RIGHT->nd_RSTR);
318 free_real(exp->nd_RIGHT->nd_REAL);
327 node_warning(exp, "floating point overflow on %s",
328 symbol2str(exp->nd_symb));
331 node_error(exp, "division by 0.0");
345 exp->nd_symb = INTEGER;
346 exp->nd_INT = cmpval;
357 /* The binary operation in "expp" is performed on the constant
358 expressions below it, and the result restored in
361 register t_node *exp = *expp;
362 arith o1 = exp->nd_LEFT->nd_INT;
363 arith o2 = exp->nd_RIGHT->nd_INT;
364 register int sz = exp->nd_type->tp_size;
367 assert(exp->nd_class == Oper);
368 assert(exp->nd_LEFT->nd_class == Value);
369 assert(exp->nd_RIGHT->nd_class == Value);
371 switch (exp->nd_symb) {
373 if (o1 == 0 || o2 == 0) {
377 tmp1 = full_mask[sz];
379 divide(&tmp1, &tmp2);
380 if (! chk_bounds(o1, tmp1, T_CARDINAL)) overflow(exp);
387 node_error(exp, exp->nd_symb == DIV ?
393 if (exp->nd_symb == MOD) o1 = o2;
397 if (! chk_bounds(o2, full_mask[sz] - o1, T_CARDINAL)) {
404 if ( exp->nd_type != address_type
405 && !chk_bounds(o2, o1, T_CARDINAL)
406 && ( exp->nd_type->tp_fund != T_INTORCARD
407 || ( exp->nd_type = int_type
408 , !chk_bounds(min_int[sz], o1 - o2, T_CARDINAL) ) )
410 node_warning(exp, W_ORDINARY,
411 "underflow in constant expression");
417 o1 = ! chk_bounds(o2, o1, T_CARDINAL);
421 o1 = ! chk_bounds(o1, o2, T_CARDINAL);
425 o1 = chk_bounds(o1, o2, T_CARDINAL);
429 o1 = chk_bounds(o2, o1, T_CARDINAL);
456 if (exp->nd_type == bool_type) exp->nd_symb = INTEGER;
463 extern arith *MkSet();
464 register t_node *exp = *expp;
465 register arith *set1, *set2, *set3;
466 register unsigned int setsize;
469 assert(exp->nd_RIGHT->nd_class == Set);
470 assert(exp->nd_symb == IN || exp->nd_LEFT->nd_class == Set);
472 set2 = exp->nd_RIGHT->nd_set;
473 setsize = (unsigned) (exp->nd_RIGHT->nd_type->tp_size) / (unsigned) word_size;
475 if (exp->nd_symb == IN) {
476 /* The setsize must fit in an unsigned, as it is
477 allocated with Malloc, so we can do the arithmetic
482 assert(exp->nd_LEFT->nd_class == Value);
484 exp->nd_LEFT->nd_INT -= exp->nd_RIGHT->nd_type->set_low;
487 /* Careful here; use exp->nd_LEFT->nd_INT to see if
488 it falls in the range of the set. Do not use i
489 for this, as i may be truncated.
491 i = (exp->nd_INT >= 0 &&
492 exp->nd_INT < setsize * wrd_bits &&
493 (set2[i / wrd_bits] & (1 << (i % wrd_bits))));
495 exp = getnode(Value);
496 exp->nd_symb = INTEGER;
497 exp->nd_lineno = (*expp)->nd_lineno;
499 exp->nd_type = bool_type;
505 set1 = exp->nd_LEFT->nd_set;
506 *expp = getnode(Set);
507 (*expp)->nd_type = exp->nd_type;
508 (*expp)->nd_lineno = exp->nd_lineno;
509 switch(exp->nd_symb) {
510 case '+': /* Set union */
511 case '-': /* Set difference */
512 case '*': /* Set intersection */
513 case '/': /* Symmetric set difference */
514 (*expp)->nd_set = set3 = MkSet(exp->nd_type->set_sz);
515 for (j = 0; j < setsize; j++) {
516 switch(exp->nd_symb) {
518 *set3++ = *set1++ | *set2++;
521 *set3++ = *set1++ & ~*set2++;
524 *set3++ = *set1++ & *set2++;
527 *set3++ = *set1++ ^ *set2++;
537 /* Constant set comparisons
539 for (j = 0; j < setsize; j++) {
540 switch(exp->nd_symb) {
542 if ((*set1 | *set2++) != *set1) break;
546 if ((*set2 | *set1++) != *set2) break;
551 if (*set1++ != *set2++) break;
557 j = exp->nd_symb == '#';
560 j = exp->nd_symb != '#';
562 *expp = getnode(Value);
563 (*expp)->nd_symb = INTEGER;
565 (*expp)->nd_type = bool_type;
566 (*expp)->nd_lineno = (*expp)->nd_lineno;
571 FreeSet(exp->nd_LEFT->nd_set);
572 FreeSet(exp->nd_RIGHT->nd_set);
579 /* a standard procedure call is found that can be evaluated
580 compile time, so do so.
582 register t_node *expr;
585 assert((*expp)->nd_class == Call);
586 expr = (*expp)->nd_RIGHT->nd_LEFT;
588 expr->nd_type = (*expp)->nd_type;
590 (*expp)->nd_RIGHT->nd_LEFT = 0;
593 expr->nd_symb = INTEGER;
594 expr->nd_class = Value;
597 if (expr->nd_INT < 0) {
598 if (! options['s'] &&
599 expr->nd_INT <= min_int[(int)(tp->tp_size)]) {
602 expr->nd_INT = - expr->nd_INT;
608 if (expr->nd_INT >= 'a' && expr->nd_INT <= 'z') {
609 expr->nd_INT += ('A' - 'a');
615 if (tp->tp_fund == T_INTEGER) {
616 expr->nd_INT = max_int[(int)(tp->tp_size)];
618 else if (tp->tp_fund == T_CARDINAL) {
619 expr->nd_INT = full_mask[(int)(tp->tp_size)];
621 else if (tp->tp_fund == T_SUBRANGE) {
622 expr->nd_INT = tp->sub_ub;
624 else expr->nd_INT = tp->enm_ncst - 1;
628 if (tp->tp_fund == T_INTEGER) {
629 expr->nd_INT = min_int[(int)(tp->tp_size)];
631 else if (tp->tp_fund == T_SUBRANGE) {
632 expr->nd_INT = tp->sub_lb;
634 else expr->nd_INT = 0;
643 expr->nd_INT = tp->tp_size;
652 register t_node *expr;
654 /* The constant value of the expression expr is made to
655 conform to the size of the type of the expression.
657 register t_type *tp = BaseType(expr->nd_type);
659 assert(expr->nd_class == Value);
660 if (tp->tp_fund == T_REAL) return;
661 if (tp->tp_fund != T_INTEGER) {
662 expr->nd_INT &= full_mask[(int)(tp->tp_size)];
665 int nbits = (int) (sizeof(arith) - tp->tp_size) * 8;
667 expr->nd_INT = (expr->nd_INT << nbits) >> nbits;
675 register arith bt = (arith)0;
679 bt = (bt << 8) + 0377;
681 fatal("array full_mask too small for this machine");
683 max_int[i] = bt & ~(1L << ((8 * i) - 1));
684 min_int[i] = - max_int[i];
685 if (! options['s']) min_int[i]--;
687 if ((int)long_size > sizeof(arith)) {
688 fatal("sizeof (arith) insufficient on this machine");
691 wrd_bits = 8 * (int) word_size;
694 for (i = 0; i < sizeof(long); i++) min_int[i] = - max_int[i];