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