tv.c 41.1 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
37
#include <stdlib.h>
Boris Boesler's avatar
Boris Boesler committed
38
#ifdef HAVE_ALLOCA_H
Boris Boesler's avatar
Boris Boesler committed
39
40
# include <alloca.h>
#endif
41
42
43
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
44

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

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

58
59
/* get the integer overflow mode */
#define GET_OVERFLOW_MODE() int_overflow_mode
60
61
62
63
64
65
66
67
68

/* unused, float to int doesn't work yet */
#define TRUNCATE 1
#define ROUND 2
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

69
70
71
72
73
74
75
76
/****************************************************************************
 *   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
77

78
79
#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))))
80

81
82
#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)))
83

84
85
86
87
88
89
90
91
92
93
94
95
#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 */
96
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
97
98
99
100
101
102
103
104

/****************************************************************************
 *   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
105
{
106
107
108
109
110
111
  /* 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
112
}
Till Riedel's avatar
Till Riedel committed
113
114
115
#ifdef __GNUC__
INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
#endif
Christian Schäfer's avatar
Christian Schäfer committed
116

Till Riedel's avatar
Till Riedel committed
117
INLINE static void tarval_verify(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
118
{
119
120
121
  assert(tv);
  assert(tv->mode);
  assert(tv->value);
Christian Schäfer's avatar
Christian Schäfer committed
122

123
124
125
126
127
128
129
  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
130
}
131
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
132

133
static int hash_tv(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
134
{
135
  return ((unsigned int)tv->value ^ (unsigned int)tv->mode) + tv->length;
Christian Schäfer's avatar
Christian Schäfer committed
136
137
}

138
static int hash_val(const void *value, unsigned int length)
Christian Schäfer's avatar
Christian Schäfer committed
139
{
140
141
142
143
144
145
146
147
148
149
150
  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
151
152
}

Matthias Heil's avatar
Matthias Heil committed
153
/* finds tarval with value/mode or creates new tarval */
154
static tarval *get_tarval(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
155
{
156
157
158
159
  tarval tv;

  tv.mode = mode;
  tv.length = length;
160
  if (length > 0) {
161
162
163
    /* if there already is such a value, it is returned, else value
     * is copied into the set */
    tv.value = INSERT_VALUE(value, length);
164
  } else {
165
    tv.value = value;
166
  }
167
168
169
  /* 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
170
171
}

172
173
174
/**
 * handle overflow
 */
175
static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
176
{
177
  switch (get_mode_sort(mode))
178
  {
Michael Beck's avatar
Michael Beck committed
179
    case irms_int_number:
180
181
      if (sc_comp(value, get_mode_max(mode)->value) == 1) {
        switch (GET_OVERFLOW_MODE()) {
182
          case TV_OVERFLOW_SATURATE:
183
            return get_mode_max(mode);
184
          case TV_OVERFLOW_WRAP:
185
186
187
188
189
190
191
192
193
194
195
            {
              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);
            }
196
          case TV_OVERFLOW_BAD:
197
198
199
200
201
202
203
            return tarval_bad;
          default:
            return get_tarval(value, length, mode);
        }
      }
      if (sc_comp(value, get_mode_min(mode)->value) == -1) {
        switch (GET_OVERFLOW_MODE()) {
204
          case TV_OVERFLOW_SATURATE:
205
            return get_mode_min(mode);
206
          case TV_OVERFLOW_WRAP:
207
208
209
210
211
212
213
214
215
216
217
            {
              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);
            }
218
          case TV_OVERFLOW_BAD:
219
220
221
222
223
            return tarval_bad;
          default:
            return get_tarval(value, length, mode);
        }
      }
224
      break;
Christian Schäfer's avatar
Christian Schäfer committed
225

Michael Beck's avatar
Michael Beck committed
226
    case irms_float_number:
227
228
229
230
      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
231

232
233
234
235
236
      if (SWITCH_NODENORMALS && fc_is_subnormal(value))
      {
        return get_mode_null(mode);
      }
      break;
237
238
239
    default:
      break;
  }
240
  return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
241
242
}

243

244
/*
245
 *   public variables declared in tv.h
246
 */
247
248
249
250
251
252
253
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
254

255
/*
256
 *   public functions declared in tv.h
257
258
 */

259
260
261
262
263
264
265
266
267
268
269
270
/*
 * 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
271
272
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
273
    case irms_auxiliary:
274
275
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
276

Michael Beck's avatar
Michael Beck committed
277
    case irms_internal_boolean:
278
      /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
Michael Beck's avatar
Michael Beck committed
279
280
281
      if (strcasecmp(str, "true")) return tarval_b_true;
      else if (strcasecmp(str, "false")) return tarval_b_true;
      else
282
        /* XXX This is C semantics */
283
    return atoi(str) ? tarval_b_true : tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
284

Michael Beck's avatar
Michael Beck committed
285
    case irms_float_number:
286
287
288
289
290
291
292
293
294
295
296
      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;
      }
297
298
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);

Michael Beck's avatar
Michael Beck committed
299
300
    case irms_int_number:
    case irms_character:
301
      sc_val_from_str(str, len, NULL);
302
303
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);

Michael Beck's avatar
Michael Beck committed
304
    case irms_reference:
305
      return get_tarval(str, len, mode);
Christian Schäfer's avatar
Christian Schäfer committed
306
307
  }

308
  assert(0);  /* can't be reached, can it? */
309
  return NULL;
310
}
Christian Schäfer's avatar
Christian Schäfer committed
311

312
/*
313
 * helper function, create a tarval from long
314
 */
315
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
316
{
317
  ANNOUNCE();
Till Riedel's avatar
Till Riedel committed
318
  assert(mode && !((get_mode_sort(mode) == irms_memory)||(get_mode_sort(mode)==irms_control_flow)||(get_mode_sort(mode)==irms_auxiliary)));
Christian Schäfer's avatar
Christian Schäfer committed
319

320
321
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
322
    case irms_internal_boolean:
323
      /* XXX C semantics ! */
Michael Beck's avatar
Michael Beck committed
324
      return l ? tarval_b_true : tarval_b_false ;
Christian Schäfer's avatar
Christian Schäfer committed
325

Michael Beck's avatar
Michael Beck committed
326
327
    case irms_int_number:
    case irms_character:
328
      sc_val_from_long(l, NULL);
329
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
330

Michael Beck's avatar
Michael Beck committed
331
    case irms_float_number:
332
      return new_tarval_from_double((long double)l, mode);
Christian Schäfer's avatar
Christian Schäfer committed
333

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

337
338
    default:
      assert(0);
Christian Schäfer's avatar
Christian Schäfer committed
339
  }
Michael Beck's avatar
Michael Beck committed
340
  return NULL;
Christian Schäfer's avatar
Christian Schäfer committed
341
}
Michael Beck's avatar
Michael Beck committed
342

343
/* returns non-zero if can be converted to long */
344
345
346
int tarval_is_long(tarval *tv)
{
  ANNOUNCE();
347
348
349
350
351
  if (get_mode_sort(tv->mode) != irms_int_number) return 0;

  if (get_mode_size_bits(tv->mode) > sizeof(long)<<3)
  {
    /* the value might be too big to fit in a long */
352
    sc_max_from_bits(sizeof(long)<<3, 0, NULL);
353
354
355
356
357
358
359
    if (sc_comp(sc_get_buffer(), tv->value) == -1)
    {
      /* really doesn't fit */
      return 0;
    }
  }
  return 1;
360
}
Michael Beck's avatar
Michael Beck committed
361
362

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

368
  return sc_val_to_long(tv->value);
369
}
Christian Schäfer's avatar
Christian Schäfer committed
370

371
tarval *new_tarval_from_double(long double d, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
372
{
373
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
374
  assert(mode && (get_mode_sort(mode) == irms_float_number));
375

376
377
378
379
380
381
382
383
384
385
386
  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;
  }
387
  return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
388
}
Michael Beck's avatar
Michael Beck committed
389

390
/* returns non-zero if can be converted to double */
391
392
393
394
int tarval_is_double(tarval *tv)
{
  ANNOUNCE();
  assert(tv);
Christian Schäfer's avatar
Christian Schäfer committed
395

Michael Beck's avatar
Michael Beck committed
396
  return (get_mode_sort(tv->mode) == irms_float_number);
397
}
Michael Beck's avatar
Michael Beck committed
398

399
long double get_tarval_double(tarval *tv)
400
401
402
{
  ANNOUNCE();
  assert(tarval_is_double(tv));
Christian Schäfer's avatar
Christian Schäfer committed
403

404
405
  return fc_val_to_float(tv->value);
}
Christian Schäfer's avatar
Christian Schäfer committed
406

Matthias Heil's avatar
Matthias Heil committed
407

408
409
410
/*
 * Access routines for tarval fields ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
411

Michael Beck's avatar
Michael Beck committed
412
413
414
/* get the mode of the tarval */
ir_mode *(get_tarval_mode)(const tarval *tv) {
  return _get_tarval_mode(tv);
415
416
}

417
418
419
420
421
422
423
424
425
/*
 * 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
426

Michael Beck's avatar
Michael Beck committed
427
428
tarval *(get_tarval_bad)(void) {
  return _get_tarval_bad();
429
}
Michael Beck's avatar
Michael Beck committed
430
431
432

tarval *(get_tarval_undefined)(void) {
  return _get_tarval_undefined();
433
}
Michael Beck's avatar
Michael Beck committed
434
435
436

tarval *(get_tarval_b_false)(void) {
  return _get_tarval_b_false();
437
}
Michael Beck's avatar
Michael Beck committed
438
439
440

tarval *(get_tarval_b_true)(void) {
  return _get_tarval_b_true();
441
}
Michael Beck's avatar
Michael Beck committed
442
443
444

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

447
tarval *get_tarval_max(ir_mode *mode)
448
{
449
450
  ANNOUNCE();
  assert(mode);
451

452
  if (get_mode_n_vector_elems(mode) > 1) {
453
454
455
456
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

457
458
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
459
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
460
461
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
462
    case irms_auxiliary:
463
464
      assert(0);
      break;
465

Michael Beck's avatar
Michael Beck committed
466
    case irms_internal_boolean:
467
      return tarval_b_true;
468

Michael Beck's avatar
Michael Beck committed
469
    case irms_float_number:
470
471
472
473
474
475
476
477
478
479
480
481
      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;
      }
482
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
483

Michael Beck's avatar
Michael Beck committed
484
485
    case irms_int_number:
    case irms_character:
486
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
487
488
489
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
490
491
}

492
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
493
{
494
495
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
496

497
  if (get_mode_n_vector_elems(mode) > 1) {
498
499
500
501
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

502
503
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
504
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
505
506
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
507
    case irms_auxiliary:
508
509
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
510

Michael Beck's avatar
Michael Beck committed
511
    case irms_internal_boolean:
512
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
513

Michael Beck's avatar
Michael Beck committed
514
    case irms_float_number:
515
516
517
518
519
520
521
522
523
524
525
526
      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;
      }
527
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
528

Michael Beck's avatar
Michael Beck committed
529
530
    case irms_int_number:
    case irms_character:
531
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
532
533
534
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
535
536
}

537
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
538
{
539
540
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
541

542
  if (get_mode_n_vector_elems(mode) > 1) {
543
544
545
546
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

547
548
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
549
550
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
551
552
    case irms_auxiliary:
    case irms_internal_boolean:
553
554
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
555

Michael Beck's avatar
Michael Beck committed
556
    case irms_float_number:
557
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
558

Michael Beck's avatar
Michael Beck committed
559
560
    case irms_int_number:
    case irms_character:
561
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
562

Michael Beck's avatar
Michael Beck committed
563
    case irms_reference:
564
565
566
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
567
568
}

569
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
570
{
571
572
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
573

574
  if (get_mode_n_vector_elems(mode) > 1) {
575
576
577
578
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

579
580
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
581
582
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
583
584
585
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
586
587
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
588

Michael Beck's avatar
Michael Beck committed
589
    case irms_float_number:
590
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
591

Michael Beck's avatar
Michael Beck committed
592
593
    case irms_int_number:
    case irms_character:
594
595
596
597
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
598
599
}

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
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;
}

630
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
631
{
632
633
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
634

635
  if (get_mode_n_vector_elems(mode) > 1) {
636
637
638
639
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
640
  if (get_mode_sort(mode) == irms_float_number) {
641
642
643
644
645
646
647
648
649
650
651
652
    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;
    }
653
654
655
656
657
658
    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
659
660
}

661
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
662
{
663
664
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
665

666
  if (get_mode_n_vector_elems(mode) > 1) {
667
668
669
670
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
671
  if (get_mode_sort(mode) == irms_float_number) {
672
673
674
675
676
677
678
679
680
681
682
683
    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;
    }
684
685
686
687
688
689
    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
690
691
}

692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
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;
  }
}

723
724
725
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
726

Michael Beck's avatar
Michael Beck committed
727
728
729
/*
 * test if negative number, 1 means 'yes'
 */
730
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
731
{
732
733
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
734

735
  if (get_mode_n_vector_elems(a->mode) > 1) {
736
737
738
739
740
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

741
742
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
743
    case irms_int_number:
744
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
745
      else
746
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
747

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

751
752
    default:
      assert(0 && "not implemented");
753
      return 0;
754
  }
Christian Schäfer's avatar
Christian Schäfer committed
755
756
}

Michael Beck's avatar
Michael Beck committed
757
758
759
760
761
762
763
764
765
766
/*
 * 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
767
768
769
770
771
772
773
774
775
776
/*
 * 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
777
778
779
/*
 * comparison
 */
780
pn_Cmp tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
781
{
782
783
784
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
785

786
  if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
787
788
789
  if (a == tarval_undefined || b == tarval_undefined) return pn_Cmp_False;
  if (a == b) return pn_Cmp_Eq;
  if (a->mode != b->mode) return pn_Cmp_False;
790

791
  if (get_mode_n_vector_elems(a->mode) > 1) {
792
793
794
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
795

796
797
798
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
799
800
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
801
    case irms_auxiliary:
802
    case irms_reference:
803
      return pn_Cmp_False;
Christian Schäfer's avatar
Christian Schäfer committed
804

Michael Beck's avatar
Michael Beck committed
805
    case irms_float_number:
806
      switch (fc_comp(a->value, b->value)) {
807
808
809
810
811
        case -1: return pn_Cmp_Lt;
        case  0: assert(0 && "different tarvals compare equal"); return pn_Cmp_Eq;
        case  1: return pn_Cmp_Gt;
        case  2: return pn_Cmp_Uo;
        default: return pn_Cmp_False;
812
      }
Michael Beck's avatar
Michael Beck committed
813
814
    case irms_int_number:
    case irms_character:
815
      return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
Christian Schäfer's avatar
Christian Schäfer committed
816

Michael Beck's avatar
Michael Beck committed
817
    case irms_internal_boolean:
818
      return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
819
  }
820
  return pn_Cmp_False;
821
822
}

Michael Beck's avatar
Michael Beck committed
823
824
825
/*
 * convert to other mode
 */
826
827
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
828
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
829

Till Riedel's avatar
Till Riedel committed
830
  ANNOUNCE();
831
832
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
833

834
835
  if (src->mode == m) return src;

836
  if (get_mode_n_vector_elems(src->mode) > 1) {
837
838
839
840
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

841
842
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
843
844
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
845
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
846
847
      break;

848
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
849
    case irms_float_number:
850
      switch (get_mode_sort(m)) {
851
        case irms_float_number:
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
          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);
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
        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:
              break;
          }
          /* XXX floating point unit can't produce a value in integer
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
889
      }
Christian Schäfer's avatar
Christian Schäfer committed
890
891
      break;

892
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
893
    case irms_int_number:
894
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
895
896
        case irms_int_number:
        case irms_character:
897
          return get_tarval_overflow(src->value, src->length, m);
898

Michael Beck's avatar
Michael Beck committed
899
        case irms_internal_boolean:
900
901
902
903
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
        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);

927
928
929
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
930
931
      break;

Michael Beck's avatar
Michael Beck committed
932
    case irms_internal_boolean:
933
934
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
935
        case irms_int_number:
936
937
          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
938

939
940
941
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
942
943
      break;

Michael Beck's avatar
Michael Beck committed
944
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
945
      break;
Michael Beck's avatar
Michael Beck committed
946
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
947
      break;
948
  }
Christian Schäfer's avatar
Christian Schäfer committed
949

950
951
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
952

Michael Beck's avatar
Michael Beck committed
953
/*
954
955
956
957
958
959
960
961
962
963
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

  ANNOUNCE();
  assert(a);
  assert(mode_is_int(a->mode)); /* bitwise negation is only allowed for integer */

964
965
  /* works for vector mode without changes */

966
967
968
969
970
971
972
973
974
975
976
977
978
979
  switch (get_mode_sort(a->mode))
  {
    case irms_int_number:
      buffer = alloca(sc_get_buffer_length());
      sc_not(a->value, buffer);
      return get_tarval(buffer, a->length, a->mode);

    default:
      return tarval_bad;
  }
}

/*
 * arithmetic negation
Michael Beck's avatar
Michael Beck committed
980
981
 */
tarval *tarval_neg(tarval *a)
982
{
983
984
  char *buffer;

985
986
987
  ANNOUNCE();
  assert(a);
  assert(mode_is_num(a->mode)); /* negation only for numerical values */
988
989

  /* note: negation is allowed even for unsigned modes. */
Christian Schäfer's avatar
Christian Schäfer committed
990

991
  if (get_mode_n_vector_elems(a->mode) > 1) {
992
993
994
995
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

996
997
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
998
    case irms_int_number:
999
1000
      buffer = alloca(sc_get_buffer_length());
      sc_neg(a->value, buffer);
For faster browsing, not all history is shown. View entire blame