renamed c++ class keyword
[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
412 /* get the mode of the tarval */
413 ir_mode *(get_tarval_mode)(const tarval *tv) {
414   return _get_tarval_mode(tv);
415 }
416
417 /*
418  * Special value query functions ============================================
419  *
420  * These functions calculate and return a tarval representing the requested
421  * value.
422  * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
423  * functions, but these are stored on initialization of the irmode module and
424  * therefore the irmode functions should be prefered to the functions below.
425  */
426
427 tarval *(get_tarval_bad)(void) {
428   return _get_tarval_bad();
429 }
430
431 tarval *(get_tarval_undefined)(void) {
432   return _get_tarval_undefined();
433 }
434
435 tarval *(get_tarval_b_false)(void) {
436   return _get_tarval_b_false();
437 }
438
439 tarval *(get_tarval_b_true)(void) {
440   return _get_tarval_b_true();
441 }
442
443 tarval *(get_tarval_P_void)(void) {
444   return _get_tarval_P_void();
445 }
446
447 tarval *get_tarval_max(ir_mode *mode)
448 {
449   ANNOUNCE();
450   assert(mode);
451
452   if (get_mode_n_vector_elems(mode) > 1) {
453     /* vector arithmetic not implemented yet */
454     return tarval_bad;
455   }
456
457   switch(get_mode_sort(mode))
458   {
459     case irms_reference:
460     case irms_control_flow:
461     case irms_memory:
462     case irms_auxiliary:
463       assert(0);
464       break;
465
466     case irms_internal_boolean:
467       return tarval_b_true;
468
469     case irms_float_number:
470       switch(get_mode_size_bits(mode))
471       {
472         case 32:
473           fc_get_max(8, 23, NULL);
474           break;
475         case 64:
476           fc_get_max(11, 52, NULL);
477           break;
478         case 80:
479           fc_get_max(15, 64, NULL);
480           break;
481       }
482       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
483
484     case irms_int_number:
485     case irms_character:
486       sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
487       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
488   }
489   return tarval_bad;
490 }
491
492 tarval *get_tarval_min(ir_mode *mode)
493 {
494   ANNOUNCE();
495   assert(mode);
496
497   if (get_mode_n_vector_elems(mode) > 1) {
498     /* vector arithmetic not implemented yet */
499     return tarval_bad;
500   }
501
502   switch(get_mode_sort(mode))
503   {
504     case irms_reference:
505     case irms_control_flow:
506     case irms_memory:
507     case irms_auxiliary:
508       assert(0);
509       break;
510
511     case irms_internal_boolean:
512       return tarval_b_false;
513
514     case irms_float_number:
515       switch(get_mode_size_bits(mode))
516       {
517         case 32:
518           fc_get_min(8, 23, NULL);
519           break;
520         case 64:
521           fc_get_min(11, 52, NULL);
522           break;
523         case 80:
524           fc_get_min(15, 64, NULL);
525           break;
526       }
527       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
528
529     case irms_int_number:
530     case irms_character:
531       sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
532       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
533   }
534   return tarval_bad;
535 }
536
537 tarval *get_tarval_null(ir_mode *mode)
538 {
539   ANNOUNCE();
540   assert(mode);
541
542   if (get_mode_n_vector_elems(mode) > 1) {
543     /* vector arithmetic not implemented yet */
544     return tarval_bad;
545   }
546
547   switch(get_mode_sort(mode))
548   {
549     case irms_control_flow:
550     case irms_memory:
551     case irms_auxiliary:
552     case irms_internal_boolean:
553       assert(0);
554       break;
555
556     case irms_float_number:
557       return new_tarval_from_double(0.0, mode);
558
559     case irms_int_number:
560     case irms_character:
561       return new_tarval_from_long(0l,  mode);
562
563     case irms_reference:
564       return tarval_P_void;
565   }
566   return tarval_bad;
567 }
568
569 tarval *get_tarval_one(ir_mode *mode)
570 {
571   ANNOUNCE();
572   assert(mode);
573
574   if (get_mode_n_vector_elems(mode) > 1) {
575     /* vector arithmetic not implemented yet */
576     return tarval_bad;
577   }
578
579   switch(get_mode_sort(mode))
580   {
581     case irms_control_flow:
582     case irms_memory:
583     case irms_auxiliary:
584     case irms_internal_boolean:
585     case irms_reference:
586       assert(0);
587       break;
588
589     case irms_float_number:
590       return new_tarval_from_double(1.0, mode);
591
592     case irms_int_number:
593     case irms_character:
594       return new_tarval_from_long(1l, mode);
595       break;
596   }
597   return tarval_bad;
598 }
599
600 tarval *get_tarval_minus_one(ir_mode *mode)
601 {
602   ANNOUNCE();
603   assert(mode);
604
605   if (get_mode_n_vector_elems(mode) > 1) {
606     /* vector arithmetic not implemented yet */
607     return tarval_bad;
608   }
609
610   switch(get_mode_sort(mode))
611   {
612     case irms_control_flow:
613     case irms_memory:
614     case irms_auxiliary:
615     case irms_internal_boolean:
616     case irms_reference:
617       assert(0);
618       break;
619
620     case irms_float_number:
621       return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
622
623     case irms_int_number:
624     case irms_character:
625       return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
626   }
627   return tarval_bad;
628 }
629
630 tarval *get_tarval_nan(ir_mode *mode)
631 {
632   ANNOUNCE();
633   assert(mode);
634
635   if (get_mode_n_vector_elems(mode) > 1) {
636     /* vector arithmetic not implemented yet */
637     return tarval_bad;
638   }
639
640   if (get_mode_sort(mode) == irms_float_number) {
641     switch(get_mode_size_bits(mode))
642     {
643       case 32:
644         fc_get_qnan(8, 23, NULL);
645         break;
646       case 64:
647         fc_get_qnan(11, 52, NULL);
648         break;
649       case 80:
650         fc_get_qnan(15, 64, NULL);
651         break;
652     }
653     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
654   }
655   else {
656     assert(0 && "tarval is not floating point");
657     return tarval_bad;
658   }
659 }
660
661 tarval *get_tarval_plus_inf(ir_mode *mode)
662 {
663   ANNOUNCE();
664   assert(mode);
665
666   if (get_mode_n_vector_elems(mode) > 1) {
667     /* vector arithmetic not implemented yet */
668     return tarval_bad;
669   }
670
671   if (get_mode_sort(mode) == irms_float_number) {
672     switch(get_mode_size_bits(mode))
673     {
674       case 32:
675         fc_get_plusinf(8, 23, NULL);
676         break;
677       case 64:
678         fc_get_plusinf(11, 52, NULL);
679         break;
680       case 80:
681         fc_get_plusinf(15, 64, NULL);
682         break;
683     }
684     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
685   }
686   else {
687     assert(0 && "tarval is not floating point");
688     return tarval_bad;
689   }
690 }
691
692 tarval *get_tarval_minus_inf(ir_mode *mode)
693 {
694   ANNOUNCE();
695   assert(mode);
696
697   if (get_mode_n_vector_elems(mode) > 1) {
698     /* vector arithmetic not implemented yet */
699     return tarval_bad;
700   }
701
702   if (get_mode_sort(mode) == irms_float_number) {
703     switch(get_mode_size_bits(mode))
704     {
705     case 32:
706       fc_get_minusinf(8, 23, NULL);
707       break;
708     case 64:
709       fc_get_minusinf(11, 52, NULL);
710       break;
711     case 80:
712       fc_get_minusinf(15, 64, NULL);
713       break;
714     }
715     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
716   }
717   else {
718     assert(0 && "tarval is not floating point");
719     return tarval_bad;
720   }
721 }
722
723 /*
724  * Arithmethic operations on tarvals ========================================
725  */
726
727 /*
728  * test if negative number, 1 means 'yes'
729  */
730 int tarval_is_negative(tarval *a)
731 {
732   ANNOUNCE();
733   assert(a);
734
735   if (get_mode_n_vector_elems(a->mode) > 1) {
736     /* vector arithmetic not implemented yet */
737     assert(0 && "tarval_is_negative is not allowed for vector modes");
738     return 0;
739   }
740
741   switch (get_mode_sort(a->mode))
742   {
743     case irms_int_number:
744       if (!mode_is_signed(a->mode)) return 0;
745       else
746     return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
747
748     case irms_float_number:
749       return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
750
751     default:
752       assert(0 && "not implemented");
753       return 0;
754   }
755 }
756
757 /*
758  * test if null, 1 means 'yes'
759  */
760 int tarval_is_null(tarval *a)
761 {
762   ir_mode *m = get_tarval_mode(a);
763
764   return a == get_tarval_null(m);
765 }
766
767 /*
768  * test if one, 1 means 'yes'
769  */
770 int tarval_is_one(tarval *a)
771 {
772   ir_mode *m = get_tarval_mode(a);
773
774   return a == get_tarval_one(m);
775 }
776
777 /*
778  * comparison
779  */
780 pn_Cmp tarval_cmp(tarval *a, tarval *b)
781 {
782   ANNOUNCE();
783   assert(a);
784   assert(b);
785
786   if (a == tarval_bad || b == tarval_bad) {
787     assert(0 && "Comparison with tarval_bad");
788     return pn_Cmp_False;
789   }
790
791   if (a == tarval_undefined || b == tarval_undefined)
792     return pn_Cmp_False;
793
794   if (a->mode != b->mode)
795     return pn_Cmp_False;
796
797   if (get_mode_n_vector_elems(a->mode) > 1) {
798     /* vector arithmetic not implemented yet */
799     assert(0 && "cmp not implemented for vector modes");
800   }
801
802   /* Here the two tarvals are unequal and of the same mode */
803   switch (get_mode_sort(a->mode))
804   {
805     case irms_control_flow:
806     case irms_memory:
807     case irms_auxiliary:
808     case irms_reference:
809       if (a == b)
810         return pn_Cmp_Eq;
811       return pn_Cmp_False;
812
813     case irms_float_number:
814       /*
815        * BEWARE: we cannot compare a == b here, because
816        * a NaN is always Unordered to any other value, even to itself!
817        */
818       switch (fc_comp(a->value, b->value)) {
819         case -1: return pn_Cmp_Lt;
820         case  0: return pn_Cmp_Eq;
821         case  1: return pn_Cmp_Gt;
822         case  2: return pn_Cmp_Uo;
823         default: return pn_Cmp_False;
824       }
825     case irms_int_number:
826     case irms_character:
827       if (a == b)
828         return pn_Cmp_Eq;
829       return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
830
831     case irms_internal_boolean:
832       if (a == b)
833         return pn_Cmp_Eq;
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  ****************************************************************************/