renamed node type Rot to Rotl to make clear that this is a LEFT rotation
[libfirm] / ir / tv / tv.c
1 /*
2  * Copyright (C) 1995-2008 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 static int cmp_tv(const void *p1, const void *p2, size_t n) {
162         const tarval *tv1 = p1;
163         const tarval *tv2 = p2;
164         (void) n;
165
166         assert(tv1->kind == k_tarval);
167         assert(tv2->kind == k_tarval);
168         if(tv1->mode < tv2->mode)
169                 return -1;
170         if(tv1->mode > tv2->mode)
171                 return 1;
172         if(tv1->length < tv2->length)
173                 return -1;
174         if(tv1->length > tv2->length)
175                 return 1;
176         if(tv1->value < tv2->value)
177                 return -1;
178         if(tv1->value > tv2->value)
179                 return 1;
180
181         return 0;
182 }
183
184 /** finds tarval with value/mode or creates new tarval */
185 static tarval *get_tarval(const void *value, int length, ir_mode *mode) {
186         tarval tv;
187
188         tv.kind   = k_tarval;
189         tv.mode   = mode;
190         tv.length = length;
191         if (length > 0) {
192                 /* if there already is such a value, it is returned, else value
193                  * is copied into the set */
194                 char *temp = alloca(length);
195                 memcpy(temp, value, length);
196                 if (get_mode_arithmetic(mode) == irma_twos_complement) {
197                         sign_extend(temp, mode);
198                 }
199                 tv.value = INSERT_VALUE(temp, length);
200         } else {
201                 tv.value = value;
202         }
203         /* if there is such a tarval, it is returned, else tv is copied
204          * into the set */
205         return (tarval *)INSERT_TARVAL(&tv);
206 }
207
208 /**
209  * handle overflow
210  */
211 static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
212 {
213         char *temp;
214
215         switch (get_mode_sort(mode)) {
216         case irms_reference:
217                 /* addresses always wrap around */
218                 temp = alloca(sc_get_buffer_length());
219                 memcpy(temp, value, sc_get_buffer_length());
220                 sc_truncate(get_mode_size_bits(mode), temp);
221                 /* the sc_ module expects that all bits are set ... */
222                 sign_extend(temp, mode);
223                 return get_tarval(temp, length, mode);
224
225         case irms_int_number:
226                 if (sc_comp(value, get_mode_max(mode)->value) == 1) {
227                         switch (GET_OVERFLOW_MODE()) {
228                         case TV_OVERFLOW_SATURATE:
229                                 return get_mode_max(mode);
230                         case TV_OVERFLOW_WRAP:
231                                 temp = alloca(sc_get_buffer_length());
232                                 memcpy(temp, value, sc_get_buffer_length());
233                                 sc_truncate(get_mode_size_bits(mode), temp);
234                                 /* the sc_ module expects that all bits are set ... */
235                                 sign_extend(temp, mode);
236                                 return get_tarval(temp, length, mode);
237                         case TV_OVERFLOW_BAD:
238                                 return tarval_bad;
239                         default:
240                                 return get_tarval(value, length, mode);
241                         }
242                 }
243                 if (sc_comp(value, get_mode_min(mode)->value) == -1) {
244                         switch (GET_OVERFLOW_MODE()) {
245                         case TV_OVERFLOW_SATURATE:
246                                 return get_mode_min(mode);
247                         case TV_OVERFLOW_WRAP: {
248                                 char *temp = alloca(sc_get_buffer_length());
249                                 memcpy(temp, value, sc_get_buffer_length());
250                                 sc_truncate(get_mode_size_bits(mode), temp);
251                                 return get_tarval(temp, length, mode);
252                         }
253                         case TV_OVERFLOW_BAD:
254                                 return tarval_bad;
255                         default:
256                                 return get_tarval(value, length, mode);
257                         }
258                 }
259                 break;
260
261         case irms_float_number:
262                 if (SWITCH_NOINFINITY && fc_is_inf(value)) {
263                         /* clip infinity to maximum value */
264                         return fc_is_negative(value) ? get_mode_min(mode) : get_mode_max(mode);
265                 }
266
267                 if (SWITCH_NODENORMALS && fc_is_subnormal(value)) {
268                         /* clip denormals to zero */
269                         return get_mode_null(mode);
270                 }
271                 break;
272
273         default:
274                 break;
275         }
276         return get_tarval(value, length, mode);
277 }
278
279 /*
280  *   public variables declared in tv.h
281  */
282 static tarval reserved_tv[4];
283
284 tarval *tarval_bad       = &reserved_tv[0];
285 tarval *tarval_undefined = &reserved_tv[1];
286 tarval *tarval_b_false   = &reserved_tv[2];
287 tarval *tarval_b_true    = &reserved_tv[3];
288
289 /*
290  *   public functions declared in tv.h
291  */
292
293 /*
294  * Constructors =============================================================
295  */
296 tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
297 {
298         assert(str);
299         assert(len);
300         assert(mode);
301
302         switch (get_mode_sort(mode)) {
303         case irms_control_flow:
304         case irms_memory:
305         case irms_auxiliary:
306                 assert(0);
307                 break;
308
309         case irms_internal_boolean:
310                 /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
311                 if (strcasecmp(str, "true")) return tarval_b_true;
312                 else if (strcasecmp(str, "false")) return tarval_b_true;
313                 else
314                         /* XXX This is C semantics */
315                         return atoi(str) ? tarval_b_true : tarval_b_false;
316
317         case irms_float_number:
318                 switch (get_mode_size_bits(mode)) {
319                 case 32:
320                         fc_val_from_str(str, len, 8, 23, NULL);
321                         break;
322                 case 64:
323                         fc_val_from_str(str, len, 11, 52, NULL);
324                         break;
325                 case 80:
326                 case 96:
327                         fc_val_from_str(str, len, 15, 64, NULL);
328                         break;
329                 default:
330                         panic("Unsupported mode in new_tarval_from_str()");
331                 }
332                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
333
334         case irms_reference:
335                 /* same as integer modes */
336         case irms_int_number:
337                 sc_val_from_str(str, len, NULL, mode);
338                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
339         }
340
341         assert(0);  /* can't be reached, can it? */
342         return NULL;
343 }
344
345 /*
346  * helper function, create a tarval from long
347  */
348 tarval *new_tarval_from_long(long l, ir_mode *mode) {
349         assert(mode);
350
351         switch (get_mode_sort(mode))   {
352         case irms_internal_boolean:
353                 /* XXX C semantics ! */
354                 return l ? tarval_b_true : tarval_b_false ;
355
356         case irms_reference:
357                 /* same as integer modes */
358         case irms_int_number:
359                 sc_val_from_long(l, NULL);
360                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
361
362         case irms_float_number:
363                 return new_tarval_from_double((long double)l, mode);
364
365         default:
366                 assert(0 && "unsupported mode sort");
367         }
368         return NULL;
369 }
370
371 /* returns non-zero if can be converted to long */
372 int tarval_is_long(tarval *tv) {
373         if (!mode_is_int(tv->mode) && !mode_is_reference(tv->mode))
374                 return 0;
375
376         if (get_mode_size_bits(tv->mode) > (int) (sizeof(long) << 3)) {
377                 /* the value might be too big to fit in a long */
378                 sc_max_from_bits(sizeof(long) << 3, 0, NULL);
379                 if (sc_comp(sc_get_buffer(), tv->value) == -1) {
380                         /* really doesn't fit */
381                         return 0;
382                 }
383         }
384         return 1;
385 }
386
387 /* this might overflow the machine's long, so use only with small values */
388 long get_tarval_long(tarval* tv) {
389         assert(tarval_is_long(tv) && "tarval too big to fit in long");
390
391         return sc_val_to_long(tv->value);
392 }
393
394 tarval *new_tarval_from_double(long double d, ir_mode *mode) {
395         assert(mode && (get_mode_sort(mode) == irms_float_number));
396
397         switch (get_mode_size_bits(mode)) {
398         case 32:
399                 fc_val_from_ieee754(d, 8, 23, NULL);
400                 break;
401         case 64:
402                 fc_val_from_ieee754(d, 11, 52, NULL);
403                 break;
404         case 80:
405         case 96:
406                 fc_val_from_ieee754(d, 15, 64, NULL);
407                 break;
408         default:
409                 panic("Unsupported mode in new_tarval_from_double()");
410         }
411         return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
412 }
413
414 /* returns non-zero if can be converted to double */
415 int tarval_is_double(tarval *tv) {
416         assert(tv);
417
418         return (get_mode_sort(tv->mode) == irms_float_number);
419 }
420
421 long double get_tarval_double(tarval *tv) {
422         assert(tarval_is_double(tv));
423
424         return fc_val_to_ieee754(tv->value);
425 }
426
427
428 /*
429  * Access routines for tarval fields ========================================
430  */
431
432 /* get the mode of the tarval */
433 ir_mode *(get_tarval_mode)(const tarval *tv) {
434         return _get_tarval_mode(tv);
435 }
436
437 /*
438  * Special value query functions ============================================
439  *
440  * These functions calculate and return a tarval representing the requested
441  * value.
442  * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
443  * functions, but these are stored on initialization of the irmode module and
444  * therefore the irmode functions should be preferred to the functions below.
445  */
446
447 tarval *(get_tarval_bad)(void) {
448         return _get_tarval_bad();
449 }
450
451 tarval *(get_tarval_undefined)(void) {
452         return _get_tarval_undefined();
453 }
454
455 tarval *(get_tarval_b_false)(void) {
456         return _get_tarval_b_false();
457 }
458
459 tarval *(get_tarval_b_true)(void) {
460         return _get_tarval_b_true();
461 }
462
463 tarval *get_tarval_max(ir_mode *mode) {
464         assert(mode);
465
466         if (get_mode_n_vector_elems(mode) > 1) {
467                 /* vector arithmetic not implemented yet */
468                 return tarval_bad;
469         }
470
471         switch(get_mode_sort(mode)) {
472         case irms_control_flow:
473         case irms_memory:
474         case irms_auxiliary:
475                 assert(0);
476                 break;
477
478         case irms_internal_boolean:
479                 return tarval_b_true;
480
481         case irms_float_number:
482                 switch(get_mode_size_bits(mode)) {
483                 case 32:
484                         fc_get_max(8, 23, NULL);
485                         break;
486                 case 64:
487                         fc_get_max(11, 52, NULL);
488                         break;
489                 case 80:
490                 case 96:
491                         fc_get_max(15, 64, NULL);
492                         break;
493                 default:
494                         panic("Unsupported mode in get_tarval_max()");
495                 }
496                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
497
498         case irms_reference:
499         case irms_int_number:
500                 sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
501                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
502         }
503         return tarval_bad;
504 }
505
506 tarval *get_tarval_min(ir_mode *mode) {
507         assert(mode);
508
509         if (get_mode_n_vector_elems(mode) > 1) {
510                 /* vector arithmetic not implemented yet */
511                 return tarval_bad;
512         }
513
514         switch(get_mode_sort(mode)) {
515         case irms_control_flow:
516         case irms_memory:
517         case irms_auxiliary:
518                 assert(0);
519                 break;
520
521         case irms_internal_boolean:
522                 return tarval_b_false;
523
524         case irms_float_number:
525                 switch(get_mode_size_bits(mode)) {
526                 case 32:
527                         fc_get_min(8, 23, NULL);
528                         break;
529                 case 64:
530                         fc_get_min(11, 52, NULL);
531                         break;
532                 case 80:
533                 case 96:
534                         fc_get_min(15, 64, NULL);
535                         break;
536                 default:
537                         panic("Unsupported mode in get_tarval_min()");
538                 }
539                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
540
541         case irms_reference:
542         case irms_int_number:
543                 sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
544                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
545         }
546         return tarval_bad;
547 }
548
549 /** The bit pattern for the pointer NULL */
550 static long _null_value = 0;
551
552 tarval *get_tarval_null(ir_mode *mode) {
553         assert(mode);
554
555         if (get_mode_n_vector_elems(mode) > 1) {
556                 /* vector arithmetic not implemented yet */
557                 return tarval_bad;
558         }
559
560         switch(get_mode_sort(mode)) {
561         case irms_control_flow:
562         case irms_memory:
563         case irms_auxiliary:
564                 assert(0);
565                 break;
566
567         case irms_float_number:
568                 return new_tarval_from_double(0.0, mode);
569
570         case irms_internal_boolean:
571         case irms_int_number:
572                 return new_tarval_from_long(0l,  mode);
573
574         case irms_reference:
575                 return new_tarval_from_long(_null_value, mode);
576         }
577         return tarval_bad;
578 }
579
580 tarval *get_tarval_one(ir_mode *mode) {
581         assert(mode);
582
583         if (get_mode_n_vector_elems(mode) > 1) {
584                 /* vector arithmetic not implemented yet */
585                 assert(0);
586                 return tarval_bad;
587         }
588
589         switch(get_mode_sort(mode)) {
590         case irms_control_flow:
591         case irms_memory:
592         case irms_auxiliary:
593                 assert(0);
594                 break;
595
596         case irms_internal_boolean:
597                 return tarval_b_true;
598
599         case irms_float_number:
600                 return new_tarval_from_double(1.0, mode);
601
602         case irms_reference:
603         case irms_int_number:
604                 return new_tarval_from_long(1l, mode);
605         }
606         return tarval_bad;
607 }
608
609 tarval *get_tarval_all_one(ir_mode *mode) {
610         assert(mode);
611
612         if (get_mode_n_vector_elems(mode) > 1) {
613                 /* vector arithmetic not implemented yet */
614                 assert(0);
615                 return tarval_bad;
616         }
617
618         switch(get_mode_sort(mode)) {
619         case irms_control_flow:
620         case irms_memory:
621         case irms_auxiliary:
622                 assert(0);
623                 return tarval_bad;
624
625         case irms_int_number:
626         case irms_internal_boolean:
627         case irms_reference:
628                 return tarval_not(get_mode_null(mode));
629
630
631         case irms_float_number:
632                 return new_tarval_from_double(1.0, mode);
633         }
634         return tarval_bad;
635 }
636
637 tarval *get_tarval_minus_one(ir_mode *mode) {
638         assert(mode);
639
640         if (get_mode_n_vector_elems(mode) > 1) {
641                 /* vector arithmetic not implemented yet */
642                 return tarval_bad;
643         }
644
645         switch(get_mode_sort(mode)) {
646         case irms_control_flow:
647         case irms_memory:
648         case irms_auxiliary:
649         case irms_internal_boolean:
650                 assert(0);
651                 break;
652
653         case irms_reference:
654                 return tarval_bad;
655
656         case irms_float_number:
657                 return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;
658
659         case irms_int_number:
660                 return new_tarval_from_long(-1l, mode);
661         }
662         return tarval_bad;
663 }
664
665 tarval *get_tarval_nan(ir_mode *mode) {
666         assert(mode);
667
668         if (get_mode_n_vector_elems(mode) > 1) {
669                 /* vector arithmetic not implemented yet */
670                 return tarval_bad;
671         }
672
673         if (get_mode_sort(mode) == irms_float_number) {
674                 switch(get_mode_size_bits(mode)) {
675                 case 32:
676                         fc_get_qnan(8, 23, NULL);
677                         break;
678                 case 64:
679                         fc_get_qnan(11, 52, NULL);
680                         break;
681                 case 80:
682                 case 96:
683                         fc_get_qnan(15, 64, NULL);
684                         break;
685                 default:
686                         panic("Unsupported mode in get_tarval_nan()");
687                 }
688                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
689         } else {
690                 assert(0 && "tarval is not floating point");
691                 return tarval_bad;
692         }
693 }
694
695 tarval *get_tarval_plus_inf(ir_mode *mode) {
696         assert(mode);
697
698         if (get_mode_n_vector_elems(mode) > 1) {
699                 /* vector arithmetic not implemented yet */
700                 return tarval_bad;
701         }
702
703         if (get_mode_sort(mode) == irms_float_number) {
704                 switch(get_mode_size_bits(mode)) {
705                 case 32:
706                         fc_get_plusinf(8, 23, NULL);
707                         break;
708                 case 64:
709                         fc_get_plusinf(11, 52, NULL);
710                         break;
711                 case 80:
712                 case 96:
713                         fc_get_plusinf(15, 64, NULL);
714                         break;
715                 default:
716                         panic("Unsupported mode in get_tarval_plus_inf()");
717                 }
718                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
719         } else {
720                 assert(0 && "tarval is not floating point");
721                 return tarval_bad;
722         }
723 }
724
725 tarval *get_tarval_minus_inf(ir_mode *mode) {
726         assert(mode);
727
728         if (get_mode_n_vector_elems(mode) > 1) {
729                 /* vector arithmetic not implemented yet */
730                 return tarval_bad;
731         }
732
733         if (get_mode_sort(mode) == irms_float_number) {
734                 switch(get_mode_size_bits(mode)) {
735                 case 32:
736                         fc_get_minusinf(8, 23, NULL);
737                         break;
738                 case 64:
739                         fc_get_minusinf(11, 52, NULL);
740                         break;
741                 case 80:
742                 case 96:
743                         fc_get_minusinf(15, 64, NULL);
744                         break;
745                 default:
746                         panic("Unsupported mode in get_tarval_minus_inf()");
747                 }
748                 return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
749         } else {
750                 assert(0 && "tarval is not floating point");
751                 return tarval_bad;
752         }
753 }
754
755 /*
756  * Arithmethic operations on tarvals ========================================
757  */
758
759 /*
760  * test if negative number, 1 means 'yes'
761  */
762 int tarval_is_negative(tarval *a) {
763         assert(a);
764
765         if (get_mode_n_vector_elems(a->mode) > 1) {
766                 /* vector arithmetic not implemented yet */
767                 assert(0 && "tarval_is_negative is not allowed for vector modes");
768                 return 0;
769         }
770
771         switch (get_mode_sort(a->mode)) {
772         case irms_int_number:
773                 if (!mode_is_signed(a->mode)) return 0;
774                 else
775                         return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
776
777         case irms_float_number:
778                 return fc_is_negative(a->value);
779
780         default:
781                 assert(0 && "not implemented");
782                 return 0;
783         }
784 }
785
786 /*
787  * test if null, 1 means 'yes'
788  */
789 int tarval_is_null(tarval *a) {
790         return
791                 a != tarval_bad &&
792                 a == get_mode_null(get_tarval_mode(a));
793 }
794
795 /*
796  * test if one, 1 means 'yes'
797  */
798 int tarval_is_one(tarval *a) {
799         return
800                 a != tarval_bad &&
801                 a == get_mode_one(get_tarval_mode(a));
802 }
803
804 int tarval_is_all_one(tarval *tv) {
805         return
806                 tv != tarval_bad &&
807                 tv == get_mode_all_one(get_tarval_mode(tv));
808 }
809
810 /*
811  * test if one, 1 means 'yes'
812  */
813 int tarval_is_minus_one(tarval *a) {
814         return
815                 a != tarval_bad &&
816                 a == get_mode_minus_one(get_tarval_mode(a));
817 }
818
819 /*
820  * comparison
821  */
822 pn_Cmp tarval_cmp(tarval *a, tarval *b) {
823         assert(a);
824         assert(b);
825
826         if (a == tarval_bad || b == tarval_bad) {
827                 assert(0 && "Comparison with tarval_bad");
828                 return pn_Cmp_False;
829         }
830
831         if (a == tarval_undefined || b == tarval_undefined)
832                 return pn_Cmp_False;
833
834         if (a->mode != b->mode)
835                 return pn_Cmp_False;
836
837         if (get_mode_n_vector_elems(a->mode) > 1) {
838                 /* vector arithmetic not implemented yet */
839                 assert(0 && "cmp not implemented for vector modes");
840         }
841
842         /* Here the two tarvals are unequal and of the same mode */
843         switch (get_mode_sort(a->mode)) {
844         case irms_control_flow:
845         case irms_memory:
846         case irms_auxiliary:
847                 if (a == b)
848                         return pn_Cmp_Eq;
849                 return pn_Cmp_False;
850
851         case irms_float_number:
852                 /* it should be safe to enable this even if other arithmetic is disabled */
853                 /*if (no_float)
854                         return pn_Cmp_False;*/
855                 /*
856                  * BEWARE: we cannot compare a == b here, because
857                  * a NaN is always Unordered to any other value, even to itself!
858                  */
859                 switch (fc_comp(a->value, b->value)) {
860                 case -1: return pn_Cmp_Lt;
861                 case  0: return pn_Cmp_Eq;
862                 case  1: return pn_Cmp_Gt;
863                 case  2: return pn_Cmp_Uo;
864                 default: return pn_Cmp_False;
865                 }
866         case irms_reference:
867         case irms_int_number:
868                 if (a == b)
869                         return pn_Cmp_Eq;
870                 return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
871
872         case irms_internal_boolean:
873                 if (a == b)
874                         return pn_Cmp_Eq;
875                 return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
876         }
877         return pn_Cmp_False;
878 }
879
880 /*
881  * convert to other mode
882  */
883 tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode) {
884         char *buffer;
885         fp_value *res;
886
887         assert(src);
888         assert(dst_mode);
889
890         if (src->mode == dst_mode) return src;
891
892         if (get_mode_n_vector_elems(src->mode) > 1) {
893                 /* vector arithmetic not implemented yet */
894                 return tarval_bad;
895         }
896
897         switch (get_mode_sort(src->mode)) {
898         case irms_control_flow:
899         case irms_memory:
900         case irms_auxiliary:
901                 break;
902
903                 /* cast float to something */
904         case irms_float_number:
905                 switch (get_mode_sort(dst_mode)) {
906                 case irms_float_number:
907                         switch (get_mode_size_bits(dst_mode)) {
908                         case 32:
909                                 fc_cast(src->value, 8, 23, NULL);
910                                 break;
911                         case 64:
912                                 fc_cast(src->value, 11, 52, NULL);
913                                 break;
914                         case 80:
915                         case 96:
916                                 fc_cast(src->value, 15, 64, NULL);
917                                 break;
918                         default:
919                                 panic("Unsupported mode in tarval_convert_to()");
920                         }
921                         return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
922
923                 case irms_int_number:
924                         switch (GET_FLOAT_TO_INT_MODE()) {
925                         case TRUNCATE:
926                                 res = fc_int(src->value, NULL);
927                                 break;
928                         case ROUND:
929                                 res = fc_rnd(src->value, NULL);
930                                 break;
931                         default:
932                                 panic("Unsupported float to int conversion mode in tarval_convert_to()");
933                                 break;
934                         }
935                         buffer = alloca(sc_get_buffer_length());
936                         if (! fc_flt2int(res, buffer, dst_mode))
937                                 return tarval_bad;
938                         return get_tarval(buffer, sc_get_buffer_length(), dst_mode);
939
940                 default:
941                         /* the rest can't be converted */
942                         return tarval_bad;
943                 }
944                 break;
945
946         /* cast int/characters to something */
947         case irms_int_number:
948                 switch (get_mode_sort(dst_mode)) {
949
950                 case irms_reference:
951                 case irms_int_number:
952                         buffer = alloca(sc_get_buffer_length());
953                         memcpy(buffer, src->value, sc_get_buffer_length());
954                         sign_extend(buffer, dst_mode);
955                         return get_tarval_overflow(buffer, src->length, dst_mode);
956
957                 case irms_internal_boolean:
958                         /* XXX C semantics */
959                         if (src == get_mode_null(src->mode)) return tarval_b_false;
960                         else return tarval_b_true;
961
962                 case irms_float_number:
963                         /* XXX floating point unit does not understand internal integer
964                          * representation, convert to string first, then create float from
965                          * string */
966                         buffer = alloca(100);
967                         /* decimal string representation because hexadecimal output is
968                          * interpreted unsigned by fc_val_from_str, so this is a HACK */
969                         snprintf(buffer, 100, "%s",
970                                 sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
971                         buffer[100 - 1] = '\0';
972                         switch (get_mode_size_bits(dst_mode)) {
973                         case 32:
974                                 fc_val_from_str(buffer, 0, 8, 23, NULL);
975                                 break;
976                         case 64:
977                                 fc_val_from_str(buffer, 0, 11, 52, NULL);
978                                 break;
979                         case 80:
980                         case 96:
981                                 fc_val_from_str(buffer, 0, 15, 64, NULL);
982                                 break;
983                         default:
984                                 panic("Unsupported mode in tarval_convert_to()");
985                         }
986                         return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
987
988                 default:
989                         break;
990                 }
991                 break;
992
993         case irms_internal_boolean:
994                 /* beware: this is C semantic for the INTERNAL boolean mode */
995                 if (get_mode_sort(dst_mode) == irms_int_number)
996                         return src == tarval_b_true ? get_mode_one(dst_mode) : get_mode_null(dst_mode);
997                 break;
998
999         case irms_reference:
1000                 if (get_mode_sort(dst_mode) == irms_int_number) {
1001                         buffer = alloca(sc_get_buffer_length());
1002                         memcpy(buffer, src->value, sc_get_buffer_length());
1003                         sign_extend(buffer, src->mode);
1004                         return get_tarval_overflow(buffer, src->length, dst_mode);
1005                 }
1006                 break;
1007         }
1008
1009         return tarval_bad;
1010 }
1011
1012 /*
1013  * bitwise negation
1014  */
1015 tarval *tarval_not(tarval *a) {
1016         char *buffer;
1017
1018         assert(a);
1019
1020         /* works for vector mode without changes */
1021
1022         switch (get_mode_sort(a->mode)) {
1023         case irms_reference:
1024         case irms_int_number:
1025                 buffer = alloca(sc_get_buffer_length());
1026                 sc_not(a->value, buffer);
1027                 return get_tarval(buffer, a->length, a->mode);
1028
1029         case irms_internal_boolean:
1030                 if (a == tarval_b_true)
1031                         return tarval_b_false;
1032                 if (a == tarval_b_false)
1033                         return tarval_b_true;
1034                 return tarval_bad;
1035
1036         default:
1037                 assert(0 && "bitwise negation is only allowed for integer and boolean");
1038                 return tarval_bad;
1039         }
1040 }
1041
1042 /*
1043  * arithmetic negation
1044  */
1045 tarval *tarval_neg(tarval *a) {
1046         char *buffer;
1047
1048         assert(a);
1049         assert(mode_is_num(a->mode)); /* negation only for numerical values */
1050
1051         /* note: negation is allowed even for unsigned modes. */
1052
1053         if (get_mode_n_vector_elems(a->mode) > 1) {
1054                 /* vector arithmetic not implemented yet */
1055                 return tarval_bad;
1056         }
1057
1058         switch (get_mode_sort(a->mode)) {
1059         case irms_int_number:
1060                 buffer = alloca(sc_get_buffer_length());
1061                 sc_neg(a->value, buffer);
1062                 return get_tarval_overflow(buffer, a->length, a->mode);
1063
1064         case irms_float_number:
1065                 /* it should be safe to enable this even if other arithmetic is disabled */
1066                 /*if (no_float)
1067                         return tarval_bad;*/
1068
1069                 fc_neg(a->value, NULL);
1070                 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1071
1072         default:
1073                 return tarval_bad;
1074         }
1075 }
1076
1077 /*
1078  * addition
1079  */
1080 tarval *tarval_add(tarval *a, tarval *b) {
1081         char *buffer;
1082
1083         assert(a);
1084         assert(b);
1085         assert(a->mode == b->mode);
1086
1087         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
1088                 /* vector arithmetic not implemented yet */
1089                 return tarval_bad;
1090         }
1091
1092         switch (get_mode_sort(a->mode)) {
1093         case irms_int_number:
1094                 /* modes of a,b are equal, so result has mode of a as this might be the character */
1095                 buffer = alloca(sc_get_buffer_length());
1096                 sc_add(a->value, b->value, buffer);
1097                 return get_tarval_overflow(buffer, a->length, a->mode);
1098
1099         case irms_float_number:
1100                 if (no_float)
1101                         return tarval_bad;
1102
1103                 fc_add(a->value, b->value, NULL);
1104                 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1105
1106         default:
1107                 return tarval_bad;
1108         }
1109 }
1110
1111 /*
1112  * subtraction
1113  */
1114 tarval *tarval_sub(tarval *a, tarval *b) {
1115         char *buffer;
1116
1117         assert(a);
1118         assert(b);
1119         assert(a->mode == b->mode);
1120
1121         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
1122                 /* vector arithmetic not implemented yet */
1123                 return tarval_bad;
1124         }
1125         switch (get_mode_sort(a->mode)) {
1126         case irms_int_number:
1127                 /* modes of a,b are equal, so result has mode of a as this might be the character */
1128                 buffer = alloca(sc_get_buffer_length());
1129                 sc_sub(a->value, b->value, buffer);
1130                 return get_tarval_overflow(buffer, a->length, a->mode);
1131
1132         case irms_float_number:
1133                 if (no_float)
1134                         return tarval_bad;
1135
1136                 fc_sub(a->value, b->value, NULL);
1137                 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1138
1139         default:
1140                 return tarval_bad;
1141         }
1142 }
1143
1144 /*
1145  * multiplication
1146  */
1147 tarval *tarval_mul(tarval *a, tarval *b) {
1148         char *buffer;
1149
1150         assert(a);
1151         assert(b);
1152         assert(a->mode == b->mode);
1153
1154         if (get_mode_n_vector_elems(a->mode) > 1) {
1155                 /* vector arithmetic not implemented yet */
1156                 return tarval_bad;
1157         }
1158
1159         switch (get_mode_sort(a->mode)) {
1160         case irms_int_number:
1161                 /* modes of a,b are equal */
1162                 buffer = alloca(sc_get_buffer_length());
1163                 sc_mul(a->value, b->value, buffer);
1164                 return get_tarval_overflow(buffer, a->length, a->mode);
1165
1166         case irms_float_number:
1167                 if (no_float)
1168                         return tarval_bad;
1169
1170                 fc_mul(a->value, b->value, NULL);
1171                 return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1172
1173         default:
1174                 return tarval_bad;
1175         }
1176 }
1177
1178 /*
1179  * floating point division
1180  */
1181 tarval *tarval_quo(tarval *a, tarval *b) {
1182         assert(a);
1183         assert(b);
1184         assert((a->mode == b->mode) && mode_is_float(a->mode));
1185
1186         if (no_float)
1187                 return tarval_bad;
1188
1189         if (get_mode_n_vector_elems(a->mode) > 1) {
1190                 /* vector arithmetic not implemented yet */
1191                 return tarval_bad;
1192         }
1193
1194         fc_div(a->value, b->value, NULL);
1195         return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1196 }
1197
1198 /*
1199  * integer division
1200  * overflow is impossible, but look out for division by zero
1201  */
1202 tarval *tarval_div(tarval *a, tarval *b) {
1203         assert(a);
1204         assert(b);
1205         assert((a->mode == b->mode) && mode_is_int(a->mode));
1206
1207         if (get_mode_n_vector_elems(a->mode) > 1) {
1208                 /* vector arithmetic not implemented yet */
1209                 return tarval_bad;
1210         }
1211
1212         /* x/0 error */
1213         if (b == get_mode_null(b->mode)) return tarval_bad;
1214         /* modes of a,b are equal */
1215         sc_div(a->value, b->value, NULL);
1216         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1217 }
1218
1219 /*
1220  * remainder
1221  * overflow is impossible, but look out for division by zero
1222  */
1223 tarval *tarval_mod(tarval *a, tarval *b) {
1224         assert(a);
1225         assert(b);
1226         assert((a->mode == b->mode) && mode_is_int(a->mode));
1227
1228         if (get_mode_n_vector_elems(a->mode) > 1) {
1229                 /* vector arithmetic not implemented yet */
1230                 return tarval_bad;
1231         }
1232
1233         /* x/0 error */
1234         if (b == get_mode_null(b->mode)) return tarval_bad;
1235         /* modes of a,b are equal */
1236         sc_mod(a->value, b->value, NULL);
1237         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1238 }
1239
1240 /*
1241  * integer division AND remainder
1242  * overflow is impossible, but look out for division by zero
1243  */
1244 tarval *tarval_divmod(tarval *a, tarval *b, tarval **mod) {
1245         int len = sc_get_buffer_length();
1246         char *div_res = alloca(len);
1247         char *mod_res = alloca(len);
1248
1249         assert(a);
1250         assert(b);
1251         assert((a->mode == b->mode) && mode_is_int(a->mode));
1252
1253         if (get_mode_n_vector_elems(a->mode) > 1) {
1254                 /* vector arithmetic not implemented yet */
1255                 return tarval_bad;
1256         }
1257
1258
1259         /* x/0 error */
1260         if (b == get_mode_null(b->mode)) return tarval_bad;
1261         /* modes of a,b are equal */
1262         sc_divmod(a->value, b->value, div_res, mod_res);
1263         *mod = get_tarval(mod_res, len, a->mode);
1264         return get_tarval(div_res, len, a->mode);
1265 }
1266
1267 /*
1268  * absolute value
1269  */
1270 tarval *tarval_abs(tarval *a) {
1271         char *buffer;
1272
1273         assert(a);
1274         assert(mode_is_num(a->mode));
1275
1276         if (get_mode_n_vector_elems(a->mode) > 1) {
1277                 /* vector arithmetic not implemented yet */
1278                 return tarval_bad;
1279         }
1280
1281         switch (get_mode_sort(a->mode)) {
1282         case irms_int_number:
1283                 if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1) {
1284                         buffer = alloca(sc_get_buffer_length());
1285                         sc_neg(a->value, buffer);
1286                         return get_tarval_overflow(buffer, a->length, a->mode);
1287                 }
1288                 return a;
1289
1290         case irms_float_number:
1291                 /* it should be safe to enable this even if other arithmetic is disabled */
1292                 /*if (no_float)
1293                         return tarval_bad;*/
1294
1295                 if (fc_comp(a->value, get_mode_null(a->mode)->value) == -1) {
1296                         fc_neg(a->value, NULL);
1297                         return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
1298                 }
1299                 return a;
1300
1301         default:
1302                 return tarval_bad;
1303         }
1304         return tarval_bad;
1305 }
1306
1307 /*
1308  * bitwise and
1309  */
1310 tarval *tarval_and(tarval *a, tarval *b) {
1311         assert(a);
1312         assert(b);
1313         assert(a->mode == b->mode);
1314
1315         /* works even for vector modes */
1316
1317         switch(get_mode_sort(a->mode)) {
1318         case irms_internal_boolean:
1319                 return (a == tarval_b_false) ? a : b;
1320
1321         case irms_int_number:
1322                 sc_and(a->value, b->value, NULL);
1323                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1324
1325         default:
1326                 assert(0 && "operation not defined on mode");
1327                 return tarval_bad;
1328         }
1329 }
1330
1331 /*
1332  * bitwise or
1333  */
1334 tarval *tarval_or (tarval *a, tarval *b) {
1335         assert(a);
1336         assert(b);
1337         assert(a->mode == b->mode);
1338
1339         /* works even for vector modes */
1340
1341         switch (get_mode_sort(a->mode)) {
1342         case irms_internal_boolean:
1343                 return (a == tarval_b_true) ? a : b;
1344
1345         case irms_int_number:
1346                 sc_or(a->value, b->value, NULL);
1347                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1348
1349         default:
1350                 assert(0 && "operation not defined on mode");
1351                 return tarval_bad;
1352         }
1353 }
1354
1355 /*
1356  * bitwise exclusive or (xor)
1357  */
1358 tarval *tarval_eor(tarval *a, tarval *b) {
1359         assert(a);
1360         assert(b);
1361         assert((a->mode == b->mode));
1362
1363         /* works even for vector modes */
1364
1365         switch (get_mode_sort(a->mode)) {
1366         case irms_internal_boolean:
1367                 return (a == b)? tarval_b_false : tarval_b_true;
1368
1369         case irms_int_number:
1370                 sc_xor(a->value, b->value, NULL);
1371                 return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1372
1373         default:
1374                 assert(0 && "operation not defined on mode");
1375                 return tarval_bad;;
1376         }
1377 }
1378
1379 /*
1380  * bitwise left shift
1381  */
1382 tarval *tarval_shl(tarval *a, tarval *b) {
1383         char *temp_val = NULL;
1384
1385         assert(a);
1386         assert(b);
1387         assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1388
1389         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1390                 /* vector arithmetic not implemented yet */
1391                 return tarval_bad;
1392         }
1393
1394         if (get_mode_modulo_shift(a->mode) != 0) {
1395                 temp_val = alloca(sc_get_buffer_length());
1396
1397                 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1398                 sc_mod(b->value, temp_val, temp_val);
1399         } else
1400                 temp_val = (char*)b->value;
1401
1402         sc_shl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1403         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1404 }
1405
1406 /*
1407  * bitwise unsigned right shift
1408  */
1409 tarval *tarval_shr(tarval *a, tarval *b) {
1410         char *temp_val = NULL;
1411
1412         assert(a);
1413         assert(b);
1414         assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1415
1416         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1417                 /* vector arithmetic not implemented yet */
1418                 return tarval_bad;
1419         }
1420
1421         if (get_mode_modulo_shift(a->mode) != 0) {
1422                 temp_val = alloca(sc_get_buffer_length());
1423
1424                 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1425                 sc_mod(b->value, temp_val, temp_val);
1426         } else
1427                 temp_val = (char*)b->value;
1428
1429         sc_shr(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1430         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1431 }
1432
1433 /*
1434  * bitwise signed right shift
1435  */
1436 tarval *tarval_shrs(tarval *a, tarval *b) {
1437         char *temp_val = NULL;
1438
1439         assert(a);
1440         assert(b);
1441         assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1442
1443         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1444                 /* vector arithmetic not implemented yet */
1445                 return tarval_bad;
1446         }
1447
1448         if (get_mode_modulo_shift(a->mode) != 0) {
1449                 temp_val = alloca(sc_get_buffer_length());
1450
1451                 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1452                 sc_mod(b->value, temp_val, temp_val);
1453         } else
1454                 temp_val = (char*)b->value;
1455
1456         sc_shrs(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1457         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1458 }
1459
1460 /*
1461  * bitwise rotation to left
1462  */
1463 tarval *tarval_rotl(tarval *a, tarval *b) {
1464         char *temp_val = NULL;
1465
1466         assert(a);
1467         assert(b);
1468         assert(mode_is_int(a->mode) && mode_is_int(b->mode));
1469
1470         if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) {
1471                 /* vector arithmetic not implemented yet */
1472                 return tarval_bad;
1473         }
1474
1475         if (get_mode_modulo_shift(a->mode) != 0) {
1476                 temp_val = alloca(sc_get_buffer_length());
1477
1478                 sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val);
1479                 sc_mod(b->value, temp_val, temp_val);
1480         } else
1481                 temp_val = (char*)b->value;
1482
1483         sc_rotl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL);
1484         return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
1485 }
1486
1487 /*
1488  * carry flag of the last operation
1489  */
1490 int tarval_carry(void) {
1491         panic("tarval_carry() requetsed: not implemented on all operations");
1492         return sc_had_carry();
1493 }
1494
1495 /*
1496  * Output of tarvals
1497  */
1498 int tarval_snprintf(char *buf, size_t len, tarval *tv) {
1499         static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL };
1500
1501         const char *str;
1502         char tv_buf[100];
1503         const tarval_mode_info *mode_info;
1504         const char *prefix, *suffix;
1505
1506         mode_info = tv->mode->tv_priv;
1507         if (! mode_info)
1508                 mode_info = &default_info;
1509         prefix = mode_info->mode_prefix ? mode_info->mode_prefix : "";
1510         suffix = mode_info->mode_suffix ? mode_info->mode_suffix : "";
1511
1512         switch (get_mode_sort(tv->mode)) {
1513         case irms_reference:
1514                 if (tv == tv->mode->null) return snprintf(buf, len, "NULL");
1515                 /* fall through */
1516         case irms_int_number:
1517                 switch (mode_info->mode_output) {
1518
1519                 case TVO_DECIMAL:
1520                         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC, mode_is_signed(tv->mode));
1521                         break;
1522
1523                 case TVO_OCTAL:
1524                         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT, 0);
1525                         break;
1526
1527                 case TVO_HEX:
1528                 case TVO_NATIVE:
1529                 default:
1530                         str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0);
1531                         break;
1532                 }
1533                 return snprintf(buf, len, "%s%s%s", prefix, str, suffix);
1534
1535         case irms_float_number:
1536                 switch (mode_info->mode_output) {
1537                 case TVO_HEX:
1538                         return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_PACKED), suffix);
1539
1540                 case TVO_HEXFLOAT:
1541                         return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_HEX), suffix);
1542
1543                 case TVO_FLOAT:
1544                 case TVO_NATIVE:
1545                 default:
1546                         return snprintf(buf, len, "%s%s%s", prefix, fc_print(tv->value, tv_buf, sizeof(tv_buf), FC_DEC), suffix);
1547                 }
1548                 break;
1549
1550         case irms_internal_boolean:
1551                 switch (mode_info->mode_output) {
1552
1553                 case TVO_DECIMAL:
1554                 case TVO_OCTAL:
1555                 case TVO_HEX:
1556                 case TVO_BINARY:
1557                         return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix);
1558
1559                 case TVO_NATIVE:
1560                 default:
1561                         return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix);
1562                 }
1563
1564         case irms_control_flow:
1565         case irms_memory:
1566         case irms_auxiliary:
1567                 return snprintf(buf, len, "<TV_OVERFLOW_BAD>");
1568         }
1569
1570         return 0;
1571 }
1572
1573 /**
1574  * Output of tarvals to stdio.
1575  */
1576 int tarval_printf(tarval *tv) {
1577         char buf[1024];
1578         int res;
1579
1580         res = tarval_snprintf(buf, sizeof(buf), tv);
1581         assert(res < (int) sizeof(buf) && "buffer to small for tarval_snprintf");
1582         printf(buf);
1583         return res;
1584 }
1585
1586 char *get_tarval_bitpattern(tarval *tv) {
1587         int i, j, pos = 0;
1588         int n = get_mode_size_bits(tv->mode);
1589         int bytes = (n + 7) / 8;
1590         char *res = xmalloc((n + 1) * sizeof(char));
1591         unsigned char byte;
1592
1593         for(i = 0; i < bytes; i++) {
1594                 byte = get_tarval_sub_bits(tv, i);
1595                 for(j = 1; j < 256; j <<= 1)
1596                         if(pos < n)
1597                                 res[pos++] = j & byte ? '1' : '0';
1598         }
1599
1600         res[n] = '\0';
1601
1602         return res;
1603 }
1604
1605 /*
1606  * access to the bitpattern
1607  */
1608 unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs) {
1609         switch (get_mode_arithmetic(tv->mode)) {
1610         case irma_twos_complement:
1611                 return sc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1612         case irma_ieee754:
1613                 return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs);
1614         default:
1615                 panic("get_tarval_sub_bits(): arithmetic mode not supported");
1616         }
1617 }
1618
1619 /*
1620  * Specify the output options of one mode.
1621  *
1622  * This functions stores the modinfo, so DO NOT DESTROY it.
1623  *
1624  * Returns zero on success.
1625  */
1626 int  set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo) {
1627         assert(mode);
1628
1629         mode->tv_priv = modeinfo;
1630         return 0;
1631 }
1632
1633 /*
1634  * Returns the output options of one mode.
1635  *
1636  * This functions returns the mode info of a given mode.
1637  */
1638 const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode) {
1639         assert(mode);
1640
1641         return mode->tv_priv;
1642 }
1643
1644 /*
1645  * Returns non-zero if a given (integer) tarval has only one single bit
1646  * set.
1647  */
1648 int tarval_is_single_bit(tarval *tv) {
1649         int i, l;
1650         int bits;
1651
1652         if (!tv || tv == tarval_bad) return 0;
1653         if (! mode_is_int(tv->mode)) return 0;
1654
1655         l = get_mode_size_bytes(tv->mode);
1656         for (bits = 0, i = l - 1; i >= 0; --i) {
1657                 unsigned char v = get_tarval_sub_bits(tv, (unsigned)i);
1658
1659                 /* check for more than one bit in these */
1660                 if (v) {
1661                         if (v & (v-1))
1662                                 return 0;
1663                         if (++bits > 1)
1664                                 return 0;
1665                 }
1666         }
1667         return bits;
1668 }
1669
1670 /*
1671  * Returns non-zero if the mantissa of a floating point IEEE-754
1672  * tarval is zero (i.e. 1.0Exxx)
1673  */
1674 int tarval_ieee754_zero_mantissa(tarval *tv) {
1675         assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
1676         return fc_zero_mantissa(tv->value);
1677 }
1678
1679 /* Returns the exponent of a floating point IEEE-754 tarval. */
1680 int tarval_ieee754_get_exponent(tarval *tv) {
1681         assert(get_mode_arithmetic(tv->mode) == irma_ieee754);
1682         return fc_get_exponent(tv->value);
1683 }
1684
1685 /*
1686  * Check if the tarval can be converted to the given mode without
1687  * precision loss.
1688  */
1689 int tarval_ieee754_can_conv_lossless(tarval *tv, ir_mode *mode) {
1690         char exp_size, mant_size;
1691         switch (get_mode_size_bits(mode)) {
1692         case 32:
1693                 exp_size = 8; mant_size = 23;
1694                 break;
1695         case 64:
1696                 exp_size = 11; mant_size = 52;
1697                 break;
1698         case 80:
1699         case 96:
1700                 exp_size = 15; mant_size = 64;
1701                 break;
1702         default:
1703                 panic("Unsupported mode in tarval_ieee754_can_conv_lossless()");
1704                 return 0;
1705         }
1706         return fc_can_lossless_conv_to(tv->value, exp_size, mant_size);
1707 }
1708
1709 /* Set the immediate precision for IEEE-754 results. */
1710 unsigned tarval_ieee754_set_immediate_precision(unsigned bits) {
1711         return fc_set_immediate_precision(bits);
1712 }
1713
1714 /* Returns non-zero if the result of the last IEEE-754 operation was exact. */
1715 unsigned tarval_ieee754_get_exact(void) {
1716         return fc_is_exact();
1717 }
1718
1719 /* check if its the a floating point NaN */
1720 int tarval_is_NaN(tarval *tv) {
1721         if (! mode_is_float(tv->mode))
1722                 return 0;
1723         return fc_is_nan(tv->value);
1724 }
1725
1726 /* check if its the a floating point +inf */
1727 int tarval_is_plus_inf(tarval *tv) {
1728         if (! mode_is_float(tv->mode))
1729                 return 0;
1730         return fc_is_inf(tv->value) && !fc_is_negative(tv->value);
1731 }
1732
1733 /* check if its the a floating point -inf */
1734 int tarval_is_minus_inf(tarval *tv) {
1735         if (! mode_is_float(tv->mode))
1736                 return 0;
1737         return fc_is_inf(tv->value) && fc_is_negative(tv->value);
1738 }
1739
1740 /* check if the tarval represents a finite value */
1741 int tarval_is_finite(tarval *tv) {
1742         if (mode_is_float(tv->mode))
1743                 return !fc_is_nan(tv->value) && !fc_is_inf(tv->value);
1744         return 1;
1745 }
1746
1747 /*
1748  * Sets the overflow mode for integer operations.
1749  */
1750 void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode) {
1751         int_overflow_mode = ov_mode;
1752 }
1753
1754 /* Get the overflow mode for integer operations. */
1755 tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) {
1756         return int_overflow_mode;
1757 }
1758
1759 /* Enable/Disable floating point constant folding. */
1760 int tarval_enable_fp_ops(int enable) {
1761         int old = !no_float;
1762
1763         no_float = !enable;
1764         return old;
1765 }
1766
1767 /**
1768  * default mode_info for output as HEX
1769  */
1770 static const tarval_mode_info hex_output = {
1771         TVO_HEX,
1772         "0x",
1773         NULL,
1774 };
1775
1776 /*
1777  * Initialization of the tarval module: called before init_mode()
1778  */
1779 void init_tarval_1(long null_value) {
1780         _null_value = null_value;
1781
1782         /* initialize the sets holding the tarvals with a comparison function and
1783          * an initial size, which is the expected number of constants */
1784         tarvals = new_set(cmp_tv, N_CONSTANTS);
1785         values  = new_set(memcmp, N_CONSTANTS);
1786         /* init strcalc with precision of 68 to support floating point values with 64
1787          * bit mantissa (needs extra bits for rounding and overflow) */
1788         init_strcalc(68);
1789         init_fltcalc(0);
1790 }
1791
1792 /*
1793  * Initialization of the tarval module: called after init_mode()
1794  */
1795 void init_tarval_2(void) {
1796         tarval_bad->kind        = k_tarval;
1797         tarval_bad->mode        = mode_BAD;
1798         tarval_bad->value       = INT_TO_PTR(resid_tarval_bad);
1799
1800         tarval_undefined->kind  = k_tarval;
1801         tarval_undefined->mode  = mode_ANY;
1802         tarval_undefined->value = INT_TO_PTR(resid_tarval_undefined);
1803
1804         tarval_b_true->kind     = k_tarval;
1805         tarval_b_true->mode     = mode_b;
1806         tarval_b_true->value    = INT_TO_PTR(resid_tarval_b_true);
1807
1808         tarval_b_false->kind    = k_tarval;
1809         tarval_b_false->mode    = mode_b;
1810         tarval_b_false->value   = INT_TO_PTR(resid_tarval_b_false);
1811
1812         /*
1813          * assign output modes that are compatible with the
1814          * old implementation: Hex output
1815          */
1816         set_tarval_mode_output_option(mode_Bs, &hex_output);
1817         set_tarval_mode_output_option(mode_Bu, &hex_output);
1818         set_tarval_mode_output_option(mode_Hs, &hex_output);
1819         set_tarval_mode_output_option(mode_Hu, &hex_output);
1820         set_tarval_mode_output_option(mode_Is, &hex_output);
1821         set_tarval_mode_output_option(mode_Iu, &hex_output);
1822         set_tarval_mode_output_option(mode_Ls, &hex_output);
1823         set_tarval_mode_output_option(mode_Lu, &hex_output);
1824         set_tarval_mode_output_option(mode_P,  &hex_output);
1825 }
1826
1827 /* free all memory occupied by tarval. */
1828 void finish_tarval(void) {
1829         finish_strcalc();
1830         finish_fltcalc();
1831         del_set(tarvals); tarvals = NULL;
1832         del_set(values);  values = NULL;
1833 }
1834
1835 /****************************************************************************
1836  *   end of tv.c
1837  ****************************************************************************/