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