tv.c 41 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
47
#include "entity_t.h"       /* needed to store pointers to entities */
#include "irmode.h"         /* defines modes etc */
Michael Beck's avatar
Michael Beck committed
48
#include "irmode_t.h"
49
#include "irnode.h"         /* defines boolean return values (pnc_number)*/
50
51
52
#include "host.h"
#include "strcalc.h"
#include "fltcalc.h"
Christian Schäfer's avatar
Christian Schäfer committed
53

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

58
59
60
61
62
63
64
65
66
67
68
69
70
71
/* 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

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

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

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

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#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
107
{
108
109
110
111
112
113
  /* 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
114
}
Till Riedel's avatar
Till Riedel committed
115
116
117
#ifdef __GNUC__
INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused));
#endif
Christian Schäfer's avatar
Christian Schäfer committed
118

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

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

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

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

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

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

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
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
222
      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);
        }
      }
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
363
364
long tarval_to_long(tarval* tv)
{
  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
399
400
401
long double tarval_to_double(tarval *tv)
{
  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

406
407
408
/* The tarval represents the address of the entity.  As the address must
   be constant the entity must have as owner the global type. */
tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
409
{
410
411
  ANNOUNCE();
  assert(ent);
Michael Beck's avatar
Michael Beck committed
412
  assert(mode && (get_mode_sort(mode) == irms_reference));
Christian Schäfer's avatar
Christian Schäfer committed
413

414
  return get_tarval((void *)ent, 0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
415
}
416
int tarval_is_entity(tarval *tv)
Christian Schäfer's avatar
Christian Schäfer committed
417
{
418
419
420
  ANNOUNCE();
  assert(tv);
  /* tv->value == NULL means dereferencing a null pointer */
Till Riedel's avatar
Till Riedel committed
421
  return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0)
422
      && (tv != tarval_P_void));
Christian Schäfer's avatar
Christian Schäfer committed
423
}
Michael Beck's avatar
Michael Beck committed
424

425
426
427
entity *tarval_to_entity(tarval *tv)
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
428
  assert(tv);
Christian Schäfer's avatar
Christian Schäfer committed
429

Michael Beck's avatar
Michael Beck committed
430
431
432
433
434
435
  if (tarval_is_entity(tv))
    return (entity *)tv->value;
  else {
    assert(0 && "tarval did not represent an entity");
    return NULL;
  }
436
}
Christian Schäfer's avatar
Christian Schäfer committed
437

Matthias Heil's avatar
Matthias Heil committed
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
void free_tarval_entity(entity *ent) {
  /* There can be a tarval referencing this entity.  Even if the
     tarval is not used by the code any more, it can still reference
     the entity as tarvals live indepently of the entity referenced.
     Further the tarval is hashed into a set. If a hash function
     evaluation happens to collide with this tarval, we will vrfy that
     it contains a proper entity and we will crash if the entity is
     freed.

     Unluckily, tarvals can neither be changed nor deleted, and to find
     one, all existing reference modes have to be tried -> a facility
     to retrieve all modes of a kind is needed. */
  ANNOUNCE();
}

453
454
455
456
/*
 * 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
457
{
458
459
460
461
  ANNOUNCE();
  assert(tv);
  return tv->mode;
}
Christian Schäfer's avatar
Christian Schäfer committed
462

463
464
465
466
467
468
469
470
471
/*
 * 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
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
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
497
498
}

499
tarval *get_tarval_max(ir_mode *mode)
500
{
501
502
  ANNOUNCE();
  assert(mode);
503

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

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

Michael Beck's avatar
Michael Beck committed
518
    case irms_internal_boolean:
519
      return tarval_b_true;
520

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

Michael Beck's avatar
Michael Beck committed
536
537
    case irms_int_number:
    case irms_character:
538
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
539
540
541
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
542
543
}

544
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
545
{
546
547
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
548

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

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

Michael Beck's avatar
Michael Beck committed
563
    case irms_internal_boolean:
564
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
565

Michael Beck's avatar
Michael Beck committed
566
    case irms_float_number:
567
568
569
570
571
572
573
574
575
576
577
578
      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;
      }
579
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Christian Schäfer's avatar
Christian Schäfer committed
580

Michael Beck's avatar
Michael Beck committed
581
582
    case irms_int_number:
    case irms_character:
583
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
584
585
586
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
587
588
}

589
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
590
{
591
592
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
593

594
595
596
597
598
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

599
600
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
601
602
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
603
604
    case irms_auxiliary:
    case irms_internal_boolean:
605
606
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
607

Michael Beck's avatar
Michael Beck committed
608
    case irms_float_number:
609
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
610

Michael Beck's avatar
Michael Beck committed
611
612
    case irms_int_number:
    case irms_character:
613
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
614

Michael Beck's avatar
Michael Beck committed
615
    case irms_reference:
616
617
618
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
619
620
}

621
tarval *get_tarval_one(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
622
{
623
624
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
625

626
627
628
629
630
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

631
632
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
633
634
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
635
636
637
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
638
639
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
640

Michael Beck's avatar
Michael Beck committed
641
    case irms_float_number:
642
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
643

Michael Beck's avatar
Michael Beck committed
644
645
    case irms_int_number:
    case irms_character:
646
647
648
649
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
650
651
}

652
tarval *get_tarval_nan(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
653
{
654
655
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
656

657
658
659
660
661
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
662
  if (get_mode_sort(mode) == irms_float_number) {
663
664
665
666
667
668
669
670
671
672
673
674
    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;
    }
675
676
677
678
679
680
    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
681
682
}

683
tarval *get_tarval_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
684
{
685
686
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
687

688
689
690
691
692
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

Michael Beck's avatar
Michael Beck committed
693
  if (get_mode_sort(mode) == irms_float_number) {
694
695
696
697
698
699
700
701
702
703
704
705
    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;
    }
706
707
708
709
710
711
    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
712
713
}

714
715
716
/*
 * Arithmethic operations on tarvals ========================================
 */
Christian Schäfer's avatar
Christian Schäfer committed
717

Michael Beck's avatar
Michael Beck committed
718
719
720
/*
 * test if negative number, 1 means 'yes'
 */
721
int tarval_is_negative(tarval *a)
Christian Schäfer's avatar
Christian Schäfer committed
722
{
723
724
  ANNOUNCE();
  assert(a);
Christian Schäfer's avatar
Christian Schäfer committed
725

726
727
728
729
730
731
  if (get_mode_vector_elems(a->mode) > 1) {
    /* vector arithmetic not implemented yet */
    assert(0 && "tarval_is_negative is not allowed for vector modes");
    return 0;
  }

732
733
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
734
    case irms_int_number:
735
      if (!mode_is_signed(a->mode)) return 0;
Michael Beck's avatar
Michael Beck committed
736
      else
737
    return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0;
Christian Schäfer's avatar
Christian Schäfer committed
738

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

742
743
    default:
      assert(0 && "not implemented");
744
      return 0;
745
  }
Christian Schäfer's avatar
Christian Schäfer committed
746
747
}

Michael Beck's avatar
Michael Beck committed
748
749
750
751
752
753
754
755
756
757
/*
 * 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
758
759
760
761
762
763
764
765
766
767
/*
 * 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
768
769
770
/*
 * comparison
 */
771
pnc_number tarval_cmp(tarval *a, tarval *b)
Christian Schäfer's avatar
Christian Schäfer committed
772
{
773
774
775
  ANNOUNCE();
  assert(a);
  assert(b);
Christian Schäfer's avatar
Christian Schäfer committed
776

777
778
779
  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;
780
781
782
783
784
785
  if (a->mode != b->mode) return False;

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

787
788
789
  /* Here the two tarvals are unequal and of the same mode */
  switch (get_mode_sort(a->mode))
  {
Till Riedel's avatar
Till Riedel committed
790
791
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
792
    case irms_auxiliary:
793
    case irms_reference:
794
      return False;
Christian Schäfer's avatar
Christian Schäfer committed
795

Michael Beck's avatar
Michael Beck committed
796
    case irms_float_number:
797
798
799
800
801
802
803
      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
804
805
    case irms_int_number:
    case irms_character:
806
      return (sc_comp(a->value, b->value)==1)?(Gt):(Lt);
Christian Schäfer's avatar
Christian Schäfer committed
807

Michael Beck's avatar
Michael Beck committed
808
    case irms_internal_boolean:
809
810
811
812
813
      return (a == tarval_b_true)?(Gt):(Lt);
  }
  return False;
}

Michael Beck's avatar
Michael Beck committed
814
815
816
/*
 * convert to other mode
 */
817
818
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
819
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
820

Till Riedel's avatar
Till Riedel committed
821
  ANNOUNCE();
822
823
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
824

825
826
  if (src->mode == m) return src;

827
828
829
830
831
  if (get_mode_vector_elems(src->mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

832
833
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
834
835
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
836
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
837
838
      break;

839
    /* cast float to something */
Michael Beck's avatar
Michael Beck committed
840
    case irms_float_number:
841
      switch (get_mode_sort(m)) {
842
    case irms_float_number:
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
          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);
858
      break;
859

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

        default:
          /* the rest can't be converted */
          return tarval_bad;
882
      }
Christian Schäfer's avatar
Christian Schäfer committed
883
884
      break;

885
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
886
    case irms_int_number:
887
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
888
889
        case irms_int_number:
        case irms_character:
890
          return get_tarval_overflow(src->value, src->length, m);
891

Michael Beck's avatar
Michael Beck committed
892
        case irms_internal_boolean:
893
894
895
896
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
        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);

920
921
922
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
923
924
      break;

Michael Beck's avatar
Michael Beck committed
925
    case irms_internal_boolean:
926
927
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
928
        case irms_int_number:
929
930
          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
931

932
933
934
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
935
936
      break;

Michael Beck's avatar
Michael Beck committed
937
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
938
      break;
Michael Beck's avatar
Michael Beck committed
939
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
940
      break;
941
  }
Christian Schäfer's avatar
Christian Schäfer committed
942

943
944
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
945

Michael Beck's avatar
Michael Beck committed
946
/*
947
948
949
950
951
952
953
954
955
956
 * 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 */

957
958
  /* works for vector mode without changes */

959
960
961
962
963
964
965
966
967
968
969
970
971
972
  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
973
974
 */
tarval *tarval_neg(tarval *a)
975
{
976
977
  char *buffer;

978
979
980
981
  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
982

983
984
985
986
987
  if (get_mode_vector_elems(a->mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

988
989
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
990
    case irms_int_number:
991
992
993
      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
994

Michael Beck's avatar
Michael Beck committed
995
    case irms_float_number:
996
997
      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
998

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