tv.c 41.7 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"
52
#include "irtools.h"
Christian Schäfer's avatar
Christian Schäfer committed
53

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

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

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

67
68
69
70
71
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

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

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

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

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

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

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

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

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

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

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

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

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

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

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

246

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Matthias Heil's avatar
Matthias Heil committed
412

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
570
571
      return tarval_P_void;
  }
  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
948
        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);

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

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

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

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

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

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

  ANNOUNCE();
  assert(a);

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

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);

For faster browsing, not all history is shown. View entire blame