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]

Re: [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.

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


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