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() */
31
#include <string.h>         /* nice things for strings */
32
#ifdef HAVE_STRINGS_H
33
#include <strings.h>        /* strings.h also includes bsd only function strcasecmp */
34
#endif
35
#include <stdlib.h>
Boris Boesler's avatar
Boris Boesler committed
36
#ifdef HAVE_ALLOCA_H
Boris Boesler's avatar
Boris Boesler committed
37
38
# include <alloca.h>
#endif
39
40
41
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
42

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

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

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

/* 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

68
69
70
71
72
73
74
75
/****************************************************************************
 *   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
76

77
78
#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))))
79

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

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

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

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

122
123
124
125
126
127
128
  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
129
}
130
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
131

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

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

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

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

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

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

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

242

243
/*
244
 *   public variables declared in tv.h
245
 */
246
247
248
249
250
251
252
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
253

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

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

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

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

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

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

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

311
/*
312
 * helper function, create a tarval from long
313
 */
314
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
315
{
316
  ANNOUNCE();
Till Riedel's avatar
Till Riedel committed
317
  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
318

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

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

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

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

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

342
/* returns non-zero if can be converted to long */
343
344
345
int tarval_is_long(tarval *tv)
{
  ANNOUNCE();
346
347
348
349
350
  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 */
351
    sc_max_from_bits(sizeof(long)<<3, 0, NULL);
352
353
354
355
356
357
358
    if (sc_comp(sc_get_buffer(), tv->value) == -1)
    {
      /* really doesn't fit */
      return 0;
    }
  }
  return 1;
359
}
Michael Beck's avatar
Michael Beck committed
360
361

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

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

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

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

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

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

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

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

Matthias Heil's avatar
Matthias Heil committed
406

407
408
409
410
/*
 * 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
411
{
412
413
414
415
  ANNOUNCE();
  assert(tv);
  return tv->mode;
}
Christian Schäfer's avatar
Christian Schäfer committed
416

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

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

436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
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
460
461
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

677
678
679
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
680

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

983
984
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
985
986
    case irms_character:
    case irms_int_number:
987
      /* modes of a,b are equal, so result has mode of a as this might be the character */
988
989
990
      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
991

Michael Beck's avatar
Michael Beck committed
992
    case irms_float_number:
993
994
      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
995

996
997
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
998
999
1000
  }
}

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