irmode.c 18.2 KB
Newer Older
Christian Schäfer's avatar
Christian Schäfer committed
1
/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2
3
4
5
** All rights reserved.
**
** Authors: Martin Trapp, Christian Schaefer
**
Christian Schäfer's avatar
Christian Schäfer committed
6
7
*/

Boris Boesler's avatar
Boris Boesler committed
8
9
/* $Id$ */

Boris Boesler's avatar
added    
Boris Boesler committed
10
11
12
13
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

Götz Lindenmaier's avatar
Götz Lindenmaier committed
14
# include "irmode_t.h"
15
# include "ident.h"
16
# include <stdlib.h>
Christian Schäfer's avatar
Christian Schäfer committed
17
# include <stddef.h>
18
# include <string.h>
Christian Schäfer's avatar
Christian Schäfer committed
19
# include "tv.h"
20
21
# include "obst.h"
# include "misc.h"
Christian Schäfer's avatar
Christian Schäfer committed
22

23
#if 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
24
static long long count = 0;
25
26
27
28
#  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__)
#else
#  define ANNOUNCE() ((void)0)
#endif
Christian Schäfer's avatar
Christian Schäfer committed
29

30
31
32
/* * *
 * local values
 * * */
33

Christian Schäfer's avatar
Christian Schäfer committed
34

Michael Beck's avatar
Michael Beck committed
35
/** dynamic array to hold all modes */
36
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
37

Michael Beck's avatar
Michael Beck committed
38
/** number of defined modes */
39
static int num_modes;
Christian Schäfer's avatar
Christian Schäfer committed
40

41
42
43
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
44

45
/**
46
 * Compare modes that don't need to have their code field
47
 * correctly set
48
49
50
 *
 * TODO: Add other fields
 **/
Till Riedel's avatar
Till Riedel committed
51
INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
52
53
{
  if (m == n) return 1;
54
  if (0 == memcmp(&m->sort, &n->sort, offsetof(ir_mode,min) - offsetof(ir_mode,sort))) return 1;
Christian Schäfer's avatar
Christian Schäfer committed
55

56
57
  return 0;
}
Matthias Heil's avatar
Matthias Heil committed
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
63
 * none found
 */
64
static ir_mode *find_mode(const ir_mode *m)
65
{
66
67
68
69
70
71
72
73
  ir_mode *n;
  struct _obstack_chunk	*p;

  p=modes.chunk;
  for( n=(ir_mode*) p->contents; (char *)n < modes.next_free; n+=sizeof(ir_mode) )
  {
    if(modes_are_equal(n,m)) return n;
  }
Matthias Heil's avatar
Matthias Heil committed
74

75
  for (p = p->prev; p; p = p->prev)
76
  {
77
78
79
80
    for( n=(ir_mode*) p->contents; (char *)n < p->limit; n+=sizeof(ir_mode) )
    {
      if(modes_are_equal(n,m)) return n;
    }
81
  }
Matthias Heil's avatar
Matthias Heil committed
82

83
84
  return NULL;
}
Christian Schäfer's avatar
Christian Schäfer committed
85

86
87
88
/**
 * sets special values of modes
 */
89
90
static void set_mode_values(ir_mode* mode)
{
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
  switch (get_mode_sort(mode))
  {
    case irms_int_number:
    case irms_float_number:
      mode->min = get_tarval_min(mode);
      mode->max = get_tarval_max(mode);
      mode->null = get_tarval_null(mode);
      mode->one = get_tarval_one(mode);
      break;

    case irms_internal_boolean:
      mode->min = tarval_b_false;
      mode->max = tarval_b_true;
      mode->null = tarval_b_false;
      mode->one = tarval_b_true;
      break;

    case irms_reference:
      mode->min = tarval_bad;
      mode->max = tarval_bad;
      mode->null = (get_mode_modecode(mode)==irm_P)?tarval_P_void:tarval_bad;
      mode->one = tarval_bad;
      break;

    case irms_character:
    case irms_auxiliary:
    case irms_memory:
    case irms_control_flow:
      mode->min = tarval_bad;
      mode->max = tarval_bad;
      mode->null = tarval_bad;
      mode->one = tarval_bad;
      break;
  }
125
}
126

127
128
129
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
130

131
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
132

133
134
135
136
137
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
138
139
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
140

141
142
143
144
/* predefined numerical modes: */
ir_mode *mode_F;    /* float */
ir_mode *mode_D;    /* double */
ir_mode *mode_E;    /* long double */
Christian Schäfer's avatar
Christian Schäfer committed
145

146
147
148
149
150
151
152
153
ir_mode *mode_Bs;   /* integral values, signed and unsigned */
ir_mode *mode_Bu;   /* 8 bit */
ir_mode *mode_Hs;   /* 16 bit */
ir_mode *mode_Hu;
ir_mode *mode_Is;   /* 32 bit */
ir_mode *mode_Iu;
ir_mode *mode_Ls;   /* 64 bit */
ir_mode *mode_Lu;
Christian Schäfer's avatar
Christian Schäfer committed
154

155
156
157
158
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
159

160
161
162
163
164
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
Michael Beck's avatar
Michael Beck committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
INLINE ir_mode *get_modeT(void) { ANNOUNCE(); return mode_T; }
INLINE ir_mode *get_modeF(void) { ANNOUNCE(); return mode_F; }
INLINE ir_mode *get_modeD(void) { ANNOUNCE(); return mode_D; }
INLINE ir_mode *get_modeE(void) { ANNOUNCE(); return mode_E; }
INLINE ir_mode *get_modeBs(void) { ANNOUNCE(); return mode_Bs; }
INLINE ir_mode *get_modeBu(void) { ANNOUNCE(); return mode_Bu; }
INLINE ir_mode *get_modeHs(void) { ANNOUNCE(); return mode_Hs; }
INLINE ir_mode *get_modeHu(void) { ANNOUNCE(); return mode_Hu; }
INLINE ir_mode *get_modeIs(void) { ANNOUNCE(); return mode_Is; }
INLINE ir_mode *get_modeIu(void) { ANNOUNCE(); return mode_Iu; }
INLINE ir_mode *get_modeLs(void) { ANNOUNCE(); return mode_Ls; }
INLINE ir_mode *get_modeLu(void) { ANNOUNCE(); return mode_Lu; }
INLINE ir_mode *get_modeC(void) { ANNOUNCE(); return mode_C; }
INLINE ir_mode *get_modeU(void) { ANNOUNCE(); return mode_U; }
INLINE ir_mode *get_modeb(void) { ANNOUNCE(); return mode_b; }
INLINE ir_mode *get_modeP(void) { ANNOUNCE(); return mode_P; }
INLINE ir_mode *get_modeX(void) { ANNOUNCE(); return mode_X; }
INLINE ir_mode *get_modeM(void) { ANNOUNCE(); return mode_M; }
INLINE ir_mode *get_modeBB(void) { ANNOUNCE(); return mode_BB; }
184
185
INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
186

187
188
189
190
/**
 * Registers a new mode if not defined yet, else returns
 * the "equivalent" one.
 */
191
static ir_mode *register_mode(const ir_mode* new_mode)
192
{
193
  ir_mode *mode = NULL;
194
195
196
197

  ANNOUNCE();
  assert(new_mode);

198
199
200
201
202
203
204
  /* copy mode struct to modes array */
  mode=(ir_mode*) obstack_copy(&modes, new_mode, sizeof(ir_mode));

  mode->kind = k_ir_mode;
  if(num_modes>=irm_max) mode->code = num_modes;
  num_modes++;

205
  set_mode_values(mode);
206
207
208
209
210
211
212
213
214
215
216

  return mode;
}

/*
 * Creates a new mode.
 */
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int align, int sign, mode_arithmetic arithmetic )
{
  ir_mode mode_tmpl;
  ir_mode *mode;
217
218

  /* sanity checks */
219
  switch (sort)
220
  {
221
    case irms_auxiliary:
222
223
    case irms_control_flow:
    case irms_memory:
224
    case irms_internal_boolean:
225
      assert(0 && "internal modes cannot be user defined");
226
      return NULL;
227
228
      break;

229
    case irms_float_number:
230
      assert(0 && "not yet implemented");
231
      return NULL;
232
233
      break;

234
235
236
    case irms_int_number:
    case irms_reference:
    case irms_character:
237
238
      break;
  }
239
240
241
242
243
244
245
  mode_tmpl.name        = new_id_from_str(name);
  mode_tmpl.sort        = sort;
  mode_tmpl.size        = bit_size;
  mode_tmpl.align       = align;
  mode_tmpl.sign        = sign ? 1 : 0;
  mode_tmpl.arithmetic  = arithmetic;
  mode_tmpl.tv_priv     = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
246

247
248
249
250
251
252
253
254
255
256
  /* first check if there already is a matching mode */
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
  else
  {
    return register_mode(&mode_tmpl);
  }
257
258
}

259
/* Functions for the direct access to all attributes od a ir_mode */
Christian Schäfer's avatar
Christian Schäfer committed
260
modecode
Michael Beck's avatar
Michael Beck committed
261
get_mode_modecode(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
262
{
263
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
264
265
266
267
  return mode->code;
}

ident *
Michael Beck's avatar
Michael Beck committed
268
get_mode_ident(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
269
{
270
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
271
272
273
  return mode->name;
}

274
const char *
Michael Beck's avatar
Michael Beck committed
275
get_mode_name(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
276
{
277
278
  ANNOUNCE();
  return id_to_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
279
280
}

281
mode_sort
Michael Beck's avatar
Michael Beck committed
282
get_mode_sort(const ir_mode* mode)
283
284
285
{
  ANNOUNCE();
  return mode->sort;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
286
287
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
288
INLINE int
Michael Beck's avatar
Michael Beck committed
289
get_mode_size_bits(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
290
{
291
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
292
293
294
  return mode->size;
}

Michael Beck's avatar
Michael Beck committed
295
int get_mode_size_bytes(const ir_mode *mode) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
296
  int size = get_mode_size_bits(mode);
297
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
298
299
  if ((size & 7) != 0) return -1;
  return size >> 3;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
300
301
}

Christian Schäfer's avatar
Christian Schäfer committed
302
int
Michael Beck's avatar
Michael Beck committed
303
get_mode_align (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
304
{
305
306
  ANNOUNCE();
  return mode->align;
Christian Schäfer's avatar
Christian Schäfer committed
307
}
308
309

int
Michael Beck's avatar
Michael Beck committed
310
get_mode_sign (const ir_mode *mode)
311
312
313
314
315
{
  ANNOUNCE();
  return mode->sign;
}

316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
int get_mode_arithmetic (const ir_mode *mode)
{
  ANNOUNCE();
  return mode->arithmetic;
}

void* get_mode_link(const ir_mode *mode)
{
  ANNOUNCE();
  return mode->link;
}

void set_mode_link(ir_mode *mode, void *l)
{
  mode->link=l;
  return;
}

Christian Schäfer's avatar
Christian Schäfer committed
334
tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
335
get_mode_min (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
336
{
337
338
339
340
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
341

342
  return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
343
344
345
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
346
get_mode_max (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
347
{
348
349
350
351
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
352

353
  return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
354
355
356
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
357
get_mode_null (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
358
{
359
360
361
362
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
363

364
  return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
365
366
}

367
368
tarval *
get_mode_one (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
369
{
370
371
372
373
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
374

375
  return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
376
377
}

378
379
tarval *
get_mode_infinite(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
380
{
381
382
383
384
385
386
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_float(mode));

  return get_tarval_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
387
388
}

389
390
tarval *
get_mode_NAN(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
391
{
392
393
394
395
396
397
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_float(mode));

  return get_tarval_nan(mode);
Christian Schäfer's avatar
Christian Schäfer committed
398
399
}

400
401
402
403
404
405
406
407
408
int
is_mode (void *thing) {
  assert(thing);
  if (get_kind(thing) == k_ir_mode)
    return 1;
  else
    return 0;
}

Christian Schäfer's avatar
Christian Schäfer committed
409
410
411
412
413
414
/* Functions to check, whether a modecode is signed, float, int, num, data,
   datab or dataM. For more exact definitions read the corresponding pages
   in the firm documentation or the followingenumeration

   The set of "float" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
415
   float = {irm_F, irm_D, irm_E}
Christian Schäfer's avatar
Christian Schäfer committed
416
417
418

   The set of "int" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
419
   int   = {irm_Bs, irm_Bu, irm_Hs, irm_Hu, irm_Is, irm_Iu, irm_Ls, irm_Lu}
Christian Schäfer's avatar
Christian Schäfer committed
420
421
422

   The set of "num" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
423
424
   num   = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
            irm_Is, irm_Iu, irm_Ls, irm_Lu}
Christian Schäfer's avatar
Christian Schäfer committed
425
426
427
428
            = {float || int}

   The set of "data" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
429
   data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
430
431
            irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P}
            = {num || irm_C || irm_U || irm_P}
Christian Schäfer's avatar
Christian Schäfer committed
432
433
434

   The set of "datab" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
435
   datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
436
            irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
Matthias Heil's avatar
Matthias Heil committed
437
            = {data || irm_b }
Christian Schäfer's avatar
Christian Schäfer committed
438
439
440

   The set of "dataM" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
441
   dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
442
            irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_M}
Christian Schäfer's avatar
Christian Schäfer committed
443
444
445
            = {data || irm_M}
*/

446
447
448
449
450
451
452
453
454
#ifdef MODE_ACCESS_DEFINES
#  undef mode_is_signed
#  undef mode_is_float
#  undef mode_is_int
#  undef mode_is_num
#  undef mode_is_data
#  undef mode_is_datab
#  undef mode_is_dataM
#endif
Christian Schäfer's avatar
Christian Schäfer committed
455
int
Michael Beck's avatar
Michael Beck committed
456
mode_is_signed (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
457
{
458
459
460
  ANNOUNCE();
  assert(mode);
  return mode->sign;
Christian Schäfer's avatar
Christian Schäfer committed
461
462
}

463
int
Michael Beck's avatar
Michael Beck committed
464
mode_is_float (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
465
{
466
467
  ANNOUNCE();
  assert(mode);
468
  return (get_mode_sort(mode) == irms_float_number);
Christian Schäfer's avatar
Christian Schäfer committed
469
470
}

471
int
Michael Beck's avatar
Michael Beck committed
472
mode_is_int (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
473
{
474
475
  ANNOUNCE();
  assert(mode);
476
  return (get_mode_sort(mode) == irms_int_number);
Christian Schäfer's avatar
Christian Schäfer committed
477
478
}

Michael Beck's avatar
Michael Beck committed
479
int mode_is_character (const ir_mode *mode)
480
481
482
483
484
485
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_character);
}

Michael Beck's avatar
Michael Beck committed
486
int mode_is_reference (const ir_mode *mode)
487
488
489
490
491
492
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_reference);
}

493
int
Michael Beck's avatar
Michael Beck committed
494
mode_is_num (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
495
{
496
497
498
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode));
Christian Schäfer's avatar
Christian Schäfer committed
499
500
}

501
int
Michael Beck's avatar
Michael Beck committed
502
mode_is_data (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
503
{
504
505
  ANNOUNCE();
  assert(mode);
506
  return (mode_is_num(mode) || get_mode_sort(mode) == irms_character || get_mode_sort(mode) == irms_reference);
Christian Schäfer's avatar
Christian Schäfer committed
507
508
509
}

int
Michael Beck's avatar
Michael Beck committed
510
mode_is_datab (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
511
{
512
513
  ANNOUNCE();
  assert(mode);
514
  return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
Christian Schäfer's avatar
Christian Schäfer committed
515
516
517
}

int
Michael Beck's avatar
Michael Beck committed
518
mode_is_dataM (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
519
{
520
521
522
  ANNOUNCE();
  assert(mode);
  return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
Christian Schäfer's avatar
Christian Schäfer committed
523
}
524
525
#ifdef MODE_ACCESS_DEFINES
#  define mode_is_signed(mode) (mode)->sign
526
527
528
529
530
531
#  define mode_is_float(mode) ((mode)->sort == irms_float_number)
#  define mode_is_int(mode) ((mode)->sort == irms_int_number)
#  define mode_is_num(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number))
#  define mode_is_data(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference))
#  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))
#  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))
532
#endif
533
/* Returns true if sm can be converted to lm without loss. */
534
int
Michael Beck's avatar
Michael Beck committed
535
smaller_mode(const ir_mode *sm, const ir_mode *lm)
536
537
538
539
540
541
542
543
544
{
  ANNOUNCE();
  assert(sm);
  assert(lm);

  if (sm == lm) return 1;

  switch(get_mode_sort(sm))
  {
545
    case irms_int_number:
546
547
      switch(get_mode_sort(lm))
      {
548
        case irms_int_number:
549
550
551
552
553
554
555
          /* integers are convertable if
           *   - both have the same sign and lm is the larger one
           *   - lm is the signed one and is at least two bits larger
           *     (one for the sign, one for the highest bit of sm)
           */
          if (mode_is_signed(sm))
          {
556
            if ( mode_is_signed(lm) && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
557
558
559
560
              return 1;
          }
          else if (mode_is_signed(lm))
          {
561
            if (get_mode_size_bits(lm) > get_mode_size_bits(sm) + 1)
562
563
              return 1;
          }
564
          else if (get_mode_size_bits(lm) > get_mode_size_bits(sm))
565
566
567
568
569
          {
            return 1;
          }
          break;

570
        case irms_float_number:
571
572
573
574
575
576
577
578
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

579
    case irms_float_number:
580
581
      /* XXX currently only the three standard 32,64,80 bit floats
       * are supported which can safely be converted */
582
      if ( (get_mode_sort(lm) == irms_float_number)
583
           && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
584
585
586
         return 1;
      break;

587
    case irms_reference:
588
589
590
591
592
593
594
595
596
597
598
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

599
/* ** initialization ** */
600
601
602
void
init_mode (void)
{
603
  ir_mode newmode;
604
605
606
  ANNOUNCE();
  /* init flexible array */

607
608
609
  obstack_init(&modes);

  num_modes  =  0;
610
  /* initialize predefined modes */
611
612
613
614
615
616
617
618
619
620
621

  /* Internal Modes */
  newmode.arithmetic = irma_none;
  newmode.size    = 0;
  newmode.align   = 0;
  newmode.sign    = 0;
  newmode.tv_priv = NULL;

  /* Control Flow Modes*/
  newmode.sort    = irms_control_flow;

622
  /* Basic Block */
623
624
625
626
627
628
629
630
631
632
633
634
635
  newmode.name    = id_from_str("BB", 2);
  newmode.code    = irm_BB;

  mode_BB = register_mode(&newmode);

/* eXecution */
  newmode.name    = id_from_str("X", 1);
  newmode.code    = irm_X;

  mode_X = register_mode(&newmode);

  /* Memory Modes */
  newmode.sort    = irms_memory;
636
637

  /* Memory */
638
639
640
641
642
643
644
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
645
646

  /* Tuple */
647
648
649
650
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
651

652
  /* ANY */
653
654
655
656
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
657
658

  /* BAD */
659
660
661
662
663
664
665
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

  /* Internal Boolean Modes */
  newmode.sort    = irms_internal_boolean;
666

667
  /* boolean */
668
669
670
671
672
673
674
675
676
677
  newmode.name    = id_from_str("b", 1);
  newmode.code    = irm_b;

  mode_b = register_mode(&newmode);

/* Data Modes */

  /* Float Number Modes */
  newmode.sort    = irms_float_number;
  newmode.arithmetic = irma_ieee754;
678
679

  /* float */
680
681
682
683
684
  newmode.name    = id_from_str("F", 1);
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
685

686
  mode_F = register_mode(&newmode);
687
688

  /* double */
689
690
691
692
693
  newmode.name    = id_from_str("D", 1);
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
694

695
  mode_D = register_mode(&newmode);
696
697

  /* extended */
698
699
700
701
702
703
704
  newmode.name    = id_from_str("E", 1);
  newmode.code    = irm_E;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 80;

  mode_E = register_mode(&newmode);
705

706
707
708
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
709
710

  /* signed byte */
711
712
713
714
715
  newmode.name    = id_from_str("Bs", 2);
  newmode.code    = irm_Bs;
  newmode.sign    = 1;
  newmode.align   = 1;
  newmode.size    = 8;
716

717
  mode_Bs = register_mode(&newmode);
718
719

  /* unsigned byte */
720
721
722
723
724
725
  newmode.name    = id_from_str("Bu", 2);
  newmode.code    = irm_Bu;
  newmode.arithmetic = irma_twos_complement;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
726

727
  mode_Bu = register_mode(&newmode);
728
729

  /* signed short integer */
730
731
732
733
734
  newmode.name    = id_from_str("Hs", 2);
  newmode.code    = irm_Hs;
  newmode.sign    = 1;
  newmode.align   = 2;
  newmode.size    = 16;
735

736
  mode_Hs = register_mode(&newmode);
737
738

  /* unsigned short integer */
739
740
741
742
743
  newmode.name    = id_from_str("Hu", 2);
  newmode.code    = irm_Hu;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
744

745
  mode_Hu = register_mode(&newmode);
746
747

  /* signed integer */
748
749
750
751
752
  newmode.name    = id_from_str("Is", 2);
  newmode.code    = irm_Is;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
753

754
  mode_Is = register_mode(&newmode);
755
756

  /* unsigned integer */
757
758
759
760
761
  newmode.name    = id_from_str("Iu", 2);
  newmode.code    = irm_Iu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
762

763
  mode_Iu = register_mode(&newmode);
764
765

  /* signed long integer */
766
767
768
769
770
  newmode.name    = id_from_str("Ls", 2);
  newmode.code    = irm_Ls;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
771

772
  mode_Ls = register_mode(&newmode);
773
774

  /* unsigned long integer */
775
776
777
778
779
780
781
  newmode.name    = id_from_str("Lu", 2);
  newmode.code    = irm_Lu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 64;

  mode_Lu = register_mode(&newmode);
782

783
  /* Character Modes */
784
785
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
786
787

  /* Character */
788
789
790
791
792
  newmode.name    = id_from_str("C", 1);
  newmode.code    = irm_C;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
793

794
  mode_C = register_mode(&newmode);
795
796

  /* Unicode character */
797
798
799
800
801
  newmode.name    = id_from_str("U", 1);
  newmode.code    = irm_U;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
802

803
804
805
806
807
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
808
809

  /* pointer */
810
811
812
813
814
815
816
  newmode.name    = id_from_str("P", 1);
  newmode.code    = irm_P;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;

  mode_P = register_mode(&newmode);
817
}