more debug info
[libfirm] / ir / ir / irmode.c
index 0a41285..75b02bc 100644 (file)
@@ -536,11 +536,11 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) {
        case irms_int_number:
                switch (get_mode_sort(lm)) {
                case irms_int_number:
-                       if(get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
+                       if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
                                return 0;
 
                        /* only two complement implemented */
-                       assert(get_mode_arithmetic(sm)==irma_twos_complement);
+                       assert(get_mode_arithmetic(sm) == irma_twos_complement);
 
                        /* integers are convertable if
                         *   - both have the same sign and lm is the larger one
@@ -548,12 +548,12 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) {
                         *     (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))
+                       if (mode_is_signed(sm)) {
+                               if (!mode_is_signed(lm))
                                        return 0;
                                return sm_bits <= lm_bits;
                        } else {
-                               if(mode_is_signed(lm)) {
+                               if (mode_is_signed(lm)) {
                                        return sm_bits < lm_bits;
                                }
                                return sm_bits <= lm_bits;
@@ -592,6 +592,37 @@ 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) {
+       int sm_bits, lm_bits;
+       ir_mode_arithmetic arith;
+
+       assert(sm);
+       assert(lm);
+
+       if (sm == lm) return 1;
+
+       if (sm == mode_b)
+               return mode_is_int(lm);
+
+       sm_bits = get_mode_size_bits(sm);
+       lm_bits = get_mode_size_bits(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;
+       }
+}
+
 /* 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));
@@ -843,7 +874,11 @@ void init_mode(void) {
 ir_mode *find_unsigned_mode(const ir_mode *mode) {
        ir_mode n = *mode;
 
-       assert(mode->sort == irms_int_number);
+       /* allowed for reference mode */
+       if (mode->sort == irms_reference)
+               n.sort = irms_int_number;
+
+       assert(n.sort == irms_int_number);
        n.sign = 0;
        return find_mode(&n);
 }
@@ -903,6 +938,25 @@ int mode_wrap_around(const ir_mode *mode) {
        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;
+
+       if (src == dst)
+               return 1;
+       if (get_mode_size_bits(src) != get_mode_size_bits(dst))
+               return 0;
+       ma = get_mode_arithmetic(src);
+       if (ma != get_mode_arithmetic(dst))
+               return 0;
+
+       return ma == irma_twos_complement || ma == irma_ones_complement;
+}
+
 void finish_mode(void) {
        obstack_free(&modes, 0);
        DEL_ARR_F(mode_list);