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