tv.c 41.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
/*
 * Project:     libFIRM
 * File name:   ir/tv/tv.c
 * Purpose:     Representation of and static computations on target machine
 *              values.
 * Author:      Mathias Heil
 * Modified by:
 * Created:
 * CVS-ID:      $Id$
 * Copyright:   (c) 2003 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */
Christian Schäfer's avatar
Christian Schäfer committed
13

14
/*
15
16
 *    Values are stored in a format depending upon chosen arithmetic
 *    module. Default uses strcalc and fltcalc.
17
18
 *
 */
19

Christian Schäfer's avatar
Christian Schäfer committed
20
/* This implementation assumes:
21
 *  - target has IEEE-754 floating-point arithmetic.  */
Christian Schäfer's avatar
Christian Schäfer committed
22

Boris Boesler's avatar
Boris Boesler committed
23
24
25
26
27
28

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif


29
#include <assert.h>         /* assertions */
Michael Beck's avatar
Michael Beck committed
30
#include <stdlib.h>         /* atoi() */
Michael Beck's avatar
Michael Beck committed
31
32
33
#ifdef HAVE_STRING_H
# include <string.h>         /* nice things for strings */
#endif
34
#ifdef HAVE_STRINGS_H
35
#include <strings.h>        /* strings.h also includes bsd only function strcasecmp */
36
#endif
Michael Beck's avatar
Michael Beck committed
37
38
39
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
Boris Boesler's avatar
Boris Boesler committed
40
#ifdef HAVE_ALLOCA_H
Boris Boesler's avatar
Boris Boesler committed
41
42
# include <alloca.h>
#endif
43
44
45
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
46

47
48
49
#include "tv_t.h"
#include "set.h"            /* to store tarvals in */
#include "entity_t.h"       /* needed to store pointers to entities */
Michael Beck's avatar
Michael Beck committed
50
#include "irmode_t.h"
51
#include "irnode.h"         /* defines boolean return values (pnc_number)*/
52
53
#include "strcalc.h"
#include "fltcalc.h"
54
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
55
#include "firm_common.h"
Christian Schäfer's avatar
Christian Schäfer committed
56

Götz Lindenmaier's avatar
Götz Lindenmaier committed
57
58
/** Size of hash tables.  Should correspond to average number of distinct constant
    target values */
59
#define N_CONSTANTS 2048
Götz Lindenmaier's avatar
Götz Lindenmaier committed
60

61
62
/* get the integer overflow mode */
#define GET_OVERFLOW_MODE() int_overflow_mode
63
64

/* unused, float to int doesn't work yet */
65
66
67
68
69
enum float_to_int_mode {
  TRUNCATE,
  ROUND
};

70
71
72
73
74
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

75
76
77
78
79
80
81
82
/****************************************************************************
 *   local definitions and macros
 ****************************************************************************/
#ifndef NDEBUG
#  define TARVAL_VERIFY(a) tarval_verify((a))
#else
#  define TARVAL_VERIFY(a) ((void)0)
#endif
Christian Schäfer's avatar
Christian Schäfer committed
83

84
85
#define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
#define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
86

87
88
#define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
#define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
89

90
91
92
93
94
95
96
97
98
99
100
101
#define fail_verify(a) _fail_verify((a), __FILE__, __LINE__)
#if 0
static long long count = 0;
#  define ANNOUNCE() printf(__FILE__": call no. %lld (%s)\n", count++, __FUNCTION__);
#else
#  define ANNOUNCE() ((void)0)
#endif
/****************************************************************************
 *   private variables
 ****************************************************************************/
static struct set *tarvals;   /* container for tarval structs */
static struct set *values;    /* container for values */
102
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
103
104
105
106
107
108
109
110

/****************************************************************************
 *   private functions
 ****************************************************************************/
#ifndef NDEBUG
static int hash_val(const void *value, unsigned int length);
static int hash_tv(tarval *tv);
static void _fail_verify(tarval *tv, const char* file, int line)
Christian Schäfer's avatar
Christian Schäfer committed
111
{
112
113
114
115
116
117
  /* print a memory image of the tarval and throw an assertion */
  if (tv)
    printf("%s:%d: Invalid tarval:\n  mode: %s\n value: [%p]\n", file, line, get_mode_name(tv->mode), tv->value);
  else
    printf("%s:%d: Invalid tarval (null)", file, line);
  assert(0);
Christian Schäfer's avatar
Christian Schäfer committed
118
}
Till Riedel's avatar
Till Riedel committed
119
120
121
#ifdef __GNUC__
INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
#endif
Christian Schäfer's avatar
Christian Schäfer committed
122

Till Riedel's avatar
Till Riedel committed
123
INLINE static void tarval_verify(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
124
{
125
126
127
  assert(tv);
  assert(tv->mode);
  assert(tv->value);
Christian Schäfer's avatar
Christian Schäfer committed
128

129
130
131
132
133
134
135
  if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
  if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;

  if (!FIND_TARVAL(tv)) fail_verify(tv);
  if (tv->length > 0 && !FIND_VALUE(tv->value, tv->length)) fail_verify(tv);

  return;
Christian Schäfer's avatar
Christian Schäfer committed
136
}
137
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
138

139
static int hash_tv(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
140
{
141
  return (PTR_TO_INT(tv->value) ^ PTR_TO_INT(tv->mode)) + tv->length;
Christian Schäfer's avatar
Christian Schäfer committed
142
143
}

144
static int hash_val(const void *value, unsigned int length)
Christian Schäfer's avatar
Christian Schäfer committed
145
{
146
147
148
149
150
151
152
153
154
155
156
  unsigned int i;
  unsigned int hash = 0;

  /* scramble the byte - array */
  for (i = 0; i < length; i++)
  {
    hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
    hash += (hash << 11) ^ (hash >> 17);
  }

  return hash;
Christian Schäfer's avatar
Christian Schäfer committed
157
158
}

Michael Beck's avatar
Michael Beck committed
159
/** finds tarval with value/mode or creates new tarval */
160
static tarval *get_tarval(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
161
{
162
163
  tarval tv;

Michael Beck's avatar
Michael Beck committed
164
165
  tv.kind   = k_tarval;
  tv.mode   = mode;
166
  tv.length = length;
167
  if (length > 0) {
168
169
170
    /* if there already is such a value, it is returned, else value
     * is copied into the set */
    tv.value = INSERT_VALUE(value, length);
171
  } else {
172
    tv.value = value;
173
  }
174
175
176
  /* if there is such a tarval, it is returned, else tv is copied
   * into the set */
  return (tarval *)INSERT_TARVAL(&tv);
Christian Schäfer's avatar
Christian Schäfer committed
177
178
}

179
180
181
/**
 * handle overflow
 */
182
static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
183
{
184
  switch (get_mode_sort(mode))
185
  {
Michael Beck's avatar
Michael Beck committed
186
    case irms_int_number:
187
188
      if (sc_comp(value, get_mode_max(mode)->value) == 1) {
        switch (GET_OVERFLOW_MODE()) {
189
          case TV_OVERFLOW_SATURATE:
190
            return get_mode_max(mode);
191
          case TV_OVERFLOW_WRAP:
192
193
194
195
196
197
198
199
200
201
202
            {
              char *temp = alloca(sc_get_buffer_length());
              char *diff = alloca(sc_get_buffer_length());
              sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
              sc_val_from_ulong(1, temp);
              sc_add(diff, temp, diff);
              sc_sub(value, diff, temp);
              while (sc_comp(temp, get_mode_max(mode)->value) == 1)
                sc_sub(temp, diff, temp);
              return get_tarval(temp, length, mode);
            }
203
          case TV_OVERFLOW_BAD:
204
205
206
207
208
209
210
            return tarval_bad;
          default:
            return get_tarval(value, length, mode);
        }
      }
      if (sc_comp(value, get_mode_min(mode)->value) == -1) {
        switch (GET_OVERFLOW_MODE()) {
211
          case TV_OVERFLOW_SATURATE:
212
            return get_mode_min(mode);
213
          case TV_OVERFLOW_WRAP:
214
215
216
217
218
219
220
221
222
223
224
            {
              char *temp = alloca(sc_get_buffer_length());
              char *diff = alloca(sc_get_buffer_length());
              sc_sub(get_mode_max(mode)->value, get_mode_min(mode)->value, diff);
              sc_val_from_ulong(1, temp);
              sc_add(diff, temp, diff);
              sc_add(value, diff, temp);
              while (sc_comp(temp, get_mode_max(mode)->value) == 1)
                sc_add(temp, diff, temp);
              return get_tarval(temp, length, mode);
            }
225
          case TV_OVERFLOW_BAD:
226
227
228
229
230
            return tarval_bad;
          default:
            return get_tarval(value, length, mode);
        }
      }
231
      break;
Christian Schäfer's avatar
Christian Schäfer committed
232

Michael Beck's avatar
Michael Beck committed
233
    case irms_float_number:
234
235
236
237
      if (SWITCH_NOINFINITY && fc_is_inf(value))
      {
        return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
      }
Christian Schäfer's avatar
Christian Schäfer committed
238

239
240
241
242
243
      if (SWITCH_NODENORMALS && fc_is_subnormal(value))
      {
        return get_mode_null(mode);
      }
      break;
244
245
246
    default:
      break;
  }
247
  return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
248
249
}

250

251
/*
252
 *   public variables declared in tv.h
253
 */
254
255
256
257
258
259
260
static tarval reserved_tv[5];

tarval *tarval_bad       = &reserved_tv[0];
tarval *tarval_undefined = &reserved_tv[1];
tarval *tarval_b_false   = &reserved_tv[2];
tarval *tarval_b_true    = &reserved_tv[3];
tarval *tarval_P_void    = &reserved_tv[4];
Christian Schäfer's avatar
Christian Schäfer committed
261

262
/*
263
 *   public functions declared in tv.h
264
265
 */

266
267
268
269
270
271
272
273
274
275
276
277
/*
 * Constructors =============================================================
 */
tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
{
  ANNOUNCE();
  assert(str);
  assert(len);
  assert(mode);

  switch (get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
278
279
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
280
    case irms_auxiliary:
281
282
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
283

Michael Beck's avatar
Michael Beck committed
284
    case irms_internal_boolean:
285
      /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
Michael Beck's avatar
Michael Beck committed
286
287
288
      if (strcasecmp(str, "true")) return tarval_b_true;
      else if (strcasecmp(str, "false")) return tarval_b_true;
      else
289
        /* XXX This is C semantics */
290
    return atoi(str) ? tarval_b_true : tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
291

Michael Beck's avatar
Michael Beck committed
292
    case irms_float_number:
293
294
295
296
297
298
299
300
301
302
303
      switch(get_mode_size_bits(mode)) {
        case 32:
          fc_val_from_str(str, len, 8, 23, NULL);
          break;
        case 64:
          fc_val_from_str(str, len, 11, 52, NULL);
          break;
        case 80:
          fc_val_from_str(str, len, 15, 64, NULL);
          break;
      }
304
305
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);

Michael Beck's avatar
Michael Beck committed
306
307
    case irms_int_number:
    case irms_character:
308
      sc_val_from_str(str, len, NULL);
309
310
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);

Michael Beck's avatar
Michael Beck committed
311
    case irms_reference:
312
      return get_tarval(str, len, mode);
Christian Schäfer's avatar
Christian Schäfer committed
313
314
  }

315
  assert(0);  /* can't be reached, can it? */
316
  return NULL;
317
}
Christian Schäfer's avatar
Christian Schäfer committed
318

319
/*
320
 * helper function, create a tarval from long
321
 */
322
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
323
{
324
  ANNOUNCE();
325
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
326

327
328
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
329
    case irms_internal_boolean:
330
      /* XXX C semantics ! */
Michael Beck's avatar
Michael Beck committed
331
      return l ? tarval_b_true : tarval_b_false ;
Christian Schäfer's avatar
Christian Schäfer committed
332

Michael Beck's avatar
Michael Beck committed
333
334
    case irms_int_number:
    case irms_character:
335
      sc_val_from_long(l, NULL);
336
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
337

Michael Beck's avatar
Michael Beck committed
338
    case irms_float_number:
339
      return new_tarval_from_double((long double)l, mode);
Christian Schäfer's avatar
Christian Schäfer committed
340

Michael Beck's avatar
Michael Beck committed
341
    case irms_reference:
Michael Beck's avatar
Michael Beck committed
342
      return l ? tarval_bad : get_tarval(NULL, 0, mode);  /* null pointer or tarval_bad */
Christian Schäfer's avatar
Christian Schäfer committed
343

344
    default:
345
      assert(0 && "unsupported mode sort");
Christian Schäfer's avatar
Christian Schäfer committed
346
  }
Michael Beck's avatar
Michael Beck committed
347
  return NULL;
Christian Schäfer's avatar
Christian Schäfer committed
348
}
Michael Beck's avatar
Michael Beck committed
349

350
/* returns non-zero if can be converted to long */
351
352
int tarval_is_long(tarval *tv)
{
353
354
  mode_sort sort = get_mode_sort(tv->mode);

355
  ANNOUNCE();
356
  if (sort != irms_int_number && sort != irms_character) return 0;
357
358
359
360

  if (get_mode_size_bits(tv->mode) > sizeof(long)<<3)
  {
    /* the value might be too big to fit in a long */
361
    sc_max_from_bits(sizeof(long)<<3, 0, NULL);
362
363
364
365
366
367
368
    if (sc_comp(sc_get_buffer(), tv->value) == -1)
    {
      /* really doesn't fit */
      return 0;
    }
  }
  return 1;
369
}
Michael Beck's avatar
Michael Beck committed
370
371

/* this might overflow the machine's long, so use only with small values */
372
long get_tarval_long(tarval* tv)
373
374
{
  ANNOUNCE();
375
  assert(tarval_is_long(tv) && "tarval too big to fit in long");
Christian Schäfer's avatar
Christian Schäfer committed
376

377
  return sc_val_to_long(tv->value);
378
}
Christian Schäfer's avatar
Christian Schäfer committed
379

380
tarval *new_tarval_from_double(long double d, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
381
{
382
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
383
  assert(mode && (get_mode_sort(mode) == irms_float_number));
384

385
386
387
388
389
390
391
392
393
394
395
  switch (get_mode_size_bits(mode)) {
    case 32:
      fc_val_from_float(d, 8, 23, NULL);
      break;
    case 64:
      fc_val_from_float(d, 11, 52, NULL);
      break;
    case 80:
      fc_val_from_float(d, 15, 64, NULL);
      break;
  }
396
  return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
397
}
Michael Beck's avatar
Michael Beck committed
398

399
/* returns non-zero if can be converted to double */
400
401
402
403
int tarval_is_double(tarval *tv)
{
  ANNOUNCE();
  assert(tv);
Christian Schäfer's avatar
Christian Schäfer committed
404

Michael Beck's avatar
Michael Beck committed
405
  return (get_mode_sort(tv->mode) == irms_float_number);
406
}
Michael Beck's avatar
Michael Beck committed
407

408
long double get_tarval_double(tarval *tv)
409
410
411
{
  ANNOUNCE();
  assert(tarval_is_double(tv));
Christian Schäfer's avatar
Christian Schäfer committed
412

413
414
  return fc_val_to_float(tv->value);
}
Christian Schäfer's avatar
Christian Schäfer committed
415

Matthias Heil's avatar
Matthias Heil committed
416

417
418
419
/*
 * Access routines for tarval fields ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
420

Michael Beck's avatar
Michael Beck committed
421
422
423
/* get the mode of the tarval */
ir_mode *(get_tarval_mode)(const tarval *tv) {
  return _get_tarval_mode(tv);
424
425
}

426
427
428
429
430
431
432
433
434
/*
 * Special value query functions ============================================
 *
 * These functions calculate and return a tarval representing the requested
 * value.
 * The functions get_mode_{Max,Min,...} return tarvals retrieved from these
 * functions, but these are stored on initialization of the irmode module and
 * therefore the irmode functions should be prefered to the functions below.
 */
Christian Schäfer's avatar
Christian Schäfer committed
435

Michael Beck's avatar
Michael Beck committed
436
437
tarval *(get_tarval_bad)(void) {
  return _get_tarval_bad();
438
}
Michael Beck's avatar
Michael Beck committed
439
440
441

tarval *(get_tarval_undefined)(void) {
  return _get_tarval_undefined();
442
}
Michael Beck's avatar
Michael Beck committed
443
444
445

tarval *(get_tarval_b_false)(void) {
  return _get_tarval_b_false();
446
}
Michael Beck's avatar
Michael Beck committed
447
448
449

tarval *(get_tarval_b_true)(void) {
  return _get_tarval_b_true();
450
}
Michael Beck's avatar
Michael Beck committed
451
452
453

tarval *(get_tarval_P_void)(void) {
  return _get_tarval_P_void();
Christian Schäfer's avatar
Christian Schäfer committed
454
455
}

456
tarval *get_tarval_max(ir_mode *mode)
457
{
458
459
  ANNOUNCE();
  assert(mode);
460

461
  if (get_mode_n_vector_elems(mode) > 1) {
462
463
464
465
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

466
467
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
468
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
469
470
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
471
    case irms_auxiliary:
472
473
      assert(0);
      break;
474

Michael Beck's avatar
Michael Beck committed
475
    case irms_internal_boolean:
476
      return tarval_b_true;
477

Michael Beck's avatar
Michael Beck committed
478
    case irms_float_number:
479
480
481
482
483
484
485
486
487
488
489
490
      switch(get_mode_size_bits(mode))
      {
        case 32:
          fc_get_max(8, 23, NULL);
          break;
        case 64:
          fc_get_max(11, 52, NULL);
          break;
        case 80:
          fc_get_max(15, 64, NULL);
          break;
      }
491
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
492

Michael Beck's avatar
Michael Beck committed
493
494
    case irms_int_number:
    case irms_character:
495
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
496
497
498
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
499
500
}

501
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
502
{
503
504
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
505

506
  if (get_mode_n_vector_elems(mode) > 1) {
507
508
509
510
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

511
512
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
513
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
514
515
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
516
    case irms_auxiliary:
517
518
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
519

Michael Beck's avatar
Michael Beck committed
520
    case irms_internal_boolean:
521
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
522

Michael Beck's avatar
Michael Beck committed
523
    case irms_float_number:
524
525
526
527
528
529
530
531
532
533
534
535
      switch(get_mode_size_bits(mode))
      {
        case 32:
          fc_get_min(8, 23, NULL);
          break;
        case 64:
          fc_get_min(11, 52, NULL);
          break;
        case 80:
          fc_get_min(15, 64, NULL);
          break;
      }
536
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
537

Michael Beck's avatar
Michael Beck committed
538
539
    case irms_int_number:
    case irms_character:
540
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
541
542
543
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
544
545
}

546
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
547
{
548
549
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
550

551
  if (get_mode_n_vector_elems(mode) > 1) {
552
553
554
555
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

556
557
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
558
559
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
560
561
    case irms_auxiliary:
    case irms_internal_boolean:
562
563
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
564

Michael Beck's avatar
Michael Beck committed
565
    case irms_float_number:
566
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
567

Michael Beck's avatar
Michael Beck committed
568
569
    case irms_int_number:
    case irms_character:
570
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
571

Michael Beck's avatar
Michael Beck committed
572
    case irms_reference:
573
574
575
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
576
577
}

578
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
579
{
580
581
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
582

583
  if (get_mode_n_vector_elems(mode) > 1) {
584
585
586
587
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

588
589
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
590
591
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
592
593
594
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
595
596
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
597

Michael Beck's avatar
Michael Beck committed
598
    case irms_float_number:
599
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
600

Michael Beck's avatar
Michael Beck committed
601
602
    case irms_int_number:
    case irms_character:
603
604
605
606
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
607
608
}

609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
tarval *get_tarval_minus_one(ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);

  if (get_mode_n_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

  switch(get_mode_sort(mode))
  {
    case irms_control_flow:
    case irms_memory:
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
      assert(0);
      break;

    case irms_float_number:
      return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;

    case irms_int_number:
    case irms_character:
      return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
  }
  return tarval_bad;
}

639
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
640
{
641
642
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
643

644
  if (get_mode_n_vector_elems(mode) > 1) {
645
646
647
648
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
649
  if (get_mode_sort(mode) == irms_float_number) {
650
651
652
653
654
655
656
657
658
659
660
661
    switch(get_mode_size_bits(mode))
    {
      case 32:
        fc_get_qnan(8, 23, NULL);
        break;
      case 64:
        fc_get_qnan(11, 52, NULL);
        break;
      case 80:
        fc_get_qnan(15, 64, NULL);
        break;
    }
662
663
664
665
666
667
    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
  }
  else {
    assert(0 && "tarval is not floating point");
    return tarval_bad;
  }
Christian Schäfer's avatar
Christian Schäfer committed
668
669
}

670
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
671
{
672
673
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
674

675
  if (get_mode_n_vector_elems(mode) > 1) {
676
677
678
679
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
680
  if (get_mode_sort(mode) == irms_float_number) {
681
682
683
684
685
686
687
688
689
690
691
692
    switch(get_mode_size_bits(mode))
    {
      case 32:
        fc_get_plusinf(8, 23, NULL);
        break;
      case 64:
        fc_get_plusinf(11, 52, NULL);
        break;
      case 80:
        fc_get_plusinf(15, 64, NULL);
        break;
    }
693
694
695
696
697
698
    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
  }
  else {
    assert(0 && "tarval is not floating point");
    return tarval_bad;
  }
Christian Schäfer's avatar
Christian Schäfer committed
699
700
}

701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
tarval *get_tarval_minus_inf(ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);

  if (get_mode_n_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

  if (get_mode_sort(mode) == irms_float_number) {
    switch(get_mode_size_bits(mode))
    {
    case 32:
      fc_get_minusinf(8, 23, NULL);
      break;
    case 64:
      fc_get_minusinf(11, 52, NULL);
      break;
    case 80:
      fc_get_minusinf(15, 64, NULL);
      break;
    }
    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
  }
  else {
    assert(0 && "tarval is not floating point");
    return tarval_bad;
  }
}

732
733
734
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
735

Michael Beck's avatar
Michael Beck committed
736
737
738
/*
 * test if negative number, 1 means 'yes'
 */
739
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
740
{
741
742
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
743

744
  if (get_mode_n_vector_elems(a->mode) > 1) {
745
746
747
748
749
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

750
751
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
752
    case irms_int_number:
753
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
754
      else
755
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
756

Michael Beck's avatar
Michael Beck committed
757
    case irms_float_number:
Michael Beck's avatar
Michael Beck committed
758
      return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
759

760
761
    default:
      assert(0 && "not implemented");
762
      return 0;
763
  }
Christian Schäfer's avatar
Christian Schäfer committed
764
765
}

Michael Beck's avatar
Michael Beck committed
766
767
768
769
770
771
772
773
774
775
/*
 * test if null, 1 means 'yes'
 */
int tarval_is_null(tarval *a)
{
  ir_mode *m = get_tarval_mode(a);

  return a == get_tarval_null(m);
}

Michael Beck's avatar
Michael Beck committed
776
777
778
779
780
781
782
783
784
785
/*
 * test if one, 1 means 'yes'
 */
int tarval_is_one(tarval *a)
{
  ir_mode *m = get_tarval_mode(a);

  return a == get_tarval_one(m);
}

Michael Beck's avatar
Michael Beck committed
786
787
788
/*
 * comparison
 */
789
pn_Cmp tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
790
{
791
792
793
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
794

795
796
797
798
799
800
801
802
803
804
  if (a == tarval_bad || b == tarval_bad) {
    assert(0 && "Comparison with tarval_bad");
    return pn_Cmp_False;
  }

  if (a == tarval_undefined || b == tarval_undefined)
    return pn_Cmp_False;

  if (a->mode != b->mode)
    return pn_Cmp_False;
805

806
  if (get_mode_n_vector_elems(a->mode) > 1) {
807
808
809
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
810

811
812
813
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
814
815
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
816
    case irms_auxiliary:
817
    case irms_reference:
818
819
      if (a == b)
        return pn_Cmp_Eq;
820
      return pn_Cmp_False;
Christian Schäfer's avatar
Christian Schäfer committed
821

Michael Beck's avatar
Michael Beck committed
822
    case irms_float_number:
823
824
825
826
      /*
       * BEWARE: we cannot compare a == b here, because
       * a NaN is always Unordered to any other value, even to itself!
       */
827
      switch (fc_comp(a->value, b->value)) {
828
        case -1: return pn_Cmp_Lt;
829
        case  0: return pn_Cmp_Eq;
830
831
832
        case  1: return pn_Cmp_Gt;
        case  2: return pn_Cmp_Uo;
        default: return pn_Cmp_False;
833
      }
Michael Beck's avatar
Michael Beck committed
834
835
    case irms_int_number:
    case irms_character:
836
837
      if (a == b)
        return pn_Cmp_Eq;
838
      return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
Christian Schäfer's avatar
Christian Schäfer committed
839

Michael Beck's avatar
Michael Beck committed
840
    case irms_internal_boolean:
841
842
      if (a == b)
        return pn_Cmp_Eq;
843
      return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
844
  }
845
  return pn_Cmp_False;
846
847
}

Michael Beck's avatar
Michael Beck committed
848
849
850
/*
 * convert to other mode
 */
851
852
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
853
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
854

Till Riedel's avatar
Till Riedel committed
855
  ANNOUNCE();
856
857
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
858

859
860
  if (src->mode == m) return src;

861
  if (get_mode_n_vector_elems(src->mode) > 1) {
862
863
864
865
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

866
867
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
868
869
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
870
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
871
872
      break;

873
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
874
    case irms_float_number:
875
      switch (get_mode_sort(m)) {
876
        case irms_float_number:
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
          switch (get_mode_size_bits(m))
          {
            case 32:
              fc_cast(src->value, 8, 23, NULL);
              break;
            case 64:
              fc_cast(src->value, 11, 52, NULL);
              break;
            case 80:
              fc_cast(src->value, 15, 64, NULL);
              break;
            default:
              break;
          }
          return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);
892

893
894
895
896
897
898
899
900
901
902
        case irms_int_number:
          switch (GET_FLOAT_TO_INT_MODE())
          {
            case TRUNCATE:
              fc_int(src->value, NULL);
              break;
            case ROUND:
              fc_rnd(src->value, NULL);
              break;
            default:
903
              assert(0);
904
905
              break;
          }
906
          /* FIXME: floating point unit can't produce a value in integer
907
908
909
910
911
912
913
914
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
915
      }
Christian Schäfer's avatar
Christian Schäfer committed
916
917
      break;

918
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
919
    case irms_int_number:
920
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
921
922
        case irms_int_number:
        case irms_character:
923
          return get_tarval_overflow(src->value, src->length, m);
924

Michael Beck's avatar
Michael Beck committed
925
        case irms_internal_boolean:
926
927
928
929
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
        case irms_float_number:
          /* XXX floating point unit does not understand internal integer
           * representation, convert to string first, then create float from
           * string */
          buffer = alloca(100);
          /* decimal string representation because hexadecimal output is
           * interpreted unsigned by fc_val_from_str, so this is a HACK */
          snprintf(buffer, 100, "%s",
                   sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC));
          switch (get_mode_size_bits(m))
          {
            case 32:
              fc_val_from_str(buffer, 0, 8, 23, NULL);
              break;
            case 64:
              fc_val_from_str(buffer, 0, 11, 52, NULL);
              break;
            case 80:
              fc_val_from_str(buffer, 0, 15, 64, NULL);
              break;
          }
          return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m);

953
954
955
956
957
958
959
#if 0
        case irms_reference:
          /* allow 0 to be casted */
          if (src == get_mode_null(src->mode))
            return get_mode_null(m);
          break;
#endif
960
961
962
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
963
964
      break;

Michael Beck's avatar
Michael Beck committed
965
    case irms_internal_boolean:
966
967
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
968
        case irms_int_number:
969
970
          if (src == tarval_b_true) return get_mode_one(m);
          else return get_mode_null(m);
Christian Schäfer's avatar
Christian Schäfer committed
971

972
973
974
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
975
976
      break;

Michael Beck's avatar
Michael Beck committed
977
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
978
      break;
Michael Beck's avatar
Michael Beck committed
979
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
980
      break;
981
  }
Christian Schäfer's avatar
Christian Schäfer committed
982

983
984
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
985

Michael Beck's avatar
Michael Beck committed
986
/*
987
988
989
990
991
992
993
994
995
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

  ANNOUNCE();
  assert(a);

996
997
  /* works for vector mode without changes */

998
999
1000
  switch (get_mode_sort(a->mode))
  {
    case irms_int_number:
For faster browsing, not all history is shown. View entire blame