fixed doxygen comments
[libfirm] / ir / ir / irmode.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/irmode.c
4  * Purpose:     Data modes of operations.
5  * Author:      Martin Trapp, Christian Schaefer
6  * Modified by: Goetz Lindenmaier, Mathias Heil
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12 #ifdef HAVE_CONFIG_H
13 # include "config.h"
14 #endif
15
16 #ifdef HAVE_STDLIB_H
17 # include <stdlib.h>
18 #endif
19 #ifdef HAVE_STRING_H
20 # include <string.h>
21 #endif
22
23 # include <stddef.h>
24
25 # include "irmode_t.h"
26 # include "ident.h"
27 # include "tv_t.h"
28 # include "obst.h"
29 # include "irhooks.h"
30
31 #if 0
32 static long long count = 0;
33 #  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__)
34 #else
35 #  define ANNOUNCE() ((void)0)
36 #endif
37
38 /* * *
39  * local values
40  * * */
41
42
43 /** dynamic array to hold all modes */
44 static struct obstack modes;
45
46 /** number of defined modes */
47 static int num_modes;
48
49 /* * *
50  * local functions
51  * * */
52
53 /**
54  * Compare modes that don't need to have their code field
55  * correctly set
56  *
57  * TODO: Add other fields
58  **/
59 INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
60 {
61   if (m == n) return 1;
62   if (m->sort         == n->sort &&
63       m->arithmetic   == n->arithmetic &&
64       m->size         == n->size &&
65       m->sign         == n->sign  &&
66       m->modulo_shift == n->modulo_shift &&
67       m->vector_elem  == n->vector_elem)
68     return 1;
69
70   return 0;
71 }
72
73 /*
74  * calculates the next obstack address
75  */
76 static void *next_obstack_adr(struct obstack *o, void *p, size_t s)
77 {
78   PTR_INT_TYPE adr = __PTR_TO_INT((char *)p);
79   int mask = obstack_alignment_mask(o);
80
81   adr += s + mask;
82
83   return __INT_TO_PTR(adr & ~mask);
84 }
85
86 /**
87  * searches the modes obstack for the given mode and returns
88  * a pointer on an equal mode already in the array, NULL if
89  * none found
90  */
91 static ir_mode *find_mode(const ir_mode *m)
92 {
93   ir_mode *n, *nn;
94   struct _obstack_chunk *p;
95
96   p  = modes.chunk;
97   n  = (ir_mode *)p->contents;
98   nn = next_obstack_adr(&modes, n, sizeof(*n));
99   for (; (char *)nn <= modes.next_free;) {
100     assert(is_mode(n));
101     if (modes_are_equal(n, m))
102       return n;
103
104     n  = nn;
105     nn = next_obstack_adr(&modes, n, sizeof(*n));
106   }
107
108   for (p = p->prev; p; p = p->prev) {
109     n  = (ir_mode *)p->contents;
110     nn = next_obstack_adr(&modes, n, sizeof(*n));
111     for (; (char *)nn < p->limit;) {
112       assert(is_mode(n));
113       if (modes_are_equal(n, m))
114         return n;
115
116       n  = nn;
117       nn = next_obstack_adr(&modes, n, sizeof(*n));
118     }
119   }
120
121   return NULL;
122 }
123
124 /**
125  * sets special values of modes
126  */
127 static void set_mode_values(ir_mode* mode)
128 {
129   switch (get_mode_sort(mode))
130   {
131     case irms_character:
132     case irms_int_number:
133     case irms_float_number:
134       mode->min  = get_tarval_min(mode);
135       mode->max  = get_tarval_max(mode);
136       mode->null = get_tarval_null(mode);
137       mode->one  = get_tarval_one(mode);
138       mode->minus_one = get_tarval_minus_one(mode);
139       break;
140
141     case irms_internal_boolean:
142       mode->min  = tarval_b_false;
143       mode->max  = tarval_b_true;
144       mode->null = tarval_b_false;
145       mode->one  = tarval_b_true;
146       mode->minus_one = tarval_bad;
147       break;
148
149     case irms_reference:
150       mode->min  = tarval_bad;
151       mode->max  = tarval_bad;
152       mode->null = get_tarval_null(mode);
153       mode->one  = tarval_bad;
154       mode->minus_one = tarval_bad;
155       break;
156
157     case irms_auxiliary:
158     case irms_memory:
159     case irms_control_flow:
160       mode->min  = tarval_bad;
161       mode->max  = tarval_bad;
162       mode->null = tarval_bad;
163       mode->one  = tarval_bad;
164       mode->minus_one = tarval_bad;
165       break;
166   }
167 }
168
169 /* * *
170  * globals defined in irmode.h
171  * * */
172
173 /* --- Predefined modes --- */
174
175 /* FIRM internal modes: */
176 ir_mode *mode_T;
177 ir_mode *mode_X;
178 ir_mode *mode_M;
179 ir_mode *mode_BB;
180 ir_mode *mode_ANY;
181 ir_mode *mode_BAD;
182
183 /* predefined numerical modes: */
184 ir_mode *mode_F;    /* float */
185 ir_mode *mode_D;    /* double */
186 ir_mode *mode_E;    /* long double */
187
188 ir_mode *mode_Bs;   /* integral values, signed and unsigned */
189 ir_mode *mode_Bu;   /* 8 bit */
190 ir_mode *mode_Hs;   /* 16 bit */
191 ir_mode *mode_Hu;
192 ir_mode *mode_Is;   /* 32 bit */
193 ir_mode *mode_Iu;
194 ir_mode *mode_Ls;   /* 64 bit */
195 ir_mode *mode_Lu;
196
197 ir_mode *mode_C;
198 ir_mode *mode_U;
199 ir_mode *mode_b;
200 ir_mode *mode_P;
201
202 /* machine specific modes */
203 ir_mode *mode_P_mach;   /* machine specific pointer mode */
204
205 /* * *
206  * functions defined in irmode.h
207  * * */
208
209 /* JNI access functions */
210 INLINE ir_mode *get_modeT(void) { ANNOUNCE(); return mode_T; }
211 INLINE ir_mode *get_modeF(void) { ANNOUNCE(); return mode_F; }
212 INLINE ir_mode *get_modeD(void) { ANNOUNCE(); return mode_D; }
213 INLINE ir_mode *get_modeE(void) { ANNOUNCE(); return mode_E; }
214 INLINE ir_mode *get_modeBs(void) { ANNOUNCE(); return mode_Bs; }
215 INLINE ir_mode *get_modeBu(void) { ANNOUNCE(); return mode_Bu; }
216 INLINE ir_mode *get_modeHs(void) { ANNOUNCE(); return mode_Hs; }
217 INLINE ir_mode *get_modeHu(void) { ANNOUNCE(); return mode_Hu; }
218 INLINE ir_mode *get_modeIs(void) { ANNOUNCE(); return mode_Is; }
219 INLINE ir_mode *get_modeIu(void) { ANNOUNCE(); return mode_Iu; }
220 INLINE ir_mode *get_modeLs(void) { ANNOUNCE(); return mode_Ls; }
221 INLINE ir_mode *get_modeLu(void) { ANNOUNCE(); return mode_Lu; }
222 INLINE ir_mode *get_modeC(void) { ANNOUNCE(); return mode_C; }
223 INLINE ir_mode *get_modeU(void) { ANNOUNCE(); return mode_U; }
224 INLINE ir_mode *get_modeb(void) { ANNOUNCE(); return mode_b; }
225 INLINE ir_mode *get_modeP(void) { ANNOUNCE(); return mode_P; }
226 INLINE ir_mode *get_modeX(void) { ANNOUNCE(); return mode_X; }
227 INLINE ir_mode *get_modeM(void) { ANNOUNCE(); return mode_M; }
228 INLINE ir_mode *get_modeBB(void) { ANNOUNCE(); return mode_BB; }
229 INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
230 INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
231
232
233 ir_mode *(get_modeP_mach)(void) {
234   ANNOUNCE();
235   return _get_modeP_mach();
236 }
237
238 void (set_modeP_mach)(ir_mode *p) {
239   ANNOUNCE();
240   _set_modeP_mach(p);
241 }
242
243 /**
244  * Registers a new mode.
245  *
246  * @param new_mode  The new mode template.
247  */
248 static ir_mode *register_mode(const ir_mode *new_mode)
249 {
250   ir_mode *mode = NULL;
251
252   ANNOUNCE();
253   assert(new_mode);
254
255   /* copy mode struct to modes array */
256   mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode));
257
258   mode->kind = k_ir_mode;
259   if (num_modes >= irm_max) mode->code = num_modes;
260   num_modes++;
261
262   set_mode_values(mode);
263
264   hook_new_mode(new_mode, mode);
265   return mode;
266 }
267
268 /*
269  * Creates a new mode.
270  */
271 ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
272                      mode_arithmetic arithmetic, unsigned int modulo_shift )
273 {
274   ir_mode mode_tmpl;
275   ir_mode *mode = NULL;
276
277   mode_tmpl.name         = new_id_from_str(name);
278   mode_tmpl.sort         = sort;
279   mode_tmpl.size         = bit_size;
280   mode_tmpl.sign         = sign ? 1 : 0;
281   mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
282   mode_tmpl.vector_elem  = 1;
283   mode_tmpl.arithmetic   = arithmetic;
284   mode_tmpl.link         = NULL;
285   mode_tmpl.tv_priv      = NULL;
286
287   mode = find_mode(&mode_tmpl);
288   if (mode) {
289     hook_new_mode(&mode_tmpl, mode);
290     return mode;
291   }
292
293   /* sanity checks */
294   switch (sort)
295   {
296     case irms_auxiliary:
297     case irms_control_flow:
298     case irms_memory:
299     case irms_internal_boolean:
300       assert(0 && "internal modes cannot be user defined");
301       break;
302
303     case irms_float_number:
304     case irms_int_number:
305     case irms_reference:
306     case irms_character:
307       mode = register_mode(&mode_tmpl);
308   }
309   return mode;
310 }
311
312 /*
313  * Creates a new vector mode.
314  */
315 ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
316                      mode_arithmetic arithmetic, unsigned int modulo_shift )
317 {
318   ir_mode mode_tmpl;
319   ir_mode *mode = NULL;
320
321   mode_tmpl.name         = new_id_from_str(name);
322   mode_tmpl.sort         = sort;
323   mode_tmpl.size         = bit_size * num_of_elem;
324   mode_tmpl.sign         = sign ? 1 : 0;
325   mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
326   mode_tmpl.vector_elem  = num_of_elem;
327   mode_tmpl.arithmetic   = arithmetic;
328   mode_tmpl.link         = NULL;
329   mode_tmpl.tv_priv      = NULL;
330
331   mode = find_mode(&mode_tmpl);
332   if (mode) {
333     hook_new_mode(&mode_tmpl, mode);
334     return mode;
335   }
336
337   if (num_of_elem <= 1) {
338     assert(0 && "vector modes should have at least 2 elements");
339     return NULL;
340   }
341
342   /* sanity checks */
343   switch (sort)
344   {
345     case irms_auxiliary:
346     case irms_control_flow:
347     case irms_memory:
348     case irms_internal_boolean:
349       assert(0 && "internal modes cannot be user defined");
350       break;
351
352     case irms_reference:
353     case irms_character:
354       assert(0 && "only integer and floating point modes can be vectorized");
355       break;
356
357     case irms_float_number:
358       assert(0 && "not yet implemented");
359       break;
360
361     case irms_int_number:
362       mode = register_mode(&mode_tmpl);
363   }
364   return mode;
365 }
366
367 /* Functions for the direct access to all attributes od a ir_mode */
368 modecode
369 (get_mode_modecode)(const ir_mode *mode)
370 {
371   ANNOUNCE();
372   return _get_mode_modecode(mode);
373 }
374
375 ident *
376 (get_mode_ident)(const ir_mode *mode)
377 {
378   ANNOUNCE();
379   return _get_mode_ident(mode);
380 }
381
382 const char *
383 get_mode_name(const ir_mode *mode)
384 {
385   ANNOUNCE();
386   return get_id_str(mode->name);
387 }
388
389 mode_sort
390 (get_mode_sort)(const ir_mode* mode)
391 {
392   ANNOUNCE();
393   return _get_mode_sort(mode);
394 }
395
396 int
397 (get_mode_size_bits)(const ir_mode *mode)
398 {
399   ANNOUNCE();
400   return _get_mode_size_bits(mode);
401 }
402
403 int
404 (get_mode_size_bytes)(const ir_mode *mode) {
405   ANNOUNCE();
406   return _get_mode_size_bytes(mode);
407 }
408
409 int
410 (get_mode_sign)(const ir_mode *mode)
411 {
412   ANNOUNCE();
413   return _get_mode_sign(mode);
414 }
415
416 int
417 (get_mode_arithmetic)(const ir_mode *mode)
418 {
419   ANNOUNCE();
420   return get_mode_arithmetic(mode);
421 }
422
423
424 /* Attribute modulo shift specifies for modes of kind irms_int_number
425  *  whether shift applies modulo to value of bits to shift.  Asserts
426  *  if mode is not irms_int_number.
427  */
428 unsigned int
429 (get_mode_modulo_shift)(const ir_mode *mode) {
430   return _get_mode_modulo_shift(mode);
431 }
432
433 unsigned int
434 (get_mode_n_vector_elems)(const ir_mode *mode) {
435   return _get_mode_vector_elems(mode);
436 }
437
438 void *
439 (get_mode_link)(const ir_mode *mode)
440 {
441   ANNOUNCE();
442   return _get_mode_link(mode);
443 }
444
445 void
446 (set_mode_link)(ir_mode *mode, void *l)
447 {
448   _set_mode_link(mode, l);
449 }
450
451 tarval *
452 get_mode_min (ir_mode *mode)
453 {
454   ANNOUNCE();
455   assert(mode);
456   assert(get_mode_modecode(mode) < num_modes);
457   assert(mode_is_data(mode));
458
459   return mode->min;
460 }
461
462 tarval *
463 get_mode_max (ir_mode *mode)
464 {
465   ANNOUNCE();
466   assert(mode);
467   assert(get_mode_modecode(mode) < num_modes);
468   assert(mode_is_data(mode));
469
470   return mode->max;
471 }
472
473 tarval *
474 get_mode_null (ir_mode *mode)
475 {
476   ANNOUNCE();
477   assert(mode);
478   assert(get_mode_modecode(mode) < num_modes);
479   assert(mode_is_data(mode));
480
481   return mode->null;
482 }
483
484 tarval *
485 get_mode_one (ir_mode *mode)
486 {
487   ANNOUNCE();
488   assert(mode);
489   assert(get_mode_modecode(mode) < num_modes);
490   assert(mode_is_data(mode));
491
492   return mode->one;
493 }
494
495 tarval *
496 get_mode_minus_one (ir_mode *mode)
497 {
498   ANNOUNCE();
499   assert(mode);
500   assert(get_mode_modecode(mode) < num_modes);
501   assert(mode_is_data(mode));
502
503   return mode->minus_one;
504 }
505
506 tarval *
507 get_mode_infinite(ir_mode *mode)
508 {
509   ANNOUNCE();
510   assert(mode);
511   assert(get_mode_modecode(mode) < num_modes);
512   assert(mode_is_float(mode));
513
514   return get_tarval_plus_inf(mode);
515 }
516
517 tarval *
518 get_mode_NAN(ir_mode *mode)
519 {
520   ANNOUNCE();
521   assert(mode);
522   assert(get_mode_modecode(mode) < num_modes);
523   assert(mode_is_float(mode));
524
525   return get_tarval_nan(mode);
526 }
527
528 int
529 is_mode (void *thing) {
530   if (get_kind(thing) == k_ir_mode)
531     return 1;
532   else
533     return 0;
534 }
535
536 int
537 (mode_is_signed)(const ir_mode *mode) {
538   ANNOUNCE();
539   return _mode_is_signed(mode);
540 }
541
542 int
543 (mode_is_float)(const ir_mode *mode) {
544   ANNOUNCE();
545   return _mode_is_float(mode);
546 }
547
548 int
549 (mode_is_int)(const ir_mode *mode) {
550   ANNOUNCE();
551   return _mode_is_int(mode);
552 }
553
554 int
555 (mode_is_character)(const ir_mode *mode) {
556   ANNOUNCE();
557   return _mode_is_character(mode);
558 }
559
560 int
561 (mode_is_reference)(const ir_mode *mode) {
562   ANNOUNCE();
563   return _mode_is_reference(mode);
564 }
565
566 int
567 (mode_is_num)(const ir_mode *mode) {
568   ANNOUNCE();
569   return _mode_is_num(mode);
570 }
571
572 int
573 (mode_is_numP)(const ir_mode *mode) {
574   ANNOUNCE();
575   return _mode_is_numP(mode);
576 }
577
578 int
579 (mode_is_data)(const ir_mode *mode) {
580   ANNOUNCE();
581   return _mode_is_data(mode);
582 }
583
584 int
585 (mode_is_datab)(const ir_mode *mode) {
586   ANNOUNCE();
587   return _mode_is_datab(mode);
588 }
589
590 int
591 (mode_is_dataM)(const ir_mode *mode) {
592   ANNOUNCE();
593   return _mode_is_dataM(mode);
594 }
595
596 int
597 (mode_is_float_vector)(const ir_mode *mode) {
598   ANNOUNCE();
599   return _mode_is_float_vector(mode);
600 }
601
602 int
603 (mode_is_int_vector)(const ir_mode *mode) {
604   ANNOUNCE();
605   return _mode_is_int_vector(mode);
606 }
607
608 /* Returns true if sm can be converted to lm without loss. */
609 int
610 smaller_mode(const ir_mode *sm, const ir_mode *lm)
611 {
612   int sm_bits, lm_bits;
613
614   ANNOUNCE();
615   assert(sm);
616   assert(lm);
617
618   if (sm == lm) return 1;
619
620   sm_bits = get_mode_size_bits(sm);
621   lm_bits = get_mode_size_bits(lm);
622
623   switch(get_mode_sort(sm))
624   {
625     case irms_int_number:
626       switch(get_mode_sort(lm))
627       {
628         case irms_int_number:
629           /* integers are convertable if
630            *   - both have the same sign and lm is the larger one
631            *   - lm is the signed one and is at least two bits larger
632            *     (one for the sign, one for the highest bit of sm)
633            *   - sm & lm are two_complement and lm has greater or equal number of bits
634            */
635           if (   get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
636               && get_mode_arithmetic(sm) == irma_twos_complement) {
637             return lm_bits >= sm_bits;
638           }
639           else if (mode_is_signed(sm))
640           {
641             if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
642               return 1;
643           }
644           else if (mode_is_signed(lm))
645           {
646             if (lm_bits > sm_bits + 1)
647               return 1;
648           }
649           else if (lm_bits >= sm_bits)
650           {
651             return 1;
652           }
653           break;
654
655         case irms_float_number:
656           /* int to float works if the float is large enough */
657           return 0;
658
659         default:
660           break;
661       }
662       break;
663
664     case irms_float_number:
665       if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
666         if ( (get_mode_sort(lm) == irms_float_number)
667            && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
668           return 1;
669       }
670       break;
671
672     case irms_reference:
673        /* do exist machines out there with different pointer lenghts ?*/
674       return 0;
675
676     default:
677       break;
678   }
679
680   /* else */
681   return 0;
682 }
683
684 /* initialization, build the default modes */
685 void
686 init_mode (void)
687 {
688   ir_mode newmode;
689   ANNOUNCE();
690   /* init flexible array */
691
692   obstack_init(&modes);
693
694   num_modes  =  0;
695   /* initialize predefined modes */
696
697   /* Internal Modes */
698   newmode.arithmetic   = irma_none;
699   newmode.size         = 0;
700   newmode.sign         = 0;
701   newmode.modulo_shift = 0;
702   newmode.vector_elem  = 0;
703   newmode.link         = NULL;
704   newmode.tv_priv      = NULL;
705
706   /* Control Flow Modes*/
707   newmode.sort    = irms_control_flow;
708
709   /* Basic Block */
710   newmode.name    = new_id_from_chars("BB", 2);
711   newmode.code    = irm_BB;
712
713   mode_BB = register_mode(&newmode);
714
715 /* eXecution */
716   newmode.name    = new_id_from_chars("X", 1);
717   newmode.code    = irm_X;
718
719   mode_X = register_mode(&newmode);
720
721   /* Memory Modes */
722   newmode.sort    = irms_memory;
723
724   /* Memory */
725   newmode.name    = new_id_from_chars("M", 1);
726   newmode.code    = irm_M;
727
728   mode_M = register_mode(&newmode);
729
730   /* Auxiliary Modes */
731   newmode.sort    = irms_auxiliary,
732
733   /* Tuple */
734   newmode.name    = new_id_from_chars("T", 1);
735   newmode.code    = irm_T;
736
737   mode_T = register_mode(&newmode);
738
739   /* ANY */
740   newmode.name    = new_id_from_chars("ANY", 3);
741   newmode.code    = irm_ANY;
742
743   mode_ANY = register_mode(&newmode);
744
745   /* BAD */
746   newmode.name    = new_id_from_chars("BAD", 3);
747   newmode.code    = irm_BAD;
748
749   mode_BAD = register_mode(&newmode);
750
751   /* Internal Boolean Modes */
752   newmode.sort    = irms_internal_boolean;
753
754   /* boolean */
755   newmode.name    = new_id_from_chars("b", 1);
756   newmode.code    = irm_b;
757
758   mode_b = register_mode(&newmode);
759
760 /* Data Modes */
761   newmode.vector_elem = 1;
762
763   /* Float Number Modes */
764   newmode.sort       = irms_float_number;
765   newmode.arithmetic = irma_ieee754;
766
767   /* float */
768   newmode.name    = new_id_from_chars("F", 1);
769   newmode.code    = irm_F;
770   newmode.sign    = 1;
771   newmode.size    = 32;
772
773   mode_F = register_mode(&newmode);
774
775   /* double */
776   newmode.name    = new_id_from_chars("D", 1);
777   newmode.code    = irm_D;
778   newmode.sign    = 1;
779   newmode.size    = 64;
780
781   mode_D = register_mode(&newmode);
782
783   /* extended */
784   newmode.name    = new_id_from_chars("E", 1);
785   newmode.code    = irm_E;
786   newmode.sign    = 1;
787   newmode.size    = 80;
788
789   mode_E = register_mode(&newmode);
790
791   /* Integer Number Modes */
792   newmode.sort         = irms_int_number;
793   newmode.arithmetic   = irma_twos_complement;
794
795   /* signed byte */
796   newmode.name         = new_id_from_chars("Bs", 2);
797   newmode.code         = irm_Bs;
798   newmode.sign         = 1;
799   newmode.size         = 8;
800   newmode.modulo_shift = 32;
801
802   mode_Bs = register_mode(&newmode);
803
804   /* unsigned byte */
805   newmode.name         = new_id_from_chars("Bu", 2);
806   newmode.code         = irm_Bu;
807   newmode.arithmetic   = irma_twos_complement;
808   newmode.sign         = 0;
809   newmode.size         = 8;
810   newmode.modulo_shift = 32;
811
812   mode_Bu = register_mode(&newmode);
813
814   /* signed short integer */
815   newmode.name         = new_id_from_chars("Hs", 2);
816   newmode.code         = irm_Hs;
817   newmode.sign         = 1;
818   newmode.size         = 16;
819   newmode.modulo_shift = 32;
820
821   mode_Hs = register_mode(&newmode);
822
823   /* unsigned short integer */
824   newmode.name         = new_id_from_chars("Hu", 2);
825   newmode.code         = irm_Hu;
826   newmode.sign         = 0;
827   newmode.size         = 16;
828   newmode.modulo_shift = 32;
829
830   mode_Hu = register_mode(&newmode);
831
832   /* signed integer */
833   newmode.name         = new_id_from_chars("Is", 2);
834   newmode.code         = irm_Is;
835   newmode.sign         = 1;
836   newmode.size         = 32;
837   newmode.modulo_shift = 32;
838
839   mode_Is = register_mode(&newmode);
840
841   /* unsigned integer */
842   newmode.name         = new_id_from_chars("Iu", 2);
843   newmode.code         = irm_Iu;
844   newmode.sign         = 0;
845   newmode.size         = 32;
846   newmode.modulo_shift = 32;
847
848   mode_Iu = register_mode(&newmode);
849
850   /* signed long integer */
851   newmode.name         = new_id_from_chars("Ls", 2);
852   newmode.code         = irm_Ls;
853   newmode.sign         = 1;
854   newmode.size         = 64;
855   newmode.modulo_shift = 64;
856
857   mode_Ls = register_mode(&newmode);
858
859   /* unsigned long integer */
860   newmode.name         = new_id_from_chars("Lu", 2);
861   newmode.code         = irm_Lu;
862   newmode.sign         = 0;
863   newmode.size         = 64;
864   newmode.modulo_shift = 64;
865
866   mode_Lu = register_mode(&newmode);
867
868   /* Character Modes */
869   newmode.sort         = irms_character;
870   newmode.arithmetic   = irma_none;
871
872   /* Character */
873   newmode.name         = new_id_from_chars("C", 1);
874   newmode.code         = irm_C;
875   newmode.sign         = 0;
876   newmode.size         = 8;
877   newmode.modulo_shift = 32;
878
879   mode_C = register_mode(&newmode);
880
881   /* Unicode character */
882   newmode.name         = new_id_from_chars("U", 1);
883   newmode.code         = irm_U;
884   newmode.sign         = 0;
885   newmode.size         = 16;
886   newmode.modulo_shift = 32;
887
888   mode_U = register_mode(&newmode);
889
890   /* Reference Modes */
891   newmode.sort    = irms_reference;
892   newmode.arithmetic = irma_twos_complement;
893
894   /* pointer */
895   newmode.name         = new_id_from_chars("P", 1);
896   newmode.code         = irm_P;
897   newmode.sign         = 0;
898   newmode.size         = 32;
899   newmode.modulo_shift = 0;
900
901   mode_P = register_mode(&newmode);
902
903   /* set the machine specific modes to the predefined ones */
904   mode_P_mach = mode_P;
905 }
906
907 /* find a signed mode for an unsigned integer mode */
908 ir_mode *find_unsigned_mode(const ir_mode *mode) {
909   ir_mode n = *mode;
910
911   if (mode->sort != irms_int_number);
912   n.sign = 0;
913   return find_mode(&n);
914 }
915
916 /* find an unsigned mode for a signed integer mode */
917 ir_mode *find_signed_mode(const ir_mode *mode) {
918   ir_mode n = *mode;
919
920   assert(mode->sort == irms_int_number);
921   n.sign = 1;
922   return find_mode(&n);
923 }
924
925 /* finds a integer mode with 2*n bits for an integer mode with n bits. */
926 ir_mode *find_double_bits_int_mode(const ir_mode *mode) {
927   ir_mode n = *mode;
928
929   assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
930
931   n.size = 2*mode->size;
932   return find_mode(&n);
933 }
934
935 /*
936  * Returns non-zero if the given mode honors signed zero's, i.e.,
937  * a +0 and a -0 exists and handled differently.
938  */
939 int mode_honor_signed_zeros(const ir_mode *mode)
940 {
941   /* for floating point, we know that IEEE 754 has +0 and -0,
942    * but always handles it identical.
943    */
944   if (mode->sort == irms_float_number)
945     return mode->arithmetic == irma_ieee754 ? 0 : 1;
946   return 0;
947 }
948
949 /*
950  * Returns non-zero if the given mode might overflow on unary Minus.
951  *
952  * This does NOT happen on IEEE 754.
953  */
954 int mode_overflow_on_unary_Minus(const ir_mode *mode)
955 {
956   if (mode->sort == irms_float_number)
957     return mode->arithmetic == irma_ieee754 ? 0 : 1;
958   return 1;
959 }
960
961 /*
962  * Returns non-zero if the mode has a reversed wrap-aound
963  * logic, especially (a + x) - x == a.
964  *
965  * This is normally true for integer modes, not for floating
966  * point modes.
967  */
968 int mode_wrap_around(const ir_mode *mode) {
969   /* FIXME: better would be an extra mode property */
970   return mode_is_int(mode);
971 }
972
973 void finish_mode(void) {
974   obstack_free(&modes, 0);
975
976   mode_T   = NULL;
977   mode_X   = NULL;
978   mode_M   = NULL;
979   mode_BB  = NULL;
980   mode_ANY = NULL;
981   mode_BAD = NULL;
982
983   mode_F   = NULL;
984   mode_D   = NULL;
985   mode_E   = NULL;
986
987   mode_Bs  = NULL;
988   mode_Bu  = NULL;
989   mode_Hs  = NULL;
990   mode_Hu  = NULL;
991   mode_Is  = NULL;
992   mode_Iu  = NULL;
993   mode_Ls  = NULL;
994   mode_Lu  = NULL;
995
996   mode_C   = NULL;
997   mode_U   = NULL;
998   mode_b   = NULL;
999   mode_P   = NULL;
1000
1001   mode_P_mach = NULL;
1002 }