Commit ad7ea5e7 authored by Götz Lindenmaier's avatar Götz Lindenmaier
Browse files

New implementation of tarval module

[r981]
parent 6b68a38a
......@@ -14,7 +14,7 @@ INSTALL_HEADERS = tv.h
SOURCES = $(INSTALL_HEADERS)
SOURCES += Makefile.in ieee754.h tv.c tv_t.h
SOURCES += Makefile.in tv.c tv_t.h strcalc.c strcalc.h fltcalc.c fltcalc.h ieee754.h
include $(topdir)/MakeRules
......
/* fltcalc.c
* Authors: Matthias Heil
*/
#include "fltcalc.h"
#include "ieee754.h"
#include <string.h>
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
/********
* globals
********/
static long double value;
#define CAST_IN(val) (*((long double *)((val))))
#define CAST_OUT(val) ((void *)&(val))
#define CLEAR_BUFFER() memset((char*)&value, 0, sizeof(long double))
/********
* private functions
********/
/********
* functions defined in fltcalc.h
********/
const void *fc_get_buffer(void)
{
return CAST_OUT(value);
}
const int fc_get_buffer_length(void)
{
return sizeof(long double);
}
void fc_val_from_str(const char *str, unsigned int len)
{
CLEAR_BUFFER();
value = strtold(str, NULL);
}
void fc_val_from_float(long double l)
{
CLEAR_BUFFER();
value = l;
}
long double fc_val_to_float(const void *val)
{
return CAST_IN(val);
}
void fc_get_min(unsigned int num_bits)
{
CLEAR_BUFFER();
switch (num_bits)
{
case 32:
value = FLT_MIN;
break;
case 64:
value = DBL_MIN;
break;
case 80:
default:
value = LDBL_MIN;
break;
}
}
void fc_get_max(unsigned int num_bits)
{
CLEAR_BUFFER();
switch (num_bits)
{
case 32:
value = FLT_MAX;
break;
case 64:
value = DBL_MAX;
break;
case 80:
default:
value = LDBL_MAX;
break;
}
}
void fc_get_nan(void)
{
/* nan: all exponent bit set, non-zero mantissa. not signalling wheni
* msb of mantissa is set (easily found using this struct */
union ieee854_long_double ld;
CLEAR_BUFFER();
ld.ieee_nan.negative = 0;
ld.ieee_nan.exponent = 0x7FFF;
ld.ieee_nan.quiet_nan = 1;
ld.ieee_nan.mantissa0 = 42;
value = ld.d;
}
void fc_get_inf(void)
{
/* +-inf: all exponent bit set, sign is easy, one is strange XXX */
union ieee854_long_double ld;
CLEAR_BUFFER();
ld.ieee_nan.negative = 0;
ld.ieee_nan.exponent = 0x7FFF;
ld.ieee_nan.quiet_nan = 0;
ld.ieee_nan.one = 1;
ld.ieee_nan.mantissa0 = 0;
ld.ieee_nan.mantissa1 = 0;
value = ld.d;
}
void fc_calc(const void *a, const void *b, int opcode)
{
CLEAR_BUFFER();
switch (opcode)
{
case FC_ADD:
value = CAST_IN(a) + CAST_IN(b);
break;
case FC_SUB:
value = CAST_IN(a) - CAST_IN(b);
break;
case FC_MUL:
value = CAST_IN(a) * CAST_IN(b);
break;
case FC_DIV:
value = CAST_IN(a) / CAST_IN(b);
break;
case FC_NEG:
value = -CAST_IN(a);
}
}
int fc_comp(const void *a, const void *b)
{
if (CAST_IN(a) == CAST_IN(b)) return 0;
else return (CAST_IN(a) > CAST_IN(b))?(1):(-1);
}
char *fc_print_dec(const void *a)
{
static char buf[100];
snprintf(buf, 100, "%1.30Lg", CAST_IN(a));
return buf;
}
#ifndef _FLTCALC_H_
#define _FLTCALC_H_
enum {
FC_ADD,
FC_SUB,
FC_MUL,
FC_DIV,
FC_NEG,
};
#define fc_add(a, b) fc_calc((a), (b), FC_ADD)
#define fc_sub(a, b) fc_calc((a), (b), FC_SUB)
#define fc_mul(a, b) fc_calc((a), (b), FC_MUL)
#define fc_div(a, b) fc_calc((a), (b), FC_DIV)
#define fc_neg(a) fc_calc((a), NULL, FC_NEG)
const void *fc_get_buffer(void);
const int fc_get_buffer_length(void);
void fc_val_from_str(const char *str, unsigned int len);
void fc_val_from_float(long double l);
long double fc_val_to_float(const void *val);
void fc_get_min(unsigned int num_bits);
void fc_get_max(unsigned int num_bits);
void fc_get_nan(void);
void fc_get_inf(void);
void fc_calc(const void *a, const void *b, int opcode);
char *fc_print_dec(const void *a);
int fc_comp(const void *a, const void *b);
#endif /* _FLTCALC_H_ */
/* IEEE754 fp format.
Copyright (C) 1995, 1996 Christian von Roques */
/* $Id$ */
/* This file was derived from the GNU C Library's ieee754.h which
carried the following copyright notice:
Copyright (C) 1992 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
/* @@@ This is completely non-portable! ISO/IEC DIS 9899, section
3.5.2.1: An implementation may allocate any addressable storage
unit large enough to hold a bit-field. If enough space remains, a
bit-field that immediately follows another bit-field in a structure
shall be packed into adjacent bits of the same unit. If
insufficient space remains, whether a bit-field that does not fit
is put into the next unit or overlaps adjacent units is
implementation-defined. The order of allocation of bit-fields
within a unit (high-order to low-order or low-order to high-order)
is implementation-defined. */
/* Floating point definitions in ieee standard number 754
only used in target values (/libfirm/ir/tv/tv.c). */
/* Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _IEEE754_H
#define _IEEE754_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#define _IEEE754_H 1
#include <features.h>
#include <endian.h>
__BEGIN_DECLS
union ieee754_float
{
float f;
/* This is the IEEE 754 single-precision format. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int mantissa:23;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int negative:1;
#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int quiet_nan:1;
unsigned int mantissa:22;
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int mantissa:22;
unsigned int quiet_nan:1;
unsigned int exponent:8;
unsigned int negative:1;
#endif /* Little endian. */
} ieee_nan;
};
#define IEEE754_FLOAT_BIAS 0x7f /* Added to exponent. */
union ieee754_double
......@@ -51,75 +72,128 @@ union ieee754_double
/* This is the IEEE 754 double-precision format. */
struct
{
#ifdef WORDS_BIGENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:11;
/* Together these comprise the mantissa. */
unsigned int mantissa0:20;
unsigned int mantissa1:32;
#else
#endif /* Big endian. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
# else
/* Together these comprise the mantissa. */
unsigned int mantissa1:32;
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
#endif
# endif
#endif /* Little endian. */
} ieee;
/* This format makes it easier to see if a NaN is a signalling NaN. */
struct
{
#ifdef WORDS_BIGENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:11;
unsigned int quiet_nan:1;
/* Together these comprise the mantissa. */
unsigned int mantissa0:19;
unsigned int mantissa1:32;
#else
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int mantissa0:19;
unsigned int quiet_nan:1;
unsigned int exponent:11;
unsigned int negative:1;
unsigned int mantissa1:32;
# else
/* Together these comprise the mantissa. */
unsigned int mantissa1:32;
unsigned int mantissa0:19;
unsigned int quiet_nan:1;
unsigned int exponent:11;
unsigned int negative:1;
# endif
#endif
} ieee_nan;
};
/* bias added to exponent of ieee754_double */
#define _IEEE754_DOUBLE_BIAS 0x3ff
#define IEEE754_DOUBLE_BIAS 0x3ff /* Added to exponent. */
union ieee754_float
union ieee854_long_double
{
float f;
long double d;
/* This is the ieee754 single-precision format. */
/* This is the IEEE 854 double-extended-precision format. */
struct
{
#ifdef WORDS_BIGENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int mantissa:23;
#else
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int exponent:15;
unsigned int empty:16;
unsigned int mantissa0:32;
unsigned int mantissa1:32;
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
unsigned int mantissa0:32;
unsigned int mantissa1:32;
# else
unsigned int mantissa1:32;
unsigned int mantissa0:32;
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
# endif
#endif
} ieee;
/* This is for extracting information about NaNs. */
/* This is for NaNs in the IEEE 854 double-extended-precision format. */
struct
{
#ifdef WORDS_BIGENDIAN
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int negative:1;
unsigned int exponent:8;
unsigned int exponent:15;
unsigned int empty:16;
unsigned int one:1;
unsigned int quiet_nan:1;
unsigned int mantissa:22;
#else
unsigned int mantissa:22;
unsigned int mantissa0:30;
unsigned int mantissa1:32;
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
# if __FLOAT_WORD_ORDER == BIG_ENDIAN
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
unsigned int mantissa0:30;
unsigned int quiet_nan:1;
unsigned int exponent:8;
unsigned int one:1;
unsigned int mantissa1:32;
# else
unsigned int mantissa1:32;
unsigned int mantissa0:30;
unsigned int quiet_nan:1;
unsigned int one:1;
unsigned int exponent:15;
unsigned int negative:1;
unsigned int empty:16;
# endif
#endif
} ieee_nan;
};
/* bias added to exponent of ieee_float */
#define _IEEE754_FLOAT_BIAS 0x7f
#define IEEE854_LONG_DOUBLE_BIAS 0x3fff
__END_DECLS
#endif /* _IEEE754_H */
#endif /* ieee754.h */
This diff is collapsed.
/****h* tools/strcalc
*
* NAME
* strcalc -- calculations using strings
* Provides basic mathematical operations on values represented as strings
*
* AUTHORS
* Matthias Heil
*
* DESCRIPTION
* The module uses a string to represent values, and provides operations
* to perform calculations with these values.
* Results are stored in an internal buffer, so you have to make a copy
* of them if you need to store the result.
*
******/
#ifndef _STRCALC_H_
#define _STRCALC_H_
#define BIGGEST_INTEGER_SIZE_IN_BYTES 8
#define SCDEBUG
/*****************************************************************************
* typedefs, enums and structs
*****************************************************************************/
enum {
SC_0 = 0,
SC_1,
SC_2,
SC_3,
SC_4,
SC_5,
SC_6,
SC_7,
SC_8,
SC_9,
SC_A,
SC_B,
SC_C,
SC_D,
SC_E,
SC_F,
};
enum {
SC_ADD = 0,
SC_SUB,
SC_NEG,
SC_MUL,
SC_DIV,
SC_MOD,
SC_SHL,
SC_SHR,
SC_SHRS,
SC_ROT,
SC_AND,
SC_OR,
SC_NOT,
SC_XOR,
};
enum {
SC_HEX,
SC_DEC,
SC_OKT,
SC_BIN,
};
/*****************************************************************************
* definitions and macros
*****************************************************************************/
#define sc_add(a, b) sc_calc((a), (b), SC_ADD)
#define sc_sub(a, b) sc_calc((a), (b), SC_SUB)
#define sc_neg(a) sc_calc((a), NULL, SC_NEG)
#define sc_and(a, b) sc_calc((a), (b), SC_AND)
#define sc_or(a, b) sc_calc((a), (b), SC_OR)
#define sc_xor(a, b) sc_calc((a), (b), SC_XOR)
#define sc_not(a) sc_calc((a), NULL, SC_NOT)
#define sc_mul(a, b) sc_calc((a), (b), SC_MUL)
#define sc_div(a, b) sc_calc((a), (b), SC_DIV)
#define sc_mod(a, b) sc_calc((a), (b), SC_MOD)
#define sc_shl(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_SHL)
#define sc_shr(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_SHR)
#define sc_shrs(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_SHRS)
#define sc_rot(a, b, c, d) sc_bitcalc((a), (b), (c), (d), SC_ROT)
#define sc_print_hex(a) sc_print((a), SC_HEX)
#define sc_print_dec(a) sc_print((a), SC_DEC)
#define sc_print_okt(a) sc_print((a), SC_OKT)
#define sc_print_bin(a) sc_print((a), SC_BIN)
/*****************************************************************************
* function declarations
*****************************************************************************/
const void *sc_get_buffer(void);
const int sc_get_buffer_length(void);
void sc_val_from_str(const char *str, unsigned int len);
void sc_val_from_long(long l);
long sc_val_to_long(const void *val);
void sc_min_from_bits(unsigned int num_bits, unsigned int sign);
void sc_max_from_bits(unsigned int num_bits, unsigned int sign);
void sc_calc(const void *val1, const void *val2, unsigned op);
void sc_bitcalc(const void *val1, const void *val2, unsigned radius, unsigned sign, unsigned op);
int sc_comp(const void *val1, const void *val2);
char* sc_print(const void *val1, unsigned base);
#endif /* _STRCALC_H_ */
This diff is collapsed.
This diff is collapsed.
......@@ -12,26 +12,38 @@
#ifndef _TV_T_H_
#define _TV_T_H_
# include "tv.h"
# include "misc.h"
#include "tv.h"
#include "xprintf.h"
/****s* tv/tarval
*
* NAME
* tarval
* This struct represents the aforementioned tarvals.
*
* DESCRIPTION
* A tarval struct consists of an internal representation of the
* value and some additional fields further describing the value.
*
* ATTRIBUTES
* ir_mode *mode The mode of the stored value
* void *value The internal representation
*
* SEE ALSO
* irmode.h for predefined modes
*
******/
struct tarval {
ir_mode *mode; /* mode of the stored value */
const void *value; /* the value stored in an internal way... */
unsigned int length; /* the length of the stored value */
};
/* xfprint output */
int tarval_print (XP_PAR1, const xprintf_info *, XP_PARN);
/** Hash function on tarvals */
unsigned tarval_hash (tarval *);
#ifdef NDEBUG
#define TARVAL_VRFY(val) ((void)0)
#else
#define TARVAL_VRFY(val) _tarval_vrfy ((val))
extern void _tarval_vrfy (const tarval *);
#endif
#ifdef STATS
void tarval_stats (void);
#else
#define tarval_stats() ((void)0)
#endif
/** remove tarval representing an entity that is about to be destroyed */
void free_tarval_entity(entity *ent);
#endif /* _TV_T_H_ */