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