fixed:
[libfirm] / ir / tv / tv.c
1 /* TV --- Target Values, aka Constant Table.
2    Copyright (C) 1995, 1996 Christian von Roques */
3
4 /* $Id$ */
5
6 /****i* tv/implementation
7  *
8  * AUTHORS
9  *    Christian von Roques
10  *    Matthias Heil
11  *
12  * NOTES
13  *    Internal storage for tarvals, 1st draft:
14  *   Integers as well as pointers are stored in a hex formatted string holding
15  *   16 characters. Booleans are not stored as there are only two of them.
16  *
17  *    Floats are just reinterpreted as byte strings, because I am not sure if
18  *   there is loss if I convert float to long double and back and furthermore
19  *   the implementation of a fully ieee compatible floating point emulation
20  *   is not sensible for now
21  *    With this information it is easy to decide the kind of stored value:
22  *   Integers have size 16, floats 4, doubles 8, long doubles 12.
23  ******/
24
25 /* This implementation assumes:
26    * both host and target have IEEE-754 floating-point arithmetic.  */
27
28 /* !!! float and double divides MUST NOT SIGNAL !!! */
29 /* @@@ query the floating-point expception status flags */
30
31 /* @@@ Problem: All Values are stored twice, once as Univ_*s and a 2nd
32    time in their real target mode. :-( */
33
34 #define MAX_INT_LENGTH 8
35 #define CHAR_BUFFER_SIZE ((MAX_INT_LENGTH) * 2)
36
37 #ifdef HAVE_CONFIG_H
38 # include <config.h>
39 #endif
40
41 #include <assert.h>         /* assertions */
42 #include <stdlib.h>         /* atoi() */
43 #include <string.h>         /* nice things for strings */
44 #include <strings.h>         /* nice things for strings */
45
46 #include <stdlib.h>
47 #include "tv_t.h"
48 #include "set.h"            /* to store tarvals in */
49 #include "tune.h"           /* some constants */
50 #include "entity_t.h"       /* needed to store pointers to entities */
51 #include "irmode.h"         /* defines modes etc */
52 #include "irmode_t.h"
53 #include "irnode.h"         /* defines boolean return values */
54 #include "host.h"
55 #include "strcalc.h"
56 #include "fltcalc.h"
57
58 /****************************************************************************
59  *   local definitions and macros
60  ****************************************************************************/
61 #ifndef NDEBUG
62 #  define TARVAL_VERIFY(a) tarval_verify((a))
63 #else
64 #  define TARVAL_VERIFY(a) ((void)0)
65 #endif
66
67 #define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
68 #define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
69
70 #define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
71 #define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
72
73 #define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
74 #if 0
75 static long long count = 0;
76 #  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__);
77 #else
78 #  define ANNOUNCE() ((void)0)
79 #endif
80 /****************************************************************************
81  *   private variables
82  ****************************************************************************/
83 static struct set *tarvals;   /* container for tarval structs */
84 static struct set *values;    /* container for values */
85
86 /****************************************************************************
87  *   private functions
88  ****************************************************************************/
89 #ifndef NDEBUG
90 static int hash_val(const void *value, unsigned int length);
91 static int hash_tv(tarval *tv);
92 static void _fail_verify(tarval *tv, const char* file, int line)
93 {
94   /* print a memory image of the tarval and throw an assertion */
95   if (tv)
96     printf("%s:%d: Invalid tarval:\n  mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
97   else
98     printf("%s:%d: Invalid tarval (null)", file, line);
99   assert(0);
100 }
101 #ifdef __GNUC__
102 INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
103 #endif
104
105 INLINE static void tarval_verify(tarval *tv)
106 {
107   assert(tv);
108   assert(tv->mode);
109   assert(tv->value);
110
111   if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
112   if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
113
114   if (!FIND_TARVAL(tv)) fail_verify(tv);
115   if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
116
117   return;
118 }
119 #endif /* NDEBUG */
120
121 static int hash_tv(tarval *tv)
122 {
123   return ((unsigned int)tv->value ^ (unsigned int)tv->mode) + tv->length;
124 }
125
126 static int hash_val(const void *value, unsigned int length)
127 {
128   unsigned int i;
129   unsigned int hash = 0;
130
131   /* scramble the byte - array */
132   for (i = 0; i < length; i++)
133   {
134     hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
135     hash += (hash << 11) ^ (hash >> 17);
136   }
137
138   return hash;
139 }
140
141 /* finds tarval with value/mode or creates new tarval */
142 static tarval *get_tarval(const void *value, int length, ir_mode *mode)
143 {
144   tarval tv;
145
146   tv.mode = mode;
147   tv.length = length;
148   if (length > 0)
149     /* if there already is such a value, it is returned, else value
150      * is copied into the set */
151     tv.value = INSERT_VALUE(value, length);
152   else
153     tv.value = value;
154
155   /* if there is such a tarval, it is returned, else tv is copied
156    * into the set */
157   return (tarval *)INSERT_TARVAL(&tv);
158 }
159
160 /**
161  * Returns non-zero if a tarval overflows.
162  *
163  * @todo Implementation did not work on all modes
164  */
165 static int overflows(tarval *tv)
166 {
167   switch (get_mode_sort(tv->mode))
168   {
169     case irms_character:
170     case irms_int_number:
171       if (sc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
172       if (sc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
173       break;
174
175     case irms_float_number:
176       /*
177        * TODO: check NaNs
178        */
179       if (fc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1;
180       if (fc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1;
181       break;
182
183     default:
184       break;
185   }
186
187   return 0;
188 }
189
190 /*
191  *   public variables declared in tv.h
192  */
193 tarval *tarval_bad;
194 tarval *tarval_undefined;
195 tarval *tarval_b_false;
196 tarval *tarval_b_true;
197 tarval *tarval_P_void;
198
199 /*
200  *   public functions declared in tv.h
201  */
202
203 /*
204  * Constructors =============================================================
205  */
206 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
207 {
208   ANNOUNCE();
209   assert(str);
210   assert(len);
211   assert(mode);
212
213   switch (get_mode_sort(mode))
214   {
215     case irms_control_flow:
216     case irms_memory:
217     case irms_auxiliary:
218       assert(0);
219       break;
220
221     case irms_internal_boolean:
222       /* match tTrRuUeE/fFaAlLsSeE */
223       if (strcasecmp(str, "true")) return tarval_b_true;
224       else if (strcasecmp(str, "false")) return tarval_b_true;
225       else
226         return atoi(str) ? tarval_b_true : tarval_b_false;
227
228     case irms_float_number:
229       fc_val_from_str(str, len);
230       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
231
232     case irms_int_number:
233     case irms_character:
234       sc_val_from_str(str, len);
235       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
236
237     case irms_reference:
238       return get_tarval(str, len, mode);
239   }
240
241   assert(0);  /* can't be reached, can it? */
242   return NULL;
243 }
244
245 #if 0
246 int tarval_is_str(tarval *tv)
247 {
248   ANNOUNCE();
249   assert(tv);
250
251   return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length > 0));
252 }
253 char *tarval_to_str(tarval *tv)
254 {
255   ANNOUNCE();
256   assert(tarval_is_str(tv));
257   return (char *)tv->value;
258 }
259 #endif
260
261 /*
262  * helper function, create a tarval from long
263  */
264 tarval *new_tarval_from_long(long l, ir_mode *mode)
265 {
266   ANNOUNCE();
267   assert(mode && !((get_mode_sort(mode) == irms_memory)||(get_mode_sort(mode)==irms_control_flow)||(get_mode_sort(mode)==irms_auxiliary)));
268
269   switch(get_mode_sort(mode))
270   {
271     case irms_internal_boolean:
272       /* XXX C-Semantics ! */
273       return l ? tarval_b_true : tarval_b_false ;
274
275     case irms_int_number:
276     case irms_character:
277       sc_val_from_long(l);
278       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
279
280     case irms_float_number:
281       return new_tarval_from_double((long double)l, mode);
282
283     case irms_reference:
284       return l ? tarval_bad : get_tarval(NULL, 0, mode);  /* null pointer or tarval_bad */
285
286     default:
287       assert(0);
288   }
289   return NULL;
290 }
291
292 /* returns non-zero if can be converted to long */
293 int tarval_is_long(tarval *tv)
294 {
295   ANNOUNCE();
296   if (get_mode_sort(tv->mode) != irms_int_number) return 0;
297
298   if (get_mode_size_bits(tv->mode) > sizeof(long)<<3)
299   {
300     /* the value might be too big to fit in a long */
301     sc_max_from_bits(sizeof(long)<<3, 0);
302     if (sc_comp(sc_get_buffer(), tv->value) == -1)
303     {
304       /* really doesn't fit */
305       return 0;
306     }
307   }
308   return 1;
309 }
310
311 /* this might overflow the machine's long, so use only with small values */
312 long tarval_to_long(tarval* tv)
313 {
314   ANNOUNCE();
315   assert(tarval_is_long(tv) && "tarval too big to fit in long");
316
317   return sc_val_to_long(tv->value);
318 }
319
320 tarval *new_tarval_from_double(long double d, ir_mode *mode)
321 {
322   ANNOUNCE();
323   assert(mode && (get_mode_sort(mode) == irms_float_number));
324
325   fc_val_from_float(d);
326   return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
327 }
328
329 /* returns non-zero if can be converted to double */
330 int tarval_is_double(tarval *tv)
331 {
332   ANNOUNCE();
333   assert(tv);
334
335   return (get_mode_sort(tv->mode) == irms_float_number);
336 }
337
338 long double tarval_to_double(tarval *tv)
339 {
340   ANNOUNCE();
341   assert(tarval_is_double(tv));
342
343   return fc_val_to_float(tv->value);
344 }
345
346 /* The tarval represents the address of the entity.  As the address must
347    be constant the entity must have as owner the global type. */
348 tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
349 {
350   ANNOUNCE();
351   assert(ent);
352   assert(mode && (get_mode_sort(mode) == irms_reference));
353
354   return get_tarval((void *)ent, 0, mode);
355 }
356 int tarval_is_entity(tarval *tv)
357 {
358   ANNOUNCE();
359   assert(tv);
360   /* tv->value == NULL means dereferencing a null pointer */
361   return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0)
362           && (tv != tarval_P_void));
363 }
364
365 entity *tarval_to_entity(tarval *tv)
366 {
367   ANNOUNCE();
368   assert(tv);
369
370   if (tarval_is_entity(tv))
371     return (entity *)tv->value;
372   else {
373     assert(0 && "tarval did not represent an entity");
374     return NULL;
375   }
376 }
377
378 void free_tarval_entity(entity *ent) {
379   /* There can be a tarval referencing this entity.  Even if the
380      tarval is not used by the code any more, it can still reference
381      the entity as tarvals live indepently of the entity referenced.
382      Further the tarval is hashed into a set. If a hash function
383      evaluation happens to collide with this tarval, we will vrfy that
384      it contains a proper entity and we will crash if the entity is
385      freed.
386
387      Unluckily, tarvals can neither be changed nor deleted, and to find
388      one, all existing reference modes have to be tried -> a facility
389      to retrieve all modes of a kind is needed. */
390   ANNOUNCE();
391 }
392
393 /*
394  * Access routines for tarval fields ========================================
395  */
396 ir_mode *get_tarval_mode (tarval *tv)       /* get the mode of the tarval */
397 {
398   ANNOUNCE();
399   assert(tv);
400   return tv->mode;
401 }
402
403 /*
404  * Special value query functions ============================================
405  *
406  * These functions calculate and return a tarval representing the requested
407  * value.
408  * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
409  * functions, but these are stored on initialization of the irmode module and
410  * therefore the irmode functions should be prefered to the functions below.
411  */
412
413 tarval *get_tarval_bad(void)
414 {
415   ANNOUNCE();
416   return tarval_bad;
417 }
418 tarval *get_tarval_undefined(void)
419 {
420   ANNOUNCE();
421   return tarval_undefined;
422 }
423 tarval *get_tarval_b_false(void)
424 {
425   ANNOUNCE();
426   return tarval_b_false;
427 }
428 tarval *get_tarval_b_true(void)
429 {
430   ANNOUNCE();
431   return tarval_b_true;
432 }
433 tarval *get_tarval_P_void(void)
434 {
435   ANNOUNCE();
436   return tarval_P_void;
437 }
438
439 tarval *get_tarval_max(ir_mode *mode)
440 {
441   ANNOUNCE();
442   assert(mode);
443
444   switch(get_mode_sort(mode))
445   {
446     case irms_reference:
447     case irms_control_flow:
448     case irms_memory:
449     case irms_auxiliary:
450       assert(0);
451       break;
452
453     case irms_internal_boolean:
454       return tarval_b_true;
455
456     case irms_float_number:
457       fc_get_max(get_mode_size_bits(mode));
458       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
459
460     case irms_int_number:
461     case irms_character:
462       sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
463       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
464   }
465   return tarval_bad;
466 }
467
468 tarval *get_tarval_min(ir_mode *mode)
469 {
470   ANNOUNCE();
471   assert(mode);
472
473   switch(get_mode_sort(mode))
474   {
475     case irms_reference:
476     case irms_control_flow:
477     case irms_memory:
478     case irms_auxiliary:
479       assert(0);
480       break;
481
482     case irms_internal_boolean:
483       return tarval_b_false;
484
485     case irms_float_number:
486       fc_get_min(get_mode_size_bits(mode));
487       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
488
489     case irms_int_number:
490     case irms_character:
491       sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode));
492       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
493   }
494   return tarval_bad;
495 }
496
497 tarval *get_tarval_null(ir_mode *mode)
498 {
499   ANNOUNCE();
500   assert(mode);
501
502   switch(get_mode_sort(mode))
503   {
504     case irms_control_flow:
505     case irms_memory:
506     case irms_auxiliary:
507     case irms_internal_boolean:
508       assert(0);
509       break;
510
511     case irms_float_number:
512       return new_tarval_from_double(0.0, mode);
513
514     case irms_int_number:
515     case irms_character:
516       return new_tarval_from_long(0l,  mode);
517
518     case irms_reference:
519       return tarval_P_void;
520   }
521   return tarval_bad;
522 }
523
524 tarval *get_tarval_one(ir_mode *mode)
525 {
526   ANNOUNCE();
527   assert(mode);
528
529   switch(get_mode_sort(mode))
530   {
531     case irms_control_flow:
532     case irms_memory:
533     case irms_auxiliary:
534     case irms_internal_boolean:
535     case irms_reference:
536       assert(0);
537       break;
538
539     case irms_float_number:
540       return new_tarval_from_double(1.0, mode);
541
542     case irms_int_number:
543     case irms_character:
544       return new_tarval_from_long(1l, mode);
545       break;
546   }
547   return tarval_bad;
548 }
549
550 tarval *get_tarval_nan(ir_mode *mode)
551 {
552   ANNOUNCE();
553   assert(mode);
554
555   if (get_mode_sort(mode) == irms_float_number) {
556     fc_get_nan();
557     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
558   }
559   else {
560     assert(0 && "tarval is not floating point");
561     return tarval_bad;
562   }
563 }
564
565 tarval *get_tarval_inf(ir_mode *mode)
566 {
567   ANNOUNCE();
568   assert(mode);
569
570   if (get_mode_sort(mode) == irms_float_number) {
571     fc_get_inf();
572     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
573   }
574   else {
575     assert(0 && "tarval is not floating point");
576     return tarval_bad;
577   }
578 }
579
580 /*
581  * Arithmethic operations on tarvals ========================================
582  */
583
584 /*
585  * test if negative number, 1 means 'yes'
586  */
587 int tarval_is_negative(tarval *a)
588 {
589   ANNOUNCE();
590   assert(a);
591
592   switch (get_mode_sort(a->mode))
593   {
594     case irms_int_number:
595       if (!mode_is_signed(a->mode)) return 0;
596       else
597         return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
598
599     case irms_float_number:
600       return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
601
602     default:
603       assert(0 && "not implemented");
604       return 0;
605   }
606 }
607
608 /*
609  * test if null, 1 means 'yes'
610  */
611 int tarval_is_null(tarval *a)
612 {
613   ir_mode *m = get_tarval_mode(a);
614
615   return a == get_tarval_null(m);
616 }
617
618 /*
619  * comparison
620  */
621 pnc_number tarval_cmp(tarval *a, tarval *b)
622 {
623   ANNOUNCE();
624   assert(a);
625   assert(b);
626
627   if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
628   if (a == tarval_undefined || b == tarval_undefined) return False;
629   if (a == b) return Eq;
630   if (get_tarval_mode(a) != get_tarval_mode(b)) return Uo;
631
632   /* Here the two tarvals are unequal and of the same mode */
633   switch (get_mode_sort(a->mode))
634   {
635     case irms_control_flow:
636     case irms_memory:
637     case irms_auxiliary:
638       return False;
639
640     case irms_float_number:
641       return (fc_comp(a->value, b->value)==1)?(Gt):(Lt);
642
643     case irms_int_number:
644     case irms_character:
645       return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
646
647     case irms_internal_boolean:
648       return (a == tarval_b_true)?(Gt):(Lt);
649
650     case irms_reference:
651       return Uo;
652   }
653   return False;
654 }
655
656 /*
657  * convert to other mode
658  */
659 tarval *tarval_convert_to(tarval *src, ir_mode *m)
660 {
661   tarval tv;
662
663   ANNOUNCE();
664   assert(src);
665   assert(m);
666
667   if (src->mode == m) return src;
668
669   switch (get_mode_sort(src->mode))
670   {
671     case irms_control_flow:
672     case irms_memory:
673     case irms_auxiliary:
674       break;
675
676     case irms_float_number:
677       switch (get_mode_sort(m)) {
678         case irms_float_number:
679           tv.mode   = m;
680           tv.length = src->length;
681           tv.value  = src->value;
682           if (overflows(&tv)) {
683             return tarval_bad;
684           }
685
686           return INSERT_TARVAL(&tv);
687
688         default:
689           break;
690       }
691       break;
692
693     case irms_int_number:
694       switch (get_mode_sort(m)) {
695         case irms_int_number:
696         case irms_character:
697           tv.mode   = m;
698           tv.length = src->length;
699           tv.value  = src->value;
700           if (overflows(&tv))
701             return tarval_bad;
702
703           return INSERT_TARVAL(&tv);
704
705         case irms_internal_boolean:
706           /* XXX C semantics */
707           if (src == get_mode_null(src->mode)) return tarval_b_false;
708           else return tarval_b_true;
709
710         default:
711           break;
712       }
713       break;
714
715     case irms_internal_boolean:
716       switch (get_mode_sort(m))
717       {
718         case irms_int_number:
719           if (src == tarval_b_true) return get_mode_one(m);
720           else return get_mode_null(m);
721
722         default:
723           break;
724       }
725       break;
726
727     case irms_character:
728       break;
729     case irms_reference:
730       break;
731   }
732
733   return tarval_bad;
734 }
735
736 /*
737  * negation
738  */
739 tarval *tarval_neg(tarval *a)
740 {
741   ANNOUNCE();
742   assert(a);
743   assert(mode_is_num(a->mode)); /* negation only for numerical values */
744   assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
745
746   switch (get_mode_sort(a->mode))
747   {
748     case irms_int_number:
749       sc_neg(a->value);
750       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
751
752     case irms_float_number:
753       fc_neg(a->value);
754       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
755
756     default:
757       return tarval_bad;
758   }
759 }
760
761 /*
762  * addition
763  */
764 tarval *tarval_add(tarval *a, tarval *b)
765 {
766   ANNOUNCE();
767   assert(a);
768   assert(b);
769   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
770
771   switch (get_mode_sort(a->mode))
772   {
773     case irms_character:
774     case irms_int_number:
775       /* modes of a,b are equal, so result has mode of a as this might be the character */
776       sc_add(a->value, b->value);
777       /* FIXME: Check for overflow */
778       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
779
780     case irms_float_number:
781       /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
782       fc_add(a->value, b->value);
783       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
784
785     default:
786       return tarval_bad;
787   }
788 }
789
790 /*
791  * subtraction
792  */
793 tarval *tarval_sub(tarval *a, tarval *b)
794 {
795   ANNOUNCE();
796   assert(a);
797   assert(b);
798   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
799
800   switch (get_mode_sort(a->mode))
801   {
802     case irms_character:
803     case irms_int_number:
804       /* modes of a,b are equal, so result has mode of a as this might be the character */
805       sc_sub(a->value, b->value);
806       /* FIXME: check for overflow */
807       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
808
809     case irms_float_number:
810       /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
811       fc_add(a->value, b->value);
812       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
813
814     default:
815       return tarval_bad;
816   }
817 }
818
819 /*
820  * multiplication
821  */
822 tarval *tarval_mul(tarval *a, tarval *b)
823 {
824   ANNOUNCE();
825   assert(a);
826   assert(b);
827   assert((a->mode == b->mode) && mode_is_num(a->mode));
828
829   switch (get_mode_sort(a->mode))
830   {
831     case irms_int_number:
832       /* modes of a,b are equal */
833       sc_mul(a->value, b->value);
834       /* FIXME: check for overflow */
835       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
836
837     case irms_float_number:
838       /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
839       fc_add(a->value, b->value);
840       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
841
842     default:
843       return tarval_bad;
844   }
845 }
846
847 /*
848  * floating point division
849  */
850 tarval *tarval_quo(tarval *a, tarval *b)
851 {
852   ANNOUNCE();
853   assert(a);
854   assert(b);
855   assert((a->mode == b->mode) && mode_is_float(a->mode));
856
857   /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */
858   fc_div(a->value, b->value);
859   return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode);
860 }
861
862 /*
863  * integer division
864  */
865 tarval *tarval_div(tarval *a, tarval *b)
866 {
867   ANNOUNCE();
868   assert(a);
869   assert(b);
870   assert((a->mode == b->mode) && mode_is_int(a->mode));
871
872   /* modes of a,b are equal */
873   sc_div(a->value, b->value);
874   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
875 }
876
877 /*
878  * remainder
879  */
880 tarval *tarval_mod(tarval *a, tarval *b)
881 {
882   ANNOUNCE();
883   assert(a);
884   assert(b);
885   assert((a->mode == b->mode) && mode_is_int(a->mode));
886
887   /* modes of a,b are equal */
888   sc_mod(a->value, b->value);
889   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
890 }
891
892 /*
893  * absolute value
894  */
895 tarval *tarval_abs(tarval *a)
896 {
897   ANNOUNCE();
898   assert(a);
899   assert(mode_is_num(a->mode));
900
901   switch (get_mode_sort(a->mode))
902   {
903     case irms_int_number:
904       if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
905       {
906         sc_neg(a->value);
907         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
908       }
909       return a;
910
911     case irms_float_number:
912       break;
913
914     default:
915       return tarval_bad;
916   }
917   return tarval_bad;
918 }
919
920 /*
921  * bitwise and
922  */
923 tarval *tarval_and(tarval *a, tarval *b)
924 {
925   ANNOUNCE();
926   assert(a);
927   assert(b);
928   assert(a->mode == b->mode);
929
930   /* GL: needed for easy optimization. */
931   if (a->mode == mode_b) return (a == tarval_b_false) ? a : b;
932
933   assert(mode_is_int(a->mode));
934
935   sc_and(a->value, b->value);
936   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
937 }
938
939 /*
940  * bitwise or
941  */
942 tarval *tarval_or (tarval *a, tarval *b)
943 {
944   ANNOUNCE();
945   assert(a);
946   assert(b);
947   assert(a->mode == b->mode);
948
949   /* GL: needed for easy optimization. */
950   if (a->mode == mode_b) return (a == tarval_b_true) ? a : b;
951
952
953   assert(mode_is_int(a->mode));
954
955   sc_or(a->value, b->value);
956   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
957 }
958
959 /*
960  * bitwise exclusive or (xor)
961  */
962 tarval *tarval_eor(tarval *a, tarval *b)
963 {
964   ANNOUNCE();
965   assert(a);
966   assert(b);
967   assert((a->mode == b->mode) && mode_is_int(a->mode));
968
969   sc_or(a->value, b->value);
970   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
971 }
972
973 /*
974  * bitwise left shift
975  */
976 tarval *tarval_shl(tarval *a, tarval *b)
977 {
978   ANNOUNCE();
979   assert(a);
980   assert(b);
981   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
982
983   sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
984   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
985 }
986
987 /*
988  * bitwise unsigned right shift
989  */
990 tarval *tarval_shr(tarval *a, tarval *b)
991 {
992   ANNOUNCE();
993   assert(a);
994   assert(b);
995   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
996
997   sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
998   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
999 }
1000
1001 /*
1002  * bitwise signed right shift
1003  */
1004 tarval *tarval_shrs(tarval *a, tarval *b)
1005 {
1006   ANNOUNCE();
1007   assert(a);
1008   assert(b);
1009   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1010
1011   sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
1012   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1013 }
1014
1015 /*
1016  * bitwise rotation
1017  */
1018 tarval *tarval_rot(tarval *a, tarval *b)
1019 {
1020   ANNOUNCE();
1021   assert(a);
1022   assert(b);
1023   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1024
1025   sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode));
1026   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1027 }
1028
1029
1030 /*
1031  * Output of tarvals
1032  */
1033 int tarval_snprintf(char *buf, size_t len, tarval *tv)
1034 {
1035   static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
1036
1037   const char *str;
1038   char tv_buf[100];
1039   const tarval_mode_info *mode_info;
1040   const char *prefix, *suffix;
1041
1042   ANNOUNCE();
1043
1044   mode_info = tv->mode->tv_priv;
1045   if (! mode_info)
1046     mode_info = &default_info;
1047   prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
1048   suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
1049
1050   switch (get_mode_sort(tv->mode))
1051   {
1052     case irms_int_number:
1053     case irms_character:
1054       switch (mode_info->mode_output) {
1055
1056       case TVO_DECIMAL:
1057         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
1058         break;
1059
1060       case TVO_OCTAL:
1061         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT);
1062         break;
1063
1064       case TVO_HEX:
1065       case TVO_NATIVE:
1066       default:
1067         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
1068         break;
1069       }
1070       return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
1071
1072     case irms_float_number:
1073       return snprintf(buf, len, "%s%s%s", prefix, fc_print_dec(tv->value, tv_buf, sizeof(tv_buf)), suffix);
1074
1075     case irms_reference:
1076       if (tv==tarval_P_void) return snprintf(buf, len, "NULL");
1077       if (tv->value != NULL)
1078         if (tarval_is_entity(tv)) {
1079           if (get_entity_peculiarity((entity *)tv->value) == existent)
1080             return snprintf(buf, len, "%s%s%s", prefix, get_entity_ld_name((entity *)tv->value), suffix);
1081           else {
1082             if (mode_info->mode_output == TVO_NATIVE)
1083               return snprintf(buf, len, "NULL");
1084             else
1085               return snprintf(buf, len, "0");
1086           }
1087         }
1088         else {
1089           if (size > tv->length) {
1090             memcpy(buf, tv->value, tv->length);
1091             buf[tv->length] = '\0';
1092           }
1093           else {
1094             /* truncated */
1095             memcpy(buf, tv->value, size-1);
1096             buf[size-1] = '\0';
1097           }
1098           return tv->length;
1099         }
1100       else
1101         return snprintf(buf, len, "void");
1102
1103     case irms_internal_boolean:
1104       switch (mode_info->mode_output) {
1105
1106       case TVO_DECIMAL:
1107       case TVO_OCTAL:
1108       case TVO_HEX:
1109       case TVO_BINARY:
1110         return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
1111
1112       case TVO_NATIVE:
1113       default:
1114         return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
1115       }
1116
1117     case irms_control_flow:
1118     case irms_memory:
1119     case irms_auxiliary:
1120       return snprintf(buf, len, "<BAD>");
1121   }
1122
1123   return 0;
1124 }
1125
1126
1127 /**
1128  * Output of tarvals to stdio.
1129  */
1130 int tarval_printf(tarval *tv) {
1131   char buf[1024];
1132   int res;
1133
1134   res = tarval_snprintf(buf, sizeof(buf), tv);
1135   assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
1136   printf(buf);
1137   return res;
1138 }
1139
1140
1141 char *tarval_bitpattern(tarval *tv)
1142 {
1143   return NULL;
1144 }
1145
1146 /*
1147  * access to the bitpattern
1148  */
1149 unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs)
1150 {
1151   switch (get_mode_sort(tv->mode)) {
1152     case irms_int_number:
1153     case irms_character:
1154       return sc_sub_bits(tv->value, tv->length, byte_ofs);
1155
1156     case irms_float_number:
1157       return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1158
1159     default:
1160       return 0;
1161   }
1162 }
1163
1164 /*
1165  * Specify the output options of one mode.
1166  *
1167  * This functions stores the modinfo, so DO NOT DESTROY it.
1168  *
1169  * Returns zero on success.
1170  */
1171 int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo)
1172 {
1173   assert(mode);
1174
1175   mode->tv_priv = modeinfo;
1176   return 0;
1177 }
1178
1179 /*
1180  * Returns the output options of one mode.
1181  *
1182  * This functions returns the modinfo of a given mode.
1183  */
1184 const tarval_mode_info *tarval_get_mode_output_option(ir_mode *mode)
1185 {
1186   assert(mode);
1187
1188   return mode->tv_priv;
1189 }
1190
1191
1192 /* Identifying some tarvals ??? */
1193 /* Implemented in old tv.c as such:
1194  *   return 0 for additive neutral,
1195  *   1 for multiplicative neutral,
1196  *   -1 for bitwise-and neutral
1197  *   2 else
1198  *
1199  * Implemented for completeness */
1200 long tarval_classify(tarval *tv)
1201 {
1202   ANNOUNCE();
1203   if (!tv || tv == tarval_bad) return 2;
1204
1205   if (tv == get_mode_null(tv->mode)) return 0;
1206   else if (tv == get_mode_one(tv->mode)) return 1;
1207   else if ((get_mode_sort(tv->mode) == irms_int_number)
1208            && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
1209
1210   return 2;
1211 }
1212
1213 /*
1214  * Initialization of the tarval module: called before init_mode()
1215  */
1216 void init_tarval_1(void)
1217 {
1218   ANNOUNCE();
1219   /* initialize the sets holding the tarvals with a comparison function and
1220    * an initial size, which is the expected number of constants */
1221   tarvals = new_set(memcmp, TUNE_NCONSTANTS);
1222   values = new_set(memcmp, TUNE_NCONSTANTS);
1223   /* init with default precision */
1224   init_strcalc(0);
1225   /* init_fltcalc(0); not yet*/
1226   tarval_bad       = (tarval*)malloc(sizeof(tarval));
1227   tarval_undefined = (tarval*)malloc(sizeof(tarval));
1228   tarval_b_true    = (tarval*)malloc(sizeof(tarval));
1229   tarval_b_false   = (tarval*)malloc(sizeof(tarval));
1230   tarval_P_void    = (tarval*)malloc(sizeof(tarval));
1231 }
1232
1233 /**
1234  * default mode_info for output as HEX
1235  */
1236 static const tarval_mode_info hex_output = {
1237   TVO_HEX,
1238   "0x",
1239   NULL,
1240 };
1241
1242 /**
1243  * default mode_info for output as reference
1244  */
1245 static const tarval_mode_info reference_output = {
1246   TVO_NATIVE,
1247   "&(",
1248   ")",
1249 };
1250
1251
1252 /*
1253  * Initialization of the tarval module: called after init_mode()
1254  */
1255 void init_tarval_2(void)
1256 {
1257   ANNOUNCE();
1258
1259   tarval_bad->mode       = mode_BAD;
1260   tarval_undefined->mode = mode_ANY;
1261   tarval_b_true->mode    = mode_b;
1262   tarval_b_false->mode   = mode_b;
1263   tarval_P_void->mode    = mode_P;
1264
1265   /*
1266    * assign output modes that are compatible with the
1267    * old implementation: Hex output
1268    */
1269   tarval_set_mode_output_option(mode_U,  &hex_output);
1270   tarval_set_mode_output_option(mode_C,  &hex_output);
1271   tarval_set_mode_output_option(mode_Bs, &hex_output);
1272   tarval_set_mode_output_option(mode_Bu, &hex_output);
1273   tarval_set_mode_output_option(mode_Hs, &hex_output);
1274   tarval_set_mode_output_option(mode_Hu, &hex_output);
1275   tarval_set_mode_output_option(mode_Hs, &hex_output);
1276   tarval_set_mode_output_option(mode_Hu, &hex_output);
1277   tarval_set_mode_output_option(mode_Is, &hex_output);
1278   tarval_set_mode_output_option(mode_Iu, &hex_output);
1279   tarval_set_mode_output_option(mode_Ls, &hex_output);
1280   tarval_set_mode_output_option(mode_Lu, &hex_output);
1281   tarval_set_mode_output_option(mode_P,  &reference_output);
1282 }
1283
1284 /****************************************************************************
1285  *   end of tv.c
1286  ****************************************************************************/