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