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