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

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

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

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

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


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

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

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

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

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

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

69
70
71
72
73
74
75
76
/****************************************************************************
 *   local definitions and macros
 ****************************************************************************/
#ifndef NDEBUG
#  define TARVAL_VERIFY(a) tarval_verify((a))
#else
#  define TARVAL_VERIFY(a) ((void)0)
#endif
Christian Schäfer's avatar
Christian Schäfer committed
77

78
79
#define INSERT_TARVAL(tv) ((tarval*)set_insert(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
#define FIND_TARVAL(tv) ((tarval*)set_find(tarvals, (tv), sizeof(tarval), hash_tv((tv))))
80

81
82
#define INSERT_VALUE(val, size) (set_insert(values, (val), size, hash_val((val), size)))
#define FIND_VALUE(val, size) (set_find(values, (val), size, hash_val((val), size)))
83

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

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

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

123
124
125
126
127
128
129
  if ((tv == tarval_bad) || (tv == tarval_undefined)) return;
  if ((tv == tarval_b_true) || (tv == tarval_b_false)) return;

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

  return;
Christian Schäfer's avatar
Christian Schäfer committed
130
}
131
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
132

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

138
static int hash_val(const void *value, unsigned int length)
Christian Schäfer's avatar
Christian Schäfer committed
139
{
140
141
142
143
144
145
146
147
148
149
150
  unsigned int i;
  unsigned int hash = 0;

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

  return hash;
Christian Schäfer's avatar
Christian Schäfer committed
151
152
}

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

  tv.mode = mode;
  tv.length = length;
160
  if (length > 0) {
161
162
163
    /* if there already is such a value, it is returned, else value
     * is copied into the set */
    tv.value = INSERT_VALUE(value, length);
164
  } else {
165
    tv.value = value;
166
  }
167
168
169
  /* if there is such a tarval, it is returned, else tv is copied
   * into the set */
  return (tarval *)INSERT_TARVAL(&tv);
Christian Schäfer's avatar
Christian Schäfer committed
170
171
}

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

Michael Beck's avatar
Michael Beck committed
226
    case irms_float_number:
227
228
229
230
      if (SWITCH_NOINFINITY && fc_is_inf(value))
      {
        return fc_is_negative(value)?get_mode_min(mode):get_mode_max(mode);
      }
Christian Schäfer's avatar
Christian Schäfer committed
231

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

243

244
/*
245
 *   public variables declared in tv.h
246
 */
247
248
249
250
251
252
253
static tarval reserved_tv[5];

tarval *tarval_bad       = &reserved_tv[0];
tarval *tarval_undefined = &reserved_tv[1];
tarval *tarval_b_false   = &reserved_tv[2];
tarval *tarval_b_true    = &reserved_tv[3];
tarval *tarval_P_void    = &reserved_tv[4];
Christian Schäfer's avatar
Christian Schäfer committed
254

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

259
260
261
262
263
264
265
266
267
268
269
270
/*
 * Constructors =============================================================
 */
tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
{
  ANNOUNCE();
  assert(str);
  assert(len);
  assert(mode);

  switch (get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
271
272
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
273
    case irms_auxiliary:
274
275
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
276

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

Michael Beck's avatar
Michael Beck committed
285
    case irms_float_number:
286
287
288
289
290
291
292
293
294
295
296
      switch(get_mode_size_bits(mode)) {
        case 32:
          fc_val_from_str(str, len, 8, 23, NULL);
          break;
        case 64:
          fc_val_from_str(str, len, 11, 52, NULL);
          break;
        case 80:
          fc_val_from_str(str, len, 15, 64, NULL);
          break;
      }
297
298
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

376
377
378
379
380
381
382
383
384
385
386
  switch (get_mode_size_bits(mode)) {
    case 32:
      fc_val_from_float(d, 8, 23, NULL);
      break;
    case 64:
      fc_val_from_float(d, 11, 52, NULL);
      break;
    case 80:
      fc_val_from_float(d, 15, 64, NULL);
      break;
  }
387
  return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
388
}
Michael Beck's avatar
Michael Beck committed
389

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

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

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

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

Matthias Heil's avatar
Matthias Heil committed
407

408
409
410
411
/*
 * Access routines for tarval fields ========================================
 */
ir_mode *get_tarval_mode (tarval *tv)       /* get the mode of the tarval */
Christian Schäfer's avatar
Christian Schäfer committed
412
{
413
414
415
416
  ANNOUNCE();
  assert(tv);
  return tv->mode;
}
Christian Schäfer's avatar
Christian Schäfer committed
417

418
419
420
421
422
423
424
425
426
/*
void *get_tarval_link (tarval *tv)
{
  ANNOUNCE ();
  assert (tv);
  return (tv->link);
}
*/

427
428
429
430
431
432
433
434
435
/*
 * 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
436

437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
tarval *get_tarval_bad(void)
{
  ANNOUNCE();
  return tarval_bad;
}
tarval *get_tarval_undefined(void)
{
  ANNOUNCE();
  return tarval_undefined;
}
tarval *get_tarval_b_false(void)
{
  ANNOUNCE();
  return tarval_b_false;
}
tarval *get_tarval_b_true(void)
{
  ANNOUNCE();
  return tarval_b_true;
}
tarval *get_tarval_P_void(void)
{
  ANNOUNCE();
  return tarval_P_void;
Christian Schäfer's avatar
Christian Schäfer committed
461
462
}

463
tarval *get_tarval_max(ir_mode *mode)
464
{
465
466
  ANNOUNCE();
  assert(mode);
467

468
  if (get_mode_n_vector_elems(mode) > 1) {
469
470
471
472
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

473
474
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
475
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
476
477
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
478
    case irms_auxiliary:
479
480
      assert(0);
      break;
481

Michael Beck's avatar
Michael Beck committed
482
    case irms_internal_boolean:
483
      return tarval_b_true;
484

Michael Beck's avatar
Michael Beck committed
485
    case irms_float_number:
486
487
488
489
490
491
492
493
494
495
496
497
      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;
      }
498
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
499

Michael Beck's avatar
Michael Beck committed
500
501
    case irms_int_number:
    case irms_character:
502
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
503
504
505
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
506
507
}

508
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
509
{
510
511
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
512

513
  if (get_mode_n_vector_elems(mode) > 1) {
514
515
516
517
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

518
519
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
520
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
521
522
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
523
    case irms_auxiliary:
524
525
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
526

Michael Beck's avatar
Michael Beck committed
527
    case irms_internal_boolean:
528
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
529

Michael Beck's avatar
Michael Beck committed
530
    case irms_float_number:
531
532
533
534
535
536
537
538
539
540
541
542
      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;
      }
543
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
544

Michael Beck's avatar
Michael Beck committed
545
546
    case irms_int_number:
    case irms_character:
547
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
548
549
550
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
551
552
}

553
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
554
{
555
556
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
557

558
  if (get_mode_n_vector_elems(mode) > 1) {
559
560
561
562
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

563
564
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
565
566
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
567
568
    case irms_auxiliary:
    case irms_internal_boolean:
569
570
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
571

Michael Beck's avatar
Michael Beck committed
572
    case irms_float_number:
573
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
574

Michael Beck's avatar
Michael Beck committed
575
576
    case irms_int_number:
    case irms_character:
577
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
578

Michael Beck's avatar
Michael Beck committed
579
    case irms_reference:
580
581
582
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
583
584
}

585
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
586
{
587
588
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
589

590
  if (get_mode_n_vector_elems(mode) > 1) {
591
592
593
594
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

595
596
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
597
598
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
599
600
601
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
602
603
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
604

Michael Beck's avatar
Michael Beck committed
605
    case irms_float_number:
606
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
607

Michael Beck's avatar
Michael Beck committed
608
609
    case irms_int_number:
    case irms_character:
610
611
612
613
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
614
615
}

616
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
617
{
618
619
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
620

621
  if (get_mode_n_vector_elems(mode) > 1) {
622
623
624
625
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
626
  if (get_mode_sort(mode) == irms_float_number) {
627
628
629
630
631
632
633
634
635
636
637
638
    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;
    }
639
640
641
642
643
644
    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
645
646
}

647
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
648
{
649
650
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
651

652
  if (get_mode_n_vector_elems(mode) > 1) {
653
654
655
656
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
657
  if (get_mode_sort(mode) == irms_float_number) {
658
659
660
661
662
663
664
665
666
667
668
669
    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;
    }
670
671
672
673
674
675
    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
676
677
}

678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
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;
  }
}

709
710
711
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
712

Michael Beck's avatar
Michael Beck committed
713
714
715
/*
 * test if negative number, 1 means 'yes'
 */
716
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
717
{
718
719
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
720

721
  if (get_mode_n_vector_elems(a->mode) > 1) {
722
723
724
725
726
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

727
728
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
729
    case irms_int_number:
730
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
731
      else
732
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
733

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

737
738
    default:
      assert(0 && "not implemented");
739
      return 0;
740
  }
Christian Schäfer's avatar
Christian Schäfer committed
741
742
}

Michael Beck's avatar
Michael Beck committed
743
744
745
746
747
748
749
750
751
752
/*
 * 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
753
754
755
756
757
758
759
760
761
762
/*
 * 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
763
764
765
/*
 * comparison
 */
766
pnc_number tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
767
{
768
769
770
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
771

772
773
774
  if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad");
  if (a == tarval_undefined || b == tarval_undefined) return False;
  if (a == b) return Eq;
775
776
  if (a->mode != b->mode) return False;

777
  if (get_mode_n_vector_elems(a->mode) > 1) {
778
779
780
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
781

782
783
784
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
785
786
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
787
    case irms_auxiliary:
788
    case irms_reference:
789
      return False;
Christian Schäfer's avatar
Christian Schäfer committed
790

Michael Beck's avatar
Michael Beck committed
791
    case irms_float_number:
792
793
794
795
796
797
798
      switch (fc_comp(a->value, b->value)) {
        case -1: return Lt;
        case  0: assert(0 && "different tarvals compare equal"); return Eq;
        case  1: return Gt;
        case  2: return Uo;
        default: return False;
      }
Michael Beck's avatar
Michael Beck committed
799
800
    case irms_int_number:
    case irms_character:
801
      return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
Christian Schäfer's avatar
Christian Schäfer committed
802

Michael Beck's avatar
Michael Beck committed
803
    case irms_internal_boolean:
804
805
806
807
808
      return (a == tarval_b_true)?(Gt):(Lt);
  }
  return False;
}

Michael Beck's avatar
Michael Beck committed
809
810
811
/*
 * convert to other mode
 */
812
813
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
814
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
815

Till Riedel's avatar
Till Riedel committed
816
  ANNOUNCE();
817
818
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
819

820
821
  if (src->mode == m) return src;

822
  if (get_mode_n_vector_elems(src->mode) > 1) {
823
824
825
826
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

827
828
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
829
830
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
831
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
832
833
      break;

834
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
835
    case irms_float_number:
836
      switch (get_mode_sort(m)) {
837
        case irms_float_number:
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
          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);
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
        case irms_int_number:
          switch (GET_FLOAT_TO_INT_MODE())
          {
            case TRUNCATE:
              fc_int(src->value, NULL);
              break;
            case ROUND:
              fc_rnd(src->value, NULL);
              break;
            default:
              break;
          }
          /* XXX floating point unit can't produce a value in integer
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
875
      }
Christian Schäfer's avatar
Christian Schäfer committed
876
877
      break;

878
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
879
    case irms_int_number:
880
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
881
882
        case irms_int_number:
        case irms_character:
883
          return get_tarval_overflow(src->value, src->length, m);
884

Michael Beck's avatar
Michael Beck committed
885
        case irms_internal_boolean:
886
887
888
889
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
        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);

913
914
915
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
916
917
      break;

Michael Beck's avatar
Michael Beck committed
918
    case irms_internal_boolean:
919
920
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
921
        case irms_int_number:
922
923
          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
924

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

Michael Beck's avatar
Michael Beck committed
930
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
931
      break;
Michael Beck's avatar
Michael Beck committed
932
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
933
      break;
934
  }
Christian Schäfer's avatar
Christian Schäfer committed
935

936
937
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
938

Michael Beck's avatar
Michael Beck committed
939
/*
940
941
942
943
944
945
946
947
948
949
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

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

950
951
  /* works for vector mode without changes */

952
953
954
955
956
957
958
959
960
961
962
963
964
965
  switch (get_mode_sort(a->mode))
  {
    case irms_int_number:
      buffer = alloca(sc_get_buffer_length());
      sc_not(a->value, buffer);
      return get_tarval(buffer, a->length, a->mode);

    default:
      return tarval_bad;
  }
}

/*
 * arithmetic negation
Michael Beck's avatar
Michael Beck committed
966
967
 */
tarval *tarval_neg(tarval *a)
968
{
969
970
  char *buffer;

971
972
973
  ANNOUNCE();
  assert(a);
  assert(mode_is_num(a->mode)); /* negation only for numerical values */
974
975

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

977
  if (get_mode_n_vector_elems(a->mode) > 1) {
978
979
980
981
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

982
983
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
984
    case irms_int_number:
985
986
987
      buffer = alloca(sc_get_buffer_length());
      sc_neg(a->value, buffer);
      return get_tarval_overflow(buffer, a->length, a->mode);
Christian Schäfer's avatar
Christian Schäfer committed
988

Michael Beck's avatar
Michael Beck committed
989
    case irms_float_number:
990
991
      fc_neg(a->value, NULL);
      return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
Christian Schäfer's avatar
Christian Schäfer committed
992

993
994
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
995
996
997
  }
}

Michael Beck's avatar
Michael Beck committed
998
999
1000
/*
 * addition
 */
For faster browsing, not all history is shown. View entire blame