blob: 6625ddccabb208e6d82947087b6895589df95360 [file] [log] [blame]
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <stdint.h>
#if defined(__i386__) || defined(__x86_64__)
#include <cpuid.h>
#include <x86intrin.h>
#endif
#include "runtime.h"
#if defined(__i386__) || defined(__x86_64__)
struct cpuid_ret {
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
};
struct cpuid_ret cpuid(uint32_t, uint32_t)
__asm__(GOSYM_PREFIX "internal_cpu.cpuid")
__attribute__((no_split_stack));
struct cpuid_ret cpuid(uint32_t eaxArg, uint32_t ecxArg) {
unsigned int eax = 0;
unsigned int ebx = 0;
unsigned int ecx = 0;
unsigned int edx = 0;
struct cpuid_ret ret;
__get_cpuid_count(eaxArg, ecxArg, &eax, &ebx, &ecx, &edx);
ret.eax = (uint32_t)(eax);
ret.ebx = (uint32_t)(ebx);
ret.ecx = (uint32_t)(ecx);
ret.edx = (uint32_t)(edx);
return ret;
}
struct xgetbv_ret {
uint32_t eax;
uint32_t edx;
};
struct xgetbv_ret xgetbv(void)
__asm__(GOSYM_PREFIX "internal_cpu.xgetbv")
__attribute__((no_split_stack));
#pragma GCC push_options
#pragma GCC target("xsave")
struct xgetbv_ret xgetbv(void) {
long long r;
struct xgetbv_ret ret;
r = _xgetbv(0);
ret.eax = r & 0xffffffff;
ret.edx = r >> 32;
return ret;
}
#pragma GCC pop_options
#endif /* defined(__i386__) || defined(__x86_64__) */