xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.arch/i386-avx512.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Test program for AVX 512 registers.
2 
3    Copyright 2014-2023 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "x86-cpuid.h"
21 
22 typedef struct
23 {
24   double f[8];
25 } v8sd_t;
26 
27 short k_data[] =
28 {
29   0x1211,
30   0x2221,
31   0x3231,
32   0x4241,
33   0x5251,
34   0x6261,
35   0x7271
36 };
37 
38 v8sd_t zmm_data[] =
39 {
40   { {  0.0,  0.125,  0.25,  0.375,  0.50,  0.625,  0.75,  0.875 } },
41   { {  1.0,  1.125,  1.25,  1.375,  1.50,  1.625,  1.75,  1.875 } },
42   { {  2.0,  2.125,  2.25,  2.375,  2.50,  2.625,  2.75,  2.875 } },
43   { {  3.0,  3.125,  3.25,  3.375,  3.50,  3.625,  3.75,  3.875 } },
44   { {  4.0,  4.125,  4.25,  4.375,  4.50,  4.625,  4.75,  4.875 } },
45   { {  5.0,  5.125,  5.25,  5.375,  5.50,  5.625,  5.75,  5.875 } },
46   { {  6.0,  6.125,  6.25,  6.375,  6.50,  6.625,  6.75,  6.875 } },
47   { {  7.0,  7.125,  7.25,  7.375,  7.50,  7.625,  7.75,  7.875 } },
48 #ifdef __x86_64__
49   { {  8.0,  8.125,  8.25,  8.375,  8.50,  8.625,  8.75,  8.875 } },
50   { {  9.0,  9.125,  9.25,  9.375,  9.50,  9.625,  9.75,  9.875 } },
51   { { 10.0, 10.125, 10.25, 10.375, 10.50, 10.625, 10.75, 10.875 } },
52   { { 11.0, 11.125, 11.25, 11.375, 11.50, 11.625, 11.75, 11.875 } },
53   { { 12.0, 12.125, 12.25, 12.375, 12.50, 12.625, 12.75, 12.875 } },
54   { { 13.0, 13.125, 13.25, 13.375, 13.50, 13.625, 13.75, 13.875 } },
55   { { 14.0, 14.125, 14.25, 14.375, 14.50, 14.625, 14.75, 14.875 } },
56   { { 15.0, 15.125, 15.25, 15.375, 15.50, 15.625, 15.75, 15.875 } },
57   { { 16.0, 16.125, 16.25, 16.375, 16.50, 16.625, 16.75, 16.875 } },
58   { { 17.0, 17.125, 17.25, 17.375, 17.50, 17.625, 17.75, 17.875 } },
59   { { 18.0, 18.125, 18.25, 18.375, 18.50, 18.625, 18.75, 18.875 } },
60   { { 19.0, 19.125, 19.25, 19.375, 19.50, 19.625, 19.75, 19.875 } },
61   { { 20.0, 20.125, 20.25, 20.375, 20.50, 20.625, 20.75, 20.875 } },
62   { { 21.0, 21.125, 21.25, 21.375, 21.50, 21.625, 21.75, 21.875 } },
63   { { 22.0, 22.125, 22.25, 22.375, 22.50, 22.625, 22.75, 22.875 } },
64   { { 23.0, 23.125, 23.25, 23.375, 23.50, 23.625, 23.75, 23.875 } },
65   { { 24.0, 24.125, 24.25, 24.375, 24.50, 24.625, 24.75, 24.875 } },
66   { { 25.0, 25.125, 25.25, 25.375, 25.50, 25.625, 25.75, 25.875 } },
67   { { 26.0, 26.125, 26.25, 26.375, 26.50, 26.625, 26.75, 26.875 } },
68   { { 27.0, 27.125, 27.25, 27.375, 27.50, 27.625, 27.75, 27.875 } },
69   { { 28.0, 28.125, 28.25, 28.375, 28.50, 28.625, 28.75, 28.875 } },
70   { { 29.0, 29.125, 29.25, 29.375, 29.50, 29.625, 29.75, 29.875 } },
71   { { 30.0, 30.125, 30.25, 30.375, 30.50, 30.625, 30.75, 30.875 } },
72   { { 31.0, 31.125, 31.25, 31.375, 31.50, 31.625, 31.75, 31.875 } },
73   { { 32.0, 32.125, 32.25, 32.375, 32.50, 32.625, 32.75, 32.875 } },
74 #endif
75 };
76 
77 int
78 have_avx512 (void)
79 {
80   unsigned int eax, ebx, ecx, edx, max_level, vendor, has_osxsave, has_avx512f;
81 
82   max_level = __get_cpuid_max (0, &vendor);
83   __cpuid (1, eax, ebx, ecx, edx);
84 
85   has_osxsave = ecx & bit_OSXSAVE;
86 
87   if (max_level >= 7)
88     {
89       __cpuid_count (7, 0, eax, ebx, ecx, edx);
90       has_avx512f = ebx & bit_AVX512F;
91     }
92 
93   if (has_osxsave && has_avx512f)
94     return 1;
95   else
96     return 0;
97 }
98 
99 void
100 move_k_data_to_reg (void)
101 {
102   asm ("kmovw 0(%0), %%k1\n\t"
103        "kmovw 2(%0), %%k2\n\t"
104        "kmovw 4(%0), %%k3\n\t"
105        "kmovw 6(%0), %%k4\n\t"
106        "kmovw 8(%0), %%k5\n\t"
107        "kmovw 10(%0), %%k6\n\t"
108        "kmovw 12(%0), %%k7\n\t"
109        : /* no output operands  */
110        : "r" (k_data));
111 }
112 
113 void
114 move_k_data_to_memory (void)
115 {
116   asm ("kmovw %%k1, 0(%0) \n\t"
117        "kmovw %%k2, 2(%0) \n\t"
118        "kmovw %%k3, 4(%0) \n\t"
119        "kmovw %%k4, 6(%0) \n\t"
120        "kmovw %%k5, 8(%0) \n\t"
121        "kmovw %%k6, 10(%0) \n\t"
122        "kmovw %%k7, 12(%0) \n\t"
123        : /* no output operands  */
124        : "r" (k_data));
125 }
126 
127 void
128 move_zmm_data_to_reg (void)
129 {
130   asm ("vmovups 0(%0), %%zmm0 \n\t"
131        "vmovups 64(%0), %%zmm1 \n\t"
132        "vmovups 128(%0), %%zmm2 \n\t"
133        "vmovups 192(%0), %%zmm3 \n\t"
134        "vmovups 256(%0), %%zmm4 \n\t"
135        "vmovups 320(%0), %%zmm5 \n\t"
136        "vmovups 384(%0), %%zmm6 \n\t"
137        "vmovups 448(%0), %%zmm7 \n\t"
138        : /* no output operands  */
139        : "r" (zmm_data));
140 #ifdef __x86_64__
141   asm ("vmovups 512(%0), %%zmm8 \n\t"
142        "vmovups 576(%0), %%zmm9 \n\t"
143        "vmovups 640(%0), %%zmm10 \n\t"
144        "vmovups 704(%0), %%zmm11 \n\t"
145        "vmovups 768(%0), %%zmm12 \n\t"
146        "vmovups 832(%0), %%zmm13 \n\t"
147        "vmovups 896(%0), %%zmm14 \n\t"
148        "vmovups 960(%0), %%zmm15 \n\t"
149        : /* no output operands  */
150        : "r" (zmm_data));
151 
152   asm ("vmovups 1024(%0), %%zmm16 \n\t"
153        "vmovups 1088(%0), %%zmm17 \n\t"
154        "vmovups 1152(%0), %%zmm18 \n\t"
155        "vmovups 1216(%0), %%zmm19 \n\t"
156        "vmovups 1280(%0), %%zmm20 \n\t"
157        "vmovups 1344(%0), %%zmm21 \n\t"
158        "vmovups 1408(%0), %%zmm22 \n\t"
159        "vmovups 1472(%0), %%zmm23 \n\t"
160        "vmovups 1536(%0), %%zmm24 \n\t"
161        "vmovups 1600(%0), %%zmm25 \n\t"
162        "vmovups 1664(%0), %%zmm26 \n\t"
163        "vmovups 1728(%0), %%zmm27 \n\t"
164        "vmovups 1792(%0), %%zmm28 \n\t"
165        "vmovups 1856(%0), %%zmm29 \n\t"
166        "vmovups 1920(%0), %%zmm30 \n\t"
167        "vmovups 1984(%0), %%zmm31 \n\t"
168        : /* no output operands  */
169        : "r" (zmm_data));
170 #endif
171 }
172 
173 void
174 move_zmm_data_to_memory (void)
175 {
176   asm ("vmovups %%zmm0, 0(%0)\n\t"
177        "vmovups %%zmm1, 64(%0)\n\t"
178        "vmovups %%zmm2, 128(%0)\n\t"
179        "vmovups %%zmm3, 192(%0)\n\t"
180        "vmovups %%zmm4, 256(%0)\n\t"
181        "vmovups %%zmm5, 320(%0)\n\t"
182        "vmovups %%zmm6, 384(%0)\n\t"
183        "vmovups %%zmm7, 448(%0)\n\t"
184        : /* no output operands  */
185        : "r" (zmm_data));
186 #ifdef __x86_64__
187   asm ("vmovups %%zmm8, 512(%0)\n\t"
188        "vmovups %%zmm9, 576(%0)\n\t"
189        "vmovups %%zmm10, 640(%0)\n\t"
190        "vmovups %%zmm11, 704(%0)\n\t"
191        "vmovups %%zmm12, 768(%0)\n\t"
192        "vmovups %%zmm13, 832(%0)\n\t"
193        "vmovups %%zmm14, 896(%0)\n\t"
194        "vmovups %%zmm15, 960(%0)\n\t"
195        : /* no output operands  */
196        : "r" (zmm_data));
197 
198   asm ("vmovups %%zmm16, 1024(%0)\n\t"
199        "vmovups %%zmm17, 1088(%0)\n\t"
200        "vmovups %%zmm18, 1152(%0)\n\t"
201        "vmovups %%zmm19, 1216(%0)\n\t"
202        "vmovups %%zmm20, 1280(%0)\n\t"
203        "vmovups %%zmm21, 1344(%0)\n\t"
204        "vmovups %%zmm22, 1408(%0)\n\t"
205        "vmovups %%zmm23, 1472(%0)\n\t"
206        "vmovups %%zmm24, 1536(%0)\n\t"
207        "vmovups %%zmm25, 1600(%0)\n\t"
208        "vmovups %%zmm26, 1664(%0)\n\t"
209        "vmovups %%zmm27, 1728(%0)\n\t"
210        "vmovups %%zmm28, 1792(%0)\n\t"
211        "vmovups %%zmm29, 1856(%0)\n\t"
212        "vmovups %%zmm30, 1920(%0)\n\t"
213        "vmovups %%zmm31, 1984(%0)\n\t"
214        : /* no output operands  */
215        : "r" (zmm_data));
216 #endif
217 }
218 
219 int
220 main (int argc, char **argv)
221 {
222   if (have_avx512 ())
223     {
224       /* Test for K registers.  */
225       move_k_data_to_reg ();
226       asm ("nop"); /* first breakpoint here  */
227 
228       move_k_data_to_memory ();
229       asm ("nop"); /* second breakpoint here  */
230 
231       /* Test for ZMM registers.  */
232       /* Move initial values from array to registers and read from ZMM regs.  */
233       move_zmm_data_to_reg ();
234       asm ("nop"); /* third breakpoint here  */
235 
236       /* Test script incremented values,
237 	 move back to array and check values.  */
238       move_zmm_data_to_memory ();
239       asm ("nop"); /* fourth breakpoint here  */
240 
241       /* Test for YMM registers.  */
242       /* Test script incremented YMM values,
243 	 move back to array and check values.  */
244       move_zmm_data_to_memory ();
245       asm ("nop"); /* fifth breakpoint here  */
246 
247       /* Test for XMM registers.  */
248       /* Test script incremented XMM values,
249 	 move back to array and check values.  */
250       move_zmm_data_to_memory ();
251       asm ("nop"); /* sixth breakpoint here  */
252 
253       asm ("vpternlogd $0xff, %zmm0, %zmm0, %zmm0");
254 #ifdef __x86_64__
255       asm ("vpternlogd $0xff, %zmm0, %zmm0, %zmm16");
256 #endif
257       asm ("vzeroupper");
258       asm ("nop"); /* seventh breakpoint here  */
259     }
260 
261   return 0;
262 }
263