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