tv.c 39.4 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
59
60
61
62
63
64
65
66
67
68
69
70
/* XXX hack until theres's a proper interface */
#define BAD 1
#define SATURATE 2
#define WRAP 3
#define GET_OVERFLOW_MODE() BAD

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

71
72
73
74
75
76
77
78
/****************************************************************************
 *   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
79

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

83
84
#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)))
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#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 */

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

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

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

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

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

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

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

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

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

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

241

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
302
    case irms_reference:
303
      return get_tarval(str, len, 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();
Till Riedel's avatar
Till Riedel committed
316
  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
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

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

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

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

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

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

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

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

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

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

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

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

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

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

Matthias Heil's avatar
Matthias Heil committed
405

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
        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;
830
      break;
831
832
833
834

        default:
          /* the rest can't be converted */
          return tarval_bad;
835
      }
Christian Schäfer's avatar
Christian Schäfer committed
836
837
      break;

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

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

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

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

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

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

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

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

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

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

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

931
932
933
934
  ANNOUNCE();
  assert(a);
  assert(mode_is_num(a->mode)); /* negation only for numerical values */
  assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */
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);
Michael Beck's avatar
Michael Beck committed
967
  assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(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