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

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

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

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

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


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

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

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

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

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

70
71
72
73
74
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

239
240
241
242
243
      if (SWITCH_NODENORMALS && fc_is_subnormal(value))
      {
        return get_mode_null(mode);
      }
      break;
244

245
246
247
    default:
      break;
  }
248
  return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
249
250
}

251

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

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
261

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

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

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

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

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

306
307
    case irms_reference:
      /* same as integer modes */
Michael Beck's avatar
Michael Beck committed
308
309
    case irms_int_number:
    case irms_character:
Michael Beck's avatar
Michael Beck committed
310
      sc_val_from_str(str, len, NULL, mode);
311
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
312
313
  }

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

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

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

332
333
    case irms_reference:
      /* same as integer modes */
Michael Beck's avatar
Michael Beck committed
334
335
    case irms_int_number:
    case irms_character:
336
      sc_val_from_long(l, NULL);
337
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
338

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

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

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

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

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

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

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

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

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

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

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

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

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

Matthias Heil's avatar
Matthias Heil committed
414

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

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

424
425
426
427
428
429
430
431
432
/*
 * 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
433

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

540
541
static long _null_value;

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
568
    case irms_reference:
569
      return new_tarval_from_long(_null_value, mode);
570
571
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
572
573
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
951
952
953
        case irms_reference:
          /* allow 0 to be casted */
          if (src == get_mode_null(src->mode))
            return get_mode_null(m);
          break;
954

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

Michael Beck's avatar
Michael Beck committed
960
    case irms_internal_boolean:
961
962
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
963
        case irms_int_number:
964
965
          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
966

967
968
969
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
970
971
      break;

Michael Beck's avatar
Michael Beck committed
972
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
973
      break;
Michael Beck's avatar
Michael Beck committed
974
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
975
      break;
976
  }
Christian Schäfer's avatar
Christian Schäfer committed
977

978
979
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
980

Michael Beck's avatar
Michael Beck committed
981
/*
982
983
984
985
986
987
988
989
990
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

  ANNOUNCE();
  assert(a);

991
992
  /* works for vector mode without changes */

993
994
995
996
997
998
999
  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);

1000
    case irms_internal_boolean:
For faster browsing, not all history is shown. View entire blame