tv.c 39.9 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_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
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
681

Michael Beck's avatar
Michael Beck committed
682
683
684
/*
 * test if negative number, 1 means 'yes'
 */
685
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
686
{
687
688
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
689

690
  if (get_mode_n_vector_elems(a->mode) > 1) {
691
692
693
694
695
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

696
697
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
698
    case irms_int_number:
699
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
700
      else
701
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
702

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

706
707
    default:
      assert(0 && "not implemented");
708
      return 0;
709
  }
Christian Schäfer's avatar
Christian Schäfer committed
710
711
}

Michael Beck's avatar
Michael Beck committed
712
713
714
715
716
717
718
719
720
721
/*
 * 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
722
723
724
725
726
727
728
729
730
731
/*
 * 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
732
733
734
/*
 * comparison
 */
735
pnc_number tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
736
{
737
738
739
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
740

741
742
743
  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;
744
745
  if (a->mode != b->mode) return False;

746
  if (get_mode_n_vector_elems(a->mode) > 1) {
747
748
749
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
750

751
752
753
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
754
755
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
756
    case irms_auxiliary:
757
    case irms_reference:
758
      return False;
Christian Schäfer's avatar
Christian Schäfer committed
759

Michael Beck's avatar
Michael Beck committed
760
    case irms_float_number:
761
762
763
764
765
766
767
      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
768
769
    case irms_int_number:
    case irms_character:
770
      return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
Christian Schäfer's avatar
Christian Schäfer committed
771

Michael Beck's avatar
Michael Beck committed
772
    case irms_internal_boolean:
773
774
775
776
777
      return (a == tarval_b_true)?(Gt):(Lt);
  }
  return False;
}

Michael Beck's avatar
Michael Beck committed
778
779
780
/*
 * convert to other mode
 */
781
782
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
783
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
784

Till Riedel's avatar
Till Riedel committed
785
  ANNOUNCE();
786
787
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
788

789
790
  if (src->mode == m) return src;

791
  if (get_mode_n_vector_elems(src->mode) > 1) {
792
793
794
795
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

796
797
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
798
799
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
800
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
801
802
      break;

803
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
804
    case irms_float_number:
805
      switch (get_mode_sort(m)) {
806
        case irms_float_number:
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
          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);
822

823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
        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;
844
      }
Christian Schäfer's avatar
Christian Schäfer committed
845
846
      break;

847
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
848
    case irms_int_number:
849
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
850
851
        case irms_int_number:
        case irms_character:
852
          return get_tarval_overflow(src->value, src->length, m);
853

Michael Beck's avatar
Michael Beck committed
854
        case irms_internal_boolean:
855
856
857
858
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
        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);

882
883
884
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
885
886
      break;

Michael Beck's avatar
Michael Beck committed
887
    case irms_internal_boolean:
888
889
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
890
        case irms_int_number:
891
892
          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
893

894
895
896
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
897
898
      break;

Michael Beck's avatar
Michael Beck committed
899
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
900
      break;
Michael Beck's avatar
Michael Beck committed
901
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
902
      break;
903
  }
Christian Schäfer's avatar
Christian Schäfer committed
904

905
906
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
907

Michael Beck's avatar
Michael Beck committed
908
/*
909
910
911
912
913
914
915
916
917
918
 * 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 */

919
920
  /* works for vector mode without changes */

921
922
923
924
925
926
927
928
929
930
931
932
933
934
  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
935
936
 */
tarval *tarval_neg(tarval *a)
937
{
938
939
  char *buffer;

940
941
942
  ANNOUNCE();
  assert(a);
  assert(mode_is_num(a->mode)); /* negation only for numerical values */
943
944

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

946
  if (get_mode_n_vector_elems(a->mode) > 1) {
947
948
949
950
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

Michael Beck's avatar
Michael Beck committed
958
    case irms_float_number:
959
960
      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
961

962
963
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
964
965
966
  }
}

Michael Beck's avatar
Michael Beck committed
967
968
969
970
/*
 * addition
 */
tarval *tarval_add(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
971
{
972
973
  char *buffer;

974
975
976
  ANNOUNCE();
  assert(a);
  assert(b);
977
  assert(a->mode == b->mode);
Christian Schäfer's avatar
Christian Schäfer committed
978

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

984
985
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
986
987
    case irms_character:
    case irms_int_number:
988
      /* modes of a,b are equal, so result has mode of a as this might be the character */
989
990
991
      buffer = alloca(sc_get_buffer_length());
      sc_add(a->value, b->value, buffer);
      return get_tarval_overflow(buffer, a->length, a->mode);
Christian Schäfer's avatar
Christian Schäfer committed
992

Michael Beck's avatar
Michael Beck committed
993
    case irms_float_number:
994
995
      fc_add(a->value, b->value, NULL);
      return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
Christian Schäfer's avatar
Christian Schäfer committed
996

997
998
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
999
1000
  }
}
For faster browsing, not all history is shown. View entire blame