This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[csl-sol210] Patch to disable ldd and std for 32-bit SPARC
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 19 May 2005 22:09:24 +0000 (UTC)
- Subject: [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