[csl-sol210] Patch to disable ldd and std for 32-bit SPARC
Eric Botcazou
ebotcazou@libertysurf.fr
Thu May 19 23:54:00 GMT 2005
> 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.
GCC doesn't emit ldd/std for integer registers in 64-bit mode (their semantics
would be that of unpack/pack insns). Both insns are deprecated in V9.
> Any comments on whether this would be a useful feature for mainline
> (and if so what should happen with -m64)?
Yes, I suppose this would be useful on mainline too.
> 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.
Some comments:
* 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.
std/ldd are swapped.
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;
Theoretically that's not quite correct, as registers that need to be saved
have to be saved. You should split every insn into 2 insns. Moreover
save_regs/restore_regs are only used in prologue/epilogue code and everything
is 64-bit aligned there, so that's unnecessary.
In practice save_regs/restore_regs are never used on Solaris so that doesn't
really matter.
@@ -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.
Same problem as with save_regs/restore_regs, unnecessary too and in practice
dead too (unless you compile with -mflat, but do not do that :-).
@@ -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,*,*,*")
Every # alternative should have length 2.
@@ -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")])
Likewise.
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
ldd/std are swapped.
@@ -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
Likewise.
--
Eric Botcazou
More information about the Gcc-patches
mailing list