convert_move: partial_int modes

DJ Delorie dj@redhat.com
Sat May 28 02:25:00 GMT 2005


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.  */



More information about the Gcc-patches mailing list