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