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