| 70 | } // anonymous namespace |
| 71 | |
| 72 | CPUInfo::CPUInfo() |
| 73 | { |
| 74 | flags = 0, family = 0, model = 0; |
| 75 | memset(name, 0, sizeof(name)); |
| 76 | memset(vendor, 0, sizeof(vendor)); |
| 77 | |
| 78 | CPUIDResult info; |
| 79 | uint32_t max_std_level, max_ext_level; |
| 80 | int64_t xcr = 0; |
| 81 | |
| 82 | cpuid(0, info.i); |
| 83 | max_std_level = info.i[0]; |
| 84 | memcpy(vendor + 0, &info.i[1], 4); |
| 85 | memcpy(vendor + 4, &info.i[3], 4); |
| 86 | memcpy(vendor + 8, &info.i[2], 4); |
| 87 | |
| 88 | if (max_std_level >= 1) |
| 89 | { |
| 90 | cpuid(1, info.i); |
| 91 | family = ((info.reg.eax >> 8) & 0xf) + ((info.reg.eax >> 20) & 0xff); |
| 92 | model = ((info.reg.eax >> 4) & 0xf) + ((info.reg.eax >> 12) & 0xf0); |
| 93 | |
| 94 | if (info.reg.edx & (1 << 26)) |
| 95 | flags |= X86_CPU_FLAG_SSE2; |
| 96 | |
| 97 | if (info.reg.ecx & 1) |
| 98 | flags |= X86_CPU_FLAG_SSE3; |
| 99 | |
| 100 | if (info.reg.ecx & 0x00000200) |
| 101 | flags |= X86_CPU_FLAG_SSSE3; |
| 102 | |
| 103 | if (info.reg.ecx & 0x00080000) |
| 104 | flags |= X86_CPU_FLAG_SSE4; |
| 105 | |
| 106 | if (info.reg.ecx & 0x00100000) |
| 107 | flags |= X86_CPU_FLAG_SSE42; |
| 108 | |
| 109 | /* Check OSXSAVE and AVX bits */ |
| 110 | if ((info.reg.ecx & 0x18000000) == 0x18000000) |
| 111 | { |
| 112 | xcr = xgetbv(); |
| 113 | if((xcr & 0x6) == 0x6) { |
| 114 | flags |= X86_CPU_FLAG_AVX; |
| 115 | |
| 116 | if(info.reg.ecx & 0x20000000) { |
| 117 | flags |= X86_CPU_FLAG_F16C; |
| 118 | } |
| 119 | } |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | if (max_std_level >= 7) |
| 124 | { |
| 125 | cpuid(7, info.i); |
| 126 | |
| 127 | if ((flags & X86_CPU_FLAG_AVX) && (info.reg.ebx & 0x00000020)) |
| 128 | flags |= X86_CPU_FLAG_AVX2; |
| 129 | |