tv.c 35.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Michael Beck's avatar
Michael Beck committed
6
7
8
9
10
11
/**
 * @file
 * @brief    Representation of and static computations on target machine
 *           values.
 * @date     2003
 * @author   Mathias Heil
yb9976's avatar
yb9976 committed
12
 * @brief
13
 *
Michael Beck's avatar
Michael Beck committed
14
15
16
17
 * Values are stored in a format depending upon chosen arithmetic
 * module. Default uses strcalc and fltcalc.
 * This implementation assumes:
 *  - target has IEEE-754 floating-point arithmetic.
18
 */
19
20
#include <assert.h>
#include <stdlib.h>
21
#include <string.h>
22
#include <stdlib.h>
23
#include <strings.h>
24

25
#include "bitfiddle.h"
26
#include "tv_t.h"
27
28
#include "set.h"
#include "entity_t.h"
Michael Beck's avatar
Michael Beck committed
29
#include "irmode_t.h"
30
#include "irnode.h"
31
32
#include "strcalc.h"
#include "fltcalc.h"
33
#include "util.h"
Michael Beck's avatar
Michael Beck committed
34
#include "xmalloc.h"
Michael Beck's avatar
Michael Beck committed
35
#include "firm_common.h"
36
#include "error.h"
Christian Schäfer's avatar
Christian Schäfer committed
37

Matthias Braun's avatar
Matthias Braun committed
38
39
/** Size of hash tables.  Should correspond to average number of distinct
 * constant target values */
40
#define N_CONSTANTS 2048
Götz Lindenmaier's avatar
Götz Lindenmaier committed
41

42
43
44
/****************************************************************************
 *   local definitions and macros
 ****************************************************************************/
45
46
#define INSERT_TARVAL(tv) (set_insert(ir_tarval, tarvals, (tv), sizeof(ir_tarval), hash_tv((tv))))
#define FIND_TARVAL(tv) (set_find(ir_tarval, tarvals, (tv), sizeof(ir_tarval), hash_tv((tv))))
47

48
49
#define INSERT_VALUE(val, size) (set_insert(char, values, (val), size, hash_val((val), size)))
#define FIND_VALUE(val, size) (set_find(char, values, (val), size, hash_val((val), size)))
50

Michael Beck's avatar
Michael Beck committed
51
52
53
54
55
56
/** A set containing all existing tarvals. */
static struct set *tarvals = NULL;
/** A set containing all existing values. */
static struct set *values = NULL;

/** The integer overflow mode. */
57
static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP;
58

59
/** Hash a tarval. */
60
static unsigned hash_tv(ir_tarval *tv)
61
{
62
	return (unsigned)((PTR_TO_INT(tv->value) ^ PTR_TO_INT(tv->mode)) + tv->length);
Christian Schäfer's avatar
Christian Schäfer committed
63
64
}

65
/** Hash a value. Treat it as a byte array. */
66
static unsigned hash_val(const void *value, size_t length)
67
{
Michael Beck's avatar
Michael Beck committed
68
	/* scramble the byte - array */
Matthias Braun's avatar
Matthias Braun committed
69
70
	unsigned hash = 0;
	for (size_t i = 0; i < length; ++i) {
Michael Beck's avatar
Michael Beck committed
71
72
73
74
		hash += (hash << 5) ^ (hash >> 27) ^ ((char*)value)[i];
		hash += (hash << 11) ^ (hash >> 17);
	}
	return hash;
Christian Schäfer's avatar
Christian Schäfer committed
75
76
}

77
78
static int cmp_tv(const void *p1, const void *p2, size_t n)
{
Matthias Braun's avatar
Matthias Braun committed
79
80
	const ir_tarval *tv1 = (const ir_tarval*) p1;
	const ir_tarval *tv2 = (const ir_tarval*) p2;
81
82
83
84
	(void) n;

	assert(tv1->kind == k_tarval);
	assert(tv2->kind == k_tarval);
85
	if (tv1->mode < tv2->mode)
86
		return -1;
87
	if (tv1->mode > tv2->mode)
88
		return 1;
89
	if (tv1->length < tv2->length)
90
		return -1;
91
	if (tv1->length > tv2->length)
92
		return 1;
93
	if (tv1->value < tv2->value)
94
		return -1;
95
	if (tv1->value > tv2->value)
96
97
98
99
100
		return 1;

	return 0;
}

Michael Beck's avatar
Michael Beck committed
101
/** finds tarval with value/mode or creates new tarval */
102
static ir_tarval *get_tarval(const void *value, size_t length, ir_mode *mode)
103
{
Matthias Braun's avatar
Matthias Braun committed
104
	ir_tarval tv;
Michael Beck's avatar
Michael Beck committed
105
106
107
108
109
110
	tv.kind   = k_tarval;
	tv.mode   = mode;
	tv.length = length;
	if (length > 0) {
		/* if there already is such a value, it is returned, else value
		 * is copied into the set */
Matthias Braun's avatar
Matthias Braun committed
111
		char *temp = ALLOCAN(char, length);
112
		memcpy(temp, value, length);
113
		if (get_mode_arithmetic(mode) == irma_twos_complement) {
114
115
			sign_extend(temp, mode);
		}
116
		tv.value = INSERT_VALUE(temp, length);
Michael Beck's avatar
Michael Beck committed
117
118
119
120
121
	} else {
		tv.value = value;
	}
	/* if there is such a tarval, it is returned, else tv is copied
	 * into the set */
122
	return INSERT_TARVAL(&tv);
Christian Schäfer's avatar
Christian Schäfer committed
123
124
}

Matthias Braun's avatar
Matthias Braun committed
125
126
127
/** handle overflow */
static ir_tarval *get_tarval_overflow(const void *value, size_t length,
                                      ir_mode *mode)
Christian Schäfer's avatar
Christian Schäfer committed
128
{
Michael Beck's avatar
Michael Beck committed
129
	switch (get_mode_sort(mode)) {
Matthias Braun's avatar
Matthias Braun committed
130
	case irms_reference: {
131
		/* addresses always wrap around */
Matthias Braun's avatar
Matthias Braun committed
132
		char *temp = ALLOCAN(char, sc_get_buffer_length());
133
		memcpy(temp, value, sc_get_buffer_length());
134
		sc_truncate(get_mode_size_bits(mode), temp);
135
136
137
		/* the sc_ module expects that all bits are set ... */
		sign_extend(temp, mode);
		return get_tarval(temp, length, mode);
Matthias Braun's avatar
Matthias Braun committed
138
	}
139

Michael Beck's avatar
Michael Beck committed
140
	case irms_int_number:
141
		if (sc_comp(value, get_mode_max(mode)->value) == ir_relation_greater) {
142
			switch (tarval_get_integer_overflow_mode()) {
Michael Beck's avatar
Michael Beck committed
143
144
			case TV_OVERFLOW_SATURATE:
				return get_mode_max(mode);
Matthias Braun's avatar
Matthias Braun committed
145
146
			case TV_OVERFLOW_WRAP: {
				char *temp = ALLOCAN(char, sc_get_buffer_length());
147
				memcpy(temp, value, sc_get_buffer_length());
148
				sc_truncate(get_mode_size_bits(mode), temp);
149
150
151
				/* the sc_ module expects that all bits are set ... */
				sign_extend(temp, mode);
				return get_tarval(temp, length, mode);
Matthias Braun's avatar
Matthias Braun committed
152
			}
Michael Beck's avatar
Michael Beck committed
153
154
155
156
157
158
			case TV_OVERFLOW_BAD:
				return tarval_bad;
			default:
				return get_tarval(value, length, mode);
			}
		}
159
		if (sc_comp(value, get_mode_min(mode)->value) == ir_relation_less) {
160
			switch (tarval_get_integer_overflow_mode()) {
Michael Beck's avatar
Michael Beck committed
161
162
163
			case TV_OVERFLOW_SATURATE:
				return get_mode_min(mode);
			case TV_OVERFLOW_WRAP: {
Matthias Braun's avatar
Matthias Braun committed
164
				char *temp = ALLOCAN(char, sc_get_buffer_length());
165
				memcpy(temp, value, sc_get_buffer_length());
166
				sc_truncate(get_mode_size_bits(mode), temp);
Michael Beck's avatar
Michael Beck committed
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
				return get_tarval(temp, length, mode);
			}
			case TV_OVERFLOW_BAD:
				return tarval_bad;
			default:
				return get_tarval(value, length, mode);
			}
		}
		break;

	case irms_float_number:
		break;

	default:
		break;
	}
	return get_tarval(value, length, mode);
Christian Schäfer's avatar
Christian Schäfer committed
184
185
}

Matthias Braun's avatar
Matthias Braun committed
186
187
static ir_tarval reserved_tv[2];
static ir_tarval nonconst_tvs[4];
188

Matthias Braun's avatar
Matthias Braun committed
189
190
ir_tarval *tarval_b_false     = &reserved_tv[0];
ir_tarval *tarval_b_true      = &reserved_tv[1];
Matthias Braun's avatar
Matthias Braun committed
191
192
193
194
ir_tarval *tarval_bad         = &nonconst_tvs[0];
ir_tarval *tarval_undefined   = &nonconst_tvs[1];
ir_tarval *tarval_reachable   = &nonconst_tvs[2];
ir_tarval *tarval_unreachable = &nonconst_tvs[3];
Christian Schäfer's avatar
Christian Schäfer committed
195

Michael Beck's avatar
Michael Beck committed
196
197
198
/**
 * get the float descriptor for given mode.
 */
199
200
201
static const float_descriptor_t *get_descriptor(const ir_mode *mode)
{
	return &mode->float_desc;
Michael Beck's avatar
Michael Beck committed
202
203
}

204
205
206
207
208
209
210
211
212
213
static ir_tarval *get_tarval_from_fp_value(fp_value *val, ir_mode *mode)
{
	const float_descriptor_t *desc          = get_descriptor(mode);
	const int                 buffer_length = fc_get_buffer_length();
	fp_value                 *tmp           = alloca(buffer_length);
	memcpy(tmp, val, buffer_length);
	fp_value *casted_val = fc_cast(tmp, desc, NULL);
	return get_tarval(casted_val, buffer_length, mode);
}

Matthias Braun's avatar
Matthias Braun committed
214
215
ir_tarval *new_integer_tarval_from_str(const char *str, size_t len, char sign,
                                       unsigned char base, ir_mode *mode)
216
{
Matthias Braun's avatar
Matthias Braun committed
217
218
	char *buffer = ALLOCAN(char, sc_get_buffer_length());
	bool ok = sc_val_from_str(sign, base, str, len, buffer);
219
220
221
222
223
	if (!ok)
		return tarval_bad;

	return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
}
224

Matthias Braun's avatar
Matthias Braun committed
225
226
static ir_tarval *new_tarval_from_str_int(const char *str, size_t len,
                                          ir_mode *mode)
227
228
229
230
231
232
233
234
235
236
{
	/* skip leading spaces */
	while (len > 0 && str[0] == ' ') {
		++str;
		--len;
	}
	if (len == 0)
		return tarval_bad;

	/* 1 sign character allowed */
Matthias Braun's avatar
Matthias Braun committed
237
	char sign = 1;
238
239
240
241
242
243
244
245
246
247
248
	if (str[0] == '-') {
		sign = -1;
		++str;
		--len;
	} else if (str[0] == '+') {
		++str;
		--len;
	}

	/* a number starting with '0x' is hexadeciaml,
	 * a number starting with '0' (and at least 1 more char) is octal */
Matthias Braun's avatar
Matthias Braun committed
249
	unsigned base = 10;
250
251
252
253
254
	if (len >= 2 && str[0] == '0') {
		if (str[1] == 'x' || str[1] == 'X') {
			str += 2;
			len -= 2;
			base = 16;
255
256
257
258
		} else if (str[1] == 'b' || str[1] == 'B') {
			str += 2;
			len -= 2;
			base = 2;
259
260
261
262
263
264
265
266
267
		} else {
			++str;
			--len;
			base = 8;
		}
	}
	if (len == 0)
		return tarval_bad;

Matthias Braun's avatar
Matthias Braun committed
268
269
	char *buffer = ALLOCAN(char, sc_get_buffer_length());
	bool  ok     = sc_val_from_str(sign, base, str, len, buffer);
270
271
272
273
274
275
	if (!ok)
		return tarval_bad;

	return get_tarval_overflow(buffer, sc_get_buffer_length(), mode);
}

Matthias Braun's avatar
Matthias Braun committed
276
ir_tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode)
277
{
Matthias Braun's avatar
Matthias Braun committed
278
279
	assert(str != NULL);
	assert(len > 0);
Michael Beck's avatar
Michael Beck committed
280
281
282
283

	switch (get_mode_sort(mode)) {
	case irms_internal_boolean:
		/* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */
284
		if (!strcasecmp(str, "true"))
285
			return tarval_b_true;
286
287
		else if (!strcasecmp(str, "false"))
			return tarval_b_false;
Michael Beck's avatar
Michael Beck committed
288
289
290
291
		else
			/* XXX This is C semantics */
			return atoi(str) ? tarval_b_true : tarval_b_false;

292
293
294
295
	case irms_float_number: {
		fp_value *val = fc_val_from_str(str, len, NULL);
		return get_tarval_from_fp_value(val, mode);
	}
Michael Beck's avatar
Michael Beck committed
296
	case irms_reference:
297
298
		if (!strcasecmp(str, "null"))
			return get_tarval_null(mode);
299
		/* FALLTHROUGH */
Michael Beck's avatar
Michael Beck committed
300
	case irms_int_number:
301
		return new_tarval_from_str_int(str, len, mode);
302
303
	default:
		panic("Unsupported tarval creation with mode %F", mode);
Michael Beck's avatar
Michael Beck committed
304
	}
305
}
Christian Schäfer's avatar
Christian Schäfer committed
306

Matthias Braun's avatar
Matthias Braun committed
307
ir_tarval *new_tarval_from_long(long l, ir_mode *mode)
308
{
309
	switch (get_mode_sort(mode))   {
Michael Beck's avatar
Michael Beck committed
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	case irms_internal_boolean:
		/* XXX C semantics ! */
		return l ? tarval_b_true : tarval_b_false ;

	case irms_reference:
		/* same as integer modes */
	case irms_int_number:
		sc_val_from_long(l, NULL);
		return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);

	case irms_float_number:
		return new_tarval_from_double((long double)l, mode);

	default:
324
		panic("unsupported mode sort");
Michael Beck's avatar
Michael Beck committed
325
	}
Christian Schäfer's avatar
Christian Schäfer committed
326
}
Michael Beck's avatar
Michael Beck committed
327

Matthias Braun's avatar
Matthias Braun committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
ir_tarval *new_tarval_from_bytes(unsigned char const *buf,
                                 ir_mode *mode, int big_endian)
{
	switch (get_mode_arithmetic(mode)) {
	case irma_twos_complement:
		if (get_mode_size_bytes(mode) == (unsigned)-1)
			return tarval_bad;
		sc_val_from_bytes(buf, get_mode_size_bytes(mode), big_endian, NULL);
		return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
	case irma_ieee754:
	case irma_x86_extended_float:
		/* not implemented yet */
		return tarval_bad;
	case irma_none:
		break;
	}
	panic("tarval from byte requested for non storable mode");
}

Matthias Braun's avatar
Matthias Braun committed
347
int tarval_is_long(ir_tarval *tv)
348
{
349
350
	if (!mode_is_int(tv->mode) && !mode_is_reference(tv->mode))
		return 0;
Michael Beck's avatar
Michael Beck committed
351

Matthias Braun's avatar
Matthias Braun committed
352
	if (get_mode_size_bits(tv->mode) > (int) (sizeof(long) << 3)) {
Michael Beck's avatar
Michael Beck committed
353
354
		/* the value might be too big to fit in a long */
		sc_max_from_bits(sizeof(long) << 3, 0, NULL);
355
		if (sc_comp(sc_get_buffer(), tv->value) == ir_relation_less) {
Michael Beck's avatar
Michael Beck committed
356
357
358
359
360
			/* really doesn't fit */
			return 0;
		}
	}
	return 1;
361
}
Michael Beck's avatar
Michael Beck committed
362

Matthias Braun's avatar
Matthias Braun committed
363
long get_tarval_long(ir_tarval* tv)
364
{
365
	assert(tarval_is_long(tv));
Michael Beck's avatar
Michael Beck committed
366
	return sc_val_to_long(tv->value);
367
}
Christian Schäfer's avatar
Christian Schäfer committed
368

369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
bool tarval_is_uint64(ir_tarval *tv)
{
	if (!mode_is_int(tv->mode) && !mode_is_reference(tv->mode))
		return false;

	if (get_mode_size_bits(tv->mode) > (int) (sizeof(uint64_t) << 3)) {
		/* the value might be too big to fit in a long */
		sc_max_from_bits(sizeof(uint64_t) << 3, 0, NULL);
		if (sc_comp(sc_get_buffer(), tv->value) == ir_relation_less) {
			/* really doesn't fit */
			return false;
		}
	}
	return true;
}

uint64_t get_tarval_uint64(ir_tarval *tv)
{
	assert(tarval_is_uint64(tv));
	return sc_val_to_uint64(tv->value);
}

391
ir_tarval *new_tarval_from_long_double(long double d, ir_mode *mode)
392
{
Michael Beck's avatar
Michael Beck committed
393
	assert(mode && (get_mode_sort(mode) == irms_float_number));
394
395
	fp_value *val = fc_val_from_ieee754(d, NULL);
	return get_tarval_from_fp_value(val, mode);
Christian Schäfer's avatar
Christian Schäfer committed
396
}
Michael Beck's avatar
Michael Beck committed
397

398
399
400
401
402
ir_tarval *new_tarval_from_double(double d, ir_mode *mode)
{
	return new_tarval_from_long_double(d, mode);
}

Matthias Braun's avatar
Matthias Braun committed
403
int tarval_is_double(ir_tarval *tv)
404
{
Matthias Braun's avatar
Matthias Braun committed
405
	return get_mode_sort(tv->mode) == irms_float_number;
406
}
Michael Beck's avatar
Michael Beck committed
407

408
long double get_tarval_long_double(ir_tarval *tv)
409
{
Michael Beck's avatar
Michael Beck committed
410
	assert(tarval_is_double(tv));
411
	return fc_val_to_ieee754((const fp_value*) tv->value);
412
}
Christian Schäfer's avatar
Christian Schäfer committed
413

414
415
416
417
418
double get_tarval_double(ir_tarval *tv)
{
	return get_tarval_long_double(tv);
}

Matthias Braun's avatar
Matthias Braun committed
419
ir_mode *(get_tarval_mode)(const ir_tarval *tv)
420
{
Michael Beck's avatar
Michael Beck committed
421
	return _get_tarval_mode(tv);
422
423
}

424
425
426
427
428
429
430
/*
 * 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
Michael Beck's avatar
Michael Beck committed
431
 * therefore the irmode functions should be preferred to the functions below.
432
 */
Christian Schäfer's avatar
Christian Schäfer committed
433

Matthias Braun's avatar
Matthias Braun committed
434
ir_tarval *(get_tarval_bad)(void)
435
{
Michael Beck's avatar
Michael Beck committed
436
	return _get_tarval_bad();
437
}
Michael Beck's avatar
Michael Beck committed
438

Matthias Braun's avatar
Matthias Braun committed
439
ir_tarval *(get_tarval_undefined)(void)
440
{
Michael Beck's avatar
Michael Beck committed
441
	return _get_tarval_undefined();
442
}
Michael Beck's avatar
Michael Beck committed
443

Matthias Braun's avatar
Matthias Braun committed
444
ir_tarval *(get_tarval_b_false)(void)
445
{
Michael Beck's avatar
Michael Beck committed
446
	return _get_tarval_b_false();
447
}
Michael Beck's avatar
Michael Beck committed
448

Matthias Braun's avatar
Matthias Braun committed
449
ir_tarval *(get_tarval_b_true)(void)
450
{
Michael Beck's avatar
Michael Beck committed
451
	return _get_tarval_b_true();
452
}
Michael Beck's avatar
Michael Beck committed
453

Matthias Braun's avatar
Matthias Braun committed
454
ir_tarval *(get_tarval_reachable)(void)
455
{
456
457
458
	return _get_tarval_reachable();
}

Matthias Braun's avatar
Matthias Braun committed
459
ir_tarval *(get_tarval_unreachable)(void)
460
{
461
462
463
	return _get_tarval_unreachable();
}

Matthias Braun's avatar
Matthias Braun committed
464
ir_tarval *get_tarval_max(ir_mode *mode)
465
{
Michael Beck's avatar
Michael Beck committed
466
	switch (get_mode_sort(mode)) {
Michael Beck's avatar
Michael Beck committed
467
468
469
	case irms_internal_boolean:
		return tarval_b_true;

Matthias Braun's avatar
Matthias Braun committed
470
471
	case irms_float_number: {
		const float_descriptor_t *desc = get_descriptor(mode);
Michael Beck's avatar
Michael Beck committed
472
		fc_get_max(desc, NULL);
Michael Beck's avatar
Michael Beck committed
473
		return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Matthias Braun's avatar
Matthias Braun committed
474
	}
Michael Beck's avatar
Michael Beck committed
475

476
477
478
479
	case irms_reference:
	case irms_int_number:
		sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
		return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
480
481
	default:
		panic("mode %F does not support maximum value", mode);
Michael Beck's avatar
Michael Beck committed
482
	}
483
484
}

Matthias Braun's avatar
Matthias Braun committed
485
ir_tarval *get_tarval_min(ir_mode *mode)
486
{
Michael Beck's avatar
Michael Beck committed
487
	switch (get_mode_sort(mode)) {
Michael Beck's avatar
Michael Beck committed
488
489
490
	case irms_internal_boolean:
		return tarval_b_false;

Matthias Braun's avatar
Matthias Braun committed
491
492
	case irms_float_number: {
		const float_descriptor_t *desc = get_descriptor(mode);
Michael Beck's avatar
Michael Beck committed
493
		fc_get_min(desc, NULL);
Michael Beck's avatar
Michael Beck committed
494
		return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Matthias Braun's avatar
Matthias Braun committed
495
	}
Michael Beck's avatar
Michael Beck committed
496

497
498
499
500
	case irms_reference:
	case irms_int_number:
		sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
		return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
501
502
	default:
		panic("mode %F does not support minimum value", mode);
Michael Beck's avatar
Michael Beck committed
503
	}
Christian Schäfer's avatar
Christian Schäfer committed
504
505
}

Michael Beck's avatar
Michael Beck committed
506
/** The bit pattern for the pointer NULL */
507
static long _null_value = 0;
508

Matthias Braun's avatar
Matthias Braun committed
509
ir_tarval *get_tarval_null(ir_mode *mode)
510
{
Michael Beck's avatar
Michael Beck committed
511
	switch (get_mode_sort(mode)) {
Michael Beck's avatar
Michael Beck committed
512
513
514
	case irms_float_number:
		return new_tarval_from_double(0.0, mode);

515
	case irms_internal_boolean:
Michael Beck's avatar
Michael Beck committed
516
517
518
519
520
	case irms_int_number:
		return new_tarval_from_long(0l,  mode);

	case irms_reference:
		return new_tarval_from_long(_null_value, mode);
521
522
	default:
		panic("mode %F does not support null value", mode);
Michael Beck's avatar
Michael Beck committed
523
	}
Christian Schäfer's avatar
Christian Schäfer committed
524
525
}

Matthias Braun's avatar
Matthias Braun committed
526
ir_tarval *get_tarval_one(ir_mode *mode)
527
{
Michael Beck's avatar
Michael Beck committed
528
	switch (get_mode_sort(mode)) {
529
530
531
	case irms_internal_boolean:
		return tarval_b_true;

Michael Beck's avatar
Michael Beck committed
532
533
534
	case irms_float_number:
		return new_tarval_from_double(1.0, mode);

535
	case irms_reference:
Michael Beck's avatar
Michael Beck committed
536
537
	case irms_int_number:
		return new_tarval_from_long(1l, mode);
538
539
	default:
		panic("mode %F does not support one value", mode);
Michael Beck's avatar
Michael Beck committed
540
	}
Christian Schäfer's avatar
Christian Schäfer committed
541
542
}

Matthias Braun's avatar
Matthias Braun committed
543
ir_tarval *get_tarval_all_one(ir_mode *mode)
544
{
Michael Beck's avatar
Michael Beck committed
545
	switch (get_mode_sort(mode)) {
546
	case irms_int_number:
Michael Beck's avatar
Michael Beck committed
547
548
	case irms_internal_boolean:
	case irms_reference:
549
550
551
		return tarval_not(get_mode_null(mode));

	case irms_float_number:
Matthias Braun's avatar
Matthias Braun committed
552
		return tarval_bad;
553
554
555

	default:
		panic("mode %F does not support all-one value", mode);
556
557
558
	}
}

Matthias Braun's avatar
Matthias Braun committed
559
int tarval_is_constant(ir_tarval *tv)
560
{
Matthias Braun's avatar
Matthias Braun committed
561
562
	size_t const num_res = ARRAY_SIZE(nonconst_tvs);
	return tv < &nonconst_tvs[0] || &nonconst_tvs[num_res] <= tv;
563
564
}

Matthias Braun's avatar
Matthias Braun committed
565
ir_tarval *get_tarval_minus_one(ir_mode *mode)
566
{
Michael Beck's avatar
Michael Beck committed
567
	switch (get_mode_sort(mode)) {
568
569
570
	case irms_reference:
		return tarval_bad;

Michael Beck's avatar
Michael Beck committed
571
572
573
574
	case irms_float_number:
		return mode_is_signed(mode) ? new_tarval_from_double(-1.0, mode) : tarval_bad;

	case irms_int_number:
575
		return new_tarval_from_long(-1l, mode);
576
577
578

	default:
		panic("mode %F does not support minus one value", mode);
Michael Beck's avatar
Michael Beck committed
579
	}
580
581
}

Matthias Braun's avatar
Matthias Braun committed
582
ir_tarval *get_tarval_nan(ir_mode *mode)
583
{
Michael Beck's avatar
Michael Beck committed
584
	if (get_mode_sort(mode) == irms_float_number) {
Matthias Braun's avatar
Matthias Braun committed
585
		const float_descriptor_t *desc = get_descriptor(mode);
Michael Beck's avatar
Michael Beck committed
586
		fc_get_qnan(desc, NULL);
Michael Beck's avatar
Michael Beck committed
587
		return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
Matthias Braun's avatar
Matthias Braun committed
588
	} else {
589
		panic("mode %F does not support NaN value", mode);
Matthias Braun's avatar
Matthias Braun committed
590
	}
Christian Schäfer's avatar
Christian Schäfer committed
591
592
}

Matthias Braun's avatar
Matthias Braun committed
593
ir_tarval *get_tarval_plus_inf(ir_mode *mode)
594
{
Michael Beck's avatar
Michael Beck committed
595
	if (get_mode_sort(mode) == irms_float_number) {
596
		const float_descriptor_t *desc = get_descriptor(mode);
Michael Beck's avatar
Michael Beck committed
597
		fc_get_plusinf(desc, NULL);
Michael Beck's avatar
Michael Beck committed
598
		return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
599
600
	} else
		panic("mode %F does not support +inf value", mode);
Christian Schäfer's avatar
Christian Schäfer committed
601
602
}

Matthias Braun's avatar
Matthias Braun committed
603
ir_tarval *get_tarval_minus_inf(ir_mode *mode)
604
{
Michael Beck's avatar
Michael Beck committed
605
	if (get_mode_sort(mode) == irms_float_number) {
606
		const float_descriptor_t *desc = get_descriptor(mode);
Michael Beck's avatar
Michael Beck committed
607
		fc_get_minusinf(desc, NULL);
Michael Beck's avatar
Michael Beck committed
608
		return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
609
610
	} else
		panic("mode %F does not support -inf value", mode);
611
612
}

613
/*
614
 * Arithmetic operations on tarvals ========================================
615
 */
Christian Schäfer's avatar
Christian Schäfer committed
616

Matthias Braun's avatar
Matthias Braun committed
617
int tarval_is_negative(ir_tarval *a)
618
{
Michael Beck's avatar
Michael Beck committed
619
620
	switch (get_mode_sort(a->mode)) {
	case irms_int_number:
Matthias Braun's avatar
Matthias Braun committed
621
622
623
		if (!mode_is_signed(a->mode)) {
			return 0;
		} else {
624
			return sc_comp(a->value, get_mode_null(a->mode)->value) == ir_relation_less ? 1 : 0;
Matthias Braun's avatar
Matthias Braun committed
625
		}
Michael Beck's avatar
Michael Beck committed
626
627

	case irms_float_number:
628
		return fc_is_negative((const fp_value*) a->value);
Michael Beck's avatar
Michael Beck committed
629
630

	default:
631
		panic("mode %F does not support negation value", a->mode);
Michael Beck's avatar
Michael Beck committed
632
	}
Christian Schäfer's avatar
Christian Schäfer committed
633
634
}

Matthias Braun's avatar
Matthias Braun committed
635
int tarval_is_null(ir_tarval *a)
636
{
Matthias Braun's avatar
Matthias Braun committed
637
	return a != tarval_bad && a == get_mode_null(get_tarval_mode(a));
Michael Beck's avatar
Michael Beck committed
638
639
}

Matthias Braun's avatar
Matthias Braun committed
640
int tarval_is_one(ir_tarval *a)
641
{
Matthias Braun's avatar
Matthias Braun committed
642
	return a != tarval_bad && a == get_mode_one(get_tarval_mode(a));
643
}
Michael Beck's avatar
Michael Beck committed
644

Matthias Braun's avatar
Matthias Braun committed
645
int tarval_is_all_one(ir_tarval *tv)
646
{
Matthias Braun's avatar
Matthias Braun committed
647
	return tv != tarval_bad && tv == get_mode_all_one(get_tarval_mode(tv));
Michael Beck's avatar
Michael Beck committed
648
649
}

Matthias Braun's avatar
Matthias Braun committed
650
int tarval_is_minus_one(ir_tarval *a)
651
{
Matthias Braun's avatar
Matthias Braun committed
652
	return a != tarval_bad && a == get_mode_minus_one(get_tarval_mode(a));
Michael Beck's avatar
Michael Beck committed
653
654
}

655
ir_relation tarval_cmp(ir_tarval *a, ir_tarval *b)
656
{
Michael Beck's avatar
Michael Beck committed
657
	if (a == tarval_bad || b == tarval_bad) {
658
		panic("Comparison with tarval_bad");
Michael Beck's avatar
Michael Beck committed
659
660
661
	}

	if (a == tarval_undefined || b == tarval_undefined)
662
		return ir_relation_false;
Michael Beck's avatar
Michael Beck committed
663
664

	if (a->mode != b->mode)
665
		return ir_relation_false;
Michael Beck's avatar
Michael Beck committed
666
667
668
669
670
671
672
673

	/* Here the two tarvals are unequal and of the same mode */
	switch (get_mode_sort(a->mode)) {
	case irms_float_number:
		/*
		 * BEWARE: we cannot compare a == b here, because
		 * a NaN is always Unordered to any other value, even to itself!
		 */
674
675
		return fc_comp((fp_value const*)a->value, (fp_value const*)b->value);

676
	case irms_reference:
Michael Beck's avatar
Michael Beck committed
677
678
	case irms_int_number:
		if (a == b)
679
			return ir_relation_equal;
680
		return sc_comp(a->value, b->value);
Michael Beck's avatar
Michael Beck committed
681
682
683

	case irms_internal_boolean:
		if (a == b)
684
685
			return ir_relation_equal;
		return a == tarval_b_true ? ir_relation_greater : ir_relation_less;
686
687
688

	default:
		panic("can't compare values of mode %F", a->mode);
Michael Beck's avatar
Michael Beck committed
689
	}
690
691
}

Matthias Braun's avatar
Matthias Braun committed
692
ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
693
{
694
695
	if (src->mode == dst_mode)
		return src;
Michael Beck's avatar
Michael Beck committed
696
697

	switch (get_mode_sort(src->mode)) {
698
	/* cast float to something */
Michael Beck's avatar
Michael Beck committed
699
	case irms_float_number:
700
		switch (get_mode_sort(dst_mode)) {
Matthias Braun's avatar
Matthias Braun committed
701
702
		case irms_float_number: {
			const float_descriptor_t *desc = get_descriptor(dst_mode);
703
			fc_cast((const fp_value*) src->value, desc, NULL);
704
			return get_tarval(fc_get_buffer(), fc_get_buffer_length(), dst_mode);
Matthias Braun's avatar
Matthias Braun committed
705
		}
Michael Beck's avatar
Michael Beck committed
706

Matthias Braun's avatar
Matthias Braun committed
707
708
709
		case irms_int_number: {
			fp_value *res = fc_int((const fp_value*) src->value, NULL);
			char     *buffer = ALLOCAN(char, sc_get_buffer_length());
710
711
712
713
714
715
716
			flt2int_result_t cres = fc_flt2int(res, buffer, dst_mode);
			switch (cres) {
			case FLT2INT_POSITIVE_OVERFLOW:
				return get_mode_max(dst_mode);
			case FLT2INT_NEGATIVE_OVERFLOW:
				return get_mode_min(dst_mode);
			case FLT2INT_UNKNOWN:
717
				return tarval_bad;
718
719
720
			case FLT2INT_OK:
				return get_tarval(buffer, sc_get_buffer_length(), dst_mode);
			}
Matthias Braun's avatar
Matthias Braun committed
721
		}
Michael Beck's avatar
Michael Beck committed
722
723

		default:
724
			break;
Michael Beck's avatar
Michael Beck committed
725
		}
726
727
		/* the rest can't be converted */
		return tarval_bad;
Michael Beck's avatar
Michael Beck committed
728

729
	/* cast int/characters to something */
Michael Beck's avatar
Michael Beck committed
730
	case irms_int_number:
731
		switch (get_mode_sort(dst_mode)) {
732
733

		case irms_reference:
Matthias Braun's avatar
Matthias Braun committed
734
735
		case irms_int_number: {
			char *buffer = ALLOCAN(char, sc_get_buffer_length());
Michael Beck's avatar
Michael Beck committed
736
			memcpy(buffer, src->value, sc_get_buffer_length());
737
			return get_tarval_overflow(buffer, src->length, dst_mode);
Matthias Braun's avatar
Matthias Braun committed
738
		}
Michael Beck's avatar
Michael Beck committed
739
740
741
742
743
744

		case irms_internal_boolean:
			/* XXX C semantics */
			if (src == get_mode_null(src->mode)) return tarval_b_false;
			else return tarval_b_true;

Matthias Braun's avatar
Matthias Braun committed
745
		case irms_float_number: {
Michael Beck's avatar
Michael Beck committed
746
747
748
			/* XXX floating point unit does not understand internal integer
			 * representation, convert to string first, then create float from
			 * string */
Matthias Braun's avatar
Matthias Braun committed
749
			char *buffer = ALLOCAN(char, 100);
Michael Beck's avatar
Michael Beck committed
750
751
			/* decimal string representation because hexadecimal output is
			 * interpreted unsigned by fc_val_from_str, so this is a HACK */
Matthias Braun's avatar
Matthias Braun committed
752
			int len = snprintf(buffer, 100, "%s",
Michael Beck's avatar
Michael Beck committed
753
754
755
				sc_print(src->value, get_mode_size_bits(src->mode), SC_DEC, mode_is_signed(src->mode)));
			buffer[100 - 1] = '\0';

756
757
			fp_value *val = fc_val_from_str(buffer, len, NULL);
			return get_tarval_from_fp_value(val, dst_mode);
Matthias Braun's avatar
Matthias Braun committed
758
		}
Michael Beck's avatar
Michael Beck committed
759
760
761
762
763
764
		default:
			break;
		}
		break;

	case irms_internal_boolean:
765
		/* beware: this is C semantic for the INTERNAL boolean mode */
766
767
		if (get_mode_sort(dst_mode) == irms_int_number)
			return src == tarval_b_true ? get_mode_one(dst_mode) : get_mode_null(dst_mode);
Michael Beck's avatar
Michael Beck committed
768
769
770
		break;

	case irms_reference:
771
		if (get_mode_sort(dst_mode) == irms_int_number) {
Matthias Braun's avatar
Matthias Braun committed
772
			char *buffer = ALLOCAN(char, sc_get_buffer_length());
773
			memcpy(buffer, src->value, sc_get_buffer_length());
774
			sign_extend(buffer, src->mode);
775
			return get_tarval_overflow(buffer, src->length, dst_mode);
776
		}
Michael Beck's avatar
Michael Beck committed
777
		break;
778
779
	default:
		return tarval_bad;
Michael Beck's avatar
Michael Beck committed
780
781
782
	}

	return tarval_bad;
783
}
Christian Schäfer's avatar
Christian Schäfer committed
784

Matthias Braun's avatar
Matthias Braun committed
785
ir_tarval *tarval_not(ir_tarval *a)
786
{
Michael Beck's avatar
Michael Beck committed
787
	switch (get_mode_sort(a->mode)) {
788
	case irms_reference:
Matthias Braun's avatar
Matthias Braun committed
789
790
	case irms_int_number: {
		char *buffer = ALLOCAN(char, sc_get_buffer_length());
Michael Beck's avatar
Michael Beck committed
791
792
		sc_not(a->value, buffer);
		return get_tarval(buffer, a->length, a->mode);
Matthias Braun's avatar
Matthias Braun committed
793
	}
Michael Beck's avatar
Michael Beck committed
794
795
796
797
798
799
800
801
802

	case irms_internal_boolean:
		if (a == tarval_b_true)
			return tarval_b_false;
		if (a == tarval_b_false)
			return tarval_b_true;
		return tarval_bad;

	default:
803
		panic("bitwise negation is only allowed for integer and boolean");
Michael Beck's avatar
Michael Beck committed
804
	}
805
806
}

Matthias Braun's avatar
Matthias Braun committed
807
ir_tarval *tarval_neg(ir_tarval *a)
808
{
Michael Beck's avatar
Michael Beck committed
809
	assert(mode_is_num(a->mode)); /* negation only for numerical values */
810

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

Michael Beck's avatar
Michael Beck committed
813
	switch (get_mode_sort(a->mode)) {
Matthias Braun's avatar
Matthias Braun committed
814
815
	case irms_int_number: {
		char *buffer = ALLOCAN(char, sc_get_buffer_length());
Michael Beck's avatar
Michael Beck committed
816
817
		sc_neg(a->value, buffer);
		return get_tarval_overflow(buffer, a->length, a->mode);
Matthias Braun's avatar
Matthias Braun committed
818
	}
Christian Schäfer's avatar
Christian Schäfer committed
819

Michael Beck's avatar
Michael Beck committed
820
	case irms_float_number:
821
		fc_neg((const fp_value*) a->value, NULL);
Michael Beck's avatar
Michael Beck committed
822
		return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
Christian Schäfer's avatar
Christian Schäfer committed
823

Michael Beck's avatar
Michael Beck committed
824
825
826
	default:
		return tarval_bad;
	}
Christian Schäfer's avatar
Christian Schäfer committed
827
828
}

Matthias Braun's avatar
Matthias Braun committed
829
ir_tarval *tarval_add(ir_tarval *a, ir_tarval *b)
830
{
831
832
833
834
	if (mode_is_reference(a->mode) && a->mode != b->mode) {
		b = tarval_convert_to(b, a->mode);
	} else if (mode_is_reference(b->mode) && b->mode != a->mode) {
		a = tarval_convert_to(a, b->mode);
835
836
837
838
	}

	assert(a->mode == b->mode);

Michael Beck's avatar
Michael Beck committed
839
	switch (get_mode_sort(a->mode)) {
840
	case irms_reference:
Matthias Braun's avatar
Matthias Braun committed
841
	case irms_int_number: {
Michael Beck's avatar
Michael Beck committed
842
		/* modes of a,b are equal, so result has mode of a as this might be the character */
Matthias Braun's avatar
Matthias Braun committed
843
		char *buffer = ALLOCAN(char, sc_get_buffer_length());
Michael Beck's avatar
Michael Beck committed
844
		sc_add(a->value, b->value, buffer);
845
		return get_tarval_overflow(buffer, a->length, a->mode);
Matthias Braun's avatar
Matthias Braun committed
846
	}
Michael Beck's avatar
Michael Beck committed
847
848

	case irms_float_number:
849
		fc_add((const fp_value*) a->value, (const fp_value*) b->value, NULL);
850
		return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
Michael Beck's avatar
Michael Beck committed
851
852
853
854

	default:
		return tarval_bad;
	}
Christian Schäfer's avatar
Christian Schäfer committed
855
856
}

Matthias Braun's avatar
Matthias Braun committed
857
ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode)
858
{