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