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