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

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

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

34
35
36
/* * *
 * local values
 * * */
37

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

196
197
198
199
200
201
202
203

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

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

  ANNOUNCE();
  assert(new_mode);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (sm == lm) return 1;

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

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

        default:
          break;
      }
      break;

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

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

    default:
      break;
  }

  /* else */
  return 0;
}

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

629
630
631
  obstack_init(&modes);

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

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

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

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

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

  mode_M = register_mode(&newmode);

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

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

  mode_T = register_mode(&newmode);
674

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

  mode_ANY = register_mode(&newmode);
680
681

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

  mode_BAD = register_mode(&newmode);

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

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

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

709
  mode_F = register_mode(&newmode);
710
711

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

718
  mode_D = register_mode(&newmode);
719
720

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

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

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

740
  mode_Bs = register_mode(&newmode);
741
742

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

750
  mode_Bu = register_mode(&newmode);
751
752

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

759
  mode_Hs = register_mode(&newmode);
760
761

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

768
  mode_Hu = register_mode(&newmode);
769
770

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

777
  mode_Is = register_mode(&newmode);
778
779

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

786
  mode_Iu = register_mode(&newmode);
787
788

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

795
  mode_Ls = register_mode(&newmode);
796
797

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

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

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

817
  mode_C = register_mode(&newmode);
818
819

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

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

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

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

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