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