-
-int mode_is_reference (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (get_mode_sort(mode) == irms_reference);
-}
-
-int
-mode_is_num (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (mode_is_int(mode) || mode_is_float(mode));
-}
-
-int
-mode_is_numP (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (mode_is_int(mode) || mode_is_float(mode) || mode_is_reference(mode));
-}
-
-int
-mode_is_data (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (mode_is_num(mode) || get_mode_sort(mode) == irms_character || get_mode_sort(mode) == irms_reference);
-}
-
-int
-mode_is_datab (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (mode_is_data(mode) || get_mode_sort(mode) == irms_internal_boolean);
-}
-
-int
-mode_is_dataM (const ir_mode *mode)
-{
- ANNOUNCE();
- assert(mode);
- return (mode_is_data(mode) || get_mode_modecode(mode) == irm_M);
-}
-#ifdef MODE_ACCESS_DEFINES
-# define mode_is_signed(mode) (mode)->sign
-# define mode_is_float(mode) ((mode)->sort == irms_float_number)
-# define mode_is_int(mode) ((mode)->sort == irms_int_number)
-# define mode_is_num(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number))
-# define mode_is_data(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference))
-# define mode_is_datab(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->sort == irms_internal_boolean))
-# define mode_is_dataM(mode) (((mode)->sort == irms_float_number) || ((mode)->sort == irms_int_number) || ((mode)->sort == irms_character) || ((mode)->sort == irms_reference) || ((mode)->code == irm_M))
-#endif
-/* Returns true if sm can be converted to lm without loss. */
-int
-smaller_mode(const ir_mode *sm, const ir_mode *lm)
+
+int smaller_mode(const ir_mode *sm, const ir_mode *lm)
+{
+ int sm_bits, lm_bits;
+
+ assert(sm);
+ assert(lm);
+
+ if (sm == lm) return 1;
+
+ sm_bits = get_mode_size_bits(sm);
+ lm_bits = get_mode_size_bits(lm);
+
+ switch (get_mode_sort(sm)) {
+ case irms_int_number:
+ switch (get_mode_sort(lm)) {
+ case irms_int_number:
+ if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
+ return 0;
+
+ /* only two complement implemented */
+ assert(get_mode_arithmetic(sm) == irma_twos_complement);
+
+ /* integers are convertable if
+ * - both have the same sign and lm is the larger one
+ * - lm is the signed one and is at least two bits larger
+ * (one for the sign, one for the highest bit of sm)
+ * - sm & lm are two_complement and lm has greater or equal number of bits
+ */
+ if (mode_is_signed(sm)) {
+ if (!mode_is_signed(lm))
+ return 0;
+ return sm_bits <= lm_bits;
+ } else {
+ if (mode_is_signed(lm)) {
+ return sm_bits < lm_bits;
+ }
+ return sm_bits <= lm_bits;
+ }
+
+ case irms_float_number:
+ /* int to float works if the float is large enough */
+ return 0;
+
+ default:
+ break;
+ }
+ break;
+
+ case irms_float_number:
+ if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
+ if ( (get_mode_sort(lm) == irms_float_number)
+ && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
+ return 1;
+ }
+ break;
+
+ case irms_reference:
+ /* do exist machines out there with different pointer lengths ?*/
+ return 0;
+
+ case irms_internal_boolean:
+ return mode_is_int(lm);
+
+ default:
+ break;
+ }
+
+ /* else */
+ return 0;
+}
+
+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 == 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 get_mode_size_bits(sm) <= get_mode_size_bits(lm);
+
+ default:
+ return 0;
+ }
+}
+
+ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
+{
+ assert(mode_is_reference(mode));
+ return mode->eq_signed;
+}
+
+void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
+{
+ assert(mode_is_reference(ref_mode));
+ assert(mode_is_int(int_mode));
+ ref_mode->eq_signed = int_mode;
+}
+
+ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)