added debug support constructors
[libfirm] / ir / tv / tv.c
1 /* TV --- Target Values, aka Constant Table.
2    Copyright (C) 1995, 1996 Christian von Roques */
3
4 /* $Id$ */
5
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.  */
15
16 /* !!! float and double divides MUST NOT SIGNAL !!! */
17 /* @@@ query the floating-point expception status flags */
18
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
26    discarded ones.  */
27
28 /* Defining this causes inclusions of functions renamed with new gmp.h */
29 #define _TARVAL_GMP_ 0
30
31 #ifdef HAVE_CONFIG_H
32 # include <config.h>
33 #endif
34
35 # include "xprintf.h"
36 #include <assert.h>
37 #include <limits.h>
38 #include <errno.h>
39 #include <math.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <ctype.h>
43
44 #include "pset.h"
45 #define TOBSTACK_ID "tv"
46 #include "obst.h"
47 #include "ieee754.h"
48 #include "tune.h"
49 #include "ident_t.h"
50 #include "tv_t.h"
51 #include "entity_t.h"
52 #include "irmode.h"
53
54 static struct obstack tv_obst;  /* obstack for all the target values */
55 static pset *tarvals;           /* pset containing pointers to _all_ tarvals */
56
57 /* currently building an object with tarval_start() & friends ? */
58 #define BUILDING obstack_object_size (&tv_obst)
59
60 /* bcopy is not ISO C */
61 #define bcopy(X, Y, Z) memcpy((Y), (X), (Z))
62
63
64 /* special tarvals: */
65 tarval *tarval_bad;
66 tarval *tarval_b_false;
67 tarval *tarval_b_true;
68 tarval *tarval_d_NaN;
69 tarval *tarval_d_Inf;
70 tarval *tarval_p_void;
71 tarval *tarval_mode_null[irm_max];
72
73 # if 0
74 /* @@@ depends on order of ir_mode */
75 static tarval_chil min_chil[8] = {
76   TARGET_SIMIN (c), 0,
77   TARGET_SIMIN (h), 0,
78   TARGET_SIMIN (i), 0,
79   TARGET_SIMIN (l), 0
80 };
81 static tarval_chil max_chil[8] = {
82   TARGET_SIMAX (c), TARGET_UIMAX (C),
83   TARGET_SIMAX (h), TARGET_UIMAX (H),
84   TARGET_SIMAX (i), TARGET_UIMAX (I),
85   TARGET_SIMAX (l), TARGET_UIMAX (L)
86 };
87 # endif
88
89 /* Used to be in irmode.h, replaced now. */
90 # define is_chilCHIL(m) ((m) <= irm_L && (m) >= irm_c) /* old */
91
92 /* return a mode-specific value */
93
94 tarval_f
95 tv_val_f (tarval *tv)
96 {
97   return tv->u.f;
98 }
99
100 tarval_d
101 tv_val_d (tarval *tv)
102 {
103   return tv->u.d;
104 }
105
106 tarval_chil
107 tv_val_chil (tarval *tv)
108 {
109   return tv->u.chil;
110 }
111
112 tarval_CHIL
113 tv_val_CHIL (tarval *tv)
114 {
115   return tv->u.CHIL;
116 }
117
118 tarval_Z
119 tv_val_Z (tarval *tv)
120 {
121   return tv->u.Z;
122 }
123
124 tarval_p
125 tv_val_p (tarval *tv)
126 {
127   return tv->u.p;
128 }
129
130 bool
131 tv_val_b (tarval *tv)
132 {
133   return tv->u.b;
134 }
135
136 tarval_B
137 tv_val_B (tarval *tv)
138 {
139   return tv->u.B;
140 }
141
142 tarval_s
143 tv_val_s (tarval *tv)
144 {
145   return tv->u.s;
146 }
147
148
149 /* Overflows `chil' signed integral `mode'?  */
150 static INLINE bool
151 chil_overflow (tarval_chil chil, ir_mode *mode)
152 {
153   assert (is_chilCHIL(get_mode_modecode(mode)));
154   return (get_mode_min(mode) && get_mode_max(mode)  /* only valid after firm initialization */
155           && (chil < tv_val_chil (get_mode_min(mode))
156               || tv_val_chil (get_mode_max(mode)) < chil));
157 }
158
159
160 /* Overflows `CHIL' unsigned integral `mode'?  */
161 static INLINE bool
162 CHIL_overflow (tarval_CHIL CHIL, ir_mode *mode)
163 {
164   assert (is_chilCHIL(get_mode_modecode(mode)));
165   return (get_mode_max(mode)   /* only valid after firm initialization */
166           && tv_val_CHIL (get_mode_max(mode)) < CHIL);
167 }
168
169
170 #ifndef NDEBUG
171 void
172 _tarval_vrfy (const tarval *val)
173 {
174   assert (val);
175   switch (get_mode_modecode(val->mode)) {
176     /* floating */
177   case irm_f:
178   case irm_d:
179     break;
180     /* integral */
181   case irm_C: case irm_H: case irm_I: case irm_L:
182     assert (!CHIL_overflow (val->u.CHIL, val->mode)); break;
183   case irm_c: case irm_h: case irm_i: case irm_l:
184     assert (!chil_overflow (val->u.chil, val->mode)); break;
185   case irm_Z:
186     break;
187     /* strange */
188   case irm_p:
189     if (val->u.p.ent)
190       assert (val->u.p.ent->kind == k_entity);
191     assert (   val->u.p.xname || val->u.p.ent
192             || !tarval_p_void || (val == tarval_p_void));
193     break;
194   case irm_s:
195   case irm_S:
196     assert (val->u.s.p); break;
197   case irm_B:
198     assert (val->u.B.p); break;
199   case irm_b:
200     assert ((unsigned)val->u.b <= 1); break;
201   default:
202     assert (val->mode == mode_T);
203   }
204 }
205 #endif
206
207
208 #ifdef STATS
209
210 void
211 tarval_stats (void)
212 {
213   pset_stats (tarvals);
214 }
215
216 #endif
217
218
219 /* Return the canonical tarval * for tv.
220    May destroy everything allocated on tv_obst after tv!  */
221 static tarval *
222 tarval_identify (tarval *tv)
223 {
224   tarval *o;
225
226   o = pset_insert (tarvals, tv, tarval_hash (tv));
227
228   if (o != tv) {
229     obstack_free (&tv_obst, (void *)tv);
230   }
231
232   TARVAL_VRFY (o);
233   return o;
234 }
235
236
237 /* Return 0 iff a equals b.  Bitwise identical NaNs compare equal.  */
238 static int
239 tarval_cmp (const void *p, const void *q)
240 {
241   const tarval *a = p;
242   const tarval *b = q;
243
244   TARVAL_VRFY (a);
245   TARVAL_VRFY (b);
246
247   if (a == b) return 0;
248   if ((void *)a->mode - (void *)b->mode)
249     return (void *)a->mode - (void *)b->mode;
250
251   switch (get_mode_modecode(a->mode)) {
252     /* floating */
253   case irm_f:
254     return memcmp (&a->u.f, &b->u.f, sizeof (a->u.f));
255   case irm_d:
256     return memcmp (&a->u.d, &b->u.d, sizeof (a->u.d));
257     /* unsigned */
258   case irm_C: case irm_H: case irm_I: case irm_L:
259     if (sizeof (int) == sizeof (tarval_CHIL)) {
260       return a->u.CHIL - b->u.CHIL;
261     }
262     return a->u.CHIL != b->u.CHIL;
263     /* signed */
264   case irm_c: case irm_h: case irm_i: case irm_l:
265     if (sizeof (int) == sizeof (tarval_chil)) {
266       return a->u.chil - b->u.chil;
267     }
268     return a->u.chil != b->u.chil;
269   case irm_Z:
270 #if _TARVAL_GMP_
271     return mpz_cmp (&a->u.Z, &b->u.Z);
272 #else
273     return 99; /* ?? */
274 #endif
275     /* strange */
276   case irm_p:
277     if (a->u.p.ent || b->u.p.ent)
278       return (char *)a->u.p.ent - (char *)b->u.p.ent;
279     if (a->u.p.xname && b->u.p.xname)
280       return strcmp (a->u.p.xname, b->u.p.xname);
281     return a->u.p.xname - b->u.p.xname;
282   case irm_b:
283     return a->u.b - b->u.b;
284   case irm_B:
285     return (  a->u.B.n - b->u.B.n
286             ? memcmp (a->u.B.p, b->u.B.p, a->u.B.n)
287             : a->u.B.n - b->u.B.n);
288   case irm_s: case irm_S:
289     return (  a->u.s.n == b->u.s.n
290             ? memcmp (a->u.s.p, b->u.s.p, a->u.s.n)
291             : a->u.s.n - b->u.s.n);
292   default: assert (0);
293   }
294 }
295
296
297 unsigned
298 tarval_hash (tarval *tv)
299 {
300   unsigned h;
301
302   h = get_mode_modecode(tv->mode) * 0x421u;
303   switch (get_mode_modecode(tv->mode)) {
304   case irm_T:
305     h = 0x94b527ce; break;
306   case irm_f:
307     /* quick & dirty */
308     { union { float f; unsigned u; } u;
309       assert (sizeof (float) <= sizeof (unsigned));
310       u.u = 0; u.f = tv->u.f;
311       h ^= u.u;
312       break;
313     }
314   case irm_d:
315     /* quick & dirty */
316     { union { double d; unsigned u[2]; } u;
317       assert (sizeof (double) <= 2*sizeof (unsigned));
318       u.u[0] = u.u[1] = 0; u.d = tv->u.d;
319       h ^= u.u[0] ^ u.u[1];
320       break;
321     }
322   case irm_C: case irm_H: case irm_I: case irm_L:
323     h ^= tv->u.CHIL; break;
324   case irm_c: case irm_h: case irm_i: case irm_l:
325     h ^= tv->u.chil; break;
326   case irm_Z:
327 #if _TARVAL_GMP_
328     h ^= mpz_get_ui (&tv->u.Z); break;
329 #else
330     h ^= (unsigned int) tv; break; /* tut das? */
331 #endif
332   case irm_p:
333     if (tv->u.p.ent) {
334       /* @@@ lower bits not random, watch for collisions; perhaps
335          replace by tv->u.p.ent - (entity *)0 */
336       h ^= ((char *)tv->u.p.ent - (char *)0) / 64;
337     } else if (tv->u.p.xname) {
338       /* Of course, strlen() in a hash function is a mistake, but this
339          case should be really rare.  */
340       h ^= ID_HASH (tv->u.p.xname, strlen (tv->u.p.xname));
341     } else {                    /* void */
342       h^= 0x2b592b88;
343     }
344     break;
345   case irm_b:
346     h ^= tv->u.b; break;
347   case irm_B:
348     h ^= tv->u.B.n; break; /* @@@ not really good */
349   case irm_s:
350     h ^= tv->u.s.p[0]<<12 ^ tv->u.s.p[tv->u.s.n]<<4 ^ tv->u.s.n; break;
351   case irm_S:
352     h ^= tv->u.s.p[0]<<4 ^ tv->u.s.p[tv->u.s.n]<<12 ^ tv->u.s.n; break;
353   default:
354     assert(0);
355   }
356   return h;
357 }
358
359
360 \f
361 /*** ***************** Initialization ************************************* ***/
362
363 void
364 tarval_init_1 (void)
365 {
366   obstack_init (&tv_obst);
367   obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
368   assert (IS_POW2 (ALIGNOF (tarval)));
369
370   /* initialize the target value table */
371   tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
372 }
373
374 void
375 tarval_init_2 (void)
376 {
377   tarval *tv;
378   union ieee754_double x;
379
380   /* assumed by tarval_hash(): */
381   assert (sizeof (float) * CHAR_BIT == 32);
382   assert (sizeof (double) * CHAR_BIT == 64);
383
384 # if 0
385   /* assumed by tarval_chil & friends: */
386   assert (   (irm_C == irm_c+1) && (irm_h == irm_C+1)
387           && (irm_H == irm_h+1) && (irm_i == irm_H+1)
388           && (irm_I == irm_i+1) && (irm_l == irm_I+1)
389           && (irm_L == irm_l+1));
390
391   /* assumed everywhere: */
392   for (i = 0;  i <= irm_L-irm_c;  i += 2) {
393     assert (   IS_POW2 (max_chil[i+1]+1)
394             && (min_chil[i] == -max_chil[i]-1)
395             && ((tarval_CHIL)max_chil[i+1] == (tarval_CHIL)max_chil[i]-min_chil[i]));
396   }
397 # endif
398
399
400   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
401   tv->mode = mode_T;
402   tarval_bad = tarval_identify (tv);
403
404   tarval_b_false = tarval_from_long (mode_b, 0);
405   tarval_b_true = tarval_from_long (mode_b, 1);
406
407   /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
408   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
409   tv->mode = mode_d;
410   x.ieee.negative = 0;
411   x.ieee.exponent = 0x7ff;
412   x.ieee.mantissa0 = 0;
413   x.ieee.mantissa1 = 0;
414   tv->u.d = x.d;
415   tarval_d_Inf = tarval_identify (tv);
416
417   /* IsNaN <-> exponent==0x7ff  && (qnan_bit | bits | fraction_low) */
418   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
419   tv->mode = mode_d;
420   x.ieee_nan.negative = 0;
421   x.ieee_nan.exponent = 0x7ff;
422   x.ieee_nan.quiet_nan = 1;     /* @@@ quiet or signalling? */
423   x.ieee_nan.mantissa0 = 42;
424   x.ieee_nan.mantissa1 = 0;
425   assert(x.d != x.d /* x.d is NaN */);
426   tv->u.d = x.d;
427   tarval_d_NaN = tarval_identify (tv);
428
429   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
430   tv->mode = mode_p;
431   tv->u.p.xname = NULL;
432   tv->u.p.ent = NULL;
433   tv->u.p.tv = NULL;
434   tarval_p_void = tarval_identify (tv);
435
436   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
437
438
439   tarval_mode_null [irm_f] = tarval_from_long (mode_f, 0);
440   tarval_mode_null [irm_d] = tarval_from_long (mode_d, 0);
441   tarval_mode_null [irm_c] = tarval_from_long (mode_c, 0);
442   tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
443   tarval_mode_null [irm_h] = tarval_from_long (mode_h, 0);
444   tarval_mode_null [irm_H] = tarval_from_long (mode_H, 0);
445   tarval_mode_null [irm_i] = tarval_from_long (mode_i, 0);
446   tarval_mode_null [irm_I] = tarval_from_long (mode_I, 0);
447   tarval_mode_null [irm_l] = tarval_from_long (mode_l, 0);
448   tarval_mode_null [irm_L] = tarval_from_long (mode_L, 0);
449   tarval_mode_null [irm_b] = tarval_b_false;
450   tarval_mode_null [irm_p] = tarval_p_void;
451 }
452
453
454 \f
455 /*** ********************** Constructors for tarvals ********************** ***/
456
457 /* copy from src to dst len chars omitting '_'. */
458 static char *
459 stripcpy (char *dst, const char *src, size_t len)
460 {
461   char *d = dst;
462
463   while (len--) {
464     if (*src == '_') src++;
465     else *d++ = *src++;
466   }
467   *d = 0;                       /* make it 0-terminated. */
468
469   return dst;
470 }
471
472
473 tarval *
474 tarval_Z_from_str (const char *s, size_t len, int base)
475 {
476   tarval *tv;
477   char *buf;
478
479   assert (!BUILDING);
480
481   buf = alloca (len+1);
482   stripcpy (buf, s, len);
483
484   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
485   tv->mode = mode_Z;
486 #if _TARVAL_GMP_
487   if (mpz_init_set_str (&tv->u.Z, buf, base)) assert (0);
488 #else
489   assert(0 && "no support for Z in tv!");
490 #endif
491
492   return tarval_identify (tv);
493 }
494
495
496 tarval *
497 tarval_B_from_str (const char *s, size_t len)
498 {
499   tarval *tv;
500   size_t n;                     /* size of B */
501   const char *r;                /* read ptr */
502   unsigned x;                   /* bit store */
503   int b;                        /* bits in x */
504   int shift;                    /* base shift */
505
506   assert (!BUILDING);
507   assert (len >= 3);
508
509   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
510   tv->mode = mode_B;
511
512   assert (s[0] == '0');
513   switch (s[1]) {
514   case 'o':
515   case 'O': shift = 3; break;
516   case 'x':
517   case 'X': shift = 4; break;
518   default: assert(0);
519   }
520
521   r = s+len;                    /* set r past input */
522   s += 2;                       /* skip header */
523   x = 0; b = 0; n = 0;
524   while (--r >= s) {
525     int d;                      /* digit */
526
527     if (*r == '_') continue;    /* skip _ styropor */
528     if (('0' <= *r) && (*r <= '9')) {
529       d = *r - '0';
530     } else if (('a' <= *r) && (*r <= 'f')) {
531       d = *r - 'a' + 10;
532     } else { assert (('A' <= *r) && (*r <= 'F'));
533       d = *r - 'A' + 10;
534     }
535
536     x |= d << b;                /* insert d into x above the b present bits */
537     b += shift;                 /* x now contains shift more bits */
538
539     if (b >= 8) {               /* we've accumulated at least a byte */
540       char c = x & 0xFF;        /* extract the lower 8 bits from x */
541       obstack_grow (&tv_obst, &c, 1);  /* and stuff them into B */
542       x >>= 8;                  /* remove the lower 8 bits from x */
543       b -= 8;                   /* x now contains 8 bits fewer */
544       ++n;                      /* B grew a byte */
545     }
546   }
547
548   if (b >= 0) {                 /* flush the rest of the bits */
549     char c = x;                 /* extract them */
550     obstack_grow (&tv_obst, &c, 1); /* and stuff them into B */
551     ++n;                        /* B grew a byte */
552   }
553
554   { unsigned char *p = obstack_finish (&tv_obst);
555     unsigned char *q = p + n;
556
557     tv->u.B.p = p;
558     tv->u.B.n = n;
559     /* reverse p in place */
560     while (p < q) { char c = *p; *p++ = *q; *q-- = c; }
561   }
562
563   return tarval_identify (tv);
564 }
565
566
567 tarval *
568 tarval_f_from_str (const char *s, size_t len)
569 {
570   tarval *tv;
571   char *buf;
572   char *eptr;
573
574   assert (!BUILDING);
575
576   buf = alloca (len+1);
577   stripcpy (buf, s, len);
578
579   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
580   tv->mode = mode_f;
581   tv->u.f = (float)strtod (buf, &eptr);
582   assert (eptr == buf+strlen(buf));
583
584   return tarval_identify (tv);
585 }
586
587
588 tarval *
589 tarval_d_from_str (const char *s, size_t len)
590 {
591   tarval *tv;
592   char *buf;
593   char *eptr;
594
595   assert (!BUILDING);
596
597   buf = alloca (len+1);
598   stripcpy (buf, s, len);
599
600   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
601   tv->mode = mode_d;
602   tv->u.d = strtod (buf, &eptr);
603   assert (eptr == buf+strlen(buf));
604
605   return tarval_identify (tv);
606 }
607
608
609 tarval *
610 tarval_s_from_str (const char *s, size_t len)
611 {
612   tarval *tv;
613
614   assert (!BUILDING);
615
616   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
617
618   tv->mode = mode_s;
619   tv->u.s.n = len;
620   tv->u.s.p = obstack_copy (&tv_obst, s, len);
621
622   return tarval_identify (tv);
623 }
624
625 tarval *
626 tarval_S_from_str (const char *s, size_t len)
627 {
628   tarval *tv;
629
630   assert (!BUILDING);
631
632   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
633
634   tv->mode = mode_S;
635   tv->u.s.n = len;
636   tv->u.s.p = obstack_copy (&tv_obst, s, len);
637
638   return tarval_identify (tv);
639 }
640
641 tarval *tarval_int_from_str (const char *s, size_t len, int base, ir_mode *m) {
642   long val;
643   char *eptr;
644   char *buf;
645
646   assert (mode_is_int(m));
647   assert (!BUILDING);
648
649   buf = alloca (len+1);
650   stripcpy (buf, s, len);
651
652   errno = 0;
653   val = strtol(buf, &eptr, base);    /* strtoll */
654   assert (eptr == buf+strlen(buf));
655   if ((errno == ERANGE)               &&
656       ((m == mode_l) || (m == mode_L))  ) {
657     printf("WARNING: Constant %s not representable. Continuing with %ld.\n",
658            s, val);
659   }
660
661   return tarval_from_long(m, val);
662 }
663
664 /* Create a tarval with mode `m' and value `i' casted to the type that
665    represents such tarvals on host.  The resulting value must be legal
666    for mode `m'.  */
667 tarval *
668 tarval_from_long (ir_mode *m, long val)
669 {
670   tarval *tv;
671
672   assert (!BUILDING);
673
674   if (m == mode_T) return tarval_bad;
675
676   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
677
678   tv->mode = m;
679   switch (get_mode_modecode(m)) {
680     /* floating */
681   case irm_f:
682     tv->u.f = val; break;
683   case irm_d:
684     tv->u.d = val; break;
685     /* unsigned */
686   case irm_C: case irm_H: case irm_I: case irm_L:
687     tv->u.CHIL = val; break;
688     /* signed */
689   case irm_c: case irm_h: case irm_i: case irm_l:
690     tv->u.chil = val; break;
691   case irm_Z:
692 #if _TARVAL_GMP_
693     mpz_init_set_si (&tv->u.Z, val);
694 #else
695     assert(0 && "no support for Z in tv!");
696 #endif
697     break;
698     /* strange */
699   case irm_p:
700     assert(!val);
701     obstack_free (&tv_obst, tv);
702     return tarval_p_void;
703   case irm_b:
704     tv->u.b = !!val;            /* u.b must be 0 or 1 */
705     break;
706   default:
707     assert(0);
708   }
709
710   return tarval_identify (tv);
711 }
712
713
714 tarval *
715 tarval_p_from_str (const char *xname)
716 {
717   tarval *tv;
718
719   assert (!BUILDING);
720
721   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
722
723   tv->mode = mode_p;
724   tv->u.p.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
725   tv->u.p.ent = NULL;
726   tv->u.p.tv = NULL;
727   return tarval_identify (tv);
728 }
729
730
731 tarval *
732 tarval_p_from_entity (entity *ent)
733 {
734   tarval *tv;
735
736   assert (!BUILDING);
737
738   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
739
740   tv->mode = mode_p;
741   tv->u.p.xname = NULL;
742   tv->u.p.ent = ent;
743   tv->u.p.tv = NULL;
744   return tarval_identify (tv);
745 }
746
747
748 /* Routines for building a tarval step by step follow.
749    Legal calling sequences:
750      tarval_start()
751      No contructors except tarval_append() and tarval_append1 ()
752      tarval_finish_as() or tarval_cancel() */
753
754 /* Begin building a tarval.  */
755 void
756 tarval_start (void)
757 {
758   assert (!BUILDING);
759   obstack_blank (&tv_obst, sizeof (tarval));
760 }
761
762
763 /* Append `n' chars from `p' to the tarval currently under construction.  */
764 void
765 tarval_append (const char *p, size_t n)
766 {
767   assert (BUILDING);
768   obstack_grow (&tv_obst, p, n);
769 }
770
771
772 /* Append `ch' to the tarval currently under construction.  */
773 void
774 tarval_append1 (char ch)
775 {
776   assert (BUILDING);
777   obstack_1grow (&tv_obst, ch);
778 }
779
780
781 /* Finish the tarval currently under construction and give id mode `m'.
782    `m' must be irm_C, irm_B, irm_s or irm_S.
783    Return NULL if the value does not make sense for this mode, this
784    can only happen in mode C.  */
785 tarval *
786 tarval_finish_as (ir_mode *m)
787 {
788   int size = obstack_object_size (&tv_obst) - sizeof (tarval);
789   tarval *tv;
790   unsigned char *p;
791   char ch = 0;                  /* initialized to shut up gcc */
792
793   assert (BUILDING && (size >= 0));
794   if (m == mode_C) {
795     if (size != 1) return tarval_cancel();
796     p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
797     ch = *p;
798     obstack_blank (&tv_obst, -size);
799   }
800   tv = obstack_finish (&tv_obst);
801   p = (unsigned char *)tv + sizeof (tarval);
802   tv->mode = m;
803
804   switch (get_mode_modecode(m)) {
805   case irm_C:
806     tv->u.CHIL = ch;
807     break;
808   case irm_B:
809     tv->u.B.n = size;
810     tv->u.B.p = p;
811     break;
812   case irm_s:
813   case irm_S:
814     tv->u.s.n = size;
815     tv->u.s.p = p;
816     break;
817   case irm_p:
818     tv->u.p.tv = NULL;
819     break;
820   default:
821     assert (0);
822   }
823
824   return tarval_identify (tv);
825 }
826
827
828 /* Cancel tarval building and return tarval_bad.  */
829 tarval *
830 tarval_cancel (void)
831 {
832   assert (BUILDING);
833   obstack_free (&tv_obst, obstack_finish (&tv_obst));
834   return tarval_bad;
835 }
836
837
838 \f
839 /*** ****************** Arithmethic operations on tarvals ***************** ***/
840
841 /* Return `src' converted to mode `m' if representable, else NULL.
842    @@@ lots of conversions missing */
843 tarval *
844 tarval_convert_to (tarval *src, ir_mode *m)
845 {
846   tarval *tv;
847
848   if (m == src->mode) return src;
849
850   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
851   tv->mode = m;
852
853   switch (get_mode_modecode(src->mode)) {
854
855   case irm_d:
856     if (m != mode_f) goto fail;
857     tv->u.f = src->u.d;
858     break;
859
860   case irm_Z:
861 #if _TARVAL_GMP_
862     switch (get_mode_modecode(m)) {
863
864     case irm_C: case irm_H: case irm_I: case irm_L:
865       if (mpz_cmp_si (&src->u.Z, 0) < 0) goto fail;
866       if (mpz_size (&src->u.Z) > 1) goto fail;
867       tv->u.CHIL = mpz_get_ui (&src->u.Z);
868       if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
869       break;
870
871     case irm_c: case irm_h: case irm_i: case irm_l:
872       tv->u.chil = mpz_get_si (&src->u.Z);
873       if (chil_overflow (tv->u.chil, m)) goto fail;
874       break;
875
876     case irm_b:
877       tv ->u.b = !mpz_cmp_ui (&src->u.Z, 0);
878       break;
879
880     case irm_p:
881       if (mpz_cmp_ui (&src->u.Z, 0)) goto fail;
882       obstack_free (&tv_obst, tv);
883       return tarval_p_void;
884
885     default: goto fail;
886     }
887 #else
888     goto fail;
889 #endif
890     break;
891
892   case irm_c: case irm_h: case irm_i: case irm_l:
893     switch (get_mode_modecode(m)) {
894     case irm_c: case irm_h: case irm_i: case irm_l:
895       tv->u.chil = src->u.chil;
896       if (chil_overflow (tv->u.chil, m)) goto fail;
897       break;
898
899     case irm_C: case irm_H: case irm_I: case irm_L:
900       tv->u.CHIL = src->u.chil;
901       if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
902       break;
903
904     case irm_Z:
905 #if _TARVAL_GMP_
906       mpz_init_set_si (&tv->u.Z, src->u.chil);
907 #else
908       goto fail;
909 #endif
910       break;
911
912     case irm_b:
913       tv->u.b = !!src->u.chil;
914       break;
915
916     default: goto fail;
917     }
918
919   case irm_C: case irm_H: case irm_I: case irm_L:
920     switch (get_mode_modecode(m)) {
921     case irm_c: case irm_h: case irm_i: case irm_l:
922       tv->u.chil = src->u.CHIL;
923       if (chil_overflow (tv->u.chil, m)) goto fail;
924       break;
925
926     case irm_C: case irm_H: case irm_I: case irm_L:
927       tv->u.CHIL = src->u.CHIL;
928       if (CHIL_overflow (tv->u.CHIL, m)) goto fail;
929       break;
930
931     case irm_Z:
932 #if _TARVAL_GMP_
933       mpz_init_set_ui (&tv->u.Z, src->u.CHIL);
934 #else
935       goto fail;
936 #endif
937       break;
938
939     case irm_b:
940       tv->u.b = !!src->u.CHIL;
941       break;
942
943     default: goto fail;
944     }
945     break;
946
947   case irm_b:
948     switch (get_mode_modecode(m)) {
949     case irm_c: case irm_h: case irm_i: case irm_l:
950       tv->u.chil = src->u.b;
951       break;
952
953     case irm_C: case irm_H: case irm_I: case irm_L:
954       tv->u.CHIL = src->u.b;
955
956     default: goto fail;
957     }
958     break;
959
960   default:
961   fail:
962     obstack_free (&tv_obst, tv);
963     return NULL;
964   }
965
966   return tarval_identify (tv);
967 }
968
969
970 /* GL Why are there no ArmRoq comments, why is this not used? */
971 tarval *
972 tarval_neg (tarval *a)
973 {
974   tarval *tv;
975
976   TARVAL_VRFY (a);
977
978   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
979
980   tv->mode = a->mode;
981
982   switch (get_mode_modecode(a->mode)) {
983     /* floating */
984   case irm_f: tv->u.f = -a->u.f; break;
985   case irm_d: tv->u.d = -a->u.d; break;
986     /* unsigned */
987   case irm_C: case irm_H: case irm_I: case irm_L:
988     tv->u.CHIL = -a->u.CHIL & tv_val_CHIL (get_mode_max(a->mode));
989     break;
990     /* signed */
991   case irm_c: case irm_h: case irm_i: case irm_l:
992     tv->u.chil = -a->u.chil;
993     if (   chil_overflow (tv->u.chil, a->mode)
994         || ((tv->u.chil >= 0) == (a->u.chil >= 0))) {
995       obstack_free (&tv_obst, tv);
996       return NULL;
997     }
998     break;
999   case irm_Z:
1000 #if _TARVAL_GMP_
1001     mpz_init (&tv->u.Z);
1002     mpz_neg (&tv->u.Z, &a->u.Z);
1003 #else
1004     obstack_free (&tv_obst, tv);
1005     tv = a;
1006     printf("\nWrong negation\n\n");
1007 #endif
1008     break;
1009     /* strange */
1010   case irm_b: tv->u.b = !a->u.b; break;
1011   default: assert(0);
1012   }
1013
1014   return tarval_identify (tv);
1015 }
1016
1017
1018 /* Compare `a' with `b'.
1019    Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
1020    result is unknown.  */
1021 ir_pncmp
1022 tarval_comp (tarval *a, tarval *b)
1023 {
1024
1025   TARVAL_VRFY (a);
1026   TARVAL_VRFY (b);
1027
1028   assert (a->mode == b->mode);
1029
1030   switch (get_mode_modecode(a->mode)) {
1031     /* floating */
1032   case irm_f: return (  a->u.f == b->u.f ? irpn_Eq
1033                       : a->u.f > b->u.f ? irpn_Gt
1034                       : a->u.f < b->u.f ? irpn_Lt
1035                       : irpn_Uo);
1036   case irm_d: return (  a->u.d == b->u.d ? irpn_Eq
1037                       : a->u.d > b->u.d ? irpn_Gt
1038                       : a->u.d < b->u.d ? irpn_Lt
1039                       : irpn_Uo);
1040     /* unsigned */
1041   case irm_C: case irm_H: case irm_I: case irm_L:
1042     return (  a->u.CHIL == b->u.CHIL ? irpn_Eq
1043             : a->u.CHIL > b->u.CHIL ? irpn_Gt
1044             : irpn_Lt);
1045     /* signed */
1046   case irm_c: case irm_h: case irm_i: case irm_l:
1047     return (  a->u.chil == b->u.chil ? irpn_Eq
1048             : a->u.chil > b->u.chil ? irpn_Gt
1049             : irpn_Lt);
1050   case irm_Z:
1051     {
1052 #if _TARVAL_GMP_
1053       int cmp = mpz_cmp (&a->u.Z, &b->u.Z);
1054       return (  cmp == 0 ? irpn_Eq
1055               : cmp > 0 ? irpn_Gt
1056               : irpn_Lt);
1057 #else
1058       return irpn_False;
1059 #endif
1060     }
1061     /* strange */
1062   case irm_b: return (  a->u.b == b->u.b ? irpn_Eq
1063                       : a->u.b > b->u.b ? irpn_Gt
1064                       : irpn_Lt);
1065   /* The following assumes that pointers are unsigned, which is valid
1066      for all sane CPUs (transputers are insane). */
1067   case irm_p: return (  a == b ? irpn_Eq
1068                       : a == tarval_p_void ? irpn_Lt
1069                       : b == tarval_p_void ? irpn_Gt
1070                       : irpn_False); /* unknown */
1071   default: assert (0);
1072   }
1073 }
1074
1075
1076 /* Return `a+b' if computable, else NULL.  Modes must be equal.  */
1077 tarval *
1078 tarval_add (tarval *a, tarval *b)
1079 {
1080   tarval *tv;
1081
1082   TARVAL_VRFY (a); TARVAL_VRFY (b);
1083   assert (a->mode == b->mode);
1084
1085   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1086
1087   tv->mode = a->mode;
1088
1089   switch (get_mode_modecode(a->mode)) {
1090     /* floating */
1091   case irm_f: tv->u.f = a->u.f + b->u.f; break; /* @@@ overflow etc */
1092   case irm_d: tv->u.d = a->u.d + b->u.d; break; /* @@@ dto. */
1093     /* unsigned */
1094   case irm_C: case irm_H: case irm_I: case irm_L:
1095     tv->u.CHIL = (a->u.CHIL + b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1096     break;
1097     /* signed */
1098   case irm_c: case irm_h: case irm_i: case irm_l:
1099     tv->u.chil = a->u.chil + b->u.chil;
1100     if (   chil_overflow (tv->u.chil, a->mode)
1101         || ((tv->u.chil > a->u.chil) ^ (b->u.chil > 0))) {
1102       obstack_free (&tv_obst, tv);
1103       return NULL;
1104     }
1105     break;
1106   case irm_Z:
1107 #if _TARVAL_GMP_
1108     mpz_init (&tv->u.Z);
1109     mpz_add (&tv->u.Z, &a->u.Z, &b->u.Z);
1110 #else
1111     obstack_free (&tv_obst, tv);
1112     return NULL;
1113 #endif
1114     break;
1115     /* strange */
1116   case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1117   default: assert(0);
1118   }
1119
1120   return tarval_identify (tv);
1121 }
1122
1123
1124 /* Return `a-b' if computable, else NULL.  Modes must be equal.  */
1125 tarval *
1126 tarval_sub (tarval *a, tarval *b)
1127 {
1128   tarval *tv;
1129
1130   TARVAL_VRFY (a); TARVAL_VRFY (b);
1131   assert (a->mode == b->mode);
1132
1133   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1134
1135   tv->mode = a->mode;
1136
1137   switch (get_mode_modecode(a->mode)) {
1138     /* floating */
1139   case irm_f: tv->u.f = a->u.f - b->u.f; break; /* @@@ overflow etc */
1140   case irm_d: tv->u.d = a->u.d - b->u.d; break; /* @@@ dto. */
1141     /* unsigned */
1142   case irm_C: case irm_H: case irm_I: case irm_L:
1143     tv->u.CHIL = (a->u.CHIL - b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1144     break;
1145     /* signed */
1146   case irm_c: case irm_h: case irm_i: case irm_l:
1147     tv->u.chil = a->u.chil - b->u.chil;
1148     if (   chil_overflow (tv->u.chil, a->mode)
1149         || ((tv->u.chil > a->u.chil) ^ (b->u.chil < 0))) {
1150       obstack_free (&tv_obst, tv);
1151       return NULL;
1152     }
1153     break;
1154   case irm_Z:
1155 #if _TARVAL_GMP_
1156     mpz_init (&tv->u.Z);
1157     mpz_sub (&tv->u.Z, &a->u.Z, &b->u.Z);
1158 #else
1159     obstack_free (&tv_obst, tv);
1160     return NULL;
1161 #endif
1162     break;
1163     /* strange */
1164   case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
1165   default: assert(0);
1166   }
1167
1168   return tarval_identify (tv);
1169 }
1170
1171 /* Return `a*b' if computable, else NULL.  Modes must be equal.  */
1172 tarval *
1173 tarval_mul (tarval *a, tarval *b)
1174 {
1175   tarval *tv;
1176
1177   TARVAL_VRFY (a); TARVAL_VRFY (b);
1178   assert (a->mode == b->mode);
1179
1180   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1181
1182   tv->mode = a->mode;
1183
1184   switch (get_mode_modecode(a->mode)) {
1185     /* floating */
1186   case irm_f: tv->u.f = a->u.f * b->u.f; break; /* @@@ overflow etc */
1187   case irm_d: tv->u.d = a->u.d * b->u.d; break; /* @@@ dto. */
1188     /* unsigned */
1189   case irm_C: case irm_H: case irm_I: case irm_L:
1190     tv->u.CHIL = (a->u.CHIL * b->u.CHIL) & tv_val_CHIL (get_mode_max(a->mode));
1191     break;
1192     /* signed */
1193   case irm_c: case irm_h: case irm_i: case irm_l:
1194     tv->u.chil = a->u.chil * b->u.chil;
1195     if (   chil_overflow (tv->u.chil, a->mode)
1196         || (b->u.chil && (tv->u.chil / b->u.chil != a->u.chil))) {
1197       obstack_free (&tv_obst, tv);
1198       return NULL;
1199     }
1200     break;
1201   case irm_Z:
1202 #if _TARVAL_GMP_
1203     mpz_init (&tv->u.Z);
1204     mpz_mul (&tv->u.Z, &a->u.Z, &b->u.Z);
1205 #else
1206     obstack_free (&tv_obst, tv);
1207     return NULL;
1208 #endif
1209     break;
1210     /* strange */
1211   case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1212   default: assert(0);
1213   }
1214
1215   return tarval_identify (tv);
1216 }
1217
1218
1219 /* Return floating-point `a/b' if computable, else NULL.
1220    Modes must be equal, non-floating-point operands are converted to irm_d.  */
1221 tarval *
1222 tarval_quo (tarval *a, tarval *b)
1223 {
1224   tarval *tv;
1225
1226   TARVAL_VRFY (a); TARVAL_VRFY (b);
1227   assert (a->mode == b->mode);
1228
1229   switch (get_mode_modecode(a->mode)) {
1230     /* floating */
1231   case irm_f:
1232     tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1233     tv->mode = mode_f;
1234     tv->u.f = a->u.f / b->u.f;  /* @@@ overflow etc */
1235     break;
1236   case irm_d:
1237     tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1238     tv->mode = mode_d;
1239     tv->u.d = a->u.d / b->u.d;  /* @@@ overflow etc */
1240     break;
1241   default:
1242     a = tarval_convert_to (a, mode_d);
1243     b = tarval_convert_to (b, mode_d);
1244     return a && b ? tarval_quo (a, b) : NULL;
1245   }
1246
1247   return tarval_identify (tv);
1248 }
1249
1250
1251 /* Return `a/b' if computable, else NULL.  Modes must be equal.  */
1252 tarval *
1253 tarval_div (tarval *a, tarval *b)
1254 {
1255   tarval *tv;
1256
1257   TARVAL_VRFY (a); TARVAL_VRFY (b);
1258   assert (a->mode == b->mode);
1259
1260   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1261
1262   tv->mode = a->mode;
1263
1264   switch (get_mode_modecode(a->mode)) {
1265     /* floating */
1266   case irm_f: tv->u.f = floor (a->u.f / b->u.f); break; /* @@@ overflow etc */
1267   case irm_d: tv->u.d = floor (a->u.d / b->u.d); break; /* @@@ dto. */
1268     /* unsigned */
1269   case irm_C: case irm_H: case irm_I: case irm_L:
1270     if (!b->u.CHIL) goto fail;
1271     tv->u.CHIL = a->u.CHIL / b->u.CHIL;
1272     break;
1273     /* signed */
1274   case irm_c: case irm_h: case irm_i: case irm_l:
1275     if (   !b->u.chil
1276         || ((b->u.chil == -1) && (a->u.chil == tv_val_chil (get_mode_max(a->mode)) ))) {
1277     fail:
1278       obstack_free (&tv_obst, tv);
1279       return NULL;
1280     }
1281     tv->u.chil = a->u.chil / b->u.chil;
1282     break;
1283   case irm_Z:
1284 #if _TARVAL_GMP_
1285     if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1286     mpz_init (&tv->u.Z);
1287     mpz_div (&tv->u.Z, &a->u.Z, &b->u.Z);
1288 #else
1289     goto fail;
1290 #endif
1291     break;
1292     /* strange */
1293   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1294   default: assert(0);
1295   }
1296
1297   return tarval_identify (tv);
1298 }
1299
1300
1301 /* Return `a%b' if computable, else NULL.  Modes must be equal.  */
1302 tarval *
1303 tarval_mod (tarval *a, tarval *b)
1304 {
1305   tarval *tv;
1306
1307   TARVAL_VRFY (a); TARVAL_VRFY (b);
1308   assert (a->mode == b->mode);
1309
1310   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1311
1312   tv->mode = a->mode;
1313
1314   switch (get_mode_modecode(a->mode)) {
1315     /* floating */
1316   case irm_f: tv->u.f = fmod (a->u.f, b->u.f); break; /* @@@ overflow etc */
1317   case irm_d: tv->u.d = fmod (a->u.d, b->u.d); break; /* @@@ dto */
1318     /* unsigned */
1319   case irm_C: case irm_H: case irm_I: case irm_L:
1320     if (!b->u.CHIL) goto fail;
1321     tv->u.CHIL = a->u.CHIL % b->u.CHIL;
1322     break;
1323     /* signed */
1324   case irm_c: case irm_h: case irm_i: case irm_l:
1325     if (!b->u.chil) {
1326     fail:
1327       obstack_free (&tv_obst, tv);
1328       return NULL;
1329     }
1330     tv->u.chil = a->u.chil % b->u.chil;
1331     break;
1332   case irm_Z:
1333 #if _TARVAL_GMP_
1334     if (!mpz_cmp_ui (&b->u.Z, 0)) goto fail;
1335     mpz_init (&tv->u.Z);
1336     mpz_mod (&tv->u.Z, &a->u.Z, &b->u.Z);
1337 #else
1338     goto fail;
1339 #endif
1340     break;
1341     /* strange */
1342   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1343   default: assert(0);
1344   }
1345
1346   return tarval_identify (tv);
1347 }
1348
1349 /* Return |a| if computable, else Null. */
1350 /*  is -max == min?? */
1351 tarval *
1352 tarval_abs (tarval *a) {
1353   TARVAL_VRFY (a);
1354   if (tv_is_negative(a)) return tarval_neg(a);
1355   return a;
1356 }
1357
1358 int
1359 tv_is_negative(tarval *a) {
1360   TARVAL_VRFY (a);
1361   switch (get_mode_modecode(a->mode)) {
1362     /* floating */
1363   case irm_f: return (a->u.f<0); break;
1364   case irm_d: return (a->u.d<0); break;
1365     /* unsigned */
1366   case irm_C: case irm_H: case irm_I: case irm_L:
1367     return 0;
1368     break;
1369     /* signed */
1370   case irm_c: case irm_h: case irm_i: case irm_l:
1371     return (a->u.chil < 0);
1372     break;
1373   case irm_Z:
1374     break;
1375   case irm_b: break;
1376   default: assert(0);
1377   }
1378
1379   return 0;
1380 }
1381
1382
1383 /* Return `a&b'.  Modes must be equal.  */
1384 tarval *
1385 tarval_and (tarval *a, tarval *b)
1386 {
1387   tarval *tv;
1388
1389   TARVAL_VRFY (a); TARVAL_VRFY (b);
1390   assert (a->mode == b->mode);
1391
1392   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1393
1394   tv->mode = a->mode;
1395
1396   switch (get_mode_modecode(a->mode)) {
1397     /* unsigned */
1398   case irm_C: case irm_H: case irm_I: case irm_L:
1399     tv->u.CHIL = a->u.CHIL & b->u.CHIL; break;
1400     /* signed */
1401   case irm_c: case irm_h: case irm_i: case irm_l:
1402     tv->u.chil = a->u.chil & b->u.chil; break;
1403   case irm_Z:
1404 #if _TARVAL_GMP_
1405     mpz_init (&tv->u.Z);
1406     mpz_and (&tv->u.Z, &a->u.Z, &b->u.Z);
1407 #else
1408     assert(0);
1409 #endif
1410     break;
1411     /* strange */
1412   case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1413   default: assert(0);
1414   }
1415
1416   return tarval_identify (tv);
1417 }
1418
1419
1420 /* Return `a|b'.  Modes must be equal.  */
1421 tarval *
1422 tarval_or (tarval *a, tarval *b)
1423 {
1424   tarval *tv;
1425
1426   TARVAL_VRFY (a); TARVAL_VRFY (b);
1427   assert (a->mode == b->mode);
1428
1429   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1430
1431   tv->mode = a->mode;
1432
1433   switch (get_mode_modecode(a->mode)) {
1434     /* unsigned */
1435   case irm_C: case irm_H: case irm_I: case irm_L:
1436     tv->u.CHIL = a->u.CHIL | b->u.CHIL; break;
1437     /* signed */
1438   case irm_c: case irm_h: case irm_i: case irm_l:
1439     tv->u.chil = a->u.chil | b->u.chil; break;
1440   case irm_Z:
1441 #if _TARVAL_GMP_
1442     mpz_init (&tv->u.Z);
1443     mpz_ior (&tv->u.Z, &a->u.Z, &b->u.Z);
1444 #else
1445     assert(0);
1446 #endif
1447     break;
1448     /* strange */
1449   case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1450   default: assert(0);
1451   }
1452
1453   return tarval_identify (tv);
1454 }
1455
1456
1457 /* Return `a^b'.  Modes must be equal.  */
1458 tarval *
1459 tarval_eor (tarval *a, tarval *b)
1460 {
1461   tarval *tv;
1462
1463   TARVAL_VRFY (a); TARVAL_VRFY (b);
1464   assert (a->mode == b->mode);
1465
1466 #if 1 /* see case irm_Z below */
1467   if (a->mode == mode_Z) return NULL;
1468 #endif
1469
1470   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1471
1472   tv->mode = a->mode;
1473
1474   switch (get_mode_modecode(a->mode)) {
1475     /* unsigned */
1476   case irm_C: case irm_H: case irm_I: case irm_L:
1477     tv->u.CHIL = a->u.CHIL ^ b->u.CHIL; break;
1478     /* signed */
1479   case irm_c: case irm_h: case irm_i: case irm_l:
1480     tv->u.chil = a->u.chil ^ b->u.chil; break;
1481   case irm_Z:
1482 #if 0
1483     /* gmp-1.3.2 declares but does not define mpz_xor() */
1484     mpz_init (&tv->u.Z);
1485     mpz_xor (&tv->u.Z, &a->u.Z, &b->u.Z);
1486 #endif
1487     break;
1488     /* strange */
1489   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1490   default: assert(0);
1491   }
1492
1493   return tarval_identify (tv);
1494 }
1495
1496
1497 /* Return `a<<b' if computable, else NULL.  */
1498 tarval *
1499 tarval_shl (tarval *a, tarval *b)
1500 {
1501   int b_is_huge;
1502   long shift;
1503   tarval *tv;
1504
1505   TARVAL_VRFY (a); TARVAL_VRFY (b);
1506
1507   shift = tarval_ord (b, &b_is_huge);
1508   if (   b_is_huge
1509       || (shift < 0)
1510       || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1511     return NULL;
1512   }
1513
1514   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1515   tv->mode = a->mode;
1516
1517   switch (get_mode_modecode(a->mode)) {
1518     /* unsigned */
1519   case irm_C: case irm_H: case irm_I: case irm_L:
1520     tv->u.CHIL = a->u.CHIL << shift;
1521     break;
1522     /* signed */
1523   case irm_c: case irm_h: case irm_i: case irm_l:
1524     tv->u.chil = a->u.chil << shift;
1525     break;
1526   case irm_Z:
1527 #if _TARVAL_GMP_
1528     mpz_init (&tv->u.Z);
1529     mpz_mul_2exp (&tv->u.Z, &a->u.Z, shift);
1530 #else
1531     assert(0);
1532 #endif
1533     break;
1534   default: assert (0);
1535   }
1536
1537   return tarval_identify (tv);
1538 }
1539
1540
1541 /* Return `a>>b' if computable, else NULL.
1542    The interpretation of >> (sign extended or not) is implementaion
1543    dependent, i.e. this is neither shr nor shrs!! */
1544 tarval *
1545 tarval_shr (tarval *a, tarval *b)
1546 {
1547   int b_is_huge;
1548   long shift;
1549   tarval *tv;
1550
1551   TARVAL_VRFY (a); TARVAL_VRFY (b);
1552
1553   shift = tarval_ord (b, &b_is_huge);
1554   if (   b_is_huge
1555       || (shift < 0)
1556       || ((shift >= get_mode_size(mode_l)*target_bits) && (a->mode != mode_Z))) {
1557     return NULL;
1558   }
1559
1560   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1561   tv->mode = a->mode;
1562
1563   switch (get_mode_modecode(a->mode)) {
1564     /* unsigned */
1565   case irm_C: case irm_H: case irm_I: case irm_L:
1566     tv->u.CHIL = a->u.CHIL >> shift;
1567     break;
1568     /* signed */
1569   case irm_c: case irm_h: case irm_i: case irm_l:
1570     tv->u.chil = a->u.chil >> shift;
1571     break;
1572   case irm_Z:
1573 #if _TARVAL_GMP_
1574     mpz_init (&tv->u.Z);
1575     mpz_div_2exp (&tv->u.Z, &a->u.Z, shift);
1576 #else
1577     assert(0);
1578 #endif
1579     break;
1580   default: assert (0);
1581   }
1582
1583   return tarval_identify (tv);
1584 }
1585
1586
1587 /* Classify `tv', which may be NULL.
1588    Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1589    multiplicative neutral element, and -1 if `tv' is the neutral
1590    element of bitwise and.  */
1591 long
1592 tarval_classify (tarval *tv)
1593 {
1594   if (!tv) return 2;
1595
1596   TARVAL_VRFY (tv);
1597
1598   switch (get_mode_modecode(tv->mode)) {
1599     /* floating */
1600   case irm_f: case irm_d:
1601     return 2;
1602     /* unsigned */
1603   case irm_C:
1604     return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_C))) - 1;
1605   case irm_H:
1606     return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_H))) - 1;
1607   case irm_I:
1608     return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_I))) - 1;
1609   case irm_L:
1610     return (long)((tv->u.CHIL+1) & tv_val_CHIL (get_mode_max(mode_L))) - 1;
1611     /* signed */
1612   case irm_c: case irm_h: case irm_i: case irm_l:
1613     return tv->u.chil;
1614   case irm_Z:
1615 #if _TARVAL_GMP_
1616     if      (mpz_cmp_si (&tv->u.Z, 0)) return 0;
1617     else if (mpz_cmp_si (&tv->u.Z, 1)) return 1;
1618     else if (mpz_cmp_si (&tv->u.Z,-1)) return -1;
1619 #endif
1620     return 2;
1621     /* strange */
1622   case irm_b:
1623     return tv->u.b;
1624   default:
1625     return 2;
1626   }
1627 }
1628
1629
1630 #if _TARVAL_GMP_
1631 bool
1632 tarval_s_fits (tarval *tv, long min, long max) {
1633   return ((  mpz_cmp_si (&tv->u.Z, min) >= 0)
1634           && mpz_cmp_si (&tv->u.Z, max) <= 0);
1635 }
1636
1637 bool
1638 tarval_u_fits (tarval *tv, unsigned long max) {
1639   return ((  mpz_sgn (&tv->u.Z) >= 0)
1640           && mpz_cmp_si (&tv->u.Z, max) <= 0);
1641 }
1642 #endif
1643
1644 /* Convert `tv' into type `long', set `fail' if not representable.
1645    If `fail' gets set for an unsigned `tv', the correct result can be
1646    obtained by casting the result to `unsigned long'.  */
1647 long
1648 tarval_ord (tarval *tv, int *fail)
1649 {
1650   TARVAL_VRFY (tv);
1651
1652   switch (get_mode_modecode(tv->mode)) {
1653     /* unsigned */
1654   case irm_C: case irm_H: case irm_I: case irm_L:
1655     *fail = tv->u.CHIL > tv_val_CHIL (get_mode_max(mode_l));
1656     return tv->u.CHIL;
1657     /* signed */
1658   case irm_c: case irm_h: case irm_i: case irm_l:
1659     *fail = 0;
1660     return tv->u.chil;
1661   case irm_Z:
1662 #if _TARVAL_GMP_
1663     *fail = (   (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) > 0)
1664              || (mpz_cmp_si (&tv->u.Z, tv_val_chil(get_mode_max(mode_l))) < 0));
1665     return mpz_get_si (&tv->u.Z);
1666 #else
1667     *fail = 1;
1668     return 0;
1669 #endif
1670     /* strange */
1671   case irm_b:
1672     *fail = 0;
1673     return tv->u.b;
1674   default: ;
1675     *fail = 1;
1676     return 0;
1677   }
1678 }
1679
1680 \f
1681 int
1682 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1683 {
1684   tarval *val = XP_GETARG (tarval *, 0);
1685   int printed;
1686   char buf[40];
1687
1688   TARVAL_VRFY (val);
1689
1690   switch (get_mode_modecode(val->mode)) {
1691
1692   case irm_T:                   /* none */
1693     printed = XPSR ("<bad>");
1694     break;
1695
1696   case irm_f:                   /* float */
1697     sprintf (buf, "%1.9e", (float)(val->u.f));
1698     printed = XPF1R ("%s", buf);
1699     break;
1700   case irm_d:                   /* double */
1701     printed = XPF1R ("%1.30g", (double)(val->u.d));
1702     break;
1703
1704   case irm_c:                   /* signed char */
1705   case irm_C:                   /* unsigned char */
1706     if ((isprint (val->u.chil)) &&
1707         (val->u.chil != '\\')   && (val->u.chil != '\'')) {
1708       printed = XPF1R ("'%c'", val->u.chil);
1709     } else {
1710       printed = XPF1R ("0x%x", (unsigned long)val->u.chil);
1711     }
1712     break;
1713
1714   case irm_h: case irm_i: case irm_l: /* signed num */
1715     printed = XPF1R ("%ld", (long)val->u.chil);
1716     break;
1717   case irm_H: case irm_I: case irm_L: /* unsigned num */
1718     printed = XPF1R ("%lu", (unsigned long)val->u.CHIL);
1719     break;
1720
1721   case irm_Z:                   /* mp int */
1722     printed = XPF1R ("%Z", &val->u.Z);
1723     break;
1724
1725   case irm_p:                   /* pointer */
1726     if (val->u.p.xname) {
1727       printed = XPR (val->u.p.xname);
1728     } else if (val->u.p.ent) {
1729       if (get_entity_peculiarity(val->u.p.ent) == existent)
1730         printed = XPF1R ("&(%I)", get_entity_ld_ident(val->u.p.ent));
1731       else
1732         printed = XPSR ("(NULL)");
1733     } else {
1734       assert (val == tarval_p_void);
1735       printed = XPSR ("(void)");
1736     }
1737     break;
1738
1739   case irm_b:                   /* boolean */
1740     if (val->u.b) printed = XPSR ("true");
1741     else          printed = XPSR ("false");
1742     break;
1743
1744   case irm_B:                   /* universal bits */
1745     printed = XPSR ("<@@@ some bits>");
1746     break;
1747
1748   case irm_s:                   /* string */
1749   case irm_S:
1750     { size_t i;
1751       char *buf = alloca (val->u.s.n + 2);
1752       char *bp;
1753
1754       printed = 0;
1755       buf[0] = '\'';
1756       bp = buf + 1;
1757       for (i = 0;  i < val->u.s.n;  ++i) {
1758         if (isprint (val->u.s.p[i])) {
1759           *bp++ = val->u.s.p[i];
1760         } else {
1761           if (bp != buf) {
1762             XPM (buf, bp-buf);
1763             bp = buf;
1764           }
1765           XPF1 ("'\\%03o'", val->u.s.p[i]);
1766         }
1767       }
1768       *bp++ = '\'';
1769       XPM (buf, bp-buf);
1770       break;
1771     }
1772
1773
1774   case irm_M:                   /* memory */
1775   case irm_R:                   /* region */
1776   default:
1777     assert (0);
1778   }
1779
1780   return printed;
1781 }
1782
1783
1784 ir_mode *
1785 get_tv_mode (tarval *tv)
1786 {
1787   return tv->mode;
1788 }
1789
1790 /* Returns the entity if the tv is a pointer to an entity, else
1791    returns NULL; */
1792 entity *get_tv_entity(tarval *tv) {
1793   entity *ent = NULL;
1794
1795   if (tv->mode == mode_p) {
1796     if (tv->u.p.xname) {
1797       assert(0);
1798       /* not an entity */
1799     } else if (tv->u.p.ent) {
1800       ent = tv->u.p.ent;
1801     } else {
1802       /* not an entity */
1803     }
1804   }
1805   return ent;
1806 }