tv.c 41.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() */
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
Michael Beck's avatar
Michael Beck committed
37
38
39
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
Boris Boesler's avatar
Boris Boesler committed
40
#ifdef HAVE_ALLOCA_H
Boris Boesler's avatar
Boris Boesler committed
41
42
# include <alloca.h>
#endif
43
44
45
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
46

47
48
49
#include "tv_t.h"
#include "set.h"            /* to store tarvals in */
#include "entity_t.h"       /* needed to store pointers to entities */
Michael Beck's avatar
Michael Beck committed
50
#include "irmode_t.h"
51
#include "irnode.h"         /* defines boolean return values (pnc_number)*/
52
53
#include "strcalc.h"
#include "fltcalc.h"
54
#include "irtools.h"
Michael Beck's avatar
Michael Beck committed
55
#include "xmalloc.h"
Michael Beck's avatar
Michael Beck committed
56
#include "firm_common.h"
Christian Schäfer's avatar
Christian Schäfer committed
57

Götz Lindenmaier's avatar
Götz Lindenmaier committed
58
59
/** Size of hash tables.  Should correspond to average number of distinct constant
    target values */
60
#define N_CONSTANTS 2048
Götz Lindenmaier's avatar
Götz Lindenmaier committed
61

62
63
/* get the integer overflow mode */
#define GET_OVERFLOW_MODE() int_overflow_mode
64
65

/* unused, float to int doesn't work yet */
66
67
68
69
70
enum float_to_int_mode {
  TRUNCATE,
  ROUND
};

71
72
73
74
75
#define GET_FLOAT_TO_INT_MODE() TRUNCATE

#define SWITCH_NOINFINITY 0
#define SWITCH_NODENORMALS 0

76
77
78
79
80
81
82
83
/****************************************************************************
 *   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
84

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

88
89
#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)))
90

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

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

Till Riedel's avatar
Till Riedel committed
124
INLINE static void tarval_verify(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
125
{
126
127
128
  assert(tv);
  assert(tv->mode);
  assert(tv->value);
Christian Schäfer's avatar
Christian Schäfer committed
129

130
131
132
133
134
135
136
  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
137
}
138
#endif /* NDEBUG */
Christian Schäfer's avatar
Christian Schäfer committed
139

140
141
/** Hash a tarval. */
static int hash_tv(tarval *tv) {
142
  return (PTR_TO_INT(tv->value) ^ PTR_TO_INT(tv->mode)) + tv->length;
Christian Schäfer's avatar
Christian Schäfer committed
143
144
}

145
146
/** Hash a value. Treat it as a byte array. */
static int hash_val(const void *value, unsigned int length) {
147
148
149
150
151
152
153
154
155
156
157
  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
158
159
}

Michael Beck's avatar
Michael Beck committed
160
/** finds tarval with value/mode or creates new tarval */
161
static tarval *get_tarval(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
162
{
163
164
  tarval tv;

Michael Beck's avatar
Michael Beck committed
165
166
  tv.kind   = k_tarval;
  tv.mode   = mode;
167
  tv.length = length;
168
  if (length > 0) {
169
170
171
    /* if there already is such a value, it is returned, else value
     * is copied into the set */
    tv.value = INSERT_VALUE(value, length);
172
  } else {
173
    tv.value = value;
174
  }
175
176
177
  /* 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
178
179
}

180
181
182
/**
 * handle overflow
 */
183
static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
184
{
185
  switch (get_mode_sort(mode))
186
  {
Michael Beck's avatar
Michael Beck committed
187
    case irms_int_number:
188
189
      if (sc_comp(value, get_mode_max(mode)->value) == 1) {
        switch (GET_OVERFLOW_MODE()) {
190
          case TV_OVERFLOW_SATURATE:
191
            return get_mode_max(mode);
192
          case TV_OVERFLOW_WRAP:
193
194
            {
              char *temp = alloca(sc_get_buffer_length());
195
196
              sc_val_from_ulong(-1, temp);
              sc_and(temp, value, temp);
Michael Beck's avatar
BugFix:    
Michael Beck committed
197
198
			  /* the sc_ module expects that all bits are set ... */
              sign_extend(temp, mode);
199
200
              return get_tarval(temp, length, mode);
            }
201
          case TV_OVERFLOW_BAD:
202
203
204
205
206
207
208
            return tarval_bad;
          default:
            return get_tarval(value, length, mode);
        }
      }
      if (sc_comp(value, get_mode_min(mode)->value) == -1) {
        switch (GET_OVERFLOW_MODE()) {
209
          case TV_OVERFLOW_SATURATE:
210
            return get_mode_min(mode);
211
          case TV_OVERFLOW_WRAP:
212
213
            {
              char *temp = alloca(sc_get_buffer_length());
214
215
              sc_val_from_ulong(-1, temp);
              sc_and(temp, value, temp);
216
217
              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
240
    default:
      break;
  }
241
  return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
242
243
}

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

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

298
299
    case irms_reference:
      /* same as integer modes */
Michael Beck's avatar
Michael Beck committed
300
301
    case irms_int_number:
    case irms_character:
Michael Beck's avatar
Michael Beck committed
302
      sc_val_from_str(str, len, NULL, mode);
303
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
304
305
  }

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

310
/*
311
 * helper function, create a tarval from long
312
 */
313
tarval *new_tarval_from_long(long l, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
314
{
315
  ANNOUNCE();
316
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
317

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

324
325
    case irms_reference:
      /* same as integer modes */
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

334
    default:
335
      assert(0 && "unsupported mode sort");
Christian Schäfer's avatar
Christian Schäfer committed
336
  }
Michael Beck's avatar
Michael Beck committed
337
  return NULL;
Christian Schäfer's avatar
Christian Schäfer committed
338
}
Michael Beck's avatar
Michael Beck committed
339

340
/* returns non-zero if can be converted to long */
341
342
int tarval_is_long(tarval *tv)
{
343
344
  mode_sort sort = get_mode_sort(tv->mode);

345
  ANNOUNCE();
346
  if (sort != irms_int_number && sort != irms_character) return 0;
347
348
349
350

  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
/*
 * Access routines for tarval fields ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
410

Michael Beck's avatar
Michael Beck committed
411
412
413
/* get the mode of the tarval */
ir_mode *(get_tarval_mode)(const tarval *tv) {
  return _get_tarval_mode(tv);
414
415
}

416
417
418
419
420
421
422
423
424
/*
 * 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
425

Michael Beck's avatar
Michael Beck committed
426
427
tarval *(get_tarval_bad)(void) {
  return _get_tarval_bad();
428
}
Michael Beck's avatar
Michael Beck committed
429
430
431

tarval *(get_tarval_undefined)(void) {
  return _get_tarval_undefined();
432
}
Michael Beck's avatar
Michael Beck committed
433
434
435

tarval *(get_tarval_b_false)(void) {
  return _get_tarval_b_false();
436
}
Michael Beck's avatar
Michael Beck committed
437
438
439

tarval *(get_tarval_b_true)(void) {
  return _get_tarval_b_true();
440
}
Michael Beck's avatar
Michael Beck committed
441

442
tarval *get_tarval_max(ir_mode *mode)
443
{
444
445
  ANNOUNCE();
  assert(mode);
446

447
  if (get_mode_n_vector_elems(mode) > 1) {
448
449
450
451
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

452
453
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
454
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
455
456
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
457
    case irms_auxiliary:
458
459
      assert(0);
      break;
460

Michael Beck's avatar
Michael Beck committed
461
    case irms_internal_boolean:
462
      return tarval_b_true;
463

Michael Beck's avatar
Michael Beck committed
464
    case irms_float_number:
465
466
467
468
469
470
471
472
473
474
475
476
      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;
      }
477
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
478

Michael Beck's avatar
Michael Beck committed
479
480
    case irms_int_number:
    case irms_character:
481
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
482
483
484
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
485
486
}

487
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
488
{
489
490
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
491

492
  if (get_mode_n_vector_elems(mode) > 1) {
493
494
495
496
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

497
498
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
499
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
500
501
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
502
    case irms_auxiliary:
503
504
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
505

Michael Beck's avatar
Michael Beck committed
506
    case irms_internal_boolean:
507
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
508

Michael Beck's avatar
Michael Beck committed
509
    case irms_float_number:
510
511
512
513
514
515
516
517
518
519
520
521
      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;
      }
522
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
523

Michael Beck's avatar
Michael Beck committed
524
525
    case irms_int_number:
    case irms_character:
526
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
527
528
529
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
530
531
}

532
533
static long _null_value;

534
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
535
{
536
537
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
538

539
  if (get_mode_n_vector_elems(mode) > 1) {
540
541
542
543
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

544
545
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
546
547
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
548
549
    case irms_auxiliary:
    case irms_internal_boolean:
550
551
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
552

Michael Beck's avatar
Michael Beck committed
553
    case irms_float_number:
554
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
555

Michael Beck's avatar
Michael Beck committed
556
557
    case irms_int_number:
    case irms_character:
558
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
559

Michael Beck's avatar
Michael Beck committed
560
    case irms_reference:
561
      return new_tarval_from_long(_null_value, mode);
562
563
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
564
565
}

566
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
567
{
568
569
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
570

571
  if (get_mode_n_vector_elems(mode) > 1) {
572
573
574
575
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

576
577
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
578
579
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
580
581
582
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
583
584
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
585

Michael Beck's avatar
Michael Beck committed
586
    case irms_float_number:
587
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
588

Michael Beck's avatar
Michael Beck committed
589
590
    case irms_int_number:
    case irms_character:
591
592
593
594
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
595
596
}

597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
tarval *get_tarval_minus_one(ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);

  if (get_mode_n_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

  switch(get_mode_sort(mode))
  {
    case irms_control_flow:
    case irms_memory:
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
      assert(0);
      break;

    case irms_float_number:
      return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;

    case irms_int_number:
    case irms_character:
      return mode_is_signed(mode) ? new_tarval_from_long(-1l, mode) : tarval_bad;
  }
  return tarval_bad;
}

627
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
628
{
629
630
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
631

632
  if (get_mode_n_vector_elems(mode) > 1) {
633
634
635
636
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
637
  if (get_mode_sort(mode) == irms_float_number) {
638
639
640
641
642
643
644
645
646
647
648
649
    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;
    }
650
651
652
653
654
655
    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
656
657
}

658
tarval *get_tarval_plus_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
659
{
660
661
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
662

663
  if (get_mode_n_vector_elems(mode) > 1) {
664
665
666
667
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
668
  if (get_mode_sort(mode) == irms_float_number) {
669
670
671
672
673
674
675
676
677
678
679
680
    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;
    }
681
682
683
684
685
686
    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
687
688
}

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
tarval *get_tarval_minus_inf(ir_mode *mode)
{
  ANNOUNCE();
  assert(mode);

  if (get_mode_n_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

  if (get_mode_sort(mode) == irms_float_number) {
    switch(get_mode_size_bits(mode))
    {
    case 32:
      fc_get_minusinf(8, 23, NULL);
      break;
    case 64:
      fc_get_minusinf(11, 52, NULL);
      break;
    case 80:
      fc_get_minusinf(15, 64, NULL);
      break;
    }
    return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
  }
  else {
    assert(0 && "tarval is not floating point");
    return tarval_bad;
  }
}

720
721
722
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
723

Michael Beck's avatar
Michael Beck committed
724
725
726
/*
 * test if negative number, 1 means 'yes'
 */
727
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
728
{
729
730
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
731

732
  if (get_mode_n_vector_elems(a->mode) > 1) {
733
734
735
736
737
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

738
739
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
740
    case irms_int_number:
741
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
742
      else
743
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
744

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

748
749
    default:
      assert(0 && "not implemented");
750
      return 0;
751
  }
Christian Schäfer's avatar
Christian Schäfer committed
752
753
}

Michael Beck's avatar
Michael Beck committed
754
755
756
757
758
759
760
761
762
763
/*
 * 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
764
765
766
767
768
769
770
771
772
773
/*
 * 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
774
775
776
/*
 * comparison
 */
777
pn_Cmp tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
778
{
779
780
781
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
782

783
784
785
786
787
788
789
790
791
792
  if (a == tarval_bad || b == tarval_bad) {
    assert(0 && "Comparison with tarval_bad");
    return pn_Cmp_False;
  }

  if (a == tarval_undefined || b == tarval_undefined)
    return pn_Cmp_False;

  if (a->mode != b->mode)
    return pn_Cmp_False;
793

794
  if (get_mode_n_vector_elems(a->mode) > 1) {
795
796
797
    /* vector arithmetic not implemented yet */
    assert(0 && "cmp not implemented for vector modes");
  }
Christian Schäfer's avatar
Christian Schäfer committed
798

799
800
801
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
802
803
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
804
    case irms_auxiliary:
805
    case irms_reference:
806
807
      if (a == b)
        return pn_Cmp_Eq;
808
      return pn_Cmp_False;
Christian Schäfer's avatar
Christian Schäfer committed
809

Michael Beck's avatar
Michael Beck committed
810
    case irms_float_number:
811
812
813
814
      /*
       * BEWARE: we cannot compare a == b here, because
       * a NaN is always Unordered to any other value, even to itself!
       */
815
      switch (fc_comp(a->value, b->value)) {
816
        case -1: return pn_Cmp_Lt;
817
        case  0: return pn_Cmp_Eq;
818
819
820
        case  1: return pn_Cmp_Gt;
        case  2: return pn_Cmp_Uo;
        default: return pn_Cmp_False;
821
      }
Michael Beck's avatar
Michael Beck committed
822
823
    case irms_int_number:
    case irms_character:
824
825
      if (a == b)
        return pn_Cmp_Eq;
826
      return sc_comp(a->value, b->value) == 1 ? pn_Cmp_Gt : pn_Cmp_Lt;
Christian Schäfer's avatar
Christian Schäfer committed
827

Michael Beck's avatar
Michael Beck committed
828
    case irms_internal_boolean:
829
830
      if (a == b)
        return pn_Cmp_Eq;
831
      return a == tarval_b_true ? pn_Cmp_Gt : pn_Cmp_Lt;
832
  }
833
  return pn_Cmp_False;
834
835
}

Michael Beck's avatar
Michael Beck committed
836
837
838
/*
 * convert to other mode
 */
839
840
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
841
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
842

Till Riedel's avatar
Till Riedel committed
843
  ANNOUNCE();
844
845
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
846

847
848
  if (src->mode == m) return src;

849
  if (get_mode_n_vector_elems(src->mode) > 1) {
850
851
852
853
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

854
855
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
856
857
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
858
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
859
860
      break;

861
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
862
    case irms_float_number:
863
      switch (get_mode_sort(m)) {
864
        case irms_float_number:
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
          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);
880

881
882
883
884
885
886
887
888
889
890
        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:
891
              assert(0);
892
893
              break;
          }
894
          /* FIXME: floating point unit can't produce a value in integer
895
896
897
898
899
900
901
902
           * representation
           * an intermediate representation is needed here first. */
          /*  return get_tarval(); */
          return tarval_bad;

        default:
          /* the rest can't be converted */
          return tarval_bad;
903
      }
Christian Schäfer's avatar
Christian Schäfer committed
904
905
      break;

906
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
907
    case irms_int_number:
908
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
909
910
        case irms_int_number:
        case irms_character:
911
          return get_tarval_overflow(src->value, src->length, m);
912

Michael Beck's avatar
Michael Beck committed
913
        case irms_internal_boolean:
914
915
916
917
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

918
919
920
921
922
923
924
925
926
        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));
927
          buffer[100 - 1] = '\0';
928
929
930
931
932
933
934
935
936
937
938
939
940
          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);
941

942
943
944
945
946
        case irms_reference:
          /* allow 0 to be casted */
          if (src == get_mode_null(src->mode))
            return get_mode_null(m);
          break;
947

948
949
950
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
951
952
      break;

Michael Beck's avatar
Michael Beck committed
953
    case irms_internal_boolean:
954
955
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
956
        case irms_int_number:
957
958
          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
959

960
961
962
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
963
964
      break;

Michael Beck's avatar
Michael Beck committed
965
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
966
      break;
Michael Beck's avatar
Michael Beck committed
967
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
968
      break;
969
  }
Christian Schäfer's avatar
Christian Schäfer committed
970

971
972
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
973

Michael Beck's avatar
Michael Beck committed
974
/*
975
976
977
978
979
980
981
982
983
 * bitwise negation
 */
tarval *tarval_not(tarval *a)
{
  char *buffer;

  ANNOUNCE();
  assert(a);

984
985
  /* works for vector mode without changes */

986
987
988
989
990
991
992
  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);

993
994
995
996
997
998
999
    case irms_internal_boolean:
      if (a == tarval_b_true)
        return tarval_b_false;
      if (a == tarval_b_false)
        return tarval_b_true;
      return tarval_bad;

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