This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
convert_move: partial_int modes
- From: DJ Delorie <dj at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 27 May 2005 22:24:26 -0400
- Subject: convert_move: partial_int modes
convert_move had logic to detect when smallest_mode_for_size didn't
give us the "to" mode, but the logic was faulty. If it gave us an
unexpected mode, we need to do *that* conversion, and then proceed to
convert *that rtx* to the target mode. The logic updated the "from
mode" but didn't update "from" to go with it.
* expr.c (convert_move): When a partial_int requires multiple
conversion steps, make sure successive steps convert the
intermediate value, not the original value.
This is needed for an internal port of ours, but with that port it
works fine with this patch and fails miserably without it.
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.790
diff -p -U3 -r1.790 expr.c
--- expr.c 17 May 2005 09:55:16 -0000 1.790
+++ expr.c 28 May 2005 02:10:52 -0000
@@ -466,19 +466,27 @@ convert_move (rtx to, rtx from, int unsi
}
if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
{
+ rtx new_from;
enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code
!= CODE_FOR_nothing);
- emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
- to, from, UNKNOWN);
if (to_mode == full_mode)
- return;
+ {
+ emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+ to, from, UNKNOWN);
+ return;
+ }
+
+ new_from = gen_reg_rtx (full_mode);
+ emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+ new_from, from, UNKNOWN);
/* else proceed to integer conversions below. */
from_mode = full_mode;
+ from = new_from;
}
/* Now both modes are integers. */