Bug 43350 - sparcv9 mode does not seem to produce LDX/STX insns
Summary: sparcv9 mode does not seem to produce LDX/STX insns
Status: SUSPENDED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: davem
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-12 20:23 UTC by Jan Engelhardt
Modified: 2012-11-07 05:44 UTC (History)
3 users (show)

See Also:
Host: sparc64-suse-linux-gnu
Target: sparc64-suse-linux-gnu
Build: sparc64-suse-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2012-11-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Engelhardt 2010-03-12 20:23:21 UTC
Glibc is perhaps the only file on a typical Linux sparcv9 system (read: ELF32) that makes use of 64-bit instructions like LDX/STX, and probably does so by using assembler.

How come gcc is not emitting the *X family of instructions when dealing with, for example, operating on uint64_t? The appended piece of sample code will make use of LDX, but only when compiled in ELF64 mode (-m64). With -m32 -mcpu=v9, it still uses the V8 doubleword mechanism and the LDD instruction. The SPARCV9 manual reads:

"LDD is provided for compatibility with SPARC-V8. It may execute slowly on SPARC-V9 machines because of data path and register-access difficulties. In some systems it may trap to emulation code. It is suggested that programmers and compilers avoid using these instructions."

$ gcc -v
Using built-in specs.
Target: sparc64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.4 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.4 --enable-linux-futex --without-system-libunwind --with-cpu=v8 --with-long-double-128 --build=sparc64-suse-linux
Thread model: posix
gcc version 4.4.1 [gcc-4_4-branch revision 150839] (SUSE Linux) 

$ gcc-4.5 -v
Using built-in specs.
COLLECT_GCC=gcc-4.5
COLLECT_LTO_WRAPPER=/usr/lib/gcc/sparc64-suse-linux/4.5/lto-wrapper
Target: sparc64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.5 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.5 --enable-linux-futex --without-system-libunwind --enable-gold --with-plugin-ld=/usr/bin/gold --with-cpu=v8 --with-long-double-128 --build=sparc64-suse-linux
Thread model: posix
gcc version 4.5.0 20100209 (experimental) [trunk revision 156621] (SUSE Linux)

#include <stdlib.h>
#include <stdint.h>

extern long long y;
long long y = 0x123;

uint32_t foo(long long i)
{
        long long x = y+i;
        return x<<2;
}
Comment 1 davem 2012-11-06 04:23:51 UTC
The problem is that the compiler is very constrained about how it
can or cannot use 64-bit operations in 32-bit v9 mode.

When we do use 64-bit instructions, we do so in a very hackish
way in 32-bit mode.  We first allocate a "safe" 64-bit register
(the OS only guarentees that %o0-%o7 and %g1-%g7 integer
registers will have their full 64-bits saved if a trap or
context switch occurs) and then we construct the 64-bit value
from the 2 32-bit source operand pieces of each 64-bit input.

Then we decompose the 64-bit "safe" register back into the
32-bit components of the output.

We have some tricks and a very simplistic data flow analyzer
that allows avoiding some aspects of the above work.

This is suboptimal, but what it means is that by the time we do
moves, we have the 64-bit values in 32-bit component registers,
so stx/ldx isn't really an option.

The basic issue is that it's an enormous task exposing to the
compiler that we really can do full 64-bit operations in these
registers.  That is a huge amount of delicate work, and therefore
this is really a feature request rather than a bug report, so I'm
closing this.
Comment 2 Jan Engelhardt 2012-11-06 16:19:09 UTC
Thanks for the description. It seems that what you say also affects the x32 mode (-mx32) for x86_64, am I correct in that observation?
Comment 3 davem 2012-11-06 18:00:30 UTC
Unfortunately I'm not familiar enough with the i386 backend to say whether the situation is identical there for x32 code generation.  But if it were the case, it would not surprise me.
Comment 4 H.J. Lu 2012-11-06 22:15:02 UTC
There is no x32 mode in hardware.  Since x32 runs in 64-bit mode
and only OS limits x32 address space to 32-bit, x32 process has
full access to 64-bit insns, just like 64-bit process.
Comment 5 Jan Engelhardt 2012-11-07 00:00:01 UTC
Dave, what do you think about a new mode for SPARC similar to -mx32, in other words, "-m64+ILP32"?
Comment 6 davem 2012-11-07 05:44:52 UTC
That's basically what -m32 -mcpu=v9 is Jan.

The compiler just isn't taking advantage of it as well as it can due to how the sparc backend is designed.

We have access to 16 64-bit registers at all times.

Please, drop this discussion, when I get a large block of time I'll work on improving the sparc backend in this area.  This discussion is just consuming my time and making it take longer for me to get to that task.

Thanks.