Commit fa9dada1 authored by Michael Beck's avatar Michael Beck
Browse files

BugFix of r22380 (fixes 176.gcc):

 - smaller_mode() had the meaning "can be represented", restored
 - renamed new implemnetation into values_in_mode() with the meaning
   "can be converted into in back" which is different from smaller_mode()

[r22408]
parent 3611de8c
......@@ -407,10 +407,26 @@ int mode_is_float_vector (const ir_mode *mode);
int mode_is_int_vector (const ir_mode *mode);
/*@}*/
/** Returns true if sm can be converted to lm without loss
according to firm definition */
/**
* Returns true if sm can be converted to lm without loss
* according to firm definition.
*
* Note that mode_Iu is NOT smaller than mode_Is here.
*
* @see values_in_mode()
*/
int smaller_mode(const ir_mode *sm, const ir_mode *lm);
/**
* Returns true if a value of mode sm can be converted into mode lm
* and backwards without loss.
*
* Note that mode_Iu values CAN be converted in mode_Is and back.
*
* @see smaller_mode()
*/
int values_in_mode(const ir_mode *sm, const ir_mode *lm);
/**
* Returns a matching unsigned mode for a given integer signed mode.
* Returns NULL if no matching mode exists.
......
......@@ -523,6 +523,79 @@ int (mode_is_int_vector)(const ir_mode *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;
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;
}
break;
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 lenghts ?*/
return 0;
case irms_internal_boolean:
return mode_is_int(lm);
default:
break;
}
/* else */
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);
......
......@@ -1254,7 +1254,7 @@ restart:
n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
} else if (get_mode_arithmetic(n_mode) == get_mode_arithmetic(a_mode)) {
if (smaller_mode(b_mode, a_mode)) {
if (values_in_mode(b_mode, a_mode)) {
n = b; /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment