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
42 #define TOBSTACK_ID "tv"
53 static struct obstack tv_obst; /* obstack for all the target values */
54 static pset *tarvals; /* pset containing pointers to _all_ tarvals */
56 /* currently building an object with tarval_start() & friends ? */
57 #define BUILDING obstack_object_size (&tv_obst)
59 /* bcopy is not ISO C */
60 #define bcopy(X, Y, Z) memcpy((Y), (X), (Z))
63 /* special tarvals: */
65 tarval *tarval_b_false;
66 tarval *tarval_b_true;
69 tarval *tarval_P_void;
70 tarval *tarval_mode_null[irm_max];
71 tarval *tarval_mode_min[irm_max];
72 tarval *tarval_mode_max[irm_max];
74 tarval *get_tarval_bad () { return tarval_bad; }
75 tarval *get_tarval_b_false () { return tarval_b_false; }
76 tarval *get_tarval_b_true () { return tarval_b_true; }
77 tarval *get_tarval_D_NaN () { return tarval_D_NaN; }
78 tarval *get_tarval_D_Inf () { return tarval_D_Inf; }
79 tarval *get_tarval_P_void () { return tarval_P_void; }
80 tarval *get_tarval_mode_null(ir_mode *mode)
81 { return tarval_mode_null[get_mode_modecode(mode)]; }
82 tarval *get_tarval_mode_min (ir_mode *mode)
83 { return tarval_mode_min[get_mode_modecode(mode)]; }
84 tarval *get_tarval_mode_max (ir_mode *mode)
85 { return tarval_mode_max[get_mode_modecode(mode)]; }
88 /* @@@ depends on order of ir_mode */
89 static tarval_sInt min_sInt[8] = {
95 static tarval_sInt max_sInt[8] = {
96 TARGET_SIMAX (c), TARGET_UIMAX (C),
97 TARGET_SIMAX (h), TARGET_UIMAX (H),
98 TARGET_SIMAX (i), TARGET_UIMAX (I),
99 TARGET_SIMAX (l), TARGET_UIMAX (L)
103 /* Used to be in irmode.h, replaced now. */
104 # define is_Int(m) ((m) <= irm_Lu && (m) >= irm_Bs) /* old */
106 /* return a mode-specific value */
109 tv_val_F (tarval *tv)
115 tv_val_D (tarval *tv)
121 tv_val_E (tarval *tv)
127 tv_val_sInt (tarval *tv)
133 tv_val_uInt (tarval *tv)
139 tv_val_P (tarval *tv)
145 tv_val_b (tarval *tv)
151 /* Overflows `sInt' signed integral `mode'? */
153 sInt_overflow (tarval_sInt sInt, ir_mode *mode)
155 assert (is_Int(get_mode_modecode(mode)));
156 return (get_mode_min(mode) && get_mode_max(mode) /* only valid after firm initialization */
157 && (sInt < tv_val_sInt (get_mode_min(mode))
158 || tv_val_sInt (get_mode_max(mode)) < sInt));
162 /* Overflows `uInt' unsigned integral `mode'? */
164 uInt_overflow (tarval_uInt uInt, ir_mode *mode)
166 assert (is_Int(get_mode_modecode(mode)));
167 return (get_mode_max(mode) /* only valid after firm initialization */
168 && tv_val_uInt (get_mode_max(mode)) < uInt);
174 _tarval_vrfy (const tarval *val)
177 switch (get_mode_modecode(val->mode)) {
184 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: {
185 // printf("Tarval is %lu\n", val->u.uInt);
186 assert (!uInt_overflow (val->u.uInt, val->mode));
188 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
189 assert (!sInt_overflow (val->u.sInt, val->mode)); break;
195 assert (val->u.P.ent->kind == k_entity);
197 assert ( val->u.P.xname || val->u.P.ent
198 || !tarval_P_void || (val == tarval_P_void));
201 assert ((unsigned)val->u.b <= 1); break;
203 assert (val->mode == mode_T);
215 pset_stats (tarvals);
221 /* Return the canonical tarval * for tv.
222 May destroy everything allocated on tv_obst after tv! */
224 tarval_identify (tarval *tv)
228 o = pset_insert (tarvals, tv, tarval_hash (tv));
231 obstack_free (&tv_obst, (void *)tv);
239 /* Return 0 iff a equals b. Bitwise identical NaNs compare equal. */
241 tarval_cmp (const void *p, const void *q)
249 if (a == b) return 0;
250 if ((char *)a->mode - (char *)b->mode)
251 return (char *)a->mode - (char *)b->mode;
253 switch (get_mode_modecode(a->mode)) {
256 return memcmp (&a->u.F, &b->u.F, sizeof (a->u.F));
258 return memcmp (&a->u.D, &b->u.D, sizeof (a->u.D));
260 return memcmp (&a->u.E, &b->u.E, sizeof (a->u.E));
262 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
263 if (sizeof (int) == sizeof (tarval_uInt)) {
264 return a->u.uInt - b->u.uInt;
266 return a->u.uInt != b->u.uInt;
268 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
269 if (sizeof (int) == sizeof (tarval_sInt)) {
270 return a->u.sInt - b->u.sInt;
272 return a->u.sInt != b->u.sInt;
274 return a->u.C - b->u.C;
276 return a->u.U - b->u.U;
278 if (a->u.P.ent || b->u.P.ent)
279 return (char *)a->u.P.ent - (char *)b->u.P.ent;
280 if (a->u.P.xname && b->u.P.xname)
281 return strcmp (a->u.P.xname, b->u.P.xname);
282 return a->u.P.xname - b->u.P.xname;
284 return a->u.b - b->u.b;
291 tarval_hash (tarval *tv)
295 h = get_mode_modecode(tv->mode) * 0x421u;
296 switch (get_mode_modecode(tv->mode)) {
298 h = 0x94b527ce; break;
301 { union { float f; unsigned u; } u;
302 assert (sizeof (float) <= sizeof (unsigned));
303 u.u = 0; u.f = tv->u.F;
309 { union { double d; unsigned u[2]; } u;
310 assert (sizeof (double) <= 2*sizeof (unsigned));
311 u.u[0] = u.u[1] = 0; u.d = tv->u.D;
312 h ^= u.u[0] ^ u.u[1];
316 { union { long double e; unsigned u[3]; } u;
317 assert (sizeof (long double) <= 3*sizeof (unsigned));
318 u.u[0] = u.u[1] = u.u[2] = 0; u.e = tv->u.E;
319 h ^= u.u[0] ^ u.u[1] ^ u.u[2];
322 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
323 h ^= tv->u.uInt; break;
324 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
325 h ^= tv->u.sInt; break;
332 /* @@@ lower bits not random, watch for collisions; perhaps
333 replace by tv->u.p.ent - (entity *)0 */
334 h ^= ((char *)tv->u.P.ent - (char *)0) / 64;
335 } else if (tv->u.P.xname) {
336 /* Of course, strlen() in a hash function is a mistake, but this
337 case should be really rare. */
338 h ^= ID_HASH (tv->u.P.xname, strlen (tv->u.P.xname));
352 /*** ***************** Initialization ************************************* ***/
357 obstack_init (&tv_obst);
358 obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
359 assert (IS_POW2 (ALIGNOF (tarval)));
361 /* initialize the target value table */
362 tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
369 union ieee754_double x;
371 /* assumed by tarval_hash(): */
372 assert (sizeof (float) * CHAR_BIT == 32);
373 assert (sizeof (double) * CHAR_BIT == 64);
376 /* assumed by tarval_sInt & friends: */
377 assert ( (irm_C == irm_c+1) && (irm_h == irm_C+1)
378 && (irm_H == irm_h+1) && (irm_i == irm_H+1)
379 && (irm_I == irm_i+1) && (irm_l == irm_I+1)
380 && (irm_L == irm_l+1));
382 /* assumed everywhere: */
383 for (i = 0; i <= irm_L-irm_c; i += 2) {
384 assert ( IS_POW2 (max_sInt[i+1]+1)
385 && (min_sInt[i] == -max_sInt[i]-1)
386 && ((tarval_uInt)max_sInt[i+1] == (tarval_uInt)max_sInt[i]-min_sInt[i]));
391 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
393 tarval_bad = tarval_identify (tv);
395 tarval_b_false = tarval_from_long (mode_b, 0);
396 tarval_b_true = tarval_from_long (mode_b, 1);
398 /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
399 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
402 x.ieee.exponent = 0x7ff;
403 x.ieee.mantissa0 = 0;
404 x.ieee.mantissa1 = 0;
406 tarval_D_Inf = tarval_identify (tv);
408 /* IsNaN <-> exponent==0x7ff && (qnan_bit | bits | fraction_low) */
409 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
411 x.ieee_nan.negative = 0;
412 x.ieee_nan.exponent = 0x7ff;
413 x.ieee_nan.quiet_nan = 1; /* @@@ quiet or signalling? */
414 x.ieee_nan.mantissa0 = 42;
415 x.ieee_nan.mantissa1 = 0;
416 assert(x.d != x.d /* x.d is NaN */);
418 tarval_D_NaN = tarval_identify (tv);
420 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
422 tv->u.P.xname = NULL;
425 tarval_P_void = tarval_identify (tv);
427 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
430 tarval_mode_null [irm_F] = tarval_from_long (mode_F, 0);
431 tarval_mode_null [irm_D] = tarval_from_long (mode_D, 0);
432 tarval_mode_null [irm_E] = tarval_from_long (mode_E, 0);
433 tarval_mode_null [irm_Bs] = tarval_from_long (mode_Bs, 0);
434 tarval_mode_null [irm_Bu] = tarval_from_long (mode_Bu, 0);
435 tarval_mode_null [irm_Hs] = tarval_from_long (mode_Hs, 0);
436 tarval_mode_null [irm_Hu] = tarval_from_long (mode_Hu, 0);
437 tarval_mode_null [irm_Is] = tarval_from_long (mode_Is, 0);
438 tarval_mode_null [irm_Iu] = tarval_from_long (mode_Iu, 0);
439 tarval_mode_null [irm_Ls] = tarval_from_long (mode_Ls, 0);
440 tarval_mode_null [irm_Lu] = tarval_from_long (mode_Lu, 0);
441 tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
442 tarval_mode_null [irm_U] = tarval_from_long (mode_U, 0);
443 tarval_mode_null [irm_b] = tarval_b_false;
444 tarval_mode_null [irm_P] = tarval_P_void;
448 /*** ********************** Constructors for tarvals ********************** ***/
450 /* copy from src to dst len chars omitting '_'. */
452 stripcpy (char *dst, const char *src, size_t len)
457 if (*src == '_') src++;
460 *d = 0; /* make it 0-terminated. */
466 tarval_F_from_str (const char *s, size_t len)
474 buf = alloca (len+1);
475 stripcpy (buf, s, len);
477 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
479 tv->u.F = (float)strtod (buf, &eptr);
480 assert (eptr == buf+strlen(buf));
482 return tarval_identify (tv);
487 tarval_D_from_str (const char *s, size_t len)
495 buf = alloca (len+1);
496 stripcpy (buf, s, len);
498 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
500 tv->u.D = strtod (buf, &eptr);
501 assert (eptr == buf+strlen(buf));
503 return tarval_identify (tv);
507 tarval_int_from_str (const char *s, size_t len, int base, ir_mode *m)
513 assert (mode_is_int(m));
516 buf = alloca (len+1);
517 stripcpy (buf, s, len);
520 val = strtol(buf, &eptr, base); /* strtoll */
521 assert (eptr == buf+strlen(buf));
522 if ((errno == ERANGE) &&
523 ((m == mode_Ls) || (m == mode_Lu)) ) {
524 printf("WARNING: Constant %s not representable. Continuing with %ld.\n",
528 return tarval_from_long(m, val);
531 /* Create a tarval with mode `m' and value `val' casted to the type that
532 represents such tarvals on host. The resulting value must be legal
535 tarval_from_long (ir_mode *m, long val)
541 if (m == mode_T) return tarval_bad;
543 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
546 switch (get_mode_modecode(m)) {
549 tv->u.F = val; break;
551 tv->u.D = val; break;
553 /* @@@ not yet implemented */
556 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
557 tv->u.uInt = val; break;
559 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
560 tv->u.sInt = val; break;
563 obstack_free (&tv_obst, tv);
564 return tarval_P_void;
566 tv->u.C = val; break;
568 tv->u.U = val; break;
570 tv->u.b = !!val; /* u.b must be 0 or 1 */
576 return tarval_identify (tv);
581 tarval_P_from_str (const char *xname)
587 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
590 tv->u.P.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
593 return tarval_identify (tv);
598 tarval_P_from_entity (entity *ent)
603 //assert(ent && "no entity given");
605 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
608 tv->u.P.xname = NULL;
611 return tarval_identify (tv);
615 /* Routines for building a tarval step by step follow.
616 Legal calling sequences:
618 No constructors except tarval_append() and tarval_append1 ()
619 tarval_finish_as() or tarval_cancel() */
621 /* Begin building a tarval. */
626 obstack_blank (&tv_obst, sizeof (tarval));
630 /* Append `n' chars from `p' to the tarval currently under construction. */
632 tarval_append (const char *p, size_t n)
635 obstack_grow (&tv_obst, p, n);
639 /* Append `ch' to the tarval currently under construction. */
641 tarval_append1 (char ch)
644 obstack_1grow (&tv_obst, ch);
648 /* Finish the tarval currently under construction and give id mode `m'.
650 Return NULL if the value does not make sense for this mode, this
651 can only happen in mode C. */
653 tarval_finish_as (ir_mode *m)
655 int size = obstack_object_size (&tv_obst) - sizeof (tarval);
658 char ch = 0; /* initialized to shut up gcc */
660 assert (BUILDING && (size >= 0));
662 if (size != 1) return tarval_cancel();
663 p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
665 obstack_blank (&tv_obst, -size);
667 tv = obstack_finish (&tv_obst);
668 p = (unsigned char *)tv + sizeof (tarval);
671 switch (get_mode_modecode(m)) {
682 return tarval_identify (tv);
686 /* Cancel tarval building and return tarval_bad. */
691 obstack_free (&tv_obst, obstack_finish (&tv_obst));
696 /*** ****************** Arithmethic operations on tarvals ***************** ***/
698 /* Return `src' converted to mode `m' if representable, else NULL.
699 @@@ lots of conversions missing */
701 tarval_convert_to (tarval *src, ir_mode *m)
705 if (m == src->mode) return src;
707 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
710 switch (get_mode_modecode(src->mode)) {
713 if (m != mode_F) goto fail;
717 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
718 switch (get_mode_modecode(m)) {
719 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
720 tv->u.sInt = src->u.sInt;
721 if (sInt_overflow (tv->u.sInt, m)) goto fail;
724 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
725 tv->u.uInt = src->u.sInt;
726 if (uInt_overflow (tv->u.uInt, m)) goto fail;
730 tv->u.b = !!src->u.sInt;
736 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
737 switch (get_mode_modecode(m)) {
738 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
739 tv->u.sInt = src->u.uInt;
740 if (sInt_overflow (tv->u.sInt, m)) goto fail;
743 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
744 tv->u.uInt = src->u.uInt;
745 if (uInt_overflow (tv->u.uInt, m)) goto fail;
749 tv->u.b = !!src->u.uInt;
757 switch (get_mode_modecode(m)) {
758 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
759 tv->u.sInt = src->u.b;
762 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
763 tv->u.uInt = src->u.b;
771 obstack_free (&tv_obst, tv);
775 return tarval_identify (tv);
779 /* GL Why are there no ArmRoq comments, why is this not used? */
781 tarval_neg (tarval *a)
787 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
791 switch (get_mode_modecode(a->mode)) {
793 case irm_F: tv->u.F = -a->u.F; break;
794 case irm_D: tv->u.D = -a->u.D; break;
796 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
797 tv->u.uInt = -a->u.uInt & tv_val_uInt (get_mode_max(a->mode));
800 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
801 tv->u.sInt = -a->u.sInt;
802 if ( sInt_overflow (tv->u.sInt, a->mode)
803 || ((tv->u.sInt >= 0) == (a->u.sInt >= 0))) {
804 obstack_free (&tv_obst, tv);
808 case irm_b: tv->u.b = !a->u.b; break;
812 return tarval_identify (tv);
816 /* Compare `a' with `b'.
817 Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
818 result is unknown. */
820 tarval_comp (tarval *a, tarval *b)
826 assert (a->mode == b->mode);
828 switch (get_mode_modecode(a->mode)) {
830 case irm_F: return ( a->u.F == b->u.F ? irpn_Eq
831 : a->u.F > b->u.F ? irpn_Gt
832 : a->u.F < b->u.F ? irpn_Lt
834 case irm_D: return ( a->u.D == b->u.D ? irpn_Eq
835 : a->u.D > b->u.D ? irpn_Gt
836 : a->u.D < b->u.D ? irpn_Lt
838 case irm_E: return ( a->u.E == b-> u.E ? irpn_Eq
839 : a->u.E > b->u.E ? irpn_Gt
840 : a->u.E < b->u.E ? irpn_Lt
843 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
844 return ( a->u.uInt == b->u.uInt ? irpn_Eq
845 : a->u.uInt > b->u.uInt ? irpn_Gt
848 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
849 return ( a->u.sInt == b->u.sInt ? irpn_Eq
850 : a->u.sInt > b->u.sInt ? irpn_Gt
852 case irm_b: return ( a->u.b == b->u.b ? irpn_Eq
853 : a->u.b > b->u.b ? irpn_Gt
855 /* The following assumes that pointers are unsigned, which is valid
856 for all sane CPUs (transputers are insane). */
857 case irm_P: return ( a == b ? irpn_Eq
858 : a == tarval_P_void ? irpn_Lt
859 : b == tarval_P_void ? irpn_Gt
860 : irpn_False); /* unknown */
866 /* Return `a+b' if computable, else NULL. Modes must be equal. */
868 tarval_add (tarval *a, tarval *b)
872 TARVAL_VRFY (a); TARVAL_VRFY (b);
873 assert (a->mode == b->mode);
875 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
879 switch (get_mode_modecode(a->mode)) {
881 case irm_F: tv->u.F = a->u.F + b->u.F; break; /* @@@ overflow etc */
882 case irm_D: tv->u.D = a->u.D + b->u.D; break; /* @@@ dto. */
883 case irm_E: tv->u.E = a->u.E + b->u.E; break; /* @@@ dto. */
885 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
886 tv->u.uInt = (a->u.uInt + b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
889 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
890 tv->u.sInt = a->u.sInt + b->u.sInt;
891 if ( sInt_overflow (tv->u.sInt, a->mode)
892 || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt > 0))) {
893 obstack_free (&tv_obst, tv);
897 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
901 return tarval_identify (tv);
905 /* Return `a-b' if computable, else NULL. Modes must be equal. */
907 tarval_sub (tarval *a, tarval *b)
911 TARVAL_VRFY (a); TARVAL_VRFY (b);
912 assert (a->mode == b->mode);
914 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
918 switch (get_mode_modecode(a->mode)) {
920 case irm_F: tv->u.F = a->u.F - b->u.F; break; /* @@@ overflow etc */
921 case irm_D: tv->u.D = a->u.D - b->u.D; break; /* @@@ dto. */
922 case irm_E: tv->u.E = a->u.E - b->u.E; break; /* @@@ dto. */
924 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
925 tv->u.uInt = (a->u.uInt - b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
928 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
929 tv->u.sInt = a->u.sInt - b->u.sInt;
930 if ( sInt_overflow (tv->u.sInt, a->mode)
931 || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt < 0))) {
932 obstack_free (&tv_obst, tv);
936 case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
940 return tarval_identify (tv);
943 /* Return `a*b' if computable, else NULL. Modes must be equal. */
945 tarval_mul (tarval *a, tarval *b)
949 TARVAL_VRFY (a); TARVAL_VRFY (b);
950 assert (a->mode == b->mode);
952 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
956 switch (get_mode_modecode(a->mode)) {
958 case irm_F: tv->u.F = a->u.F * b->u.F; break; /* @@@ overflow etc */
959 case irm_D: tv->u.D = a->u.D * b->u.D; break; /* @@@ dto. */
960 case irm_E: tv->u.E = a->u.E * b->u.E; break; /* @@@ dto. */
962 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
963 tv->u.uInt = (a->u.uInt * b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
966 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
967 tv->u.sInt = a->u.sInt * b->u.sInt;
968 if ( sInt_overflow (tv->u.sInt, a->mode)
969 || (b->u.sInt && (tv->u.sInt / b->u.sInt != a->u.sInt))) {
970 obstack_free (&tv_obst, tv);
974 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
978 return tarval_identify (tv);
982 /* Return floating-point `a/b' if computable, else NULL.
983 Modes must be equal, non-floating-point operands are converted to irm_D. */
985 tarval_quo (tarval *a, tarval *b)
989 TARVAL_VRFY (a); TARVAL_VRFY (b);
990 assert (a->mode == b->mode);
992 switch (get_mode_modecode(a->mode)) {
995 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
997 tv->u.F = a->u.F / b->u.F; /* @@@ overflow etc */
1000 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1002 tv->u.D = a->u.D / b->u.D; /* @@@ overflow etc */
1005 a = tarval_convert_to (a, mode_D);
1006 b = tarval_convert_to (b, mode_D);
1007 return a && b ? tarval_quo (a, b) : NULL;
1010 return tarval_identify (tv);
1014 /* Return `a/b' if computable, else NULL. Modes must be equal. */
1016 tarval_div (tarval *a, tarval *b)
1020 TARVAL_VRFY (a); TARVAL_VRFY (b);
1021 assert (a->mode == b->mode);
1023 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1027 switch (get_mode_modecode(a->mode)) {
1029 case irm_F: tv->u.F = floor (a->u.F / b->u.F); break; /* @@@ overflow etc */
1030 case irm_D: tv->u.D = floor (a->u.D / b->u.D); break; /* @@@ dto. */
1031 case irm_E: tv->u.E = floor (a->u.E / b->u.E); break; /* @@@ dto. */
1033 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1034 if (!b->u.uInt) goto fail;
1035 tv->u.uInt = a->u.uInt / b->u.uInt;
1038 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1040 || ((b->u.sInt == -1) && (a->u.sInt == tv_val_sInt (get_mode_max(a->mode)) ))) {
1042 obstack_free (&tv_obst, tv);
1045 tv->u.sInt = a->u.sInt / b->u.sInt;
1047 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1051 return tarval_identify (tv);
1055 /* Return `a%b' if computable, else NULL. Modes must be equal. */
1057 tarval_mod (tarval *a, tarval *b)
1061 TARVAL_VRFY (a); TARVAL_VRFY (b);
1062 assert (a->mode == b->mode);
1064 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1068 switch (get_mode_modecode(a->mode)) {
1070 case irm_F: tv->u.F = fmod (a->u.F, b->u.F); break; /* @@@ overflow etc */
1071 case irm_D: tv->u.D = fmod (a->u.D, b->u.D); break; /* @@@ dto */
1072 case irm_E: tv->u.E = fmod (a->u.E, b->u.E); break; /* @@@ dto. */
1074 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1075 if (!b->u.uInt) goto fail;
1076 tv->u.uInt = a->u.uInt % b->u.uInt;
1079 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1082 obstack_free (&tv_obst, tv);
1085 tv->u.sInt = a->u.sInt % b->u.sInt;
1087 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1091 return tarval_identify (tv);
1094 /* Return |a| if computable, else Null. */
1095 /* is -max == min?? */
1097 tarval_abs (tarval *a) {
1099 if (tv_is_negative(a)) return tarval_neg(a);
1104 tv_is_negative(tarval *a) {
1106 switch (get_mode_modecode(a->mode)) {
1108 case irm_F: return (a->u.F<0);
1109 case irm_D: return (a->u.D<0);
1110 case irm_E: return (a->u.E<0);
1112 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1116 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1117 return (a->u.sInt < 0);
1127 /* Return `a&b'. Modes must be equal. */
1129 tarval_and (tarval *a, tarval *b)
1133 TARVAL_VRFY (a); TARVAL_VRFY (b);
1134 assert (a->mode == b->mode);
1136 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1140 switch (get_mode_modecode(a->mode)) {
1142 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1143 tv->u.uInt = a->u.uInt & b->u.uInt; break;
1145 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1146 tv->u.sInt = a->u.sInt & b->u.sInt; break;
1147 case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1151 return tarval_identify (tv);
1155 /* Return `a|b'. Modes must be equal. */
1157 tarval_or (tarval *a, tarval *b)
1161 TARVAL_VRFY (a); TARVAL_VRFY (b);
1162 assert (a->mode == b->mode);
1164 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1168 switch (get_mode_modecode(a->mode)) {
1170 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1171 tv->u.uInt = a->u.uInt | b->u.uInt; break;
1173 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1174 tv->u.sInt = a->u.sInt | b->u.sInt; break;
1175 case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1179 return tarval_identify (tv);
1183 /* Return `a^b'. Modes must be equal. */
1185 tarval_eor (tarval *a, tarval *b)
1189 TARVAL_VRFY (a); TARVAL_VRFY (b);
1190 assert (a->mode == b->mode);
1192 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1196 switch (get_mode_modecode(a->mode)) {
1198 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1199 tv->u.uInt = a->u.uInt ^ b->u.uInt; break;
1201 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1202 tv->u.sInt = a->u.sInt ^ b->u.sInt; break;
1203 case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1207 return tarval_identify (tv);
1211 /* Return `a<<b' if computable, else NULL. */
1213 tarval_shl (tarval *a, tarval *b)
1219 TARVAL_VRFY (a); TARVAL_VRFY (b);
1221 shift = tarval_ord (b, &b_is_huge);
1224 || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
1228 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1231 switch (get_mode_modecode(a->mode)) {
1233 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1234 tv->u.uInt = a->u.uInt << shift;
1237 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1238 tv->u.sInt = a->u.sInt << shift;
1240 default: assert (0);
1243 return tarval_identify (tv);
1247 /* Return `a>>b' if computable, else NULL.
1248 The interpretation of >> (sign extended or not) is implementaion
1249 dependent, i.e. this is neither shr nor shrs!! */
1251 tarval_shr (tarval *a, tarval *b)
1257 TARVAL_VRFY (a); TARVAL_VRFY (b);
1259 shift = tarval_ord (b, &b_is_huge);
1262 || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
1266 tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1269 switch (get_mode_modecode(a->mode)) {
1271 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1272 tv->u.uInt = a->u.uInt >> shift;
1275 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1276 tv->u.sInt = a->u.sInt >> shift;
1278 default: assert (0);
1281 return tarval_identify (tv);
1285 /* Classify `tv', which may be NULL.
1286 Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1287 multiplicative neutral element, and -1 if `tv' is the neutral
1288 element of bitwise and. */
1290 tarval_classify (tarval *tv)
1296 switch (get_mode_modecode(tv->mode)) {
1298 case irm_F: case irm_D: case irm_E:
1302 return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Bu))) - 1;
1304 return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Hu))) - 1;
1306 return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Iu))) - 1;
1308 return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Lu))) - 1;
1310 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1319 /* Convert `tv' into type `long', set `fail' if not representable.
1320 If `fail' gets set for an unsigned `tv', the correct result can be
1321 obtained by casting the result to `unsigned long'. */
1323 tarval_ord (tarval *tv, int *fail)
1327 switch (get_mode_modecode(tv->mode)) {
1329 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1330 *fail = tv->u.uInt > tv_val_uInt (get_mode_max(mode_Ls));
1333 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1346 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1348 tarval *val = XP_GETARG (tarval *, 0);
1354 switch (get_mode_modecode(val->mode)) {
1356 case irm_T: /* none */
1357 printed = XPSR ("<bad>");
1360 case irm_F: /* float */
1361 sprintf (buf, "%1.9e", (float)(val->u.F));
1362 printed = XPF1R ("%s", buf);
1364 case irm_D: /* double */
1365 printed = XPF1R ("%1.30g", (double)(val->u.D));
1368 case irm_C: /* character */
1369 if ((isprint (val->u.C)) &&
1370 (val->u.C != '\\') && (val->u.C != '\'')) {
1371 printed = XPF1R ("'%c'", val->u.C);
1373 printed = XPF1R ("0x%x", (unsigned long)val->u.C);
1376 case irm_U: /* unicode character */
1377 printed = XPF1R ("0x%x", (unsigned long)val->u.U);
1380 case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls: /* signed num */
1381 printed = XPF1R ("%ld", (long)val->u.sInt);
1383 case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: /* unsigned num */
1384 printed = XPF1R ("%lu", (unsigned long)val->u.uInt);
1387 case irm_P: /* pointer */
1388 if (val->u.P.xname) {
1389 printed = XPR (val->u.P.xname);
1390 } else if (val->u.P.ent) {
1391 if (get_entity_peculiarity(val->u.P.ent) == existent)
1392 printed = XPF1R ("&(%I)", get_entity_ld_ident(val->u.P.ent));
1394 printed = XPSR ("(NULL)");
1396 assert (val == tarval_P_void);
1397 printed = XPSR ("(NULL)");
1401 case irm_b: /* boolean */
1402 if (val->u.b) printed = XPSR ("true");
1403 else printed = XPSR ("false");
1406 case irm_M: /* memory */
1407 case irm_BB: /* region */
1417 get_tv_mode (tarval *tv)
1422 /* Returns the entity if the tv is a pointer to an entity, else
1424 entity *get_tv_entity(tarval *tv) {
1427 if (tv->mode == mode_P) {
1428 if (tv->u.P.xname) {
1431 } else if (tv->u.P.ent) {
1442 free_tv_entity(entity *ent) {
1443 /* There can be a tarval referencing this entity. Even if the
1444 tarval is not used by the code any more, it can still reference
1445 the entity as tarvals live forever (They live on an obstack.).
1446 Further the tarval is hashed into a set. If a hash function
1447 evaluation happens to collide with this tarval, we will vrfy that
1448 it contains a proper entity and we will crash if the entity is
1449 freed. We cannot remove tarvals from the obstack but we can
1450 remove the entry in the hash table. */
1451 tarval *found = NULL;
1452 tarval *tv = (tarval *)pset_first(tarvals);
1454 entity *tv_ent = get_tv_entity(tv);
1455 if ((tv_ent) && (tv_ent == ent)) found = tv;
1456 tv = pset_next(tarvals);
1459 pset_remove(tarvals, found, tarval_hash(found));