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