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]

Another fix for simd subregs: reload & simplify_subreg


It needed these patches to get the included testcase to
compile for sh64-elf (and some target specific patches
thrown in, but that is another story).
... and as an added bonus, reload gets a little simpler.

-- 
--------------------------
SuperH
2430 Aztec West / Almondsbury / BRISTOL / BS32 4AQ
T:+44 1454 462330
Mon Jul 15 12:32:59 2002  J"orn Rennecke <joern.rennecke@superh.com>

gcc:
	* reload.c (find_reloads_toplev): Use simplify_gen_subreg.
	* simplify-rtx.c (simplify_subreg): When converting to a non-int
	mode, try to convert to an integer mode of matching size first.

gcc/testsuite:
	* gcc.c-torture/compile/simd-4.c: New test.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.185
diff -p -r1.185 reload.c
*** reload.c	14 Jun 2002 01:41:53 -0000	1.185
--- reload.c	12 Jul 2002 02:57:15 -0000
*************** find_reloads_toplev (x, opnum, type, ind
*** 4404,4453 ****
  
        if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
  	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
! 	  && reg_equiv_constant[regno] != 0
! 	  && (tem = operand_subword (reg_equiv_constant[regno],
! 				     SUBREG_BYTE (x) / UNITS_PER_WORD, 0,
! 				     GET_MODE (SUBREG_REG (x)))) != 0)
  	{
! 	  /* TEM is now a word sized constant for the bits from X that
! 	     we wanted.  However, TEM may be the wrong representation.
! 
! 	     Use gen_lowpart_common to convert a CONST_INT into a
! 	     CONST_DOUBLE and vice versa as needed according to by the mode
! 	     of the SUBREG.  */
! 	  tem = gen_lowpart_common (GET_MODE (x), tem);
  	  if (!tem)
  	    abort ();
  	  return tem;
  	}
- 
-       /* If the SUBREG is wider than a word, the above test will fail.
- 	 For example, we might have a SImode SUBREG of a DImode SUBREG_REG
- 	 for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
- 	 a 32 bit target.  We still can - and have to - handle this
- 	 for non-paradoxical subregs of CONST_INTs.  */
-       if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
- 	  && reg_equiv_constant[regno] != 0
- 	  && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
- 	  && (GET_MODE_SIZE (GET_MODE (x))
- 	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
- 	{
- 	  int shift = SUBREG_BYTE (x) * BITS_PER_UNIT;
- 	  if (WORDS_BIG_ENDIAN)
- 	    shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
- 		     - GET_MODE_BITSIZE (GET_MODE (x))
- 		     - shift);
- 	  /* Here we use the knowledge that CONST_INTs have a
- 	     HOST_WIDE_INT field.  */
- 	  if (shift >= HOST_BITS_PER_WIDE_INT)
- 	    shift = HOST_BITS_PER_WIDE_INT - 1;
- 	  return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
- 	}
- 
-       if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
- 	  && reg_equiv_constant[regno] != 0
- 	  && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
- 	abort ();
  
        /* If the subreg contains a reg that will be converted to a mem,
  	 convert the subreg to a narrower memref now.
--- 4407,4421 ----
  
        if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
  	  && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
! 	  && reg_equiv_constant[regno] != 0)
  	{
! 	  tem =
! 	    simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
! 				 GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
  	  if (!tem)
  	    abort ();
  	  return tem;
  	}
  
        /* If the subreg contains a reg that will be converted to a mem,
  	 convert the subreg to a narrower memref now.
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.110
diff -p -r1.110 simplify-rtx.c
*** simplify-rtx.c	11 Jul 2002 23:52:59 -0000	1.110
--- simplify-rtx.c	12 Jul 2002 02:57:16 -0000
*************** simplify_subreg (outermode, op, innermod
*** 2339,2346 ****
  	      return NULL_RTX;
  	  return simplify_subreg (outermode, op, new_mode, subbyte);
  	}
!       else if (GET_MODE_CLASS (outermode) != MODE_VECTOR_INT
! 	       && GET_MODE_CLASS (outermode) != MODE_VECTOR_FLOAT)
          /* This shouldn't happen, but let's not do anything stupid.  */
  	return NULL_RTX;
      }
--- 2339,2345 ----
  	      return NULL_RTX;
  	  return simplify_subreg (outermode, op, new_mode, subbyte);
  	}
!       else if (GET_MODE_CLASS (outermode) == MODE_INT)
          /* This shouldn't happen, but let's not do anything stupid.  */
  	return NULL_RTX;
      }
*************** simplify_subreg (outermode, op, innermod
*** 2372,2378 ****
  	 Later it we should move all simplification code here and rewrite
  	 GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
  	 using SIMPLIFY_SUBREG.  */
!       if (subreg_lowpart_offset (outermode, innermode) == byte)
  	{
  	  rtx new = gen_lowpart_if_possible (outermode, op);
  	  if (new)
--- 2378,2385 ----
  	 Later it we should move all simplification code here and rewrite
  	 GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
  	 using SIMPLIFY_SUBREG.  */
!       if (subreg_lowpart_offset (outermode, innermode) == byte
! 	  && GET_CODE (op) != CONST_VECTOR)
  	{
  	  rtx new = gen_lowpart_if_possible (outermode, op);
  	  if (new)
*************** simplify_subreg (outermode, op, innermod
*** 2391,2396 ****
--- 2398,2416 ----
  	    return new;
  	}
  
+       if (GET_MODE_CLASS (outermode) != MODE_INT)
+ 	{
+ 	  enum machine_mode new_mode = int_mode_for_mode (outermode);
+ 
+ 	  if (new_mode != innermode || byte != 0)
+ 	    {
+ 	      op = simplify_subreg (new_mode, op, innermode, byte);
+ 	      if (! op)
+ 		return NULL_RTX;
+ 	      return simplify_subreg (outermode, op, new_mode, 0);
+ 	    }
+ 	}
+ 
        offset = byte * BITS_PER_UNIT;
        switch (GET_CODE (op))
  	{
*** /dev/null	Thu Aug 30 21:30:55 2001
--- testsuite/gcc.c-torture/compile/simd-4.c	Fri Jul 12 13:22:49 2002
***************
*** 0 ****
--- 1,15 ----
+ typedef float floatvect2 __attribute__((mode(V4SF)));
+ 
+ typedef union
+ {
+     floatvect2 vector;
+     float f[2];
+ }resfloatvect2;
+ 
+ void tempf(floatvect2 *x, floatvect2 *y)
+ {
+         floatvect2 temp= *x;
+         floatvect2 temp1=*y;
+         resfloatvect2 temp2;
+         *x=temp+temp1;
+ }

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