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
26 /* Defining this causes inclusions of functions renamed with new gmp.h */
27 #define _TARVAL_GMP_ 0
42 #define TOBSTACK_ID "tv"
51 static struct obstack tv_obst; /* obstack for all the target values */
52 static pset *tarvals; /* pset containing pointers to _all_ tarvals */
54 /* currently building an object with tarval_start() & friends ? */
55 #define BUILDING obstack_object_size (&tv_obst)
57 /* special tarvals: */
59 tarval *tarval_b_false;
60 tarval *tarval_b_true;
63 tarval *tarval_p_void;
64 tarval *tarval_mode_null[irm_max];
67 /* @@@ depends on order of ir_mode */
68 static tarval_chil min_chil[8] = {
74 static tarval_chil max_chil[8] = {
75 TARGET_SIMAX (c), TARGET_UIMAX (C),
76 TARGET_SIMAX (h), TARGET_UIMAX (H),
77 TARGET_SIMAX (i), TARGET_UIMAX (I),
78 TARGET_SIMAX (l), TARGET_UIMAX (L)
82 /* return a mode-specific value */
97 tv_val_chil (tarval *tv)
103 tv_val_CHIL (tarval *tv)
109 tv_val_Z (tarval *tv)
115 tv_val_p (tarval *tv)
121 tv_val_b (tarval *tv)
127 tv_val_B (tarval *tv)
133 tv_val_s (tarval *tv)
139 /* Overflows `chil' signed integral `mode'? */
141 chil_overflow (tarval_chil chil, ir_mode *mode)
143 assert (is_chilCHIL(get_mode_modecode(mode)));
144 return (get_mode_min(mode) && get_mode_max(mode) /* only valid after firm initialization */
145 && (chil < tv_val_chil (get_mode_min(mode))
146 || tv_val_chil (get_mode_max(mode)) < chil));
150 /* Overflows `CHIL' unsigned integral `mode'? */
152 CHIL_overflow (tarval_CHIL CHIL, ir_mode *mode)
154 assert (is_chilCHIL(get_mode_modecode(mode)));
155 return (get_mode_max(mode) /* only valid after firm initialization */
156 && tv_val_CHIL (get_mode_max(mode)) < CHIL);
162 _tarval_vrfy (const tarval *val)
165 switch (get_mode_modecode(val->mode)) {
171 case irm_C: case irm_H: case irm_I: case irm_L:
172 assert (!CHIL_overflow (val->u.CHIL, val->mode)); break;
173 case irm_c: case irm_h: case irm_i: case irm_l:
174 assert (!chil_overflow (val->u.chil, val->mode)); break;
180 assert (val->u.p.ent->kind == k_entity);
181 assert ( val->u.p.xname || val->u.p.ent
182 || !tarval_p_void || (val == tarval_p_void));
186 assert (val->u.s.p); break;
188 assert (val->u.B.p); break;
190 assert ((unsigned)val->u.b <= 1); break;
192 assert (val->mode == mode_T);
203 pset_stats (tarvals);
209 /* Return the canonical tarval * for tv.
210 May destroy everything allocated on tv_obst after tv! */
212 tarval_identify (tarval *tv)
216 o = pset_insert (tarvals, tv, tarval_hash (tv));
219 obstack_free (&tv_obst, (void *)tv);
227 /* Return 0 iff a equals b. Bitwise identical NaNs compare equal. */
229 tarval_cmp (const void *p, const void *q)
237 if (a == b) return 0;
238 if ((void *)a->mode - (void *)b->mode)
239 return (void *)a->mode - (void *)b->mode;
241 switch (get_mode_modecode(a->mode)) {
244 return memcmp (&a->u.f, &b->u.f, sizeof (a->u.f));
246 return memcmp (&a->u.d, &b->u.d, sizeof (a->u.d));
248 case irm_C: case irm_H: case irm_I: case irm_L:
249 if (sizeof (int) == sizeof (tarval_CHIL)) {
250 return a->u.CHIL - b->u.CHIL;
252 return a->u.CHIL != b->u.CHIL;
254 case irm_c: case irm_h: case irm_i: case irm_l:
255 if (sizeof (int) == sizeof (tarval_chil)) {
256 return a->u.chil - b->u.chil;
258 return a->u.chil != b->u.chil;
261 return mpz_cmp (&a->u.Z, &b->u.Z);
267 if (a->u.p.ent || b->u.p.ent)
268 return (char *)a->u.p.ent - (char *)b->u.p.ent;
269 if (a->u.p.xname && b->u.p.xname)
270 return strcmp (a->u.p.xname, b->u.p.xname);
271 return a->u.p.xname - b->u.p.xname;
273 return a->u.b - b->u.b;
275 return ( a->u.B.n - b->u.B.n
276 ? memcmp (a->u.B.p, b->u.B.p, a->u.B.n)
277 : a->u.B.n - b->u.B.n);
278 case irm_s: case irm_S:
279 return ( a->u.s.n == b->u.s.n
280 ? memcmp (a->u.s.p, b->u.s.p, a->u.s.n)
281 : a->u.s.n - b->u.s.n);
288 tarval_hash (tarval *tv)
292 h = get_mode_modecode(tv->mode) * 0x421u;
293 switch (get_mode_modecode(tv->mode)) {
295 h = 0x94b527ce; break;
298 { union { float f; unsigned u; } u;
299 assert (sizeof (float) <= sizeof (unsigned));
300 u.u = 0; u.f = tv->u.f;
306 { union { double d; unsigned u[2]; } u;
307 assert (sizeof (double) <= 2*sizeof (unsigned));
308 u.u[0] = u.u[1] = 0; u.d = tv->u.d;
309 h ^= u.u[0] ^ u.u[1];
312 case irm_C: case irm_H: case irm_I: case irm_L:
313 h ^= tv->u.CHIL; break;
314 case irm_c: case irm_h: case irm_i: case irm_l:
315 h ^= tv->u.chil; break;
318 h ^= mpz_get_ui (&tv->u.Z); break;
320 h ^= (unsigned int) tv; break; /* tut das? */
324 /* @@@ lower bits not random, watch for collisions; perhaps
325 replace by tv->u.p.ent - (entity *)0 */
326 h ^= ((char *)tv->u.p.ent - (char *)0) / 64;
327 } else if (tv->u.p.xname) {
328 /* Of course, strlen() in a hash function is a mistake, but this
329 case should be really rare. */
330 h ^= ID_HASH (tv->u.p.xname, strlen (tv->u.p.xname));
338 h ^= tv->u.B.n; break; /* @@@ not really good */
340 h ^= tv->u.s.p[0]<<12 ^ tv->u.s.p[tv->u.s.n]<<4 ^ tv->u.s.n; break;
342 h ^= tv->u.s.p[0]<<4 ^ tv->u.s.p[tv->u.s.n]<<12 ^ tv->u.s.n; break;
351 /*** ***************** Initialization ************************************* ***/
356 obstack_init (&tv_obst);
357 obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
358 assert (IS_POW2 (ALIGNOF (tarval)));
360 /* initialize the target value table */
361 tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
368 union ieee754_double x;
370 /* assumed by tarval_hash(): */
371 assert (sizeof (float) * CHAR_BIT == 32);
372 assert (sizeof (double) * CHAR_BIT == 64);
375 /* assumed by tarval_chil & friends: */
376 assert ( (irm_C == irm_c+1) && (irm_h == irm_C+1)
377 && (irm_H == irm_h+1) && (irm_i == irm_H+1)
378 && (irm_I == irm_i+1) && (irm_l == irm_I+1)
379 && (irm_L == irm_l+1));
381 /* assumed everywhere: */
382 for (i = 0; i <= irm_L-irm_c; i += 2) {
383 assert ( IS_POW2 (max_chil[i+1]+1)
384 && (min_chil[i] == -max_chil[i]-1)
385 && ((tarval_CHIL)max_chil[i+1] == (tarval_CHIL)max_chil[i]-min_chil[i]));
390 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
392 tarval_bad = tarval_identify (tv);
394 tarval_b_false = tarval_from_long (mode_b, 0);
395 tarval_b_true = tarval_from_long (mode_b, 1);
397 /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
398 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
401 x.ieee.exponent = 0x7ff;
402 x.ieee.mantissa0 = 0;
403 x.ieee.mantissa1 = 0;
405 tarval_d_Inf = tarval_identify (tv);
407 /* IsNaN <-> exponent==0x7ff && (qnan_bit | bits | fraction_low) */
408 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
410 x.ieee_nan.negative = 0;
411 x.ieee_nan.exponent = 0x7ff;
412 x.ieee_nan.quiet_nan = 1; /* @@@ quiet or signalling? */
413 x.ieee_nan.mantissa0 = 42;
414 x.ieee_nan.mantissa1 = 0;
415 assert(x.d != x.d /* x.d is NaN */);
417 tarval_d_NaN = tarval_identify (tv);
419 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
421 tv->u.p.xname = NULL;
424 tarval_p_void = tarval_identify (tv);
426 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
429 tarval_mode_null [irm_f] = tarval_from_long (mode_f, 0);
430 tarval_mode_null [irm_d] = tarval_from_long (mode_d, 0);
431 tarval_mode_null [irm_c] = tarval_from_long (mode_c, 0);
432 tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
433 tarval_mode_null [irm_h] = tarval_from_long (mode_h, 0);
434 tarval_mode_null [irm_H] = tarval_from_long (mode_H, 0);
435 tarval_mode_null [irm_i] = tarval_from_long (mode_i, 0);
436 tarval_mode_null [irm_I] = tarval_from_long (mode_I, 0);
437 tarval_mode_null [irm_l] = tarval_from_long (mode_l, 0);
438 tarval_mode_null [irm_L] = tarval_from_long (mode_L, 0);
439 tarval_mode_null [irm_b] = tarval_b_false;
440 tarval_mode_null [irm_p] = tarval_p_void;
445 /*** ********************** Constructors for tarvals ********************** ***/
447 /* copy from src to dst len chars omitting '_'. */
449 stripcpy (char *dst, const char *src, size_t len)
454 if (*src == '_') src++;
457 *d = 0; /* make it 0-terminated. */
464 tarval_Z_from_str (const char *s, size_t len, int base)
471 buf = alloca (len+1);
472 stripcpy (buf, s, len);
474 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
477 if (mpz_init_set_str (&tv->u.Z, buf, base)) assert (0);
479 assert(0 && "no support for Z in tv!");
482 return tarval_identify (tv);
487 tarval_B_from_str (const char *s, size_t len)
490 size_t n; /* size of B */
491 const char *r; /* read ptr */
492 unsigned x; /* bit store */
493 int b; /* bits in x */
494 int shift; /* base shift */
499 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
502 assert (s[0] == '0');
505 case 'O': shift = 3; break;
507 case 'X': shift = 4; break;
511 r = s+len; /* set r past input */
512 s += 2; /* skip header */
517 if (*r == '_') continue; /* skip _ styropor */
518 if (('0' <= *r) && (*r <= '9')) {
520 } else if (('a' <= *r) && (*r <= 'f')) {
522 } else { assert (('A' <= *r) && (*r <= 'F'));
526 x |= d << b; /* insert d into x above the b present bits */
527 b += shift; /* x now contains shift more bits */
529 if (b >= 8) { /* we've accumulated at least a byte */
530 char c = x & 0xFF; /* extract the lower 8 bits from x */
531 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
532 x >>= 8; /* remove the lower 8 bits from x */
533 b -= 8; /* x now contains 8 bits fewer */
534 ++n; /* B grew a byte */
538 if (b >= 0) { /* flush the rest of the bits */
539 char c = x; /* extract them */
540 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
541 ++n; /* B grew a byte */
544 { unsigned char *p = obstack_finish (&tv_obst);
545 unsigned char *q = p + n;
549 /* reverse p in place */
550 while (p < q) { char c = *p; *p++ = *q; *q-- = c; }
553 return tarval_identify (tv);
558 tarval_d_from_str (const char *s, size_t len)
566 buf = alloca (len+1);
567 stripcpy (buf, s, len);
569 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
571 tv->u.d = strtod (buf, &eptr);
572 assert (eptr == buf+strlen(buf));
574 return tarval_identify (tv);
579 tarval_s_from_str (const char *s, size_t len)
585 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
589 tv->u.s.p = obstack_copy (&tv_obst, s, len);
591 return tarval_identify (tv);
595 tarval_S_from_str (const char *s, size_t len)
601 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
605 tv->u.s.p = obstack_copy (&tv_obst, s, len);
607 return tarval_identify (tv);
611 /* Create a tarval with mode `m' and value `i' casted to the type that
612 represents such tarvals on host. The resulting value must be legal
615 tarval_from_long (ir_mode *m, long val)
621 if (m == mode_T) return tarval_bad;
623 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
626 switch (get_mode_modecode(m)) {
629 tv->u.f = val; break;
631 tv->u.d = val; break;
633 case irm_C: case irm_H: case irm_I: case irm_L:
634 tv->u.CHIL = val; break;
636 case irm_c: case irm_h: case irm_i: case irm_l:
637 tv->u.chil = val; break;
640 mpz_init_set_si (&tv->u.Z, val);
642 assert(0 && "no support for Z in tv!");
648 obstack_free (&tv_obst, tv);
649 return tarval_p_void;
651 tv->u.b = !!val; /* u.b must be 0 or 1 */
657 return tarval_identify (tv);
662 tarval_p_from_str (const char *xname)
668 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
671 tv->u.p.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
674 return tarval_identify (tv);
679 tarval_p_from_entity (entity *ent)
685 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
688 tv->u.p.xname = NULL;
691 return tarval_identify (tv);
695 /* Routines for building a tarval step by step follow.
696 Legal calling sequences:
698 No contructors except tarval_append() and tarval_append1 ()
699 tarval_finish_as() or tarval_cancel() */
701 /* Begin building a tarval. */
706 obstack_blank (&tv_obst, sizeof (tarval));
710 /* Append `n' chars from `p' to the tarval currently under construction. */
712 tarval_append (const char *p, size_t n)
715 obstack_grow (&tv_obst, p, n);
719 /* Append `ch' to the tarval currently under construction. */
721 tarval_append1 (char ch)
724 obstack_1grow (&tv_obst, ch);
728 /* Finish the tarval currently under construction and give id mode `m'.
729 `m' must be irm_C, irm_B, irm_s or irm_S.
730 Return NULL if the value does not make sense for this mode, this
731 can only happen in mode C. */
733 tarval_finish_as (ir_mode *m)
735 int size = obstack_object_size (&tv_obst) - sizeof (tarval);
738 char ch = 0; /* initialized to shut up gcc */
740 assert (BUILDING && (size >= 0));
742 if (size != 1) return tarval_cancel();
743 p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
745 obstack_blank (&tv_obst, -size);
747 tv = obstack_finish (&tv_obst);
748 p = (unsigned char *)tv + sizeof (tarval);
751 switch (get_mode_modecode(m)) {
771 return tarval_identify (tv);
775 /* Cancel tarval building and return tarval_bad. */
780 obstack_free (&tv_obst, obstack_finish (&tv_obst));
786 /*** ****************** Arithmethic operations on tarvals ***************** ***/
788 /* Return `src' converted to mode `m' if representable, else NULL.
789 @@@ lots of conversions missing */
791 tarval_convert_to (tarval *src, ir_mode *m)
795 if (m == src->mode) return src;
797 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
800 switch (get_mode_modecode(src->mode)) {
803 if (m != mode_f) goto fail;
809 switch (get_mode_modecode(m)) {
811 case irm_C: case irm_H: case irm_I: case irm_L:
812 if (mpz_cmp_si (&src->u.Z, 0) < 0) goto fail;
813 if (mpz_size (&src->u.Z) > 1) goto fail;
814 tv->u.CHIL = mpz_get_ui (&src->u.Z);
815 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
818 case irm_c: case irm_h: case irm_i: case irm_l:
819 tv->u.chil = mpz_get_si (&src->u.Z);
820 if (chil_overflow (tv->u.chil, m)) goto fail;
824 tv ->u.b = !mpz_cmp_ui (&src->u.Z, 0);
828 if (mpz_cmp_ui (&src->u.Z, 0)) goto fail;
829 obstack_free (&tv_obst, tv);
830 return tarval_p_void;
839 case irm_c: case irm_h: case irm_i: case irm_l:
840 switch (get_mode_modecode(m)) {
841 case irm_c: case irm_h: case irm_i: case irm_l:
842 tv->u.chil = src->u.chil;
843 if (chil_overflow (tv->u.chil, m)) goto fail;
846 case irm_C: case irm_H: case irm_I: case irm_L:
847 tv->u.CHIL = src->u.chil;
848 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
853 mpz_init_set_si (&tv->u.Z, src->u.chil);
860 tv->u.b = !!src->u.chil;
866 case irm_C: case irm_H: case irm_I: case irm_L:
867 switch (get_mode_modecode(m)) {
868 case irm_c: case irm_h: case irm_i: case irm_l:
869 tv->u.chil = src->u.CHIL;
870 if (chil_overflow (tv->u.chil, m)) goto fail;
873 case irm_C: case irm_H: case irm_I: case irm_L:
874 tv->u.CHIL = src->u.CHIL;
875 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
880 mpz_init_set_ui (&tv->u.Z, src->u.CHIL);
887 tv->u.b = !!src->u.CHIL;
895 switch (get_mode_modecode(m)) {
896 case irm_c: case irm_h: case irm_i: case irm_l:
897 tv->u.chil = src->u.b;
900 case irm_C: case irm_H: case irm_I: case irm_L:
901 tv->u.CHIL = src->u.b;
909 obstack_free (&tv_obst, tv);
913 return tarval_identify (tv);
917 /* GL Why are there no ArmRoq comments, why is this not used? */
919 tarval_neg (tarval *a)
925 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
929 switch (get_mode_modecode(a->mode)) {
931 case irm_f: tv->u.f = -a->u.f; break;
932 case irm_d: tv->u.d = -a->u.d; break;
934 case irm_C: case irm_H: case irm_I: case irm_L:
935 tv->u.CHIL = -a->u.CHIL & tv_val_CHIL (get_mode_max(a->mode));
938 case irm_c: case irm_h: case irm_i: case irm_l:
939 tv->u.chil = -a->u.chil;
940 if ( chil_overflow (tv->u.chil, a->mode)
941 || ((tv->u.chil >= 0) == (a->u.chil >= 0))) {
942 obstack_free (&tv_obst, tv);
949 mpz_neg (&tv->u.Z, &a->u.Z);
951 obstack_free (&tv_obst, tv);
953 printf("\nWrong negation\n\n");
957 case irm_b: tv->u.b = !a->u.b; break;
961 return tarval_identify (tv);
965 /* Compare `a' with `b'.
966 Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
967 result is unknown. */
969 tarval_comp (tarval *a, tarval *b)
975 assert (a->mode == b->mode);
977 switch (get_mode_modecode(a->mode)) {
979 case irm_f: return ( a->u.f == b->u.f ? irpn_Eq
980 : a->u.f > b->u.f ? irpn_Gt
981 : a->u.f < b->u.f ? irpn_Lt
983 case irm_d: return ( a->u.d == b->u.d ? irpn_Eq
984 : a->u.d > b->u.d ? irpn_Gt
985 : a->u.d < b->u.d ? irpn_Lt
988 case irm_C: case irm_H: case irm_I: case irm_L:
989 return ( a->u.CHIL == b->u.CHIL ? irpn_Eq
990 : a->u.CHIL > b->u.CHIL ? irpn_Gt
993 case irm_c: case irm_h: case irm_i: case irm_l:
994 return ( a->u.chil == b->u.chil ? irpn_Eq
995 : a->u.chil > b->u.chil ? irpn_Gt
1000 int cmp = mpz_cmp (&a->u.Z, &b->u.Z);
1001 return ( cmp == 0 ? irpn_Eq
1009 case irm_b: return ( a->u.b == b->u.b ? irpn_Eq
1010 : a->u.b > b->u.b ? irpn_Gt
1012 /* The following assumes that pointers are unsigned, which is valid
1013 for all sane CPUs (transputers are insane). */
1014 case irm_p: return ( a == b ? irpn_Eq
1015 : a == tarval_p_void ? irpn_Lt
1016 : b == tarval_p_void ? irpn_Gt
1017 : irpn_False); /* unknown */
1018 default: assert (0);
1023 /* Return `a+b' if computable, else NULL. Modes must be equal. */
1025 tarval_add (tarval *a, tarval *b)
1029 TARVAL_VRFY (a); TARVAL_VRFY (b);
1030 assert (a->mode == b->mode);
1032 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1036 switch (get_mode_modecode(a->mode)) {
1038 case irm_f: tv->u.f = a->u.f + b->u.f; break; /* @@@ overflow etc */
1039 case irm_d: tv->u.d = a->u.d + b->u.d; break; /* @@@ dto. */
1041 case irm_C: case irm_H: case irm_I: case irm_L:
1042 tv->u.CHIL = (a->u.CHIL + b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1045 case irm_c: case irm_h: case irm_i: case irm_l:
1046 tv->u.chil = a->u.chil + b->u.chil;
1047 if ( chil_overflow (tv->u.chil, a->mode)
1048 || ((tv->u.chil > a->u.chil) ^ (b->u.chil > 0))) {
1049 obstack_free (&tv_obst, tv);
1055 mpz_init (&tv->u.Z);
1056 mpz_add (&tv->u.Z, &a->u.Z, &b->u.Z);
1058 obstack_free (&tv_obst, tv);
1063 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1067 return tarval_identify (tv);
1071 /* Return `a-b' if computable, else NULL. Modes must be equal. */
1073 tarval_sub (tarval *a, tarval *b)
1077 TARVAL_VRFY (a); TARVAL_VRFY (b);
1078 assert (a->mode == b->mode);
1080 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1084 switch (get_mode_modecode(a->mode)) {
1086 case irm_f: tv->u.f = a->u.f - b->u.f; break; /* @@@ overflow etc */
1087 case irm_d: tv->u.d = a->u.d - b->u.d; break; /* @@@ dto. */
1089 case irm_C: case irm_H: case irm_I: case irm_L:
1090 tv->u.CHIL = (a->u.CHIL - b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1093 case irm_c: case irm_h: case irm_i: case irm_l:
1094 tv->u.chil = a->u.chil - b->u.chil;
1095 if ( chil_overflow (tv->u.chil, a->mode)
1096 || ((tv->u.chil > a->u.chil) ^ (b->u.chil < 0))) {
1097 obstack_free (&tv_obst, tv);
1103 mpz_init (&tv->u.Z);
1104 mpz_sub (&tv->u.Z, &a->u.Z, &b->u.Z);
1106 obstack_free (&tv_obst, tv);
1111 case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
1115 return tarval_identify (tv);
1118 /* Return `a*b' if computable, else NULL. Modes must be equal. */
1120 tarval_mul (tarval *a, tarval *b)
1124 TARVAL_VRFY (a); TARVAL_VRFY (b);
1125 assert (a->mode == b->mode);
1127 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1131 switch (get_mode_modecode(a->mode)) {
1133 case irm_f: tv->u.f = a->u.f * b->u.f; break; /* @@@ overflow etc */
1134 case irm_d: tv->u.d = a->u.d * b->u.d; break; /* @@@ dto. */
1136 case irm_C: case irm_H: case irm_I: case irm_L:
1137 tv->u.CHIL = (a->u.CHIL * b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1140 case irm_c: case irm_h: case irm_i: case irm_l:
1141 tv->u.chil = a->u.chil * b->u.chil;
1142 if ( chil_overflow (tv->u.chil, a->mode)
1143 || (b->u.chil && (tv->u.chil / b->u.chil != a->u.chil))) {
1144 obstack_free (&tv_obst, tv);
1150 mpz_init (&tv->u.Z);
1151 mpz_mul (&tv->u.Z, &a->u.Z, &b->u.Z);
1153 obstack_free (&tv_obst, tv);
1158 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1162 return tarval_identify (tv);
1166 /* Return floating-point `a/b' if computable, else NULL.
1167 Modes must be equal, non-floating-point operands are converted to irm_d. */
1169 tarval_quo (tarval *a, tarval *b)
1173 TARVAL_VRFY (a); TARVAL_VRFY (b);
1174 assert (a->mode == b->mode);
1176 switch (get_mode_modecode(a->mode)) {
1179 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1181 tv->u.f = a->u.f / b->u.f; /* @@@ overflow etc */
1184 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1186 tv->u.d = a->u.d / b->u.d; /* @@@ overflow etc */
1189 a = tarval_convert_to (a, mode_d);
1190 b = tarval_convert_to (b, mode_d);
1191 return a && b ? tarval_quo (a, b) : NULL;
1194 return tarval_identify (tv);
1198 /* Return `a/b' if computable, else NULL. Modes must be equal. */
1200 tarval_div (tarval *a, tarval *b)
1204 TARVAL_VRFY (a); TARVAL_VRFY (b);
1205 assert (a->mode == b->mode);
1207 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1211 switch (get_mode_modecode(a->mode)) {
1213 case irm_f: tv->u.f = floor (a->u.f / b->u.f); break; /* @@@ overflow etc */
1214 case irm_d: tv->u.d = floor (a->u.d / b->u.d); break; /* @@@ dto. */
1216 case irm_C: case irm_H: case irm_I: case irm_L:
1217 if (!b->u.CHIL) goto fail;
1218 tv->u.CHIL = a->u.CHIL / b->u.CHIL;
1221 case irm_c: case irm_h: case irm_i: case irm_l:
1223 || ((b->u.chil == -1) && (a->u.chil == tv_val_chil (get_mode_max(a->mode)) ))) {
1225 obstack_free (&tv_obst, tv);
1228 tv->u.chil = a->u.chil / b->u.chil;
1232 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1233 mpz_init (&tv->u.Z);
1234 mpz_div (&tv->u.Z, &a->u.Z, &b->u.Z);
1240 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1244 return tarval_identify (tv);
1248 /* Return `a%b' if computable, else NULL. Modes must be equal. */
1250 tarval_mod (tarval *a, tarval *b)
1254 TARVAL_VRFY (a); TARVAL_VRFY (b);
1255 assert (a->mode == b->mode);
1257 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1261 switch (get_mode_modecode(a->mode)) {
1263 case irm_f: tv->u.f = fmod (a->u.f, b->u.f); break; /* @@@ overflow etc */
1264 case irm_d: tv->u.d = fmod (a->u.d, b->u.d); break; /* @@@ dto */
1266 case irm_C: case irm_H: case irm_I: case irm_L:
1267 if (!b->u.CHIL) goto fail;
1268 tv->u.CHIL = a->u.CHIL % b->u.CHIL;
1271 case irm_c: case irm_h: case irm_i: case irm_l:
1274 obstack_free (&tv_obst, tv);
1277 tv->u.chil = a->u.chil % b->u.chil;
1281 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1282 mpz_init (&tv->u.Z);
1283 mpz_mod (&tv->u.Z, &a->u.Z, &b->u.Z);
1289 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1293 return tarval_identify (tv);
1296 /* Return |a| if computable, else Null. */
1297 /* is -max == min?? */
1299 tarval_abs (tarval *a) {
1301 if (tv_is_negative(a)) return tarval_neg(a);
1306 tv_is_negative(tarval *a) {
1308 switch (get_mode_modecode(a->mode)) {
1310 case irm_f: return (a->u.f<0); break;
1311 case irm_d: return (a->u.d<0); break;
1313 case irm_C: case irm_H: case irm_I: case irm_L:
1317 case irm_c: case irm_h: case irm_i: case irm_l:
1318 return (a->u.chil < 0);
1330 /* Return `a&b'. Modes must be equal. */
1332 tarval_and (tarval *a, tarval *b)
1336 TARVAL_VRFY (a); TARVAL_VRFY (b);
1337 assert (a->mode == b->mode);
1339 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1343 switch (get_mode_modecode(a->mode)) {
1345 case irm_C: case irm_H: case irm_I: case irm_L:
1346 tv->u.CHIL = a->u.CHIL & b->u.CHIL; break;
1348 case irm_c: case irm_h: case irm_i: case irm_l:
1349 tv->u.chil = a->u.chil & b->u.chil; break;
1352 mpz_init (&tv->u.Z);
1353 mpz_and (&tv->u.Z, &a->u.Z, &b->u.Z);
1359 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1363 return tarval_identify (tv);
1367 /* Return `a|b'. Modes must be equal. */
1369 tarval_or (tarval *a, tarval *b)
1373 TARVAL_VRFY (a); TARVAL_VRFY (b);
1374 assert (a->mode == b->mode);
1376 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1380 switch (get_mode_modecode(a->mode)) {
1382 case irm_C: case irm_H: case irm_I: case irm_L:
1383 tv->u.CHIL = a->u.CHIL | b->u.CHIL; break;
1385 case irm_c: case irm_h: case irm_i: case irm_l:
1386 tv->u.chil = a->u.chil | b->u.chil; break;
1389 mpz_init (&tv->u.Z);
1390 mpz_ior (&tv->u.Z, &a->u.Z, &b->u.Z);
1396 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1400 return tarval_identify (tv);
1404 /* Return `a^b'. Modes must be equal. */
1406 tarval_eor (tarval *a, tarval *b)
1410 TARVAL_VRFY (a); TARVAL_VRFY (b);
1411 assert (a->mode == b->mode);
1413 #if 1 /* see case irm_Z below */
1414 if (a->mode == mode_Z) return NULL;
1417 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1421 switch (get_mode_modecode(a->mode)) {
1423 case irm_C: case irm_H: case irm_I: case irm_L:
1424 tv->u.CHIL = a->u.CHIL ^ b->u.CHIL; break;
1426 case irm_c: case irm_h: case irm_i: case irm_l:
1427 tv->u.chil = a->u.chil ^ b->u.chil; break;
1430 /* gmp-1.3.2 declares but does not define mpz_xor() */
1431 mpz_init (&tv->u.Z);
1432 mpz_xor (&tv->u.Z, &a->u.Z, &b->u.Z);
1436 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1440 return tarval_identify (tv);
1444 /* Return `a<<b' if computable, else NULL. */
1446 tarval_shl (tarval *a, tarval *b)
1452 TARVAL_VRFY (a); TARVAL_VRFY (b);
1454 shift = tarval_ord (b, &b_is_huge);
1457 || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1461 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1464 switch (get_mode_modecode(a->mode)) {
1466 case irm_C: case irm_H: case irm_I: case irm_L:
1467 tv->u.CHIL = a->u.CHIL << shift;
1470 case irm_c: case irm_h: case irm_i: case irm_l:
1471 tv->u.chil = a->u.chil << shift;
1475 mpz_init (&tv->u.Z);
1476 mpz_mul_2exp (&tv->u.Z, &a->u.Z, shift);
1481 default: assert (0);
1484 return tarval_identify (tv);
1488 /* Return `a>>b' if computable, else NULL.
1489 The interpretation of >> (sign extended or not) is implementaion
1490 dependent, i.e. this is neither shr nor shrs!! */
1492 tarval_shr (tarval *a, tarval *b)
1498 TARVAL_VRFY (a); TARVAL_VRFY (b);
1500 shift = tarval_ord (b, &b_is_huge);
1503 || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1507 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1510 switch (get_mode_modecode(a->mode)) {
1512 case irm_C: case irm_H: case irm_I: case irm_L:
1513 tv->u.CHIL = a->u.CHIL >> shift;
1516 case irm_c: case irm_h: case irm_i: case irm_l:
1517 tv->u.chil = a->u.chil >> shift;
1521 mpz_init (&tv->u.Z);
1522 mpz_div_2exp (&tv->u.Z, &a->u.Z, shift);
1527 default: assert (0);
1530 return tarval_identify (tv);
1534 /* Classify `tv', which may be NULL.
1535 Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1536 multiplicative neutral element, and -1 if `tv' is the neutral
1537 element of bitwise and. */
1539 tarval_classify (tarval *tv)
1545 switch (get_mode_modecode(tv->mode)) {
1547 case irm_f: case irm_d:
1551 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_C))) - 1;
1553 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_H))) - 1;
1555 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_I))) - 1;
1557 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_L))) - 1;
1559 case irm_c: case irm_h: case irm_i: case irm_l:
1563 if (mpz_cmp_si (&tv->u.Z, 0)) return 0;
1564 else if (mpz_cmp_si (&tv->u.Z, 1)) return 1;
1565 else if (mpz_cmp_si (&tv->u.Z,-1)) return -1;
1579 tarval_s_fits (tarval *tv, long min, long max) {
1580 return (( mpz_cmp_si (&tv->u.Z, min) >= 0)
1581 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1585 tarval_u_fits (tarval *tv, unsigned long max) {
1586 return (( mpz_sgn (&tv->u.Z) >= 0)
1587 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1591 /* Convert `tv' into type `long', set `fail' if not representable.
1592 If `fail' gets set for an unsigned `tv', the correct result can be
1593 obtained by casting the result to `unsigned long'. */
1595 tarval_ord (tarval *tv, int *fail)
1599 switch (get_mode_modecode(tv->mode)) {
1601 case irm_C: case irm_H: case irm_I: case irm_L:
1602 *fail = tv->u.CHIL > tv_val_CHIL (get_mode_max(mode_l));
1605 case irm_c: case irm_h: case irm_i: case irm_l:
1610 *fail = ( (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) > 0)
1611 || (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) < 0));
1612 return mpz_get_si (&tv->u.Z);
1629 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1631 tarval *val = XP_GETARG (tarval *, 0);
1636 switch (get_mode_modecode(val->mode)) {
1638 case irm_T: /* none */
1639 printed = XPSR ("<bad>");
1642 case irm_f: /* float */
1643 printed = XPF1R ("%g", (double)(val->u.f));
1645 case irm_d: /* double */
1646 printed = XPF1R ("%g", (double)(val->u.d));
1649 case irm_c: /* signed char */
1650 case irm_C: /* unsigned char */
1651 if (isprint (val->u.chil)) {
1652 printed = XPF1R ("'%c'", val->u.chil);
1654 printed = XPF1R ("'\\%03o'", val->u.chil);
1658 case irm_h: case irm_i: case irm_l: /* signed num */
1659 printed = XPF1R ("%ld", (long)val->u.chil);
1661 case irm_H: case irm_I: case irm_L: /* unsigned num */
1662 printed = XPF1R ("%lu", (unsigned long)val->u.CHIL);
1665 case irm_Z: /* mp int */
1666 printed = XPF1R ("%Z", &val->u.Z);
1669 case irm_p: /* pointer */
1670 if (val->u.p.xname) {
1671 printed = XPR (val->u.p.xname);
1672 } else if (val->u.p.ent) {
1673 printed = XPF1R ("(%I)", val->u.p.ent->name);
1675 assert (val == tarval_p_void);
1676 printed = XPSR ("(void)");
1680 case irm_b: /* boolean */
1681 if (val->u.b) printed = XPSR ("true");
1682 else printed = XPSR ("false");
1685 case irm_B: /* universal bits */
1686 printed = XPSR ("<@@@ some bits>");
1689 case irm_s: /* string */
1692 char *buf = alloca (val->u.s.n + 2);
1698 for (i = 0; i < val->u.s.n; ++i) {
1699 if (isprint (val->u.s.p[i])) {
1700 *bp++ = val->u.s.p[i];
1706 XPF1 ("'\\%03o'", val->u.s.p[i]);
1715 case irm_M: /* memory */
1716 case irm_R: /* region */
1726 get_tv_mode (tarval *tv)