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
#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
362
363
long tarval_to_long(tarval* tv)
{
  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
398
399
400
long double tarval_to_double(tarval *tv)
{
  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

405
/* The tarval represents the address of the entity.  As the address must
Beyhan's avatar
Beyhan committed
406
407
408
   be constant the entity must have as owner the global type.
 * We no more support this function: Use the new SymConst instead.
 */
409
tarval *new_tarval_from_entity (entity *ent, ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
410
{
411
412
  ANNOUNCE();
  assert(ent);
Michael Beck's avatar
Michael Beck committed
413
  assert(mode && (get_mode_sort(mode) == irms_reference));
Christian Schäfer's avatar
Christian Schäfer committed
414

415
  return get_tarval((void *)ent, 0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
416
}
Beyhan's avatar
Beyhan committed
417
418


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

Götz Lindenmaier's avatar
Götz Lindenmaier committed
428
429
430
#undef tarval_to_entity
entity *tarval_to_entity(tarval *tv) { return get_tarval_entity(tv); }
entity *get_tarval_entity(tarval *tv)
431
432
{
  ANNOUNCE();
Michael Beck's avatar
Michael Beck committed
433
  assert(tv);
Christian Schäfer's avatar
Christian Schäfer committed
434

Michael Beck's avatar
Michael Beck committed
435
436
437
438
439
440
  if (tarval_is_entity(tv))
    return (entity *)tv->value;
  else {
    assert(0 && "tarval did not represent an entity");
    return NULL;
  }
441
}
Christian Schäfer's avatar
Christian Schäfer committed
442

Matthias Heil's avatar
Matthias Heil committed
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
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();
}

458
459
460
461
/*
 * 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
462
{
463
464
465
466
  ANNOUNCE();
  assert(tv);
  return tv->mode;
}
Christian Schäfer's avatar
Christian Schäfer committed
467

468
469
470
471
472
473
474
475
476
/*
 * 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
477

478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
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
502
503
}

504
tarval *get_tarval_max(ir_mode *mode)
505
{
506
507
  ANNOUNCE();
  assert(mode);
508

509
510
511
512
513
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

514
515
  switch(get_mode_sort(mode))
  {
Michael Beck's avatar
Michael Beck committed
516
    case irms_reference:
Till Riedel's avatar
Till Riedel committed
517
518
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
519
    case irms_auxiliary:
520
521
      assert(0);
      break;
522

Michael Beck's avatar
Michael Beck committed
523
    case irms_internal_boolean:
524
      return tarval_b_true;
525

Michael Beck's avatar
Michael Beck committed
526
    case irms_float_number:
527
528
529
530
531
532
533
534
535
536
537
538
      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;
      }
539
      return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
540

Michael Beck's avatar
Michael Beck committed
541
542
    case irms_int_number:
    case irms_character:
543
      sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
544
545
546
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
547
548
}

549
tarval *get_tarval_min(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
550
{
551
552
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
553

554
555
556
557
558
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

Michael Beck's avatar
Michael Beck committed
568
    case irms_internal_boolean:
569
      return tarval_b_false;
Christian Schäfer's avatar
Christian Schäfer committed
570

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

Michael Beck's avatar
Michael Beck committed
586
587
    case irms_int_number:
    case irms_character:
588
      sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
589
590
591
      return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
592
593
}

594
tarval *get_tarval_null(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
595
{
596
597
  ANNOUNCE();
  assert(mode);
Götz Lindenmaier's avatar
Götz Lindenmaier committed
598

599
600
601
602
603
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

604
605
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
606
607
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
608
609
    case irms_auxiliary:
    case irms_internal_boolean:
610
611
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
612

Michael Beck's avatar
Michael Beck committed
613
    case irms_float_number:
614
      return new_tarval_from_double(0.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
615

Michael Beck's avatar
Michael Beck committed
616
617
    case irms_int_number:
    case irms_character:
618
      return new_tarval_from_long(0l,  mode);
Christian Schäfer's avatar
Christian Schäfer committed
619

Michael Beck's avatar
Michael Beck committed
620
    case irms_reference:
621
622
623
      return tarval_P_void;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
624
625
}

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

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

636
637
  switch(get_mode_sort(mode))
  {
Till Riedel's avatar
Till Riedel committed
638
639
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
640
641
642
    case irms_auxiliary:
    case irms_internal_boolean:
    case irms_reference:
643
644
      assert(0);
      break;
Christian Schäfer's avatar
Christian Schäfer committed
645

Michael Beck's avatar
Michael Beck committed
646
    case irms_float_number:
647
      return new_tarval_from_double(1.0, mode);
Christian Schäfer's avatar
Christian Schäfer committed
648

Michael Beck's avatar
Michael Beck committed
649
650
    case irms_int_number:
    case irms_character:
651
652
653
654
      return new_tarval_from_long(1l, mode);
      break;
  }
  return tarval_bad;
Christian Schäfer's avatar
Christian Schäfer committed
655
656
}

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

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

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

688
tarval *get_tarval_inf(ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
689
{
690
691
  ANNOUNCE();
  assert(mode);
Christian Schäfer's avatar
Christian Schäfer committed
692

693
694
695
696
697
  if (get_mode_vector_elems(mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

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

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

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

731
732
733
734
735
736
  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;
  }

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

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

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

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

782
783
784
  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;
785
786
787
788
789
790
  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
791

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

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

Michael Beck's avatar
Michael Beck committed
813
    case irms_internal_boolean:
814
815
816
817
818
      return (a == tarval_b_true)?(Gt):(Lt);
  }
  return False;
}

Michael Beck's avatar
Michael Beck committed
819
820
821
/*
 * convert to other mode
 */
822
823
tarval *tarval_convert_to(tarval *src, ir_mode *m)
{
824
  char *buffer;
Christian Schäfer's avatar
Christian Schäfer committed
825

Till Riedel's avatar
Till Riedel committed
826
  ANNOUNCE();
827
828
  assert(src);
  assert(m);
Christian Schäfer's avatar
Christian Schäfer committed
829

830
831
  if (src->mode == m) return src;

832
833
834
835
836
  if (get_mode_vector_elems(src->mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

837
838
  switch (get_mode_sort(src->mode))
  {
Till Riedel's avatar
Till Riedel committed
839
840
    case irms_control_flow:
    case irms_memory:
Michael Beck's avatar
Michael Beck committed
841
    case irms_auxiliary:
Christian Schäfer's avatar
Christian Schäfer committed
842
843
      break;

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

865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
        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;
882
      break;
883
884
885
886

        default:
          /* the rest can't be converted */
          return tarval_bad;
887
      }
Christian Schäfer's avatar
Christian Schäfer committed
888
889
      break;

890
    /* cast int to something */
Michael Beck's avatar
Michael Beck committed
891
    case irms_int_number:
892
      switch (get_mode_sort(m)) {
Michael Beck's avatar
Michael Beck committed
893
894
        case irms_int_number:
        case irms_character:
895
          return get_tarval_overflow(src->value, src->length, m);
896

Michael Beck's avatar
Michael Beck committed
897
        case irms_internal_boolean:
898
899
900
901
          /* XXX C semantics */
          if (src == get_mode_null(src->mode)) return tarval_b_false;
          else return tarval_b_true;

902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
        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);

925
926
927
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
928
929
      break;

Michael Beck's avatar
Michael Beck committed
930
    case irms_internal_boolean:
931
932
      switch (get_mode_sort(m))
      {
Michael Beck's avatar
Michael Beck committed
933
        case irms_int_number:
934
935
          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
936

937
938
939
        default:
          break;
      }
Christian Schäfer's avatar
Christian Schäfer committed
940
941
      break;

Michael Beck's avatar
Michael Beck committed
942
    case irms_character:
Christian Schäfer's avatar
Christian Schäfer committed
943
      break;
Michael Beck's avatar
Michael Beck committed
944
    case irms_reference:
Christian Schäfer's avatar
Christian Schäfer committed
945
      break;
946
  }
Christian Schäfer's avatar
Christian Schäfer committed
947

948
949
  return tarval_bad;
}
Christian Schäfer's avatar
Christian Schäfer committed
950

Michael Beck's avatar
Michael Beck committed
951
/*
952
953
954
955
956
957
958
959
960
961
 * 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 */

962
963
  /* works for vector mode without changes */

964
965
966
967
968
969
970
971
972
973
974
975
976
977
  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
978
979
 */
tarval *tarval_neg(tarval *a)
980
{
981
982
  char *buffer;

983
984
985
986
  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
987

988
989
990
991
992
  if (get_mode_vector_elems(a->mode) > 1) {
    /* vector arithmetic not implemented yet */
    return tarval_bad;
  }

993
994
  switch (get_mode_sort(a->mode))
  {
Michael Beck's avatar
Michael Beck committed
995
    case irms_int_number:
996
997
998
      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
999

Michael Beck's avatar
Michael Beck committed
1000
    case irms_float_number:
For faster browsing, not all history is shown. View entire blame