On 09/21/2017 11:14 AM, Rainer Orth wrote:
> Hi Daniel,
>
>> On 09/19/2017 01:58 AM, Jakub Jelinek wrote:
>>> What can be done in libgcc is detect in configure whether the assembler
>>> supports AVX, and if not, provide some alternative (e.g. because the insns
>>> are always the same, you could just code them as .byte or something 
>>> similar).
>>>
>>> Say like:
>>> --- i386-asm.h      2017-09-18 18:34:30.917126996 +0200
>>> +++ i386-asm.h      2017-09-19 08:56:58.829559038 +0200
>>> @@ -70,6 +70,7 @@ ASMNAME(fn):
>>>  #ifdef MS2SYSV_STUB_AVX
>>>  # define MS2SYSV_STUB_PREFIX __avx_
>>>  # define MOVAPS vmovaps
>>> +# define BYTE .byte
>>>  #elif defined(MS2SYSV_STUB_SSE)
>>>  # define MS2SYSV_STUB_PREFIX __sse_
>>>  # define MOVAPS movaps
>>> @@ -84,7 +85,8 @@ ASMNAME(fn):
>>>     FUNC_END(PASTE2(MS2SYSV_STUB_PREFIX, base_name))
>>>  
>>>  /* Save SSE registers 6-15. off is the offset of rax to get to xmm6.  */
>>> -# define SSE_SAVE             \
>>> +# ifdef HAVE_AS_AVX
>> I'm not exactly an autotools expert, but libtim defines HAVE_AS_AVX from
>> libitm/acinclude.m4 -- of course I need it in libgcc.  Similarly, gcc
>> has a nice generic gcc_GAS_CHECK_FEATURE macro in gcc/acinclude.m4 which
>> it uses for all of its HAVE_AS_* macro tests defined in
>> gcc/configure.ac.  I can just copy, paste and edit what's in libitm, but
>> I find that rather distasteful.  Is there a cleaner way to do this?  Can
>> I suck gcc_GAS_CHECK_FEATURE and it's deps out of gcc/acinclude.m4 and
>> put it somewhere central, like config/as.m4?  The upside would be the
>> ability to make HAVE_AS_* macros in other sub-projects more uniform.
> This might be an option as a followup: less code duplication is
> certainly a good thing ;-)
>
>> Alternatively, I can just do the copy and paste and deal with it -- it's
>> not that much code. :)
> However, given that the above will take some time and testing and your
> patch has broken macOS bootstrap, I'd go this route now to unbreak the
> tree ASAP.
>
>       Rainer

A very good point!  So libgcc doesn't use a config.in. :(  So what about
committing my patch as is with HAVE_AS_AVX never defined and the avx
version of the stubs always being built via the .byte directives so that
the build is un-broken, and then figure out how (and where) to add
HAVE_AS_AVX afterwards?  I would still prefer to run a full bootstrap,
but updating an already build bootstrap is good and the tests should
hopefully be fixed on Solaris as well.

Thanks,
Daniel


diff --git a/gcc/testsuite/gcc.target/i386/pr82196-1.c b/gcc/testsuite/gcc.target/i386/pr82196-1.c
index ef858328f00..541d975480d 100644
--- a/gcc/testsuite/gcc.target/i386/pr82196-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr82196-1.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target lp64 } } */
 /* { dg-options "-msse -mcall-ms2sysv-xlogues -O2" } */
-/* { dg-final { scan-assembler "call.*__sse_savms64_18" } } */
-/* { dg-final { scan-assembler "jmp.*__sse_resms64x_18" } } */
+/* { dg-final { scan-assembler "call.*__sse_savms64f?_12" } } */
+/* { dg-final { scan-assembler "jmp.*__sse_resms64f?x_12" } } */
 
 void __attribute__((sysv_abi)) a() {
 }
@@ -9,6 +9,5 @@ void __attribute__((sysv_abi)) a() {
 static void __attribute__((sysv_abi)) (*volatile a_noinfo)() = a;
 
 void __attribute__((ms_abi)) b() {
-  __asm__ __volatile__ ("" :::"rbx", "rbp", "r12", "r13", "r14", "r15");
   a_noinfo ();
 }
diff --git a/gcc/testsuite/gcc.target/i386/pr82196-2.c b/gcc/testsuite/gcc.target/i386/pr82196-2.c
index 8fe58411d5e..7166d068bc1 100644
--- a/gcc/testsuite/gcc.target/i386/pr82196-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr82196-2.c
@@ -1,7 +1,7 @@
 /* { dg-do compile { target lp64 } } */
 /* { dg-options "-mavx -mcall-ms2sysv-xlogues -O2" } */
-/* { dg-final { scan-assembler "call.*__avx_savms64_18" } } */
-/* { dg-final { scan-assembler "jmp.*__avx_resms64x_18" } } */
+/* { dg-final { scan-assembler "call.*__avx_savms64f?_12" } } */
+/* { dg-final { scan-assembler "jmp.*__avx_resms64f?x_12" } } */
 
 void __attribute__((sysv_abi)) a() {
 }
@@ -9,6 +9,5 @@ void __attribute__((sysv_abi)) a() {
 static void __attribute__((sysv_abi)) (*volatile a_noinfo)() = a;
 
 void __attribute__((ms_abi)) b() {
-  __asm__ __volatile__ ("" :::"rbx", "rbp", "r12", "r13", "r14", "r15");
   a_noinfo ();
 }
diff --git a/libgcc/config/i386/i386-asm.h b/libgcc/config/i386/i386-asm.h
index 424e0f72aac..91e1c0123ff 100644
--- a/libgcc/config/i386/i386-asm.h
+++ b/libgcc/config/i386/i386-asm.h
@@ -69,13 +69,15 @@ ASMNAME(fn):
 
 #ifdef MS2SYSV_STUB_AVX
 # define MS2SYSV_STUB_PREFIX __avx_
-# define MOVAPS vmovaps
+# ifdef HAVE_AS_AVX
+#  define MOVAPS vmovaps
+# endif
 #elif defined(MS2SYSV_STUB_SSE)
 # define MS2SYSV_STUB_PREFIX __sse_
 # define MOVAPS movaps
 #endif
 
-#if defined (MS2SYSV_STUB_PREFIX) && defined (MOVAPS)
+#if defined (MS2SYSV_STUB_PREFIX)
 
 # define MS2SYSV_STUB_BEGIN(base_name) \
 	HIDDEN_FUNC(PASTE2(MS2SYSV_STUB_PREFIX, base_name))
@@ -83,8 +85,10 @@ ASMNAME(fn):
 # define MS2SYSV_STUB_END(base_name) \
 	FUNC_END(PASTE2(MS2SYSV_STUB_PREFIX, base_name))
 
-/* Save SSE registers 6-15. off is the offset of rax to get to xmm6.  */
-# define SSE_SAVE		   \
+/* If expanding for sse or avx and we have assembler support.  */
+# ifdef MOVAPS
+/* Save SSE registers 6-15 using rax as the base address.  */
+#  define SSE_SAVE		   \
 	MOVAPS %xmm15,-0x30(%rax); \
 	MOVAPS %xmm14,-0x20(%rax); \
 	MOVAPS %xmm13,-0x10(%rax); \
@@ -96,8 +100,8 @@ ASMNAME(fn):
 	MOVAPS %xmm7,  0x50(%rax); \
 	MOVAPS %xmm6,  0x60(%rax)
 
-/* Restore SSE registers 6-15. off is the offset of rsi to get to xmm6.  */
-# define SSE_RESTORE		    \
+/* Restore SSE registers 6-15 using rsi as the base address.  */
+#  define SSE_RESTORE		    \
 	MOVAPS -0x30(%rsi), %xmm15; \
 	MOVAPS -0x20(%rsi), %xmm14; \
 	MOVAPS -0x10(%rsi), %xmm13; \
@@ -108,6 +112,32 @@ ASMNAME(fn):
 	MOVAPS  0x40(%rsi), %xmm8 ; \
 	MOVAPS  0x50(%rsi), %xmm7 ; \
 	MOVAPS  0x60(%rsi), %xmm6
-
+# else /* MOVAPS */
+/* If the assembler doesn't support AVX then directly emit machine code
+   for the instructions above directly.  */
+#  define BYTE .byte
+#  define SSE_SAVE							    \
+	BYTE 0xc5, 0x78, 0x29, 0x78, 0xd0; /* vmovaps %xmm15,-0x30(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x70, 0xe0; /* vmovaps %xmm14,-0x20(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x68, 0xf0; /* vmovaps %xmm13,-0x10(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x20;       /* vmovaps %xmm12,     (%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x58, 0x10; /* vmovaps %xmm11, 0x10(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x50, 0x20; /* vmovaps %xmm10, 0x20(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x48, 0x30; /* vmovaps %xmm9,  0x30(%rax) */ \
+	BYTE 0xc5, 0x78, 0x29, 0x40, 0x40; /* vmovaps %xmm8,  0x40(%rax) */ \
+	BYTE 0xc5, 0xf8, 0x29, 0x78, 0x50; /* vmovaps %xmm7,  0x50(%rax) */ \
+	BYTE 0xc5, 0xf8, 0x29, 0x70, 0x60; /* vmovaps %xmm6,  0x60(%rax) */
+#  define SSE_RESTORE							    \
+	BYTE 0xc5, 0x78, 0x28, 0x7e, 0xd0; /* vmovaps -0x30(%rsi),%xmm15 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x76, 0xe0; /* vmovaps -0x20(%rsi),%xmm14 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x6e, 0xf0; /* vmovaps -0x10(%rsi),%xmm13 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x26;       /* vmovaps      (%rsi),%xmm12 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x5e, 0x10; /* vmovaps  0x10(%rsi),%xmm11 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x56, 0x20; /* vmovaps  0x20(%rsi),%xmm10 */ \
+	BYTE 0xc5, 0x78, 0x28, 0x4e, 0x30; /* vmovaps  0x30(%rsi),%xmm9  */ \
+	BYTE 0xc5, 0x78, 0x28, 0x46, 0x40; /* vmovaps  0x40(%rsi),%xmm8  */ \
+	BYTE 0xc5, 0xf8, 0x28, 0x7e, 0x50; /* vmovaps  0x50(%rsi),%xmm7  */ \
+	BYTE 0xc5, 0xf8, 0x28, 0x76, 0x60; /* vmovaps  0x60(%rsi),%xmm6  */
+# endif /* MOVAPS */
 #endif /* defined (MS2SYSV_STUB_ISA) && defined (MOVAPS) */
 #endif /* I386_ASM_H */

Reply via email to