1 /* TV --- Target Values, aka Constant Table.
2 Copyright (C) 1995, 1996 Christian von Roques */
4 /* This implementation assumes:
5 * target characters/strings can be represented as type `char'/`char *',
6 * host's type `long'/`unsigned long' can hold values of mode `l'/`L',
7 * both host and target have two's complement integral arithmetic,
8 host's C operators `/' and `%' match target's div and mod.
9 target_max_<mode> == (1<<k)-1 for some k>0
10 target_min_<mode> == -target_max_<mode>-1
11 target_max_<Mode> == target_max_<mode>-target_min_<mode>
12 * both host and target have IEEE-754 floating-point arithmetic. */
14 /* !!! float and double divides MUST NOT SIGNAL !!! */
15 /* @@@ query the floating-point expception status flags */
17 /* @@@ ToDo: tarval_convert_to is not fully implemented! */
18 /* @@@ Problem: All Values are stored twice, once as Univ_*s and a 2nd
19 time in their real target mode. :-( */
20 /* @@@ Perhaps use a set instead of a pset: new tarvals allocated on
21 stack, copied into set by tarval_identify() if really new. If
22 tarval_identify() discards often enough, the extra copy for kept
23 values is cheaper than the extra obstack_alloc()/free() for
39 #define TOBSTACK_ID "tv"
46 # include "entity_t.h"
48 static struct obstack tv_obst; /* obstack for all the target values */
49 static pset *tarvals; /* pset containing pointers to _all_ tarvals */
51 /* currently building an object with tarval_start() & friends ? */
52 #define BUILDING obstack_object_size (&tv_obst)
54 /* special tarvals: */
56 tarval *tarval_b_false;
57 tarval *tarval_b_true;
60 tarval *tarval_p_void;
61 tarval *tarval_mode_null[irm_max];
64 /* @@@ depends on order of ir_mode */
65 static tarval_chil min_chil[8] = {
71 static tarval_chil max_chil[8] = {
72 TARGET_SIMAX (c), TARGET_UIMAX (C),
73 TARGET_SIMAX (h), TARGET_UIMAX (H),
74 TARGET_SIMAX (i), TARGET_UIMAX (I),
75 TARGET_SIMAX (l), TARGET_UIMAX (L)
79 /* return a mode-specific value */
94 tv_val_chil (tarval *tv)
100 tv_val_CHIL (tarval *tv)
106 tv_val_Z (tarval *tv)
112 tv_val_p (tarval *tv)
118 tv_val_b (tarval *tv)
124 tv_val_B (tarval *tv)
130 tv_val_s (tarval *tv)
136 /* Overflows `chil' signed integral `mode'? */
138 chil_overflow (tarval_chil chil, ir_mode *mode)
140 assert (is_chilCHIL(mode->code));
141 return (mode->min && mode->max /* only valid after firm initialization */
142 && (chil < tv_val_chil (mode->min) || tv_val_chil (mode->max) < chil));
146 /* Overflows `CHIL' unsigned integral `mode'? */
148 CHIL_overflow (tarval_CHIL CHIL, ir_mode *mode)
150 assert (is_chilCHIL(mode->code));
151 return (mode->max /* only valid after firm initialization */
152 && tv_val_CHIL (mode->max) < CHIL);
158 _tarval_vrfy (const tarval *val)
161 switch (val->mode->code) {
167 case irm_C: case irm_H: case irm_I: case irm_L:
168 assert (!CHIL_overflow (val->u.CHIL, val->mode)); break;
169 case irm_c: case irm_h: case irm_i: case irm_l:
170 assert (!chil_overflow (val->u.chil, val->mode)); break;
176 assert (val->u.p.ent->kind == k_entity);
177 assert ( val->u.p.xname || val->u.p.ent
178 || !tarval_p_void || (val == tarval_p_void));
182 assert (val->u.s.p); break;
184 assert (val->u.B.p); break;
186 assert ((unsigned)val->u.b <= 1); break;
188 assert (val->mode == mode_T);
199 pset_stats (tarvals);
205 /* Return the canonical tarval * for tv.
206 May destroy everything allocated on tv_obst after tv! */
208 tarval_identify (tarval *tv)
212 o = pset_insert (tarvals, tv, tarval_hash (tv));
215 obstack_free (&tv_obst, (void *)tv);
223 /* Return 0 iff a equals b. Bitwise identical NaNs compare equal. */
225 tarval_cmp (const void *p, const void *q)
233 if (a == b) return 0;
234 if (a->mode - b->mode) return a->mode - b->mode;
236 switch (a->mode->code) {
239 return memcmp (&a->u.f, &b->u.f, sizeof (a->u.f));
241 return memcmp (&a->u.d, &b->u.d, sizeof (a->u.d));
243 case irm_C: case irm_H: case irm_I: case irm_L:
244 if (sizeof (int) == sizeof (tarval_CHIL)) {
245 return a->u.CHIL - b->u.CHIL;
247 return a->u.CHIL != b->u.CHIL;
249 case irm_c: case irm_h: case irm_i: case irm_l:
250 if (sizeof (int) == sizeof (tarval_chil)) {
251 return a->u.chil - b->u.chil;
253 return a->u.chil != b->u.chil;
255 return mpz_cmp (&a->u.Z, &b->u.Z);
258 if (a->u.p.ent || b->u.p.ent)
259 return (char *)a->u.p.ent - (char *)b->u.p.ent;
260 if (a->u.p.xname && b->u.p.xname)
261 return strcmp (a->u.p.xname, b->u.p.xname);
262 return a->u.p.xname - b->u.p.xname;
264 return a->u.b - b->u.b;
266 return ( a->u.B.n - b->u.B.n
267 ? memcmp (a->u.B.p, b->u.B.p, a->u.B.n)
268 : a->u.B.n - b->u.B.n);
269 case irm_s: case irm_S:
270 return ( a->u.s.n == b->u.s.n
271 ? memcmp (a->u.s.p, b->u.s.p, a->u.s.n)
272 : a->u.s.n - b->u.s.n);
279 tarval_hash (tarval *tv)
283 h = tv->mode->code * 0x421u;
284 switch (tv->mode->code) {
286 h = 0x94b527ce; break;
289 { union { float f; unsigned u; } u;
290 assert (sizeof (float) <= sizeof (unsigned));
291 u.u = 0; u.f = tv->u.f;
297 { union { double d; unsigned u[2]; } u;
298 assert (sizeof (double) <= 2*sizeof (unsigned));
299 u.u[0] = u.u[1] = 0; u.d = tv->u.d;
300 h ^= u.u[0] ^ u.u[1];
303 case irm_C: case irm_H: case irm_I: case irm_L:
304 h ^= tv->u.CHIL; break;
305 case irm_c: case irm_h: case irm_i: case irm_l:
306 h ^= tv->u.chil; break;
308 h ^= mpz_get_ui (&tv->u.Z); break;
311 /* @@@ lower bits not random, watch for collisions; perhaps
312 replace by tv->u.p.ent - (entity *)0 */
313 h ^= ((char *)tv->u.p.ent - (char *)0) / 64;
314 } else if (tv->u.p.xname) {
315 /* Of course, strlen() in a hash function is a mistake, but this
316 case should be really rare. */
317 h ^= ID_HASH (tv->u.p.xname, strlen (tv->u.p.xname));
325 h ^= tv->u.B.n; break; /* @@@ not really good */
327 h ^= tv->u.s.p[0]<<12 ^ tv->u.s.p[tv->u.s.n]<<4 ^ tv->u.s.n; break;
329 h ^= tv->u.s.p[0]<<4 ^ tv->u.s.p[tv->u.s.n]<<12 ^ tv->u.s.n; break;
338 /******************** Initialization ****************************************/
343 obstack_init (&tv_obst);
344 obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
345 assert (IS_POW2 (ALIGNOF (tarval)));
347 /* initialize the target value table */
348 tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
355 union ieee754_double x;
357 /* assumed by tarval_hash(): */
358 assert (sizeof (float) * CHAR_BIT == 32);
359 assert (sizeof (double) * CHAR_BIT == 64);
362 /* assumed by tarval_chil & friends: */
363 assert ( (irm_C == irm_c+1) && (irm_h == irm_C+1)
364 && (irm_H == irm_h+1) && (irm_i == irm_H+1)
365 && (irm_I == irm_i+1) && (irm_l == irm_I+1)
366 && (irm_L == irm_l+1));
368 /* assumed everywhere: */
369 for (i = 0; i <= irm_L-irm_c; i += 2) {
370 assert ( IS_POW2 (max_chil[i+1]+1)
371 && (min_chil[i] == -max_chil[i]-1)
372 && ((tarval_CHIL)max_chil[i+1] == (tarval_CHIL)max_chil[i]-min_chil[i]));
377 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
379 tarval_bad = tarval_identify (tv);
381 tarval_b_false = tarval_from_long (mode_b, 0);
382 tarval_b_true = tarval_from_long (mode_b, 1);
384 /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
385 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
388 x.ieee.exponent = 0x7ff;
389 x.ieee.mantissa0 = 0;
390 x.ieee.mantissa1 = 0;
392 tarval_d_Inf = tarval_identify (tv);
394 /* IsNaN <-> exponent==0x7ff && (qnan_bit | bits | fraction_low) */
395 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
397 x.ieee_nan.negative = 0;
398 x.ieee_nan.exponent = 0x7ff;
399 x.ieee_nan.quiet_nan = 1; /* @@@ quiet or signalling? */
400 x.ieee_nan.mantissa0 = 42;
401 x.ieee_nan.mantissa1 = 0;
402 assert(x.d != x.d /* x.d is NaN */);
404 tarval_d_NaN = tarval_identify (tv);
406 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
408 tv->u.p.xname = NULL;
411 tarval_p_void = tarval_identify (tv);
413 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
416 tarval_mode_null [irm_f] = tarval_from_long (mode_f, 0);
417 tarval_mode_null [irm_d] = tarval_from_long (mode_d, 0);
418 tarval_mode_null [irm_c] = tarval_from_long (mode_c, 0);
419 tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
420 tarval_mode_null [irm_h] = tarval_from_long (mode_h, 0);
421 tarval_mode_null [irm_H] = tarval_from_long (mode_H, 0);
422 tarval_mode_null [irm_i] = tarval_from_long (mode_i, 0);
423 tarval_mode_null [irm_I] = tarval_from_long (mode_I, 0);
424 tarval_mode_null [irm_l] = tarval_from_long (mode_l, 0);
425 tarval_mode_null [irm_L] = tarval_from_long (mode_L, 0);
426 tarval_mode_null [irm_b] = tarval_b_false;
427 tarval_mode_null [irm_p] = tarval_p_void;
432 /************************* Constructors for tarvals *************************/
434 /* copy from src to dst len chars omitting '_'. */
436 stripcpy (char *dst, const char *src, size_t len)
441 if (*src == '_') src++;
444 *d = 0; /* make it 0-terminated. */
451 tarval_Z_from_str (const char *s, size_t len, int base)
458 buf = alloca (len+1);
459 stripcpy (buf, s, len);
461 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
463 if (mpz_init_set_str (&tv->u.Z, buf, base)) assert (0);
465 return tarval_identify (tv);
470 tarval_B_from_str (const char *s, size_t len)
473 size_t n; /* size of B */
474 const char *r; /* read ptr */
475 unsigned x; /* bit store */
476 int b; /* bits in x */
477 int shift; /* base shift */
482 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
485 assert (s[0] == '0');
488 case 'O': shift = 3; break;
490 case 'X': shift = 4; break;
494 r = s+len; /* set r past input */
495 s += 2; /* skip header */
500 if (*r == '_') continue; /* skip _ styropor */
501 if (('0' <= *r) && (*r <= '9')) {
503 } else if (('a' <= *r) && (*r <= 'f')) {
505 } else { assert (('A' <= *r) && (*r <= 'F'));
509 x |= d << b; /* insert d into x above the b present bits */
510 b += shift; /* x now contains shift more bits */
512 if (b >= 8) { /* we've accumulated at least a byte */
513 char c = x & 0xFF; /* extract the lower 8 bits from x */
514 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
515 x >>= 8; /* remove the lower 8 bits from x */
516 b -= 8; /* x now contains 8 bits fewer */
517 ++n; /* B grew a byte */
521 if (b >= 0) { /* flush the rest of the bits */
522 char c = x; /* extract them */
523 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
524 ++n; /* B grew a byte */
527 { unsigned char *p = obstack_finish (&tv_obst);
528 unsigned char *q = p + n;
532 /* reverse p in place */
533 while (p < q) { char c = *p; *p++ = *q; *q-- = c; }
536 return tarval_identify (tv);
541 tarval_d_from_str (const char *s, size_t len)
549 buf = alloca (len+1);
550 stripcpy (buf, s, len);
552 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
554 tv->u.d = strtod (buf, &eptr);
555 assert (eptr == buf+strlen(buf));
557 return tarval_identify (tv);
562 tarval_s_from_str (const char *s, size_t len)
568 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
572 tv->u.s.p = obstack_copy (&tv_obst, s, len);
574 return tarval_identify (tv);
578 tarval_S_from_str (const char *s, size_t len)
584 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
588 tv->u.s.p = obstack_copy (&tv_obst, s, len);
590 return tarval_identify (tv);
594 /* Create a tarval with mode `m' and value `i' casted to the type that
595 represents such tarvals on host. The resulting value must be legal
598 tarval_from_long (ir_mode *m, long val)
604 if (m == mode_T) return tarval_bad;
606 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
612 tv->u.f = val; break;
614 tv->u.d = val; break;
616 case irm_C: case irm_H: case irm_I: case irm_L:
617 tv->u.CHIL = val; break;
619 case irm_c: case irm_h: case irm_i: case irm_l:
620 tv->u.chil = val; break;
622 mpz_init_set_si (&tv->u.Z, val);
627 obstack_free (&tv_obst, tv);
628 return tarval_p_void;
630 tv->u.b = !!val; /* u.b must be 0 or 1 */
636 return tarval_identify (tv);
641 tarval_p_from_str (const char *xname)
647 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
650 tv->u.p.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
653 return tarval_identify (tv);
658 tarval_p_from_entity (entity *ent)
664 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
667 tv->u.p.xname = NULL;
670 return tarval_identify (tv);
674 /* Routines for building a tarval step by step follow.
675 Legal calling sequences:
677 No contructors except tarval_append() and tarval_append1 ()
678 tarval_finish_as() or tarval_cancel() */
680 /* Begin building a tarval. */
685 obstack_blank (&tv_obst, sizeof (tarval));
689 /* Append `n' chars from `p' to the tarval currently under construction. */
691 tarval_append (const char *p, size_t n)
694 obstack_grow (&tv_obst, p, n);
698 /* Append `ch' to the tarval currently under construction. */
700 tarval_append1 (char ch)
703 obstack_1grow (&tv_obst, ch);
707 /* Finish the tarval currently under construction and give id mode `m'.
708 `m' must be irm_C, irm_B, irm_s or irm_S.
709 Return NULL if the value does not make sense for this mode, this
710 can only happen in mode C. */
712 tarval_finish_as (ir_mode *m)
714 int size = obstack_object_size (&tv_obst) - sizeof (tarval);
717 char ch = 0; /* initialized to shut up gcc */
719 assert (BUILDING && (size >= 0));
721 if (size != 1) return tarval_cancel();
722 p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
724 obstack_blank (&tv_obst, -size);
726 tv = obstack_finish (&tv_obst);
727 p = (unsigned char *)tv + sizeof (tarval);
750 return tarval_identify (tv);
754 /* Cancel tarval building and return tarval_bad. */
759 obstack_free (&tv_obst, obstack_finish (&tv_obst));
765 /********************* Arithmethic operations on tarvals ********************/
767 /* Return `src' converted to mode `m' if representable, else NULL.
768 @@@ lots of conversions missing */
770 tarval_convert_to (tarval *src, ir_mode *m)
774 if (m == src->mode) return src;
776 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
779 switch (src->mode->code) {
782 if (m != mode_f) goto fail;
789 case irm_C: case irm_H: case irm_I: case irm_L:
790 if (mpz_cmp_si (&src->u.Z, 0) < 0) goto fail;
791 if (mpz_size (&src->u.Z) > 1) goto fail;
792 tv->u.CHIL = mpz_get_ui (&src->u.Z);
793 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
796 case irm_c: case irm_h: case irm_i: case irm_l:
797 tv->u.chil = mpz_get_si (&src->u.Z);
798 if (chil_overflow (tv->u.chil, m)) goto fail;
802 tv ->u.b = !mpz_cmp_ui (&src->u.Z, 0);
806 if (mpz_cmp_ui (&src->u.Z, 0)) goto fail;
807 obstack_free (&tv_obst, tv);
808 return tarval_p_void;
814 case irm_c: case irm_h: case irm_i: case irm_l:
816 case irm_c: case irm_h: case irm_i: case irm_l:
817 tv->u.chil = src->u.chil;
818 if (chil_overflow (tv->u.chil, m)) goto fail;
821 case irm_C: case irm_H: case irm_I: case irm_L:
822 tv->u.CHIL = src->u.chil;
823 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
827 mpz_init_set_si (&tv->u.Z, src->u.chil);
831 tv->u.b = !!src->u.chil;
837 case irm_C: case irm_H: case irm_I: case irm_L:
839 case irm_c: case irm_h: case irm_i: case irm_l:
840 tv->u.chil = src->u.CHIL;
841 if (chil_overflow (tv->u.chil, m)) goto fail;
844 case irm_C: case irm_H: case irm_I: case irm_L:
845 tv->u.CHIL = src->u.CHIL;
846 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
850 mpz_init_set_ui (&tv->u.Z, src->u.CHIL);
854 tv->u.b = !!src->u.CHIL;
863 case irm_c: case irm_h: case irm_i: case irm_l:
864 tv->u.chil = src->u.b;
867 case irm_C: case irm_H: case irm_I: case irm_L:
868 tv->u.CHIL = src->u.b;
876 obstack_free (&tv_obst, tv);
880 return tarval_identify (tv);
885 tarval_neg (tarval *a)
891 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
895 switch (a->mode->code) {
897 case irm_f: tv->u.f = -a->u.f; break;
898 case irm_d: tv->u.d = -a->u.d; break;
900 case irm_C: case irm_H: case irm_I: case irm_L:
901 tv->u.CHIL = -a->u.CHIL & tv_val_CHIL (a->mode->max);
904 case irm_c: case irm_h: case irm_i: case irm_l:
905 tv->u.chil = -a->u.chil;
906 if ( chil_overflow (tv->u.chil, a->mode)
907 || ((tv->u.chil >= 0) == (a->u.chil >= 0))) {
908 obstack_free (&tv_obst, tv);
914 mpz_neg (&tv->u.Z, &a->u.Z);
917 case irm_b: tv->u.b = !a->u.b; break;
921 return tarval_identify (tv);
925 /* Compare `a' with `b'.
926 Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
927 result is unknown. */
929 tarval_comp (tarval *a, tarval *b)
935 assert (a->mode == b->mode);
937 switch (a->mode->code) {
939 case irm_f: return ( a->u.f == b->u.f ? irpn_Eq
940 : a->u.f > b->u.f ? irpn_Gt
941 : a->u.f < b->u.f ? irpn_Lt
943 case irm_d: return ( a->u.d == b->u.d ? irpn_Eq
944 : a->u.d > b->u.d ? irpn_Gt
945 : a->u.d < b->u.d ? irpn_Lt
948 case irm_C: case irm_H: case irm_I: case irm_L:
949 return ( a->u.CHIL == b->u.CHIL ? irpn_Eq
950 : a->u.CHIL > b->u.CHIL ? irpn_Gt
953 case irm_c: case irm_h: case irm_i: case irm_l:
954 return ( a->u.chil == b->u.chil ? irpn_Eq
955 : a->u.chil > b->u.chil ? irpn_Gt
958 { int cmp = mpz_cmp (&a->u.Z, &b->u.Z);
959 return ( cmp == 0 ? irpn_Eq
964 case irm_b: return ( a->u.b == b->u.b ? irpn_Eq
965 : a->u.b > b->u.b ? irpn_Gt
967 /* The following assumes that pointers are unsigned, which is valid
968 for all sane CPUs (transputers are insane). */
969 case irm_p: return ( a == b ? irpn_Eq
970 : a == tarval_p_void ? irpn_Lt
971 : b == tarval_p_void ? irpn_Gt
972 : irpn_False); /* unknown */
978 /* Return `a+b' if computable, else NULL. Modes must be equal. */
980 tarval_add (tarval *a, tarval *b)
984 TARVAL_VRFY (a); TARVAL_VRFY (b);
985 assert (a->mode == b->mode);
987 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
991 switch (a->mode->code) {
993 case irm_f: tv->u.f = a->u.f + b->u.f; break; /* @@@ overflow etc */
994 case irm_d: tv->u.d = a->u.d + b->u.d; break; /* @@@ dto. */
996 case irm_C: case irm_H: case irm_I: case irm_L:
997 tv->u.CHIL = (a->u.CHIL + b->u.CHIL) & tv_val_CHIL (a->mode->max);
1000 case irm_c: case irm_h: case irm_i: case irm_l:
1001 tv->u.chil = a->u.chil + b->u.chil;
1002 if ( chil_overflow (tv->u.chil, a->mode)
1003 || ((tv->u.chil > a->u.chil) ^ (b->u.chil > 0))) {
1004 obstack_free (&tv_obst, tv);
1009 mpz_init (&tv->u.Z);
1010 mpz_add (&tv->u.Z, &a->u.Z, &b->u.Z);
1013 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1017 return tarval_identify (tv);
1021 /* Return `a-b' if computable, else NULL. Modes must be equal. */
1023 tarval_sub (tarval *a, tarval *b)
1027 TARVAL_VRFY (a); TARVAL_VRFY (b);
1028 assert (a->mode == b->mode);
1030 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1034 switch (a->mode->code) {
1036 case irm_f: tv->u.f = a->u.f - b->u.f; break; /* @@@ overflow etc */
1037 case irm_d: tv->u.d = a->u.d - b->u.d; break; /* @@@ dto. */
1039 case irm_C: case irm_H: case irm_I: case irm_L:
1040 tv->u.CHIL = (a->u.CHIL - b->u.CHIL) & tv_val_CHIL (a->mode->max);
1043 case irm_c: case irm_h: case irm_i: case irm_l:
1044 tv->u.chil = a->u.chil - b->u.chil;
1045 if ( chil_overflow (tv->u.chil, a->mode)
1046 || ((tv->u.chil > a->u.chil) ^ (b->u.chil < 0))) {
1047 obstack_free (&tv_obst, tv);
1052 mpz_init (&tv->u.Z);
1053 mpz_sub (&tv->u.Z, &a->u.Z, &b->u.Z);
1056 case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
1060 return tarval_identify (tv);
1064 /* Return `a*b' if computable, else NULL. Modes must be equal. */
1066 tarval_mul (tarval *a, tarval *b)
1070 TARVAL_VRFY (a); TARVAL_VRFY (b);
1071 assert (a->mode == b->mode);
1073 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1077 switch (a->mode->code) {
1079 case irm_f: tv->u.f = a->u.f * b->u.f; break; /* @@@ overflow etc */
1080 case irm_d: tv->u.d = a->u.d * b->u.d; break; /* @@@ dto. */
1082 case irm_C: case irm_H: case irm_I: case irm_L:
1083 tv->u.CHIL = (a->u.CHIL * b->u.CHIL) & tv_val_CHIL (a->mode->max);
1086 case irm_c: case irm_h: case irm_i: case irm_l:
1087 tv->u.chil = a->u.chil * b->u.chil;
1088 if ( chil_overflow (tv->u.chil, a->mode)
1089 || (b->u.chil && (tv->u.chil / b->u.chil != a->u.chil))) {
1090 obstack_free (&tv_obst, tv);
1095 mpz_init (&tv->u.Z);
1096 mpz_mul (&tv->u.Z, &a->u.Z, &b->u.Z);
1099 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1103 return tarval_identify (tv);
1107 /* Return floating-point `a/b' if computable, else NULL.
1108 Modes must be equal, non-floating-point operands are converted to irm_d. */
1110 tarval_quo (tarval *a, tarval *b)
1114 TARVAL_VRFY (a); TARVAL_VRFY (b);
1115 assert (a->mode == b->mode);
1117 switch (a->mode->code) {
1120 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1122 tv->u.f = a->u.f / b->u.f; /* @@@ overflow etc */
1125 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1127 tv->u.d = a->u.d / b->u.d; /* @@@ overflow etc */
1130 a = tarval_convert_to (a, mode_d);
1131 b = tarval_convert_to (b, mode_d);
1132 return a && b ? tarval_quo (a, b) : NULL;
1135 return tarval_identify (tv);
1139 /* Return `a/b' if computable, else NULL. Modes must be equal. */
1141 tarval_div (tarval *a, tarval *b)
1145 TARVAL_VRFY (a); TARVAL_VRFY (b);
1146 assert (a->mode == b->mode);
1148 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1152 switch (a->mode->code) {
1154 case irm_f: tv->u.f = floor (a->u.f / b->u.f); break; /* @@@ overflow etc */
1155 case irm_d: tv->u.d = floor (a->u.d / b->u.d); break; /* @@@ dto. */
1157 case irm_C: case irm_H: case irm_I: case irm_L:
1158 if (!b->u.CHIL) goto fail;
1159 tv->u.CHIL = a->u.CHIL / b->u.CHIL;
1162 case irm_c: case irm_h: case irm_i: case irm_l:
1164 || ((b->u.chil == -1) && (a->u.chil == tv_val_chil (a->mode->max) ))) {
1166 obstack_free (&tv_obst, tv);
1169 tv->u.chil = a->u.chil / b->u.chil;
1172 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1173 mpz_init (&tv->u.Z);
1174 mpz_div (&tv->u.Z, &a->u.Z, &b->u.Z);
1177 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1181 return tarval_identify (tv);
1185 /* Return `a%b' if computable, else NULL. Modes must be equal. */
1187 tarval_mod (tarval *a, tarval *b)
1191 TARVAL_VRFY (a); TARVAL_VRFY (b);
1192 assert (a->mode == b->mode);
1194 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1198 switch (a->mode->code) {
1200 case irm_f: tv->u.f = fmod (a->u.f, b->u.f); break; /* @@@ overflow etc */
1201 case irm_d: tv->u.d = fmod (a->u.d, b->u.d); break; /* @@@ dto */
1203 case irm_C: case irm_H: case irm_I: case irm_L:
1204 if (!b->u.CHIL) goto fail;
1205 tv->u.CHIL = a->u.CHIL % b->u.CHIL;
1208 case irm_c: case irm_h: case irm_i: case irm_l:
1211 obstack_free (&tv_obst, tv);
1214 tv->u.chil = a->u.chil % b->u.chil;
1217 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1218 mpz_init (&tv->u.Z);
1219 mpz_mod (&tv->u.Z, &a->u.Z, &b->u.Z);
1222 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1226 return tarval_identify (tv);
1230 /* Return `a&b'. Modes must be equal. */
1232 tarval_and (tarval *a, tarval *b)
1236 TARVAL_VRFY (a); TARVAL_VRFY (b);
1237 assert (a->mode == b->mode);
1239 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1243 switch (a->mode->code) {
1245 case irm_C: case irm_H: case irm_I: case irm_L:
1246 tv->u.CHIL = a->u.CHIL & b->u.CHIL; break;
1248 case irm_c: case irm_h: case irm_i: case irm_l:
1249 tv->u.chil = a->u.chil & b->u.chil; break;
1251 mpz_init (&tv->u.Z);
1252 mpz_and (&tv->u.Z, &a->u.Z, &b->u.Z);
1255 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1259 return tarval_identify (tv);
1263 /* Return `a|b'. Modes must be equal. */
1265 tarval_or (tarval *a, tarval *b)
1269 TARVAL_VRFY (a); TARVAL_VRFY (b);
1270 assert (a->mode == b->mode);
1272 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1276 switch (a->mode->code) {
1278 case irm_C: case irm_H: case irm_I: case irm_L:
1279 tv->u.CHIL = a->u.CHIL | b->u.CHIL; break;
1281 case irm_c: case irm_h: case irm_i: case irm_l:
1282 tv->u.chil = a->u.chil | b->u.chil; break;
1284 mpz_init (&tv->u.Z);
1285 mpz_ior (&tv->u.Z, &a->u.Z, &b->u.Z);
1288 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1292 return tarval_identify (tv);
1296 /* Return `a^b'. Modes must be equal. */
1298 tarval_eor (tarval *a, tarval *b)
1302 TARVAL_VRFY (a); TARVAL_VRFY (b);
1303 assert (a->mode == b->mode);
1305 #if 1 /* see case irm_Z below */
1306 if (a->mode == mode_Z) return NULL;
1309 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1313 switch (a->mode->code) {
1315 case irm_C: case irm_H: case irm_I: case irm_L:
1316 tv->u.CHIL = a->u.CHIL ^ b->u.CHIL; break;
1318 case irm_c: case irm_h: case irm_i: case irm_l:
1319 tv->u.chil = a->u.chil ^ b->u.chil; break;
1321 #if 0 /* gmp-1.3.2 declares but does not define mpz_xor() */
1322 mpz_init (&tv->u.Z);
1323 mpz_xor (&tv->u.Z, &a->u.Z, &b->u.Z);
1327 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1331 return tarval_identify (tv);
1335 /* Return `a<<b' if computable, else NULL. */
1337 tarval_shl (tarval *a, tarval *b)
1343 TARVAL_VRFY (a); TARVAL_VRFY (b);
1345 shift = tarval_ord (b, &b_is_huge);
1348 || ((shift >= mode_l->size*target_bits) && (a->mode != mode_Z))) {
1352 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1355 switch (a->mode->code) {
1357 case irm_C: case irm_H: case irm_I: case irm_L:
1358 tv->u.CHIL = a->u.CHIL << shift;
1361 case irm_c: case irm_h: case irm_i: case irm_l:
1362 tv->u.chil = a->u.chil << shift;
1365 mpz_init (&tv->u.Z);
1366 mpz_mul_2exp (&tv->u.Z, &a->u.Z, shift);
1368 default: assert (0);
1371 return tarval_identify (tv);
1375 /* Return `a>>b' if computable, else NULL. */
1377 tarval_shr (tarval *a, tarval *b)
1383 TARVAL_VRFY (a); TARVAL_VRFY (b);
1385 shift = tarval_ord (b, &b_is_huge);
1388 || ((shift >= mode_l->size*target_bits) && (a->mode != mode_Z))) {
1392 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1395 switch (a->mode->code) {
1397 case irm_C: case irm_H: case irm_I: case irm_L:
1398 tv->u.CHIL = a->u.CHIL >> shift;
1401 case irm_c: case irm_h: case irm_i: case irm_l:
1402 tv->u.chil = a->u.chil >> shift;
1405 mpz_init (&tv->u.Z);
1406 mpz_div_2exp (&tv->u.Z, &a->u.Z, shift);
1408 default: assert (0);
1411 return tarval_identify (tv);
1415 /* Classify `tv', which may be NULL.
1416 Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1417 multiplicative neutral element, and -1 if `tv' is the neutral
1418 element of bitwise and. */
1420 tarval_classify (tarval *tv)
1426 switch (tv->mode->code) {
1428 case irm_f: case irm_d:
1432 return (long)((tv->u.CHIL+1) & tv_val_CHIL (mode_C->max)) - 1;
1434 return (long)((tv->u.CHIL+1) & tv_val_CHIL (mode_H->max)) - 1;
1436 return (long)((tv->u.CHIL+1) & tv_val_CHIL (mode_I->max)) - 1;
1438 return (long)((tv->u.CHIL+1) & tv_val_CHIL (mode_L->max)) - 1;
1440 case irm_c: case irm_h: case irm_i: case irm_l:
1443 if (mpz_cmp_si (&tv->u.Z, 0)) return 0;
1444 else if (mpz_cmp_si (&tv->u.Z, 1)) return 1;
1445 else if (mpz_cmp_si (&tv->u.Z,-1)) return -1;
1457 tarval_s_fits (tarval *tv, long min, long max) {
1458 return (( mpz_cmp_si (&tv->u.Z, min) >= 0)
1459 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1463 tarval_u_fits (tarval *tv, unsigned long max) {
1464 return (( mpz_sgn (&tv->u.Z) >= 0)
1465 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1469 /* Convert `tv' into type `long', set `fail' if not representable.
1470 If `fail' gets set for an unsigned `tv', the correct result can be
1471 obtained by casting the result to `unsigned long'. */
1473 tarval_ord (tarval *tv, int *fail)
1477 switch (tv->mode->code) {
1479 case irm_C: case irm_H: case irm_I: case irm_L:
1480 *fail = tv->u.CHIL > tv_val_CHIL (mode_l->max);
1483 case irm_c: case irm_h: case irm_i: case irm_l:
1487 *fail = ( (mpz_cmp_si (&tv->u.Z, tv_val_chil(mode_l->max)) > 0)
1488 || (mpz_cmp_si (&tv->u.Z, tv_val_chil(mode_l->min)) < 0));
1489 return mpz_get_si (&tv->u.Z);
1503 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1505 tarval *val = XP_GETARG (tarval *, 0);
1510 switch (val->mode->code) {
1512 case irm_T: /* none */
1513 printed = XPSR ("<bad>");
1516 case irm_f: /* float */
1517 printed = XPF1R ("%g", (double)(val->u.f));
1519 case irm_d: /* double */
1520 printed = XPF1R ("%g", (double)(val->u.d));
1523 case irm_c: /* signed char */
1524 case irm_C: /* unsigned char */
1525 if (isprint (val->u.chil)) {
1526 printed = XPF1R ("'%c'", val->u.chil);
1528 printed = XPF1R ("'\\%03o'", val->u.chil);
1532 case irm_h: case irm_i: case irm_l: /* signed num */
1533 printed = XPF1R ("%ld", (long)val->u.chil);
1535 case irm_H: case irm_I: case irm_L: /* unsigned num */
1536 printed = XPF1R ("%lu", (unsigned long)val->u.CHIL);
1539 case irm_Z: /* mp int */
1540 printed = XPF1R ("%Z", &val->u.Z);
1543 case irm_p: /* pointer */
1544 if (val->u.p.xname) {
1545 printed = XPR (val->u.p.xname);
1546 } else if (val->u.p.ent) {
1547 printed = XPF1R ("(%I)", val->u.p.ent->name);
1549 assert (val == tarval_p_void);
1550 printed = XPSR ("(void)");
1554 case irm_b: /* boolean */
1555 if (val->u.b) printed = XPSR ("true");
1556 else printed = XPSR ("false");
1559 case irm_B: /* universal bits */
1560 printed = XPSR ("<@@@ some bits>");
1563 case irm_s: /* string */
1566 char *buf = alloca (val->u.s.n + 2);
1572 for (i = 0; i < val->u.s.n; ++i) {
1573 if (isprint (val->u.s.p[i])) {
1574 *bp++ = val->u.s.p[i];
1580 XPF1 ("'\\%03o'", val->u.s.p[i]);
1589 case irm_M: /* memory */
1590 case irm_R: /* region */
1599 get_tv_mode (tarval *tv)