1ebfddbc1766481ac3755a0542f709738c91ff7f
[libfirm] / ir / ir / irmode.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Martin Trapp, Christian Schaefer
5 **
6 */
7
8 /* $Id$ */
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14 # include "irmode_t.h"
15 # include "ident.h"
16 # include <stdlib.h>
17 # include <stddef.h>
18 # include <string.h>
19 # include "tv.h"
20 # include "obst.h"
21 # include "misc.h"
22
23 #if 0
24 static long long count = 0;
25 #  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__)
26 #else
27 #  define ANNOUNCE() ((void)0)
28 #endif
29
30 /* * *
31  * local values
32  * * */
33
34
35 /** dynamic array to hold all modes */
36 static struct obstack modes;
37
38 /** number of defined modes */
39 static int num_modes;
40
41 /* * *
42  * local functions
43  * * */
44
45 /**
46  * Compare modes that don't need to have their code field
47  * correctly set
48  *
49  * TODO: Add other fields
50  **/
51 INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
52 {
53   if (m == n) return 1;
54   if(!bcmp( m + offsetof(ir_mode,sort) , n + offsetof(ir_mode,sort), offsetof(ir_mode,min)-offsetof(ir_mode,min))) return 1;
55
56   return 0;
57 }
58
59 /**
60  * searches the modes obstack for the given mode and returns
61  * a pointer on an equal mode already in the array, NULL if
62  * none found
63  */
64 static ir_mode *find_mode(const ir_mode *m)
65 {
66   ir_mode *n;
67   struct _obstack_chunk *p;
68
69   p=modes.chunk;
70   for( n=(ir_mode*) p->contents; (char *)n < modes.next_free; n+=sizeof(ir_mode) )
71   {
72     if(modes_are_equal(n,m)) return n;
73   }
74
75   for (p = p->prev; p; p = p->prev)
76   {
77     for( n=(ir_mode*) p->contents; (char *)n < p->limit; n+=sizeof(ir_mode) )
78     {
79       if(modes_are_equal(n,m)) return n;
80     }
81   }
82
83   return NULL;
84 }
85
86 /**
87  * sets special values of modes
88  */
89 static void set_mode_values(ir_mode* mode)
90 {
91   mode->min = get_tarval_min(mode);
92   mode->max= get_tarval_max(mode);
93   mode->null= get_tarval_null(mode);
94   mode->one= get_tarval_one(mode);
95 }
96 /* * *
97  * globals defined in irmode.h
98  * * */
99
100 /* --- Predefined modes --- */
101
102 /* FIRM internal modes: */
103 ir_mode *mode_T;
104 ir_mode *mode_X;
105 ir_mode *mode_M;
106 ir_mode *mode_BB;
107 ir_mode *mode_ANY;
108 ir_mode *mode_BAD;
109
110 /* predefined numerical modes: */
111 ir_mode *mode_F;    /* float */
112 ir_mode *mode_D;    /* double */
113 ir_mode *mode_E;    /* long double */
114
115 ir_mode *mode_Bs;   /* integral values, signed and unsigned */
116 ir_mode *mode_Bu;   /* 8 bit */
117 ir_mode *mode_Hs;   /* 16 bit */
118 ir_mode *mode_Hu;
119 ir_mode *mode_Is;   /* 32 bit */
120 ir_mode *mode_Iu;
121 ir_mode *mode_Ls;   /* 64 bit */
122 ir_mode *mode_Lu;
123
124 ir_mode *mode_C;
125 ir_mode *mode_U;
126 ir_mode *mode_b;
127 ir_mode *mode_P;
128
129 /* * *
130  * functions defined in irmode.h
131  * * */
132
133 /* JNI access functions */
134 INLINE ir_mode *get_modeT(void) { ANNOUNCE(); return mode_T; }
135 INLINE ir_mode *get_modeF(void) { ANNOUNCE(); return mode_F; }
136 INLINE ir_mode *get_modeD(void) { ANNOUNCE(); return mode_D; }
137 INLINE ir_mode *get_modeE(void) { ANNOUNCE(); return mode_E; }
138 INLINE ir_mode *get_modeBs(void) { ANNOUNCE(); return mode_Bs; }
139 INLINE ir_mode *get_modeBu(void) { ANNOUNCE(); return mode_Bu; }
140 INLINE ir_mode *get_modeHs(void) { ANNOUNCE(); return mode_Hs; }
141 INLINE ir_mode *get_modeHu(void) { ANNOUNCE(); return mode_Hu; }
142 INLINE ir_mode *get_modeIs(void) { ANNOUNCE(); return mode_Is; }
143 INLINE ir_mode *get_modeIu(void) { ANNOUNCE(); return mode_Iu; }
144 INLINE ir_mode *get_modeLs(void) { ANNOUNCE(); return mode_Ls; }
145 INLINE ir_mode *get_modeLu(void) { ANNOUNCE(); return mode_Lu; }
146 INLINE ir_mode *get_modeC(void) { ANNOUNCE(); return mode_C; }
147 INLINE ir_mode *get_modeU(void) { ANNOUNCE(); return mode_U; }
148 INLINE ir_mode *get_modeb(void) { ANNOUNCE(); return mode_b; }
149 INLINE ir_mode *get_modeP(void) { ANNOUNCE(); return mode_P; }
150 INLINE ir_mode *get_modeX(void) { ANNOUNCE(); return mode_X; }
151 INLINE ir_mode *get_modeM(void) { ANNOUNCE(); return mode_M; }
152 INLINE ir_mode *get_modeBB(void) { ANNOUNCE(); return mode_BB; }
153 INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
154 INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
155
156 /**
157  * Registers a new mode if not defined yet, else returns
158  * the "equivalent" one.
159  */
160 static ir_mode *register_mode(const ir_mode* new_mode)
161 {
162   ir_mode *mode = NULL;
163
164   ANNOUNCE();
165   assert(new_mode);
166
167
168
169   /* copy mode struct to modes array */
170   mode=(ir_mode*) obstack_copy(&modes, new_mode, sizeof(ir_mode));
171
172   mode->kind = k_ir_mode;
173   if(num_modes>=irm_max) mode->code = num_modes;
174   num_modes++;
175
176   if(mode->sort==irms_int_number || mode->sort==irms_float_number || mode->sort==irms_character) set_mode_values(mode);
177
178   return mode;
179 }
180
181 /*
182  * Creates a new mode.
183  */
184 ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int align, int sign, mode_arithmetic arithmetic )
185 {
186   ir_mode mode_tmpl;
187   ir_mode *mode;
188
189   /* sanity checks */
190   switch (sort)
191   {
192     case irms_auxiliary:
193     case irms_control_flow:
194     case irms_memory:
195     case irms_internal_boolean:
196       assert(0 && "internal modes cannot be user defined");
197       return NULL;
198       break;
199
200     case irms_float_number:
201       assert(0 && "not yet implemented");
202       return NULL;
203       break;
204
205     case irms_int_number:
206     case irms_reference:
207     case irms_character:
208       break;
209   }
210   mode_tmpl.name        = new_id_from_str(name);
211   mode_tmpl.sort        = sort;
212   mode_tmpl.size        = bit_size;
213   mode_tmpl.align       = align;
214   mode_tmpl.sign        = sign ? 1 : 0;
215   mode_tmpl.arithmetic  = arithmetic;
216   mode_tmpl.tv_priv     = NULL;
217
218   /* first check if there already is a matching mode */
219   mode = find_mode(&mode_tmpl);
220   if (mode)
221   {
222     return mode;
223   }
224   else
225   {
226     return register_mode(&mode_tmpl);
227   }
228 }
229
230 /* Functions for the direct access to all attributes od a ir_mode */
231 modecode
232 get_mode_modecode(const ir_mode *mode)
233 {
234   ANNOUNCE();
235   return mode->code;
236 }
237
238 ident *
239 get_mode_ident(const ir_mode *mode)
240 {
241   ANNOUNCE();
242   return mode->name;
243 }
244
245 const char *
246 get_mode_name(const ir_mode *mode)
247 {
248   ANNOUNCE();
249   return id_to_str(mode->name);
250 }
251
252 mode_sort
253 get_mode_sort(const ir_mode* mode)
254 {
255   ANNOUNCE();
256   return mode->sort;
257 }
258
259 INLINE int
260 get_mode_size_bits(const ir_mode *mode)
261 {
262   ANNOUNCE();
263   return mode->size;
264 }
265
266 int get_mode_size_bytes(const ir_mode *mode) {
267   int size = get_mode_size_bits(mode);
268   ANNOUNCE();
269   if ((size & 7) != 0) return -1;
270   return size >> 3;
271 }
272
273 int
274 get_mode_align (const ir_mode *mode)
275 {
276   ANNOUNCE();
277   return mode->align;
278 }
279
280 int
281 get_mode_sign (const ir_mode *mode)
282 {
283   ANNOUNCE();
284   return mode->sign;
285 }
286
287 int get_mode_arithmetic (const ir_mode *mode)
288 {
289   ANNOUNCE();
290   return mode->arithmetic;
291 }
292
293 void* get_mode_link(const ir_mode *mode)
294 {
295   ANNOUNCE();
296   return mode->link;
297 }
298
299 void set_mode_link(ir_mode *mode, void *l)
300 {
301   mode->link=l;
302   return;
303 }
304
305 tarval *
306 get_mode_min (ir_mode *mode)
307 {
308   ANNOUNCE();
309   assert(mode);
310   assert(get_mode_modecode(mode) < num_modes);
311   assert(mode_is_data(mode));
312
313   return mode->min;
314 }
315
316 tarval *
317 get_mode_max (ir_mode *mode)
318 {
319   ANNOUNCE();
320   assert(mode);
321   assert(get_mode_modecode(mode) < num_modes);
322   assert(mode_is_data(mode));
323
324   return mode->max;
325 }
326
327 tarval *
328 get_mode_null (ir_mode *mode)
329 {
330   ANNOUNCE();
331   assert(mode);
332   assert(get_mode_modecode(mode) < num_modes);
333   assert(mode_is_data(mode));
334
335   return mode->null;
336 }
337
338 tarval *
339 get_mode_one (ir_mode *mode)
340 {
341   ANNOUNCE();
342   assert(mode);
343   assert(get_mode_modecode(mode) < num_modes);
344   assert(mode_is_data(mode));
345
346   return mode->one;
347 }
348
349 tarval *
350 get_mode_infinite(ir_mode *mode)
351 {
352   ANNOUNCE();
353   assert(mode);
354   assert(get_mode_modecode(mode) < num_modes);
355   assert(mode_is_float(mode));
356
357   return get_tarval_inf(mode);
358 }
359
360 tarval *
361 get_mode_NAN(ir_mode *mode)
362 {
363   ANNOUNCE();
364   assert(mode);
365   assert(get_mode_modecode(mode) < num_modes);
366   assert(mode_is_float(mode));
367
368   return get_tarval_nan(mode);
369 }
370
371 int
372 is_mode (void *thing) {
373   assert(thing);
374   if (get_kind(thing) == k_ir_mode)
375     return 1;
376   else
377     return 0;
378 }
379
380 /* Functions to check, whether a modecode is signed, float, int, num, data,
381    datab or dataM. For more exact definitions read the corresponding pages
382    in the firm documentation or the followingenumeration
383
384    The set of "float" is defined as:
385    ---------------------------------
386    float = {irm_F, irm_D, irm_E}
387
388    The set of "int" is defined as:
389    -------------------------------
390    int   = {irm_Bs, irm_Bu, irm_Hs, irm_Hu, irm_Is, irm_Iu, irm_Ls, irm_Lu}
391
392    The set of "num" is defined as:
393    -------------------------------
394    num   = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
395             irm_Is, irm_Iu, irm_Ls, irm_Lu}
396             = {float || int}
397
398    The set of "data" is defined as:
399    -------------------------------
400    data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
401             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P}
402             = {num || irm_C || irm_U || irm_P}
403
404    The set of "datab" is defined as:
405    ---------------------------------
406    datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
407             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
408             = {data || irm_b }
409
410    The set of "dataM" is defined as:
411    ---------------------------------
412    dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
413             irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_M}
414             = {data || irm_M}
415 */
416
417 #ifdef MODE_ACCESS_DEFINES
418 #  undef mode_is_signed
419 #  undef mode_is_float
420 #  undef mode_is_int
421 #  undef mode_is_num
422 #  undef mode_is_data
423 #  undef mode_is_datab
424 #  undef mode_is_dataM
425 #endif
426 int
427 mode_is_signed (const ir_mode *mode)
428 {
429   ANNOUNCE();
430   assert(mode);
431   return mode->sign;
432 }
433
434 int
435 mode_is_float (const ir_mode *mode)
436 {
437   ANNOUNCE();
438   assert(mode);
439   return (get_mode_sort(mode) == irms_float_number);
440 }
441
442 int
443 mode_is_int (const ir_mode *mode)
444 {
445   ANNOUNCE();
446   assert(mode);
447   return (get_mode_sort(mode) == irms_int_number);
448 }
449
450 int mode_is_character (const ir_mode *mode)
451 {
452   ANNOUNCE();
453   assert(mode);
454   return (get_mode_sort(mode) == irms_character);
455 }
456
457 int mode_is_reference (const ir_mode *mode)
458 {
459   ANNOUNCE();
460   assert(mode);
461   return (get_mode_sort(mode) == irms_reference);
462 }
463
464 int
465 mode_is_num (const ir_mode *mode)
466 {
467   ANNOUNCE();
468   assert(mode);
469   return (mode_is_int(mode) || mode_is_float(mode));
470 }
471
472 int
473 mode_is_data (const ir_mode *mode)
474 {
475   ANNOUNCE();
476   assert(mode);
477   return (mode_is_num(mode) || get_mode_sort(mode) == irms_character || get_mode_sort(mode) == irms_reference);
478 }
479
480 int
481 mode_is_datab (const ir_mode *mode)
482 {
483   ANNOUNCE();
484   assert(mode);
485   return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
486 }
487
488 int
489 mode_is_dataM (const ir_mode *mode)
490 {
491   ANNOUNCE();
492   assert(mode);
493   return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
494 }
495 #ifdef MODE_ACCESS_DEFINES
496 #  define mode_is_signed(mode) (mode)->sign
497 #  define mode_is_float(mode) ((mode)->sort == irms_float_number)
498 #  define mode_is_int(mode) ((mode)->sort == irms_int_number)
499 #  define mode_is_num(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number))
500 #  define mode_is_data(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference))
501 #  define mode_is_datab(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->sort == irms_internal_boolean))
502 #  define mode_is_dataM(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->code == irm_M))
503 #endif
504 /* Returns true if sm can be converted to lm without loss. */
505 int
506 smaller_mode(const ir_mode *sm, const ir_mode *lm)
507 {
508   ANNOUNCE();
509   assert(sm);
510   assert(lm);
511
512   if (sm == lm) return 1;
513
514   switch(get_mode_sort(sm))
515   {
516     case irms_int_number:
517       switch(get_mode_sort(lm))
518       {
519         case irms_int_number:
520           /* integers are convertable if
521            *   - both have the same sign and lm is the larger one
522            *   - lm is the signed one and is at least two bits larger
523            *     (one for the sign, one for the highest bit of sm)
524            */
525           if (mode_is_signed(sm))
526           {
527             if ( mode_is_signed(lm) && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
528               return 1;
529           }
530           else if (mode_is_signed(lm))
531           {
532             if (get_mode_size_bits(lm) > get_mode_size_bits(sm) + 1)
533               return 1;
534           }
535           else if (get_mode_size_bits(lm) > get_mode_size_bits(sm))
536           {
537             return 1;
538           }
539           break;
540
541         case irms_float_number:
542           /* int to float works if the float is large enough */
543           return 0;
544
545         default:
546           break;
547       }
548       break;
549
550     case irms_float_number:
551       /* XXX currently only the three standard 32,64,80 bit floats
552        * are supported which can safely be converted */
553       if ( (get_mode_sort(lm) == irms_float_number)
554            && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
555          return 1;
556       break;
557
558     case irms_reference:
559        /* do exist machines out there with different pointer lenghts ?*/
560       return 0;
561
562     default:
563       break;
564   }
565
566   /* else */
567   return 0;
568 }
569
570 /* ** initialization ** */
571 void
572 init_mode (void)
573 {
574   ir_mode newmode;
575   ANNOUNCE();
576   /* init flexible array */
577
578   obstack_init(&modes);
579
580   num_modes  =  0;
581   /* initialize predefined modes */
582
583   /* Internal Modes */
584   newmode.arithmetic = irma_none;
585   newmode.size    = 0;
586   newmode.align   = 0;
587   newmode.sign    = 0;
588   newmode.tv_priv = NULL;
589
590   /* Control Flow Modes*/
591   newmode.sort    = irms_control_flow;
592
593   /* Basic Block */
594   newmode.name    = id_from_str("BB", 2);
595   newmode.code    = irm_BB;
596
597   mode_BB = register_mode(&newmode);
598
599 /* eXecution */
600   newmode.name    = id_from_str("X", 1);
601   newmode.code    = irm_X;
602
603   mode_X = register_mode(&newmode);
604
605   /* Memory Modes */
606   newmode.sort    = irms_memory;
607
608   /* Memory */
609   newmode.name    = id_from_str("M", 1);
610   newmode.code    = irm_M;
611
612   mode_M = register_mode(&newmode);
613
614   /* Auxiliary Modes */
615   newmode.sort    = irms_auxiliary,
616
617   /* Tuple */
618   newmode.name    = id_from_str("T", 1);
619   newmode.code    = irm_T;
620
621   mode_T = register_mode(&newmode);
622
623   /* ANY */
624   newmode.name    = id_from_str("ANY", 3);
625   newmode.code    = irm_ANY;
626
627   mode_ANY = register_mode(&newmode);
628
629   /* BAD */
630   newmode.name    = id_from_str("BAD", 3);
631   newmode.code    = irm_BAD;
632
633   mode_BAD = register_mode(&newmode);
634
635   /* Internal Boolean Modes */
636   newmode.sort    = irms_internal_boolean;
637
638   /* boolean */
639   newmode.name    = id_from_str("b", 1);
640   newmode.code    = irm_b;
641
642   mode_b = register_mode(&newmode);
643
644 /* Data Modes */
645
646   /* Float Number Modes */
647   newmode.sort    = irms_float_number;
648   newmode.arithmetic = irma_ieee754;
649
650   /* float */
651   newmode.name    = id_from_str("F", 1);
652   newmode.code    = irm_F;
653   newmode.sign    = 1;
654   newmode.align   = 4;
655   newmode.size    = 32;
656
657   mode_F = register_mode(&newmode);
658
659   /* double */
660   newmode.name    = id_from_str("D", 1);
661   newmode.code    = irm_D;
662   newmode.sign    = 1;
663   newmode.align   = 4;
664   newmode.size    = 64;
665
666   mode_D = register_mode(&newmode);
667
668   /* extended */
669   newmode.name    = id_from_str("E", 1);
670   newmode.code    = irm_E;
671   newmode.sign    = 1;
672   newmode.align   = 4;
673   newmode.size    = 80;
674
675   mode_E = register_mode(&newmode);
676
677   /* Integer Number Modes */
678   newmode.sort    = irms_int_number;
679   newmode.arithmetic = irma_twos_complement;
680
681   /* signed byte */
682   newmode.name    = id_from_str("Bs", 2);
683   newmode.code    = irm_Bs;
684   newmode.sign    = 1;
685   newmode.align   = 1;
686   newmode.size    = 8;
687
688   mode_Bs = register_mode(&newmode);
689
690   /* unsigned byte */
691   newmode.name    = id_from_str("Bu", 2);
692   newmode.code    = irm_Bu;
693   newmode.arithmetic = irma_twos_complement;
694   newmode.sign    = 0;
695   newmode.align   = 1;
696   newmode.size    = 8;
697
698   mode_Bu = register_mode(&newmode);
699
700   /* signed short integer */
701   newmode.name    = id_from_str("Hs", 2);
702   newmode.code    = irm_Hs;
703   newmode.sign    = 1;
704   newmode.align   = 2;
705   newmode.size    = 16;
706
707   mode_Hs = register_mode(&newmode);
708
709   /* unsigned short integer */
710   newmode.name    = id_from_str("Hu", 2);
711   newmode.code    = irm_Hu;
712   newmode.sign    = 0;
713   newmode.align   = 2;
714   newmode.size    = 16;
715
716   mode_Hu = register_mode(&newmode);
717
718   /* signed integer */
719   newmode.name    = id_from_str("Is", 2);
720   newmode.code    = irm_Is;
721   newmode.sign    = 1;
722   newmode.align   = 4;
723   newmode.size    = 32;
724
725   mode_Is = register_mode(&newmode);
726
727   /* unsigned integer */
728   newmode.name    = id_from_str("Iu", 2);
729   newmode.code    = irm_Iu;
730   newmode.sign    = 0;
731   newmode.align   = 4;
732   newmode.size    = 32;
733
734   mode_Iu = register_mode(&newmode);
735
736   /* signed long integer */
737   newmode.name    = id_from_str("Ls", 2);
738   newmode.code    = irm_Ls;
739   newmode.sign    = 1;
740   newmode.align   = 4;
741   newmode.size    = 64;
742
743   mode_Ls = register_mode(&newmode);
744
745   /* unsigned long integer */
746   newmode.name    = id_from_str("Lu", 2);
747   newmode.code    = irm_Lu;
748   newmode.sign    = 0;
749   newmode.align   = 4;
750   newmode.size    = 64;
751
752   mode_Lu = register_mode(&newmode);
753
754   /* Integer Number Modes */
755   newmode.sort    = irms_character;
756   newmode.arithmetic = irma_none;
757
758   /* Character */
759   newmode.name    = id_from_str("C", 1);
760   newmode.code    = irm_C;
761   newmode.sign    = 0;
762   newmode.align   = 1;
763   newmode.size    = 8;
764
765   mode_C = register_mode(&newmode);
766
767   /* Unicode character */
768   newmode.name    = id_from_str("U", 1);
769   newmode.code    = irm_U;
770   newmode.sign    = 0;
771   newmode.align   = 2;
772   newmode.size    = 16;
773
774   mode_U = register_mode(&newmode);
775
776   /* Reference Modes */
777   newmode.sort    = irms_reference;
778   newmode.arithmetic = irma_twos_complement;
779
780   /* pointer */
781   newmode.name    = id_from_str("P", 1);
782   newmode.code    = irm_P;
783   newmode.sign    = 0;
784   newmode.align   = 4;
785   newmode.size    = 32;
786
787   mode_P = register_mode(&newmode);
788 }