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