1 /* TV --- Target Values, aka Constant Table.
2 Copyright (C) 1995, 1996 Christian von Roques */
6 /* This implementation assumes:
7 * target characters/strings can be represented as type `char'/`char *',
8 * host's type `long'/`unsigned long' can hold values of mode `l'/`L',
9 * both host and target have two's complement integral arithmetic,
10 host's C operators `/' and `%' match target's div and mod.
11 target_max_<mode> == (1<<k)-1 for some k>0
12 target_min_<mode> == -target_max_<mode>-1
13 target_max_<Mode> == target_max_<mode>-target_min_<mode>
14 * both host and target have IEEE-754 floating-point arithmetic. */
16 /* !!! float and double divides MUST NOT SIGNAL !!! */
17 /* @@@ query the floating-point expception status flags */
19 /* @@@ ToDo: tarval_convert_to is not fully implemented! */
20 /* @@@ Problem: All Values are stored twice, once as Univ_*s and a 2nd
21 time in their real target mode. :-( */
22 /* @@@ Perhaps use a set instead of a pset: new tarvals allocated on
23 stack, copied into set by tarval_identify() if really new. If
24 tarval_identify() discards often enough, the extra copy for kept
25 values is cheaper than the extra obstack_alloc()/free() for
28 /* Defining this causes inclusions of functions renamed with new gmp.h */
29 #define _TARVAL_GMP_ 0
45 #define TOBSTACK_ID "tv"
54 static struct obstack tv_obst; /* obstack for all the target values */
55 static pset *tarvals; /* pset containing pointers to _all_ tarvals */
57 /* currently building an object with tarval_start() & friends ? */
58 #define BUILDING obstack_object_size (&tv_obst)
60 /* bcopy is not ISO C */
61 #define bcopy(X, Y, Z) memcpy((Y), (X), (Z))
64 /* special tarvals: */
66 tarval *tarval_b_false;
67 tarval *tarval_b_true;
70 tarval *tarval_p_void;
71 tarval *tarval_mode_null[irm_max];
72 tarval *tarval_mode_min[irm_max];
73 tarval *tarval_mode_max[irm_max];
75 tarval *get_tarval_bad () { return tarval_bad; }
76 tarval *get_tarval_b_false () { return tarval_b_false; }
77 tarval *get_tarval_b_true () { return tarval_b_true; }
78 tarval *get_tarval_d_NaN () { return tarval_d_NaN; }
79 tarval *get_tarval_d_Inf () { return tarval_d_Inf; }
80 tarval *get_tarval_p_void () { return tarval_p_void; }
81 tarval *get_tarval_mode_null(ir_mode *mode)
82 { return tarval_mode_null[get_mode_modecode(mode)]; }
83 tarval *get_tarval_mode_min (ir_mode *mode)
84 { return tarval_mode_min[get_mode_modecode(mode)]; }
85 tarval *get_tarval_mode_max (ir_mode *mode)
86 { return tarval_mode_max[get_mode_modecode(mode)]; }
89 /* @@@ depends on order of ir_mode */
90 static tarval_chil min_chil[8] = {
96 static tarval_chil max_chil[8] = {
97 TARGET_SIMAX (c), TARGET_UIMAX (C),
98 TARGET_SIMAX (h), TARGET_UIMAX (H),
99 TARGET_SIMAX (i), TARGET_UIMAX (I),
100 TARGET_SIMAX (l), TARGET_UIMAX (L)
104 /* Used to be in irmode.h, replaced now. */
105 # define is_chilCHIL(m) ((m) <= irm_L && (m) >= irm_c) /* old */
107 /* return a mode-specific value */
110 tv_val_f (tarval *tv)
116 tv_val_d (tarval *tv)
122 tv_val_chil (tarval *tv)
128 tv_val_CHIL (tarval *tv)
134 tv_val_Z (tarval *tv)
140 tv_val_p (tarval *tv)
146 tv_val_b (tarval *tv)
152 tv_val_B (tarval *tv)
158 tv_val_s (tarval *tv)
164 /* Overflows `chil' signed integral `mode'? */
166 chil_overflow (tarval_chil chil, ir_mode *mode)
168 assert (is_chilCHIL(get_mode_modecode(mode)));
169 return (get_mode_min(mode) && get_mode_max(mode) /* only valid after firm initialization */
170 && (chil < tv_val_chil (get_mode_min(mode))
171 || tv_val_chil (get_mode_max(mode)) < chil));
175 /* Overflows `CHIL' unsigned integral `mode'? */
177 CHIL_overflow (tarval_CHIL CHIL, ir_mode *mode)
179 assert (is_chilCHIL(get_mode_modecode(mode)));
180 return (get_mode_max(mode) /* only valid after firm initialization */
181 && tv_val_CHIL (get_mode_max(mode)) < CHIL);
187 _tarval_vrfy (const tarval *val)
190 switch (get_mode_modecode(val->mode)) {
196 case irm_C: case irm_H: case irm_I: case irm_L:
197 assert (!CHIL_overflow (val->u.CHIL, val->mode)); break;
198 case irm_c: case irm_h: case irm_i: case irm_l:
199 assert (!chil_overflow (val->u.chil, val->mode)); break;
205 assert (val->u.p.ent->kind == k_entity);
206 assert ( val->u.p.xname || val->u.p.ent
207 || !tarval_p_void || (val == tarval_p_void));
211 assert (val->u.s.p); break;
213 assert (val->u.B.p); break;
215 assert ((unsigned)val->u.b <= 1); break;
217 assert (val->mode == mode_T);
228 pset_stats (tarvals);
234 /* Return the canonical tarval * for tv.
235 May destroy everything allocated on tv_obst after tv! */
237 tarval_identify (tarval *tv)
241 o = pset_insert (tarvals, tv, tarval_hash (tv));
244 obstack_free (&tv_obst, (void *)tv);
252 /* Return 0 iff a equals b. Bitwise identical NaNs compare equal. */
254 tarval_cmp (const void *p, const void *q)
262 if (a == b) return 0;
263 if ((void *)a->mode - (void *)b->mode)
264 return (void *)a->mode - (void *)b->mode;
266 switch (get_mode_modecode(a->mode)) {
269 return memcmp (&a->u.f, &b->u.f, sizeof (a->u.f));
271 return memcmp (&a->u.d, &b->u.d, sizeof (a->u.d));
273 case irm_C: case irm_H: case irm_I: case irm_L:
274 if (sizeof (int) == sizeof (tarval_CHIL)) {
275 return a->u.CHIL - b->u.CHIL;
277 return a->u.CHIL != b->u.CHIL;
279 case irm_c: case irm_h: case irm_i: case irm_l:
280 if (sizeof (int) == sizeof (tarval_chil)) {
281 return a->u.chil - b->u.chil;
283 return a->u.chil != b->u.chil;
286 return mpz_cmp (&a->u.Z, &b->u.Z);
292 if (a->u.p.ent || b->u.p.ent)
293 return (char *)a->u.p.ent - (char *)b->u.p.ent;
294 if (a->u.p.xname && b->u.p.xname)
295 return strcmp (a->u.p.xname, b->u.p.xname);
296 return a->u.p.xname - b->u.p.xname;
298 return a->u.b - b->u.b;
300 return ( a->u.B.n - b->u.B.n
301 ? memcmp (a->u.B.p, b->u.B.p, a->u.B.n)
302 : a->u.B.n - b->u.B.n);
303 case irm_s: case irm_S:
304 return ( a->u.s.n == b->u.s.n
305 ? memcmp (a->u.s.p, b->u.s.p, a->u.s.n)
306 : a->u.s.n - b->u.s.n);
313 tarval_hash (tarval *tv)
317 h = get_mode_modecode(tv->mode) * 0x421u;
318 switch (get_mode_modecode(tv->mode)) {
320 h = 0x94b527ce; break;
323 { union { float f; unsigned u; } u;
324 assert (sizeof (float) <= sizeof (unsigned));
325 u.u = 0; u.f = tv->u.f;
331 { union { double d; unsigned u[2]; } u;
332 assert (sizeof (double) <= 2*sizeof (unsigned));
333 u.u[0] = u.u[1] = 0; u.d = tv->u.d;
334 h ^= u.u[0] ^ u.u[1];
337 case irm_C: case irm_H: case irm_I: case irm_L:
338 h ^= tv->u.CHIL; break;
339 case irm_c: case irm_h: case irm_i: case irm_l:
340 h ^= tv->u.chil; break;
343 h ^= mpz_get_ui (&tv->u.Z); break;
345 h ^= (unsigned int) tv; break; /* tut das? */
349 /* @@@ lower bits not random, watch for collisions; perhaps
350 replace by tv->u.p.ent - (entity *)0 */
351 h ^= ((char *)tv->u.p.ent - (char *)0) / 64;
352 } else if (tv->u.p.xname) {
353 /* Of course, strlen() in a hash function is a mistake, but this
354 case should be really rare. */
355 h ^= ID_HASH (tv->u.p.xname, strlen (tv->u.p.xname));
363 h ^= tv->u.B.n; break; /* @@@ not really good */
365 h ^= tv->u.s.p[0]<<12 ^ tv->u.s.p[tv->u.s.n]<<4 ^ tv->u.s.n; break;
367 h ^= tv->u.s.p[0]<<4 ^ tv->u.s.p[tv->u.s.n]<<12 ^ tv->u.s.n; break;
376 /*** ***************** Initialization ************************************* ***/
381 obstack_init (&tv_obst);
382 obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
383 assert (IS_POW2 (ALIGNOF (tarval)));
385 /* initialize the target value table */
386 tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
393 union ieee754_double x;
395 /* assumed by tarval_hash(): */
396 assert (sizeof (float) * CHAR_BIT == 32);
397 assert (sizeof (double) * CHAR_BIT == 64);
400 /* assumed by tarval_chil & friends: */
401 assert ( (irm_C == irm_c+1) && (irm_h == irm_C+1)
402 && (irm_H == irm_h+1) && (irm_i == irm_H+1)
403 && (irm_I == irm_i+1) && (irm_l == irm_I+1)
404 && (irm_L == irm_l+1));
406 /* assumed everywhere: */
407 for (i = 0; i <= irm_L-irm_c; i += 2) {
408 assert ( IS_POW2 (max_chil[i+1]+1)
409 && (min_chil[i] == -max_chil[i]-1)
410 && ((tarval_CHIL)max_chil[i+1] == (tarval_CHIL)max_chil[i]-min_chil[i]));
415 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
417 tarval_bad = tarval_identify (tv);
419 tarval_b_false = tarval_from_long (mode_b, 0);
420 tarval_b_true = tarval_from_long (mode_b, 1);
422 /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
423 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
426 x.ieee.exponent = 0x7ff;
427 x.ieee.mantissa0 = 0;
428 x.ieee.mantissa1 = 0;
430 tarval_d_Inf = tarval_identify (tv);
432 /* IsNaN <-> exponent==0x7ff && (qnan_bit | bits | fraction_low) */
433 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
435 x.ieee_nan.negative = 0;
436 x.ieee_nan.exponent = 0x7ff;
437 x.ieee_nan.quiet_nan = 1; /* @@@ quiet or signalling? */
438 x.ieee_nan.mantissa0 = 42;
439 x.ieee_nan.mantissa1 = 0;
440 assert(x.d != x.d /* x.d is NaN */);
442 tarval_d_NaN = tarval_identify (tv);
444 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
446 tv->u.p.xname = NULL;
449 tarval_p_void = tarval_identify (tv);
451 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
454 tarval_mode_null [irm_f] = tarval_from_long (mode_f, 0);
455 tarval_mode_null [irm_d] = tarval_from_long (mode_d, 0);
456 tarval_mode_null [irm_c] = tarval_from_long (mode_c, 0);
457 tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
458 tarval_mode_null [irm_h] = tarval_from_long (mode_h, 0);
459 tarval_mode_null [irm_H] = tarval_from_long (mode_H, 0);
460 tarval_mode_null [irm_i] = tarval_from_long (mode_i, 0);
461 tarval_mode_null [irm_I] = tarval_from_long (mode_I, 0);
462 tarval_mode_null [irm_l] = tarval_from_long (mode_l, 0);
463 tarval_mode_null [irm_L] = tarval_from_long (mode_L, 0);
464 tarval_mode_null [irm_b] = tarval_b_false;
465 tarval_mode_null [irm_p] = tarval_p_void;
470 /*** ********************** Constructors for tarvals ********************** ***/
472 /* copy from src to dst len chars omitting '_'. */
474 stripcpy (char *dst, const char *src, size_t len)
479 if (*src == '_') src++;
482 *d = 0; /* make it 0-terminated. */
489 tarval_Z_from_str (const char *s, size_t len, int base)
496 buf = alloca (len+1);
497 stripcpy (buf, s, len);
499 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
502 if (mpz_init_set_str (&tv->u.Z, buf, base)) assert (0);
504 assert(0 && "no support for Z in tv!");
507 return tarval_identify (tv);
512 tarval_B_from_str (const char *s, size_t len)
515 size_t n; /* size of B */
516 const char *r; /* read ptr */
517 unsigned x; /* bit store */
518 int b; /* bits in x */
519 int shift; /* base shift */
524 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
527 assert (s[0] == '0');
530 case 'O': shift = 3; break;
532 case 'X': shift = 4; break;
536 r = s+len; /* set r past input */
537 s += 2; /* skip header */
542 if (*r == '_') continue; /* skip _ styropor */
543 if (('0' <= *r) && (*r <= '9')) {
545 } else if (('a' <= *r) && (*r <= 'f')) {
547 } else { assert (('A' <= *r) && (*r <= 'F'));
551 x |= d << b; /* insert d into x above the b present bits */
552 b += shift; /* x now contains shift more bits */
554 if (b >= 8) { /* we've accumulated at least a byte */
555 char c = x & 0xFF; /* extract the lower 8 bits from x */
556 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
557 x >>= 8; /* remove the lower 8 bits from x */
558 b -= 8; /* x now contains 8 bits fewer */
559 ++n; /* B grew a byte */
563 if (b >= 0) { /* flush the rest of the bits */
564 char c = x; /* extract them */
565 obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
566 ++n; /* B grew a byte */
569 { unsigned char *p = obstack_finish (&tv_obst);
570 unsigned char *q = p + n;
574 /* reverse p in place */
575 while (p < q) { char c = *p; *p++ = *q; *q-- = c; }
578 return tarval_identify (tv);
583 tarval_f_from_str (const char *s, size_t len)
591 buf = alloca (len+1);
592 stripcpy (buf, s, len);
594 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
596 tv->u.f = (float)strtod (buf, &eptr);
597 assert (eptr == buf+strlen(buf));
599 return tarval_identify (tv);
604 tarval_d_from_str (const char *s, size_t len)
612 buf = alloca (len+1);
613 stripcpy (buf, s, len);
615 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
617 tv->u.d = strtod (buf, &eptr);
618 assert (eptr == buf+strlen(buf));
620 return tarval_identify (tv);
625 tarval_s_from_str (const char *s, size_t len)
631 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
635 tv->u.s.p = obstack_copy (&tv_obst, s, len);
637 return tarval_identify (tv);
641 tarval_S_from_str (const char *s, size_t len)
647 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
651 tv->u.s.p = obstack_copy (&tv_obst, s, len);
653 return tarval_identify (tv);
656 tarval *tarval_int_from_str (const char *s, size_t len, int base, ir_mode *m) {
661 assert (mode_is_int(m));
664 buf = alloca (len+1);
665 stripcpy (buf, s, len);
668 val = strtol(buf, &eptr, base); /* strtoll */
669 assert (eptr == buf+strlen(buf));
670 if ((errno == ERANGE) &&
671 ((m == mode_l) || (m == mode_L)) ) {
672 printf("WARNING: Constant %s not representable. Continuing with %ld.\n",
676 return tarval_from_long(m, val);
679 /* Create a tarval with mode `m' and value `i' casted to the type that
680 represents such tarvals on host. The resulting value must be legal
683 tarval_from_long (ir_mode *m, long val)
689 if (m == mode_T) return tarval_bad;
691 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
694 switch (get_mode_modecode(m)) {
697 tv->u.f = val; break;
699 tv->u.d = val; break;
701 case irm_C: case irm_H: case irm_I: case irm_L:
702 tv->u.CHIL = val; break;
704 case irm_c: case irm_h: case irm_i: case irm_l:
705 tv->u.chil = val; break;
708 mpz_init_set_si (&tv->u.Z, val);
710 assert(0 && "no support for Z in tv!");
716 obstack_free (&tv_obst, tv);
717 return tarval_p_void;
719 tv->u.b = !!val; /* u.b must be 0 or 1 */
725 return tarval_identify (tv);
730 tarval_p_from_str (const char *xname)
736 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
739 tv->u.p.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
742 return tarval_identify (tv);
747 tarval_p_from_entity (entity *ent)
753 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
756 tv->u.p.xname = NULL;
759 return tarval_identify (tv);
763 /* Routines for building a tarval step by step follow.
764 Legal calling sequences:
766 No contructors except tarval_append() and tarval_append1 ()
767 tarval_finish_as() or tarval_cancel() */
769 /* Begin building a tarval. */
774 obstack_blank (&tv_obst, sizeof (tarval));
778 /* Append `n' chars from `p' to the tarval currently under construction. */
780 tarval_append (const char *p, size_t n)
783 obstack_grow (&tv_obst, p, n);
787 /* Append `ch' to the tarval currently under construction. */
789 tarval_append1 (char ch)
792 obstack_1grow (&tv_obst, ch);
796 /* Finish the tarval currently under construction and give id mode `m'.
797 `m' must be irm_C, irm_B, irm_s or irm_S.
798 Return NULL if the value does not make sense for this mode, this
799 can only happen in mode C. */
801 tarval_finish_as (ir_mode *m)
803 int size = obstack_object_size (&tv_obst) - sizeof (tarval);
806 char ch = 0; /* initialized to shut up gcc */
808 assert (BUILDING && (size >= 0));
810 if (size != 1) return tarval_cancel();
811 p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
813 obstack_blank (&tv_obst, -size);
815 tv = obstack_finish (&tv_obst);
816 p = (unsigned char *)tv + sizeof (tarval);
819 switch (get_mode_modecode(m)) {
839 return tarval_identify (tv);
843 /* Cancel tarval building and return tarval_bad. */
848 obstack_free (&tv_obst, obstack_finish (&tv_obst));
854 /*** ****************** Arithmethic operations on tarvals ***************** ***/
856 /* Return `src' converted to mode `m' if representable, else NULL.
857 @@@ lots of conversions missing */
859 tarval_convert_to (tarval *src, ir_mode *m)
863 if (m == src->mode) return src;
865 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
868 switch (get_mode_modecode(src->mode)) {
871 if (m != mode_f) goto fail;
877 switch (get_mode_modecode(m)) {
879 case irm_C: case irm_H: case irm_I: case irm_L:
880 if (mpz_cmp_si (&src->u.Z, 0) < 0) goto fail;
881 if (mpz_size (&src->u.Z) > 1) goto fail;
882 tv->u.CHIL = mpz_get_ui (&src->u.Z);
883 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
886 case irm_c: case irm_h: case irm_i: case irm_l:
887 tv->u.chil = mpz_get_si (&src->u.Z);
888 if (chil_overflow (tv->u.chil, m)) goto fail;
892 tv ->u.b = !mpz_cmp_ui (&src->u.Z, 0);
896 if (mpz_cmp_ui (&src->u.Z, 0)) goto fail;
897 obstack_free (&tv_obst, tv);
898 return tarval_p_void;
907 case irm_c: case irm_h: case irm_i: case irm_l:
908 switch (get_mode_modecode(m)) {
909 case irm_c: case irm_h: case irm_i: case irm_l:
910 tv->u.chil = src->u.chil;
911 if (chil_overflow (tv->u.chil, m)) goto fail;
914 case irm_C: case irm_H: case irm_I: case irm_L:
915 tv->u.CHIL = src->u.chil;
916 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
921 mpz_init_set_si (&tv->u.Z, src->u.chil);
928 tv->u.b = !!src->u.chil;
934 case irm_C: case irm_H: case irm_I: case irm_L:
935 switch (get_mode_modecode(m)) {
936 case irm_c: case irm_h: case irm_i: case irm_l:
937 tv->u.chil = src->u.CHIL;
938 if (chil_overflow (tv->u.chil, m)) goto fail;
941 case irm_C: case irm_H: case irm_I: case irm_L:
942 tv->u.CHIL = src->u.CHIL;
943 if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
948 mpz_init_set_ui (&tv->u.Z, src->u.CHIL);
955 tv->u.b = !!src->u.CHIL;
963 switch (get_mode_modecode(m)) {
964 case irm_c: case irm_h: case irm_i: case irm_l:
965 tv->u.chil = src->u.b;
968 case irm_C: case irm_H: case irm_I: case irm_L:
969 tv->u.CHIL = src->u.b;
977 obstack_free (&tv_obst, tv);
981 return tarval_identify (tv);
985 /* GL Why are there no ArmRoq comments, why is this not used? */
987 tarval_neg (tarval *a)
993 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
997 switch (get_mode_modecode(a->mode)) {
999 case irm_f: tv->u.f = -a->u.f; break;
1000 case irm_d: tv->u.d = -a->u.d; break;
1002 case irm_C: case irm_H: case irm_I: case irm_L:
1003 tv->u.CHIL = -a->u.CHIL & tv_val_CHIL (get_mode_max(a->mode));
1006 case irm_c: case irm_h: case irm_i: case irm_l:
1007 tv->u.chil = -a->u.chil;
1008 if ( chil_overflow (tv->u.chil, a->mode)
1009 || ((tv->u.chil >= 0) == (a->u.chil >= 0))) {
1010 obstack_free (&tv_obst, tv);
1016 mpz_init (&tv->u.Z);
1017 mpz_neg (&tv->u.Z, &a->u.Z);
1019 obstack_free (&tv_obst, tv);
1021 printf("\nWrong negation\n\n");
1025 case irm_b: tv->u.b = !a->u.b; break;
1029 return tarval_identify (tv);
1033 /* Compare `a' with `b'.
1034 Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
1035 result is unknown. */
1037 tarval_comp (tarval *a, tarval *b)
1043 assert (a->mode == b->mode);
1045 switch (get_mode_modecode(a->mode)) {
1047 case irm_f: return ( a->u.f == b->u.f ? irpn_Eq
1048 : a->u.f > b->u.f ? irpn_Gt
1049 : a->u.f < b->u.f ? irpn_Lt
1051 case irm_d: return ( a->u.d == b->u.d ? irpn_Eq
1052 : a->u.d > b->u.d ? irpn_Gt
1053 : a->u.d < b->u.d ? irpn_Lt
1056 case irm_C: case irm_H: case irm_I: case irm_L:
1057 return ( a->u.CHIL == b->u.CHIL ? irpn_Eq
1058 : a->u.CHIL > b->u.CHIL ? irpn_Gt
1061 case irm_c: case irm_h: case irm_i: case irm_l:
1062 return ( a->u.chil == b->u.chil ? irpn_Eq
1063 : a->u.chil > b->u.chil ? irpn_Gt
1068 int cmp = mpz_cmp (&a->u.Z, &b->u.Z);
1069 return ( cmp == 0 ? irpn_Eq
1077 case irm_b: return ( a->u.b == b->u.b ? irpn_Eq
1078 : a->u.b > b->u.b ? irpn_Gt
1080 /* The following assumes that pointers are unsigned, which is valid
1081 for all sane CPUs (transputers are insane). */
1082 case irm_p: return ( a == b ? irpn_Eq
1083 : a == tarval_p_void ? irpn_Lt
1084 : b == tarval_p_void ? irpn_Gt
1085 : irpn_False); /* unknown */
1086 default: assert (0);
1091 /* Return `a+b' if computable, else NULL. Modes must be equal. */
1093 tarval_add (tarval *a, tarval *b)
1097 TARVAL_VRFY (a); TARVAL_VRFY (b);
1098 assert (a->mode == b->mode);
1100 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1104 switch (get_mode_modecode(a->mode)) {
1106 case irm_f: tv->u.f = a->u.f + b->u.f; break; /* @@@ overflow etc */
1107 case irm_d: tv->u.d = a->u.d + b->u.d; break; /* @@@ dto. */
1109 case irm_C: case irm_H: case irm_I: case irm_L:
1110 tv->u.CHIL = (a->u.CHIL + b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1113 case irm_c: case irm_h: case irm_i: case irm_l:
1114 tv->u.chil = a->u.chil + b->u.chil;
1115 if ( chil_overflow (tv->u.chil, a->mode)
1116 || ((tv->u.chil > a->u.chil) ^ (b->u.chil > 0))) {
1117 obstack_free (&tv_obst, tv);
1123 mpz_init (&tv->u.Z);
1124 mpz_add (&tv->u.Z, &a->u.Z, &b->u.Z);
1126 obstack_free (&tv_obst, tv);
1131 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1135 return tarval_identify (tv);
1139 /* Return `a-b' if computable, else NULL. Modes must be equal. */
1141 tarval_sub (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 (get_mode_modecode(a->mode)) {
1154 case irm_f: tv->u.f = a->u.f - b->u.f; break; /* @@@ overflow etc */
1155 case irm_d: tv->u.d = a->u.d - b->u.d; break; /* @@@ dto. */
1157 case irm_C: case irm_H: case irm_I: case irm_L:
1158 tv->u.CHIL = (a->u.CHIL - b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1161 case irm_c: case irm_h: case irm_i: case irm_l:
1162 tv->u.chil = a->u.chil - b->u.chil;
1163 if ( chil_overflow (tv->u.chil, a->mode)
1164 || ((tv->u.chil > a->u.chil) ^ (b->u.chil < 0))) {
1165 obstack_free (&tv_obst, tv);
1171 mpz_init (&tv->u.Z);
1172 mpz_sub (&tv->u.Z, &a->u.Z, &b->u.Z);
1174 obstack_free (&tv_obst, tv);
1179 case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
1183 return tarval_identify (tv);
1186 /* Return `a*b' if computable, else NULL. Modes must be equal. */
1188 tarval_mul (tarval *a, tarval *b)
1192 TARVAL_VRFY (a); TARVAL_VRFY (b);
1193 assert (a->mode == b->mode);
1195 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1199 switch (get_mode_modecode(a->mode)) {
1201 case irm_f: tv->u.f = a->u.f * b->u.f; break; /* @@@ overflow etc */
1202 case irm_d: tv->u.d = a->u.d * b->u.d; break; /* @@@ dto. */
1204 case irm_C: case irm_H: case irm_I: case irm_L:
1205 tv->u.CHIL = (a->u.CHIL * b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1208 case irm_c: case irm_h: case irm_i: case irm_l:
1209 tv->u.chil = a->u.chil * b->u.chil;
1210 if ( chil_overflow (tv->u.chil, a->mode)
1211 || (b->u.chil && (tv->u.chil / b->u.chil != a->u.chil))) {
1212 obstack_free (&tv_obst, tv);
1218 mpz_init (&tv->u.Z);
1219 mpz_mul (&tv->u.Z, &a->u.Z, &b->u.Z);
1221 obstack_free (&tv_obst, tv);
1226 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1230 return tarval_identify (tv);
1234 /* Return floating-point `a/b' if computable, else NULL.
1235 Modes must be equal, non-floating-point operands are converted to irm_d. */
1237 tarval_quo (tarval *a, tarval *b)
1241 TARVAL_VRFY (a); TARVAL_VRFY (b);
1242 assert (a->mode == b->mode);
1244 switch (get_mode_modecode(a->mode)) {
1247 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1249 tv->u.f = a->u.f / b->u.f; /* @@@ overflow etc */
1252 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1254 tv->u.d = a->u.d / b->u.d; /* @@@ overflow etc */
1257 a = tarval_convert_to (a, mode_d);
1258 b = tarval_convert_to (b, mode_d);
1259 return a && b ? tarval_quo (a, b) : NULL;
1262 return tarval_identify (tv);
1266 /* Return `a/b' if computable, else NULL. Modes must be equal. */
1268 tarval_div (tarval *a, tarval *b)
1272 TARVAL_VRFY (a); TARVAL_VRFY (b);
1273 assert (a->mode == b->mode);
1275 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1279 switch (get_mode_modecode(a->mode)) {
1281 case irm_f: tv->u.f = floor (a->u.f / b->u.f); break; /* @@@ overflow etc */
1282 case irm_d: tv->u.d = floor (a->u.d / b->u.d); break; /* @@@ dto. */
1284 case irm_C: case irm_H: case irm_I: case irm_L:
1285 if (!b->u.CHIL) goto fail;
1286 tv->u.CHIL = a->u.CHIL / b->u.CHIL;
1289 case irm_c: case irm_h: case irm_i: case irm_l:
1291 || ((b->u.chil == -1) && (a->u.chil == tv_val_chil (get_mode_max(a->mode)) ))) {
1293 obstack_free (&tv_obst, tv);
1296 tv->u.chil = a->u.chil / b->u.chil;
1300 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1301 mpz_init (&tv->u.Z);
1302 mpz_div (&tv->u.Z, &a->u.Z, &b->u.Z);
1308 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1312 return tarval_identify (tv);
1316 /* Return `a%b' if computable, else NULL. Modes must be equal. */
1318 tarval_mod (tarval *a, tarval *b)
1322 TARVAL_VRFY (a); TARVAL_VRFY (b);
1323 assert (a->mode == b->mode);
1325 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1329 switch (get_mode_modecode(a->mode)) {
1331 case irm_f: tv->u.f = fmod (a->u.f, b->u.f); break; /* @@@ overflow etc */
1332 case irm_d: tv->u.d = fmod (a->u.d, b->u.d); break; /* @@@ dto */
1334 case irm_C: case irm_H: case irm_I: case irm_L:
1335 if (!b->u.CHIL) goto fail;
1336 tv->u.CHIL = a->u.CHIL % b->u.CHIL;
1339 case irm_c: case irm_h: case irm_i: case irm_l:
1342 obstack_free (&tv_obst, tv);
1345 tv->u.chil = a->u.chil % b->u.chil;
1349 if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1350 mpz_init (&tv->u.Z);
1351 mpz_mod (&tv->u.Z, &a->u.Z, &b->u.Z);
1357 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1361 return tarval_identify (tv);
1364 /* Return |a| if computable, else Null. */
1365 /* is -max == min?? */
1367 tarval_abs (tarval *a) {
1369 if (tv_is_negative(a)) return tarval_neg(a);
1374 tv_is_negative(tarval *a) {
1376 switch (get_mode_modecode(a->mode)) {
1378 case irm_f: return (a->u.f<0); break;
1379 case irm_d: return (a->u.d<0); break;
1381 case irm_C: case irm_H: case irm_I: case irm_L:
1385 case irm_c: case irm_h: case irm_i: case irm_l:
1386 return (a->u.chil < 0);
1398 /* Return `a&b'. Modes must be equal. */
1400 tarval_and (tarval *a, tarval *b)
1404 TARVAL_VRFY (a); TARVAL_VRFY (b);
1405 assert (a->mode == b->mode);
1407 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1411 switch (get_mode_modecode(a->mode)) {
1413 case irm_C: case irm_H: case irm_I: case irm_L:
1414 tv->u.CHIL = a->u.CHIL & b->u.CHIL; break;
1416 case irm_c: case irm_h: case irm_i: case irm_l:
1417 tv->u.chil = a->u.chil & b->u.chil; break;
1420 mpz_init (&tv->u.Z);
1421 mpz_and (&tv->u.Z, &a->u.Z, &b->u.Z);
1427 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1431 return tarval_identify (tv);
1435 /* Return `a|b'. Modes must be equal. */
1437 tarval_or (tarval *a, tarval *b)
1441 TARVAL_VRFY (a); TARVAL_VRFY (b);
1442 assert (a->mode == b->mode);
1444 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1448 switch (get_mode_modecode(a->mode)) {
1450 case irm_C: case irm_H: case irm_I: case irm_L:
1451 tv->u.CHIL = a->u.CHIL | b->u.CHIL; break;
1453 case irm_c: case irm_h: case irm_i: case irm_l:
1454 tv->u.chil = a->u.chil | b->u.chil; break;
1457 mpz_init (&tv->u.Z);
1458 mpz_ior (&tv->u.Z, &a->u.Z, &b->u.Z);
1464 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1468 return tarval_identify (tv);
1472 /* Return `a^b'. Modes must be equal. */
1474 tarval_eor (tarval *a, tarval *b)
1478 TARVAL_VRFY (a); TARVAL_VRFY (b);
1479 assert (a->mode == b->mode);
1481 #if 1 /* see case irm_Z below */
1482 if (a->mode == mode_Z) return NULL;
1485 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1489 switch (get_mode_modecode(a->mode)) {
1491 case irm_C: case irm_H: case irm_I: case irm_L:
1492 tv->u.CHIL = a->u.CHIL ^ b->u.CHIL; break;
1494 case irm_c: case irm_h: case irm_i: case irm_l:
1495 tv->u.chil = a->u.chil ^ b->u.chil; break;
1498 /* gmp-1.3.2 declares but does not define mpz_xor() */
1499 mpz_init (&tv->u.Z);
1500 mpz_xor (&tv->u.Z, &a->u.Z, &b->u.Z);
1504 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1508 return tarval_identify (tv);
1512 /* Return `a<<b' if computable, else NULL. */
1514 tarval_shl (tarval *a, tarval *b)
1520 TARVAL_VRFY (a); TARVAL_VRFY (b);
1522 shift = tarval_ord (b, &b_is_huge);
1525 || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1529 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1532 switch (get_mode_modecode(a->mode)) {
1534 case irm_C: case irm_H: case irm_I: case irm_L:
1535 tv->u.CHIL = a->u.CHIL << shift;
1538 case irm_c: case irm_h: case irm_i: case irm_l:
1539 tv->u.chil = a->u.chil << shift;
1543 mpz_init (&tv->u.Z);
1544 mpz_mul_2exp (&tv->u.Z, &a->u.Z, shift);
1549 default: assert (0);
1552 return tarval_identify (tv);
1556 /* Return `a>>b' if computable, else NULL.
1557 The interpretation of >> (sign extended or not) is implementaion
1558 dependent, i.e. this is neither shr nor shrs!! */
1560 tarval_shr (tarval *a, tarval *b)
1566 TARVAL_VRFY (a); TARVAL_VRFY (b);
1568 shift = tarval_ord (b, &b_is_huge);
1571 || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1575 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1578 switch (get_mode_modecode(a->mode)) {
1580 case irm_C: case irm_H: case irm_I: case irm_L:
1581 tv->u.CHIL = a->u.CHIL >> shift;
1584 case irm_c: case irm_h: case irm_i: case irm_l:
1585 tv->u.chil = a->u.chil >> shift;
1589 mpz_init (&tv->u.Z);
1590 mpz_div_2exp (&tv->u.Z, &a->u.Z, shift);
1595 default: assert (0);
1598 return tarval_identify (tv);
1602 /* Classify `tv', which may be NULL.
1603 Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1604 multiplicative neutral element, and -1 if `tv' is the neutral
1605 element of bitwise and. */
1607 tarval_classify (tarval *tv)
1613 switch (get_mode_modecode(tv->mode)) {
1615 case irm_f: case irm_d:
1619 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_C))) - 1;
1621 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_H))) - 1;
1623 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_I))) - 1;
1625 return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_L))) - 1;
1627 case irm_c: case irm_h: case irm_i: case irm_l:
1631 if (mpz_cmp_si (&tv->u.Z, 0)) return 0;
1632 else if (mpz_cmp_si (&tv->u.Z, 1)) return 1;
1633 else if (mpz_cmp_si (&tv->u.Z,-1)) return -1;
1647 tarval_s_fits (tarval *tv, long min, long max) {
1648 return (( mpz_cmp_si (&tv->u.Z, min) >= 0)
1649 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1653 tarval_u_fits (tarval *tv, unsigned long max) {
1654 return (( mpz_sgn (&tv->u.Z) >= 0)
1655 && mpz_cmp_si (&tv->u.Z, max) <= 0);
1659 /* Convert `tv' into type `long', set `fail' if not representable.
1660 If `fail' gets set for an unsigned `tv', the correct result can be
1661 obtained by casting the result to `unsigned long'. */
1663 tarval_ord (tarval *tv, int *fail)
1667 switch (get_mode_modecode(tv->mode)) {
1669 case irm_C: case irm_H: case irm_I: case irm_L:
1670 *fail = tv->u.CHIL > tv_val_CHIL (get_mode_max(mode_l));
1673 case irm_c: case irm_h: case irm_i: case irm_l:
1678 *fail = ( (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) > 0)
1679 || (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) < 0));
1680 return mpz_get_si (&tv->u.Z);
1697 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1699 tarval *val = XP_GETARG (tarval *, 0);
1705 switch (get_mode_modecode(val->mode)) {
1707 case irm_T: /* none */
1708 printed = XPSR ("<bad>");
1711 case irm_f: /* float */
1712 sprintf (buf, "%1.9e", (float)(val->u.f));
1713 printed = XPF1R ("%s", buf);
1715 case irm_d: /* double */
1716 printed = XPF1R ("%1.30g", (double)(val->u.d));
1719 case irm_c: /* signed char */
1720 case irm_C: /* unsigned char */
1721 if ((isprint (val->u.chil)) &&
1722 (val->u.chil != '\\') && (val->u.chil != '\'')) {
1723 printed = XPF1R ("'%c'", val->u.chil);
1725 printed = XPF1R ("0x%x", (unsigned long)val->u.chil);
1729 case irm_h: case irm_i: case irm_l: /* signed num */
1730 printed = XPF1R ("%ld", (long)val->u.chil);
1732 case irm_H: case irm_I: case irm_L: /* unsigned num */
1733 printed = XPF1R ("%lu", (unsigned long)val->u.CHIL);
1736 case irm_Z: /* mp int */
1737 printed = XPF1R ("%Z", &val->u.Z);
1740 case irm_p: /* pointer */
1741 if (val->u.p.xname) {
1742 printed = XPR (val->u.p.xname);
1743 } else if (val->u.p.ent) {
1744 if (get_entity_peculiarity(val->u.p.ent) == existent)
1745 printed = XPF1R ("&(%I)", get_entity_ld_ident(val->u.p.ent));
1747 printed = XPSR ("(NULL)");
1749 assert (val == tarval_p_void);
1750 printed = XPSR ("(void)");
1754 case irm_b: /* boolean */
1755 if (val->u.b) printed = XPSR ("true");
1756 else printed = XPSR ("false");
1759 case irm_B: /* universal bits */
1760 printed = XPSR ("<@@@ some bits>");
1763 case irm_s: /* string */
1766 char *buf = alloca (val->u.s.n + 2);
1772 for (i = 0; i < val->u.s.n; ++i) {
1773 if (isprint (val->u.s.p[i])) {
1774 *bp++ = val->u.s.p[i];
1780 XPF1 ("'\\%03o'", val->u.s.p[i]);
1789 case irm_M: /* memory */
1790 case irm_R: /* region */
1800 get_tv_mode (tarval *tv)
1805 /* Returns the entity if the tv is a pointer to an entity, else
1807 entity *get_tv_entity(tarval *tv) {
1810 if (tv->mode == mode_p) {
1811 if (tv->u.p.xname) {
1814 } else if (tv->u.p.ent) {