irmode.c 20.8 KB
Newer Older
Götz Lindenmaier's avatar
Götz Lindenmaier committed
1
2
3
4
5
6
7
8
9
10
11
/*
 * 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
added    
Boris Boesler committed
12
#ifdef HAVE_CONFIG_H
Michael Beck's avatar
Michael Beck committed
13
# include "config.h"
Boris Boesler's avatar
added    
Boris Boesler committed
14
15
#endif

Michael Beck's avatar
Michael Beck committed
16
#ifdef HAVE_STDLIB_H
17
# include <stdlib.h>
Michael Beck's avatar
Michael Beck committed
18
19
#endif
#ifdef HAVE_STRING_H
20
# include <string.h>
Michael Beck's avatar
Michael Beck committed
21
22
23
#endif

# include <stddef.h>
24
25
26

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

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

37
38
39
/* * *
 * local values
 * * */
40

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

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

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

48
49
50
/* * *
 * local functions
 * * */
Christian Schäfer's avatar
Christian Schäfer committed
51

52
/**
53
 * Compare modes that don't need to have their code field
54
 * correctly set
55
56
57
 *
 * TODO: Add other fields
 **/
Till Riedel's avatar
Till Riedel committed
58
INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n)
59
60
{
  if (m == n) return 1;
61
62
63
64
65
66
  if (m->sort         == n->sort &&
      m->arithmetic   == n->arithmetic &&
      m->size         == n->size &&
      m->sign         == n->sign  &&
      m->modulo_shift == n->modulo_shift &&
      m->vector_elem  == n->vector_elem)
67
    return 1;
Christian Schäfer's avatar
Christian Schäfer committed
68

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

72
73
74
75
76
77
78
79
/*
 * 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);

80
  adr += s + mask;
81

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

227

Michael Beck's avatar
Michael Beck committed
228
ir_mode *(get_modeP_mach)(void) {
229
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
230
231
232
233
234
235
236
  return __get_modeP_mach();
}

void (set_modeP_mach)(ir_mode *p) {
  ANNOUNCE();
  __set_modeP_mach(p);
}
237

238
/**
239
240
241
 * Registers a new mode.
 *
 * @param new_mode  The new mode template.
242
 */
243
static ir_mode *register_mode(const ir_mode* new_mode)
244
{
245
  ir_mode *mode = NULL;
246
247
248
249

  ANNOUNCE();
  assert(new_mode);

250
  /* copy mode struct to modes array */
251
  mode = (ir_mode*)obstack_copy(&modes, new_mode, sizeof(ir_mode));
252
253

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

257
  set_mode_values(mode);
258
259
260
261
262
263
264

  return mode;
}

/*
 * Creates a new mode.
 */
Michael Beck's avatar
Michael Beck committed
265
ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign,
266
		     mode_arithmetic arithmetic, unsigned int modulo_shift )
267
268
269
{
  ir_mode mode_tmpl;
  ir_mode *mode;
270

271
272
273
274
275
  mode_tmpl.name         = new_id_from_str(name);
  mode_tmpl.sort         = sort;
  mode_tmpl.size         = bit_size;
  mode_tmpl.sign         = sign ? 1 : 0;
  mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0;
276
  mode_tmpl.vector_elem  = 1;
277
278
279
  mode_tmpl.arithmetic   = arithmetic;
  mode_tmpl.link         = NULL;
  mode_tmpl.tv_priv      = NULL;
Christian Schäfer's avatar
Christian Schäfer committed
280

281
282
283
284
285
  mode = find_mode(&mode_tmpl);
  if (mode)
  {
    return mode;
  }
286
287
288

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

306
307
308
/*
 * Creates a new vector mode.
 */
Michael Beck's avatar
Michael Beck committed
309
ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign,
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
		     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.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();
Michael Beck's avatar
Michael Beck committed
364
  return __get_mode_modecode(mode);
Christian Schäfer's avatar
Christian Schäfer committed
365
366
367
}

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();
Michael Beck's avatar
Michael Beck committed
371
  return __get_mode_ident(mode);
Christian Schäfer's avatar
Christian Schäfer committed
372
373
}

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
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
385
  return __get_mode_sort(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
386
387
}

Michael Beck's avatar
Michael Beck committed
388
389
int
(get_mode_size_bits)(const ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
390
{
391
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
392
  return __get_mode_size_bits(mode);
Christian Schäfer's avatar
Christian Schäfer committed
393
394
}

Michael Beck's avatar
Michael Beck committed
395
396
int
(get_mode_size_bytes)(const ir_mode *mode) {
397
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
398
  return __get_mode_size_bytes(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
399
400
}

401
int
Michael Beck's avatar
Michael Beck committed
402
(get_mode_sign)(const ir_mode *mode)
403
404
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
405
  return __get_mode_sign(mode);
406
407
}

Michael Beck's avatar
Michael Beck committed
408
409
int
(get_mode_arithmetic)(const ir_mode *mode)
410
411
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
412
  return get_mode_arithmetic(mode);
413
414
}

415
416
417
418
419

/* 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.
 */
Michael Beck's avatar
Michael Beck committed
420
421
422
unsigned int
(get_mode_modulo_shift)(const ir_mode *mode) {
  return __get_mode_modulo_shift(mode);
423
424
}

Michael Beck's avatar
Michael Beck committed
425
unsigned int
426
(get_mode_n_vector_elems)(const ir_mode *mode) {
Michael Beck's avatar
Michael Beck committed
427
  return __get_mode_vector_elems(mode);
428
429
}

Michael Beck's avatar
Michael Beck committed
430
431
void *
(get_mode_link)(const ir_mode *mode)
432
433
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
434
  return __get_mode_link(mode);
435
436
}

Michael Beck's avatar
Michael Beck committed
437
438
void
(set_mode_link)(ir_mode *mode, void *l)
439
{
Michael Beck's avatar
Michael Beck committed
440
  __set_mode_link(mode, l);
441
442
}

Christian Schäfer's avatar
Christian Schäfer committed
443
tarval *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
444
get_mode_min (ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
445
{
446
447
448
449
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_data(mode));
Christian Schäfer's avatar
Christian Schäfer committed
450

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

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

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

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

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

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

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

487
488
tarval *
get_mode_infinite(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
489
{
490
491
492
493
494
  ANNOUNCE();
  assert(mode);
  assert(get_mode_modecode(mode) < num_modes);
  assert(mode_is_float(mode));

495
  return get_tarval_plus_inf(mode);
Christian Schäfer's avatar
Christian Schäfer committed
496
497
}

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

509
510
511
512
513
514
515
516
int
is_mode (void *thing) {
  if (get_kind(thing) == k_ir_mode)
    return 1;
  else
    return 0;
}

Christian Schäfer's avatar
Christian Schäfer committed
517
int
Michael Beck's avatar
Michael Beck committed
518
(mode_is_signed)(const ir_mode *mode) {
519
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
520
  return __mode_is_signed(mode);
Christian Schäfer's avatar
Christian Schäfer committed
521
522
}

523
int
Michael Beck's avatar
Michael Beck committed
524
(mode_is_float)(const ir_mode *mode) {
525
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
526
  return __mode_is_float(mode);
Christian Schäfer's avatar
Christian Schäfer committed
527
528
}

529
int
Michael Beck's avatar
Michael Beck committed
530
(mode_is_int)(const ir_mode *mode) {
531
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
532
  return __mode_is_int(mode);
Christian Schäfer's avatar
Christian Schäfer committed
533
534
}

Michael Beck's avatar
Michael Beck committed
535
536
int
(mode_is_character)(const ir_mode *mode) {
537
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
538
  return __mode_is_character(mode);
539
540
}

Michael Beck's avatar
Michael Beck committed
541
542
int
(mode_is_reference)(const ir_mode *mode) {
543
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
544
  return __mode_is_reference(mode);
545
546
}

547
int
Michael Beck's avatar
Michael Beck committed
548
(mode_is_num)(const ir_mode *mode) {
549
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
550
  return __mode_is_num(mode);
Christian Schäfer's avatar
Christian Schäfer committed
551
552
}

Michael Beck's avatar
fixed:    
Michael Beck committed
553
int
Michael Beck's avatar
Michael Beck committed
554
(mode_is_numP)(const ir_mode *mode) {
Michael Beck's avatar
fixed:    
Michael Beck committed
555
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
556
  return __mode_is_numP(mode);
Michael Beck's avatar
fixed:    
Michael Beck committed
557
558
}

559
int
Michael Beck's avatar
Michael Beck committed
560
(mode_is_data)(const ir_mode *mode) {
561
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
562
  return __mode_is_data(mode);
Christian Schäfer's avatar
Christian Schäfer committed
563
564
565
}

int
Michael Beck's avatar
Michael Beck committed
566
(mode_is_datab)(const ir_mode *mode) {
567
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
568
  return __mode_is_datab(mode);
Christian Schäfer's avatar
Christian Schäfer committed
569
570
571
}

int
Michael Beck's avatar
Michael Beck committed
572
(mode_is_dataM)(const ir_mode *mode) {
573
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
574
  return __mode_is_dataM(mode);
Christian Schäfer's avatar
Christian Schäfer committed
575
}
576
577

int
Michael Beck's avatar
Michael Beck committed
578
(mode_is_float_vector)(const ir_mode *mode) {
579
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
580
  return __mode_is_float_vector(mode);
581
582
583
}

int
Michael Beck's avatar
Michael Beck committed
584
(mode_is_int_vector)(const ir_mode *mode) {
585
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
586
587
588
  return __mode_is_int_vector(mode);
}

589
/* Returns true if sm can be converted to lm without loss. */
590
int
Michael Beck's avatar
Michael Beck committed
591
smaller_mode(const ir_mode *sm, const ir_mode *lm)
592
{
Michael Beck's avatar
Michael Beck committed
593
594
  int sm_bits, lm_bits;

595
596
597
598
599
600
  ANNOUNCE();
  assert(sm);
  assert(lm);

  if (sm == lm) return 1;

Michael Beck's avatar
Michael Beck committed
601
602
603
  sm_bits = get_mode_size_bits(sm);
  lm_bits = get_mode_size_bits(lm);

604
605
  switch(get_mode_sort(sm))
  {
606
    case irms_int_number:
607
608
      switch(get_mode_sort(lm))
      {
609
        case irms_int_number:
610
611
612
613
          /* 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
614
	   *   - sm & lm are two_complement and lm has greater or equal number of bits
615
           */
Michael Beck's avatar
Michael Beck committed
616
617
618
619
620
          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))
621
          {
Michael Beck's avatar
Michael Beck committed
622
            if ( mode_is_signed(lm) && (lm_bits >= sm_bits) )
623
624
625
626
              return 1;
          }
          else if (mode_is_signed(lm))
          {
Michael Beck's avatar
Michael Beck committed
627
            if (lm_bits > sm_bits + 1)
628
629
              return 1;
          }
Michael Beck's avatar
Michael Beck committed
630
          else if (lm_bits >= sm_bits)
631
632
633
634
635
          {
            return 1;
          }
          break;

636
        case irms_float_number:
637
638
639
640
641
642
643
644
          /* int to float works if the float is large enough */
          return 0;

        default:
          break;
      }
      break;

645
    case irms_float_number:
Michael Beck's avatar
Michael Beck committed
646
647
648
649
650
      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;
      }
651
652
      break;

653
    case irms_reference:
654
655
656
657
658
659
660
661
662
663
664
       /* do exist machines out there with different pointer lenghts ?*/
      return 0;

    default:
      break;
  }

  /* else */
  return 0;
}

665
/* initialization, build the default modes */
666
667
668
void
init_mode (void)
{
669
  ir_mode newmode;
670
671
672
  ANNOUNCE();
  /* init flexible array */

673
674
675
  obstack_init(&modes);

  num_modes  =  0;
676
  /* initialize predefined modes */
677
678

  /* Internal Modes */
679
680
681
682
  newmode.arithmetic   = irma_none;
  newmode.size         = 0;
  newmode.sign         = 0;
  newmode.modulo_shift = 0;
683
  newmode.vector_elem  = 0;
684
685
  newmode.link         = NULL;
  newmode.tv_priv      = NULL;
686
687
688
689

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

690
  /* Basic Block */
691
  newmode.name    = new_id_from_chars("BB", 2);
692
693
694
695
696
  newmode.code    = irm_BB;

  mode_BB = register_mode(&newmode);

/* eXecution */
697
  newmode.name    = new_id_from_chars("X", 1);
698
699
700
701
702
703
  newmode.code    = irm_X;

  mode_X = register_mode(&newmode);

  /* Memory Modes */
  newmode.sort    = irms_memory;
704
705

  /* Memory */
706
  newmode.name    = new_id_from_chars("M", 1);
707
708
709
710
711
712
  newmode.code    = irm_M;

  mode_M = register_mode(&newmode);

  /* Auxiliary Modes */
  newmode.sort    = irms_auxiliary,
713
714

  /* Tuple */
715
  newmode.name    = new_id_from_chars("T", 1);
716
717
718
  newmode.code    = irm_T;

  mode_T = register_mode(&newmode);
719

720
  /* ANY */
721
  newmode.name    = new_id_from_chars("ANY", 3);
722
723
724
  newmode.code    = irm_ANY;

  mode_ANY = register_mode(&newmode);
725
726

  /* BAD */
727
  newmode.name    = new_id_from_chars("BAD", 3);
728
729
730
731
732
733
  newmode.code    = irm_BAD;

  mode_BAD = register_mode(&newmode);

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

735
  /* boolean */
736
  newmode.name    = new_id_from_chars("b", 1);
737
738
739
740
741
  newmode.code    = irm_b;

  mode_b = register_mode(&newmode);

/* Data Modes */
742
  newmode.vector_elem = 1;
743
744

  /* Float Number Modes */
745
  newmode.sort       = irms_float_number;
746
  newmode.arithmetic = irma_ieee754;
747
748

  /* float */
749
  newmode.name    = new_id_from_chars("F", 1);
750
751
752
  newmode.code    = irm_F;
  newmode.sign    = 1;
  newmode.size    = 32;
753

754
  mode_F = register_mode(&newmode);
755
756

  /* double */
757
  newmode.name    = new_id_from_chars("D", 1);
758
759
760
  newmode.code    = irm_D;
  newmode.sign    = 1;
  newmode.size    = 64;
761

762
  mode_D = register_mode(&newmode);
763
764

  /* extended */
765
  newmode.name    = new_id_from_chars("E", 1);
766
767
768
769
770
  newmode.code    = irm_E;
  newmode.sign    = 1;
  newmode.size    = 80;

  mode_E = register_mode(&newmode);
771

772
  /* Integer Number Modes */
773
774
  newmode.sort         = irms_int_number;
  newmode.arithmetic   = irma_twos_complement;
775
776

  /* signed byte */
777
  newmode.name         = new_id_from_chars("Bs", 2);
778
779
780
  newmode.code         = irm_Bs;
  newmode.sign         = 1;
  newmode.size         = 8;
781
  newmode.modulo_shift = 32;
782

783
  mode_Bs = register_mode(&newmode);
784
785

  /* unsigned byte */
786
  newmode.name         = new_id_from_chars("Bu", 2);
787
788
789
790
  newmode.code         = irm_Bu;
  newmode.arithmetic   = irma_twos_complement;
  newmode.sign         = 0;
  newmode.size         = 8;
791
  newmode.modulo_shift = 32;
792

793
  mode_Bu = register_mode(&newmode);
794
795

  /* signed short integer */
796
  newmode.name         = new_id_from_chars("Hs", 2);
797
798
799
  newmode.code         = irm_Hs;
  newmode.sign         = 1;
  newmode.size         = 16;
800
  newmode.modulo_shift = 32;
801

802
  mode_Hs = register_mode(&newmode);
803
804

  /* unsigned short integer */
805
  newmode.name         = new_id_from_chars("Hu", 2);
806
807
808
  newmode.code         = irm_Hu;
  newmode.sign         = 0;
  newmode.size         = 16;
809
  newmode.modulo_shift = 32;
810

811
  mode_Hu = register_mode(&newmode);
812
813

  /* signed integer */
814
  newmode.name         = new_id_from_chars("Is", 2);
815
816
817
  newmode.code         = irm_Is;
  newmode.sign         = 1;
  newmode.size         = 32;
818
  newmode.modulo_shift = 32;
819

820
  mode_Is = register_mode(&newmode);
821
822

  /* unsigned integer */
823
  newmode.name         = new_id_from_chars("Iu", 2);
824
825
826
  newmode.code         = irm_Iu;
  newmode.sign         = 0;
  newmode.size         = 32;
827
  newmode.modulo_shift = 32;
828

829
  mode_Iu = register_mode(&newmode);
830
831

  /* signed long integer */
832
  newmode.name         = new_id_from_chars("Ls", 2);
833
834
835
  newmode.code         = irm_Ls;
  newmode.sign         = 1;
  newmode.size         = 64;
836
  newmode.modulo_shift = 64;
837

838
  mode_Ls = register_mode(&newmode);
839
840

  /* unsigned long integer */
841
  newmode.name         = new_id_from_chars("Lu", 2);
842
843
844
  newmode.code         = irm_Lu;
  newmode.sign         = 0;
  newmode.size         = 64;
845
  newmode.modulo_shift = 64;
846
847

  mode_Lu = register_mode(&newmode);
848

849
  /* Character Modes */
850
851
  newmode.sort         = irms_character;
  newmode.arithmetic   = irma_none;
852
853

  /* Character */
854
  newmode.name         = new_id_from_chars("C", 1);
855
856
857
  newmode.code         = irm_C;
  newmode.sign         = 0;
  newmode.size         = 8;
858
  newmode.modulo_shift = 32;
859

860
  mode_C = register_mode(&newmode);
861
862

  /* Unicode character */
863
  newmode.name         = new_id_from_chars("U", 1);
864
865
866
  newmode.code         = irm_U;
  newmode.sign         = 0;
  newmode.size         = 16;
867
  newmode.modulo_shift = 32;
868

869
870
871
872
873
  mode_U = register_mode(&newmode);

  /* Reference Modes */
  newmode.sort    = irms_reference;
  newmode.arithmetic = irma_twos_complement;
874
875

  /* pointer */
876
  newmode.name         = new_id_from_chars("P", 1);
877
878
879
  newmode.code         = irm_P;
  newmode.sign         = 0;
  newmode.size         = 32;
880
  newmode.modulo_shift = 0;
881
882

  mode_P = register_mode(&newmode);
Michael Beck's avatar
fixed:    
Michael Beck committed
883
884
885

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

Michael Beck's avatar
Michael Beck committed
888
889
/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode) {
890
891
  ir_mode n = *mode;

Michael Beck's avatar
Michael Beck committed
892
  if (mode->sort != irms_int_number);
893
894
895
896
  n.sign = 0;
  return find_mode(&n);
}

Michael Beck's avatar
Michael Beck committed
897
898
/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode) {
899
900
901
902
903
904
905
  ir_mode n = *mode;

  assert(mode->sort == irms_int_number);
  n.sign = 1;
  return find_mode(&n);
}

Michael Beck's avatar
Michael Beck committed
906
907
908
909
910
911
912
913
914
/* finds a integer mode with 2*n bits for an integer mode with n bits. */
ir_mode *find_double_bits_int_mode(const ir_mode *mode) {
  ir_mode n = *mode;

  assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);

  n.size = 2*mode->size;
  return find_mode(&n);
}
915

916
917
918
919
920
921
922
923
924
925
926
927
928
929
/*
 * Returns non-zero if the given mode honors signed zero's, i.e.,
 * a +0 and a -0 exists and handled differently.
 */
int mode_honor_signed_zeros(const ir_mode *mode)
{
  /* for floating point, we know that IEEE 754 has +0 and -0,
   * but always handles it identical.
   */
  if (mode->sort == irms_float_number)
    return mode->arithmetic == irma_ieee754 ? 0 : 1;
  return 0;
}

930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
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;
  mode_Bu = NULL;
  mode_Hs = NULL;
  mode_Hu = NULL;
  mode_Is = NULL;
  mode_Iu = NULL;
  mode_Ls = NULL;
  mode_Lu = NULL;

  mode_C = NULL;
  mode_U = NULL;
  mode_b = NULL;
  mode_P = NULL;

  mode_P_mach = NULL;
}