irmode.c 22.7 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
62
63
64
65
  if (m->sort         == n->sort &&
      m->arithmetic   == n->arithmetic &&
      m->size         == n->size &&
      m->align        == n->align &&
      m->sign         == n->sign  &&
      m->modulo_shift == n->modulo_shift &&
      m->vector_elem  == n->vector_elem)
66
    return 1;
Christian Schäfer's avatar
Christian Schäfer committed
67

68
69
  return 0;
}
Matthias Heil's avatar
Matthias Heil committed
70

71
72
73
74
75
76
77
78
/*
 * calculates the next obstack address
 */
static void *next_obstack_adr(struct obstack *o, void *p, size_t s)
{
  PTR_INT_TYPE adr = __PTR_TO_INT((char *)p);
  int mask = obstack_alignment_mask(o);

79
  adr += s + mask;
80

81
  return __INT_TO_PTR(adr & ~mask);
82
83
}

84
/**
85
 * searches the modes obstack for the given mode and returns
86
 * a pointer on an equal mode already in the array, NULL if
87
88
 * none found
 */
89
static ir_mode *find_mode(const ir_mode *m)
90
{
91
  ir_mode *n, *nn;
92
93
  struct _obstack_chunk	*p;

94
95
96
97
  p  = modes.chunk;
  n  = (ir_mode *)p->contents;
  nn = next_obstack_adr(&modes, n, sizeof(*n));
  for (; (char *)nn <= modes.next_free;) {
98
99
100
    assert(is_mode(n));
    if (modes_are_equal(n, m))
      return n;
101
102
103

    n  = nn;
    nn = next_obstack_adr(&modes, n, sizeof(*n));
104
  }
Matthias Heil's avatar
Matthias Heil committed
105

106
  for (p = p->prev; p; p = p->prev) {
107
108
109
    n  = (ir_mode *)p->contents;
    nn = next_obstack_adr(&modes, n, sizeof(*n));
    for (; (char *)nn < p->limit;) {
110
111
112
      assert(is_mode(n));
      if (modes_are_equal(n, m))
	return n;
113
114
115
116

      n  = nn;
      nn = next_obstack_adr(&modes, n, sizeof(*n));
    }
117
  }
Matthias Heil's avatar
Matthias Heil committed
118

119
120
  return NULL;
}
Christian Schäfer's avatar
Christian Schäfer committed
121

122
123
124
/**
 * sets special values of modes
 */
125
126
static void set_mode_values(ir_mode* mode)
{
127
128
  switch (get_mode_sort(mode))
  {
129
    case irms_character:
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
    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;
148
      mode->null = (get_mode_modecode(mode) == irm_P) ? tarval_P_void : tarval_bad;
149
150
151
152
153
154
155
156
157
158
159
160
      mode->one = tarval_bad;
      break;

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

163
164
165
/* * *
 * globals defined in irmode.h
 * * */
Matthias Heil's avatar
Matthias Heil committed
166

167
/* --- Predefined modes --- */
Christian Schäfer's avatar
Christian Schäfer committed
168

169
170
171
172
173
/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_BB;
174
175
ir_mode *mode_ANY;
ir_mode *mode_BAD;
Christian Schäfer's avatar
Christian Schäfer committed
176

177
178
179
180
/* 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
181

182
183
184
185
186
187
188
189
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
190

191
192
193
194
ir_mode *mode_C;
ir_mode *mode_U;
ir_mode *mode_b;
ir_mode *mode_P;
Michael Beck's avatar
fixed:    
Michael Beck committed
195
196
197

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

199
200
201
202
203
/* * *
 * functions defined in irmode.h
 * * */

/* JNI access functions */
Michael Beck's avatar
Michael Beck committed
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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; }
223
224
INLINE ir_mode *get_modeANY(void) { ANNOUNCE(); return mode_ANY; }
INLINE ir_mode *get_modeBAD(void) { ANNOUNCE(); return mode_BAD; }
225

226
227
228
229
230
231
232
233

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

234
235
236
237
/**
 * Registers a new mode if not defined yet, else returns
 * the "equivalent" one.
 */
238
static ir_mode *register_mode(const ir_mode* new_mode)
239
{
240
  ir_mode *mode = NULL;
241
242
243
244

  ANNOUNCE();
  assert(new_mode);

245
  /* copy mode struct to modes array */
246
  mode = (ir_mode*)obstack_copy(&modes, new_mode, sizeof(ir_mode));
247
248
249
250
251

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

252
  set_mode_values(mode);
253
254
255
256
257
258
259

  return mode;
}

/*
 * Creates a new mode.
 */
260
261
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int align, int sign,
		     mode_arithmetic arithmetic, unsigned int modulo_shift )
262
263
264
{
  ir_mode mode_tmpl;
  ir_mode *mode;
265

266
267
268
269
270
271
  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.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
272
  mode_tmpl.vector_elem  = 1;
273
274
275
  mode_tmpl.arithmetic   = arithmetic;
  mode_tmpl.link         = NULL;
  mode_tmpl.tv_priv      = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
276

277
278
279
280
281
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
282
283
284

  /* sanity checks */
  switch (sort)
285
  {
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
    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);
301
  }
302
  return NULL; /* to shut up gcc */
303
304
}

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
/*
 * Creates a new vector mode.
 */
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int align, int sign,
		     mode_arithmetic arithmetic, unsigned int modulo_shift )
{
  ir_mode mode_tmpl;
  ir_mode *mode;

  mode_tmpl.name         = new_id_from_str(name);
  mode_tmpl.sort         = sort;
  mode_tmpl.size         = bit_size * num_of_elem;
  mode_tmpl.align        = align;
  mode_tmpl.sign         = sign ? 1 : 0;
  mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
  mode_tmpl.vector_elem  = num_of_elem;
  mode_tmpl.arithmetic   = arithmetic;
  mode_tmpl.link         = NULL;
  mode_tmpl.tv_priv      = NULL;

  mode = find_mode(&mode_tmpl);
  if (mode)
    return mode;

  if (num_of_elem <= 1) {
    assert(0 && "vector modes should have at least 2 elements");
    return NULL;
  }

  /* sanity checks */
  switch (sort)
  {
    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_reference:
    case irms_character:
      assert(0 && "only integer and floating point modes can be vectorized");
      return NULL;

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

    case irms_int_number:
      return register_mode(&mode_tmpl);
  }
  return NULL; /* to shut up gcc */
}

359
/* Functions for the direct access to all attributes od a ir_mode */
Christian Schäfer's avatar
Christian Schäfer committed
360
modecode
Michael Beck's avatar
Michael Beck committed
361
get_mode_modecode(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
362
{
363
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
364
365
366
367
  return mode->code;
}

ident *
Michael Beck's avatar
Michael Beck committed
368
get_mode_ident(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
369
{
370
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
371
372
373
  return mode->name;
}

374
const char *
Michael Beck's avatar
Michael Beck committed
375
get_mode_name(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
376
{
377
  ANNOUNCE();
378
  return get_id_str(mode->name);
Christian Schäfer's avatar
Christian Schäfer committed
379
380
}

381
mode_sort
Michael Beck's avatar
Michael Beck committed
382
get_mode_sort(const ir_mode* mode)
383
384
385
{
  ANNOUNCE();
  return mode->sort;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
386
387
}

Götz Lindenmaier's avatar
Götz Lindenmaier committed
388
INLINE int
Michael Beck's avatar
Michael Beck committed
389
get_mode_size_bits(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
390
{
391
  ANNOUNCE();
Christian Schäfer's avatar
Christian Schäfer committed
392
393
394
  return mode->size;
}

Michael Beck's avatar
Michael Beck committed
395
int get_mode_size_bytes(const ir_mode *mode) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
396
  int size = get_mode_size_bits(mode);
397
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
398
399
  if ((size & 7) != 0) return -1;
  return size >> 3;
Götz Lindenmaier's avatar
Götz Lindenmaier committed
400
401
}

Christian Schäfer's avatar
Christian Schäfer committed
402
int
Michael Beck's avatar
Michael Beck committed
403
get_mode_align (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
404
{
405
406
  ANNOUNCE();
  return mode->align;
Christian Schäfer's avatar
Christian Schäfer committed
407
}
408
409

int
Michael Beck's avatar
Michael Beck committed
410
get_mode_sign (const ir_mode *mode)
411
412
413
414
415
{
  ANNOUNCE();
  return mode->sign;
}

416
417
418
419
420
421
int get_mode_arithmetic (const ir_mode *mode)
{
  ANNOUNCE();
  return mode->arithmetic;
}

422
423
424
425
426

/* Attribute modulo shift specifies for modes of kind irms_int_number
 *  whether shift applies modulo to value of bits to shift.  Asserts
 *  if mode is not irms_int_number.
 */
Götz Lindenmaier's avatar
Götz Lindenmaier committed
427
unsigned int get_mode_modulo_shift(const ir_mode *mode) {
428
429
430
  return mode->modulo_shift;
}

431
432
433
434
435
unsigned int get_mode_vector_elems(const ir_mode *mode) {
  return mode->vector_elem;
}

void *get_mode_link(const ir_mode *mode)
436
437
438
439
440
441
442
443
444
445
446
{
  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
447
tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
448
get_mode_min (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
449
{
450
451
452
453
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
454

455
  return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
456
457
458
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
459
get_mode_max (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
460
{
461
462
463
464
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
465

466
  return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
467
468
469
}

tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
470
get_mode_null (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
471
{
472
473
474
475
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
476

477
  return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
478
479
}

480
481
tarval *
get_mode_one (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
482
{
483
484
485
486
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
487

488
  return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
489
490
}

491
492
tarval *
get_mode_infinite(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
493
{
494
495
496
497
498
499
  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
500
501
}

502
503
tarval *
get_mode_NAN(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
504
{
505
506
507
508
509
510
  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
511
512
}

513
514
515
516
517
518
519
520
521
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
522
523
524
525
526
527
/* 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
528
   float = {irm_F, irm_D, irm_E}
Christian Schäfer's avatar
Christian Schäfer committed
529
530
531

   The set of "int" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
532
   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
533
534
535

   The set of "num" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
536
537
   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
538
539
540
541
            = {float || int}

   The set of "data" is defined as:
   -------------------------------
Matthias Heil's avatar
Matthias Heil committed
542
   data  = {irm_F, irm_D, irm_E irm_Bs, irm_Bu, irm_Hs, irm_Hu,
543
544
            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
545
546
547

   The set of "datab" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
548
   datab = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
549
            irm_Is, irm_Iu, irm_Ls, irm_Lu, irm_C, irm_U, irm_P, irm_b}
Matthias Heil's avatar
Matthias Heil committed
550
            = {data || irm_b }
Christian Schäfer's avatar
Christian Schäfer committed
551
552
553

   The set of "dataM" is defined as:
   ---------------------------------
Matthias Heil's avatar
Matthias Heil committed
554
   dataM = {irm_F, irm_D, irm_E, irm_Bs, irm_Bu, irm_Hs, irm_Hu,
555
            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
556
557
558
            = {data || irm_M}
*/

559
560
561
562
563
#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
564
#  undef mode_is_numP
565
566
567
568
#  undef mode_is_data
#  undef mode_is_datab
#  undef mode_is_dataM
#endif
Christian Schäfer's avatar
Christian Schäfer committed
569
int
Michael Beck's avatar
Michael Beck committed
570
mode_is_signed (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
571
{
572
573
574
  ANNOUNCE();
  assert(mode);
  return mode->sign;
Christian Schäfer's avatar
Christian Schäfer committed
575
576
}

577
int
Michael Beck's avatar
Michael Beck committed
578
mode_is_float (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
579
{
580
581
  ANNOUNCE();
  assert(mode);
582
  return (get_mode_sort(mode) == irms_float_number);
Christian Schäfer's avatar
Christian Schäfer committed
583
584
}

585
int
Michael Beck's avatar
Michael Beck committed
586
mode_is_int (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
587
{
588
589
  ANNOUNCE();
  assert(mode);
590
  return (get_mode_sort(mode) == irms_int_number);
Christian Schäfer's avatar
Christian Schäfer committed
591
592
}

Michael Beck's avatar
Michael Beck committed
593
int mode_is_character (const ir_mode *mode)
594
595
596
597
598
599
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_character);
}

Michael Beck's avatar
Michael Beck committed
600
int mode_is_reference (const ir_mode *mode)
601
602
603
604
605
606
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_reference);
}

607
int
Michael Beck's avatar
Michael Beck committed
608
mode_is_num (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
609
{
610
611
612
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode));
Christian Schäfer's avatar
Christian Schäfer committed
613
614
}

Michael Beck's avatar
fixed:    
Michael Beck committed
615
616
617
618
619
620
621
622
int
mode_is_numP (const ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);
  return (mode_is_int(mode) || mode_is_float(mode) || mode_is_reference(mode));
}

623
int
Michael Beck's avatar
Michael Beck committed
624
mode_is_data (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
625
{
626
627
  ANNOUNCE();
  assert(mode);
628
  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
629
630
631
}

int
Michael Beck's avatar
Michael Beck committed
632
mode_is_datab (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
633
{
634
635
  ANNOUNCE();
  assert(mode);
636
  return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
Christian Schäfer's avatar
Christian Schäfer committed
637
638
639
}

int
Michael Beck's avatar
Michael Beck committed
640
mode_is_dataM (const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
641
{
642
643
644
  ANNOUNCE();
  assert(mode);
  return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
Christian Schäfer's avatar
Christian Schäfer committed
645
}
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

int
mode_is_float_vector (const ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_float_number) && (get_mode_vector_elems(mode) > 1);
}

int
mode_is_int_vector (const ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);
  return (get_mode_sort(mode) == irms_int_number) && (get_mode_vector_elems(mode) > 1);
}

663
664
#ifdef MODE_ACCESS_DEFINES
#  define mode_is_signed(mode) (mode)->sign
665
666
667
668
669
670
#  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))
671
672
#  define mode_is_float_vector(mode) (((mode)->sort == irms_float_number) && ((mode)->vector_elem > 1))
#  define mode_is_int_vector(mode) (((mode)->sort == irms_int_number) && ((mode)->vector_elem > 1))
673
#endif
674
/* Returns true if sm can be converted to lm without loss. */
675
int
Michael Beck's avatar
Michael Beck committed
676
smaller_mode(const ir_mode *sm, const ir_mode *lm)
677
{
Michael Beck's avatar
Michael Beck committed
678
679
  int sm_bits, lm_bits;

680
681
682
683
684
685
  ANNOUNCE();
  assert(sm);
  assert(lm);

  if (sm == lm) return 1;

Michael Beck's avatar
Michael Beck committed
686
687
688
  sm_bits = get_mode_size_bits(sm);
  lm_bits = get_mode_size_bits(lm);

689
690
  switch(get_mode_sort(sm))
  {
691
    case irms_int_number:
692
693
      switch(get_mode_sort(lm))
      {
694
        case irms_int_number:
695
696
697
698
          /* 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)
Michael Beck's avatar
Michael Beck committed
699
	   *   - sm & lm are two_complement and lm has greater or equal number of bits
700
           */
Michael Beck's avatar
Michael Beck committed
701
702
703
704
705
          if (   get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
	      && get_mode_arithmetic(sm) == irma_twos_complement) {
	    return lm_bits >= sm_bits;
	  }
          else if (mode_is_signed(sm))
706
          {
Michael Beck's avatar
Michael Beck committed
707
            if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
708
709
710
711
              return 1;
          }
          else if (mode_is_signed(lm))
          {
Michael Beck's avatar
Michael Beck committed
712
            if (lm_bits > sm_bits + 1)
713
714
              return 1;
          }
Michael Beck's avatar
Michael Beck committed
715
          else if (lm_bits >= sm_bits)
716
717
718
719
720
          {
            return 1;
          }
          break;

721
        case irms_float_number:
722
723
724
725
726
727
728
729
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

730
    case irms_float_number:
Michael Beck's avatar
Michael Beck committed
731
732
733
734
735
      if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
        if ( (get_mode_sort(lm) == irms_float_number)
           && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
          return 1;
      }
736
737
      break;

738
    case irms_reference:
739
740
741
742
743
744
745
746
747
748
749
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

750
/* ** initialization ** */
751
752
753
void
init_mode (void)
{
754
  ir_mode newmode;
755
756
757
  ANNOUNCE();
  /* init flexible array */

758
759
760
  obstack_init(&modes);

  num_modes  =  0;
761
  /* initialize predefined modes */
762
763

  /* Internal Modes */
764
765
766
767
768
  newmode.arithmetic   = irma_none;
  newmode.size         = 0;
  newmode.align        = 0;
  newmode.sign         = 0;
  newmode.modulo_shift = 0;
769
  newmode.vector_elem  = 0;
770
771
  newmode.link         = NULL;
  newmode.tv_priv      = NULL;
772
773
774
775

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

776
  /* Basic Block */
777
778
779
780
781
782
783
784
785
786
787
788
789
  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;
790
791

  /* Memory */
792
793
794
795
796
797
798
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
799
800

  /* Tuple */
801
802
803
804
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
805

806
  /* ANY */
807
808
809
810
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
811
812

  /* BAD */
813
814
815
816
817
818
819
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

821
  /* boolean */
822
823
824
825
826
827
  newmode.name    = id_from_str("b", 1);
  newmode.code    = irm_b;

  mode_b = register_mode(&newmode);

/* Data Modes */
828
  newmode.vector_elem = 1;
829
830
831
832

  /* Float Number Modes */
  newmode.sort    = irms_float_number;
  newmode.arithmetic = irma_ieee754;
833
834

  /* float */
835
836
837
838
839
  newmode.name    = id_from_str("F", 1);
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
840

841
  mode_F = register_mode(&newmode);
842
843

  /* double */
844
845
846
847
848
  newmode.name    = id_from_str("D", 1);
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
849

850
  mode_D = register_mode(&newmode);
851
852

  /* extended */
853
854
855
856
857
858
859
  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);
860

861
862
863
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
864
865

  /* signed byte */
866
867
868
869
870
  newmode.name    = id_from_str("Bs", 2);
  newmode.code    = irm_Bs;
  newmode.sign    = 1;
  newmode.align   = 1;
  newmode.size    = 8;
871
  newmode.modulo_shift = 32;
872

873
  mode_Bs = register_mode(&newmode);
874
875

  /* unsigned byte */
876
877
878
879
880
881
  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;
882
  newmode.modulo_shift = 32;
883

884
  mode_Bu = register_mode(&newmode);
885
886

  /* signed short integer */
887
888
889
890
891
  newmode.name    = id_from_str("Hs", 2);
  newmode.code    = irm_Hs;
  newmode.sign    = 1;
  newmode.align   = 2;
  newmode.size    = 16;
892
  newmode.modulo_shift = 32;
893

894
  mode_Hs = register_mode(&newmode);
895
896

  /* unsigned short integer */
897
898
899
900
901
  newmode.name    = id_from_str("Hu", 2);
  newmode.code    = irm_Hu;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
902
  newmode.modulo_shift = 32;
903

904
  mode_Hu = register_mode(&newmode);
905
906

  /* signed integer */
907
908
909
910
911
  newmode.name    = id_from_str("Is", 2);
  newmode.code    = irm_Is;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 32;
912
  newmode.modulo_shift = 32;
913

914
  mode_Is = register_mode(&newmode);
915
916

  /* unsigned integer */
917
918
919
920
921
  newmode.name    = id_from_str("Iu", 2);
  newmode.code    = irm_Iu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
922
  newmode.modulo_shift = 32;
923

924
  mode_Iu = register_mode(&newmode);
925
926

  /* signed long integer */
927
928
929
930
931
  newmode.name    = id_from_str("Ls", 2);
  newmode.code    = irm_Ls;
  newmode.sign    = 1;
  newmode.align   = 4;
  newmode.size    = 64;
932
  newmode.modulo_shift = 64;
933

934
  mode_Ls = register_mode(&newmode);
935
936

  /* unsigned long integer */
937
938
939
940
941
  newmode.name    = id_from_str("Lu", 2);
  newmode.code    = irm_Lu;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 64;
942
  newmode.modulo_shift = 64;
943
944

  mode_Lu = register_mode(&newmode);
945

946
  /* Character Modes */
947
948
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
949
950

  /* Character */
951
952
953
954
955
  newmode.name    = id_from_str("C", 1);
  newmode.code    = irm_C;
  newmode.sign    = 0;
  newmode.align   = 1;
  newmode.size    = 8;
956
  newmode.modulo_shift = 32;
957

958
  mode_C = register_mode(&newmode);
959
960

  /* Unicode character */
961
962
963
964
965
  newmode.name    = id_from_str("U", 1);
  newmode.code    = irm_U;
  newmode.sign    = 0;
  newmode.align   = 2;
  newmode.size    = 16;
966
  newmode.modulo_shift = 32;
967

968
969
970
971
972
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
973
974

  /* pointer */
975
976
977
978
979
  newmode.name    = id_from_str("P", 1);
  newmode.code    = irm_P;
  newmode.sign    = 0;
  newmode.align   = 4;
  newmode.size    = 32;
980
  newmode.modulo_shift = 0;
981
982

  mode_P = register_mode(&newmode);
Michael Beck's avatar
fixed:    
Michael Beck committed
983
984
985

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