Allocated predefined tarvals statically, this solves some
[libfirm] / ir / tv / tv.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/tv/tv.c
4  * Purpose:     Representation of and static computations on target machine
5  *              values.
6  * Author:      Mathias Heil
7  * Modified by:
8  * Created:
9  * CVS-ID:      $Id$
10  * Copyright:   (c) 2003 Universität Karlsruhe
11  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
12  */
13
14 /*
15  *    Values are stored in a format depending upon chosen arithmetic
16  *    module. Default uses strcalc and fltcalc.
17  *
18  */
19
20 /* This implementation assumes:
21  *  - target has IEEE-754 floating-point arithmetic.  */
22
23 #include <assert.h>         /* assertions */
24 #include <stdlib.h>         /* atoi() */
25 #include <string.h>         /* nice things for strings */
26 #include <strings.h>        /* strings.h also includes bsd only function strcasecmp */
27 #include <stdlib.h>
28 #include <alloca.h>
29
30 #include "tv_t.h"
31 #include "set.h"            /* to store tarvals in */
32 //#include "tune.h"           /* some constants */
33 #include "entity_t.h"       /* needed to store pointers to entities */
34 #include "irmode.h"         /* defines modes etc */
35 #include "irmode_t.h"
36 #include "irnode.h"         /* defines boolean return values (pnc_number)*/
37 #include "host.h"
38 #include "strcalc.h"
39 #include "fltcalc.h"
40
41 /** Size of hash tables.  Should correspond to average number of distinct constant
42     target values */
43 #define N_CONSTANTS     2048
44
45 /* XXX hack until theres's a proper interface */
46 #define BAD 1
47 #define SATURATE 2
48 #define WRAP 3
49 #define GET_OVERFLOW_MODE() BAD
50
51 /* unused, float to int doesn't work yet */
52 #define TRUNCATE 1
53 #define ROUND 2
54 #define GET_FLOAT_TO_INT_MODE() TRUNCATE
55
56 #define SWITCH_NOINFINITY 0
57 #define SWITCH_NODENORMALS 0
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 #ifdef __GNUC__
103 INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
104 #endif
105
106 INLINE static void tarval_verify(tarval *tv)
107 {
108   assert(tv);
109   assert(tv->mode);
110   assert(tv->value);
111
112   if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
113   if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;
114
115   if (!FIND_TARVAL(tv)) fail_verify(tv);
116   if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);
117
118   return;
119 }
120 #endif /* NDEBUG */
121
122 static int hash_tv(tarval *tv)
123 {
124   return ((unsigned int)tv->value ^ (unsigned int)tv->mode) + tv->length;
125 }
126
127 static int hash_val(const void *value, unsigned int length)
128 {
129   unsigned int i;
130   unsigned int hash = 0;
131
132   /* scramble the byte - array */
133   for (i = 0; i < length; i++)
134   {
135     hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
136     hash += (hash << 11) ^ (hash >> 17);
137   }
138
139   return hash;
140 }
141
142 /* finds tarval with value/mode or creates new tarval */
143 static tarval *get_tarval(const void *value, int length, ir_mode *mode)
144 {
145   tarval tv;
146
147   tv.mode = mode;
148   tv.length = length;
149   if (length > 0) {
150     /* if there already is such a value, it is returned, else value
151      * is copied into the set */
152     tv.value = INSERT_VALUE(value, length);
153   } else {
154     tv.value = value;
155   }
156   /* if there is such a tarval, it is returned, else tv is copied
157    * into the set */
158   return (tarval *)INSERT_TARVAL(&tv);
159 }
160
161 static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
162 {
163   switch (get_mode_sort(mode))
164   {
165     case irms_int_number:
166       if (sc_comp(value, get_mode_max(mode)->value) == 1) {
167         switch (GET_OVERFLOW_MODE()) {
168           case SATURATE:
169             return get_mode_max(mode);
170           case WRAP:
171             {
172               char *temp = alloca(sc_get_buffer_length());
173               char *diff = alloca(sc_get_buffer_length());
174               sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
175               sc_val_from_ulong(1, temp);
176               sc_add(diff, temp, diff);
177               sc_sub(value, diff, temp);
178               while (sc_comp(temp, get_mode_max(mode)->value) == 1)
179                 sc_sub(temp, diff, temp);
180               return get_tarval(temp, length, mode);
181             }
182           case BAD:
183             return tarval_bad;
184           default:
185             return get_tarval(value, length, mode);
186         }
187       }
188       if (sc_comp(value, get_mode_min(mode)->value) == -1) {
189         switch (GET_OVERFLOW_MODE()) {
190           case SATURATE:
191             return get_mode_min(mode);
192           case WRAP:
193             {
194               char *temp = alloca(sc_get_buffer_length());
195               char *diff = alloca(sc_get_buffer_length());
196               sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
197               sc_val_from_ulong(1, temp);
198               sc_add(diff, temp, diff);
199               sc_add(value, diff, temp);
200               while (sc_comp(temp, get_mode_max(mode)->value) == 1)
201                 sc_add(temp, diff, temp);
202               return get_tarval(temp, length, mode);
203             }
204           case BAD:
205             return tarval_bad;
206           default:
207             return get_tarval(value, length, mode);
208         }
209       }
210       break;
211
212     case irms_float_number:
213       if (SWITCH_NOINFINITY && fc_is_inf(value))
214       {
215         return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
216       }
217
218       if (SWITCH_NODENORMALS && fc_is_subnormal(value))
219       {
220         return get_mode_null(mode);
221       }
222       break;
223     default:
224       break;
225   }
226   return get_tarval(value, length, mode);
227 }
228
229
230 /*
231  *   public variables declared in tv.h
232  */
233 static tarval reserved_tv[5];
234
235 tarval *tarval_bad       = &reserved_tv[0];
236 tarval *tarval_undefined = &reserved_tv[1];
237 tarval *tarval_b_false   = &reserved_tv[2];
238 tarval *tarval_b_true    = &reserved_tv[3];
239 tarval *tarval_P_void    = &reserved_tv[4];
240
241 /*
242  *   public functions declared in tv.h
243  */
244
245 /*
246  * Constructors =============================================================
247  */
248 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
249 {
250   ANNOUNCE();
251   assert(str);
252   assert(len);
253   assert(mode);
254
255   switch (get_mode_sort(mode))
256   {
257     case irms_control_flow:
258     case irms_memory:
259     case irms_auxiliary:
260       assert(0);
261       break;
262
263     case irms_internal_boolean:
264       /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
265       if (strcasecmp(str, "true")) return tarval_b_true;
266       else if (strcasecmp(str, "false")) return tarval_b_true;
267       else
268         /* XXX This is C semantics */
269         return atoi(str) ? tarval_b_true : tarval_b_false;
270
271     case irms_float_number:
272       switch(get_mode_size_bits(mode)) {
273         case 32:
274           fc_val_from_str(str, len, 8, 23, NULL);
275           break;
276         case 64:
277           fc_val_from_str(str, len, 11, 52, NULL);
278           break;
279         case 80:
280           fc_val_from_str(str, len, 15, 64, NULL);
281           break;
282       }
283       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
284
285     case irms_int_number:
286     case irms_character:
287       sc_val_from_str(str, len, NULL);
288       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
289
290     case irms_reference:
291       return get_tarval(str, len, mode);
292   }
293
294   assert(0);  /* can't be reached, can it? */
295   return NULL;
296 }
297
298 /*
299  * helper function, create a tarval from long
300  */
301 tarval *new_tarval_from_long(long l, ir_mode *mode)
302 {
303   ANNOUNCE();
304   assert(mode && !((get_mode_sort(mode) == irms_memory)||(get_mode_sort(mode)==irms_control_flow)||(get_mode_sort(mode)==irms_auxiliary)));
305
306   switch(get_mode_sort(mode))
307   {
308     case irms_internal_boolean:
309       /* XXX C semantics ! */
310       return l ? tarval_b_true : tarval_b_false ;
311
312     case irms_int_number:
313     case irms_character:
314       sc_val_from_long(l, NULL);
315       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
316
317     case irms_float_number:
318       return new_tarval_from_double((long double)l, mode);
319
320     case irms_reference:
321       return l ? tarval_bad : get_tarval(NULL, 0, mode);  /* null pointer or tarval_bad */
322
323     default:
324       assert(0);
325   }
326   return NULL;
327 }
328
329 /* returns non-zero if can be converted to long */
330 int tarval_is_long(tarval *tv)
331 {
332   ANNOUNCE();
333   if (get_mode_sort(tv->mode) != irms_int_number) return 0;
334
335   if (get_mode_size_bits(tv->mode) > sizeof(long)<<3)
336   {
337     /* the value might be too big to fit in a long */
338     sc_max_from_bits(sizeof(long)<<3, 0, NULL);
339     if (sc_comp(sc_get_buffer(), tv->value) == -1)
340     {
341       /* really doesn't fit */
342       return 0;
343     }
344   }
345   return 1;
346 }
347
348 /* this might overflow the machine's long, so use only with small values */
349 long tarval_to_long(tarval* tv)
350 {
351   ANNOUNCE();
352   assert(tarval_is_long(tv) && "tarval too big to fit in long");
353
354   return sc_val_to_long(tv->value);
355 }
356
357 tarval *new_tarval_from_double(long double d, ir_mode *mode)
358 {
359   ANNOUNCE();
360   assert(mode && (get_mode_sort(mode) == irms_float_number));
361
362   switch (get_mode_size_bits(mode)) {
363     case 32:
364       fc_val_from_float(d, 8, 23, NULL);
365       break;
366     case 64:
367       fc_val_from_float(d, 11, 52, NULL);
368       break;
369     case 80:
370       fc_val_from_float(d, 15, 64, NULL);
371       break;
372   }
373   return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
374 }
375
376 /* returns non-zero if can be converted to double */
377 int tarval_is_double(tarval *tv)
378 {
379   ANNOUNCE();
380   assert(tv);
381
382   return (get_mode_sort(tv->mode) == irms_float_number);
383 }
384
385 long double tarval_to_double(tarval *tv)
386 {
387   ANNOUNCE();
388   assert(tarval_is_double(tv));
389
390   return fc_val_to_float(tv->value);
391 }
392
393 /* The tarval represents the address of the entity.  As the address must
394    be constant the entity must have as owner the global type. */
395 tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
396 {
397   ANNOUNCE();
398   assert(ent);
399   assert(mode && (get_mode_sort(mode) == irms_reference));
400
401   return get_tarval((void *)ent, 0, mode);
402 }
403 int tarval_is_entity(tarval *tv)
404 {
405   ANNOUNCE();
406   assert(tv);
407   /* tv->value == NULL means dereferencing a null pointer */
408   return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0)
409           && (tv != tarval_P_void));
410 }
411
412 entity *tarval_to_entity(tarval *tv)
413 {
414   ANNOUNCE();
415   assert(tv);
416
417   if (tarval_is_entity(tv))
418     return (entity *)tv->value;
419   else {
420     assert(0 && "tarval did not represent an entity");
421     return NULL;
422   }
423 }
424
425 void free_tarval_entity(entity *ent) {
426   /* There can be a tarval referencing this entity.  Even if the
427      tarval is not used by the code any more, it can still reference
428      the entity as tarvals live indepently of the entity referenced.
429      Further the tarval is hashed into a set. If a hash function
430      evaluation happens to collide with this tarval, we will vrfy that
431      it contains a proper entity and we will crash if the entity is
432      freed.
433
434      Unluckily, tarvals can neither be changed nor deleted, and to find
435      one, all existing reference modes have to be tried -> a facility
436      to retrieve all modes of a kind is needed. */
437   ANNOUNCE();
438 }
439
440 /*
441  * Access routines for tarval fields ========================================
442  */
443 ir_mode *get_tarval_mode (tarval *tv)       /* get the mode of the tarval */
444 {
445   ANNOUNCE();
446   assert(tv);
447   return tv->mode;
448 }
449
450 /*
451  * Special value query functions ============================================
452  *
453  * These functions calculate and return a tarval representing the requested
454  * value.
455  * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
456  * functions, but these are stored on initialization of the irmode module and
457  * therefore the irmode functions should be prefered to the functions below.
458  */
459
460 tarval *get_tarval_bad(void)
461 {
462   ANNOUNCE();
463   return tarval_bad;
464 }
465 tarval *get_tarval_undefined(void)
466 {
467   ANNOUNCE();
468   return tarval_undefined;
469 }
470 tarval *get_tarval_b_false(void)
471 {
472   ANNOUNCE();
473   return tarval_b_false;
474 }
475 tarval *get_tarval_b_true(void)
476 {
477   ANNOUNCE();
478   return tarval_b_true;
479 }
480 tarval *get_tarval_P_void(void)
481 {
482   ANNOUNCE();
483   return tarval_P_void;
484 }
485
486 tarval *get_tarval_max(ir_mode *mode)
487 {
488   ANNOUNCE();
489   assert(mode);
490
491   switch(get_mode_sort(mode))
492   {
493     case irms_reference:
494     case irms_control_flow:
495     case irms_memory:
496     case irms_auxiliary:
497       assert(0);
498       break;
499
500     case irms_internal_boolean:
501       return tarval_b_true;
502
503     case irms_float_number:
504       switch(get_mode_size_bits(mode))
505       {
506         case 32:
507           fc_get_max(8, 23, NULL);
508           break;
509         case 64:
510           fc_get_max(11, 52, NULL);
511           break;
512         case 80:
513           fc_get_max(15, 64, NULL);
514           break;
515       }
516       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
517
518     case irms_int_number:
519     case irms_character:
520       sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
521       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
522   }
523   return tarval_bad;
524 }
525
526 tarval *get_tarval_min(ir_mode *mode)
527 {
528   ANNOUNCE();
529   assert(mode);
530
531   switch(get_mode_sort(mode))
532   {
533     case irms_reference:
534     case irms_control_flow:
535     case irms_memory:
536     case irms_auxiliary:
537       assert(0);
538       break;
539
540     case irms_internal_boolean:
541       return tarval_b_false;
542
543     case irms_float_number:
544       switch(get_mode_size_bits(mode))
545       {
546         case 32:
547           fc_get_min(8, 23, NULL);
548           break;
549         case 64:
550           fc_get_min(11, 52, NULL);
551           break;
552         case 80:
553           fc_get_min(15, 64, NULL);
554           break;
555       }
556       return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
557
558     case irms_int_number:
559     case irms_character:
560       sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
561       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
562   }
563   return tarval_bad;
564 }
565
566 tarval *get_tarval_null(ir_mode *mode)
567 {
568   ANNOUNCE();
569   assert(mode);
570
571   switch(get_mode_sort(mode))
572   {
573     case irms_control_flow:
574     case irms_memory:
575     case irms_auxiliary:
576     case irms_internal_boolean:
577       assert(0);
578       break;
579
580     case irms_float_number:
581       return new_tarval_from_double(0.0, mode);
582
583     case irms_int_number:
584     case irms_character:
585       return new_tarval_from_long(0l,  mode);
586
587     case irms_reference:
588       return tarval_P_void;
589   }
590   return tarval_bad;
591 }
592
593 tarval *get_tarval_one(ir_mode *mode)
594 {
595   ANNOUNCE();
596   assert(mode);
597
598   switch(get_mode_sort(mode))
599   {
600     case irms_control_flow:
601     case irms_memory:
602     case irms_auxiliary:
603     case irms_internal_boolean:
604     case irms_reference:
605       assert(0);
606       break;
607
608     case irms_float_number:
609       return new_tarval_from_double(1.0, mode);
610
611     case irms_int_number:
612     case irms_character:
613       return new_tarval_from_long(1l, mode);
614       break;
615   }
616   return tarval_bad;
617 }
618
619 tarval *get_tarval_nan(ir_mode *mode)
620 {
621   ANNOUNCE();
622   assert(mode);
623
624   if (get_mode_sort(mode) == irms_float_number) {
625     switch(get_mode_size_bits(mode))
626     {
627       case 32:
628         fc_get_qnan(8, 23, NULL);
629         break;
630       case 64:
631         fc_get_qnan(11, 52, NULL);
632         break;
633       case 80:
634         fc_get_qnan(15, 64, NULL);
635         break;
636     }
637     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
638   }
639   else {
640     assert(0 && "tarval is not floating point");
641     return tarval_bad;
642   }
643 }
644
645 tarval *get_tarval_inf(ir_mode *mode)
646 {
647   ANNOUNCE();
648   assert(mode);
649
650   if (get_mode_sort(mode) == irms_float_number) {
651     switch(get_mode_size_bits(mode))
652     {
653       case 32:
654         fc_get_plusinf(8, 23, NULL);
655         break;
656       case 64:
657         fc_get_plusinf(11, 52, NULL);
658         break;
659       case 80:
660         fc_get_plusinf(15, 64, NULL);
661         break;
662     }
663     return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
664   }
665   else {
666     assert(0 && "tarval is not floating point");
667     return tarval_bad;
668   }
669 }
670
671 /*
672  * Arithmethic operations on tarvals ========================================
673  */
674
675 /*
676  * test if negative number, 1 means 'yes'
677  */
678 int tarval_is_negative(tarval *a)
679 {
680   ANNOUNCE();
681   assert(a);
682
683   switch (get_mode_sort(a->mode))
684   {
685     case irms_int_number:
686       if (!mode_is_signed(a->mode)) return 0;
687       else
688         return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
689
690     case irms_float_number:
691       return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
692
693     default:
694       assert(0 && "not implemented");
695       return 0;
696   }
697 }
698
699 /*
700  * test if null, 1 means 'yes'
701  */
702 int tarval_is_null(tarval *a)
703 {
704   ir_mode *m = get_tarval_mode(a);
705
706   return a == get_tarval_null(m);
707 }
708
709 /*
710  * comparison
711  */
712 pnc_number tarval_cmp(tarval *a, tarval *b)
713 {
714   ANNOUNCE();
715   assert(a);
716   assert(b);
717
718   if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
719   if (a == tarval_undefined || b == tarval_undefined) return False;
720   if (a == b) return Eq;
721   if (get_tarval_mode(a) != get_tarval_mode(b)) return False;
722
723   /* Here the two tarvals are unequal and of the same mode */
724   switch (get_mode_sort(a->mode))
725   {
726     case irms_control_flow:
727     case irms_memory:
728     case irms_auxiliary:
729     case irms_reference:
730       return False;
731
732     case irms_float_number:
733       switch (fc_comp(a->value, b->value)) {
734         case -1: return Lt;
735         case  0: assert(0 && "different tarvals compare equal"); return Eq;
736         case  1: return Gt;
737         case  2: return Uo;
738         default: return False;
739       }
740     case irms_int_number:
741     case irms_character:
742       return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
743
744     case irms_internal_boolean:
745       return (a == tarval_b_true)?(Gt):(Lt);
746   }
747   return False;
748 }
749
750 /*
751  * convert to other mode
752  */
753 tarval *tarval_convert_to(tarval *src, ir_mode *m)
754 {
755   char *buffer;
756
757   ANNOUNCE();
758   assert(src);
759   assert(m);
760
761   if (src->mode == m) return src;
762
763   switch (get_mode_sort(src->mode))
764   {
765     case irms_control_flow:
766     case irms_memory:
767     case irms_auxiliary:
768       break;
769
770     /* cast float to something */
771     case irms_float_number:
772       switch (get_mode_sort(m)) {
773         case irms_float_number:
774           switch (get_mode_size_bits(m))
775           {
776             case 32:
777               fc_cast(src->value, 8, 23, NULL);
778               break;
779             case 64:
780               fc_cast(src->value, 11, 52, NULL);
781               break;
782             case 80:
783               fc_cast(src->value, 15, 64, NULL);
784               break;
785             default:
786               break;
787           }
788           return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
789           break;
790
791         case irms_int_number:
792           switch (GET_FLOAT_TO_INT_MODE())
793           {
794             case TRUNCATE:
795               fc_int(src->value, NULL);
796               break;
797             case ROUND:
798               fc_rnd(src->value, NULL);
799               break;
800             default:
801               break;
802           }
803           /* XXX floating point unit can't produce a value in integer
804            * representation
805            * an intermediate representation is needed here first. */
806           /*  return get_tarval(); */
807           return tarval_bad;
808           break;
809
810         default:
811           /* the rest can't be converted */
812           return tarval_bad;
813       }
814       break;
815
816     /* cast int to something */
817     case irms_int_number:
818       switch (get_mode_sort(m)) {
819         case irms_int_number:
820         case irms_character:
821           return get_tarval_overflow(src->value, src->length, m);
822
823         case irms_internal_boolean:
824           /* XXX C semantics */
825           if (src == get_mode_null(src->mode)) return tarval_b_false;
826           else return tarval_b_true;
827
828         case irms_float_number:
829           /* XXX floating point unit does not understand internal integer
830            * representation, convert to string first, then create float from
831            * string */
832           buffer = alloca(100);
833           /* decimal string representation because hexadecimal output is
834            * interpreted unsigned by fc_val_from_str, so this is a HACK */
835           snprintf(buffer, 100, "%s",
836                    sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC));
837           switch (get_mode_size_bits(m))
838           {
839             case 32:
840               fc_val_from_str(buffer, 0, 8, 23, NULL);
841               break;
842             case 64:
843               fc_val_from_str(buffer, 0, 11, 52, NULL);
844               break;
845             case 80:
846               fc_val_from_str(buffer, 0, 15, 64, NULL);
847               break;
848           }
849           return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
850
851         default:
852           break;
853       }
854       break;
855
856     case irms_internal_boolean:
857       switch (get_mode_sort(m))
858       {
859         case irms_int_number:
860           if (src == tarval_b_true) return get_mode_one(m);
861           else return get_mode_null(m);
862
863         default:
864           break;
865       }
866       break;
867
868     case irms_character:
869       break;
870     case irms_reference:
871       break;
872   }
873
874   return tarval_bad;
875 }
876
877 /*
878  * negation
879  */
880 tarval *tarval_neg(tarval *a)
881 {
882   char *buffer;
883
884   ANNOUNCE();
885   assert(a);
886   assert(mode_is_num(a->mode)); /* negation only for numerical values */
887   assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
888
889   switch (get_mode_sort(a->mode))
890   {
891     case irms_int_number:
892       buffer = alloca(sc_get_buffer_length());
893       sc_neg(a->value, buffer);
894       return get_tarval_overflow(buffer, a->length, a->mode);
895
896     case irms_float_number:
897       fc_neg(a->value, NULL);
898       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
899
900     default:
901       return tarval_bad;
902   }
903 }
904
905 /*
906  * addition
907  */
908 tarval *tarval_add(tarval *a, tarval *b)
909 {
910   char *buffer;
911
912   ANNOUNCE();
913   assert(a);
914   assert(b);
915   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
916
917   switch (get_mode_sort(a->mode))
918   {
919     case irms_character:
920     case irms_int_number:
921       /* modes of a,b are equal, so result has mode of a as this might be the character */
922       buffer = alloca(sc_get_buffer_length());
923       sc_add(a->value, b->value, buffer);
924       return get_tarval_overflow(buffer, a->length, a->mode);
925
926     case irms_float_number:
927       fc_add(a->value, b->value, NULL);
928       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
929
930     default:
931       return tarval_bad;
932   }
933 }
934
935 /*
936  * subtraction
937  */
938 tarval *tarval_sub(tarval *a, tarval *b)
939 {
940   char *buffer;
941
942   ANNOUNCE();
943   assert(a);
944   assert(b);
945   assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode)));
946
947   switch (get_mode_sort(a->mode))
948   {
949     case irms_character:
950     case irms_int_number:
951       /* modes of a,b are equal, so result has mode of a as this might be the character */
952       buffer = alloca(sc_get_buffer_length());
953       sc_sub(a->value, b->value, buffer);
954       return get_tarval_overflow(buffer, a->length, a->mode);
955
956     case irms_float_number:
957       fc_sub(a->value, b->value, NULL);
958       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
959
960     default:
961       return tarval_bad;
962   }
963 }
964
965 /*
966  * multiplication
967  */
968 tarval *tarval_mul(tarval *a, tarval *b)
969 {
970   char *buffer;
971
972   ANNOUNCE();
973   assert(a);
974   assert(b);
975   assert((a->mode == b->mode) && mode_is_num(a->mode));
976
977   switch (get_mode_sort(a->mode))
978   {
979     case irms_int_number:
980       /* modes of a,b are equal */
981       buffer = alloca(sc_get_buffer_length());
982       sc_mul(a->value, b->value, buffer);
983       return get_tarval_overflow(buffer, a->length, a->mode);
984
985     case irms_float_number:
986       fc_mul(a->value, b->value, NULL);
987       return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
988
989     default:
990       return tarval_bad;
991   }
992 }
993
994 /*
995  * floating point division
996  */
997 tarval *tarval_quo(tarval *a, tarval *b)
998 {
999   ANNOUNCE();
1000   assert(a);
1001   assert(b);
1002   assert((a->mode == b->mode) && mode_is_float(a->mode));
1003
1004   fc_div(a->value, b->value, NULL);
1005   return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1006 }
1007
1008 /*
1009  * integer division
1010  * overflow is impossible, but look out for division by zero
1011  */
1012 tarval *tarval_div(tarval *a, tarval *b)
1013 {
1014   ANNOUNCE();
1015   assert(a);
1016   assert(b);
1017   assert((a->mode == b->mode) && mode_is_int(a->mode));
1018
1019   /* x/0 error */
1020   if (b == get_mode_null(b->mode)) return tarval_bad;
1021   /* modes of a,b are equal */
1022   sc_div(a->value, b->value, NULL);
1023   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1024 }
1025
1026 /*
1027  * remainder
1028  * overflow is impossible, but look out for division by zero
1029  */
1030 tarval *tarval_mod(tarval *a, tarval *b)
1031 {
1032   ANNOUNCE();
1033   assert(a);
1034   assert(b);
1035   assert((a->mode == b->mode) && mode_is_int(a->mode));
1036
1037   /* x/0 error */
1038   if (b == get_mode_null(b->mode)) return tarval_bad;
1039   /* modes of a,b are equal */
1040   sc_mod(a->value, b->value, NULL);
1041   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1042 }
1043
1044 /*
1045  * absolute value
1046  */
1047 tarval *tarval_abs(tarval *a)
1048 {
1049   char *buffer;
1050
1051   ANNOUNCE();
1052   assert(a);
1053   assert(mode_is_num(a->mode));
1054
1055   switch (get_mode_sort(a->mode))
1056   {
1057     case irms_int_number:
1058       if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1)
1059       {
1060         buffer = alloca(sc_get_buffer_length());
1061         sc_neg(a->value, buffer);
1062         return get_tarval_overflow(buffer, a->length, a->mode);
1063       }
1064       return a;
1065
1066     case irms_float_number:
1067       if (fc_comp(a->value, get_mode_null(a->mode)->value) == -1)
1068       {
1069         fc_neg(a->value, NULL);
1070         return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1071       }
1072       return a;
1073
1074     default:
1075       return tarval_bad;
1076   }
1077   return tarval_bad;
1078 }
1079
1080 /*
1081  * bitwise and
1082  */
1083 tarval *tarval_and(tarval *a, tarval *b)
1084 {
1085   ANNOUNCE();
1086   assert(a);
1087   assert(b);
1088   assert(a->mode == b->mode);
1089
1090   switch(get_mode_sort(a->mode))
1091   {
1092     case irms_internal_boolean:
1093       return (a == tarval_b_false) ? a : b;
1094
1095     case irms_int_number:
1096       sc_and(a->value, b->value, NULL);
1097       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1098
1099     default:
1100       assert(0 && "operation not defined on mode");
1101       return tarval_bad;
1102   }
1103 }
1104
1105 /*
1106  * bitwise or
1107  */
1108 tarval *tarval_or (tarval *a, tarval *b)
1109 {
1110   ANNOUNCE();
1111   assert(a);
1112   assert(b);
1113   assert(a->mode == b->mode);
1114
1115   switch (get_mode_sort(a->mode))
1116   {
1117     case irms_internal_boolean:
1118       return (a == tarval_b_true) ? a : b;
1119
1120     case irms_int_number:
1121       sc_or(a->value, b->value, NULL);
1122       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1123
1124     default:
1125       assert(0 && "operation not defined on mode");
1126       return tarval_bad;;
1127   }
1128 }
1129
1130 /*
1131  * bitwise exclusive or (xor)
1132  */
1133 tarval *tarval_eor(tarval *a, tarval *b)
1134 {
1135   ANNOUNCE();
1136   assert(a);
1137   assert(b);
1138   assert((a->mode == b->mode));
1139
1140   switch (get_mode_sort(a->mode))
1141   {
1142     case irms_internal_boolean:
1143       return (a == b)? tarval_b_false : tarval_b_true;
1144
1145     case irms_int_number:
1146       sc_or(a->value, b->value, NULL);
1147       return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1148
1149     default:
1150       assert(0 && "operation not defined on mode");
1151       return tarval_bad;;
1152   }
1153 }
1154
1155 /*
1156  * bitwise left shift
1157  */
1158 tarval *tarval_shl(tarval *a, tarval *b)
1159 {
1160   ANNOUNCE();
1161   assert(a);
1162   assert(b);
1163   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1164
1165   sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1166   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1167 }
1168
1169 /*
1170  * bitwise unsigned right shift
1171  */
1172 tarval *tarval_shr(tarval *a, tarval *b)
1173 {
1174   ANNOUNCE();
1175   assert(a);
1176   assert(b);
1177   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1178
1179   sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1180   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1181 }
1182
1183 /*
1184  * bitwise signed right shift
1185  */
1186 tarval *tarval_shrs(tarval *a, tarval *b)
1187 {
1188   ANNOUNCE();
1189   assert(a);
1190   assert(b);
1191   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1192
1193   sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1194   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1195 }
1196
1197 /*
1198  * bitwise rotation
1199  */
1200 tarval *tarval_rot(tarval *a, tarval *b)
1201 {
1202   ANNOUNCE();
1203   assert(a);
1204   assert(b);
1205   assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1206
1207   sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1208   return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1209 }
1210
1211
1212 /*
1213  * Output of tarvals
1214  */
1215 int tarval_snprintf(char *buf, size_t len, tarval *tv)
1216 {
1217   static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
1218
1219   const char *str;
1220   char tv_buf[100];
1221   const tarval_mode_info *mode_info;
1222   const char *prefix, *suffix;
1223
1224   ANNOUNCE();
1225
1226   mode_info = tv->mode->tv_priv;
1227   if (! mode_info)
1228     mode_info = &default_info;
1229   prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
1230   suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
1231
1232   switch (get_mode_sort(tv->mode))
1233   {
1234     case irms_int_number:
1235     case irms_character:
1236       switch (mode_info->mode_output) {
1237
1238       case TVO_DECIMAL:
1239         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC);
1240         break;
1241
1242       case TVO_OCTAL:
1243         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT);
1244         break;
1245
1246       case TVO_HEX:
1247       case TVO_NATIVE:
1248       default:
1249         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX);
1250         break;
1251       }
1252       return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
1253
1254     case irms_float_number:
1255       switch (mode_info->mode_output) {
1256         case TVO_HEX:
1257           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_PACKED), suffix);
1258
1259         case TVO_HEXFLOAT:
1260           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_HEX), suffix);
1261
1262         case TVO_FLOAT:
1263         case TVO_NATIVE:
1264         default:
1265           return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_DEC), suffix);
1266       }
1267       break;
1268
1269     case irms_reference:
1270       if (tv==tarval_P_void) return snprintf(buf, len, "NULL");
1271       if (tv->value != NULL)
1272         if (tarval_is_entity(tv)) {
1273           if (get_entity_peculiarity((entity *)tv->value) == peculiarity_existent)
1274             return snprintf(buf, len, "%s%s%s", prefix, get_entity_ld_name((entity *)tv->value), suffix);
1275           else {
1276             if (mode_info->mode_output == TVO_NATIVE)
1277               return snprintf(buf, len, "NULL");
1278             else
1279               return snprintf(buf, len, "0");
1280           }
1281         }
1282         else {
1283           if (size > tv->length) {
1284             memcpy(buf, tv->value, tv->length);
1285             buf[tv->length] = '\0';
1286           }
1287           else {
1288             /* truncated */
1289             memcpy(buf, tv->value, size-1);
1290             buf[size-1] = '\0';
1291           }
1292           return tv->length;
1293         }
1294       else
1295         return snprintf(buf, len, "void");
1296
1297     case irms_internal_boolean:
1298       switch (mode_info->mode_output) {
1299
1300       case TVO_DECIMAL:
1301       case TVO_OCTAL:
1302       case TVO_HEX:
1303       case TVO_BINARY:
1304         return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
1305
1306       case TVO_NATIVE:
1307       default:
1308         return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
1309       }
1310
1311     case irms_control_flow:
1312     case irms_memory:
1313     case irms_auxiliary:
1314       return snprintf(buf, len, "<BAD>");
1315   }
1316
1317   return 0;
1318 }
1319
1320
1321 /**
1322  * Output of tarvals to stdio.
1323  */
1324 int tarval_printf(tarval *tv) {
1325   char buf[1024];
1326   int res;
1327
1328   res = tarval_snprintf(buf, sizeof(buf), tv);
1329   assert(res < sizeof(buf) && "buffer to small for tarval_snprintf");
1330   printf(buf);
1331   return res;
1332 }
1333
1334
1335 char *tarval_bitpattern(tarval *tv)
1336 {
1337   return NULL;
1338 }
1339
1340 /*
1341  * access to the bitpattern
1342  */
1343 unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs)
1344 {
1345   switch (get_mode_sort(tv->mode)) {
1346     case irms_int_number:
1347     case irms_character:
1348       return sc_sub_bits(tv->value, tv->length, byte_ofs);
1349
1350     case irms_float_number:
1351       return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1352
1353     default:
1354       return 0;
1355   }
1356 }
1357
1358 /*
1359  * Specify the output options of one mode.
1360  *
1361  * This functions stores the modinfo, so DO NOT DESTROY it.
1362  *
1363  * Returns zero on success.
1364  */
1365 int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo)
1366 {
1367   assert(mode);
1368
1369   mode->tv_priv = modeinfo;
1370   return 0;
1371 }
1372
1373 /*
1374  * Returns the output options of one mode.
1375  *
1376  * This functions returns the modinfo of a given mode.
1377  */
1378 const tarval_mode_info *tarval_get_mode_output_option(ir_mode *mode)
1379 {
1380   assert(mode);
1381
1382   return mode->tv_priv;
1383 }
1384
1385
1386 /* Identifying some tarvals ??? */
1387 /* Implemented in old tv.c as such:
1388  *   return 0 for additive neutral,
1389  *   1 for multiplicative neutral,
1390  *   -1 for bitwise-and neutral
1391  *   2 else
1392  *
1393  * Implemented for compatibility */
1394 long tarval_classify(tarval *tv)
1395 {
1396   ANNOUNCE();
1397   if (!tv || tv == tarval_bad) return 2;
1398
1399   if (tv == get_mode_null(tv->mode)) return 0;
1400   else if (tv == get_mode_one(tv->mode)) return 1;
1401   else if ((get_mode_sort(tv->mode) == irms_int_number)
1402            && (tv == new_tarval_from_long(-1, tv->mode))) return -1;
1403
1404   return 2;
1405 }
1406
1407 /**
1408  * default mode_info for output as HEX
1409  */
1410 static const tarval_mode_info hex_output = {
1411   TVO_HEX,
1412   "0x",
1413   NULL,
1414 };
1415
1416 /**
1417  * default mode_info for output as reference
1418  */
1419 static const tarval_mode_info reference_output = {
1420   TVO_NATIVE,
1421   "&(",
1422   ")",
1423 };
1424
1425
1426 /*
1427  * Initialization of the tarval module: called before init_mode()
1428  */
1429 void init_tarval_1(void)
1430 {
1431   ANNOUNCE();
1432   /* initialize the sets holding the tarvals with a comparison function and
1433    * an initial size, which is the expected number of constants */
1434   tarvals = new_set(memcmp, N_CONSTANTS);
1435   values  = new_set(memcmp, N_CONSTANTS);
1436   /* init strcalc with precision of 68 to support floating point values with 64
1437    * bit mantissa (needs extra bits for rounding and overflow) */
1438   init_strcalc(68);
1439   init_fltcalc(0);
1440 }
1441
1442 /*
1443  * Initialization of the tarval module: called after init_mode()
1444  */
1445 void init_tarval_2(void)
1446 {
1447   ANNOUNCE();
1448
1449   tarval_bad->mode       = mode_BAD;
1450   tarval_undefined->mode = mode_ANY;
1451   tarval_b_true->mode    = mode_b;
1452   tarval_b_false->mode   = mode_b;
1453   tarval_P_void->mode    = mode_P;
1454
1455   /*
1456    * assign output modes that are compatible with the
1457    * old implementation: Hex output
1458    */
1459   tarval_set_mode_output_option(mode_U,  &hex_output);
1460   tarval_set_mode_output_option(mode_C,  &hex_output);
1461   tarval_set_mode_output_option(mode_Bs, &hex_output);
1462   tarval_set_mode_output_option(mode_Bu, &hex_output);
1463   tarval_set_mode_output_option(mode_Hs, &hex_output);
1464   tarval_set_mode_output_option(mode_Hu, &hex_output);
1465   tarval_set_mode_output_option(mode_Is, &hex_output);
1466   tarval_set_mode_output_option(mode_Iu, &hex_output);
1467   tarval_set_mode_output_option(mode_Ls, &hex_output);
1468   tarval_set_mode_output_option(mode_Lu, &hex_output);
1469   tarval_set_mode_output_option(mode_P,  &reference_output);
1470 }
1471
1472 /****************************************************************************
1473  *   end of tv.c
1474  ****************************************************************************/