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