Alex Vaghin | bc2ef10 | 2018-06-04 16:47:02 +0200 | [diff] [blame] | 1 | // Copyright 2018 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | // +build 386 amd64 amd64p32 |
| 6 | // +build gccgo |
| 7 | |
| 8 | #include <cpuid.h> |
| 9 | #include <stdint.h> |
| 10 | |
| 11 | // Need to wrap __get_cpuid_count because it's declared as static. |
| 12 | int |
| 13 | gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, |
| 14 | uint32_t *eax, uint32_t *ebx, |
| 15 | uint32_t *ecx, uint32_t *edx) |
| 16 | { |
| 17 | return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); |
| 18 | } |
| 19 | |
| 20 | // xgetbv reads the contents of an XCR (Extended Control Register) |
| 21 | // specified in the ECX register into registers EDX:EAX. |
| 22 | // Currently, the only supported value for XCR is 0. |
| 23 | // |
| 24 | // TODO: Replace with a better alternative: |
| 25 | // |
| 26 | // #include <xsaveintrin.h> |
| 27 | // |
| 28 | // #pragma GCC target("xsave") |
| 29 | // |
| 30 | // void gccgoXgetbv(uint32_t *eax, uint32_t *edx) { |
| 31 | // unsigned long long x = _xgetbv(0); |
| 32 | // *eax = x & 0xffffffff; |
| 33 | // *edx = (x >> 32) & 0xffffffff; |
| 34 | // } |
| 35 | // |
| 36 | // Note that _xgetbv is defined starting with GCC 8. |
| 37 | void |
| 38 | gccgoXgetbv(uint32_t *eax, uint32_t *edx) |
| 39 | { |
| 40 | __asm(" xorl %%ecx, %%ecx\n" |
| 41 | " xgetbv" |
| 42 | : "=a"(*eax), "=d"(*edx)); |
| 43 | } |