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