irmode.c 18.4 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
ir_mode *mode_P_mach;
160

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

/* JNI access functions */
Michael Beck's avatar
Michael Beck committed
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
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; }
185
186
INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
187

188
189
190
191
192
193
194
195

ir_mode *get_modeP_mach(void)  { ANNOUNCE(); return mode_P_mach; }
void     set_modeP_mach(ir_mode *p) {
  ANNOUNCE();
  assert(mode_is_reference(p));
  mode_P_mach = p;
 }

196
197
198
199
/**
 * Registers a new mode if not defined yet, else returns
 * the "equivalent" one.
 */
200
static ir_mode *register_mode(const ir_mode* new_mode)
201
{
202
  ir_mode *mode = NULL;
203
204
205
206

  ANNOUNCE();
  assert(new_mode);

207
208
209
210
211
212
213
  /* 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++;

214
  set_mode_values(mode);
215
216
217
218
219
220
221
222
223
224
225

  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;
226
227

  /* sanity checks */
228
  switch (sort)
229
  {
230
    case irms_auxiliary:
231
232
    case irms_control_flow:
    case irms_memory:
233
    case irms_internal_boolean:
234
      assert(0 && "internal modes cannot be user defined");
235
      return NULL;
236
237
      break;

238
    case irms_float_number:
239
      assert(0 && "not yet implemented");
240
      return NULL;
241
242
      break;

243
244
245
    case irms_int_number:
    case irms_reference:
    case irms_character:
246
247
      break;
  }
248
249
250
251
252
253
254
  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
255

256
257
258
259
260
261
262
263
264
265
  /* first check if there already is a matching mode */
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
  else
  {
    return register_mode(&mode_tmpl);
  }
266
267
}

268
/* Functions for the direct access to all attributes od a ir_mode */
Christian Schäfer's avatar
Christian Schäfer committed
269
modecode
Michael Beck's avatar
Michael Beck committed
270
get_mode_modecode(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
271
{
272
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
273
274
275
276
  return mode->code;
}

ident *
Michael Beck's avatar
Michael Beck committed
277
get_mode_ident(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
278
{
279
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
280
281
282
  return mode->name;
}

283
const char *
Michael Beck's avatar
Michael Beck committed
284
get_mode_name(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
285
{
286
287
  ANNOUNCE();
  return id_to_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
288
289
}

290
mode_sort
Michael Beck's avatar
Michael Beck committed
291
get_mode_sort(const ir_mode* mode)
292
293
294
{
  ANNOUNCE();
  return mode->sort;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
295
296
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
297
INLINE int
Michael Beck's avatar
Michael Beck committed
298
get_mode_size_bits(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
299
{
300
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
301
302
303
  return mode->size;
}

Michael Beck's avatar
Michael Beck committed
304
int get_mode_size_bytes(const ir_mode *mode) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
305
  int size = get_mode_size_bits(mode);
306
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
307
308
  if ((size & 7) != 0) return -1;
  return size >> 3;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
309
310
}

Christian Schäfer's avatar
Christian Schäfer committed
311
int
Michael Beck's avatar
Michael Beck committed
312
get_mode_align (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
313
{
314
315
  ANNOUNCE();
  return mode->align;
Christian Schäfer's avatar
Christian Schäfer committed
316
}
317
318

int
Michael Beck's avatar
Michael Beck committed
319
get_mode_sign (const ir_mode *mode)
320
321
322
323
324
{
  ANNOUNCE();
  return mode->sign;
}

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
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
343
tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
344
get_mode_min (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
345
{
346
347
348
349
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
350

351
  return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
352
353
354
}

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

362
  return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
363
364
365
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
366
get_mode_null (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
367
{
368
369
370
371
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
372

373
  return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
374
375
}

376
377
tarval *
get_mode_one (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
378
{
379
380
381
382
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
383

384
  return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
385
386
}

387
388
tarval *
get_mode_infinite(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
389
{
390
391
392
393
394
395
  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
396
397
}

398
399
tarval *
get_mode_NAN(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
400
{
401
402
403
404
405
406
  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
407
408
}

409
410
411
412
413
414
415
416
417
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
418
419
420
421
422
423
/* 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
424
   float = {irm_F, irm_D, irm_E}
Christian Schäfer's avatar
Christian Schäfer committed
425
426
427

   The set of "int" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
428
   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
429
430
431

   The set of "num" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
432
433
   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
434
435
436
437
            = {float || int}

   The set of "data" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
438
   data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
439
440
            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
441
442
443

   The set of "datab" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
444
   datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
445
            irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
Matthias Heil's avatar
Matthias Heil committed
446
            = {data || irm_b }
Christian Schäfer's avatar
Christian Schäfer committed
447
448
449

   The set of "dataM" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
450
   dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
451
            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
452
453
454
            = {data || irm_M}
*/

455
456
457
458
459
460
461
462
463
#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
464
int
Michael Beck's avatar
Michael Beck committed
465
mode_is_signed (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
466
{
467
468
469
  ANNOUNCE();
  assert(mode);
  return mode->sign;
Christian Schäfer's avatar
Christian Schäfer committed
470
471
}

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

480
int
Michael Beck's avatar
Michael Beck committed
481
mode_is_int (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
482
{
483
484
  ANNOUNCE();
  assert(mode);
485
  return (get_mode_sort(mode) == irms_int_number);
Christian Schäfer's avatar
Christian Schäfer committed
486
487
}

Michael Beck's avatar
Michael Beck committed
488
int mode_is_character (const ir_mode *mode)
489
490
491
492
493
494
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_character);
}

Michael Beck's avatar
Michael Beck committed
495
int mode_is_reference (const ir_mode *mode)
496
497
498
499
500
501
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_reference);
}

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

510
int
Michael Beck's avatar
Michael Beck committed
511
mode_is_data (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
512
{
513
514
  ANNOUNCE();
  assert(mode);
515
  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
516
517
518
}

int
Michael Beck's avatar
Michael Beck committed
519
mode_is_datab (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
520
{
521
522
  ANNOUNCE();
  assert(mode);
523
  return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
Christian Schäfer's avatar
Christian Schäfer committed
524
525
526
}

int
Michael Beck's avatar
Michael Beck committed
527
mode_is_dataM (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
528
{
529
530
531
  ANNOUNCE();
  assert(mode);
  return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
Christian Schäfer's avatar
Christian Schäfer committed
532
}
533
534
#ifdef MODE_ACCESS_DEFINES
#  define mode_is_signed(mode) (mode)->sign
535
536
537
538
539
540
#  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))
541
#endif
542
/* Returns true if sm can be converted to lm without loss. */
543
int
Michael Beck's avatar
Michael Beck committed
544
smaller_mode(const ir_mode *sm, const ir_mode *lm)
545
546
547
548
549
550
551
552
553
{
  ANNOUNCE();
  assert(sm);
  assert(lm);

  if (sm == lm) return 1;

  switch(get_mode_sort(sm))
  {
554
    case irms_int_number:
555
556
      switch(get_mode_sort(lm))
      {
557
        case irms_int_number:
558
559
560
561
562
563
564
          /* 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))
          {
565
            if ( mode_is_signed(lm) && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
566
567
568
569
              return 1;
          }
          else if (mode_is_signed(lm))
          {
570
            if (get_mode_size_bits(lm) > get_mode_size_bits(sm) + 1)
571
572
              return 1;
          }
573
          else if (get_mode_size_bits(lm) > get_mode_size_bits(sm))
574
575
576
577
578
          {
            return 1;
          }
          break;

579
        case irms_float_number:
580
581
582
583
584
585
586
587
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

588
    case irms_float_number:
589
590
      /* XXX currently only the three standard 32,64,80 bit floats
       * are supported which can safely be converted */
591
      if ( (get_mode_sort(lm) == irms_float_number)
592
           && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
593
594
595
         return 1;
      break;

596
    case irms_reference:
597
598
599
600
601
602
603
604
605
606
607
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

608
/* ** initialization ** */
609
610
611
void
init_mode (void)
{
612
  ir_mode newmode;
613
614
615
  ANNOUNCE();
  /* init flexible array */

616
617
618
  obstack_init(&modes);

  num_modes  =  0;
619
  /* initialize predefined modes */
620
621
622
623
624
625
626
627
628
629
630

  /* 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;

631
  /* Basic Block */
632
633
634
635
636
637
638
639
640
641
642
643
644
  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;
645
646

  /* Memory */
647
648
649
650
651
652
653
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
654
655

  /* Tuple */
656
657
658
659
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
660

661
  /* ANY */
662
663
664
665
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
666
667

  /* BAD */
668
669
670
671
672
673
674
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

676
  /* boolean */
677
678
679
680
681
682
683
684
685
686
  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;
687
688

  /* float */
689
690
691
692
693
  newmode.name    = id_from_str("F", 1);
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
694

695
  mode_F = register_mode(&newmode);
696
697

  /* double */
698
699
700
701
702
  newmode.name    = id_from_str("D", 1);
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
703

704
  mode_D = register_mode(&newmode);
705
706

  /* extended */
707
708
709
710
711
712
713
  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);
714

715
716
717
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
718
719

  /* signed byte */
720
721
722
723
724
  newmode.name    = id_from_str("Bs", 2);
  newmode.code    = irm_Bs;
  newmode.sign    = 1;
  newmode.align   = 1;
  newmode.size    = 8;
725

726
  mode_Bs = register_mode(&newmode);
727
728

  /* unsigned byte */
729
730
731
732
733
734
  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;
735

736
  mode_Bu = register_mode(&newmode);
737
738

  /* signed short integer */
739
740
741
742
743
  newmode.name    = id_from_str("Hs", 2);
  newmode.code    = irm_Hs;
  newmode.sign    = 1;
  newmode.align   = 2;
  newmode.size    = 16;
744

745
  mode_Hs = register_mode(&newmode);
746
747

  /* unsigned short integer */
748
749
750
751
752
  newmode.name    = id_from_str("Hu", 2);
  newmode.code    = irm_Hu;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
753

754
  mode_Hu = register_mode(&newmode);
755
756

  /* signed integer */
757
758
759
760
761
  newmode.name    = id_from_str("Is", 2);
  newmode.code    = irm_Is;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
762

763
  mode_Is = register_mode(&newmode);
764
765

  /* unsigned integer */
766
767
768
769
770
  newmode.name    = id_from_str("Iu", 2);
  newmode.code    = irm_Iu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
771

772
  mode_Iu = register_mode(&newmode);
773
774

  /* signed long integer */
775
776
777
778
779
  newmode.name    = id_from_str("Ls", 2);
  newmode.code    = irm_Ls;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
780

781
  mode_Ls = register_mode(&newmode);
782
783

  /* unsigned long integer */
784
785
786
787
788
789
790
  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);
791

792
  /* Character Modes */
793
794
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
795
796

  /* Character */
797
798
799
800
801
  newmode.name    = id_from_str("C", 1);
  newmode.code    = irm_C;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
802

803
  mode_C = register_mode(&newmode);
804
805

  /* Unicode character */
806
807
808
809
810
  newmode.name    = id_from_str("U", 1);
  newmode.code    = irm_U;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
811

812
813
814
815
816
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
817
818

  /* pointer */
819
820
821
822
823
824
825
  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);
826
}