X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ftv.h;h=e4224e97286ac6f4bbf2a62f71864094b464c68c;hb=285ae217b4be997248440b80fdea5dbd146316e1;hp=f39ec3f68b3c0cccd16033b77f4631760be02aff;hpb=4e2debaef1574838e2f08d16ef0d1b7e6397ee4e;p=libfirm diff --git a/ir/tv/tv.h b/ir/tv/tv.h index f39ec3f68..e4224e972 100644 --- a/ir/tv/tv.h +++ b/ir/tv/tv.h @@ -1,52 +1,26 @@ +/* + * Project: libFIRM + * File name: ir/tv/tv.h + * Purpose: Representation of and static computations on target machine + * values. + * Author: Mathias Heil + * Modified by: + * Created: + * CVS-ID: $Id$ + * Copyright: (c) 2003 Universität Karlsruhe + * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. + */ + /** * @file tv.h * * Declarations for Target Values. */ - -/* $Id$ */ - -/* -Discussion of new interface, proposals by Prof. Waite: -(email of 13.6.2001) -> 1. You say that you plan to replace the tv module. That replacement is -> absolutely essential for an ANSI C translator: Section 6.1.3.2 of the -> standard says that the representation of an integer_constant depends -> upon its value as well as any suffixes that are attached to it. The -> possible Firm modes for such a constant are i, I, l, and L. The -> current tv module provides only one integer conversion routine, and -> that requires conversion by the client. Since the type of the value -> argument is long, this may preclude the representation of an unsigned -> long constant. -> -> There is a similar problem with floating constants. Floating -> constants can be suffixed in C, and the mode depends upon the suffix. -> It can indicate that the constant is of type long double, which your -> current tv module is incapable of representing. -> -> Your tv module interface accepts two kinds of information: modes and -> values. Values obtained from the program text might be uninterpreted -> strings, strings interpreted as integers, and strings interpreted as -> reals. Values provided by the compiler are usually integers. Modes are -> always Firm modes. It seems to me that the tv module should provide -> tarval* constructors for three of the four kinds of values. Each of these -> constructors should have an ir_mode parameter and one or more parameters -> appropriate for the kind of value. As is currently the case, one -> constructor should be provided for both compiler-generated integers and -> source strings interpreted as integers. (This avoids problems of -> different conversion radices -- the client does the conversion.) For -> symmetry, the constructor for source strings interpreted as reals should -> accept a long double parameter and require the client to do the -> conversion. - -*/ - #ifndef _TV_H_ #define _TV_H_ -# include "irmode.h" -# include "entity.h" -# include "irnode.h" /* for pnc_number enum */ +#include "irmode.h" +#include "irnode.h" /****h* libfirm/tv * @@ -55,7 +29,6 @@ Discussion of new interface, proposals by Prof. Waite: * Internal representation for machine values. * * AUTHORS - * Christian von Roques * Matthias Heil * * DESCRIPTION @@ -85,7 +58,7 @@ Discussion of new interface, proposals by Prof. Waite: * SEE ALSO * Techreport 1999-14 * irmode.h for the modes definitions - * irnode.h for the pnc_numbers table + * irnode.h for the pn_Cmp table * * tarval_init1 and tarval_init2 for initialization of the * module @@ -175,18 +148,20 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode); */ tarval *new_tarval_from_long(long l, ir_mode *mode); -/** +/** Return value as long if possible. + * * This returns a long int with the value represented value, or * gibberish, depending on the size of long int and the size of the * stored value. It works for e.g. 1 as mode_Ls, but might not work for * get_mode_max(mode_Ls). * This will overflow silently, so use only if you know what * you are doing! (better check with tarval_is_long()...) + * Works only for int modes, even not for character modes! */ -long tarval_to_long(tarval *tv); +long get_tarval_long(tarval *tv); /** - * This validates if tarval_to_long() will return a satisfying + * This validates if get_tarval_long() will return a satisfying * result. I.e. if tv is an int_number and between min, max * of long int (signed!) */ @@ -195,11 +170,11 @@ int tarval_is_long(tarval *tv); /** * Constructor function for new tarvals. * - * @param d The long double representing the value + * @param d The (long) double representing the value * @param mode The mode requested for the result tarval * * This function creates a new tarval representing the value represented - * by a long double. If a tarval representing this value already exists, + * by a (long) double. If a tarval representing this value already exists, * this tarval is returned instead of a new one. So tarvals are directly * comparable since their representation is unique. * Only modes of sort float_number can be constructed this way. @@ -211,7 +186,7 @@ int tarval_is_long(tarval *tv); * value/mode pair. * * @note - * If the long double is not representable in the given mode an assertion + * If the (long) double is not representable in the given mode an assertion * is thrown. This will happen for any mode not of sort float_number. * * @sa @@ -228,7 +203,7 @@ tarval *new_tarval_from_double(long double d, ir_mode *mode); * This will overflow silently, so use only if you know what * you are doing! (better check with tarval_is_long...) */ -long double tarval_to_double(tarval *tv); +long double get_tarval_double(tarval *tv); /** * This validates if tarval_to_double() will return a satisfying @@ -237,22 +212,6 @@ long double tarval_to_double(tarval *tv); */ int tarval_is_double(tarval *tv); -/** - * Construct a tarval that represents the address of the entity. - * - * The address must be constant, the entity must have as owner the global type. - */ -tarval *new_tarval_from_entity (entity *ent, ir_mode *mode); - -/** - * Returns the associated entity of a tarval. - */ -entity *tarval_to_entity(tarval *tv); - -/** - * Returns non-zero if a the given tarval represents an entity. - */ -int tarval_is_entity(tarval *tv); /** ********** Access routines for tarval fields ********** **/ @@ -280,17 +239,34 @@ int tarval_is_entity(tarval *tv); */ /** Returns the mode of the tarval. */ -ir_mode *get_tarval_mode (tarval *tv); +ir_mode *get_tarval_mode (const tarval *tv); + +/** Returns the contents of the 'link' field of the tarval */ +/* void *get_tarval_link (tarval*); */ /* Testing properties of the represented values */ -/** Returns 0 if tv is positive, else > 0. +/** + * Returns 1 if tv is negative * - * @todo - * not tested! + * @param a the tarval */ int tarval_is_negative(tarval *a); +/** + * Returns 1 if tv is null + * + * @param a the tarval + */ +int tarval_is_null(tarval *a); + +/** + * Returns 1 if tv is the "one" + * + * @param a the tarval + */ +int tarval_is_one(tarval *a); + /** The 'bad' tarval. */ extern tarval *tarval_bad; /** Returns the 'bad tarval. */ @@ -303,6 +279,7 @@ tarval *get_tarval_undefined(void); /** The mode_b tarval 'false'. */ extern tarval *tarval_b_false; + /** Returns the mode_b tarval 'false'. */ tarval *get_tarval_b_false(void); @@ -311,16 +288,11 @@ extern tarval *tarval_b_true; /** Returns the mode_b tarval 'true'. */ tarval *get_tarval_b_true(void); -/** The 'void' pointer tarval. */ -extern tarval *tarval_P_void; -/** Returns the 'void' pointer tarval. */ -tarval *get_tarval_P_void(void); - /* 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. */ + * therefore the irmode functions should be preferred to the functions below. */ /** Returns the maximum value of a given mode. */ tarval *get_tarval_max(ir_mode *mode); @@ -328,45 +300,69 @@ tarval *get_tarval_max(ir_mode *mode); /** Returns the minimum value of a given mode. */ tarval *get_tarval_min(ir_mode *mode); -/** Returns the 0 value (additive neutral) of a given mode. */ +/** Returns the 0 value (additive neutral) of a given mode. + For reference modes, the NULL value is returned (old tarval_P_void) */ tarval *get_tarval_null(ir_mode *mode); /** Returns the 1 value (multiplicative neutral) of a given mode. */ tarval *get_tarval_one(ir_mode *mode); +/** Returns the -1 value (multiplicative neutral) of a given mode. + * Returns tarval bad for unsigned modes */ +tarval *get_tarval_minus_one(ir_mode *mode); + /** Return quite nan for float_number modes. */ tarval *get_tarval_nan(ir_mode *mode); /** Return +inf for float_number modes. */ -tarval *get_tarval_inf(ir_mode *mode); +tarval *get_tarval_plus_inf(ir_mode *mode); + +/** Return -inf for float_number modes. */ +tarval *get_tarval_minus_inf(ir_mode *mode); + +/* ******************** Arithmetic operations on tarvals ******************** */ + +typedef enum _tarval_int_overflow_mode_t { + TV_OVERFLOW_BAD, /**< tarval module will return tarval_bad if a overflow occurs */ + TV_OVERFLOW_WRAP, /**< tarval module will overflow will be ignored, wrap around occurs */ + TV_OVERFLOW_SATURATE /**< tarval module will saturate the overflow */ +} tarval_int_overflow_mode_t; + +/** + * Sets the overflow mode for integer operations. + */ +void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode); -/* ******************** Arithmethic operations on tarvals ******************** */ +/** + * Get the overflow mode for integer operations. + */ +tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void); /** * Compares two tarvals * - * Compare a with b and return a pnc_number describing the relation - * between a and b. This is either Uo, Lt, Eq, Gt, or False if a or b - * are symbolic pointers which can not be compared at all. + * Compare a with b and return a pn_Cmp describing the relation + * between a and b. This is either pn_Cmp_Uo, pn_Cmp_Lt, pn_Cmp_Eq, pn_Cmp_Gt, + * or pn_Cmp_False if a or b are symbolic pointers which can not be compared at all. * * @param a A tarval to be compared * @param b A tarval to be compared * * @return - * The pnc_number best describing the relation between a and b is returned. + * The pn_Cmp best describing the relation between a and b is returned. * This means the mode with the least bits set is returned, e.g. if the - * tarvals are equal the pnc_number 'Eq' is returned, not 'Ge' which + * tarvals are equal the pn_Cmp 'pn_Cmp_Eq' is returned, not 'pn_Cmp_Ge' which * indicates 'greater or equal' * * @sa - * irnode.h for the definition of pnc_numbers + * irnode.h for the definition of pn_Cmp */ -pnc_number tarval_cmp(tarval *a, tarval *b); +pn_Cmp tarval_cmp(tarval *a, tarval *b); /** * Converts a tarval to another mode. * - * Convert tarval 'src' to mode 'mode', this will suceed if and only if mode + * Convert tarval 'src' to mode 'mode', this will succeed if and only if mode * 'mode' is wider than the mode of src, as defined in the firm documentation * and as returned by the function mode_is_smaller defined in irmode.h. * @@ -385,7 +381,7 @@ pnc_number tarval_cmp(tarval *a, tarval *b); * FIRM documentation for conversion rules * mode_is_smaller defined in irmode.h */ -tarval *tarval_convert_to(tarval *src, ir_mode *m); +tarval *tarval_convert_to(tarval *src, ir_mode *mode); /* * These function implement basic computations representable as opcodes @@ -396,12 +392,12 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m); * traval_abs: * a - the tarval to operate on * - * all oters: + * all others: * a - the first operand tarval * b - the second operand tarval * * RESULT - * If neccessary a new tarval is constructed for the resulting value, + * If necessary a new tarval is constructed for the resulting value, * or the one already carrying the computation result is retrieved and * returned as result. * @@ -412,7 +408,10 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m); * The sort member of the struct mode defines which operations are valid */ -/** Negation of a tarval. */ +/** bitwise Negation of a tarval. */ +tarval *tarval_not(tarval *a); + +/** arithmetic Negation of a tarval. */ tarval *tarval_neg(tarval *a); /** Addition of two tarvals. */ @@ -457,6 +456,9 @@ tarval *tarval_shrs(tarval *a, tarval *b); /** Rotation. */ tarval *tarval_rot(tarval *a, tarval *b); +/** Carry flag of the last operation */ +int tarval_carry(void); + /* *********** Output of tarvals *********** */ /** @@ -465,40 +467,52 @@ tarval *tarval_rot(tarval *a, tarval *b); * Some modes allow more that one representation, for instance integers * can be represented hex or decimal. Of course it would be enough to have * one and let every backend convert it into the 'right' one. - * However, we can do this in the tarval much simplier... + * However, we can do this in the tarval much simpler... */ typedef enum { - TVO_NATIVE, /**< the default output mode, depends on the mode */ - TVO_HEX, /**< use hex representation, always possible */ - TVO_DECIMAL, /**< use decimal representation */ - TVO_OCTAL, /**< use octal representation */ - TVO_BINARY, /**< use binary representation */ - TVO_FLOAT /**< use floating point representation */ + TVO_NATIVE, /**< the default output mode, depends on the mode */ + TVO_HEX, /**< use hex representation, always possible */ + TVO_DECIMAL, /**< use decimal representation */ + TVO_OCTAL, /**< use octal representation */ + TVO_BINARY, /**< use binary representation */ + TVO_FLOAT, /**< use floating point representation (i.e 1.342e-2)*/ + TVO_HEXFLOAT /**< use hexadecimal floating point representation (i.e 0x1.ea32p-12)*/ } tv_output_mode; /** * This structure contains helper information to format the output - * of a tarval of an mode. + * of a tarval of a mode. */ typedef struct tarval_mode_info { - tv_output_mode mode_output; /**< if != TVO_NATIVE select a special mode */ - const char *mode_prefix; /**< if set, this prefix will be printed - before a value of this mode */ - const char *mode_suffix; /**< if set, this suffix will be printed - after a value of this mode */ + tv_output_mode mode_output; /**< if != TVO_NATIVE select a special mode */ + const char *mode_prefix; /**< if set, this prefix will be printed + before a value of this mode */ + const char *mode_suffix; /**< if set, this suffix will be printed + after a value of this mode */ } tarval_mode_info; /** * Specify the output options of one mode. * - * This functions stores the modinfo, so DO NOT DESTROY it. + * This functions stores the mode info, so DO NOT DESTROY it. * - * @param mode a ir_mode that should be associated - * @param modeinfo the output format info + * @param mode a ir_mode that should be associated + * @param modeinfo the output format info * - * Returns zero on success. + * @return zero on success. */ -int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo); +int set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo); + +/** + * Returns the output options of one mode. + * + * This functions returns the mode info of a given mode. + * + * @param mode a ir_mode that should be associated + * + * @return the output option + */ +const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode); /** * Returns Bit representation of a tarval value, as string of '0' and '1' @@ -516,14 +530,14 @@ int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinf * @note * The string is allocated using malloc() and is free()ed on the next call * of this function. - * The string consists of the ascii characters '0' and '1' and is + * The string consists of the ASCII characters '0' and '1' and is * null terminated * * @sa * irmode.h for the definition of the ir_mode struct * the size member of aforementioned struct */ -char *tarval_bitpattern(tarval *tv); +char *get_tarval_bitpattern(tarval *tv); /** * Returns the bitpattern of the bytes_ofs byte. @@ -541,47 +555,54 @@ char *tarval_bitpattern(tarval *tv); * Because this is the bit representation of the target machine, only the following * operations are legal on the result: * - * - concatenation (endian dependance MUST be handled by the CALLER) + * - concatenation (endian dependence MUST be handled by the CALLER) * - bitwise logical operations to select/mask bits * - * @param tv the tarval - * @param byte_ofs the byte offset + * @param tv the tarval + * @param byte_ofs the byte offset * * @note - * The result of this funcion is undefined if the mode is neither integer nor float. + * The result of this function is undefined if the mode is neither integer nor float. */ -unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs); +unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs); /** - * Identifying some tarvals ??? + * Return values of tarval classify + */ +typedef enum _tarval_classification_t { + TV_CLASSIFY_NULL = 0, /**< the tarval represents the additive neutral element */ + TV_CLASSIFY_ONE = +1, /**< the tarval represents the multiplicative neutral element */ + TV_CLASSIFY_ALL_ONE = -1, /**< the tarval represents the bitwise-and neutral element */ + TV_CLASSIFY_OTHER = 2 /**< all other tarvals */ +} tarval_classification_t; + +/** + * Identifying tarvals values for algebraic simplifications. + * + * @param tv the tarval * * @return - * - 0 for additive neutral, - * - +1 for multiplicative neutral, - * - -1 for bitwise-and neutral - * - 2 else - * - * @deprecated - * This function is deprecated and its use strongly discouraged. - * Implemented for completeness. + * - TV_CLASSIFY_NULL for additive neutral or the NULL tarval for reference modes, + * - TV_CLASSIFY_ONE for multiplicative neutral, + * - TV_CLASSIFY_ALL_ONE for bitwise-and neutral + * - TV_CLASSIFY_OTHER else */ -long tarval_classify(tarval *tv); +tarval_classification_t classify_tarval(tarval *tv); /** - * Initialization of the tarval module. - * - * Call before init_mode(). + * Returns non-zero if a given (integer) tarval has only one single bit + * set. */ -void init_tarval_1(void); +int is_single_bit_tarval(tarval *tv); /** - * Initialization of the tarval module. - * - * Call after init_mode(). + * Output of tarvals to a buffer. */ -void init_tarval_2(void); +int tarval_snprintf(char *buf, size_t buflen, tarval *tv); -typedef int printf_func (void* , const char *, ...); -int tarval_xprintf(printf_func *print_func, void *out, tarval *tv); +/** + * Output of tarvals to stdio. + */ +int tarval_printf(tarval *tv); #endif /* _TV_H_ */