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