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]

SH patch applied: fix target/21255



2005-08-31  J"orn Rennecke <joern.rennecke@st.com>

gcc:
	PR target/21255
	* sh.c (print_operand, %R and %S): Add handling of floating point
	registers, memory, constants and invalid operands.
gcc/testsuite:
	PR target/21255
	* gcc.dg/pr21255-1.c: New test.
	* gcc.dg/pr21255-2-mb.c: Likewise.
	* gcc.dg/pr21255-2-ml.c: Likewise.
	* gcc.dg/pr21255-3.c: Likewise.
	* gcc.dg/pr21255-4.c: Likewise.

Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.345
diff -p -r1.345 sh.c
*** config/sh/sh.c	23 Aug 2005 13:06:55 -0000	1.345
--- config/sh/sh.c	31 Aug 2005 18:49:49 -0000
*************** print_operand (FILE *stream, rtx x, int 
*** 734,744 ****
        x = mark_constant_pool_use (x);
        output_addr_const (stream, x);
        break;
      case 'R':
!       fputs (reg_names[REGNO (x) + LSW], (stream));
        break;
      case 'S':
!       fputs (reg_names[REGNO (x) + MSW], (stream));
        break;
      case 'T':
        /* Next word of a double.  */
--- 734,799 ----
        x = mark_constant_pool_use (x);
        output_addr_const (stream, x);
        break;
+     /* N.B.: %R / %S / %T adjust memory addresses by four.
+        For SHMEDIA, that means they can be used to access the first and
+        second 32 bit part of a 64 bit (or larger) value that
+        might be held in floating point registers or memory.
+        While they can be used to access 64 bit parts of a larger value
+        held in general purpose registers, that won't work with memory -
+        neither for fp registers, since the frxx names are used.  */
      case 'R':
!       if (REG_P (x) || GET_CODE (x) == SUBREG)
! 	{
! 	  regno = true_regnum (x);
! 	  regno += FP_REGISTER_P (regno) ? 1 : LSW;
! 	  fputs (reg_names[regno], (stream));
! 	}
!       else if (MEM_P (x))
! 	{
! 	  x = adjust_address (x, SImode, 4 * LSW);
! 	  print_operand_address (stream, XEXP (x, 0));
! 	}
!       else
! 	{
! 	  rtx sub = NULL_RTX;
! 
! 	  mode = GET_MODE (x);
! 	  if (mode == VOIDmode)
! 	    mode = DImode;
! 	  if (GET_MODE_SIZE (mode) >= 8)
! 	    sub = simplify_subreg (SImode, x, mode, 4 * LSW);
! 	  if (sub)
! 	    print_operand (stream, sub, 0);
! 	  else
! 	    output_operand_lossage ("invalid operand to %%R");
! 	}
        break;
      case 'S':
!       if (REG_P (x) || GET_CODE (x) == SUBREG)
! 	{
! 	  regno = true_regnum (x);
! 	  regno += FP_REGISTER_P (regno) ? 0 : MSW;
! 	  fputs (reg_names[regno], (stream));
! 	}
!       else if (MEM_P (x))
! 	{
! 	  x = adjust_address (x, SImode, 4 * MSW);
! 	  print_operand_address (stream, XEXP (x, 0));
! 	}
!       else
! 	{
! 	  rtx sub = NULL_RTX;
! 
! 	  mode = GET_MODE (x);
! 	  if (mode == VOIDmode)
! 	    mode = DImode;
! 	  if (GET_MODE_SIZE (mode) >= 8)
! 	    sub = simplify_subreg (SImode, x, mode, 4 * MSW);
! 	  if (sub)
! 	    print_operand (stream, sub, 0);
! 	  else
! 	    output_operand_lossage ("invalid operand to %%S");
! 	}
        break;
      case 'T':
        /* Next word of a double.  */
*** /dev/null	2004-06-24 19:04:38.000000000 +0100
--- testsuite/gcc.dg/pr21255-1.c	2005-08-31 19:05:05.000000000 +0100
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile { target "sh*-*-*" } } */
+ /* { dg-options "-O2 -fomit-frame-pointer" } */
+ /* { dg-final { scan-assembler "mov fr4,fr.; mov fr5,fr." } } */
+ double
+ f (double d)
+ {
+   double r;
+ 
+ #if defined (__SH_FPU_DOUBLE__) && !TARGET_SHMEDIA
+   asm ("mov %S1,%S0; mov %R1,%R0" : "=f" (r) : "f" (d));
+ #else
+   asm ("mov fr4,fr4; mov fr5,fr5");
+ #endif
+   return r;
+ }
*** /dev/null	2004-06-24 19:04:38.000000000 +0100
--- testsuite/gcc.dg/pr21255-2-mb.c	2005-08-31 19:20:33.000000000 +0100
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile { target "sh*-*-*" } } */
+ /* { dg-options "-mb -O2 -fomit-frame-pointer" } */
+ /* { dg-final { scan-assembler "mov @r.,r.; mov @\\(4,r.\\),r." } } */
+ double d;
+ 
+ double
+ f (void)
+ {
+   double r;
+ 
+ /* If -ml from the target options is passed after -mb from dg-options, we
+    end up with th reverse endianness.  */
+ #if TARGET_SHMEDIA || defined (__LITTLE_ENDIAN__)
+   asm ("mov @r1,r3; mov @(4,r1),r4");
+ #else
+   asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d));
+ #endif
+   return r;
+ }
*** /dev/null	2004-06-24 19:04:38.000000000 +0100
--- testsuite/gcc.dg/pr21255-2-ml.c	2005-08-31 19:19:46.000000000 +0100
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do compile { target "sh*-*-*" } } */
+ /* { dg-options "-ml -O2 -fomit-frame-pointer" } */
+ /* { dg-final { scan-assembler "mov @\\(4,r.\\),r.; mov @r.,r." } } */
+ double d;
+ 
+ double
+ f (void)
+ {
+   double r;
+ 
+ /* If -mb from the target options is passed after -ml from dg-options, we
+    end up with th reverse endianness.  */
+ #if TARGET_SHMEDIA || defined (__BIG_ENDIAN__)
+   asm ("mov @(4,r1),r4; mov @r1,r3");
+ #else
+   asm ("mov %S1,%S0; mov %R1,%R0" : "=&r" (r) : "m" (d));
+ #endif
+   return r;
+ }
*** /dev/null	2004-06-24 19:04:38.000000000 +0100
--- testsuite/gcc.dg/pr21255-3.c	2005-08-31 18:32:32.000000000 +0100
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile { target "sh*-*-*" } } */
+ /* { dg-options "-O2 -fomit-frame-pointer" } */
+ /* { dg-final { scan-assembler "mov #?0,r.*; mov #?20,r" } } */
+ /* { dg-final { scan-assembler "mov #?1077149696,r.*; mov #?0,r" } } */
+ double
+ f ()
+ {
+   double r;
+ 
+   asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (20));
+   asm ("mov %S1,%S0; mov %R1,%R0" : "+r" (r) : "i" (20.));
+   return r;
+ }
*** /dev/null	2004-06-24 19:04:38.000000000 +0100
--- testsuite/gcc.dg/pr21255-4.c	2005-08-31 19:35:50.000000000 +0100
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile { target "sh*-*-*" } } */
+ /* { dg-options "-O2 -fomit-frame-pointer" } */
+ 
+ double
+ f ()
+ {
+   double r;
+ 
+   asm ("mov %S1,%S0; mov %R1,%R0" : "=r" (r) : "i" (f));
+ /* { dg-error "invalid operand to %S" "" {target "sh*-*-*" }  9 } */
+ /* { dg-error "invalid operand to %R" "" {target "sh*-*-*" }  9 } */
+   return r;
+ }

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