sign_extend does zero extension for unsigned integer modes
[r8359]
and often defined in other ways! */
static const char sex_digit[4] = { SC_E, SC_C, SC_8, SC_0 };
and often defined in other ways! */
static const char sex_digit[4] = { SC_E, SC_C, SC_8, SC_0 };
+static const char zex_digit[4] = { SC_1, SC_3, SC_7, SC_F };
static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 };
static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 };
static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 };
static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 };
- * Do sign extension if the mode is signed, expects all upper bits
- * cleared.
+ * Do sign extension if the mode is signed, otherwise to zero extension.
*/
void sign_extend(char *calc_buffer, ir_mode *mode) {
*/
void sign_extend(char *calc_buffer, ir_mode *mode) {
- if (mode_is_signed(mode)) {
- int bits = get_mode_size_bits(mode) - 1;
- int ofs = bits >> 2;
- int max = max_digit[bits & 3];
- int i;
+ int bits = get_mode_size_bits(mode) - 1;
+ int nibble = bits >> 2;
+ int max = max_digit[bits & 3];
+ int i;
- if (calc_buffer[ofs] > max) {
+ if (mode_is_signed(mode)) {
+ if (calc_buffer[nibble] > max) {
/* sign bit is set, we need sign expansion */
/* sign bit is set, we need sign expansion */
- for (i = ofs + 1; i < calc_buffer_size; ++i)
+ for (i = nibble + 1; i < calc_buffer_size; ++i)
- calc_buffer[ofs] = or_table[(int) calc_buffer[ofs]][(int) sex_digit[bits & 3]];
+ calc_buffer[nibble] = or_table[(int)calc_buffer[nibble]][(int)sex_digit[bits & 3]];
+ } else {
+ /* set all bits to zero */
+ for (i = nibble + 1; i < calc_buffer_size; ++i)
+ calc_buffer[i] = SC_0;
+ calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]];
+ } else {
+ /* do zero extension */
+ for (i = nibble + 1; i < calc_buffer_size; ++i)
+ calc_buffer[i] = SC_0;
+ calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]];
switch (get_mode_sort(m)) {
case irms_int_number:
case irms_character:
switch (get_mode_sort(m)) {
case irms_int_number:
case irms_character:
- return get_tarval_overflow(src->value, src->length, m);
+ buffer = alloca(sc_get_buffer_length());
+ memcpy(buffer, src->value, sc_get_buffer_length());
+ sign_extend(buffer, src->mode);
+ return get_tarval_overflow(buffer, src->length, m);
case irms_internal_boolean:
/* XXX C semantics */
case irms_internal_boolean:
/* XXX C semantics */