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