irmode.c 19.1 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Project:     libFIRM
 * File name:   ir/ir/irmode.c
 * Purpose:     Data modes of operations.
 * Author:      Martin Trapp, Christian Schaefer
 * Modified by: Goetz Lindenmaier, Mathias Heil
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 1998-2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

Boris Boesler's avatar
Boris Boesler committed
13

Boris Boesler's avatar
added    
Boris Boesler committed
14
15
16
17
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

18
# include <stdlib.h>
Christian Schäfer's avatar
Christian Schäfer committed
19
# include <stddef.h>
20
# include <string.h>
21
22
23
24
# include <stdbool.h>

# include "irmode_t.h"
# include "ident.h"
Christian Schäfer's avatar
Christian Schäfer committed
25
# include "tv.h"
26
# include "obst.h"
Christian Schäfer's avatar
Christian Schäfer committed
27

28
#if 0
Götz Lindenmaier's avatar
Götz Lindenmaier committed
29
static long long count = 0;
30
31
32
33
#  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
34

35
36
37
/* * *
 * local values
 * * */
38

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

Michael Beck's avatar
Michael Beck committed
40
/** dynamic array to hold all modes */
41
static struct obstack modes;
Christian Schäfer's avatar
Christian Schäfer committed
42

Michael Beck's avatar
Michael Beck committed
43
/** number of defined modes */
44
static int num_modes;
Christian Schäfer's avatar
Christian Schäfer committed
45

46
47
48
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
49

50
/**
51
 * Compare modes that don't need to have their code field
52
 * correctly set
53
54
55
 *
 * TODO: Add other fields
 **/
Till Riedel's avatar
Till Riedel committed
56
INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
57
58
{
  if (m == n) return 1;
59
60
61
  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
62

63
64
  return 0;
}
Matthias Heil's avatar
Matthias Heil committed
65

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

76
77
78
79
80
  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;
81
  }
Matthias Heil's avatar
Matthias Heil committed
82

83
84
85
86
87
  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;
88
  }
Matthias Heil's avatar
Matthias Heil committed
89

90
91
  return NULL;
}
Christian Schäfer's avatar
Christian Schäfer committed
92

93
94
95
/**
 * sets special values of modes
 */
96
97
static void set_mode_values(ir_mode* mode)
{
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
127
128
129
130
131
  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;
  }
132
}
133

134
135
136
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
137

138
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
139

140
141
142
143
144
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
145
146
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
147

148
149
150
151
/* 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
152

153
154
155
156
157
158
159
160
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
161

162
163
164
165
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
166
167
168

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

170
171
172
173
174
/* * *
 * functions defined in irmode.h
 * * */

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

197
198
199
200
201
202
203
204

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

205
206
207
208
/**
 * Registers a new mode if not defined yet, else returns
 * the "equivalent" one.
 */
209
static ir_mode *register_mode(const ir_mode* new_mode)
210
{
211
  ir_mode *mode = NULL;
212
213
214
215

  ANNOUNCE();
  assert(new_mode);

216
217
218
219
220
221
222
  /* 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++;

223
  set_mode_values(mode);
224
225
226
227
228
229
230
231
232
233
234

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

236
237
238
239
240
241
  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;
242
  mode_tmpl.link        = NULL;
243
  mode_tmpl.tv_priv     = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
244

245
246
247
248
249
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
250
251
252

  /* sanity checks */
  switch (sort)
253
  {
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    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);
269
  }
270
  return NULL; /* to shut up gcc */
271
272
}

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

ident *
Michael Beck's avatar
Michael Beck committed
282
get_mode_ident(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
283
{
284
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
285
286
287
  return mode->name;
}

288
const char *
Michael Beck's avatar
Michael Beck committed
289
get_mode_name(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
290
{
291
  ANNOUNCE();
292
  return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
293
294
}

295
mode_sort
Michael Beck's avatar
Michael Beck committed
296
get_mode_sort(const ir_mode* mode)
297
298
299
{
  ANNOUNCE();
  return mode->sort;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
300
301
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
302
INLINE int
Michael Beck's avatar
Michael Beck committed
303
get_mode_size_bits(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
304
{
305
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
306
307
308
  return mode->size;
}

Michael Beck's avatar
Michael Beck committed
309
int get_mode_size_bytes(const ir_mode *mode) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
310
  int size = get_mode_size_bits(mode);
311
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
312
313
  if ((size & 7) != 0) return -1;
  return size >> 3;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
314
315
}

Christian Schäfer's avatar
Christian Schäfer committed
316
int
Michael Beck's avatar
Michael Beck committed
317
get_mode_align (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
318
{
319
320
  ANNOUNCE();
  return mode->align;
Christian Schäfer's avatar
Christian Schäfer committed
321
}
322
323

int
Michael Beck's avatar
Michael Beck committed
324
get_mode_sign (const ir_mode *mode)
325
326
327
328
329
{
  ANNOUNCE();
  return mode->sign;
}

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

356
  return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
357
358
359
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
360
get_mode_max (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
361
{
362
363
364
365
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
366

367
  return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
368
369
370
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
371
get_mode_null (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
372
{
373
374
375
376
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
377

378
  return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
379
380
}

381
382
tarval *
get_mode_one (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
383
{
384
385
386
387
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
388

389
  return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
390
391
}

392
393
tarval *
get_mode_infinite(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
394
{
395
396
397
398
399
400
  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
401
402
}

403
404
tarval *
get_mode_NAN(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
405
{
406
407
408
409
410
411
  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
412
413
}

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

   The set of "int" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
433
   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
434
435
436

   The set of "num" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
437
438
   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
439
440
441
442
            = {float || int}

   The set of "data" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
443
   data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
444
445
            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
446
447
448

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

   The set of "dataM" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
455
   dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
456
            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
457
458
459
            = {data || irm_M}
*/

460
461
462
463
464
#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
465
#  undef mode_is_numP
466
467
468
469
#  undef mode_is_data
#  undef mode_is_datab
#  undef mode_is_dataM
#endif
Christian Schäfer's avatar
Christian Schäfer committed
470
int
Michael Beck's avatar
Michael Beck committed
471
mode_is_signed (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
472
{
473
474
475
  ANNOUNCE();
  assert(mode);
  return mode->sign;
Christian Schäfer's avatar
Christian Schäfer committed
476
477
}

478
int
Michael Beck's avatar
Michael Beck committed
479
mode_is_float (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
480
{
481
482
  ANNOUNCE();
  assert(mode);
483
  return (get_mode_sort(mode) == irms_float_number);
Christian Schäfer's avatar
Christian Schäfer committed
484
485
}

486
int
Michael Beck's avatar
Michael Beck committed
487
mode_is_int (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
488
{
489
490
  ANNOUNCE();
  assert(mode);
491
  return (get_mode_sort(mode) == irms_int_number);
Christian Schäfer's avatar
Christian Schäfer committed
492
493
}

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

Michael Beck's avatar
Michael Beck committed
501
int mode_is_reference (const ir_mode *mode)
502
503
504
505
506
507
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_reference);
}

508
int
Michael Beck's avatar
Michael Beck committed
509
mode_is_num (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
510
{
511
512
513
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode));
Christian Schäfer's avatar
Christian Schäfer committed
514
515
}

Michael Beck's avatar
fixed:    
Michael Beck committed
516
517
518
519
520
521
522
523
int
mode_is_numP (const ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode) || mode_is_reference(mode));
}

524
int
Michael Beck's avatar
Michael Beck committed
525
mode_is_data (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
526
{
527
528
  ANNOUNCE();
  assert(mode);
529
  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
530
531
532
}

int
Michael Beck's avatar
Michael Beck committed
533
mode_is_datab (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
534
{
535
536
  ANNOUNCE();
  assert(mode);
537
  return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
Christian Schäfer's avatar
Christian Schäfer committed
538
539
540
}

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

  if (sm == lm) return 1;

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

593
        case irms_float_number:
594
595
596
597
598
599
600
601
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

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

610
    case irms_reference:
611
612
613
614
615
616
617
618
619
620
621
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

622
/* ** initialization ** */
623
624
625
void
init_mode (void)
{
626
  ir_mode newmode;
627
628
629
  ANNOUNCE();
  /* init flexible array */

630
631
632
  obstack_init(&modes);

  num_modes  =  0;
633
  /* initialize predefined modes */
634
635
636
637
638
639

  /* Internal Modes */
  newmode.arithmetic = irma_none;
  newmode.size    = 0;
  newmode.align   = 0;
  newmode.sign    = 0;
640
  newmode.link    = NULL;
641
642
643
644
645
  newmode.tv_priv = NULL;

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

646
  /* Basic Block */
647
648
649
650
651
652
653
654
655
656
657
658
659
  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;
660
661

  /* Memory */
662
663
664
665
666
667
668
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
669
670

  /* Tuple */
671
672
673
674
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
675

676
  /* ANY */
677
678
679
680
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
681
682

  /* BAD */
683
684
685
686
687
688
689
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

691
  /* boolean */
692
693
694
695
696
697
698
699
700
701
  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;
702
703

  /* float */
704
705
706
707
708
  newmode.name    = id_from_str("F", 1);
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
709

710
  mode_F = register_mode(&newmode);
711
712

  /* double */
713
714
715
716
717
  newmode.name    = id_from_str("D", 1);
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
718

719
  mode_D = register_mode(&newmode);
720
721

  /* extended */
722
723
724
725
726
727
728
  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);
729

730
731
732
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
733
734

  /* signed byte */
735
736
737
738
739
  newmode.name    = id_from_str("Bs", 2);
  newmode.code    = irm_Bs;
  newmode.sign    = 1;
  newmode.align   = 1;
  newmode.size    = 8;
740

741
  mode_Bs = register_mode(&newmode);
742
743

  /* unsigned byte */
744
745
746
747
748
749
  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;
750

751
  mode_Bu = register_mode(&newmode);
752
753

  /* signed short integer */
754
755
756
757
758
  newmode.name    = id_from_str("Hs", 2);
  newmode.code    = irm_Hs;
  newmode.sign    = 1;
  newmode.align   = 2;
  newmode.size    = 16;
759

760
  mode_Hs = register_mode(&newmode);
761
762

  /* unsigned short integer */
763
764
765
766
767
  newmode.name    = id_from_str("Hu", 2);
  newmode.code    = irm_Hu;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
768

769
  mode_Hu = register_mode(&newmode);
770
771

  /* signed integer */
772
773
774
775
776
  newmode.name    = id_from_str("Is", 2);
  newmode.code    = irm_Is;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
777

778
  mode_Is = register_mode(&newmode);
779
780

  /* unsigned integer */
781
782
783
784
785
  newmode.name    = id_from_str("Iu", 2);
  newmode.code    = irm_Iu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
786

787
  mode_Iu = register_mode(&newmode);
788
789

  /* signed long integer */
790
791
792
793
794
  newmode.name    = id_from_str("Ls", 2);
  newmode.code    = irm_Ls;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
795

796
  mode_Ls = register_mode(&newmode);
797
798

  /* unsigned long integer */
799
800
801
802
803
804
805
  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);
806

807
  /* Character Modes */
808
809
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
810
811

  /* Character */
812
813
814
815
816
  newmode.name    = id_from_str("C", 1);
  newmode.code    = irm_C;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
817

818
  mode_C = register_mode(&newmode);
819
820

  /* Unicode character */
821
822
823
824
825
  newmode.name    = id_from_str("U", 1);
  newmode.code    = irm_U;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
826

827
828
829
830
831
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
832
833

  /* pointer */
834
835
836
837
838
839
840
  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
841
842
843

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