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