a208d9b077403c0e45967641d0b20e9e15171b0f
[libfirm] / ir / ir / irmode.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief    Data modes of operations.
9  * @author   Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
10  */
11 #include "config.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stddef.h>
16 #include <stdbool.h>
17
18 #include "irprog_t.h"
19 #include "irmode_t.h"
20 #include "ident.h"
21 #include "tv_t.h"
22 #include "obst.h"
23 #include "irhooks.h"
24 #include "irtools.h"
25 #include "array.h"
26 #include "error.h"
27 #include "pattern_dmp.h"
28
29 /** Obstack to hold all modes. */
30 static struct obstack modes;
31
32 /** The list of all currently existing modes. */
33 static ir_mode **mode_list;
34
35 static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
36 {
37         return m->sort         == n->sort &&
38                m->arithmetic   == n->arithmetic &&
39                m->size         == n->size &&
40                m->sign         == n->sign &&
41                m->modulo_shift == n->modulo_shift;
42 }
43
44 /**
45  * searches the modes obstack for the given mode and returns
46  * a pointer on an equal mode already in the array, NULL if
47  * none found
48  */
49 static ir_mode *find_mode(const ir_mode *m)
50 {
51         size_t i, n_modes;
52         for (i = 0, n_modes = ARR_LEN(mode_list); i < n_modes; ++i) {
53                 ir_mode *n = mode_list[i];
54                 if (modes_are_equal(n, m))
55                         return n;
56         }
57         return NULL;
58 }
59
60 /**
61  * sets special values of modes
62  */
63 static void set_mode_values(ir_mode* mode)
64 {
65         switch (get_mode_sort(mode))    {
66         case irms_reference:
67         case irms_int_number:
68         case irms_float_number:
69                 mode->min  = get_tarval_min(mode);
70                 mode->max  = get_tarval_max(mode);
71                 mode->null = get_tarval_null(mode);
72                 mode->one  = get_tarval_one(mode);
73                 mode->minus_one = get_tarval_minus_one(mode);
74                 if (get_mode_sort(mode) != irms_float_number) {
75                         mode->all_one = get_tarval_all_one(mode);
76                 } else {
77                         mode->all_one = tarval_bad;
78                 }
79                 break;
80
81         case irms_internal_boolean:
82                 mode->min  = tarval_b_false;
83                 mode->max  = tarval_b_true;
84                 mode->null = tarval_b_false;
85                 mode->one  = tarval_b_true;
86                 mode->minus_one = tarval_bad;
87                 mode->all_one = tarval_b_true;
88                 break;
89
90         case irms_control_flow:
91         case irms_block:
92         case irms_tuple:
93         case irms_any:
94         case irms_bad:
95         case irms_memory:
96                 mode->min  = tarval_bad;
97                 mode->max  = tarval_bad;
98                 mode->null = tarval_bad;
99                 mode->one  = tarval_bad;
100                 mode->minus_one = tarval_bad;
101                 break;
102         }
103 }
104
105 ir_mode *mode_T;
106 ir_mode *mode_X;
107 ir_mode *mode_M;
108 ir_mode *mode_BB;
109 ir_mode *mode_ANY;
110 ir_mode *mode_BAD;
111
112 ir_mode *mode_F;
113 ir_mode *mode_D;
114 ir_mode *mode_Q;
115
116 ir_mode *mode_Bs;
117 ir_mode *mode_Bu;
118 ir_mode *mode_Hs;
119 ir_mode *mode_Hu;
120 ir_mode *mode_Is;
121 ir_mode *mode_Iu;
122 ir_mode *mode_Ls;
123 ir_mode *mode_Lu;
124 ir_mode *mode_LLs;
125 ir_mode *mode_LLu;
126
127 ir_mode *mode_b;
128 ir_mode *mode_P;
129
130 ir_mode *mode_P_code;
131 ir_mode *mode_P_data;
132
133 ir_mode *get_modeT(void) { return mode_T; }
134 ir_mode *get_modeF(void) { return mode_F; }
135 ir_mode *get_modeD(void) { return mode_D; }
136 ir_mode *get_modeQ(void) { return mode_Q; }
137 ir_mode *get_modeBs(void) { return mode_Bs; }
138 ir_mode *get_modeBu(void) { return mode_Bu; }
139 ir_mode *get_modeHs(void) { return mode_Hs; }
140 ir_mode *get_modeHu(void) { return mode_Hu; }
141 ir_mode *get_modeIs(void) { return mode_Is; }
142 ir_mode *get_modeIu(void) { return mode_Iu; }
143 ir_mode *get_modeLs(void) { return mode_Ls; }
144 ir_mode *get_modeLu(void) { return mode_Lu; }
145 ir_mode *get_modeLLs(void){ return mode_LLs; }
146 ir_mode *get_modeLLu(void){ return mode_LLu; }
147 ir_mode *get_modeb(void) { return mode_b; }
148 ir_mode *get_modeP(void) { return mode_P; }
149 ir_mode *get_modeX(void) { return mode_X; }
150 ir_mode *get_modeM(void) { return mode_M; }
151 ir_mode *get_modeBB(void) { return mode_BB; }
152 ir_mode *get_modeANY(void) { return mode_ANY; }
153 ir_mode *get_modeBAD(void) { return mode_BAD; }
154
155
156 ir_mode *(get_modeP_code)(void)
157 {
158         return get_modeP_code_();
159 }
160
161 ir_mode *(get_modeP_data)(void)
162 {
163         return get_modeP_data_();
164 }
165
166 void set_modeP_code(ir_mode *p)
167 {
168         assert(mode_is_reference(p));
169         mode_P_code = p;
170 }
171
172 void set_modeP_data(ir_mode *p)
173 {
174         assert(mode_is_reference(p));
175         mode_P_data = p;
176         mode_P = p;
177 }
178
179 /*
180  * Creates a new mode.
181  */
182 static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
183                            ir_mode_arithmetic arithmetic, unsigned bit_size,
184                            int sign, unsigned modulo_shift)
185 {
186         ir_mode *mode_tmpl = OALLOCZ(&modes, ir_mode);
187
188         mode_tmpl->name         = new_id_from_str(name);
189         mode_tmpl->sort         = sort;
190         mode_tmpl->size         = bit_size;
191         mode_tmpl->sign         = sign ? 1 : 0;
192         mode_tmpl->modulo_shift = modulo_shift;
193         mode_tmpl->arithmetic   = arithmetic;
194         mode_tmpl->link         = NULL;
195         mode_tmpl->tv_priv      = NULL;
196         return mode_tmpl;
197 }
198
199 static ir_mode *register_mode(ir_mode *mode)
200 {
201         /* does any of the existing modes have the same properties? */
202         ir_mode *old = find_mode(mode);
203         if (old != NULL) {
204                 /* remove new mode from obstack */
205                 obstack_free(&modes, mode);
206                 return old;
207         }
208
209         mode->kind = k_ir_mode;
210         mode->type = new_type_primitive(mode);
211         ARR_APP1(ir_mode*, mode_list, mode);
212         set_mode_values(mode);
213         hook_new_mode(mode);
214         return mode;
215 }
216
217 ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
218                       unsigned bit_size, int sign, unsigned modulo_shift)
219 {
220         ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
221                                      sign, modulo_shift);
222         return register_mode(result);
223 }
224
225 ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
226                             unsigned bit_size, unsigned modulo_shift)
227 {
228         ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
229                                      0, modulo_shift);
230         return register_mode(result);
231 }
232
233 ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
234                         unsigned exponent_size, unsigned mantissa_size)
235 {
236         bool     explicit_one = false;
237         unsigned bit_size     = exponent_size + mantissa_size + 1;
238         ir_mode *result;
239
240         if (arithmetic == irma_x86_extended_float) {
241                 explicit_one = true;
242                 bit_size++;
243         } else if (arithmetic != irma_ieee754) {
244                 panic("Arithmetic %s invalid for float");
245         }
246         if (exponent_size >= 256)
247                 panic("Exponents >= 256 bits not supported");
248         if (mantissa_size >= 256)
249                 panic("Mantissa >= 256 bits not supported");
250
251         result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
252         result->float_desc.exponent_size = exponent_size;
253         result->float_desc.mantissa_size = mantissa_size;
254         result->float_desc.explicit_one  = explicit_one;
255         return register_mode(result);
256 }
257
258 ident *(get_mode_ident)(const ir_mode *mode)
259 {
260         return get_mode_ident_(mode);
261 }
262
263 const char *get_mode_name(const ir_mode *mode)
264 {
265         return get_id_str(mode->name);
266 }
267
268 unsigned (get_mode_size_bits)(const ir_mode *mode)
269 {
270         return get_mode_size_bits_(mode);
271 }
272
273 unsigned (get_mode_size_bytes)(const ir_mode *mode)
274 {
275         return get_mode_size_bytes_(mode);
276 }
277
278 int (get_mode_sign)(const ir_mode *mode)
279 {
280         return get_mode_sign_(mode);
281 }
282
283 ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode)
284 {
285         return get_mode_arithmetic_(mode);
286 }
287
288
289 unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
290 {
291         return get_mode_modulo_shift_(mode);
292 }
293
294 void *(get_mode_link)(const ir_mode *mode)
295 {
296         return get_mode_link_(mode);
297 }
298
299 void (set_mode_link)(ir_mode *mode, void *l)
300 {
301         set_mode_link_(mode, l);
302 }
303
304 ir_tarval *get_mode_min(ir_mode *mode)
305 {
306         assert(mode);
307         assert(mode_is_data(mode));
308
309         return mode->min;
310 }
311
312 ir_tarval *get_mode_max(ir_mode *mode)
313 {
314         assert(mode);
315         assert(mode_is_data(mode));
316
317         return mode->max;
318 }
319
320 ir_tarval *get_mode_null(ir_mode *mode)
321 {
322         assert(mode);
323         assert(mode_is_datab(mode));
324
325         return mode->null;
326 }
327
328 ir_tarval *get_mode_one(ir_mode *mode)
329 {
330         assert(mode);
331         assert(mode_is_datab(mode));
332
333         return mode->one;
334 }
335
336 ir_tarval *get_mode_minus_one(ir_mode *mode)
337 {
338         assert(mode);
339         assert(mode_is_data(mode));
340
341         return mode->minus_one;
342 }
343
344 ir_tarval *get_mode_all_one(ir_mode *mode)
345 {
346         assert(mode);
347         assert(mode_is_datab(mode));
348         return mode->all_one;
349 }
350
351 ir_tarval *get_mode_infinite(ir_mode *mode)
352 {
353         assert(mode);
354         assert(mode_is_float(mode));
355
356         return get_tarval_plus_inf(mode);
357 }
358
359 ir_tarval *get_mode_NAN(ir_mode *mode)
360 {
361         assert(mode);
362         assert(mode_is_float(mode));
363
364         return get_tarval_nan(mode);
365 }
366
367 int is_mode(const void *thing)
368 {
369         return get_kind(thing) == k_ir_mode;
370 }
371
372 int (mode_is_signed)(const ir_mode *mode)
373 {
374         return mode_is_signed_(mode);
375 }
376
377 int (mode_is_float)(const ir_mode *mode)
378 {
379         return mode_is_float_(mode);
380 }
381
382 int (mode_is_int)(const ir_mode *mode)
383 {
384         return mode_is_int_(mode);
385 }
386
387 int (mode_is_reference)(const ir_mode *mode)
388 {
389         return mode_is_reference_(mode);
390 }
391
392 int (mode_is_num)(const ir_mode *mode)
393 {
394         return mode_is_num_(mode);
395 }
396
397 int (mode_is_data)(const ir_mode *mode)
398 {
399         return mode_is_data_(mode);
400 }
401
402 int (mode_is_datab)(const ir_mode *mode)
403 {
404         return mode_is_datab_(mode);
405 }
406
407 int (mode_is_dataM)(const ir_mode *mode)
408 {
409         return mode_is_dataM_(mode);
410 }
411
412 unsigned (get_mode_mantissa_size)(const ir_mode *mode)
413 {
414         return get_mode_mantissa_size_(mode);
415 }
416
417 unsigned (get_mode_exponent_size)(const ir_mode *mode)
418 {
419         return get_mode_exponent_size_(mode);
420 }
421
422 int smaller_mode(const ir_mode *sm, const ir_mode *lm)
423 {
424         int sm_bits, lm_bits;
425
426         assert(sm);
427         assert(lm);
428
429         if (sm == lm) return 1;
430
431         sm_bits = get_mode_size_bits(sm);
432         lm_bits = get_mode_size_bits(lm);
433
434         switch (get_mode_sort(sm)) {
435         case irms_int_number:
436                 switch (get_mode_sort(lm)) {
437                 case irms_int_number:
438                         if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
439                                 return 0;
440
441                         /* only two complement implemented */
442                         assert(get_mode_arithmetic(sm) == irma_twos_complement);
443
444                         /* integers are convertable if
445                          *   - both have the same sign and lm is the larger one
446                          *   - lm is the signed one and is at least two bits larger
447                          *     (one for the sign, one for the highest bit of sm)
448                          *   - sm & lm are two_complement and lm has greater or equal number of bits
449                          */
450                         if (mode_is_signed(sm)) {
451                                 if (!mode_is_signed(lm))
452                                         return 0;
453                                 return sm_bits <= lm_bits;
454                         } else {
455                                 if (mode_is_signed(lm)) {
456                                         return sm_bits < lm_bits;
457                                 }
458                                 return sm_bits <= lm_bits;
459                         }
460
461                 case irms_float_number:
462                         /* int to float works if the float is large enough */
463                         return 0;
464
465                 default:
466                         break;
467                 }
468                 break;
469
470         case irms_float_number:
471                 if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
472                         if ( (get_mode_sort(lm) == irms_float_number)
473                                 && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
474                                 return 1;
475                 }
476                 break;
477
478         case irms_reference:
479                 /* do exist machines out there with different pointer lengths ?*/
480                 return 0;
481
482         case irms_internal_boolean:
483                 return mode_is_int(lm);
484
485         default:
486                 break;
487         }
488
489         /* else */
490         return 0;
491 }
492
493 int values_in_mode(const ir_mode *sm, const ir_mode *lm)
494 {
495         if (sm == lm)
496                 return true;
497
498         if (sm == mode_b)
499                 return mode_is_int(lm) || mode_is_float(lm);
500
501         ir_mode_arithmetic larith = get_mode_arithmetic(lm);
502         ir_mode_arithmetic sarith = get_mode_arithmetic(sm);
503         switch (larith) {
504         case irma_x86_extended_float:
505         case irma_ieee754:
506                 if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) {
507                         return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
508                 } else if (sarith == irma_twos_complement) {
509                         unsigned int_mantissa   = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0);
510                         unsigned float_mantissa = get_mode_mantissa_size(lm) + 1;
511                         return int_mantissa <= float_mantissa;
512                 }
513                 break;
514         case irma_twos_complement:
515                 if (sarith == irma_twos_complement) {
516                         return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
517                 }
518                 break;
519         case irma_none:
520                 break;
521         }
522         return false;
523 }
524
525 ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
526 {
527         assert(mode_is_reference(mode));
528         return mode->eq_signed;
529 }
530
531 void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
532 {
533         assert(mode_is_reference(ref_mode));
534         assert(mode_is_int(int_mode));
535         ref_mode->eq_signed = int_mode;
536 }
537
538 ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
539 {
540         assert(mode_is_reference(mode));
541         return mode->eq_unsigned;
542 }
543
544 void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
545 {
546         assert(mode_is_reference(ref_mode));
547         assert(mode_is_int(int_mode));
548         ref_mode->eq_unsigned = int_mode;
549 }
550
551 static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
552 {
553         ir_mode *mode = alloc_mode(name, sort, irma_none, 0, 0, 0);
554         return register_mode(mode);
555 }
556
557 void init_mode(void)
558 {
559         obstack_init(&modes);
560         mode_list = NEW_ARR_F(ir_mode*, 0);
561
562         /* initialize predefined modes */
563         mode_BB  = new_internal_mode("BB",  irms_block);
564         mode_X   = new_internal_mode("X",   irms_control_flow);
565         mode_M   = new_internal_mode("M",   irms_memory);
566         mode_T   = new_internal_mode("T",   irms_tuple);
567         mode_ANY = new_internal_mode("ANY", irms_any);
568         mode_BAD = new_internal_mode("BAD", irms_bad);
569         mode_b   = new_internal_mode("b",   irms_internal_boolean);
570
571         mode_F   = new_float_mode("F", irma_ieee754,  8, 23);
572         mode_D   = new_float_mode("D", irma_ieee754, 11, 52);
573         mode_Q   = new_float_mode("Q", irma_ieee754, 15, 112);
574
575         mode_Bs  = new_int_mode("Bs",  irma_twos_complement, 8,   1, 32);
576         mode_Bu  = new_int_mode("Bu",  irma_twos_complement, 8,   0, 32);
577         mode_Hs  = new_int_mode("Hs",  irma_twos_complement, 16,  1, 32);
578         mode_Hu  = new_int_mode("Hu",  irma_twos_complement, 16,  0, 32);
579         mode_Is  = new_int_mode("Is",  irma_twos_complement, 32,  1, 32);
580         mode_Iu  = new_int_mode("Iu",  irma_twos_complement, 32,  0, 32);
581         mode_Ls  = new_int_mode("Ls",  irma_twos_complement, 64,  1, 64);
582         mode_Lu  = new_int_mode("Lu",  irma_twos_complement, 64,  0, 64);
583         mode_LLs = new_int_mode("LLs", irma_twos_complement, 128, 1, 128);
584         mode_LLu = new_int_mode("LLu", irma_twos_complement, 128, 0, 128);
585
586         mode_P   = new_reference_mode("P", irma_twos_complement, 32, 32);
587         set_reference_mode_signed_eq(mode_P, mode_Is);
588         set_reference_mode_unsigned_eq(mode_P, mode_Iu);
589
590         /* set the machine specific modes to the predefined ones */
591         mode_P_code = mode_P;
592         mode_P_data = mode_P;
593 }
594
595 ir_mode *find_unsigned_mode(const ir_mode *mode)
596 {
597         ir_mode n = *mode;
598
599         /* allowed for reference mode */
600         if (mode->sort == irms_reference)
601                 n.sort = irms_int_number;
602
603         assert(n.sort == irms_int_number);
604         n.sign = 0;
605         return find_mode(&n);
606 }
607
608 ir_mode *find_signed_mode(const ir_mode *mode)
609 {
610         ir_mode n = *mode;
611
612         assert(mode->sort == irms_int_number);
613         n.sign = 1;
614         return find_mode(&n);
615 }
616
617 ir_mode *find_double_bits_int_mode(const ir_mode *mode)
618 {
619         ir_mode n = *mode;
620
621         assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
622
623         n.size = 2*mode->size;
624         return find_mode(&n);
625 }
626
627 int mode_honor_signed_zeros(const ir_mode *mode)
628 {
629         /* for floating point, we know that IEEE 754 has +0 and -0,
630          * but always handles it identical.
631          */
632         return
633                 mode->sort == irms_float_number &&
634                 mode->arithmetic != irma_ieee754;
635 }
636
637 int mode_overflow_on_unary_Minus(const ir_mode *mode)
638 {
639         if (mode->sort == irms_float_number)
640                 return mode->arithmetic == irma_ieee754 ? 0 : 1;
641         return 1;
642 }
643
644 int mode_wrap_around(const ir_mode *mode)
645 {
646         /* FIXME: better would be an extra mode property */
647         return mode_is_int(mode);
648 }
649
650 int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
651 {
652         ir_mode_arithmetic ma;
653
654         if (src == dst)
655                 return 1;
656         if (get_mode_size_bits(src) != get_mode_size_bits(dst))
657                 return 0;
658         ma = get_mode_arithmetic(src);
659         if (ma != get_mode_arithmetic(dst))
660                 return 0;
661
662         return ma == irma_twos_complement;
663 }
664
665 ir_type *(get_type_for_mode) (const ir_mode *mode)
666 {
667         return get_type_for_mode_(mode);
668 }
669
670 size_t ir_get_n_modes(void)
671 {
672         return ARR_LEN(mode_list);
673 }
674
675 ir_mode *ir_get_mode(size_t num)
676 {
677         assert(num < ARR_LEN(mode_list));
678         return mode_list[num];
679 }
680
681 void finish_mode(void)
682 {
683         obstack_free(&modes, 0);
684         DEL_ARR_F(mode_list);
685
686         mode_T   = NULL;
687         mode_X   = NULL;
688         mode_M   = NULL;
689         mode_BB  = NULL;
690         mode_ANY = NULL;
691         mode_BAD = NULL;
692
693         mode_F   = NULL;
694         mode_D   = NULL;
695
696         mode_Bs  = NULL;
697         mode_Bu  = NULL;
698         mode_Hs  = NULL;
699         mode_Hu  = NULL;
700         mode_Is  = NULL;
701         mode_Iu  = NULL;
702         mode_Ls  = NULL;
703         mode_Lu  = NULL;
704
705         mode_b   = NULL;
706
707         mode_P      = NULL;
708         mode_P_code = NULL;
709         mode_P_data = NULL;
710 }