added a firm_kind field
[libfirm] / ir / tv / tv.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/tv/tv.c
4  * Purpose:     Representation of and static computations on target machine
5  *              values.
6  * Author:      Mathias Heil
7  * Modified by:
8  * Created:
9  * CVS-ID:      $Id$
10  * Copyright:   (c) 2003 Universität Karlsruhe
11  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
12  */
13
14 /*
15  *    Values are stored in a format depending upon chosen arithmetic
16  *    module. Default uses strcalc and fltcalc.
17  *
18  */
19
20 /* This implementation assumes:
21  *  - target has IEEE-754 floating-point arithmetic.  */
22
23
24 #ifdef HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28
29 #include <assert.h>         /* assertions */
30 #include <stdlib.h>         /* atoi() */
31 #ifdef HAVE_STRING_H
32 # include <string.h>         /* nice things for strings */
33 #endif
34 #ifdef HAVE_STRINGS_H
35 #include <strings.h>        /* strings.h also includes bsd only function strcasecmp */
36 #endif
37 #ifdef HAVE_STDLIB_H
38 # include <stdlib.h>
39 #endif
40 #ifdef HAVE_ALLOCA_H
41 # include <alloca.h>
42 #endif
43 #ifdef HAVE_MALLOC_H
44 # include <malloc.h>
45 #endif
46
47 #include "tv_t.h"
48 #include "set.h"            /* to store tarvals in */
49 #include "entity_t.h"       /* needed to store pointers to entities */
50 #include "irmode_t.h"
51 #include "irnode.h"         /* defines boolean return values (pnc_number)*/
52 #include "strcalc.h"
53 #include "fltcalc.h"
54 #include "irtools.h"
55
56 /** Size of hash tables.  Should correspond to average number of distinct constant
57     target values */
58 #define N_CONSTANTS 2048
59
60 /* get the integer overflow mode */
61 #define GET_OVERFLOW_MODE() int_overflow_mode
62
63 /* unused, float to int doesn't work yet */
64 enum float_to_int_mode {
65   TRUNCATE,
66   ROUND
67 };
68
69 #define GET_FLOAT_TO_INT_MODE() TRUNCATE
70
71 #define SWITCH_NOINFINITY 0
72 #define SWITCH_NODENORMALS 0
73
74 /****************************************************************************
75  *   local definitions and macros
76  ****************************************************************************/
77 #ifndef NDEBUG
78 #  define TARVAL_VERIFY(a) tarval_verify((a))
79 #else
80 #  define TARVAL_VERIFY(a) ((void)0)
81 #endif
82
83 #define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
84 #define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
85
86 #define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
87 #define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
88
89 #define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
90 #if 0
91 static long long count = 0;
92 #  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__);
93 #else
94 #  define ANNOUNCE() ((void)0)
95 #endif
96 /****************************************************************************
97  *   private variables
98  ****************************************************************************/
99 static struct set *tarvals;   /* container for tarval structs */
100 static struct set *values;    /* container for values */
101 static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
102
103 /****************************************************************************
104  *   private functions
105  ****************************************************************************/
106 #ifndef NDEBUG
107 static int hash_val(const void *value, unsigned int length);
108 static int hash_tv(tarval *tv);
109 static void _fail_verify(tarval *tv, const char* file, int line)
110 {
111   /* print a memory image of the tarval and throw an assertion */
112   if (tv)
113     printf("%s:%d: Invalid tarval:\n  mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
114   else
115     printf("%s:%d: Invalid tarval (null)", file, line);
116   assert(0);
117 }
118 #ifdef __GNUC__
119 INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
120 #endif
121
122 INLINE static void tarval_verify(tarval *tv)
123 {
124   assert(tv);
125   assert(tv->mode);
126   assert(tv->value);
127
128   if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
129   if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
130
131   if (!FIND_TARVAL(tv)) fail_verify(tv);
132   if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
133
134   return;
135 }
136 #endif /* NDEBUG */
137
138 static int hash_tv(tarval *tv)
139 {
140   return (PTR_TO_INT(tv->value) ^ PTR_TO_INT(tv->mode)) + tv->length;
141 }
142
143 static int hash_val(const void *value, unsigned int length)
144 {
145   unsigned int i;
146   unsigned int hash = 0;
147
148   /* scramble the byte - array */
149   for (i = 0; i < length; i++)
150   {
151     hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
152     hash += (hash << 11) ^ (hash >> 17);
153   }
154
155   return hash;
156 }
157
158 /** finds tarval with value/mode or creates new tarval */
159 static tarval *get_tarval(const void *value, int length, ir_mode *mode)
160 {
161   tarval tv;
162
163   tv.kind   = k_tarval;
164   tv.mode   = mode;
165   tv.length = length;
166   if (length > 0) {
167     /* if there already is such a value, it is returned, else value
168      * is copied into the set */
169     tv.value = INSERT_VALUE(value, length);
170   } else {
171     tv.value = value;
172   }
173   /* if there is such a tarval, it is returned, else tv is copied
174    * into the set */
175   return (tarval *)INSERT_TARVAL(&tv);
176 }
177
178 /**
179  * handle overflow
180  */
181 static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
182 {
183   switch (get_mode_sort(mode))
184   {
185     case irms_int_number:
186       if (sc_comp(value, get_mode_max(mode)->value) == 1) {
187         switch (GET_OVERFLOW_MODE()) {
188           case TV_OVERFLOW_SATURATE:
189             return get_mode_max(mode);
190           case TV_OVERFLOW_WRAP:
191             {
192               char *temp = alloca(sc_get_buffer_length());
193               char *diff = alloca(sc_get_buffer_length());
194               sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
195               sc_val_from_ulong(1, temp);
196               sc_add(diff, temp, diff);
197               sc_sub(value, diff, temp);
198               while (sc_comp(temp, get_mode_max(mode)->value) == 1)
199                 sc_sub(temp, diff, temp);
200               return get_tarval(temp, length, mode);
201             }
202           case TV_OVERFLOW_BAD:
203             return tarval_bad;
204           default:
205             return get_tarval(value, length, mode);
206         }
207       }
208       if (sc_comp(value, get_mode_min(mode)->value) == -1) {
209         switch (GET_OVERFLOW_MODE()) {
210           case TV_OVERFLOW_SATURATE:
211             return get_mode_min(mode);
212           case TV_OVERFLOW_WRAP:
213             {
214               char *temp = alloca(sc_get_buffer_length());
215               char *diff = alloca(sc_get_buffer_length());
216               sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
217               sc_val_from_ulong(1, temp);
218               sc_add(diff, temp, diff);
219               sc_add(value, diff, temp);
220               while (sc_comp(temp, get_mode_max(mode)->value) == 1)
221                 sc_add(temp, diff, temp);
222               return get_tarval(temp, length, mode);
223             }
224           case TV_OVERFLOW_BAD:
225             return tarval_bad;
226           default:
227             return get_tarval(value, length, mode);
228         }
229       }
230       break;
231
232     case irms_float_number:
233       if (SWITCH_NOINFINITY && fc_is_inf(value))
234       {
235         return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
236       }
237
238       if (SWITCH_NODENORMALS && fc_is_subnormal(value))
239       {
240         return get_mode_null(mode);
241       }
242       break;
243     default:
244       break;
245   }
246   return get_tarval(value, length, mode);
247 }
248
249
250 /*
251  *   public variables declared in tv.h
252  */
253 static tarval reserved_tv[5];
254
255 tarval *tarval_bad       = &reserved_tv[0];
256 tarval *tarval_undefined = &reserved_tv[1];
257 tarval *tarval_b_false   = &reserved_tv[2];
258 tarval *tarval_b_true    = &reserved_tv[3];
259 tarval *tarval_P_void    = &reserved_tv[4];
260
261 /*
262  *   public functions declared in tv.h
263  */
264
265 /*
266  * Constructors =============================================================
267  */
268 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
269 {
270   ANNOUNCE();
271   assert(str);
272   assert(len);
273   assert(mode);
274
275   switch (get_mode_sort(mode))
276   {
277     case irms_control_flow:
278     case irms_memory:
279     case irms_auxiliary:
280       assert(0);
281       break;
282
283     case irms_internal_boolean:
284       /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
285       if (strcasecmp(str, "true")) return tarval_b_true;
286       else if (strcasecmp(str, "false")) return tarval_b_true;
287       else
288         /* XXX This is C semantics */
289     return atoi(str) ? tarval_b_true : tarval_b_false;
290
291     case irms_float_number:
292       switch(get_mode_size_bits(mode)) {
293         case 32:
294           fc_val_from_str(str, len, 8, 23, NULL);
295           break;
296         case 64:
297           fc_val_from_str(str, len, 11, 52, NULL);
298           break;
299         case 80:
300           fc_val_from_str(str, len, 15, 64, NULL);
301           break;
302       }
303       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
304
305     case irms_int_number:
306     case irms_character:
307       sc_val_from_str(str, len, NULL);
308       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
309
310     case irms_reference:
311       return get_tarval(str, len, mode);
312   }
313
314   assert(0);  /* can't be reached, can it? */
315   return NULL;
316 }
317
318 /*
319  * helper function, create a tarval from long
320  */
321 tarval *new_tarval_from_long(long l, ir_mode *mode)
322 {
323   ANNOUNCE();
324   assert(mode);
325
326   switch(get_mode_sort(mode))
327   {
328     case irms_internal_boolean:
329       /* XXX C semantics ! */
330       return l ? tarval_b_true : tarval_b_false ;
331
332     case irms_int_number:
333     case irms_character:
334       sc_val_from_long(l, NULL);
335       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
336
337     case irms_float_number:
338       return new_tarval_from_double((long double)l, mode);
339
340     case irms_reference:
341       return l ? tarval_bad : get_tarval(NULL, 0, mode);  /* null pointer or tarval_bad */
342
343     default:
344       assert(0 && "unsupported mode sort");
345   }
346   return NULL;
347 }
348
349 /* returns non-zero if can be converted to long */
350 int tarval_is_long(tarval *tv)
351 {
352   mode_sort sort = get_mode_sort(tv->mode);
353
354   ANNOUNCE();
355   if (sort != irms_int_number && sort != irms_character) return 0;
356
357   if (get_mode_size_bits(tv->mode) > sizeof(long)<<3)
358   {
359     /* the value might be too big to fit in a long */
360     sc_max_from_bits(sizeof(long)<<3, 0, NULL);
361     if (sc_comp(sc_get_buffer(), tv->value) == -1)
362     {
363       /* really doesn't fit */
364       return 0;
365     }
366   }
367   return 1;
368 }
369
370 /* this might overflow the machine's long, so use only with small values */
371 long get_tarval_long(tarval* tv)
372 {
373   ANNOUNCE();
374   assert(tarval_is_long(tv) && "tarval too big to fit in long");
375
376   return sc_val_to_long(tv->value);
377 }
378
379 tarval *new_tarval_from_double(long double d, ir_mode *mode)
380 {
381   ANNOUNCE();
382   assert(mode && (get_mode_sort(mode) == irms_float_number));
383
384   switch (get_mode_size_bits(mode)) {
385     case 32:
386       fc_val_from_float(d, 8, 23, NULL);
387       break;
388     case 64:
389       fc_val_from_float(d, 11, 52, NULL);
390       break;
391     case 80:
392       fc_val_from_float(d, 15, 64, NULL);
393       break;
394   }
395   return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
396 }
397
398 /* returns non-zero if can be converted to double */
399 int tarval_is_double(tarval *tv)
400 {
401   ANNOUNCE();
402   assert(tv);
403
404   return (get_mode_sort(tv->mode) == irms_float_number);
405 }
406
407 long double get_tarval_double(tarval *tv)
408 {
409   ANNOUNCE();
410   assert(tarval_is_double(tv));
411
412   return fc_val_to_float(tv->value);
413 }
414
415
416 /*
417  * Access routines for tarval fields ========================================
418  */
419
420 /* get the mode of the tarval */
421 ir_mode *(get_tarval_mode)(const tarval *tv) {
422   return _get_tarval_mode(tv);
423 }
424
425 /*
426  * Special value query functions ============================================
427  *
428  * These functions calculate and return a tarval representing the requested
429  * value.
430  * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
431  * functions, but these are stored on initialization of the irmode module and
432  * therefore the irmode functions should be prefered to the functions below.
433  */
434
435 tarval *(get_tarval_bad)(void) {
436   return _get_tarval_bad();
437 }
438
439 tarval *(get_tarval_undefined)(void) {
440   return _get_tarval_undefined();
441 }
442
443 tarval *(get_tarval_b_false)(void) {
444   return _get_tarval_b_false();
445 }
446
447 tarval *(get_tarval_b_true)(void) {
448   return _get_tarval_b_true();
449 }
450
451 tarval *(get_tarval_P_void)(void) {
452   return _get_tarval_P_void();
453 }
454
455 tarval *get_tarval_max(ir_mode *mode)
456 {
457   ANNOUNCE();
458   assert(mode);
459
460   if (get_mode_n_vector_elems(mode) > 1) {
461     /* vector arithmetic not implemented yet */
462     return tarval_bad;
463   }
464
465   switch(get_mode_sort(mode))
466   {
467     case irms_reference:
468     case irms_control_flow:
469     case irms_memory:
470     case irms_auxiliary:
471       assert(0);
472       break;
473
474     case irms_internal_boolean:
475       return tarval_b_true;
476
477     case irms_float_number:
478       switch(get_mode_size_bits(mode))
479       {
480         case 32:
481           fc_get_max(8, 23, NULL);
482           break;
483         case 64:
484           fc_get_max(11, 52, NULL);
485           break;
486         case 80:
487           fc_get_max(15, 64, NULL);
488           break;
489       }
490       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
491
492     case irms_int_number:
493     case irms_character:
494       sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
495       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
496   }
497   return tarval_bad;
498 }
499
500 tarval *get_tarval_min(ir_mode *mode)
501 {
502   ANNOUNCE();
503   assert(mode);
504
505   if (get_mode_n_vector_elems(mode) > 1) {
506     /* vector arithmetic not implemented yet */
507     return tarval_bad;
508   }
509
510   switch(get_mode_sort(mode))
511   {
512     case irms_reference:
513     case irms_control_flow:
514     case irms_memory:
515     case irms_auxiliary:
516       assert(0);
517       break;
518
519     case irms_internal_boolean:
520       return tarval_b_false;
521
522     case irms_float_number:
523       switch(get_mode_size_bits(mode))
524       {
525         case 32:
526           fc_get_min(8, 23, NULL);
527           break;
528         case 64:
529           fc_get_min(11, 52, NULL);
530           break;
531         case 80:
532           fc_get_min(15, 64, NULL);
533           break;
534       }
535       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
536
537     case irms_int_number:
538     case irms_character:
539       sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
540       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
541   }
542   return tarval_bad;
543 }
544
545 tarval *get_tarval_null(ir_mode *mode)
546 {
547   ANNOUNCE();
548   assert(mode);
549
550   if (get_mode_n_vector_elems(mode) > 1) {
551     /* vector arithmetic not implemented yet */
552     return tarval_bad;
553   }
554
555   switch(get_mode_sort(mode))
556   {
557     case irms_control_flow:
558     case irms_memory:
559     case irms_auxiliary:
560     case irms_internal_boolean:
561       assert(0);
562       break;
563
564     case irms_float_number:
565       return new_tarval_from_double(0.0, mode);
566
567     case irms_int_number:
568     case irms_character:
569       return new_tarval_from_long(0l,  mode);
570
571     case irms_reference:
572       return tarval_P_void;
573   }
574   return tarval_bad;
575 }
576
577 tarval *get_tarval_one(ir_mode *mode)
578 {
579   ANNOUNCE();
580   assert(mode);
581
582   if (get_mode_n_vector_elems(mode) > 1) {
583     /* vector arithmetic not implemented yet */
584     return tarval_bad;
585   }
586
587   switch(get_mode_sort(mode))
588   {
589     case irms_control_flow:
590     case irms_memory:
591     case irms_auxiliary:
592     case irms_internal_boolean:
593     case irms_reference:
594       assert(0);
595       break;
596
597     case irms_float_number:
598       return new_tarval_from_double(1.0, mode);
599
600     case irms_int_number:
601     case irms_character:
602       return new_tarval_from_long(1l, mode);
603       break;
604   }
605   return tarval_bad;
606 }
607
608 tarval *get_tarval_minus_one(ir_mode *mode)
609 {
610   ANNOUNCE();
611   assert(mode);
612
613   if (get_mode_n_vector_elems(mode) > 1) {
614     /* vector arithmetic not implemented yet */
615     return tarval_bad;
616   }
617
618   switch(get_mode_sort(mode))
619   {
620     case irms_control_flow:
621     case irms_memory:
622     case irms_auxiliary:
623     case irms_internal_boolean:
624     case irms_reference:
625       assert(0);
626       break;
627
628     case irms_float_number:
629       return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
630
631     case irms_int_number:
632     case irms_character:
633       return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
634   }
635   return tarval_bad;
636 }
637
638 tarval *get_tarval_nan(ir_mode *mode)
639 {
640   ANNOUNCE();
641   assert(mode);
642
643   if (get_mode_n_vector_elems(mode) > 1) {
644     /* vector arithmetic not implemented yet */
645     return tarval_bad;
646   }
647
648   if (get_mode_sort(mode) == irms_float_number) {
649     switch(get_mode_size_bits(mode))
650     {
651       case 32:
652         fc_get_qnan(8, 23, NULL);
653         break;
654       case 64:
655         fc_get_qnan(11, 52, NULL);
656         break;
657       case 80:
658         fc_get_qnan(15, 64, NULL);
659         break;
660     }
661     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
662   }
663   else {
664     assert(0 && "tarval is not floating point");
665     return tarval_bad;
666   }
667 }
668
669 tarval *get_tarval_plus_inf(ir_mode *mode)
670 {
671   ANNOUNCE();
672   assert(mode);
673
674   if (get_mode_n_vector_elems(mode) > 1) {
675     /* vector arithmetic not implemented yet */
676     return tarval_bad;
677   }
678
679   if (get_mode_sort(mode) == irms_float_number) {
680     switch(get_mode_size_bits(mode))
681     {
682       case 32:
683         fc_get_plusinf(8, 23, NULL);
684         break;
685       case 64:
686         fc_get_plusinf(11, 52, NULL);
687         break;
688       case 80:
689         fc_get_plusinf(15, 64, NULL);
690         break;
691     }
692     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
693   }
694   else {
695     assert(0 && "tarval is not floating point");
696     return tarval_bad;
697   }
698 }
699
700 tarval *get_tarval_minus_inf(ir_mode *mode)
701 {
702   ANNOUNCE();
703   assert(mode);
704
705   if (get_mode_n_vector_elems(mode) > 1) {
706     /* vector arithmetic not implemented yet */
707     return tarval_bad;
708   }
709
710   if (get_mode_sort(mode) == irms_float_number) {
711     switch(get_mode_size_bits(mode))
712     {
713     case 32:
714       fc_get_minusinf(8, 23, NULL);
715       break;
716     case 64:
717       fc_get_minusinf(11, 52, NULL);
718       break;
719     case 80:
720       fc_get_minusinf(15, 64, NULL);
721       break;
722     }
723     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
724   }
725   else {
726     assert(0 && "tarval is not floating point");
727     return tarval_bad;
728   }
729 }
730
731 /*
732  * Arithmethic operations on tarvals ========================================
733  */
734
735 /*
736  * test if negative number, 1 means 'yes'
737  */
738 int tarval_is_negative(tarval *a)
739 {
740   ANNOUNCE();
741   assert(a);
742
743   if (get_mode_n_vector_elems(a->mode) > 1) {
744     /* vector arithmetic not implemented yet */
745     assert(0 && "tarval_is_negative is not allowed for vector modes");
746     return 0;
747   }
748
749   switch (get_mode_sort(a->mode))
750   {
751     case irms_int_number:
752       if (!mode_is_signed(a->mode)) return 0;
753       else
754     return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
755
756     case irms_float_number:
757       return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
758
759     default:
760       assert(0 && "not implemented");
761       return 0;
762   }
763 }
764
765 /*
766  * test if null, 1 means 'yes'
767  */
768 int tarval_is_null(tarval *a)
769 {
770   ir_mode *m = get_tarval_mode(a);
771
772   return a == get_tarval_null(m);
773 }
774
775 /*
776  * test if one, 1 means 'yes'
777  */
778 int tarval_is_one(tarval *a)
779 {
780   ir_mode *m = get_tarval_mode(a);
781
782   return a == get_tarval_one(m);
783 }
784
785 /*
786  * comparison
787  */
788 pn_Cmp tarval_cmp(tarval *a, tarval *b)
789 {
790   ANNOUNCE();
791   assert(a);
792   assert(b);
793
794   if (a == tarval_bad || b == tarval_bad) {
795     assert(0 && "Comparison with tarval_bad");
796     return pn_Cmp_False;
797   }
798
799   if (a == tarval_undefined || b == tarval_undefined)
800     return pn_Cmp_False;
801
802   if (a->mode != b->mode)
803     return pn_Cmp_False;
804
805   if (get_mode_n_vector_elems(a->mode) > 1) {
806     /* vector arithmetic not implemented yet */
807     assert(0 && "cmp not implemented for vector modes");
808   }
809
810   /* Here the two tarvals are unequal and of the same mode */
811   switch (get_mode_sort(a->mode))
812   {
813     case irms_control_flow:
814     case irms_memory:
815     case irms_auxiliary:
816     case irms_reference:
817       if (a == b)
818         return pn_Cmp_Eq;
819       return pn_Cmp_False;
820
821     case irms_float_number:
822       /*
823        * BEWARE: we cannot compare a == b here, because
824        * a NaN is always Unordered to any other value, even to itself!
825        */
826       switch (fc_comp(a->value, b->value)) {
827         case -1: return pn_Cmp_Lt;
828         case  0: return pn_Cmp_Eq;
829         case  1: return pn_Cmp_Gt;
830         case  2: return pn_Cmp_Uo;
831         default: return pn_Cmp_False;
832       }
833     case irms_int_number:
834     case irms_character:
835       if (a == b)
836         return pn_Cmp_Eq;
837       return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
838
839     case irms_internal_boolean:
840       if (a == b)
841         return pn_Cmp_Eq;
842       return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
843   }
844   return pn_Cmp_False;
845 }
846
847 /*
848  * convert to other mode
849  */
850 tarval *tarval_convert_to(tarval *src, ir_mode *m)
851 {
852   char *buffer;
853
854   ANNOUNCE();
855   assert(src);
856   assert(m);
857
858   if (src->mode == m) return src;
859
860   if (get_mode_n_vector_elems(src->mode) > 1) {
861     /* vector arithmetic not implemented yet */
862     return tarval_bad;
863   }
864
865   switch (get_mode_sort(src->mode))
866   {
867     case irms_control_flow:
868     case irms_memory:
869     case irms_auxiliary:
870       break;
871
872     /* cast float to something */
873     case irms_float_number:
874       switch (get_mode_sort(m)) {
875         case irms_float_number:
876           switch (get_mode_size_bits(m))
877           {
878             case 32:
879               fc_cast(src->value, 8, 23, NULL);
880               break;
881             case 64:
882               fc_cast(src->value, 11, 52, NULL);
883               break;
884             case 80:
885               fc_cast(src->value, 15, 64, NULL);
886               break;
887             default:
888               break;
889           }
890           return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
891
892         case irms_int_number:
893           switch (GET_FLOAT_TO_INT_MODE())
894           {
895             case TRUNCATE:
896               fc_int(src->value, NULL);
897               break;
898             case ROUND:
899               fc_rnd(src->value, NULL);
900               break;
901             default:
902               assert(0);
903               break;
904           }
905           /* FIXME: floating point unit can't produce a value in integer
906            * representation
907            * an intermediate representation is needed here first. */
908           /*  return get_tarval(); */
909           return tarval_bad;
910
911         default:
912           /* the rest can't be converted */
913           return tarval_bad;
914       }
915       break;
916
917     /* cast int to something */
918     case irms_int_number:
919       switch (get_mode_sort(m)) {
920         case irms_int_number:
921         case irms_character:
922           return get_tarval_overflow(src->value, src->length, m);
923
924         case irms_internal_boolean:
925           /* XXX C semantics */
926           if (src == get_mode_null(src->mode)) return tarval_b_false;
927           else return tarval_b_true;
928
929         case irms_float_number:
930           /* XXX floating point unit does not understand internal integer
931            * representation, convert to string first, then create float from
932            * string */
933           buffer = alloca(100);
934           /* decimal string representation because hexadecimal output is
935            * interpreted unsigned by fc_val_from_str, so this is a HACK */
936           snprintf(buffer, 100, "%s",
937                    sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC));
938           switch (get_mode_size_bits(m))
939           {
940             case 32:
941               fc_val_from_str(buffer, 0, 8, 23, NULL);
942               break;
943             case 64:
944               fc_val_from_str(buffer, 0, 11, 52, NULL);
945               break;
946             case 80:
947               fc_val_from_str(buffer, 0, 15, 64, NULL);
948               break;
949           }
950           return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
951
952 #if 0
953         case irms_reference:
954           /* allow 0 to be casted */
955           if (src == get_mode_null(src->mode))
956             return get_mode_null(m);
957           break;
958 #endif
959         default:
960           break;
961       }
962       break;
963
964     case irms_internal_boolean:
965       switch (get_mode_sort(m))
966       {
967         case irms_int_number:
968           if (src == tarval_b_true) return get_mode_one(m);
969           else return get_mode_null(m);
970
971         default:
972           break;
973       }
974       break;
975
976     case irms_character:
977       break;
978     case irms_reference:
979       break;
980   }
981
982   return tarval_bad;
983 }
984
985 /*
986  * bitwise negation
987  */
988 tarval *tarval_not(tarval *a)
989 {
990   char *buffer;
991
992   ANNOUNCE();
993   assert(a);
994
995   /* works for vector mode without changes */
996
997   switch (get_mode_sort(a->mode))
998   {
999     case irms_int_number:
1000       buffer = alloca(sc_get_buffer_length());
1001       sc_not(a->value, buffer);
1002       return get_tarval(buffer, a->length, a->mode);
1003
1004     case irms_internal_boolean:
1005       if (a == tarval_b_true)
1006         return tarval_b_false;
1007       if (a == tarval_b_false)
1008         return tarval_b_true;
1009       return tarval_bad;
1010
1011     default:
1012       assert(0 && "bitwise negation is only allowed for integer and boolean");
1013       return tarval_bad;
1014   }
1015 }
1016
1017 /*
1018  * arithmetic negation
1019  */
1020 tarval *tarval_neg(tarval *a)
1021 {
1022   char *buffer;
1023
1024   ANNOUNCE();
1025   assert(a);
1026   assert(mode_is_num(a->mode)); /* negation only for numerical values */
1027
1028   /* note: negation is allowed even for unsigned modes. */
1029
1030   if (get_mode_n_vector_elems(a->mode) > 1) {
1031     /* vector arithmetic not implemented yet */
1032     return tarval_bad;
1033   }
1034
1035   switch (get_mode_sort(a->mode))
1036   {
1037     case irms_int_number:
1038       buffer = alloca(sc_get_buffer_length());
1039       sc_neg(a->value, buffer);
1040       return get_tarval_overflow(buffer, a->length, a->mode);
1041
1042     case irms_float_number:
1043       fc_neg(a->value, NULL);
1044       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1045
1046     default:
1047       return tarval_bad;
1048   }
1049 }
1050
1051 /*
1052  * addition
1053  */
1054 tarval *tarval_add(tarval *a, tarval *b)
1055 {
1056   char *buffer;
1057
1058   ANNOUNCE();
1059   assert(a);
1060   assert(b);
1061   assert(a->mode == b->mode);
1062
1063   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
1064     /* vector arithmetic not implemented yet */
1065     return tarval_bad;
1066   }
1067
1068   switch (get_mode_sort(a->mode))
1069   {
1070     case irms_character:
1071     case irms_int_number:
1072       /* modes of a,b are equal, so result has mode of a as this might be the character */
1073       buffer = alloca(sc_get_buffer_length());
1074       sc_add(a->value, b->value, buffer);
1075       return get_tarval_overflow(buffer, a->length, a->mode);
1076
1077     case irms_float_number:
1078       fc_add(a->value, b->value, NULL);
1079       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1080
1081     default:
1082       return tarval_bad;
1083   }
1084 }
1085
1086 /*
1087  * subtraction
1088  */
1089 tarval *tarval_sub(tarval *a, tarval *b)
1090 {
1091   char *buffer;
1092
1093   ANNOUNCE();
1094   assert(a);
1095   assert(b);
1096   assert(a->mode == b->mode);
1097
1098   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
1099     /* vector arithmetic not implemented yet */
1100     return tarval_bad;
1101   }
1102   switch (get_mode_sort(a->mode))
1103   {
1104     case irms_character:
1105     case irms_int_number:
1106       /* modes of a,b are equal, so result has mode of a as this might be the character */
1107       buffer = alloca(sc_get_buffer_length());
1108       sc_sub(a->value, b->value, buffer);
1109       return get_tarval_overflow(buffer, a->length, a->mode);
1110
1111     case irms_float_number:
1112       fc_sub(a->value, b->value, NULL);
1113       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1114
1115     default:
1116       return tarval_bad;
1117   }
1118 }
1119
1120 /*
1121  * multiplication
1122  */
1123 tarval *tarval_mul(tarval *a, tarval *b)
1124 {
1125   char *buffer;
1126
1127   ANNOUNCE();
1128   assert(a);
1129   assert(b);
1130   assert(a->mode == b->mode);
1131
1132   if (get_mode_n_vector_elems(a->mode) > 1) {
1133     /* vector arithmetic not implemented yet */
1134     return tarval_bad;
1135   }
1136
1137   switch (get_mode_sort(a->mode))
1138   {
1139     case irms_int_number:
1140       /* modes of a,b are equal */
1141       buffer = alloca(sc_get_buffer_length());
1142       sc_mul(a->value, b->value, buffer);
1143       return get_tarval_overflow(buffer, a->length, a->mode);
1144
1145     case irms_float_number:
1146       fc_mul(a->value, b->value, NULL);
1147       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1148
1149     default:
1150       return tarval_bad;
1151   }
1152 }
1153
1154 /*
1155  * floating point division
1156  */
1157 tarval *tarval_quo(tarval *a, tarval *b)
1158 {
1159   ANNOUNCE();
1160   assert(a);
1161   assert(b);
1162   assert((a->mode == b->mode) && mode_is_float(a->mode));
1163
1164   if (get_mode_n_vector_elems(a->mode) > 1) {
1165     /* vector arithmetic not implemented yet */
1166     return tarval_bad;
1167   }
1168
1169   fc_div(a->value, b->value, NULL);
1170   return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1171 }
1172
1173 /*
1174  * integer division
1175  * overflow is impossible, but look out for division by zero
1176  */
1177 tarval *tarval_div(tarval *a, tarval *b)
1178 {
1179   ANNOUNCE();
1180   assert(a);
1181   assert(b);
1182   assert((a->mode == b->mode) && mode_is_int(a->mode));
1183
1184   if (get_mode_n_vector_elems(a->mode) > 1) {
1185     /* vector arithmetic not implemented yet */
1186     return tarval_bad;
1187   }
1188
1189   /* x/0 error */
1190   if (b == get_mode_null(b->mode)) return tarval_bad;
1191   /* modes of a,b are equal */
1192   sc_div(a->value, b->value, NULL);
1193   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1194 }
1195
1196 /*
1197  * remainder
1198  * overflow is impossible, but look out for division by zero
1199  */
1200 tarval *tarval_mod(tarval *a, tarval *b)
1201 {
1202   ANNOUNCE();
1203   assert(a);
1204   assert(b);
1205   assert((a->mode == b->mode) && mode_is_int(a->mode));
1206
1207   if (get_mode_n_vector_elems(a->mode) > 1) {
1208     /* vector arithmetic not implemented yet */
1209     return tarval_bad;
1210   }
1211
1212   /* x/0 error */
1213   if (b == get_mode_null(b->mode)) return tarval_bad;
1214   /* modes of a,b are equal */
1215   sc_mod(a->value, b->value, NULL);
1216   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1217 }
1218
1219 /*
1220  * absolute value
1221  */
1222 tarval *tarval_abs(tarval *a)
1223 {
1224   char *buffer;
1225
1226   ANNOUNCE();
1227   assert(a);
1228   assert(mode_is_num(a->mode));
1229
1230   if (get_mode_n_vector_elems(a->mode) > 1) {
1231     /* vector arithmetic not implemented yet */
1232     return tarval_bad;
1233   }
1234
1235   switch (get_mode_sort(a->mode))
1236   {
1237     case irms_int_number:
1238       if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
1239       {
1240         buffer = alloca(sc_get_buffer_length());
1241         sc_neg(a->value, buffer);
1242         return get_tarval_overflow(buffer, a->length, a->mode);
1243       }
1244       return a;
1245
1246     case irms_float_number:
1247       if (fc_comp(a->value, get_mode_null(a->mode)->value) == -1)
1248       {
1249         fc_neg(a->value, NULL);
1250         return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1251       }
1252       return a;
1253
1254     default:
1255       return tarval_bad;
1256   }
1257   return tarval_bad;
1258 }
1259
1260 /*
1261  * bitwise and
1262  */
1263 tarval *tarval_and(tarval *a, tarval *b)
1264 {
1265   ANNOUNCE();
1266   assert(a);
1267   assert(b);
1268   assert(a->mode == b->mode);
1269
1270   /* works even for vector modes */
1271
1272   switch(get_mode_sort(a->mode))
1273   {
1274     case irms_internal_boolean:
1275       return (a == tarval_b_false) ? a : b;
1276
1277     case irms_int_number:
1278       sc_and(a->value, b->value, NULL);
1279       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1280
1281     default:
1282       assert(0 && "operation not defined on mode");
1283       return tarval_bad;
1284   }
1285 }
1286
1287 /*
1288  * bitwise or
1289  */
1290 tarval *tarval_or (tarval *a, tarval *b)
1291 {
1292   ANNOUNCE();
1293   assert(a);
1294   assert(b);
1295   assert(a->mode == b->mode);
1296
1297   /* works even for vector modes */
1298
1299   switch (get_mode_sort(a->mode))
1300   {
1301     case irms_internal_boolean:
1302       return (a == tarval_b_true) ? a : b;
1303
1304     case irms_int_number:
1305       sc_or(a->value, b->value, NULL);
1306       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1307
1308     default:
1309       assert(0 && "operation not defined on mode");
1310       return tarval_bad;;
1311   }
1312 }
1313
1314 /*
1315  * bitwise exclusive or (xor)
1316  */
1317 tarval *tarval_eor(tarval *a, tarval *b)
1318 {
1319   ANNOUNCE();
1320   assert(a);
1321   assert(b);
1322   assert((a->mode == b->mode));
1323
1324   /* works even for vector modes */
1325
1326   switch (get_mode_sort(a->mode))
1327   {
1328     case irms_internal_boolean:
1329       return (a == b)? tarval_b_false : tarval_b_true;
1330
1331     case irms_int_number:
1332       sc_xor(a->value, b->value, NULL);
1333       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1334
1335     default:
1336       assert(0 && "operation not defined on mode");
1337       return tarval_bad;;
1338   }
1339 }
1340
1341 /*
1342  * bitwise left shift
1343  */
1344 tarval *tarval_shl(tarval *a, tarval *b)
1345 {
1346   char *temp_val = NULL;
1347   ANNOUNCE();
1348   assert(a);
1349   assert(b);
1350   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1351
1352   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1353     /* vector arithmetic not implemented yet */
1354     return tarval_bad;
1355   }
1356
1357   if (get_mode_modulo_shift(a->mode) != 0)
1358   {
1359     temp_val = alloca(sc_get_buffer_length());
1360
1361     sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1362     sc_mod(b->value, temp_val, temp_val);
1363   }
1364   else
1365     temp_val = (char*)b->value;
1366
1367   sc_shl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1368   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1369 }
1370
1371 /*
1372  * bitwise unsigned right shift
1373  */
1374 tarval *tarval_shr(tarval *a, tarval *b)
1375 {
1376   char *temp_val = NULL;
1377   ANNOUNCE();
1378   assert(a);
1379   assert(b);
1380   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1381
1382   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1383     /* vector arithmetic not implemented yet */
1384     return tarval_bad;
1385   }
1386
1387   if (get_mode_modulo_shift(a->mode) != 0)
1388   {
1389     temp_val = alloca(sc_get_buffer_length());
1390
1391     sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1392     sc_mod(b->value, temp_val, temp_val);
1393   }
1394   else
1395     temp_val = (char*)b->value;
1396
1397   sc_shr(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1398   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1399 }
1400
1401 /*
1402  * bitwise signed right shift
1403  */
1404 tarval *tarval_shrs(tarval *a, tarval *b)
1405 {
1406   char *temp_val = NULL;
1407   ANNOUNCE();
1408   assert(a);
1409   assert(b);
1410   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1411
1412   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1413     /* vector arithmetic not implemented yet */
1414     return tarval_bad;
1415   }
1416
1417   if (get_mode_modulo_shift(a->mode) != 0)
1418   {
1419     temp_val = alloca(sc_get_buffer_length());
1420
1421     sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1422     sc_mod(b->value, temp_val, temp_val);
1423   }
1424   else
1425     temp_val = (char*)b->value;
1426
1427   sc_shrs(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1428   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1429 }
1430
1431 /*
1432  * bitwise rotation
1433  */
1434 tarval *tarval_rot(tarval *a, tarval *b)
1435 {
1436   char *temp_val = NULL;
1437   ANNOUNCE();
1438   assert(a);
1439   assert(b);
1440   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1441
1442   if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1443     /* vector arithmetic not implemented yet */
1444     return tarval_bad;
1445   }
1446
1447   if (get_mode_modulo_shift(a->mode) != 0)
1448   {
1449     temp_val = alloca(sc_get_buffer_length());
1450
1451     sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1452     sc_mod(b->value, temp_val, temp_val);
1453   }
1454   else
1455     temp_val = (char*)b->value;
1456
1457   sc_rot(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1458   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1459 }
1460
1461 /*
1462  * carry flag of the last operation
1463  */
1464 int tarval_carry(void)
1465 {
1466   return sc_had_carry();
1467 }
1468
1469 /*
1470  * Output of tarvals
1471  */
1472 int tarval_snprintf(char *buf, size_t len, tarval *tv)
1473 {
1474   static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
1475
1476   const char *str;
1477   char tv_buf[100];
1478   const tarval_mode_info *mode_info;
1479   const char *prefix, *suffix;
1480
1481   ANNOUNCE();
1482
1483   mode_info = tv->mode->tv_priv;
1484   if (! mode_info)
1485     mode_info = &default_info;
1486   prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
1487   suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
1488
1489   switch (get_mode_sort(tv->mode))
1490   {
1491     case irms_int_number:
1492     case irms_character:
1493       switch (mode_info->mode_output) {
1494
1495       case TVO_DECIMAL:
1496         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
1497     break;
1498
1499       case TVO_OCTAL:
1500         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT);
1501     break;
1502
1503       case TVO_HEX:
1504       case TVO_NATIVE:
1505       default:
1506         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
1507     break;
1508       }
1509       return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
1510
1511     case irms_float_number:
1512       switch (mode_info->mode_output) {
1513         case TVO_HEX:
1514           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_PACKED), suffix);
1515
1516         case TVO_HEXFLOAT:
1517           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_HEX), suffix);
1518
1519         case TVO_FLOAT:
1520         case TVO_NATIVE:
1521         default:
1522           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_DEC), suffix);
1523       }
1524       break;
1525
1526     case irms_reference:
1527       if (tv == tarval_P_void) return snprintf(buf, len, "NULL");
1528       if (tv->value != NULL){
1529       if (len > tv->length) {
1530         memcpy(buf, tv->value, tv->length);
1531         buf[tv->length] = '\0';
1532       }
1533       else {
1534         /* truncated */
1535         memcpy(buf, tv->value, len-1);
1536         buf[len-1] = '\0';
1537       }
1538       return tv->length;
1539          }
1540       else
1541     return snprintf(buf, len, "void");
1542
1543     case irms_internal_boolean:
1544       switch (mode_info->mode_output) {
1545
1546       case TVO_DECIMAL:
1547       case TVO_OCTAL:
1548       case TVO_HEX:
1549       case TVO_BINARY:
1550         return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
1551
1552       case TVO_NATIVE:
1553       default:
1554         return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
1555       }
1556
1557     case irms_control_flow:
1558     case irms_memory:
1559     case irms_auxiliary:
1560       return snprintf(buf, len, "<TV_OVERFLOW_BAD>");
1561   }
1562
1563   return 0;
1564 }
1565
1566
1567 /**
1568  * Output of tarvals to stdio.
1569  */
1570 int tarval_printf(tarval *tv) {
1571   char buf[1024];
1572   int res;
1573
1574   res = tarval_snprintf(buf, sizeof(buf), tv);
1575   assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
1576   printf(buf);
1577   return res;
1578 }
1579
1580
1581 char *get_tarval_bitpattern(tarval *tv)
1582 {
1583   int i, j, pos = 0;
1584   int n = get_mode_size_bits(tv->mode);
1585   int bytes = (n + 7) / 8;
1586   char *res = malloc((n + 1) * sizeof(char));
1587   unsigned char byte;
1588
1589   for(i = 0; i < bytes; i++) {
1590     byte = get_tarval_sub_bits(tv, i);
1591     for(j = 1; j < 256; j <<= 1)
1592       if(pos < n)
1593     res[pos++] = j & byte ? '1' : '0';
1594   }
1595
1596   res[n] = '\0';
1597
1598   return res;
1599 }
1600
1601 /*
1602  * access to the bitpattern
1603  */
1604 unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs)
1605 {
1606   switch (get_mode_sort(tv->mode)) {
1607     case irms_int_number:
1608     case irms_character:
1609       return sc_sub_bits(tv->value, tv->length, byte_ofs);
1610
1611     case irms_float_number:
1612       return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1613
1614     default:
1615       return 0;
1616   }
1617 }
1618
1619 /*
1620  * Specify the output options of one mode.
1621  *
1622  * This functions stores the modinfo, so DO NOT DESTROY it.
1623  *
1624  * Returns zero on success.
1625  */
1626 int  set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo)
1627 {
1628   assert(mode);
1629
1630   mode->tv_priv = modeinfo;
1631   return 0;
1632 }
1633
1634 /*
1635  * Returns the output options of one mode.
1636  *
1637  * This functions returns the mode info of a given mode.
1638  */
1639 const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode)
1640 {
1641   assert(mode);
1642
1643   return mode->tv_priv;
1644 }
1645
1646 /*
1647  * Identifying tarvals values for algebraic simplifications.
1648  *
1649  * Returns:
1650  *   - TV_CLASSIFY_NULL    for additive neutral,
1651  *   - TV_CLASSIFY_ONE     for multiplicative neutral,
1652  *   - TV_CLASSIFY_ALL_ONE for bitwise-and neutral
1653  *   - TV_CLASSIFY_OTHER   else
1654  */
1655 tarval_classification_t classify_tarval(tarval *tv)
1656 {
1657   ANNOUNCE();
1658   if (!tv || tv == tarval_bad) return TV_CLASSIFY_OTHER;
1659
1660   if (tv == get_mode_null(tv->mode))
1661     return TV_CLASSIFY_NULL;
1662   else if (tv == get_mode_one(tv->mode))
1663     return TV_CLASSIFY_ONE;
1664   else if ((get_mode_sort(tv->mode) == irms_int_number)
1665            && (tv == new_tarval_from_long(-1, tv->mode)))
1666     return TV_CLASSIFY_ALL_ONE;
1667
1668   return TV_CLASSIFY_OTHER;
1669 }
1670
1671 /**
1672  * Sets the overflow mode for integer operations.
1673  */
1674 void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode) {
1675   int_overflow_mode = ov_mode;
1676 }
1677
1678 /**
1679  * Get the overflow mode for integer operations.
1680  */
1681 tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) {
1682   return int_overflow_mode;
1683 }
1684
1685 /**
1686  * default mode_info for output as HEX
1687  */
1688 static const tarval_mode_info hex_output = {
1689   TVO_HEX,
1690   "0x",
1691   NULL,
1692 };
1693
1694 /**
1695  * default mode_info for output as reference
1696  */
1697 static const tarval_mode_info reference_output = {
1698   TVO_NATIVE,
1699   "&(",
1700   ")",
1701 };
1702
1703
1704 /*
1705  * Initialization of the tarval module: called before init_mode()
1706  */
1707 void init_tarval_1(void)
1708 {
1709   ANNOUNCE();
1710   /* initialize the sets holding the tarvals with a comparison function and
1711    * an initial size, which is the expected number of constants */
1712   tarvals = new_set(memcmp, N_CONSTANTS);
1713   values  = new_set(memcmp, N_CONSTANTS);
1714   /* init strcalc with precision of 68 to support floating point values with 64
1715    * bit mantissa (needs extra bits for rounding and overflow) */
1716   init_strcalc(68);
1717   init_fltcalc(0);
1718 }
1719
1720 /*
1721  * Initialization of the tarval module: called after init_mode()
1722  */
1723 void init_tarval_2(void)
1724 {
1725   ANNOUNCE();
1726
1727   tarval.bad->kind       = k_tarval;
1728   tarval_bad->mode       = mode_BAD;
1729
1730   tarval_undefined->kind = k_tarval;
1731   tarval_undefined->mode = mode_ANY;
1732
1733   tarval_b_true->kind    = k_tarval;
1734   tarval_b_true->mode    = mode_b;
1735
1736   tarval_b_false->kind   = k_tarval
1737   tarval_b_false->mode   = mode_b;
1738
1739   tarval_P_void->kind    = k_tarval;
1740   tarval_P_void->mode    = mode_P;
1741
1742   /*
1743    * assign output modes that are compatible with the
1744    * old implementation: Hex output
1745    */
1746   set_tarval_mode_output_option(mode_U,  &hex_output);
1747   set_tarval_mode_output_option(mode_C,  &hex_output);
1748   set_tarval_mode_output_option(mode_Bs, &hex_output);
1749   set_tarval_mode_output_option(mode_Bu, &hex_output);
1750   set_tarval_mode_output_option(mode_Hs, &hex_output);
1751   set_tarval_mode_output_option(mode_Hu, &hex_output);
1752   set_tarval_mode_output_option(mode_Is, &hex_output);
1753   set_tarval_mode_output_option(mode_Iu, &hex_output);
1754   set_tarval_mode_output_option(mode_Ls, &hex_output);
1755   set_tarval_mode_output_option(mode_Lu, &hex_output);
1756   set_tarval_mode_output_option(mode_P,  &reference_output);
1757 }
1758
1759 /* free all memory occupied by tarval. */
1760 void finish_tarval(void) {
1761   finish_strcalc ();
1762   finish_fltcalc ();
1763   del_set(tarvals); tarvals = NULL;
1764   del_set(values);  values = NULL;
1765 }
1766
1767 /****************************************************************************
1768  *   end of tv.c
1769  ****************************************************************************/