tv.c 41.6 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 "xmalloc.h"
Michael Beck's avatar
Michael Beck committed
56
#include "firm_common.h"
Christian Schäfer's avatar
Christian Schäfer committed
57

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

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

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

71
72
73
74
75
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

76
77
78
79
80
81
82
83
/****************************************************************************
 *   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
84

85
86
#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))))
87

88
89
#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)))
90

91
92
93
94
95
96
97
98
99
100
101
102
#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 */
103
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
104
105
106
107
108
109
110
111

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

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

130
131
132
133
134
135
136
  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
137
}
138
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
139

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

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

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

Michael Beck's avatar
Michael Beck committed
165
166
  tv.kind   = k_tarval;
  tv.mode   = mode;
167
  tv.length = length;
168
  if (length > 0) {
169
170
171
    /* if there already is such a value, it is returned, else value
     * is copied into the set */
    tv.value = INSERT_VALUE(value, length);
172
  } else {
173
    tv.value = value;
174
  }
175
176
177
  /* 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
178
179
}

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

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

230
231
232
233
234
      if (SWITCH_NODENORMALS && fc_is_subnormal(value))
      {
        return get_mode_null(mode);
      }
      break;
235

236
237
238
    default:
      break;
  }
239
  return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
240
241
}

242
/*
243
 *   public variables declared in tv.h
244
 */
245
static tarval reserved_tv[4];
246
247
248
249
250

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];
Christian Schäfer's avatar
Christian Schäfer committed
251

252
/*
253
 *   public functions declared in tv.h
254
255
 */

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

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

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

296
297
    case irms_reference:
      /* same as integer modes */
Michael Beck's avatar
Michael Beck committed
298
299
    case irms_int_number:
    case irms_character:
Michael Beck's avatar
Michael Beck committed
300
      sc_val_from_str(str, len, NULL, mode);
301
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
302
303
  }

304
  assert(0);  /* can't be reached, can it? */
305
  return NULL;
306
}
Christian Schäfer's avatar
Christian Schäfer committed
307

308
/*
309
 * helper function, create a tarval from long
310
 */
311
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
312
{
313
  ANNOUNCE();
314
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
315

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

322
323
    case irms_reference:
      /* same as integer modes */
Michael Beck's avatar
Michael Beck committed
324
325
    case irms_int_number:
    case irms_character:
326
      sc_val_from_long(l, NULL);
327
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
328

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

332
    default:
333
      assert(0 && "unsupported mode sort");
Christian Schäfer's avatar
Christian Schäfer committed
334
  }
Michael Beck's avatar
Michael Beck committed
335
  return NULL;
Christian Schäfer's avatar
Christian Schäfer committed
336
}
Michael Beck's avatar
Michael Beck committed
337

338
/* returns non-zero if can be converted to long */
339
340
int tarval_is_long(tarval *tv)
{
341
342
  mode_sort sort = get_mode_sort(tv->mode);

343
  ANNOUNCE();
344
  if (sort != irms_int_number && sort != irms_character) return 0;
345
346
347
348

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

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

365
  return sc_val_to_long(tv->value);
366
}
Christian Schäfer's avatar
Christian Schäfer committed
367

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

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

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

Michael Beck's avatar
Michael Beck committed
393
  return (get_mode_sort(tv->mode) == irms_float_number);
394
}
Michael Beck's avatar
Michael Beck committed
395

396
long double get_tarval_double(tarval *tv)
397
398
399
{
  ANNOUNCE();
  assert(tarval_is_double(tv));
Christian Schäfer's avatar
Christian Schäfer committed
400

401
402
  return fc_val_to_float(tv->value);
}
Christian Schäfer's avatar
Christian Schäfer committed
403

Matthias Heil's avatar
Matthias Heil committed
404

405
406
407
/*
 * Access routines for tarval fields ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
408

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

414
415
416
417
418
419
420
421
422
/*
 * 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
423

Michael Beck's avatar
Michael Beck committed
424
425
tarval *(get_tarval_bad)(void) {
  return _get_tarval_bad();
426
}
Michael Beck's avatar
Michael Beck committed
427
428
429

tarval *(get_tarval_undefined)(void) {
  return _get_tarval_undefined();
430
}
Michael Beck's avatar
Michael Beck committed
431
432
433

tarval *(get_tarval_b_false)(void) {
  return _get_tarval_b_false();
434
}
Michael Beck's avatar
Michael Beck committed
435
436
437

tarval *(get_tarval_b_true)(void) {
  return _get_tarval_b_true();
438
}
Michael Beck's avatar
Michael Beck committed
439

440
tarval *get_tarval_max(ir_mode *mode)
441
{
442
443
  ANNOUNCE();
  assert(mode);
444

445
  if (get_mode_n_vector_elems(mode) > 1) {
446
447
448
449
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

450
451
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
452
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
453
454
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
455
    case irms_auxiliary:
456
457
      assert(0);
      break;
458

Michael Beck's avatar
Michael Beck committed
459
    case irms_internal_boolean:
460
      return tarval_b_true;
461

Michael Beck's avatar
Michael Beck committed
462
    case irms_float_number:
463
464
465
466
467
468
469
470
471
472
473
474
      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;
      }
475
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
476

Michael Beck's avatar
Michael Beck committed
477
478
    case irms_int_number:
    case irms_character:
479
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
480
481
482
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
483
484
}

485
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
486
{
487
488
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
489

490
  if (get_mode_n_vector_elems(mode) > 1) {
491
492
493
494
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

495
496
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
497
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
498
499
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
500
    case irms_auxiliary:
501
502
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
503

Michael Beck's avatar
Michael Beck committed
504
    case irms_internal_boolean:
505
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
506

Michael Beck's avatar
Michael Beck committed
507
    case irms_float_number:
508
509
510
511
512
513
514
515
516
517
518
519
      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;
      }
520
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
521

Michael Beck's avatar
Michael Beck committed
522
523
    case irms_int_number:
    case irms_character:
524
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
525
526
527
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
528
529
}

530
531
static long _null_value;

532
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
533
{
534
535
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
536

537
  if (get_mode_n_vector_elems(mode) > 1) {
538
539
540
541
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

542
543
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
544
545
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
546
547
    case irms_auxiliary:
    case irms_internal_boolean:
548
549
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
550

Michael Beck's avatar
Michael Beck committed
551
    case irms_float_number:
552
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
553

Michael Beck's avatar
Michael Beck committed
554
555
    case irms_int_number:
    case irms_character:
556
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
557

Michael Beck's avatar
Michael Beck committed
558
    case irms_reference:
559
      return new_tarval_from_long(_null_value, mode);
560
561
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
562
563
}

564
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
565
{
566
567
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
568

569
  if (get_mode_n_vector_elems(mode) > 1) {
570
571
572
573
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

574
575
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
576
577
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
578
579
580
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
581
582
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
583

Michael Beck's avatar
Michael Beck committed
584
    case irms_float_number:
585
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
586

Michael Beck's avatar
Michael Beck committed
587
588
    case irms_int_number:
    case irms_character:
589
590
591
592
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
593
594
}

595
596
597
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
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;
}

625
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
626
{
627
628
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
629

630
  if (get_mode_n_vector_elems(mode) > 1) {
631
632
633
634
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

656
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
657
{
658
659
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
660

661
  if (get_mode_n_vector_elems(mode) > 1) {
662
663
664
665
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

687
688
689
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
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;
  }
}

718
719
720
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
721

Michael Beck's avatar
Michael Beck committed
722
723
724
/*
 * test if negative number, 1 means 'yes'
 */
725
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
726
{
727
728
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
729

730
  if (get_mode_n_vector_elems(a->mode) > 1) {
731
732
733
734
735
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

736
737
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
738
    case irms_int_number:
739
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
740
      else
741
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
742

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

746
747
    default:
      assert(0 && "not implemented");
748
      return 0;
749
  }
Christian Schäfer's avatar
Christian Schäfer committed
750
751
}

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

781
782
783
784
785
786
787
788
789
790
  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;
791

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

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

Michael Beck's avatar
Michael Beck committed
808
    case irms_float_number:
809
810
811
812
      /*
       * BEWARE: we cannot compare a == b here, because
       * a NaN is always Unordered to any other value, even to itself!
       */
813
      switch (fc_comp(a->value, b->value)) {
814
        case -1: return pn_Cmp_Lt;
815
        case  0: return pn_Cmp_Eq;
816
817
818
        case  1: return pn_Cmp_Gt;
        case  2: return pn_Cmp_Uo;
        default: return pn_Cmp_False;
819
      }
Michael Beck's avatar
Michael Beck committed
820
821
    case irms_int_number:
    case irms_character:
822
823
      if (a == b)
        return pn_Cmp_Eq;
824
      return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
Christian Schäfer's avatar
Christian Schäfer committed
825

Michael Beck's avatar
Michael Beck committed
826
    case irms_internal_boolean:
827
828
      if (a == b)
        return pn_Cmp_Eq;
829
      return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
830
  }
831
  return pn_Cmp_False;
832
833
}

Michael Beck's avatar
Michael Beck committed
834
835
836
/*
 * convert to other mode
 */
837
838
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
839
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
840

Till Riedel's avatar
Till Riedel committed
841
  ANNOUNCE();
842
843
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
844

845
846
  if (src->mode == m) return src;

847
  if (get_mode_n_vector_elems(src->mode) > 1) {
848
849
850
851
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

852
853
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
854
855
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
856
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
857
858
      break;

859
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
860
    case irms_float_number:
861
      switch (get_mode_sort(m)) {
862
        case irms_float_number:
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
          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);
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:
889
              assert(0);
890
891
              break;
          }
892
          /* FIXME: floating point unit can't produce a value in integer
893
894
895
896
897
898
899
900
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
901
      }
Christian Schäfer's avatar
Christian Schäfer committed
902
903
      break;

904
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
905
    case irms_int_number:
906
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
907
908
        case irms_int_number:
        case irms_character:
909
          return get_tarval_overflow(src->value, src->length, m);
910

Michael Beck's avatar
Michael Beck committed
911
        case irms_internal_boolean:
912
913
914
915
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
        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);
938

939
940
941
942
943
        case irms_reference:
          /* allow 0 to be casted */
          if (src == get_mode_null(src->mode))
            return get_mode_null(m);
          break;
944

945
946
947
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
948
949
      break;

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

957
958
959
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
960
961
      break;

Michael Beck's avatar
Michael Beck committed
962
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
963
      break;
Michael Beck's avatar
Michael Beck committed
964
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
965
      break;
966
  }
Christian Schäfer's avatar
Christian Schäfer committed
967

968
969
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
970

Michael Beck's avatar
Michael Beck committed
971
/*
972
973
974
975
976
977
978
979
980
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

  ANNOUNCE();
  assert(a);

981
982
  /* works for vector mode without changes */

983
984
985
986
987
988
989
  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);

990
991
992
993
994
995
996
    case irms_internal_boolean:
      if (a == tarval_b_true)
        return tarval_b_false;
      if (a == tarval_b_false)
        return tarval_b_true;
      return tarval_bad;

997
    default:
998
      assert(0 && "bitwise negation is only allowed for integer and boolean");
999
1000
      return tarval_bad;
  }
For faster browsing, not all history is shown. View entire blame