Commit 0d1dddb3 authored by Michael Beck's avatar Michael Beck
Browse files

Cleaned up the tarval handling:

- removed the *_calc functions
- simplified floating point handling
- renamed functions

[r15291]
parent cbbed842
......@@ -576,7 +576,7 @@ tarval_classification_t classify_tarval(tarval *tv);
* Returns non-zero if a given (integer) tarval has only one single bit
* set.
*/
int is_single_bit_tarval(tarval *tv);
int tarval_is_single_bit(tarval *tv);
/**
* Output of tarvals to a buffer.
......@@ -588,4 +588,16 @@ int tarval_snprintf(char *buf, size_t buflen, tarval *tv);
*/
int tarval_printf(tarval *tv);
/**
* Returns non-zero if the mantissa of a floating point IEEE-754
* tarval is zero (i.e. 1.0Exxx)
*/
int tarval_ieee754_zero_mantissa(tarval *tv);
/**
* Returns the exponent of a floating point IEEE-754
* tarval.
*/
int tarval_ieee754_get_exponent(tarval *tv);
#endif /* FIRM_TV_TV_H */
......@@ -2983,7 +2983,7 @@ static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
*/
if ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) &&
(get_irn_op(left) == op_And)) {
if (is_single_bit_tarval(tv)) {
if (tarval_is_single_bit(tv)) {
/* check for Constant's match. We have check hare the tarvals,
because our const might be changed */
ir_node *la = get_And_left(left);
......
This diff is collapsed.
......@@ -37,33 +37,25 @@ typedef long double LLDBL;
typedef double LLDBL;
#endif
typedef enum {
FC_add, /**< addition */
FC_sub, /**< subtraction */
FC_mul, /**< multiplication */
FC_div, /**< divide */
FC_neg, /**< negate */
FC_int, /**< truncate to integer */
FC_rnd /**< round to integer */
} fc_op_t;
enum {
FC_DEC,
FC_HEX,
FC_BIN,
FC_PACKED
FC_DEC,
FC_HEX,
FC_BIN,
FC_PACKED
};
/** IEEE-754 Rounding modes. */
typedef enum {
FC_TONEAREST, /**< if unsure, to the nearest even */
FC_TOPOSITIVE, /**< to +oo */
FC_TONEGATIVE, /**< to -oo */
FC_TOZERO /**< to 0 */
FC_TONEAREST, /**< if unsure, to the nearest even */
FC_TOPOSITIVE, /**< to +oo */
FC_TONEGATIVE, /**< to -oo */
FC_TOZERO /**< to 0 */
} fc_rounding_mode_t;
#define FC_DEFAULT_PRECISION 64
typedef struct _fp_value fp_value;
/*@{*/
/** internal buffer access
* All functions that accept NULL as return buffer put their result into an
......@@ -75,7 +67,7 @@ const void *fc_get_buffer(void);
int fc_get_buffer_length(void);
/*}@*/
char *fc_val_from_str(const char *str, unsigned int len, char exp_size, char mant_size, char *result);
void *fc_val_from_str(const char *str, unsigned int len, char exp_size, char mant_size, void *result);
/** get the representation of a floating point value
* This function tries to builds a representation having the same value as the
......@@ -94,7 +86,7 @@ char *fc_val_from_str(const char *str, unsigned int len, char exp_size, char man
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
char *fc_val_from_float(LLDBL l, char exp_size, char mant_size, char *result);
fp_value *fc_val_from_ieee754(LLDBL l, char exp_size, char mant_size, fp_value *result);
/** retrieve the float value of an internal value
* This function casts the internal value to LLDBL and returns a LLDBL with
......@@ -106,7 +98,7 @@ char *fc_val_from_float(LLDBL l, char exp_size, char mant_size, char *result);
* @param val The representation of a float value
* @return a float value approximating the represented value
*/
LLDBL fc_val_to_float(const void *val);
LLDBL fc_val_to_ieee754(const fp_value *val);
/** cast a value to another precision
* This function changes the precision of a float representation.
......@@ -123,7 +115,7 @@ LLDBL fc_val_to_float(const void *val);
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
char *fc_cast(const void *val, char exp_size, char mant_size, char *result);
fp_value *fc_cast(const fp_value *val, char exp_size, char mant_size, fp_value *result);
/*@{*/
/** build a special float value
......@@ -141,29 +133,29 @@ char *fc_cast(const void *val, char exp_size, char mant_size, char *result);
* @return The result pointer passed to the function. If this was NULL this returns
* a pointer to the internal accumulator buffer
*/
char *fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, char* result);
char *fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, char* result);
char *fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, char* result);
char *fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, char* result);
char *fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result);
char *fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, char* result);
fp_value *fc_get_min(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
fp_value *fc_get_max(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
fp_value *fc_get_snan(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
fp_value *fc_get_qnan(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
fp_value *fc_get_plusinf(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
fp_value *fc_get_minusinf(unsigned int exponent_size, unsigned int mantissa_size, fp_value *result);
/*@}*/
int fc_is_zero(const void *a);
int fc_is_negative(const void *a);
int fc_is_inf(const void *a);
int fc_is_nan(const void *a);
int fc_is_subnormal(const void *a);
int fc_is_zero(const fp_value *a);
int fc_is_negative(const fp_value *a);
int fc_is_inf(const fp_value *a);
int fc_is_nan(const fp_value *a);
int fc_is_subnormal(const fp_value *a);
char *fc_add(const void *a, const void *b, void *result);
char *fc_sub(const void *a, const void *b, void *result);
char *fc_mul(const void *a, const void *b, void *result);
char *fc_div(const void *a, const void *b, void *result);
char *fc_neg(const void *a, void *result);
char *fc_int(const void *a, void *result);
char *fc_rnd(const void *a, void *result);
fp_value *fc_add(const fp_value *a, const fp_value *b, fp_value *result);
fp_value *fc_sub(const fp_value *a, const fp_value *b, fp_value *result);
fp_value *fc_mul(const fp_value *a, const fp_value *b, fp_value *result);
fp_value *fc_div(const fp_value *a, const fp_value *b, fp_value *result);
fp_value *fc_neg(const fp_value *a, fp_value *result);
fp_value *fc_int(const fp_value *a, fp_value *result);
fp_value *fc_rnd(const fp_value *a, fp_value *result);
char *fc_print(const void *a, char *buf, int buflen, unsigned base);
char *fc_print(const fp_value *a, char *buf, int buflen, unsigned base);
/** Compare two values
* This function compares two values
......@@ -176,7 +168,17 @@ char *fc_print(const void *a, char *buf, int buflen, unsigned base);
* 1 if a > b
* 2 if either value is NaN
*/
int fc_comp(const void *a, const void *b);
int fc_comp(const fp_value *a, const fp_value *b);
/**
* Returns non-zero if the mantissa is zero, i.e. 1.0Exxx
*/
int fc_zero_mantissa(const fp_value *value);
/**
* Returns the exponent of a value.
*/
int fc_get_exponent(const fp_value *value);
/** Set new rounding mode
* This function sets the rounding mode to one of the following, returning
......@@ -243,7 +245,7 @@ fc_rounding_mode_t fc_get_rounding_mode(void);
* byte.
* @return 8 bits of encoded data
*/
unsigned char fc_sub_bits(const void *val, unsigned num_bit, unsigned byte_ofs);
unsigned char fc_sub_bits(const fp_value *val, unsigned num_bit, unsigned byte_ofs);
void init_fltcalc(int precision);
void finish_fltcalc(void);
......
......@@ -663,7 +663,7 @@ static void _divmod(const char *rDividend, const char *divisor, char *quot, char
char *neg_val2;
char div_sign = 0; /* remember division result sign */
char rem_sign = 0; /* remember remainder esult sign */
char rem_sign = 0; /* remember remainder result sign */
int c_dividend; /* loop counters */
......@@ -1162,7 +1162,7 @@ void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) {
}
void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) {
char* pos;
char* pos;
int i, bits;
if (buffer == NULL) buffer = calc_buffer;
......@@ -1179,107 +1179,6 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) {
*pos++ = SC_0;
}
void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer) {
char *unused_res; /* temp buffer holding unused result of divmod */
const char *val1 = (const char *)value1;
const char *val2 = (const char *)value2;
unused_res = alloca(calc_buffer_size);
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1)));
switch (op) {
case SC_NEG:
_negate(val1, calc_buffer);
DEBUGPRINTF_COMPUTATION(("negated: %s\n", sc_print_hex(calc_buffer)));
break;
case SC_OR:
DEBUGPRINTF_COMPUTATION(("| "));
_bitor(val1, val2, calc_buffer);
break;
case SC_AND:
DEBUGPRINTF_COMPUTATION(("& "));
_bitand(val1, val2, calc_buffer);
break;
case SC_XOR:
DEBUGPRINTF_COMPUTATION(("^ "));
_bitxor(val1, val2, calc_buffer);
break;
case SC_NOT:
_bitnot(val1, calc_buffer);
DEBUGPRINTF_COMPUTATION(("bit-negated: %s\n", sc_print_hex(calc_buffer)));
break;
case SC_ADD:
DEBUGPRINTF_COMPUTATION(("+ "));
_add(val1, val2, calc_buffer);
break;
case SC_SUB:
DEBUGPRINTF_COMPUTATION(("- "));
_sub(val1, val2, calc_buffer);
break;
case SC_MUL:
DEBUGPRINTF_COMPUTATION(("* "));
_mul(val1, val2, calc_buffer);
break;
case SC_DIV:
DEBUGPRINTF_COMPUTATION(("/ "));
_divmod(val1, val2, calc_buffer, unused_res);
break;
case SC_MOD:
DEBUGPRINTF_COMPUTATION(("%% "));
_divmod(val1, val2, unused_res, calc_buffer);
break;
default:
assert(0);
}
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_bitcalc(const void* value1, const void* value2, int radius, int sign, unsigned op, void* buffer) {
const char *val1 = (const char *)value1;
const char *val2 = (const char *)value2;
long offset;
carry_flag = 0;
offset = sc_val_to_long(val2);
DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1)));
switch (op) {
case SC_SHL:
DEBUGPRINTF_COMPUTATION(("<< %ld ", offset));
_shl(val1, calc_buffer, offset, radius, sign);
break;
case SC_SHR:
DEBUGPRINTF_COMPUTATION((">> %ld ", offset));
_shr(val1, calc_buffer, offset, radius, sign, 0);
break;
case SC_SHRS:
DEBUGPRINTF_COMPUTATION((">>> %ld ", offset));
_shr(val1, calc_buffer, offset, radius, sign, 1);
break;
case SC_ROT:
DEBUGPRINTF_COMPUTATION(("<<>> %ld ", offset));
_rot(val1, calc_buffer, offset, radius, sign);
break;
default:
assert(0);
}
DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memmove(buffer, calc_buffer, calc_buffer_size);
}
}
int sc_comp(const void* value1, const void* value2) {
int counter = calc_buffer_size - 1;
const char *val1 = (const char *)value1;
......@@ -1347,8 +1246,9 @@ int sc_is_zero(const void *value) {
const char* val = (const char *)value;
int counter;
for (counter = 0; counter < calc_buffer_size; counter++) {
if (val[counter] != SC_0) return 0;
for (counter = 0; counter < calc_buffer_size; ++counter) {
if (val[counter] != SC_0)
return 0;
}
return 1;
}
......@@ -1551,3 +1451,229 @@ void finish_strcalc(void) {
int sc_get_precision(void) {
return bit_pattern_size;
}
void sc_add(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s + ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_add(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_sub(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s - ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_sub(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_neg(const void *value1, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("- %s ->", sc_print_hex(value1)));
_negate(value1, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_and(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_bitand(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_or(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s | ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_bitor(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_xor(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s ^ ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_bitxor(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_not(const void *value1, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("~ %s ->", sc_print_hex(value1)));
_bitnot(value1, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_mul(const void *value1, const void *value2, void *buffer) {
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s * ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_mul(value1, value2, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_div(const void *value1, const void *value2, void *buffer) {
/* temp buffer holding unused result of divmod */
char *unused_res = alloca(calc_buffer_size);
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s / ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_divmod(value1, value2, calc_buffer, unused_res);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_mod(const void *value1, const void *value2, void *buffer) {
/* temp buffer holding unused result of divmod */
char *unused_res = alloca(calc_buffer_size);
CLEAR_BUFFER(calc_buffer);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s ", sc_print_hex(value1)));
DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
_divmod(value1, value2, unused_res, calc_buffer);
DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memcpy(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_shl(const void *val1, const void *val2, int radius, int sign, void *buffer) {
long offset = sc_val_to_long(val2);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s << %ld ", sc_print_hex(value1), offset));
_shl(val1, calc_buffer, offset, radius, sign);
DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memmove(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_shr(const void *val1, const void *val2, int radius, int sign, void *buffer) {
long offset = sc_val_to_long(val2);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s >>u %ld ", sc_print_hex(value1), offset));
_shr(val1, calc_buffer, offset, radius, sign, 0);
DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memmove(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_shrs(const void *val1, const void *val2, int radius, int sign, void *buffer) {
long offset = sc_val_to_long(val2);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), offset));
_shr(val1, calc_buffer, offset, radius, sign, 1);
DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memmove(buffer, calc_buffer, calc_buffer_size);
}
}
void sc_rot(const void *val1, const void *val2, int radius, int sign, void *buffer) {
long offset = sc_val_to_long(val2);
carry_flag = 0;
DEBUGPRINTF_COMPUTATION(("%s <<>> %ld ", sc_print_hex(value1), offset));
_rot(val1, calc_buffer, offset, radius, sign);
DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
if ((buffer != NULL) && (buffer != calc_buffer)) {
memmove(buffer, calc_buffer, calc_buffer_size);
}
}
......@@ -76,26 +76,6 @@ enum {
SC_F
};
/**
* Possible operations on integer values.
*/
typedef enum {
SC_ADD = 0, /**< Addition */
SC_SUB, /**< Subtraction */
SC_NEG, /**< Unary Minus */
SC_MUL, /**< Multiplication */
SC_DIV, /**< Integer Division (with rounding toward zero ?) */
SC_MOD, /**< Devision Remainder */
SC_SHL, /**< Left Shift */
SC_SHR, /**< Logical (unsigned) Right Shift */
SC_SHRS, /**< Arithmetic (signed) Right Shift */
SC_ROT, /**< Rotation (both directions) */
SC_AND, /**< Bitwise And */
SC_OR, /**< Bitwise Or */
SC_NOT, /**< Bitwise Not */
SC_XOR /**< Bitwise Exclusive Or */
} sc_op_t;
/**
* The output mode for integer values.
*/
......@@ -108,22 +88,22 @@ enum base_t {
};
/*
* definitions and macros
* Interface
*/
#define sc_add(a, b, c) sc_calc((a), (b), SC_ADD, (c))
#define sc_sub(a, b, c) sc_calc((a), (b), SC_SUB, (c))
#define sc_neg(a, c) sc_calc((a), NULL, SC_NEG, (c))
#define sc_and(a, b, c) sc_calc((a), (b), SC_AND, (c))
#define sc_or(a, b, c) sc_calc((a), (b), SC_OR, (c))
#define sc_xor(a, b, c) sc_calc((a), (b), SC_XOR, (c))
#define sc_not(a, c) sc_calc((a), NULL, SC_NOT, (c))
#define sc_mul(a, b, c) sc_calc((a), (b), SC_MUL, (c))
#define sc_div(a, b, c) sc_calc((a), (b), SC_DIV, (c))
#define sc_mod(a, b, c) sc_calc((a), (b), SC_MOD, (c))
#define sc_shl(a, b, c, d, e) sc_bitcalc((a), (b), (c), (d), SC_SHL, (e))
#define sc_shr(a, b, c, d, e) sc_bitcalc((a), (b), (c), (d), SC_SHR, (e))
#define sc_shrs(a, b, c, d, e) sc_bitcalc((a), (b), (c), (d), SC_SHRS, (e))
#define sc_rot(a, b, c, d, e) sc_bitcalc((a), (b), (c), (d), SC_ROT, (e))
void sc_add(const void *value1, const void *value2, void *buffer);
void sc_sub(const void *value1, const void *value2, void *buffer);