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]

[cft] arm load/store multiple cleanup


We were trying to preserve the bits that, previously, absolutely
positively had to be preserved for correctness.  Better, I think
is to use the proper routines to preserve all of the alias info.

Can someone test this properly, please?


r~



	* config/arm/arm.c (arm_gen_load_multiple): Use
	adjust_automodify_address.  Take base memory and offset instead
	of unchanging/struct/scalar bits.
	(arm_gen_store_multiple): Likewise.
	(arm_gen_movmemqi): Use adjust_automodify_address.
	* config/arm/arm-protos.h: Update decls.
	* config/arm/arm.md (load_multiple): Update arm_gen_load_multiple call.
	(store_multiple): Similarly.

Index: arm-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
retrieving revision 1.74
diff -c -p -d -r1.74 arm-protos.h
*** arm-protos.h	11 Aug 2004 21:02:45 -0000	1.74
--- arm-protos.h	18 Aug 2004 21:58:09 -0000
*************** extern int load_multiple_sequence (rtx *
*** 116,123 ****
  extern const char *emit_ldm_seq (rtx *, int);
  extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
  extern const char * emit_stm_seq (rtx *, int);
! extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int);
! extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int);
  extern int arm_gen_movmemqi (rtx *);
  extern rtx arm_gen_rotated_half_load (rtx);
  extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
--- 116,125 ----
  extern const char *emit_ldm_seq (rtx *, int);
  extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
  extern const char * emit_stm_seq (rtx *, int);
! extern rtx arm_gen_load_multiple (int, int, rtx, int, int,
! 				  rtx, HOST_WIDE_INT *);
! extern rtx arm_gen_store_multiple (int, int, rtx, int, int,
! 				   rtx, HOST_WIDE_INT *);
  extern int arm_gen_movmemqi (rtx *);
  extern rtx arm_gen_rotated_half_load (rtx);
  extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
Index: arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.392
diff -c -p -d -r1.392 arm.c
*** arm.c	18 Aug 2004 21:08:23 -0000	1.392
--- arm.c	18 Aug 2004 21:58:10 -0000
*************** multi_register_push (rtx op, enum machin
*** 5893,5905 ****
  
  rtx
  arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
! 		       int write_back, int unchanging_p, int in_struct_p,
! 		       int scalar_p)
  {
    int i = 0, j;
    rtx result;
    int sign = up ? 1 : -1;
!   rtx mem;
  
    /* XScale has load-store double instructions, but they have stricter
       alignment requirements than load-store multiple, so we cannot
--- 5893,5905 ----
  
  rtx
  arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
! 		       int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
  {
+   HOST_WIDE_INT offset = *offsetp;
    int i = 0, j;
    rtx result;
    int sign = up ? 1 : -1;
!   rtx mem, addr;
  
    /* XScale has load-store double instructions, but they have stricter
       alignment requirements than load-store multiple, so we cannot
*************** arm_gen_load_multiple (int base_regno, i
*** 5937,5951 ****
        
        for (i = 0; i < count; i++)
  	{
! 	  mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign));
! 	  MEM_READONLY_P (mem) = unchanging_p;
! 	  MEM_IN_STRUCT_P (mem) = in_struct_p;
! 	  MEM_SCALAR_P (mem) = scalar_p;
  	  emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
  	}
  
        if (write_back)
! 	emit_move_insn (from, plus_constant (from, count * 4 * sign));
  
        seq = get_insns ();
        end_sequence ();
--- 5937,5953 ----
        
        for (i = 0; i < count; i++)
  	{
! 	  addr = plus_constant (from, i * 4 * sign);
! 	  mem = adjust_automodify_address (basemem, SImode, addr, offset);
  	  emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
+ 	  offset += 4 * sign;
  	}
  
        if (write_back)
! 	{
! 	  emit_move_insn (from, plus_constant (from, count * 4 * sign));
! 	  *offsetp = offset;
! 	}
  
        seq = get_insns ();
        end_sequence ();
*************** arm_gen_load_multiple (int base_regno, i
*** 5966,5991 ****
  
    for (j = 0; i < count; i++, j++)
      {
!       mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
!       MEM_READONLY_P (mem) = unchanging_p;
!       MEM_IN_STRUCT_P (mem) = in_struct_p;
!       MEM_SCALAR_P (mem) = scalar_p;
        XVECEXP (result, 0, i)
  	= gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
      }
  
    return result;
  }
  
  rtx
  arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
! 			int write_back, int unchanging_p, int in_struct_p,
! 			int scalar_p)
  {
    int i = 0, j;
    rtx result;
    int sign = up ? 1 : -1;
!   rtx mem;
  
    /* See arm_gen_load_multiple for discussion of
       the pros/cons of ldm/stm usage for XScale.  */
--- 5968,5995 ----
  
    for (j = 0; i < count; i++, j++)
      {
!       addr = plus_constant (from, j * 4 * sign);
!       mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
        XVECEXP (result, 0, i)
  	= gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
+       offset += 4 * sign;
      }
  
+   if (write_back)
+     *offsetp = offset;
+ 
    return result;
  }
  
  rtx
  arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
! 			int write_back, rtx basemem, HOST_WIDE_INT *offsetp)
  {
+   HOST_WIDE_INT offset = *offsetp;
    int i = 0, j;
    rtx result;
    int sign = up ? 1 : -1;
!   rtx mem, addr;
  
    /* See arm_gen_load_multiple for discussion of
       the pros/cons of ldm/stm usage for XScale.  */
*************** arm_gen_store_multiple (int base_regno, 
*** 5997,6011 ****
        
        for (i = 0; i < count; i++)
  	{
! 	  mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign));
! 	  MEM_READONLY_P (mem) = unchanging_p;
! 	  MEM_IN_STRUCT_P (mem) = in_struct_p;
! 	  MEM_SCALAR_P (mem) = scalar_p;
  	  emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
  	}
  
        if (write_back)
! 	emit_move_insn (to, plus_constant (to, count * 4 * sign));
  
        seq = get_insns ();
        end_sequence ();
--- 6001,6017 ----
        
        for (i = 0; i < count; i++)
  	{
! 	  addr = plus_constant (to, i * 4 * sign);
! 	  mem = adjust_automodify_address (basemem, SImode, addr, offset);
  	  emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
+ 	  offset += 4 * sign;
  	}
  
        if (write_back)
! 	{
! 	  emit_move_insn (to, plus_constant (to, count * 4 * sign));
! 	  *offsetp = offset;
! 	}
  
        seq = get_insns ();
        end_sequence ();
*************** arm_gen_store_multiple (int base_regno, 
*** 6026,6040 ****
  
    for (j = 0; i < count; i++, j++)
      {
!       mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
!       MEM_READONLY_P (mem) = unchanging_p;
!       MEM_IN_STRUCT_P (mem) = in_struct_p;
!       MEM_SCALAR_P (mem) = scalar_p;
! 
        XVECEXP (result, 0, i)
  	= gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
      }
  
    return result;
  }
  
--- 6032,6047 ----
  
    for (j = 0; i < count; i++, j++)
      {
!       addr = plus_constant (to, j * 4 * sign);
!       mem = adjust_automodify_address_nv (basemem, SImode, addr, offset);
        XVECEXP (result, 0, i)
  	= gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
+       offset += 4 * sign;
      }
  
+   if (write_back)
+     *offsetp = offset;
+ 
    return result;
  }
  
*************** int
*** 6042,6054 ****
  arm_gen_movmemqi (rtx *operands)
  {
    HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
    int i;
!   rtx src, dst;
!   rtx st_src, st_dst, fin_src, fin_dst;
    rtx part_bytes_reg = NULL;
    rtx mem;
-   int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
-   int dst_scalar_p, src_scalar_p;
  
    if (GET_CODE (operands[2]) != CONST_INT
        || GET_CODE (operands[3]) != CONST_INT
--- 6049,6059 ----
  arm_gen_movmemqi (rtx *operands)
  {
    HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
+   HOST_WIDE_INT srcoffset, dstoffset;
    int i;
!   rtx src, dst, srcbase, dstbase;
    rtx part_bytes_reg = NULL;
    rtx mem;
  
    if (GET_CODE (operands[2]) != CONST_INT
        || GET_CODE (operands[3]) != CONST_INT
*************** arm_gen_movmemqi (rtx *operands)
*** 6056,6077 ****
        || INTVAL (operands[3]) & 3)
      return 0;
  
!   st_dst = XEXP (operands[0], 0);
!   st_src = XEXP (operands[1], 0);
! 
!   dst_unchanging_p = MEM_READONLY_P (operands[0]);
!   dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
!   dst_scalar_p = MEM_SCALAR_P (operands[0]);
!   src_unchanging_p = MEM_READONLY_P (operands[1]);
!   src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
!   src_scalar_p = MEM_SCALAR_P (operands[1]);
  
!   fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
!   fin_src = src = copy_to_mode_reg (SImode, st_src);
  
    in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
    out_words_to_go = INTVAL (operands[2]) / 4;
    last_bytes = INTVAL (operands[2]) & 3;
  
    if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
      part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
--- 6061,6076 ----
        || INTVAL (operands[3]) & 3)
      return 0;
  
!   dstbase = operands[0];
!   srcbase = operands[1];
  
!   dst = copy_to_mode_reg (SImode, XEXP (dstbase, 0));
!   src = copy_to_mode_reg (SImode, XEXP (srcbase, 0));
  
    in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
    out_words_to_go = INTVAL (operands[2]) / 4;
    last_bytes = INTVAL (operands[2]) & 3;
+   dstoffset = srcoffset = 0;
  
    if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
      part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
*************** arm_gen_movmemqi (rtx *operands)
*** 6080,6117 ****
      {
        if (in_words_to_go > 4)
  	emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
! 					  src_unchanging_p,
! 					  src_in_struct_p,
! 					  src_scalar_p));
        else
  	emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, 
! 					  FALSE, src_unchanging_p,
! 					  src_in_struct_p, src_scalar_p));
  
        if (out_words_to_go)
  	{
  	  if (out_words_to_go > 4)
  	    emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
! 					       dst_unchanging_p,
! 					       dst_in_struct_p,
! 					       dst_scalar_p));
  	  else if (out_words_to_go != 1)
  	    emit_insn (arm_gen_store_multiple (0, out_words_to_go,
  					       dst, TRUE, 
  					       (last_bytes == 0
  						? FALSE : TRUE),
! 					       dst_unchanging_p,
! 					       dst_in_struct_p,
! 					       dst_scalar_p));
  	  else
  	    {
! 	      mem = gen_rtx_MEM (SImode, dst);
! 	      MEM_READONLY_P (mem) = dst_unchanging_p;
! 	      MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
! 	      MEM_SCALAR_P (mem) = dst_scalar_p;
  	      emit_move_insn (mem, gen_rtx_REG (SImode, 0));
  	      if (last_bytes != 0)
! 		emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
  	    }
  	}
  
--- 6079,6109 ----
      {
        if (in_words_to_go > 4)
  	emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
! 					  srcbase, &srcoffset));
        else
  	emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, 
! 					  FALSE, srcbase, &srcoffset));
  
        if (out_words_to_go)
  	{
  	  if (out_words_to_go > 4)
  	    emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
! 					       dstbase, &dstoffset));
  	  else if (out_words_to_go != 1)
  	    emit_insn (arm_gen_store_multiple (0, out_words_to_go,
  					       dst, TRUE, 
  					       (last_bytes == 0
  						? FALSE : TRUE),
! 					       dstbase, &dstoffset));
  	  else
  	    {
! 	      mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
  	      emit_move_insn (mem, gen_rtx_REG (SImode, 0));
  	      if (last_bytes != 0)
! 		{
! 		  emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
! 		  dstoffset += 4;
! 		}
  	    }
  	}
  
*************** arm_gen_movmemqi (rtx *operands)
*** 6124,6142 ****
      {
        rtx sreg;
        
!       mem = gen_rtx_MEM (SImode, src);
!       MEM_READONLY_P (mem) = src_unchanging_p;
!       MEM_IN_STRUCT_P (mem) = src_in_struct_p;
!       MEM_SCALAR_P (mem) = src_scalar_p;
!       emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
!       emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
!       
!       mem = gen_rtx_MEM (SImode, dst);
!       MEM_READONLY_P (mem) = dst_unchanging_p;
!       MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
!       MEM_SCALAR_P (mem) = dst_scalar_p;
        emit_move_insn (mem, sreg);
-       emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
        in_words_to_go--;
        
        if (in_words_to_go)	/* Sanity check */
--- 6116,6126 ----
      {
        rtx sreg;
        
!       mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
!       sreg = copy_to_reg (mem);
! 
!       mem = adjust_automodify_address (dstbase, SImode, dst, dstoffset);
        emit_move_insn (mem, sreg);
        in_words_to_go--;
        
        if (in_words_to_go)	/* Sanity check */
*************** arm_gen_movmemqi (rtx *operands)
*** 6148,6157 ****
        if (in_words_to_go < 0)
  	abort ();
  
!       mem = gen_rtx_MEM (SImode, src);
!       MEM_READONLY_P (mem) = src_unchanging_p;
!       MEM_IN_STRUCT_P (mem) = src_in_struct_p;
!       MEM_SCALAR_P (mem) = src_scalar_p;
        part_bytes_reg = copy_to_mode_reg (SImode, mem);
      }
  
--- 6132,6138 ----
        if (in_words_to_go < 0)
  	abort ();
  
!       mem = adjust_automodify_address (srcbase, SImode, src, srcoffset);
        part_bytes_reg = copy_to_mode_reg (SImode, mem);
      }
  
*************** arm_gen_movmemqi (rtx *operands)
*** 6169,6178 ****
        
        while (last_bytes)
  	{
! 	  mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
! 	  MEM_READONLY_P (mem) = dst_unchanging_p;
! 	  MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
! 	  MEM_SCALAR_P (mem) = dst_scalar_p;
  	  emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
  
  	  if (--last_bytes)
--- 6150,6158 ----
        
        while (last_bytes)
  	{
! 	  mem = adjust_automodify_address (dstbase, QImode,
! 					   plus_constant (dst, last_bytes - 1),
! 					   dstoffset + last_bytes - 1);
  	  emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
  
  	  if (--last_bytes)
*************** arm_gen_movmemqi (rtx *operands)
*** 6188,6215 ****
      {
        if (last_bytes > 1)
  	{
! 	  mem = gen_rtx_MEM (HImode, dst);
! 	  MEM_READONLY_P (mem) = dst_unchanging_p;
! 	  MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
! 	  MEM_SCALAR_P (mem) = dst_scalar_p;
  	  emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
  	  last_bytes -= 2;
  	  if (last_bytes)
  	    {
  	      rtx tmp = gen_reg_rtx (SImode);
- 
  	      emit_insn (gen_addsi3 (dst, dst, const2_rtx));
  	      emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
  	      part_bytes_reg = tmp;
  	    }
  	}
        
        if (last_bytes)
  	{
! 	  mem = gen_rtx_MEM (QImode, dst);
! 	  MEM_READONLY_P (mem) = dst_unchanging_p;
! 	  MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
! 	  MEM_SCALAR_P (mem) = dst_scalar_p;
  	  emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
  	}
      }
--- 6168,6189 ----
      {
        if (last_bytes > 1)
  	{
! 	  mem = adjust_automodify_address (dstbase, HImode, dst, dstoffset);
  	  emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
  	  last_bytes -= 2;
  	  if (last_bytes)
  	    {
  	      rtx tmp = gen_reg_rtx (SImode);
  	      emit_insn (gen_addsi3 (dst, dst, const2_rtx));
  	      emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
  	      part_bytes_reg = tmp;
+ 	      dstoffset += 2;
  	    }
  	}
        
        if (last_bytes)
  	{
! 	  mem = adjust_automodify_address (dstbase, QImode, dst, dstoffset);
  	  emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
  	}
      }
Index: arm.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.md,v
retrieving revision 1.179
diff -c -p -d -r1.179 arm.md
*** arm.md	18 Aug 2004 08:24:26 -0000	1.179
--- arm.md	18 Aug 2004 21:58:10 -0000
***************
*** 5244,5250 ****
                            (match_operand:SI 1 "" ""))
                       (use (match_operand:SI 2 "" ""))])]
    "TARGET_ARM"
!   "
    /* Support only fixed point registers.  */
    if (GET_CODE (operands[2]) != CONST_INT
        || INTVAL (operands[2]) > 14
--- 5244,5252 ----
                            (match_operand:SI 1 "" ""))
                       (use (match_operand:SI 2 "" ""))])]
    "TARGET_ARM"
! {
!   HOST_WIDE_INT offset = 0;
! 
    /* Support only fixed point registers.  */
    if (GET_CODE (operands[2]) != CONST_INT
        || INTVAL (operands[2]) > 14
***************
*** 5258,5268 ****
    operands[3]
      = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
  			     force_reg (SImode, XEXP (operands[1], 0)),
! 			     TRUE, FALSE, MEM_READONLY_P (operands[1]),
! 			     MEM_IN_STRUCT_P (operands[1]),
! 	                     MEM_SCALAR_P (operands[1]));
!   "
! )
  
  ;; Load multiple with write-back
  
--- 5260,5267 ----
    operands[3]
      = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
  			     force_reg (SImode, XEXP (operands[1], 0)),
! 			     TRUE, FALSE, operands[1], &offset);
! })
  
  ;; Load multiple with write-back
  
***************
*** 5366,5372 ****
                            (match_operand:SI 1 "" ""))
                       (use (match_operand:SI 2 "" ""))])]
    "TARGET_ARM"
!   "
    /* Support only fixed point registers.  */
    if (GET_CODE (operands[2]) != CONST_INT
        || INTVAL (operands[2]) > 14
--- 5365,5373 ----
                            (match_operand:SI 1 "" ""))
                       (use (match_operand:SI 2 "" ""))])]
    "TARGET_ARM"
! {
!   HOST_WIDE_INT offset = 0;
! 
    /* Support only fixed point registers.  */
    if (GET_CODE (operands[2]) != CONST_INT
        || INTVAL (operands[2]) > 14
***************
*** 5380,5390 ****
    operands[3]
      = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
  			      force_reg (SImode, XEXP (operands[0], 0)),
! 			      TRUE, FALSE, MEM_READONLY_P (operands[0]),
! 			      MEM_IN_STRUCT_P (operands[0]), 
! 	                      MEM_SCALAR_P (operands[0]));
!   "
! )
  
  ;; Store multiple with write-back
  
--- 5381,5388 ----
    operands[3]
      = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
  			      force_reg (SImode, XEXP (operands[0], 0)),
! 			      TRUE, FALSE, operands[0], &offset);
! })
  
  ;; Store multiple with write-back
  


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