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

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

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

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

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


29
#include <assert.h>         /* assertions */
Michael Beck's avatar
Michael Beck committed
30
#include <stdlib.h>         /* atoi() */
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, get_mode_size_bits(tv->mode), mode_is_signed(tv->mode));
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
/*
 * 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
426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
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
451
452
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
569
    case irms_reference:
570
571
572
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
573
574
}

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

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

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

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

Michael Beck's avatar
Michael Beck committed
598
599
    case irms_int_number:
    case irms_character:
600
601
602
603
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
604
605
}

606
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
607
{
608
609
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
610

611
  if (get_mode_n_vector_elems(mode) > 1) {
612
613
614
615
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
616
  if (get_mode_sort(mode) == irms_float_number) {
617
618
619
620
621
622
623
624
625
626
627
628
    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;
    }
629
630
631
632
633
634
    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
635
636
}

637
tarval *get_tarval_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
638
{
639
640
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
641

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

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

668
669
670
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
671

Michael Beck's avatar
Michael Beck committed
672
673
674
/*
 * test if negative number, 1 means 'yes'
 */
675
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
676
{
677
678
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
679

680
  if (get_mode_n_vector_elems(a->mode) > 1) {
681
682
683
684
685
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

686
687
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
688
    case irms_int_number:
689
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
690
      else
691
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
692

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

696
697
    default:
      assert(0 && "not implemented");
698
      return 0;
699
  }
Christian Schäfer's avatar
Christian Schäfer committed
700
701
}

Michael Beck's avatar
Michael Beck committed
702
703
704
705
706
707
708
709
710
711
/*
 * 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
712
713
714
715
716
717
718
719
720
721
/*
 * 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
722
723
724
/*
 * comparison
 */
725
pnc_number tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
726
{
727
728
729
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
730

731
732
733
  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;
734
735
  if (a->mode != b->mode) return False;

736
  if (get_mode_n_vector_elems(a->mode) > 1) {
737
738
739
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
740

741
742
743
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
744
745
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
746
    case irms_auxiliary:
747
    case irms_reference:
748
      return False;
Christian Schäfer's avatar
Christian Schäfer committed
749

Michael Beck's avatar
Michael Beck committed
750
    case irms_float_number:
751
752
753
754
755
756
757
      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
758
759
    case irms_int_number:
    case irms_character:
760
      return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
Christian Schäfer's avatar
Christian Schäfer committed
761

Michael Beck's avatar
Michael Beck committed
762
    case irms_internal_boolean:
763
764
765
766
767
      return (a == tarval_b_true)?(Gt):(Lt);
  }
  return False;
}

Michael Beck's avatar
Michael Beck committed
768
769
770
/*
 * convert to other mode
 */
771
772
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
773
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
774

Till Riedel's avatar
Till Riedel committed
775
  ANNOUNCE();
776
777
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
778

779
780
  if (src->mode == m) return src;

781
  if (get_mode_n_vector_elems(src->mode) > 1) {
782
783
784
785
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

786
787
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
788
789
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
790
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
791
792
      break;

793
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
794
    case irms_float_number:
795
      switch (get_mode_sort(m)) {
796
        case irms_float_number:
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
          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);
812

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
        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;
834
      }
Christian Schäfer's avatar
Christian Schäfer committed
835
836
      break;

837
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
838
    case irms_int_number:
839
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
840
841
        case irms_int_number:
        case irms_character:
842
          return get_tarval_overflow(src->value, src->length, m);
843

Michael Beck's avatar
Michael Beck committed
844
        case irms_internal_boolean:
845
846
847
848
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
        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);

872
873
874
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
875
876
      break;

Michael Beck's avatar
Michael Beck committed
877
    case irms_internal_boolean:
878
879
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
880
        case irms_int_number:
881
882
          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
883

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

Michael Beck's avatar
Michael Beck committed
889
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
890
      break;
Michael Beck's avatar
Michael Beck committed
891
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
892
      break;
893
  }
Christian Schäfer's avatar
Christian Schäfer committed
894

895
896
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
897

Michael Beck's avatar
Michael Beck committed
898
/*
899
900
901
902
903
904
905
906
907
908
 * 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 */

909
910
  /* works for vector mode without changes */

911
912
913
914
915
916
917
918
919
920
921
922
923
924
  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
925
926
 */
tarval *tarval_neg(tarval *a)
927
{
928
929
  char *buffer;

930
931
932
  ANNOUNCE();
  assert(a);
  assert(mode_is_num(a->mode)); /* negation only for numerical values */
933
934

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

936
  if (get_mode_n_vector_elems(a->mode) > 1) {
937
938
939
940
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

941
942
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
943
    case irms_int_number:
944
945
946
      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
947

Michael Beck's avatar
Michael Beck committed
948
    case irms_float_number:
949
950
      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
951

952
953
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
954
955
956
  }
}

Michael Beck's avatar
Michael Beck committed
957
958
959
960
/*
 * addition
 */
tarval *tarval_add(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
961
{
962
963
  char *buffer;

964
965
966
  ANNOUNCE();
  assert(a);
  assert(b);
967
  assert(a->mode == b->mode);
Christian Schäfer's avatar
Christian Schäfer committed
968

969
  if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) {
970
971
972
973
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

974
975
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
976
977
    case irms_character:
    case irms_int_number:
978
      /* modes of a,b are equal, so result has mode of a as this might be the character */
979
980
981
      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
982

Michael Beck's avatar
Michael Beck committed
983
    case irms_float_number:
984
985
      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
986

987
988
    default:
      return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
989
990
991
  }
}

Michael Beck's avatar
Michael Beck committed
992
993
994
995
/*
 * subtraction
 */
tarval *tarval_sub(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
996
{
997
998
  char *buffer;

999
1000
  ANNOUNCE();
  assert(a);
For faster browsing, not all history is shown. View entire blame