/*
- * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved.
- *
* This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Data modes of operations.
* @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil
- * @version $Id$
*/
#include "config.h"
/** The list of all currently existing modes. */
static ir_mode **mode_list;
-const char *get_mode_arithmetic_name(ir_mode_arithmetic ari)
-{
-#define X(a) case a: return #a
- switch (ari) {
- X(irma_uninitialized);
- X(irma_none);
- X(irma_twos_complement);
- X(irma_ieee754);
- X(irma_x86_extended_float);
- default: return "<unknown>";
- }
-#undef X
-}
-
static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
{
return m->sort == n->sort &&
}
}
-/* * *
- * globals defined in irmode.h
- * * */
-
-/* --- Predefined modes --- */
-
-/* FIRM internal modes: */
ir_mode *mode_T;
ir_mode *mode_X;
ir_mode *mode_M;
ir_mode *mode_ANY;
ir_mode *mode_BAD;
-/* predefined numerical modes: */
ir_mode *mode_F;
ir_mode *mode_D;
ir_mode *mode_Q;
-ir_mode *mode_Bs; /* integral values, signed and unsigned */
-ir_mode *mode_Bu; /* 8 bit */
-ir_mode *mode_Hs; /* 16 bit */
+ir_mode *mode_Bs;
+ir_mode *mode_Bu;
+ir_mode *mode_Hs;
ir_mode *mode_Hu;
-ir_mode *mode_Is; /* 32 bit */
+ir_mode *mode_Is;
ir_mode *mode_Iu;
-ir_mode *mode_Ls; /* 64 bit */
+ir_mode *mode_Ls;
ir_mode *mode_Lu;
-ir_mode *mode_LLs; /* 128 bit */
+ir_mode *mode_LLs;
ir_mode *mode_LLu;
ir_mode *mode_b;
ir_mode *mode_P;
-/* machine specific modes */
-ir_mode *mode_P_code; /**< machine specific pointer mode for code addresses */
-ir_mode *mode_P_data; /**< machine specific pointer mode for data addresses */
-
-/* * *
- * functions defined in irmode.h
- * * */
+ir_mode *mode_P_code;
+ir_mode *mode_P_data;
ir_mode *get_modeT(void) { return mode_T; }
ir_mode *get_modeF(void) { return mode_F; }
mode->kind = k_ir_mode;
mode->type = new_type_primitive(mode);
ARR_APP1(ir_mode*, mode_list, mode);
- add_irp_mode(mode);
set_mode_values(mode);
hook_new_mode(mode);
return mode;
if (mantissa_size >= 256)
panic("Mantissa >= 256 bits not supported");
- result = alloc_mode(name, irms_float_number, irma_ieee754, bit_size, 1, 0);
+ result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0);
result->float_desc.exponent_size = exponent_size;
result->float_desc.mantissa_size = mantissa_size;
result->float_desc.explicit_one = explicit_one;
return register_mode(result);
}
-/* Functions for the direct access to all attributes of an ir_mode */
ident *(get_mode_ident)(const ir_mode *mode)
{
return get_mode_ident_(mode);
}
-/* Attribute modulo shift specifies for modes of kind irms_int_number
- * whether shift applies modulo to value of bits to shift. Asserts
- * if mode is not irms_int_number.
- */
unsigned int (get_mode_modulo_shift)(const ir_mode *mode)
{
return get_mode_modulo_shift_(mode);
return get_mode_exponent_size_(mode);
}
-/* Returns true if sm can be converted to lm without loss. */
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
int sm_bits, lm_bits;
return 0;
}
-/* Returns true if a value of mode sm can be converted into mode lm
- and backwards without loss. */
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
- ir_mode_arithmetic arith;
-
- assert(sm);
- assert(lm);
-
- if (sm == lm) return 1;
+ if (sm == lm)
+ return true;
if (sm == mode_b)
- return mode_is_int(lm);
-
- arith = get_mode_arithmetic(sm);
- if (arith != get_mode_arithmetic(lm))
- return 0;
-
- switch (arith) {
- case irma_twos_complement:
- case irma_ieee754:
+ return mode_is_int(lm) || mode_is_float(lm);
+
+ ir_mode_arithmetic larith = get_mode_arithmetic(lm);
+ ir_mode_arithmetic sarith = get_mode_arithmetic(sm);
+ switch (larith) {
+ case irma_x86_extended_float:
+ case irma_ieee754:
+ if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) {
return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
-
- default:
- return 0;
+ } else if (sarith == irma_twos_complement) {
+ unsigned int_mantissa = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0);
+ unsigned float_mantissa = get_mode_mantissa_size(lm) + 1;
+ return int_mantissa <= float_mantissa;
+ }
+ break;
+ case irma_twos_complement:
+ if (sarith == irma_twos_complement) {
+ return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
+ }
+ break;
+ case irma_none:
+ break;
}
+ return false;
}
-/* Return the signed integer equivalent mode for an reference mode. */
ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
{
assert(mode_is_reference(mode));
return mode->eq_signed;
}
-/* Sets the signed integer equivalent mode for an reference mode. */
void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
assert(mode_is_reference(ref_mode));
ref_mode->eq_signed = int_mode;
}
-/* Return the unsigned integer equivalent mode for an reference mode. */
ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
{
assert(mode_is_reference(mode));
return mode->eq_unsigned;
}
-/* Sets the unsigned integer equivalent mode for an reference mode. */
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
assert(mode_is_reference(ref_mode));
return register_mode(mode);
}
-/* initialization, build the default modes */
void init_mode(void)
{
obstack_init(&modes);
mode_P_data = mode_P;
}
-/* find a signed mode for an unsigned integer mode */
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
ir_mode n = *mode;
return find_mode(&n);
}
-/* find an unsigned mode for a signed integer mode */
ir_mode *find_signed_mode(const ir_mode *mode)
{
ir_mode n = *mode;
return find_mode(&n);
}
-/* finds a integer mode with 2*n bits for an integer mode with n bits. */
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
ir_mode n = *mode;
return find_mode(&n);
}
-/*
- * Returns non-zero if the given mode honors signed zero's, i.e.,
- * a +0 and a -0 exists and handled differently.
- */
int mode_honor_signed_zeros(const ir_mode *mode)
{
/* for floating point, we know that IEEE 754 has +0 and -0,
mode->arithmetic != irma_ieee754;
}
-/*
- * Returns non-zero if the given mode might overflow on unary Minus.
- *
- * This does NOT happen on IEEE 754.
- */
int mode_overflow_on_unary_Minus(const ir_mode *mode)
{
if (mode->sort == irms_float_number)
return 1;
}
-/*
- * Returns non-zero if the mode has a reversed wrap-around
- * logic, especially (a + x) - x == a.
- *
- * This is normally true for integer modes, not for floating
- * point modes.
- */
int mode_wrap_around(const ir_mode *mode)
{
/* FIXME: better would be an extra mode property */
return mode_is_int(mode);
}
-/*
- * Returns non-zero if the cast from mode src to mode dst is a
- * reinterpret cast (ie. only the bit pattern is reinterpreted,
- * no conversion is done)
- */
int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst)
{
ir_mode_arithmetic ma;
return get_type_for_mode_(mode);
}
+size_t ir_get_n_modes(void)
+{
+ return ARR_LEN(mode_list);
+}
+
+ir_mode *ir_get_mode(size_t num)
+{
+ assert(num < ARR_LEN(mode_list));
+ return mode_list[num];
+}
+
void finish_mode(void)
{
obstack_free(&modes, 0);