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