tv.c 41.3 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
47
#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
48
#include "irmode_t.h"
49
#include "irnode.h"         /* defines boolean return values (pnc_number)*/
50
51
#include "strcalc.h"
#include "fltcalc.h"
Christian Schäfer's avatar
Christian Schäfer committed
52

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

57
58
/* get the integer overflow mode */
#define GET_OVERFLOW_MODE() int_overflow_mode
59
60

/* unused, float to int doesn't work yet */
61
62
63
64
65
enum float_to_int_mode {
  TRUNCATE,
  ROUND
};

66
67
68
69
70
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

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

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

83
84
#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)))
85

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

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

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

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

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

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

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

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

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

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

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

245

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

257
/*
258
 *   public functions declared in tv.h
259
260
 */

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

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

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

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

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

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

314
/*
315
 * helper function, create a tarval from long
316
 */
317
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
318
{
319
  ANNOUNCE();
320
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
321

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

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

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

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

339
    default:
340
      assert(0 && "unsupported mode sort");
Christian Schäfer's avatar
Christian Schäfer committed
341
  }
Michael Beck's avatar
Michael Beck committed
342
  return NULL;
Christian Schäfer's avatar
Christian Schäfer committed
343
}
Michael Beck's avatar
Michael Beck committed
344

345
/* returns non-zero if can be converted to long */
346
347
int tarval_is_long(tarval *tv)
{
348
349
  mode_sort sort = get_mode_sort(tv->mode);

350
  ANNOUNCE();
351
  if (sort != irms_int_number && sort != irms_character) return 0;
352
353
354
355

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

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

372
  return sc_val_to_long(tv->value);
373
}
Christian Schäfer's avatar
Christian Schäfer committed
374

375
tarval *new_tarval_from_double(long double d, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
376
{
377
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
378
  assert(mode && (get_mode_sort(mode) == irms_float_number));
379

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

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

Michael Beck's avatar
Michael Beck committed
400
  return (get_mode_sort(tv->mode) == irms_float_number);
401
}
Michael Beck's avatar
Michael Beck committed
402

403
long double get_tarval_double(tarval *tv)
404
405
406
{
  ANNOUNCE();
  assert(tarval_is_double(tv));
Christian Schäfer's avatar
Christian Schäfer committed
407

408
409
  return fc_val_to_float(tv->value);
}
Christian Schäfer's avatar
Christian Schäfer committed
410

Matthias Heil's avatar
Matthias Heil committed
411

412
413
414
/*
 * Access routines for tarval fields ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
415

Michael Beck's avatar
Michael Beck committed
416
417
418
/* get the mode of the tarval */
ir_mode *(get_tarval_mode)(const tarval *tv) {
  return _get_tarval_mode(tv);
419
420
}

421
422
423
424
425
426
427
428
429
/*
 * 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
430

Michael Beck's avatar
Michael Beck committed
431
432
tarval *(get_tarval_bad)(void) {
  return _get_tarval_bad();
433
}
Michael Beck's avatar
Michael Beck committed
434
435
436

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

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

tarval *(get_tarval_b_true)(void) {
  return _get_tarval_b_true();
445
}
Michael Beck's avatar
Michael Beck committed
446
447
448

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

451
tarval *get_tarval_max(ir_mode *mode)
452
{
453
454
  ANNOUNCE();
  assert(mode);
455

456
  if (get_mode_n_vector_elems(mode) > 1) {
457
458
459
460
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

461
462
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
463
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
464
465
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
466
    case irms_auxiliary:
467
468
      assert(0);
      break;
469

Michael Beck's avatar
Michael Beck committed
470
    case irms_internal_boolean:
471
      return tarval_b_true;
472

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

Michael Beck's avatar
Michael Beck committed
488
489
    case irms_int_number:
    case irms_character:
490
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
491
492
493
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
494
495
}

496
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
497
{
498
499
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
500

501
  if (get_mode_n_vector_elems(mode) > 1) {
502
503
504
505
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

Michael Beck's avatar
Michael Beck committed
515
    case irms_internal_boolean:
516
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
517

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

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

541
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
542
{
543
544
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
545

546
  if (get_mode_n_vector_elems(mode) > 1) {
547
548
549
550
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

Michael Beck's avatar
Michael Beck committed
560
    case irms_float_number:
561
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
562

Michael Beck's avatar
Michael Beck committed
563
564
    case irms_int_number:
    case irms_character:
565
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
566

Michael Beck's avatar
Michael Beck committed
567
    case irms_reference:
568
569
570
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
571
572
}

573
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
574
{
575
576
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
577

578
  if (get_mode_n_vector_elems(mode) > 1) {
579
580
581
582
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

Michael Beck's avatar
Michael Beck committed
593
    case irms_float_number:
594
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
595

Michael Beck's avatar
Michael Beck committed
596
597
    case irms_int_number:
    case irms_character:
598
599
600
601
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
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
630
631
632
633
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;
}

634
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
635
{
636
637
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
638

639
  if (get_mode_n_vector_elems(mode) > 1) {
640
641
642
643
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

665
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
666
{
667
668
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
669

670
  if (get_mode_n_vector_elems(mode) > 1) {
671
672
673
674
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

727
728
729
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
730

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

739
  if (get_mode_n_vector_elems(a->mode) > 1) {
740
741
742
743
744
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

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

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

755
756
    default:
      assert(0 && "not implemented");
757
      return 0;
758
  }
Christian Schäfer's avatar
Christian Schäfer committed
759
760
}

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

790
791
792
793
794
795
796
797
798
799
  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;
800

801
  if (get_mode_n_vector_elems(a->mode) > 1) {
802
803
804
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
805

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

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

Michael Beck's avatar
Michael Beck committed
835
    case irms_internal_boolean:
836
837
      if (a == b)
        return pn_Cmp_Eq;
838
      return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
839
  }
840
  return pn_Cmp_False;
841
842
}

Michael Beck's avatar
Michael Beck committed
843
844
845
/*
 * convert to other mode
 */
846
847
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
848
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
849

Till Riedel's avatar
Till Riedel committed
850
  ANNOUNCE();
851
852
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
853

854
855
  if (src->mode == m) return src;

856
  if (get_mode_n_vector_elems(src->mode) > 1) {
857
858
859
860
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

861
862
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
863
864
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
865
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
866
867
      break;

868
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
869
    case irms_float_number:
870
      switch (get_mode_sort(m)) {
871
        case irms_float_number:
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
          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);
887

888
889
890
891
892
893
894
895
896
897
        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:
898
              assert(0);
899
900
              break;
          }
901
          /* FIXME: floating point unit can't produce a value in integer
902
903
904
905
906
907
908
909
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
910
      }
Christian Schäfer's avatar
Christian Schäfer committed
911
912
      break;

913
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
914
    case irms_int_number:
915
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
916
917
        case irms_int_number:
        case irms_character:
918
          return get_tarval_overflow(src->value, src->length, m);
919

Michael Beck's avatar
Michael Beck committed
920
        case irms_internal_boolean:
921
922
923
924
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
        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);

948
949
950
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
951
952
      break;

Michael Beck's avatar
Michael Beck committed
953
    case irms_internal_boolean:
954
955
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
956
        case irms_int_number:
957
958
          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
959

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_character:
Christian Schäfer's avatar
Christian Schäfer committed
966
      break;
Michael Beck's avatar
Michael Beck committed
967
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
968
      break;
969
  }
Christian Schäfer's avatar
Christian Schäfer committed
970

971
972
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
973

Michael Beck's avatar
Michael Beck committed
974
/*
975
976
977
978
979
980
981
982
983
984
 * 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 */

985
986
  /* works for vector mode without changes */

987
988
989
990
991
992
993
994
995
996
997
998
999
1000
  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
For faster browsing, not all history is shown. View entire blame