e8e9e87b3c73b4590b876fade71ce0ba12dc69ae
[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 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 # include "xprintf.h"
33 #include <assert.h>
34 #include <limits.h>
35 #include <errno.h>
36 #include <math.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40
41 #include "pset.h"
42 #define TOBSTACK_ID "tv"
43 #include "obst.h"
44 #include "ieee754.h"
45 #include "tune.h"
46 #include "xp_help.h"
47 #include "tv_t.h"
48 #include "entity_t.h"
49 #include "ident_t.h"
50 #include "irmode.h"
51
52 static struct obstack tv_obst;  /* obstack for all the target values */
53 static pset *tarvals;           /* pset containing pointers to _all_ tarvals */
54
55 /* currently building an object with tarval_start() & friends ? */
56 #define BUILDING obstack_object_size (&tv_obst)
57
58 /* bcopy is not ISO C */
59 #define bcopy(X, Y, Z) memcpy((Y), (X), (Z))
60
61
62 /* special tarvals: */
63 tarval *tarval_bad;
64 tarval *tarval_b_false;
65 tarval *tarval_b_true;
66 tarval *tarval_D_NaN;
67 tarval *tarval_D_Inf;
68 tarval *tarval_P_void;
69 tarval *tarval_mode_null[irm_max];
70 tarval *tarval_mode_min[irm_max];
71 tarval *tarval_mode_max[irm_max];
72
73 tarval *get_tarval_bad      ()              { return tarval_bad;     }
74 tarval *get_tarval_b_false  ()              { return tarval_b_false; }
75 tarval *get_tarval_b_true   ()              { return tarval_b_true;  }
76 tarval *get_tarval_D_NaN    ()              { return tarval_D_NaN;   }
77 tarval *get_tarval_D_Inf    ()              { return tarval_D_Inf;   }
78 tarval *get_tarval_P_void   ()              { return tarval_P_void;  }
79 tarval *get_tarval_mode_null(ir_mode *mode)
80   { return tarval_mode_null[get_mode_modecode(mode)]; }
81 tarval *get_tarval_mode_min (ir_mode *mode)
82   { return tarval_mode_min[get_mode_modecode(mode)];  }
83 tarval *get_tarval_mode_max (ir_mode *mode)
84   { return tarval_mode_max[get_mode_modecode(mode)];  }
85
86 # if 0
87 /* @@@ depends on order of ir_mode */
88 static tarval_sInt min_sInt[8] = {
89   TARGET_SIMIN (c), 0,
90   TARGET_SIMIN (h), 0,
91   TARGET_SIMIN (i), 0,
92   TARGET_SIMIN (l), 0
93 };
94 static tarval_sInt max_sInt[8] = {
95   TARGET_SIMAX (c), TARGET_UIMAX (C),
96   TARGET_SIMAX (h), TARGET_UIMAX (H),
97   TARGET_SIMAX (i), TARGET_UIMAX (I),
98   TARGET_SIMAX (l), TARGET_UIMAX (L)
99 };
100 # endif
101
102 /* Used to be in irmode.h, replaced now. */
103 # define is_Int(m) ((m) <= irm_Lu && (m) >= irm_Bs) /* old */
104
105 /* return a mode-specific value */
106
107 tarval_F
108 tv_val_F (tarval *tv)
109 {
110   return tv->u.F;
111 }
112
113 tarval_D
114 tv_val_D (tarval *tv)
115 {
116   return tv->u.D;
117 }
118
119 tarval_E
120 tv_val_E (tarval *tv)
121 {
122   return tv->u.E;
123 }
124
125 tarval_sInt
126 tv_val_sInt (tarval *tv)
127 {
128   return tv->u.sInt;
129 }
130
131 tarval_uInt
132 tv_val_uInt (tarval *tv)
133 {
134   return tv->u.uInt;
135 }
136
137 tarval_P
138 tv_val_P (tarval *tv)
139 {
140   return tv->u.P;
141 }
142
143 bool
144 tv_val_b (tarval *tv)
145 {
146   return tv->u.b;
147 }
148
149
150 /* Overflows `sInt' signed integral `mode'?  */
151 static INLINE bool
152 sInt_overflow (tarval_sInt sInt, ir_mode *mode)
153 {
154   assert (is_Int(get_mode_modecode(mode)));
155   return (get_mode_min(mode) && get_mode_max(mode)  /* only valid after firm initialization */
156           && (sInt < tv_val_sInt (get_mode_min(mode))
157               || tv_val_sInt (get_mode_max(mode)) < sInt));
158 }
159
160
161 /* Overflows `uInt' unsigned integral `mode'?  */
162 static INLINE bool
163 uInt_overflow (tarval_uInt uInt, ir_mode *mode)
164 {
165   assert (is_Int(get_mode_modecode(mode)));
166   return (get_mode_max(mode)   /* only valid after firm initialization */
167           && tv_val_uInt (get_mode_max(mode)) < uInt);
168 }
169
170
171 #ifndef NDEBUG
172 void
173 _tarval_vrfy (const tarval *val)
174 {
175   assert (val);
176   switch (get_mode_modecode(val->mode)) {
177     /* floating */
178   case irm_F:
179   case irm_D:
180   case irm_E:
181     break;
182     /* integral */
183   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: {
184     //    printf("Tarval is %lu\n", val->u.uInt);
185     assert (!uInt_overflow (val->u.uInt, val->mode));
186     } break;
187   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
188     assert (!sInt_overflow (val->u.sInt, val->mode)); break;
189   case irm_C:
190   case irm_U:
191     break;
192   case irm_P:
193     if (val->u.P.ent)
194       assert (val->u.P.ent->kind == k_entity);
195     assert (   val->u.P.xname || val->u.P.ent
196             || !tarval_P_void || (val == tarval_P_void));
197     break;
198   case irm_b:
199     assert ((unsigned)val->u.b <= 1); break;
200   default:
201     assert (val->mode == mode_T);
202   }
203 }
204 #endif
205
206
207 #ifdef STATS
208
209 static void
210 tarval_stats (void)
211 {
212   pset_stats (tarvals);
213 }
214
215 #endif
216
217
218 /* Return the canonical tarval * for tv.
219    May destroy everything allocated on tv_obst after tv!  */
220 static tarval *
221 tarval_identify (tarval *tv)
222 {
223   tarval *o;
224
225   o = pset_insert (tarvals, tv, tarval_hash (tv));
226
227   if (o != tv) {
228     obstack_free (&tv_obst, (void *)tv);
229   }
230
231   TARVAL_VRFY (o);
232   return o;
233 }
234
235
236 /* Return 0 iff a equals b.  Bitwise identical NaNs compare equal.  */
237 static int
238 tarval_cmp (const void *p, const void *q)
239 {
240   const tarval *a = p;
241   const tarval *b = q;
242
243   TARVAL_VRFY (a);
244   TARVAL_VRFY (b);
245
246   if (a == b) return 0;
247   if ((char *)a->mode - (char *)b->mode)
248     return (char *)a->mode - (char *)b->mode;
249
250   switch (get_mode_modecode(a->mode)) {
251     /* floating */
252   case irm_F:
253     return memcmp (&a->u.F, &b->u.F, sizeof (a->u.F));
254   case irm_D:
255     return memcmp (&a->u.D, &b->u.D, sizeof (a->u.D));
256   case irm_E:
257     return memcmp (&a->u.E, &b->u.E, sizeof (a->u.E));
258     /* unsigned */
259   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
260     if (sizeof (int) == sizeof (tarval_uInt)) {
261       return a->u.uInt - b->u.uInt;
262     }
263     return a->u.uInt != b->u.uInt;
264     /* signed */
265   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
266     if (sizeof (int) == sizeof (tarval_sInt)) {
267       return a->u.sInt - b->u.sInt;
268     }
269     return a->u.sInt != b->u.sInt;
270   case irm_C:
271     return a->u.C - b->u.C;
272   case irm_U:
273     return a->u.U - b->u.U;
274   case irm_P:
275     if (a->u.P.ent || b->u.P.ent)
276       return (char *)a->u.P.ent - (char *)b->u.P.ent;
277     if (a->u.P.xname && b->u.P.xname)
278       return strcmp (a->u.P.xname, b->u.P.xname);
279     return a->u.P.xname - b->u.P.xname;
280   case irm_b:
281     return a->u.b - b->u.b;
282   default: assert (0);
283   }
284 }
285
286
287 unsigned
288 tarval_hash (tarval *tv)
289 {
290   unsigned h;
291
292   h = get_mode_modecode(tv->mode) * 0x421u;
293   switch (get_mode_modecode(tv->mode)) {
294   case irm_T:
295     h = 0x94b527ce; break;
296   case irm_F:
297     /* quick & dirty */
298     { union { float f; unsigned u; } u;
299       assert (sizeof (float) <= sizeof (unsigned));
300       u.u = 0; u.f = tv->u.F;
301       h ^= u.u;
302       break;
303     }
304   case irm_D:
305     /* quick & dirty */
306     { union { double d; unsigned u[2]; } u;
307       assert (sizeof (double) <= 2*sizeof (unsigned));
308       u.u[0] = u.u[1] = 0; u.d = tv->u.D;
309       h ^= u.u[0] ^ u.u[1];
310       break;
311     }
312   case irm_E:
313     { union { long double e; unsigned u[3]; } u;
314       assert (sizeof (long double) <= 3*sizeof (unsigned));
315       u.u[0] = u.u[1] = u.u[2] = 0; u.e = tv->u.E;
316       h ^= u.u[0] ^ u.u[1] ^ u.u[2];
317       break;
318     }
319   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
320     h ^= tv->u.uInt; break;
321   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
322     h ^= tv->u.sInt; break;
323   case irm_C:
324     h ^= tv->u.C; break;
325   case irm_U:
326     h ^= tv->u.U; break;
327   case irm_P:
328     if (tv->u.P.ent) {
329       /* @@@ lower bits not random, watch for collisions; perhaps
330          replace by tv->u.p.ent - (entity *)0 */
331       h ^= ((char *)tv->u.P.ent - (char *)0) / 64;
332     } else if (tv->u.P.xname) {
333       /* Of course, strlen() in a hash function is a mistake, but this
334          case should be really rare.  */
335       h ^= ID_HASH (tv->u.P.xname, strlen (tv->u.P.xname));
336     } else {                    /* void */
337       h^= 0x2b592b88;
338     }
339     break;
340   case irm_b:
341     h ^= tv->u.b; break;
342   default:
343     assert(0);
344   }
345   return h;
346 }
347
348
349 /*** ***************** Initialization ************************************* ***/
350
351 void
352 tarval_init_1 (void)
353 {
354   obstack_init (&tv_obst);
355   obstack_alignment_mask (&tv_obst) = ALIGNOF (tarval) - 1;
356   assert (IS_POW2 (ALIGNOF (tarval)));
357
358   /* initialize the target value table */
359   tarvals = new_pset (tarval_cmp, TUNE_NCONSTANTS);
360 }
361
362 void
363 tarval_init_2 (void)
364 {
365   tarval *tv;
366   union ieee754_double x;
367
368   /* assumed by tarval_hash(): */
369   assert (sizeof (float) * CHAR_BIT == 32);
370   assert (sizeof (double) * CHAR_BIT == 64);
371
372 # if 0
373   /* assumed by tarval_sInt & friends: */
374   assert (   (irm_C == irm_c+1) && (irm_h == irm_C+1)
375           && (irm_H == irm_h+1) && (irm_i == irm_H+1)
376           && (irm_I == irm_i+1) && (irm_l == irm_I+1)
377           && (irm_L == irm_l+1));
378
379   /* assumed everywhere: */
380   for (i = 0;  i <= irm_L-irm_c;  i += 2) {
381     assert (   IS_POW2 (max_sInt[i+1]+1)
382             && (min_sInt[i] == -max_sInt[i]-1)
383             && ((tarval_uInt)max_sInt[i+1] == (tarval_uInt)max_sInt[i]-min_sInt[i]));
384   }
385 # endif
386
387
388   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
389   tv->mode = mode_T;
390   tarval_bad = tarval_identify (tv);
391
392   tarval_b_false = tarval_from_long (mode_b, 0);
393   tarval_b_true = tarval_from_long (mode_b, 1);
394
395   /* IsInf <-> exponent == 0x7ff && ! (bits | fraction_low) */
396   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
397   tv->mode = mode_D;
398   x.ieee.negative = 0;
399   x.ieee.exponent = 0x7ff;
400   x.ieee.mantissa0 = 0;
401   x.ieee.mantissa1 = 0;
402   tv->u.D = x.d;
403   tarval_D_Inf = tarval_identify (tv);
404
405   /* IsNaN <-> exponent==0x7ff  && (qnan_bit | bits | fraction_low) */
406   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
407   tv->mode = mode_D;
408   x.ieee_nan.negative = 0;
409   x.ieee_nan.exponent = 0x7ff;
410   x.ieee_nan.quiet_nan = 1;     /* @@@ quiet or signalling? */
411   x.ieee_nan.mantissa0 = 42;
412   x.ieee_nan.mantissa1 = 0;
413   assert(x.d != x.d /* x.d is NaN */);
414   tv->u.D = x.d;
415   tarval_D_NaN = tarval_identify (tv);
416
417   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
418   tv->mode = mode_P;
419   tv->u.P.xname = NULL;
420   tv->u.P.ent = NULL;
421   tv->u.P.tv = NULL;
422   tarval_P_void = tarval_identify (tv);
423
424   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
425
426
427   tarval_mode_null [irm_F] = tarval_from_long (mode_F, 0);
428   tarval_mode_null [irm_D] = tarval_from_long (mode_D, 0);
429   tarval_mode_null [irm_E] = tarval_from_long (mode_E, 0);
430   tarval_mode_null [irm_Bs] = tarval_from_long (mode_Bs, 0);
431   tarval_mode_null [irm_Bu] = tarval_from_long (mode_Bu, 0);
432   tarval_mode_null [irm_Hs] = tarval_from_long (mode_Hs, 0);
433   tarval_mode_null [irm_Hu] = tarval_from_long (mode_Hu, 0);
434   tarval_mode_null [irm_Is] = tarval_from_long (mode_Is, 0);
435   tarval_mode_null [irm_Iu] = tarval_from_long (mode_Iu, 0);
436   tarval_mode_null [irm_Ls] = tarval_from_long (mode_Ls, 0);
437   tarval_mode_null [irm_Lu] = tarval_from_long (mode_Lu, 0);
438   tarval_mode_null [irm_C] = tarval_from_long (mode_C, 0);
439   tarval_mode_null [irm_U] = tarval_from_long (mode_U, 0);
440   tarval_mode_null [irm_b] = tarval_b_false;
441   tarval_mode_null [irm_P] = tarval_P_void;
442 }
443
444
445 /*** ********************** Constructors for tarvals ********************** ***/
446
447 /* copy from src to dst len chars omitting '_'. */
448 static char *
449 stripcpy (char *dst, const char *src, size_t len)
450 {
451   char *d = dst;
452
453   while (len--) {
454     if (*src == '_') src++;
455     else *d++ = *src++;
456   }
457   *d = 0;                       /* make it 0-terminated. */
458
459   return dst;
460 }
461
462 tarval *
463 tarval_F_from_str (const char *s, size_t len)
464 {
465   tarval *tv;
466   char *buf;
467   char *eptr;
468
469   assert (!BUILDING);
470
471   buf = alloca (len+1);
472   stripcpy (buf, s, len);
473
474   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
475   tv->mode = mode_F;
476   tv->u.F = (float)strtod (buf, &eptr);
477   assert (eptr == buf+strlen(buf));
478
479   return tarval_identify (tv);
480 }
481
482
483 tarval *
484 tarval_D_from_str (const char *s, size_t len)
485 {
486   tarval *tv;
487   char *buf;
488   char *eptr;
489
490   assert (!BUILDING);
491
492   buf = alloca (len+1);
493   stripcpy (buf, s, len);
494
495   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
496   tv->mode = mode_D;
497   tv->u.D = strtod (buf, &eptr);
498   assert (eptr == buf+strlen(buf));
499
500   return tarval_identify (tv);
501 }
502
503 tarval *
504 tarval_int_from_str (const char *s, size_t len, int base, ir_mode *m)
505 {
506   long val;
507   char *eptr;
508   char *buf;
509
510   assert (mode_is_int(m));
511   assert (!BUILDING);
512
513   buf = alloca (len+1);
514   stripcpy (buf, s, len);
515
516   errno = 0;
517   val = strtol(buf, &eptr, base);    /* strtoll */
518   assert (eptr == buf+strlen(buf));
519   if ((errno == ERANGE)               &&
520       ((m == mode_Ls) || (m == mode_Lu))  ) {
521     printf("WARNING: Constant %s not representable. Continuing with %ld.\n",
522            s, val);
523   }
524
525   return tarval_from_long(m, val);
526 }
527
528 /* Create a tarval with mode `m' and value `val' casted to the type that
529    represents such tarvals on host.  The resulting value must be legal
530    for mode `m'.  */
531 tarval *
532 tarval_from_long (ir_mode *m, long val)
533 {
534   tarval *tv;
535
536   assert (!BUILDING);
537
538   if (m == mode_T) return tarval_bad;
539
540   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
541
542   tv->mode = m;
543   switch (get_mode_modecode(m)) {
544     /* floating */
545   case irm_F:
546     tv->u.F = val; break;
547   case irm_D:
548     tv->u.D = val; break;
549   case irm_E:
550     /* @@@ not yet implemented */
551     break;
552     /* unsigned */
553   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
554     tv->u.uInt = val; break;
555     /* signed */
556   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
557     tv->u.sInt = val; break;
558   case irm_P:
559     assert(!val);
560     obstack_free (&tv_obst, tv);
561     return tarval_P_void;
562   case irm_C:
563     tv->u.C = val; break;
564   case irm_U:
565     tv->u.U = val; break;
566   case irm_b:
567     tv->u.b = !!val;            /* u.b must be 0 or 1 */
568     break;
569   default:
570     assert(0);
571   }
572
573   return tarval_identify (tv);
574 }
575
576
577 tarval *
578 tarval_P_from_str (const char *xname)
579 {
580   tarval *tv;
581
582   assert (!BUILDING);
583
584   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
585
586   tv->mode = mode_P;
587   tv->u.P.xname = obstack_copy0 (&tv_obst, xname, strlen (xname));
588   tv->u.P.ent = NULL;
589   tv->u.P.tv = NULL;
590   return tarval_identify (tv);
591 }
592
593
594 tarval *
595 tarval_P_from_entity (entity *ent)
596 {
597   tarval *tv;
598
599   assert (!BUILDING);
600
601   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
602
603   tv->mode = mode_P;
604   tv->u.P.xname = NULL;
605   tv->u.P.ent = ent;
606   tv->u.P.tv = NULL;
607   return tarval_identify (tv);
608 }
609
610
611 /* Routines for building a tarval step by step follow.
612    Legal calling sequences:
613      tarval_start()
614      No constructors except tarval_append() and tarval_append1 ()
615      tarval_finish_as() or tarval_cancel() */
616
617 /* Begin building a tarval.  */
618 void
619 tarval_start (void)
620 {
621   assert (!BUILDING);
622   obstack_blank (&tv_obst, sizeof (tarval));
623 }
624
625
626 /* Append `n' chars from `p' to the tarval currently under construction.  */
627 void
628 tarval_append (const char *p, size_t n)
629 {
630   assert (BUILDING);
631   obstack_grow (&tv_obst, p, n);
632 }
633
634
635 /* Append `ch' to the tarval currently under construction.  */
636 void
637 tarval_append1 (char ch)
638 {
639   assert (BUILDING);
640   obstack_1grow (&tv_obst, ch);
641 }
642
643
644 /* Finish the tarval currently under construction and give id mode `m'.
645    `m' must be irm_Bu,
646    Return NULL if the value does not make sense for this mode, this
647    can only happen in mode C.  */
648 tarval *
649 tarval_finish_as (ir_mode *m)
650 {
651   int size = obstack_object_size (&tv_obst) - sizeof (tarval);
652   tarval *tv;
653   unsigned char *p;
654   char ch = 0;                  /* initialized to shut up gcc */
655
656   assert (BUILDING && (size >= 0));
657   if (m == mode_Bu) {
658     if (size != 1) return tarval_cancel();
659     p = (unsigned char *)obstack_base (&tv_obst) + sizeof (tarval);
660     ch = *p;
661     obstack_blank (&tv_obst, -size);
662   }
663   tv = obstack_finish (&tv_obst);
664   p = (unsigned char *)tv + sizeof (tarval);
665   tv->mode = m;
666
667   switch (get_mode_modecode(m)) {
668   case irm_Bu:
669     tv->u.uInt = ch;
670     break;
671   case irm_P:
672     tv->u.P.tv = NULL;
673     break;
674   default:
675     assert (0);
676   }
677
678   return tarval_identify (tv);
679 }
680
681
682 /* Cancel tarval building and return tarval_bad.  */
683 tarval *
684 tarval_cancel (void)
685 {
686   assert (BUILDING);
687   obstack_free (&tv_obst, obstack_finish (&tv_obst));
688   return tarval_bad;
689 }
690
691
692 /*** ****************** Arithmethic operations on tarvals ***************** ***/
693
694 /* Return `src' converted to mode `m' if representable, else NULL.
695    @@@ lots of conversions missing */
696 tarval *
697 tarval_convert_to (tarval *src, ir_mode *m)
698 {
699   tarval *tv;
700
701   if (m == src->mode) return src;
702
703   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
704   tv->mode = m;
705
706   switch (get_mode_modecode(src->mode)) {
707
708   case irm_D:
709     if (m != mode_F) goto fail;
710     tv->u.F = src->u.D;
711     break;
712
713   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
714     switch (get_mode_modecode(m)) {
715     case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
716       tv->u.sInt = src->u.sInt;
717       if (sInt_overflow (tv->u.sInt, m)) goto fail;
718       break;
719
720     case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
721       tv->u.uInt = src->u.sInt;
722       if (uInt_overflow (tv->u.uInt, m)) goto fail;
723       break;
724
725     case irm_b:
726       tv->u.b = !!src->u.sInt;
727       break;
728
729     default: goto fail;
730     }
731
732   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
733     switch (get_mode_modecode(m)) {
734     case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
735       tv->u.sInt = src->u.uInt;
736       if (sInt_overflow (tv->u.sInt, m)) goto fail;
737       break;
738
739     case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
740       tv->u.uInt = src->u.uInt;
741       if (uInt_overflow (tv->u.uInt, m)) goto fail;
742       break;
743
744     case irm_b:
745       tv->u.b = !!src->u.uInt;
746       break;
747
748     default: goto fail;
749     }
750     break;
751
752   case irm_b:
753     switch (get_mode_modecode(m)) {
754     case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
755       tv->u.sInt = src->u.b;
756       break;
757
758     case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
759       tv->u.uInt = src->u.b;
760
761     default: goto fail;
762     }
763     break;
764
765   default:
766   fail:
767     obstack_free (&tv_obst, tv);
768     return NULL;
769   }
770
771   return tarval_identify (tv);
772 }
773
774
775 /* GL Why are there no ArmRoq comments, why is this not used? */
776 tarval *
777 tarval_neg (tarval *a)
778 {
779   tarval *tv;
780
781   TARVAL_VRFY (a);
782
783   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
784
785   tv->mode = a->mode;
786
787   switch (get_mode_modecode(a->mode)) {
788     /* floating */
789   case irm_F: tv->u.F = -a->u.F; break;
790   case irm_D: tv->u.D = -a->u.D; break;
791     /* unsigned */
792   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
793     tv->u.uInt = -a->u.uInt & tv_val_uInt (get_mode_max(a->mode));
794     break;
795     /* signed */
796   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
797     tv->u.sInt = -a->u.sInt;
798     if (   sInt_overflow (tv->u.sInt, a->mode)
799         || ((tv->u.sInt >= 0) == (a->u.sInt >= 0))) {
800       obstack_free (&tv_obst, tv);
801       return NULL;
802     }
803     break;
804   case irm_b: tv->u.b = !a->u.b; break;
805   default: assert(0);
806   }
807
808   return tarval_identify (tv);
809 }
810
811
812 /* Compare `a' with `b'.
813    Return one of irpn_Lt, irpn_Eq, irpn_Gt, irpn_Uo, or irpn_False if
814    result is unknown.  */
815 ir_pncmp
816 tarval_comp (tarval *a, tarval *b)
817 {
818
819   TARVAL_VRFY (a);
820   TARVAL_VRFY (b);
821
822   assert (a->mode == b->mode);
823
824   switch (get_mode_modecode(a->mode)) {
825     /* floating */
826   case irm_F: return (  a->u.F == b->u.F ? irpn_Eq
827                       : a->u.F > b->u.F ? irpn_Gt
828                       : a->u.F < b->u.F ? irpn_Lt
829                       : irpn_Uo);
830   case irm_D: return (  a->u.D == b->u.D ? irpn_Eq
831                       : a->u.D > b->u.D ? irpn_Gt
832                       : a->u.D < b->u.D ? irpn_Lt
833                       : irpn_Uo);
834   case irm_E: return (  a->u.E == b-> u.E ? irpn_Eq
835               : a->u.E > b->u.E ? irpn_Gt
836               : a->u.E < b->u.E ? irpn_Lt
837               : irpn_Uo);
838     /* unsigned */
839   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
840     return (  a->u.uInt == b->u.uInt ? irpn_Eq
841             : a->u.uInt > b->u.uInt ? irpn_Gt
842             : irpn_Lt);
843     /* signed */
844   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
845     return (  a->u.sInt == b->u.sInt ? irpn_Eq
846             : a->u.sInt > b->u.sInt ? irpn_Gt
847             : irpn_Lt);
848   case irm_b: return (  a->u.b == b->u.b ? irpn_Eq
849                       : a->u.b > b->u.b ? irpn_Gt
850                       : irpn_Lt);
851   /* The following assumes that pointers are unsigned, which is valid
852      for all sane CPUs (transputers are insane). */
853   case irm_P: return (  a == b ? irpn_Eq
854                       : a == tarval_P_void ? irpn_Lt
855                       : b == tarval_P_void ? irpn_Gt
856                       : irpn_False); /* unknown */
857   default: assert (0);
858   }
859 }
860
861
862 /* Return `a+b' if computable, else NULL.  Modes must be equal.  */
863 tarval *
864 tarval_add (tarval *a, tarval *b)
865 {
866   tarval *tv;
867
868   TARVAL_VRFY (a); TARVAL_VRFY (b);
869   assert (a->mode == b->mode);
870
871   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
872
873   tv->mode = a->mode;
874
875   switch (get_mode_modecode(a->mode)) {
876     /* floating */
877   case irm_F: tv->u.F = a->u.F + b->u.F; break; /* @@@ overflow etc */
878   case irm_D: tv->u.D = a->u.D + b->u.D; break; /* @@@ dto. */
879   case irm_E: tv->u.E = a->u.E + b->u.E; break; /* @@@ dto. */
880     /* unsigned */
881   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
882     tv->u.uInt = (a->u.uInt + b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
883     break;
884     /* signed */
885   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
886     tv->u.sInt = a->u.sInt + b->u.sInt;
887     if (   sInt_overflow (tv->u.sInt, a->mode)
888         || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt > 0))) {
889       obstack_free (&tv_obst, tv);
890       return NULL;
891     }
892     break;
893   case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
894   default: assert(0);
895   }
896
897   return tarval_identify (tv);
898 }
899
900
901 /* Return `a-b' if computable, else NULL.  Modes must be equal.  */
902 tarval *
903 tarval_sub (tarval *a, tarval *b)
904 {
905   tarval *tv;
906
907   TARVAL_VRFY (a); TARVAL_VRFY (b);
908   assert (a->mode == b->mode);
909
910   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
911
912   tv->mode = a->mode;
913
914   switch (get_mode_modecode(a->mode)) {
915     /* floating */
916   case irm_F: tv->u.F = a->u.F - b->u.F; break; /* @@@ overflow etc */
917   case irm_D: tv->u.D = a->u.D - b->u.D; break; /* @@@ dto. */
918   case irm_E: tv->u.E = a->u.E - b->u.E; break; /* @@@ dto. */
919     /* unsigned */
920   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
921     tv->u.uInt = (a->u.uInt - b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
922     break;
923     /* signed */
924   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
925     tv->u.sInt = a->u.sInt - b->u.sInt;
926     if (   sInt_overflow (tv->u.sInt, a->mode)
927         || ((tv->u.sInt > a->u.sInt) ^ (b->u.sInt < 0))) {
928       obstack_free (&tv_obst, tv);
929       return NULL;
930     }
931     break;
932   case irm_b: tv->u.b = a->u.b & ~b->u.b; break; /* u.b is in canonical form */
933   default: assert(0);
934   }
935
936   return tarval_identify (tv);
937 }
938
939 /* Return `a*b' if computable, else NULL.  Modes must be equal.  */
940 tarval *
941 tarval_mul (tarval *a, tarval *b)
942 {
943   tarval *tv;
944
945   TARVAL_VRFY (a); TARVAL_VRFY (b);
946   assert (a->mode == b->mode);
947
948   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
949
950   tv->mode = a->mode;
951
952   switch (get_mode_modecode(a->mode)) {
953     /* floating */
954   case irm_F: tv->u.F = a->u.F * b->u.F; break; /* @@@ overflow etc */
955   case irm_D: tv->u.D = a->u.D * b->u.D; break; /* @@@ dto. */
956   case irm_E: tv->u.E = a->u.E * b->u.E; break; /* @@@ dto. */
957     /* unsigned */
958   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
959     tv->u.uInt = (a->u.uInt * b->u.uInt) & tv_val_uInt (get_mode_max(a->mode));
960     break;
961     /* signed */
962   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
963     tv->u.sInt = a->u.sInt * b->u.sInt;
964     if (   sInt_overflow (tv->u.sInt, a->mode)
965         || (b->u.sInt && (tv->u.sInt / b->u.sInt != a->u.sInt))) {
966       obstack_free (&tv_obst, tv);
967       return NULL;
968     }
969     break;
970   case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
971   default: assert(0);
972   }
973
974   return tarval_identify (tv);
975 }
976
977
978 /* Return floating-point `a/b' if computable, else NULL.
979    Modes must be equal, non-floating-point operands are converted to irm_D.  */
980 tarval *
981 tarval_quo (tarval *a, tarval *b)
982 {
983   tarval *tv;
984
985   TARVAL_VRFY (a); TARVAL_VRFY (b);
986   assert (a->mode == b->mode);
987
988   switch (get_mode_modecode(a->mode)) {
989     /* floating */
990   case irm_F:
991     tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
992     tv->mode = mode_F;
993     tv->u.F = a->u.F / b->u.F;  /* @@@ overflow etc */
994     break;
995   case irm_D:
996     tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
997     tv->mode = mode_D;
998     tv->u.D = a->u.D / b->u.D;  /* @@@ overflow etc */
999     break;
1000   default:
1001     a = tarval_convert_to (a, mode_D);
1002     b = tarval_convert_to (b, mode_D);
1003     return a && b ? tarval_quo (a, b) : NULL;
1004   }
1005
1006   return tarval_identify (tv);
1007 }
1008
1009
1010 /* Return `a/b' if computable, else NULL.  Modes must be equal.  */
1011 tarval *
1012 tarval_div (tarval *a, tarval *b)
1013 {
1014   tarval *tv;
1015
1016   TARVAL_VRFY (a); TARVAL_VRFY (b);
1017   assert (a->mode == b->mode);
1018
1019   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1020
1021   tv->mode = a->mode;
1022
1023   switch (get_mode_modecode(a->mode)) {
1024     /* floating */
1025   case irm_F: tv->u.F = floor (a->u.F / b->u.F); break; /* @@@ overflow etc */
1026   case irm_D: tv->u.D = floor (a->u.D / b->u.D); break; /* @@@ dto. */
1027   case irm_E: tv->u.E = floor (a->u.E / b->u.E); break; /* @@@ dto. */
1028     /* unsigned */
1029   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1030     if (!b->u.uInt) goto fail;
1031     tv->u.uInt = a->u.uInt / b->u.uInt;
1032     break;
1033     /* signed */
1034   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1035     if (   !b->u.sInt
1036         || ((b->u.sInt == -1) && (a->u.sInt == tv_val_sInt (get_mode_max(a->mode)) ))) {
1037     fail:
1038       obstack_free (&tv_obst, tv);
1039       return NULL;
1040     }
1041     tv->u.sInt = a->u.sInt / b->u.sInt;
1042     break;
1043   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1044   default: assert(0);
1045   }
1046
1047   return tarval_identify (tv);
1048 }
1049
1050
1051 /* Return `a%b' if computable, else NULL.  Modes must be equal.  */
1052 tarval *
1053 tarval_mod (tarval *a, tarval *b)
1054 {
1055   tarval *tv;
1056
1057   TARVAL_VRFY (a); TARVAL_VRFY (b);
1058   assert (a->mode == b->mode);
1059
1060   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1061
1062   tv->mode = a->mode;
1063
1064   switch (get_mode_modecode(a->mode)) {
1065     /* floating */
1066   case irm_F: tv->u.F = fmod (a->u.F, b->u.F); break; /* @@@ overflow etc */
1067   case irm_D: tv->u.D = fmod (a->u.D, b->u.D); break; /* @@@ dto */
1068   case irm_E: tv->u.E = fmod (a->u.E, b->u.E); break; /* @@@ dto. */
1069     /* unsigned */
1070   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1071     if (!b->u.uInt) goto fail;
1072     tv->u.uInt = a->u.uInt % b->u.uInt;
1073     break;
1074     /* signed */
1075   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1076     if (!b->u.sInt) {
1077     fail:
1078       obstack_free (&tv_obst, tv);
1079       return NULL;
1080     }
1081     tv->u.sInt = a->u.sInt % b->u.sInt;
1082     break;
1083   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1084   default: assert(0);
1085   }
1086
1087   return tarval_identify (tv);
1088 }
1089
1090 /* Return |a| if computable, else Null. */
1091 /*  is -max == min?? */
1092 tarval *
1093 tarval_abs (tarval *a) {
1094   TARVAL_VRFY (a);
1095   if (tv_is_negative(a)) return tarval_neg(a);
1096   return a;
1097 }
1098
1099 int
1100 tv_is_negative(tarval *a) {
1101   TARVAL_VRFY (a);
1102   switch (get_mode_modecode(a->mode)) {
1103     /* floating */
1104   case irm_F: return (a->u.F<0);
1105   case irm_D: return (a->u.D<0);
1106   case irm_E: return (a->u.E<0);
1107     /* unsigned */
1108   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1109     return 0;
1110     break;
1111     /* signed */
1112   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1113     return (a->u.sInt < 0);
1114     break;
1115   case irm_b: break;
1116   default: assert(0);
1117   }
1118
1119   return 0;
1120 }
1121
1122
1123 /* Return `a&b'.  Modes must be equal.  */
1124 tarval *
1125 tarval_and (tarval *a, tarval *b)
1126 {
1127   tarval *tv;
1128
1129   TARVAL_VRFY (a); TARVAL_VRFY (b);
1130   assert (a->mode == b->mode);
1131
1132   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1133
1134   tv->mode = a->mode;
1135
1136   switch (get_mode_modecode(a->mode)) {
1137     /* unsigned */
1138   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1139     tv->u.uInt = a->u.uInt & b->u.uInt; break;
1140     /* signed */
1141   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1142     tv->u.sInt = a->u.sInt & b->u.sInt; break;
1143   case irm_b: tv->u.b = a->u.b & b->u.b; break; /* u.b is in canonical form */
1144   default: assert(0);
1145   }
1146
1147   return tarval_identify (tv);
1148 }
1149
1150
1151 /* Return `a|b'.  Modes must be equal.  */
1152 tarval *
1153 tarval_or (tarval *a, tarval *b)
1154 {
1155   tarval *tv;
1156
1157   TARVAL_VRFY (a); TARVAL_VRFY (b);
1158   assert (a->mode == b->mode);
1159
1160   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1161
1162   tv->mode = a->mode;
1163
1164   switch (get_mode_modecode(a->mode)) {
1165     /* unsigned */
1166   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1167     tv->u.uInt = a->u.uInt | b->u.uInt; break;
1168     /* signed */
1169   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1170     tv->u.sInt = a->u.sInt | b->u.sInt; break;
1171   case irm_b: tv->u.b = a->u.b | b->u.b; break; /* u.b is in canonical form */
1172   default: assert(0);
1173   }
1174
1175   return tarval_identify (tv);
1176 }
1177
1178
1179 /* Return `a^b'.  Modes must be equal.  */
1180 tarval *
1181 tarval_eor (tarval *a, tarval *b)
1182 {
1183   tarval *tv;
1184
1185   TARVAL_VRFY (a); TARVAL_VRFY (b);
1186   assert (a->mode == b->mode);
1187
1188   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1189
1190   tv->mode = a->mode;
1191
1192   switch (get_mode_modecode(a->mode)) {
1193     /* unsigned */
1194   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1195     tv->u.uInt = a->u.uInt ^ b->u.uInt; break;
1196     /* signed */
1197   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1198     tv->u.sInt = a->u.sInt ^ b->u.sInt; break;
1199   case irm_b: tv->u.b = a->u.b ^ b->u.b; break; /* u.b is in canonical form */
1200   default: assert(0);
1201   }
1202
1203   return tarval_identify (tv);
1204 }
1205
1206
1207 /* Return `a<<b' if computable, else NULL.  */
1208 tarval *
1209 tarval_shl (tarval *a, tarval *b)
1210 {
1211   int b_is_huge;
1212   long shift;
1213   tarval *tv;
1214
1215   TARVAL_VRFY (a); TARVAL_VRFY (b);
1216
1217   shift = tarval_ord (b, &b_is_huge);
1218   if (   b_is_huge
1219       || (shift < 0)
1220       || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
1221     return NULL;
1222   }
1223
1224   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1225   tv->mode = a->mode;
1226
1227   switch (get_mode_modecode(a->mode)) {
1228     /* unsigned */
1229   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1230     tv->u.uInt = a->u.uInt << shift;
1231     break;
1232     /* signed */
1233   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1234     tv->u.sInt = a->u.sInt << shift;
1235     break;
1236   default: assert (0);
1237   }
1238
1239   return tarval_identify (tv);
1240 }
1241
1242
1243 /* Return `a>>b' if computable, else NULL.
1244    The interpretation of >> (sign extended or not) is implementaion
1245    dependent, i.e. this is neither shr nor shrs!! */
1246 tarval *
1247 tarval_shr (tarval *a, tarval *b)
1248 {
1249   int b_is_huge;
1250   long shift;
1251   tarval *tv;
1252
1253   TARVAL_VRFY (a); TARVAL_VRFY (b);
1254
1255   shift = tarval_ord (b, &b_is_huge);
1256   if (   b_is_huge
1257       || (shift < 0)
1258       || ((shift >= get_mode_size(mode_Ls)*target_bits))) {
1259     return NULL;
1260   }
1261
1262   tv = (tarval *)obstack_alloc (&tv_obst, sizeof (tarval));
1263   tv->mode = a->mode;
1264
1265   switch (get_mode_modecode(a->mode)) {
1266     /* unsigned */
1267   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1268     tv->u.uInt = a->u.uInt >> shift;
1269     break;
1270     /* signed */
1271   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1272     tv->u.sInt = a->u.sInt >> shift;
1273     break;
1274   default: assert (0);
1275   }
1276
1277   return tarval_identify (tv);
1278 }
1279
1280
1281 /* Classify `tv', which may be NULL.
1282    Return 0 if `tv' is the additive neutral element, 1 if `tv' is the
1283    multiplicative neutral element, and -1 if `tv' is the neutral
1284    element of bitwise and.  */
1285 long
1286 tarval_classify (tarval *tv)
1287 {
1288   if (!tv) return 2;
1289
1290   TARVAL_VRFY (tv);
1291
1292   switch (get_mode_modecode(tv->mode)) {
1293     /* floating */
1294   case irm_F: case irm_D: case irm_E:
1295     return 2;
1296     /* unsigned */
1297   case irm_Bu:
1298     return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Bu))) - 1;
1299   case irm_Hu:
1300     return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Hu))) - 1;
1301   case irm_Iu:
1302     return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Iu))) - 1;
1303   case irm_Lu:
1304     return (long)((tv->u.uInt+1) & tv_val_uInt (get_mode_max(mode_Lu))) - 1;
1305     /* signed */
1306   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1307     return tv->u.sInt;
1308   case irm_b:
1309     return tv->u.b;
1310   default:
1311     return 2;
1312   }
1313 }
1314
1315 /* Convert `tv' into type `long', set `fail' if not representable.
1316    If `fail' gets set for an unsigned `tv', the correct result can be
1317    obtained by casting the result to `unsigned long'.  */
1318 long
1319 tarval_ord (tarval *tv, int *fail)
1320 {
1321   TARVAL_VRFY (tv);
1322
1323   switch (get_mode_modecode(tv->mode)) {
1324     /* unsigned */
1325   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu:
1326     *fail = tv->u.uInt > tv_val_uInt (get_mode_max(mode_Ls));
1327     return tv->u.uInt;
1328     /* signed */
1329   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls:
1330     *fail = 0;
1331     return tv->u.sInt;
1332   case irm_b:
1333     *fail = 0;
1334     return tv->u.b;
1335   default: ;
1336     *fail = 1;
1337     return 0;
1338   }
1339 }
1340
1341 int
1342 tarval_print (XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN)
1343 {
1344   tarval *val = XP_GETARG (tarval *, 0);
1345   int printed;
1346   char buf[40];
1347
1348   TARVAL_VRFY (val);
1349
1350   switch (get_mode_modecode(val->mode)) {
1351
1352   case irm_T:                   /* none */
1353     printed = XPSR ("<bad>");
1354     break;
1355
1356   case irm_F:                   /* float */
1357     sprintf (buf, "%1.9e", (float)(val->u.F));
1358     printed = XPF1R ("%s", buf);
1359     break;
1360   case irm_D:                   /* double */
1361     printed = XPF1R ("%1.30g", (double)(val->u.D));
1362     break;
1363
1364   case irm_C:           /* character */
1365     if ((isprint (val->u.C)) &&
1366         (val->u.C != '\\')   && (val->u.C != '\'')) {
1367       printed = XPF1R ("'%c'", val->u.C);
1368     } else {
1369       printed = XPF1R ("0x%x", (unsigned long)val->u.C);
1370     }
1371     break;
1372   case irm_U:           /* unicode character */
1373       printed = XPF1R ("0x%x", (unsigned long)val->u.U);
1374     break;
1375
1376   case irm_Bs: case irm_Hs: case irm_Is: case irm_Ls: /* signed num */
1377     printed = XPF1R ("%ld", (long)val->u.sInt);
1378     break;
1379   case irm_Bu: case irm_Hu: case irm_Iu: case irm_Lu: /* unsigned num */
1380     printed = XPF1R ("%lu", (unsigned long)val->u.uInt);
1381     break;
1382
1383   case irm_P:                   /* pointer */
1384     if (val->u.P.xname) {
1385       printed = XPR (val->u.P.xname);
1386     } else if (val->u.P.ent) {
1387       if (get_entity_peculiarity(val->u.P.ent) == existent)
1388         printed = XPF1R ("&(%I)", get_entity_ld_ident(val->u.P.ent));
1389       else
1390         printed = XPSR ("(NULL)");
1391     } else {
1392       assert (val == tarval_P_void);
1393       printed = XPSR ("(void)");
1394     }
1395     break;
1396
1397   case irm_b:                   /* boolean */
1398     if (val->u.b) printed = XPSR ("true");
1399     else          printed = XPSR ("false");
1400     break;
1401
1402   case irm_M:                   /* memory */
1403   case irm_BB:                  /* region */
1404   default:
1405     assert (0);
1406   }
1407
1408   return printed;
1409 }
1410
1411
1412 ir_mode *
1413 get_tv_mode (tarval *tv)
1414 {
1415   return tv->mode;
1416 }
1417
1418 /* Returns the entity if the tv is a pointer to an entity, else
1419    returns NULL; */
1420 entity *get_tv_entity(tarval *tv) {
1421   entity *ent = NULL;
1422
1423   if (tv->mode == mode_P) {
1424     if (tv->u.P.xname) {
1425       assert(0);
1426       /* not an entity */
1427     } else if (tv->u.P.ent) {
1428       ent = tv->u.P.ent;
1429     } else {
1430       /* not an entity */
1431     }
1432   }
1433   return ent;
1434 }