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]

[csl-sol210] Patch to disable ldd and std for 32-bit SPARC


This patch, for csl-sol210-3_4-branch (which is now being used more
generally for the Solaris 10 compiler on SPARC as well as AMD64), adds
a command-line option to disable use of the SPARC ldd and std
instructions with integer operands.  This is for use with large bodies
of legacy code which has inadequately aligned 64-bit values.  As the
specification given was for such an option for 32-bit mode only, not
much consideration has been given to how it interacts with -m64; some
ldd and std uses may be disabled in 64-bit mode, but not all since
64-bit-only instruction patterns have not been touched.

Any comments on whether this would be a useful feature for mainline
(and if so what should happen with -m64)?

Bootstrapped with no regressions on sparc-sun-solaris2.10.1, and ran
the testsuite with -mno-integer-ldd-std with no regressions.  Applied
to csl-sol210-3_4-branch.

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-05-19  Joseph S. Myers  <joseph@codesourcery.com>

	* gcc/config/sparc/sparc.h (MASK_NO_INTEGER_LDD_STD,
	TARGET_INTEGER_LDD_STD): New.
	(TARGET_SWITCHES): Define -mno-integer-ldd-std option.
	* gcc/doc/invoke.texi (-mno-integer-std-ldd): Document.
	* gcc/config/sparc/sparc.c (save_regs, restore_regs,
	sparc_splitdi_legitimate, sparc_flat_save_restore): Check
	TARGET_INTEGER_LDD_STD.
	* gcc/config/sparc/sparc.md (movdi_insn_sp32_v9, movdi_insn_sp32):
	Disable unless TARGET_INTEGER_LDD_STD.
	(movdi_insn_sp32_v9_nolddstd, movdi_insn_sp32_nolddstd): New
	patterns if !TARGET_INTEGER_LDD_STD.
	(define_peephole2): Disable use of widen_memory_access unless
	TARGET_INTEGER_LDD_STD.

diff -rupN GCC.orig/gcc/config/sparc/sparc.c GCC/gcc/config/sparc/sparc.c
--- GCC.orig/gcc/config/sparc/sparc.c	2004-10-13 14:16:25.000000000 +0000
+++ GCC/gcc/config/sparc/sparc.c	2005-05-18 23:07:24.000000000 +0000
@@ -4117,7 +4117,8 @@ save_regs (FILE *file, int low, int high
 	{
 	  if (regs_ever_live[i] && ! call_used_regs[i])
 	    {
-	      if (regs_ever_live[i+1] && ! call_used_regs[i+1])
+	      if (TARGET_INTEGER_LDD_STD
+		  && regs_ever_live[i+1] && ! call_used_regs[i+1])
 		{
 		  fprintf (file, "\tstd\t%s, [%s+%d]\n",
 			   reg_names[i], base, offset + 4 * n_regs);
@@ -4180,7 +4181,8 @@ restore_regs (FILE *file, int low, int h
       for (i = low; i < high; i += 2)
 	{
 	  if (regs_ever_live[i] && ! call_used_regs[i])
-	    if (regs_ever_live[i+1] && ! call_used_regs[i+1])
+	    if (TARGET_INTEGER_LDD_STD
+		&& regs_ever_live[i+1] && ! call_used_regs[i+1])
 	      fprintf (file, "\tldd\t[%s+%d], %s\n",
 		       base, offset + 4 * n_regs, reg_names[i]),
 	      n_regs += 2;
@@ -6742,7 +6744,8 @@ sparc_splitdi_legitimate (rtx reg, rtx m
 
   /* If we have legitimate args for ldd/std, we do not want
      the split to happen.  */
-  if ((REGNO (reg) % 2) == 0
+  if (TARGET_INTEGER_LDD_STD
+      && (REGNO (reg) % 2) == 0
       && mem_min_alignment (mem, 8))
     return 0;
 
@@ -7740,7 +7743,8 @@ sparc_flat_save_restore (FILE *file, con
 	{
 	  if ((gmask & (1L << regno)) != 0)
 	    {
-	      if ((regno & 0x1) == 0 && ((gmask & (1L << (regno+1))) != 0))
+	      if (TARGET_INTEGER_LDD_STD
+		  && (regno & 0x1) == 0 && ((gmask & (1L << (regno+1))) != 0))
 		{
 		  /* We can save two registers in a row.  If we're not at a
 		     double word boundary, move to one.
diff -rupN GCC.orig/gcc/config/sparc/sparc.h GCC/gcc/config/sparc/sparc.h
--- GCC.orig/gcc/config/sparc/sparc.h	2004-05-31 21:40:19.000000000 +0000
+++ GCC/gcc/config/sparc/sparc.h	2005-05-18 23:06:59.000000000 +0000
@@ -517,6 +517,10 @@ extern int target_flags;
 #define MASK_LONG_DOUBLE_128 0x8000000
 #define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
 
+/* Do not use integer ldd and std.  */
+#define MASK_NO_INTEGER_LDD_STD 0x10000000
+#define TARGET_INTEGER_LDD_STD (!(target_flags & MASK_NO_INTEGER_LDD_STD))
+
 /* TARGET_HARD_MUL: Use hardware multiply instructions but not %y.
    TARGET_HARD_MUL32: Use hardware multiply instructions with rd %y
    to get high 32 bits.  False in V8+ or V9 because multiply stores
@@ -577,7 +581,11 @@ extern int target_flags;
      N_("Utilize Visual Instruction Set") }, 				\
     {"no-vis", -MASK_VIS,						\
      N_("Do not utilize Visual Instruction Set") }, 			\
-    /* ??? These are deprecated, coerced to -mcpu=.  Delete in 2.9.  */ \
+    {"integer-ldd-std", -MASK_NO_INTEGER_LDD_STD,			\
+     N_("Utilize integer ldd and std") },				\
+    {"no-integer-ldd-std", MASK_NO_INTEGER_LDD_STD,			\
+     N_("Do not utilize integer ldd and std") },			\
+    /* ??? These are deprecated, coerced to -mcpu=.  Delete in 2.9.  */	\
     {"cypress", 0,							\
      N_("Optimize for Cypress processors") }, 				\
     {"sparclite", 0,							\
diff -rupN GCC.orig/gcc/config/sparc/sparc.md GCC/gcc/config/sparc/sparc.md
--- GCC.orig/gcc/config/sparc/sparc.md	2004-10-13 14:16:26.000000000 +0000
+++ GCC/gcc/config/sparc/sparc.md	2005-05-18 23:11:16.000000000 +0000
@@ -2104,7 +2104,7 @@
 					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
         (match_operand:DI 1 "input_operand"
 					" J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
-  "! TARGET_ARCH64 && TARGET_V9
+  "! TARGET_ARCH64 && TARGET_V9 && TARGET_INTEGER_LDD_STD
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
    stx\t%%g0, %0
@@ -2126,12 +2126,39 @@
    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
 
+(define_insn "*movdi_insn_sp32_v9_nolddstd"
+  [(set (match_operand:DI 0 "nonimmediate_operand"
+					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
+        (match_operand:DI 1 "input_operand"
+					" J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
+  "! TARGET_ARCH64 && TARGET_V9 && ! TARGET_INTEGER_LDD_STD
+   && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+  "@
+   stx\t%%g0, %0
+   #
+   #
+   #
+   #
+   #
+   #
+   #
+   std\t%1, %0
+   ldd\t%1, %0
+   #
+   #
+   fmovd\\t%1, %0
+   ldd\\t%1, %0
+   std\\t%1, %0"
+  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
+   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
+   (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
+
 (define_insn "*movdi_insn_sp32"
   [(set (match_operand:DI 0 "nonimmediate_operand"
 				"=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
         (match_operand:DI 1 "input_operand"
 				" J,U,T,r,o,i,r, f, T, o, f, f"))]
-  "! TARGET_ARCH64
+  "! TARGET_ARCH64 && TARGET_INTEGER_LDD_STD
    && (register_operand (operands[0], DImode)
        || register_operand (operands[1], DImode))"
   "@
@@ -2150,6 +2177,30 @@
   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
 
+(define_insn "*movdi_insn_sp32_nolddstd"
+  [(set (match_operand:DI 0 "nonimmediate_operand"
+				"=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
+        (match_operand:DI 1 "input_operand"
+				" J,U,T,r,o,i,r, f, T, o, f, f"))]
+  "! TARGET_ARCH64 && ! TARGET_INTEGER_LDD_STD
+   && (register_operand (operands[0], DImode)
+       || register_operand (operands[1], DImode))"
+  "@
+   #
+   #
+   #
+   #
+   #
+   #
+   #
+   std\t%1, %0
+   ldd\t%1, %0
+   #
+   #
+   #"
+  [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
+   (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
+
 ;; The following are generated by sparc_emit_set_const64
 (define_insn "*movdi_sp64_dbl"
   [(set (match_operand:DI 0 "register_operand" "=r")
@@ -7948,7 +7999,7 @@
       (const_int 0))
    (set (match_operand:SI 1 "memory_operand" "")
       (const_int 0))]
-  "TARGET_V9
+  "TARGET_V9 && TARGET_INTEGER_LDD_STD
    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
   [(set (match_dup 0)
        (const_int 0))]
@@ -7959,7 +8010,7 @@
       (const_int 0))
    (set (match_operand:SI 1 "memory_operand" "")
       (const_int 0))]
-  "TARGET_V9
+  "TARGET_V9 && TARGET_INTEGER_LDD_STD
    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
   [(set (match_dup 1)
        (const_int 0))]
@@ -7970,7 +8021,8 @@
         (match_operand:SI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "")
         (match_operand:SI 3 "memory_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[0], operands[2]) 
+  "TARGET_INTEGER_LDD_STD
+   && registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
   [(set (match_dup 0)
 	(match_dup 1))]
@@ -7982,7 +8034,8 @@
         (match_operand:SI 1 "register_operand" ""))
    (set (match_operand:SI 2 "memory_operand" "")
         (match_operand:SI 3 "register_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[1], operands[3]) 
+  "TARGET_INTEGER_LDD_STD
+   && registers_ok_for_ldd_peep (operands[1], operands[3]) 
    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
   [(set (match_dup 0)
 	(match_dup 1))]
@@ -7994,7 +8047,8 @@
         (match_operand:SF 1 "memory_operand" ""))
    (set (match_operand:SF 2 "register_operand" "")
         (match_operand:SF 3 "memory_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[0], operands[2]) 
+  "TARGET_INTEGER_LDD_STD
+   && registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
   [(set (match_dup 0)
 	(match_dup 1))]
@@ -8006,7 +8060,8 @@
         (match_operand:SF 1 "register_operand" ""))
    (set (match_operand:SF 2 "memory_operand" "")
         (match_operand:SF 3 "register_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[1], operands[3]) 
+  "TARGET_INTEGER_LDD_STD
+  && registers_ok_for_ldd_peep (operands[1], operands[3]) 
   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
   [(set (match_dup 0)
 	(match_dup 1))]
@@ -8018,7 +8073,8 @@
         (match_operand:SI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "")
         (match_operand:SI 3 "memory_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[2], operands[0]) 
+  "TARGET_INTEGER_LDD_STD
+  && registers_ok_for_ldd_peep (operands[2], operands[0]) 
   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
   [(set (match_dup 2)
 	(match_dup 3))]
@@ -8030,7 +8086,8 @@
         (match_operand:SI 1 "register_operand" ""))
    (set (match_operand:SI 2 "memory_operand" "")
         (match_operand:SI 3 "register_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[3], operands[1]) 
+  "TARGET_INTEGER_LDD_STD
+  && registers_ok_for_ldd_peep (operands[3], operands[1]) 
   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
   [(set (match_dup 2)
 	(match_dup 3))]
@@ -8043,7 +8100,8 @@
         (match_operand:SF 1 "memory_operand" ""))
    (set (match_operand:SF 2 "register_operand" "")
         (match_operand:SF 3 "memory_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[2], operands[0]) 
+  "TARGET_INTEGER_LDD_STD
+  && registers_ok_for_ldd_peep (operands[2], operands[0]) 
   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
   [(set (match_dup 2)
 	(match_dup 3))]
@@ -8055,7 +8113,8 @@
         (match_operand:SF 1 "register_operand" ""))
    (set (match_operand:SF 2 "memory_operand" "")
         (match_operand:SF 3 "register_operand" ""))]
-  "registers_ok_for_ldd_peep (operands[3], operands[1]) 
+  "TARGET_INTEGER_LDD_STD
+  && registers_ok_for_ldd_peep (operands[3], operands[1]) 
   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
   [(set (match_dup 2)
 	(match_dup 3))]
diff -rupN GCC.orig/gcc/doc/invoke.texi GCC/gcc/doc/invoke.texi
--- GCC.orig/gcc/doc/invoke.texi	2004-10-06 20:15:08.000000000 +0000
+++ GCC/gcc/doc/invoke.texi	2005-05-18 22:36:20.000000000 +0000
@@ -365,6 +365,7 @@ in the following sections.
 -mstack-bias  -mno-stack-bias @gol
 -munaligned-doubles  -mno-unaligned-doubles @gol
 -mv8plus  -mno-v8plus  -mvis  -mno-vis @gol
+-minteger-std-ldd  -mno-integer-std-ldd @gol
 -mcypress  -mf930  -mf934 @gol
 -msparclite  -msupersparc  -mv8
 -threads -pthreads}
@@ -6375,6 +6376,15 @@ mode for all SPARC-V9 processors.
 @opindex mno-vis
 With @option{-mvis}, GCC generates code that takes advantage of the UltraSPARC
 Visual Instruction Set extensions.  The default is @option{-mno-vis}.
+
+@item -minteger-std-ldd
+@itemx -mno-integer-std-ldd
+@opindex minteger-std-ldd
+@opindex mno-integer-std-ldd
+With @option{-mno-integer-std-ldd}, GCC does not use the @code{ldd}
+and @code{std} instructions for integer operands in 32-bit mode.  This
+is for use with legacy code using 64-bit quantities which are not
+64-bit aligned.  The default is @option{-minteger-std-ldd}.
 @end table
 
 These @samp{-m} options are supported in addition to the above


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