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