becopyheur2: Cache the admissible registers eagerly.
[libfirm] / ir / ir / irmode.c
index 58a4cd0..a208d9b 100644 (file)
@@ -1,27 +1,12 @@
 /*
- * 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"
 
@@ -47,20 +32,6 @@ static struct obstack modes;
 /** 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 &&
@@ -131,13 +102,6 @@ static void set_mode_values(ir_mode* mode)
        }
 }
 
-/* * *
- * globals defined in irmode.h
- * * */
-
-/* --- Predefined modes --- */
-
-/* FIRM internal modes: */
 ir_mode *mode_T;
 ir_mode *mode_X;
 ir_mode *mode_M;
@@ -145,32 +109,26 @@ ir_mode *mode_BB;
 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; }
@@ -251,7 +209,6 @@ static ir_mode *register_mode(ir_mode *mode)
        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;
@@ -291,14 +248,13 @@ ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
        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);
@@ -330,10 +286,6 @@ ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *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);
@@ -467,7 +419,6 @@ unsigned (get_mode_exponent_size)(const ir_mode *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;
@@ -539,42 +490,44 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm)
        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));
@@ -582,14 +535,12 @@ void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_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));
@@ -603,7 +554,6 @@ static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
        return register_mode(mode);
 }
 
-/* initialization, build the default modes */
 void init_mode(void)
 {
        obstack_init(&modes);
@@ -642,7 +592,6 @@ void init_mode(void)
        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;
@@ -656,7 +605,6 @@ ir_mode *find_unsigned_mode(const ir_mode *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;
@@ -666,7 +614,6 @@ ir_mode *find_signed_mode(const ir_mode *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;
@@ -677,10 +624,6 @@ ir_mode *find_double_bits_int_mode(const ir_mode *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,
@@ -691,11 +634,6 @@ int mode_honor_signed_zeros(const ir_mode *mode)
                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)
@@ -703,24 +641,12 @@ int mode_overflow_on_unary_Minus(const ir_mode *mode)
        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;
@@ -741,6 +667,17 @@ ir_type *(get_type_for_mode) (const ir_mode *mode)
        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);