irmode.c 18.8 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
55
56
  if (m->sort == n->sort && m->arithmetic == n->arithmetic && m->size == n->size && m->align == n->align && m->sign == n->sign)
    return 1;
//  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
57

58
59
  return 0;
}
Matthias Heil's avatar
Matthias Heil committed
60

61
/**
62
 * searches the modes obstack for the given mode and returns
63
 * a pointer on an equal mode already in the array, NULL if
64
65
 * none found
 */
66
static ir_mode *find_mode(const ir_mode *m)
67
{
68
69
70
  ir_mode *n;
  struct _obstack_chunk	*p;

71
72
73
74
75
  p = modes.chunk;
  for ( n = (ir_mode *)p->contents; (char *)(n+1) <= modes.next_free; ++n) {
    assert(is_mode(n));
    if (modes_are_equal(n, m))
      return n;
76
  }
Matthias Heil's avatar
Matthias Heil committed
77

78
79
80
81
82
  for (p = p->prev; p; p = p->prev) {
    for (n = (ir_mode *)p->contents; (char *)(n+1) < p->limit; ++n)
      assert(is_mode(n));
      if (modes_are_equal(n, m))
	return n;
83
  }
Matthias Heil's avatar
Matthias Heil committed
84

85
86
  return NULL;
}
Christian Schäfer's avatar
Christian Schäfer committed
87

88
89
90
/**
 * sets special values of modes
 */
91
92
static void set_mode_values(ir_mode* mode)
{
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
125
126
  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;
  }
127
}
128

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

133
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
134

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

143
144
145
146
/* 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
147

148
149
150
151
152
153
154
155
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
156

157
158
159
160
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
161
162
163

/* machine specific modes */
ir_mode *mode_P_mach;	/* machine specific pointer mode */
164

165
166
167
168
169
/* * *
 * functions defined in irmode.h
 * * */

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

192
193
194
195
196
197
198
199

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;
 }

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

  ANNOUNCE();
  assert(new_mode);

211
212
213
214
215
216
217
  /* 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++;

218
  set_mode_values(mode);
219
220
221
222
223
224
225
226
227
228
229

  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;
230

231
232
233
234
235
236
  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;
237
  mode_tmpl.link        = NULL;
238
  mode_tmpl.tv_priv     = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
239

240
241
242
243
244
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
245
246
247

  /* sanity checks */
  switch (sort)
248
  {
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
    case irms_auxiliary:
    case irms_control_flow:
    case irms_memory:
    case irms_internal_boolean:
      assert(0 && "internal modes cannot be user defined");
      return NULL;

    case irms_float_number:
      assert(0 && "not yet implemented");
      return NULL;

    case irms_int_number:
    case irms_reference:
    case irms_character:
      return register_mode(&mode_tmpl);
264
  }
265
  return NULL; /* to shut up gcc */
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
  ANNOUNCE();
287
  return get_id_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
#ifdef MODE_ACCESS_DEFINES
#  undef mode_is_signed
#  undef mode_is_float
#  undef mode_is_int
#  undef mode_is_num
Michael Beck's avatar
fixed:    
Michael Beck committed
460
#  undef mode_is_numP
461
462
463
464
#  undef mode_is_data
#  undef mode_is_datab
#  undef mode_is_dataM
#endif
Christian Schäfer's avatar
Christian Schäfer committed
465
int
Michael Beck's avatar
Michael Beck committed
466
mode_is_signed (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
467
{
468
469
470
  ANNOUNCE();
  assert(mode);
  return mode->sign;
Christian Schäfer's avatar
Christian Schäfer committed
471
472
}

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

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

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

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

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

Michael Beck's avatar
fixed:    
Michael Beck committed
511
512
513
514
515
516
517
518
int
mode_is_numP (const ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode) || mode_is_reference(mode));
}

519
int
Michael Beck's avatar
Michael Beck committed
520
mode_is_data (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
521
{
522
523
  ANNOUNCE();
  assert(mode);
524
  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
525
526
527
}

int
Michael Beck's avatar
Michael Beck committed
528
mode_is_datab (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
529
{
530
531
  ANNOUNCE();
  assert(mode);
532
  return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
Christian Schäfer's avatar
Christian Schäfer committed
533
534
535
}

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

  if (sm == lm) return 1;

  switch(get_mode_sort(sm))
  {
563
    case irms_int_number:
564
565
      switch(get_mode_sort(lm))
      {
566
        case irms_int_number:
567
568
569
570
571
572
573
          /* 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))
          {
574
            if ( mode_is_signed(lm) && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
575
576
577
578
              return 1;
          }
          else if (mode_is_signed(lm))
          {
579
            if (get_mode_size_bits(lm) > get_mode_size_bits(sm) + 1)
580
581
              return 1;
          }
582
          else if (get_mode_size_bits(lm) > get_mode_size_bits(sm))
583
584
585
586
587
          {
            return 1;
          }
          break;

588
        case irms_float_number:
589
590
591
592
593
594
595
596
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

597
    case irms_float_number:
598
599
      /* XXX currently only the three standard 32,64,80 bit floats
       * are supported which can safely be converted */
600
      if ( (get_mode_sort(lm) == irms_float_number)
601
           && (get_mode_size_bits(lm) > get_mode_size_bits(sm)) )
602
603
604
         return 1;
      break;

605
    case irms_reference:
606
607
608
609
610
611
612
613
614
615
616
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

617
/* ** initialization ** */
618
619
620
void
init_mode (void)
{
621
  ir_mode newmode;
622
623
624
  ANNOUNCE();
  /* init flexible array */

625
626
627
  obstack_init(&modes);

  num_modes  =  0;
628
  /* initialize predefined modes */
629
630
631
632
633
634

  /* Internal Modes */
  newmode.arithmetic = irma_none;
  newmode.size    = 0;
  newmode.align   = 0;
  newmode.sign    = 0;
635
  newmode.link    = NULL;
636
637
638
639
640
  newmode.tv_priv = NULL;

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

641
  /* Basic Block */
642
643
644
645
646
647
648
649
650
651
652
653
654
  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;
655
656

  /* Memory */
657
658
659
660
661
662
663
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
664
665

  /* Tuple */
666
667
668
669
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
670

671
  /* ANY */
672
673
674
675
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
676
677

  /* BAD */
678
679
680
681
682
683
684
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

686
  /* boolean */
687
688
689
690
691
692
693
694
695
696
  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;
697
698

  /* float */
699
700
701
702
703
  newmode.name    = id_from_str("F", 1);
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
704

705
  mode_F = register_mode(&newmode);
706
707

  /* double */
708
709
710
711
712
  newmode.name    = id_from_str("D", 1);
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
713

714
  mode_D = register_mode(&newmode);
715
716

  /* extended */
717
718
719
720
721
722
723
  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);
724

725
726
727
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
728
729

  /* signed byte */
730
731
732
733
734
  newmode.name    = id_from_str("Bs", 2);
  newmode.code    = irm_Bs;
  newmode.sign    = 1;
  newmode.align   = 1;
  newmode.size    = 8;
735

736
  mode_Bs = register_mode(&newmode);
737
738

  /* unsigned byte */
739
740
741
742
743
744
  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;
745

746
  mode_Bu = register_mode(&newmode);
747
748

  /* signed short integer */
749
750
751
752
753
  newmode.name    = id_from_str("Hs", 2);
  newmode.code    = irm_Hs;
  newmode.sign    = 1;
  newmode.align   = 2;
  newmode.size    = 16;
754

755
  mode_Hs = register_mode(&newmode);
756
757

  /* unsigned short integer */
758
759
760
761
762
  newmode.name    = id_from_str("Hu", 2);
  newmode.code    = irm_Hu;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
763

764
  mode_Hu = register_mode(&newmode);
765
766

  /* signed integer */
767
768
769
770
771
  newmode.name    = id_from_str("Is", 2);
  newmode.code    = irm_Is;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
772

773
  mode_Is = register_mode(&newmode);
774
775

  /* unsigned integer */
776
777
778
779
780
  newmode.name    = id_from_str("Iu", 2);
  newmode.code    = irm_Iu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
781

782
  mode_Iu = register_mode(&newmode);
783
784

  /* signed long integer */
785
786
787
788
789
  newmode.name    = id_from_str("Ls", 2);
  newmode.code    = irm_Ls;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
790

791
  mode_Ls = register_mode(&newmode);
792
793

  /* unsigned long integer */
794
795
796
797
798
799
800
  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);
801

802
  /* Character Modes */
803
804
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
805
806

  /* Character */
807
808
809
810
811
  newmode.name    = id_from_str("C", 1);
  newmode.code    = irm_C;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
812

813
  mode_C = register_mode(&newmode);
814
815

  /* Unicode character */
816
817
818
819
820
  newmode.name    = id_from_str("U", 1);
  newmode.code    = irm_U;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
821

822
823
824
825
826
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
827
828

  /* pointer */
829
830
831
832
833
834
835
  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);
Michael Beck's avatar
fixed:    
Michael Beck committed
836
837
838

  /* set the machine specific modes to the predifined ones */
  mode_P_mach = mode_P;
839
}