irmode.c 23.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
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
    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:
    case irms_int_number:
    case irms_reference:
    case irms_character:
      return register_mode(&mode_tmpl);
298
  }
299
  return NULL; /* to shut up gcc */
300
301
}

302
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
/*
 * 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 */
}

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

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

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

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

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

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

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

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

413
414
415
416
417
418
int get_mode_arithmetic (const ir_mode *mode)
{
  ANNOUNCE();
  return mode->arithmetic;
}

419
420
421
422
423

/* 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
424
unsigned int get_mode_modulo_shift(const ir_mode *mode) {
425
426
427
  return mode->modulo_shift;
}

428
429
430
431
432
unsigned int get_mode_vector_elems(const ir_mode *mode) {
  return mode->vector_elem;
}

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

452
  return mode->min;
Christian Schäfer's avatar
Christian Schäfer committed
453
454
455
}

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

463
  return mode->max;
Christian Schäfer's avatar
Christian Schäfer committed
464
465
466
}

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

474
  return mode->null;
Christian Schäfer's avatar
Christian Schäfer committed
475
476
}

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

485
  return mode->one;
Christian Schäfer's avatar
Christian Schäfer committed
486
487
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

677
678
679
680
681
682
  ANNOUNCE();
  assert(sm);
  assert(lm);

  if (sm == lm) return 1;

Michael Beck's avatar
Michael Beck committed
683
684
685
  sm_bits = get_mode_size_bits(sm);
  lm_bits = get_mode_size_bits(lm);

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

718
        case irms_float_number:
719
720
721
722
723
724
725
726
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

727
    case irms_float_number:
Michael Beck's avatar
Michael Beck committed
728
729
730
731
732
      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;
      }
733
734
      break;

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

    default:
      break;
  }

  /* else */
  return 0;
}

747
/* ** initialization ** */
748
749
750
void
init_mode (void)
{
751
  ir_mode newmode;
752
753
754
  ANNOUNCE();
  /* init flexible array */

755
756
757
  obstack_init(&modes);

  num_modes  =  0;
758
  /* initialize predefined modes */
759
760

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

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

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

  /* Memory */
789
790
791
792
793
794
795
  newmode.name    = id_from_str("M", 1);
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
796
797

  /* Tuple */
798
799
800
801
  newmode.name    = id_from_str("T", 1);
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
802

803
  /* ANY */
804
805
806
807
  newmode.name    = id_from_str("ANY", 3);
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
808
809

  /* BAD */
810
811
812
813
814
815
816
  newmode.name    = id_from_str("BAD", 3);
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

818
  /* boolean */
819
820
821
822
823
824
  newmode.name    = id_from_str("b", 1);
  newmode.code    = irm_b;

  mode_b = register_mode(&newmode);

/* Data Modes */
825
  newmode.vector_elem = 1;
826
827
828
829

  /* Float Number Modes */
  newmode.sort    = irms_float_number;
  newmode.arithmetic = irma_ieee754;
830
831

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

838
  mode_F = register_mode(&newmode);
839
840

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

847
  mode_D = register_mode(&newmode);
848
849

  /* extended */
850
851
852
853
854
855
856
  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);
857

858
859
860
  /* Integer Number Modes */
  newmode.sort    = irms_int_number;
  newmode.arithmetic = irma_twos_complement;
861
862

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

870
  mode_Bs = register_mode(&newmode);
871
872

  /* unsigned byte */
873
874
875
876
877
878
  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;
879
  newmode.modulo_shift = 32;
880

881
  mode_Bu = register_mode(&newmode);
882
883

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

891
  mode_Hs = register_mode(&newmode);
892
893

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

901
  mode_Hu = register_mode(&newmode);
902
903

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

911
  mode_Is = register_mode(&newmode);
912
913

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

921
  mode_Iu = register_mode(&newmode);
922
923

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

931
  mode_Ls = register_mode(&newmode);
932
933

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

  mode_Lu = register_mode(&newmode);
942

943
  /* Character Modes */
944
945
  newmode.sort    = irms_character;
  newmode.arithmetic = irma_none;
946
947

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

955
  mode_C = register_mode(&newmode);
956
957

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

965
966
967
968
969
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
970
971

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

  mode_P = register_mode(&newmode);
Michael Beck's avatar
fixed:    
Michael Beck committed
980
981
982

  /* set the machine specific modes to the predifined ones */
  mode_P_mach = mode_P;
983
}
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000


void finish_mode(void) {
  obstack_free(&modes, 0);

  mode_T = NULL;
  mode_X = NULL;
  mode_M = NULL;
  mode_BB = NULL;
  mode_ANY = NULL;
  mode_BAD = NULL;

  mode_F = NULL;
  mode_D = NULL;
  mode_E = NULL;

  mode_Bs = NULL;