This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH/RFC] SH: Many ICEs on complex numbers


On Sun, Dec 12, 2004 at 05:06:13PM +0900, Kaz Kojima wrote:
> All new failures for complex numbers went away on x86 cross
> sh4-unknown-linux-gnu with your patch.  Thanks!

Thanks.  Additionally tested on ia64-linux, and comments updated.


r~


        * expr.c (emit_move_change_mode): New.
        (emit_move_via_alt_mode): Use it.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.758
diff -c -p -d -r1.758 expr.c
*** expr.c	9 Dec 2004 10:54:34 -0000	1.758
--- expr.c	12 Dec 2004 21:10:25 -0000
*************** read_complex_part (rtx cplx, bool imag_p
*** 2652,2697 ****
  			    true, NULL_RTX, imode, imode);
  }
  
! /* A subroutine of emit_move_insn_1.  Generate a move from Y into X using
!    ALT_MODE instead of the operand's natural mode, MODE.  CODE is the insn
!    code for the move in ALT_MODE, and is known to be valid.  Returns the
!    instruction emitted.  */
  
  static rtx
! emit_move_via_alt_mode (enum machine_mode alt_mode, enum machine_mode mode,
! 			enum insn_code code, rtx x, rtx y)
  {
!   /* Get X and Y in ALT_MODE.  We can't use gen_lowpart here because it
!      may call change_address which is not appropriate if we were
!      called when a reload was in progress.  We don't have to worry
!      about changing the address since the size in bytes is supposed to
!      be the same.  Copy the MEM to change the mode and move any
!      substitutions from the old MEM to the new one.  */
  
!   if (reload_in_progress)
      {
!       rtx x1 = x, y1 = y;
! 
!       x = gen_lowpart_common (alt_mode, x1);
!       if (x == 0 && MEM_P (x1))
! 	{
! 	  x = adjust_address_nv (x1, alt_mode, 0);
! 	  copy_replacements (x1, x);
! 	}
  
!       y = gen_lowpart_common (alt_mode, y1);
!       if (y == 0 && MEM_P (y1))
! 	{
! 	  y = adjust_address_nv (y1, alt_mode, 0);
! 	  copy_replacements (y1, y);
! 	}
      }
    else
      {
!       x = simplify_gen_subreg (alt_mode, x, mode, 0);
!       y = simplify_gen_subreg (alt_mode, y, mode, 0);
      }
  
    return emit_insn (GEN_FCN (code) (x, y));
  }
  
--- 2652,2706 ----
  			    true, NULL_RTX, imode, imode);
  }
  
! /* A subroutine of emit_move_via_alt_mode.  Yet another lowpart generator.
!    NEW_MODE and OLD_MODE are the same size.  Return NULL if X cannot be
!    represented in NEW_MODE.  */
  
  static rtx
! emit_move_change_mode (enum machine_mode new_mode,
! 		       enum machine_mode old_mode, rtx x)
  {
!   rtx ret;
  
!   if (reload_in_progress && MEM_P (x))
      {
!       /* We can't use gen_lowpart here because it may call change_address
! 	 which is not appropriate if we were called when a reload was in
! 	 progress.  We don't have to worry about changing the address since
! 	 the size in bytes is supposed to be the same.  Copy the MEM to
! 	 change the mode and move any substitutions from the old MEM to
! 	 the new one.  */
  
!       ret = adjust_address_nv (x, new_mode, 0);
!       copy_replacements (x, ret);
      }
    else
      {
!       /* Note that we do want simplify_subreg's behaviour of validating
! 	 that the new mode is ok for a hard register.  If we were to use
! 	 simplify_gen_subreg, we would create the subreg, but would
! 	 probably run into the target not being able to implement it.  */
!       ret = simplify_subreg (new_mode, x, old_mode, 0);
      }
  
+   return ret;
+ }
+ 
+ /* A subroutine of emit_move_insn_1.  Generate a move from Y into X using
+    ALT_MODE instead of the operand's natural mode, MODE.  CODE is the insn
+    code for the move in ALT_MODE, and is known to be valid.  Returns the
+    instruction emitted, or NULL if X or Y cannot be represented in ALT_MODE.  */
+ 
+ static rtx
+ emit_move_via_alt_mode (enum machine_mode alt_mode, enum machine_mode mode,
+ 			enum insn_code code, rtx x, rtx y)
+ {
+   x = emit_move_change_mode (alt_mode, mode, x);
+   if (x == NULL_RTX)
+     return NULL_RTX;
+   y = emit_move_change_mode (alt_mode, mode, y);
+   if (y == NULL_RTX)
+     return NULL_RTX;
    return emit_insn (GEN_FCN (code) (x, y));
  }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]