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