X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firmode.c;h=75b02bcb73f097abb44caae59bf6edd74e67a447;hb=bb5c6d5ce2e35c4074900017f8c8e1a4935054d0;hp=0a41285e50e34e61949c90f04e35349778992551;hpb=077eace885a7e700b3189f8d65acd04e689d4292;p=libfirm diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index 0a41285e5..75b02bcb7 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -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);