[PATCH 2/6] tests/basic: clutter YMM and ZMM registers on i386 and AMD64

Jussi Kivilinna jussi.kivilinna at iki.fi
Tue Sep 8 13:46:38 CEST 2026


* tests/basic.c (CLUTTER_VECTOR_REGISTER_COUNT)
[CLUTTER_VECTOR_REGISTER_AMD64]: Increase to 32.
(clutter_vector_registers): Make clutter data static and prepare it only
once.
[CLUTTER_VECTOR_REGISTER_AMD64, CLUTTER_VECTOR_REGISTER_I386]: Detect AVX
and AVX512 from hwflist; add YMM and ZMM register cluttering.
--

Cluttering only XMM registers left upper halfs of YMM and ZMM registers
untouched, so bugs in AVX and AVX512 implementations could pass unnoticed.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 tests/basic.c | 209 ++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 167 insertions(+), 42 deletions(-)

diff --git a/tests/basic.c b/tests/basic.c
index 9ec1b596..00d6586d 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -246,7 +246,7 @@ progress_handler (void *cb_data, const char *what, int printchar,
      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
     defined(__SSE2__)
 # define CLUTTER_VECTOR_REGISTER_AMD64 1
-# define CLUTTER_VECTOR_REGISTER_COUNT 16
+# define CLUTTER_VECTOR_REGISTER_COUNT 32
 #elif defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4 && \
       defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(__SSE2__)
 # define CLUTTER_VECTOR_REGISTER_I386 1
@@ -295,7 +295,8 @@ static inline ALWAYS_INLINE void
 clutter_vector_registers(void)
 {
 #ifdef CLUTTER_VECTOR_REGISTER_COUNT
-  unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16];
+  static unsigned char data[CLUTTER_VECTOR_REGISTER_COUNT][16];
+  static int data_init;
 #if defined(CLUTTER_VECTOR_REGISTER_AARCH64) || \
     defined(CLUTTER_VECTOR_REGISTER_NEON)
   static int init;
@@ -316,9 +317,12 @@ clutter_vector_registers(void)
 
   if (!have_neon)
     return;
-#elif defined(CLUTTER_VECTOR_REGISTER_I386)
+#elif defined(CLUTTER_VECTOR_REGISTER_AMD64) || \
+      defined(CLUTTER_VECTOR_REGISTER_I386)
   static int init;
-  static int have_ssse3;
+  static int have_sse2;
+  static int have_avx;
+  static int have_avx512;
 
   if (!init)
     {
@@ -327,55 +331,176 @@ clutter_vector_registers(void)
       string = gcry_get_config (0, "hwflist");
       if (string)
 	{
-	  have_ssse3 = (strstr(string, "intel-ssse3:") != NULL);
+	  int have_ssse3 = (strstr(string, "intel-ssse3:") != NULL);
+	  have_sse2 = have_ssse3; /* XMM registers supported */
+	  have_avx = (strstr(string, "intel-avx:") != NULL); /* YMM */
+	  have_avx512 = (strstr(string, "intel-avx512:") != NULL); /* ZMM */
 	  xfree(string);
 	}
+
+#ifdef CLUTTER_VECTOR_REGISTER_AMD64
+      have_sse2 = 1;
+#endif
+
       init = 1;
     }
 
-  if (!have_ssse3)
+  if (!have_sse2)
     return;
 #endif
 
-  prepare_vector_data(data);
+  if (!data_init)
+    {
+      prepare_vector_data(data);
+      data_init = 1;
+    }
 
 #if defined(CLUTTER_VECTOR_REGISTER_AMD64)
-  asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n"
-	       "movdqu (1 * 16)(%[data]), %%xmm1\n"
-	       "movdqu (2 * 16)(%[data]), %%xmm2\n"
-	       "movdqu (3 * 16)(%[data]), %%xmm3\n"
-	       "movdqu (4 * 16)(%[data]), %%xmm4\n"
-	       "movdqu (5 * 16)(%[data]), %%xmm5\n"
-	       "movdqu (6 * 16)(%[data]), %%xmm6\n"
-	       "movdqu (7 * 16)(%[data]), %%xmm7\n"
-	       "movdqu (8 * 16)(%[data]), %%xmm8\n"
-	       "movdqu (9 * 16)(%[data]), %%xmm9\n"
-	       "movdqu (10 * 16)(%[data]), %%xmm10\n"
-	       "movdqu (11 * 16)(%[data]), %%xmm11\n"
-	       "movdqu (12 * 16)(%[data]), %%xmm12\n"
-	       "movdqu (13 * 16)(%[data]), %%xmm13\n"
-	       "movdqu (14 * 16)(%[data]), %%xmm14\n"
-	       "movdqu (15 * 16)(%[data]), %%xmm15\n"
-	      :
-	      : [data] "r" (&data[0])
-	      : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
-	        "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
-	        "xmm13", "xmm14", "xmm15"
-	      );
+  if (0)
+    { }
+# ifdef HAVE_GCC_INLINE_ASM_AVX512
+  else if (have_avx512)
+    asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n"
+		 "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n"
+		 "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n"
+		 "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n"
+		 "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n"
+		 "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n"
+		 "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n"
+		 "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n"
+		 "vbroadcasti32x4 (8 * 16)(%[data]), %%zmm8\n"
+		 "vbroadcasti32x4 (9 * 16)(%[data]), %%zmm9\n"
+		 "vbroadcasti32x4 (10 * 16)(%[data]), %%zmm10\n"
+		 "vbroadcasti32x4 (11 * 16)(%[data]), %%zmm11\n"
+		 "vbroadcasti32x4 (12 * 16)(%[data]), %%zmm12\n"
+		 "vbroadcasti32x4 (13 * 16)(%[data]), %%zmm13\n"
+		 "vbroadcasti32x4 (14 * 16)(%[data]), %%zmm14\n"
+		 "vbroadcasti32x4 (15 * 16)(%[data]), %%zmm15\n"
+		 "vbroadcasti32x4 (16 * 16)(%[data]), %%zmm16\n"
+		 "vbroadcasti32x4 (17 * 16)(%[data]), %%zmm17\n"
+		 "vbroadcasti32x4 (18 * 16)(%[data]), %%zmm18\n"
+		 "vbroadcasti32x4 (19 * 16)(%[data]), %%zmm19\n"
+		 "vbroadcasti32x4 (20 * 16)(%[data]), %%zmm20\n"
+		 "vbroadcasti32x4 (21 * 16)(%[data]), %%zmm21\n"
+		 "vbroadcasti32x4 (22 * 16)(%[data]), %%zmm22\n"
+		 "vbroadcasti32x4 (23 * 16)(%[data]), %%zmm23\n"
+		 "vbroadcasti32x4 (24 * 16)(%[data]), %%zmm24\n"
+		 "vbroadcasti32x4 (25 * 16)(%[data]), %%zmm25\n"
+		 "vbroadcasti32x4 (26 * 16)(%[data]), %%zmm26\n"
+		 "vbroadcasti32x4 (27 * 16)(%[data]), %%zmm27\n"
+		 "vbroadcasti32x4 (28 * 16)(%[data]), %%zmm28\n"
+		 "vbroadcasti32x4 (29 * 16)(%[data]), %%zmm29\n"
+		 "vbroadcasti32x4 (30 * 16)(%[data]), %%zmm30\n"
+		 "vbroadcasti32x4 (31 * 16)(%[data]), %%zmm31\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
+		   "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
+		   "xmm13", "xmm14", "xmm15"
+#  ifdef __AVX512F__
+		   , "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21",
+		   "xmm22", "xmm23", "xmm24", "xmm25", "xmm26", "xmm27",
+		   "xmm28", "xmm29", "xmm30", "xmm31"
+#  endif
+		 );
+# endif
+# ifdef HAVE_GCC_INLINE_ASM_AVX
+  else if (have_avx)
+    asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n"
+		 "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n"
+		 "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n"
+		 "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n"
+		 "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n"
+		 "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n"
+		 "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n"
+		 "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n"
+		 "vbroadcastf128 (8 * 16)(%[data]), %%ymm8\n"
+		 "vbroadcastf128 (9 * 16)(%[data]), %%ymm9\n"
+		 "vbroadcastf128 (10 * 16)(%[data]), %%ymm10\n"
+		 "vbroadcastf128 (11 * 16)(%[data]), %%ymm11\n"
+		 "vbroadcastf128 (12 * 16)(%[data]), %%ymm12\n"
+		 "vbroadcastf128 (13 * 16)(%[data]), %%ymm13\n"
+		 "vbroadcastf128 (14 * 16)(%[data]), %%ymm14\n"
+		 "vbroadcastf128 (15 * 16)(%[data]), %%ymm15\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
+		   "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
+		   "xmm13", "xmm14", "xmm15"
+		 );
+# endif
+  else
+    asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n"
+		 "movdqu (1 * 16)(%[data]), %%xmm1\n"
+		 "movdqu (2 * 16)(%[data]), %%xmm2\n"
+		 "movdqu (3 * 16)(%[data]), %%xmm3\n"
+		 "movdqu (4 * 16)(%[data]), %%xmm4\n"
+		 "movdqu (5 * 16)(%[data]), %%xmm5\n"
+		 "movdqu (6 * 16)(%[data]), %%xmm6\n"
+		 "movdqu (7 * 16)(%[data]), %%xmm7\n"
+		 "movdqu (8 * 16)(%[data]), %%xmm8\n"
+		 "movdqu (9 * 16)(%[data]), %%xmm9\n"
+		 "movdqu (10 * 16)(%[data]), %%xmm10\n"
+		 "movdqu (11 * 16)(%[data]), %%xmm11\n"
+		 "movdqu (12 * 16)(%[data]), %%xmm12\n"
+		 "movdqu (13 * 16)(%[data]), %%xmm13\n"
+		 "movdqu (14 * 16)(%[data]), %%xmm14\n"
+		 "movdqu (15 * 16)(%[data]), %%xmm15\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
+		   "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12",
+		   "xmm13", "xmm14", "xmm15"
+		 );
 #elif defined(CLUTTER_VECTOR_REGISTER_I386)
-  asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n"
-	       "movdqu (1 * 16)(%[data]), %%xmm1\n"
-	       "movdqu (2 * 16)(%[data]), %%xmm2\n"
-	       "movdqu (3 * 16)(%[data]), %%xmm3\n"
-	       "movdqu (4 * 16)(%[data]), %%xmm4\n"
-	       "movdqu (5 * 16)(%[data]), %%xmm5\n"
-	       "movdqu (6 * 16)(%[data]), %%xmm6\n"
-	       "movdqu (7 * 16)(%[data]), %%xmm7\n"
-	      :
-	      : [data] "r" (&data[0])
-	      : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
-	        "xmm6", "xmm7"
-	      );
+  if (0)
+    { }
+# ifdef HAVE_GCC_INLINE_ASM_AVX512
+  else if (have_avx512)
+    asm volatile("vbroadcasti32x4 (0 * 16)(%[data]), %%zmm0\n"
+		 "vbroadcasti32x4 (1 * 16)(%[data]), %%zmm1\n"
+		 "vbroadcasti32x4 (2 * 16)(%[data]), %%zmm2\n"
+		 "vbroadcasti32x4 (3 * 16)(%[data]), %%zmm3\n"
+		 "vbroadcasti32x4 (4 * 16)(%[data]), %%zmm4\n"
+		 "vbroadcasti32x4 (5 * 16)(%[data]), %%zmm5\n"
+		 "vbroadcasti32x4 (6 * 16)(%[data]), %%zmm6\n"
+		 "vbroadcasti32x4 (7 * 16)(%[data]), %%zmm7\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
+		   "xmm6", "xmm7"
+		);
+# endif
+# ifdef HAVE_GCC_INLINE_ASM_AVX
+  else if (have_avx)
+    asm volatile("vbroadcastf128 (0 * 16)(%[data]), %%ymm0\n"
+		 "vbroadcastf128 (1 * 16)(%[data]), %%ymm1\n"
+		 "vbroadcastf128 (2 * 16)(%[data]), %%ymm2\n"
+		 "vbroadcastf128 (3 * 16)(%[data]), %%ymm3\n"
+		 "vbroadcastf128 (4 * 16)(%[data]), %%ymm4\n"
+		 "vbroadcastf128 (5 * 16)(%[data]), %%ymm5\n"
+		 "vbroadcastf128 (6 * 16)(%[data]), %%ymm6\n"
+		 "vbroadcastf128 (7 * 16)(%[data]), %%ymm7\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5",
+		   "ymm6", "ymm7"
+		);
+# endif
+  else
+    asm volatile("movdqu (0 * 16)(%[data]), %%xmm0\n"
+		 "movdqu (1 * 16)(%[data]), %%xmm1\n"
+		 "movdqu (2 * 16)(%[data]), %%xmm2\n"
+		 "movdqu (3 * 16)(%[data]), %%xmm3\n"
+		 "movdqu (4 * 16)(%[data]), %%xmm4\n"
+		 "movdqu (5 * 16)(%[data]), %%xmm5\n"
+		 "movdqu (6 * 16)(%[data]), %%xmm6\n"
+		 "movdqu (7 * 16)(%[data]), %%xmm7\n"
+		 :
+		 : [data] "r" (&data[0])
+		 : "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
+		   "xmm6", "xmm7"
+		);
 #elif defined(CLUTTER_VECTOR_REGISTER_AARCH64)
   asm volatile("mov x0, %[ptr]\n"
 	       "ld1 {v0.16b}, [x0], #16\n"
-- 
2.53.0



More information about the Gcrypt-devel mailing list