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