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.
1444 Even if the tarval is not used by the code any more,
1445 it can still reference an entity. If a hash function
1446 happens to collide with this tarval, we will verify that
1447 it contains a proper entity and we will crash.
1448 As we cannot remove tarvals (they are on an obstack) we
1449 overwrite ent with NULL. */
1450 /* Get the tarval by allocating a new one. */
1451 tarval *tv = (tarval *)pset_first(tarvals);
1452 tarval *found = NULL;
1454 entity *tv_ent = get_tv_entity(tv);
1455 if ((tv_ent) && (tv_ent == ent)) {
1457 //pset_remove(tarvals, tv, tarval_hash(tv));
1458 //tv->u.P.ent = NULL;
1461 tv = pset_next(tarvals);
1464 // pset_break(tarvals);
1466 pset_remove(tarvals, found, tarval_hash(found));