aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-10-25 18:40:48 +1000
committerRichard Henderson <richard.henderson@linaro.org>2023-03-05 13:44:07 -0800
commit5d133dd839e80e48702916b629c8b396e28611c8 (patch)
treec3efe42bb4b656db1ae526f2dcfdc4e238a2a1d9
parent417aeaff542e6349694b6ebcdff127f926ec3c7e (diff)
downloadqemu-5d133dd839e80e48702916b629c8b396e28611c8.zip
qemu-5d133dd839e80e48702916b629c8b396e28611c8.tar.gz
qemu-5d133dd839e80e48702916b629c8b396e28611c8.tar.bz2
include/qemu/cpuid: Introduce xgetbv_low
Replace the two uses of asm to expand xgetbv with an inline function. Since one of the two has been using the mnemonic, assume that the comment about "older versions of the assember" is obsolete, as even that is 4 years old. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--include/qemu/cpuid.h7
-rw-r--r--tcg/i386/tcg-target.c.inc11
-rw-r--r--util/bufferiszero.c3
3 files changed, 12 insertions, 9 deletions
diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 7adb12d..1451e8e 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -71,4 +71,11 @@
#define bit_LZCNT (1 << 5)
#endif
+static inline unsigned xgetbv_low(unsigned c)
+{
+ unsigned a, d;
+ asm("xgetbv" : "=a"(a), "=d"(d) : "c"(c));
+ return a;
+}
+
#endif /* QEMU_CPUID_H */
diff --git a/tcg/i386/tcg-target.c.inc b/tcg/i386/tcg-target.c.inc
index 883ced8..028ece6 100644
--- a/tcg/i386/tcg-target.c.inc
+++ b/tcg/i386/tcg-target.c.inc
@@ -4156,12 +4156,9 @@ static void tcg_target_init(TCGContext *s)
/* There are a number of things we must check before we can be
sure of not hitting invalid opcode. */
if (c & bit_OSXSAVE) {
- unsigned xcrl, xcrh;
- /* The xgetbv instruction is not available to older versions of
- * the assembler, so we encode the instruction manually.
- */
- asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcrl), "=d" (xcrh) : "c" (0));
- if ((xcrl & 6) == 6) {
+ unsigned bv = xgetbv_low(0);
+
+ if ((bv & 6) == 6) {
have_avx1 = (c & bit_AVX) != 0;
have_avx2 = (b7 & bit_AVX2) != 0;
@@ -4172,7 +4169,7 @@ static void tcg_target_init(TCGContext *s)
* check that OPMASK and all extended ZMM state are enabled
* even if we're not using them -- the insns will fault.
*/
- if ((xcrl & 0xe0) == 0xe0
+ if ((bv & 0xe0) == 0xe0
&& (b7 & bit_AVX512F)
&& (b7 & bit_AVX512VL)) {
have_avx512vl = true;
diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index 1790ded..1886bc5 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -258,8 +258,7 @@ static void __attribute__((constructor)) init_cpuid_cache(void)
/* We must check that AVX is not just available, but usable. */
if ((c & bit_OSXSAVE) && (c & bit_AVX) && max >= 7) {
- int bv;
- __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0));
+ unsigned bv = xgetbv_low(0);
__cpuid_count(7, 0, a, b, c, d);
if ((bv & 0x6) == 0x6 && (b & bit_AVX2)) {
cache |= CACHE_AVX2;