mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-13 13:29:58 -05:00
core-util, cpu-x86: use __get_cpuid() instead of homegrown assembly
The get_cpuid() function in cpu-x86.c was buggy on x86-64. When building without optimizations, the homegrown assembly code overwrote the beginning of the function argument list on the stack. That happened to work fine on regular x86-64, but caused crashing with the x32 ABI. At least GCC and clang provide cpuid.h, which has the __get_cpuid() function that can be used instead of the homegrown assembly. The PA_REG_* constants can be removed as well, because they're not used any more. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=103656
This commit is contained in:
parent
2062fc8b0e
commit
c8bd93c5a7
4 changed files with 38 additions and 48 deletions
|
|
@ -24,35 +24,28 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_CPUID_H
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
#include <pulsecore/log.h>
|
||||
|
||||
#include "cpu-x86.h"
|
||||
|
||||
#if defined (__i386__) || defined (__amd64__)
|
||||
static void get_cpuid(uint32_t op, uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *d) {
|
||||
__asm__ __volatile__ (
|
||||
" push %%"PA_REG_b" \n\t"
|
||||
" cpuid \n\t"
|
||||
" mov %%ebx, %%esi \n\t"
|
||||
" pop %%"PA_REG_b" \n\t"
|
||||
|
||||
: "=a" (*a), "=S" (*b), "=c" (*c), "=d" (*d)
|
||||
: "0" (op)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags) {
|
||||
#if defined (__i386__) || defined (__amd64__)
|
||||
#if (defined(__i386__) || defined(__amd64__)) && defined(HAVE_CPUID_H)
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
uint32_t level;
|
||||
|
||||
*flags = 0;
|
||||
|
||||
/* get standard level */
|
||||
get_cpuid(0x00000000, &level, &ebx, &ecx, &edx);
|
||||
if (__get_cpuid(0x00000000, &level, &ebx, &ecx, &edx) == 0)
|
||||
goto finish;
|
||||
|
||||
if (level >= 1) {
|
||||
get_cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
|
||||
if (__get_cpuid(0x00000001, &eax, &ebx, &ecx, &edx) == 0)
|
||||
goto finish;
|
||||
|
||||
if (edx & (1<<15))
|
||||
*flags |= PA_CPU_X86_CMOV;
|
||||
|
|
@ -80,9 +73,12 @@ void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags) {
|
|||
}
|
||||
|
||||
/* get extended level */
|
||||
get_cpuid(0x80000000, &level, &ebx, &ecx, &edx);
|
||||
if (__get_cpuid(0x80000000, &level, &ebx, &ecx, &edx) == 0)
|
||||
goto finish;
|
||||
|
||||
if (level >= 0x80000001) {
|
||||
get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
||||
if (__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx) == 0)
|
||||
goto finish;
|
||||
|
||||
if (edx & (1<<22))
|
||||
*flags |= PA_CPU_X86_MMXEXT;
|
||||
|
|
@ -97,6 +93,7 @@ void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags) {
|
|||
*flags |= PA_CPU_X86_3DNOW;
|
||||
}
|
||||
|
||||
finish:
|
||||
pa_log_info("CPU flags: %s%s%s%s%s%s%s%s%s%s%s",
|
||||
(*flags & PA_CPU_X86_CMOV) ? "CMOV " : "",
|
||||
(*flags & PA_CPU_X86_MMX) ? "MMX " : "",
|
||||
|
|
@ -109,7 +106,7 @@ void pa_cpu_get_x86_flags(pa_cpu_x86_flag_t *flags) {
|
|||
(*flags & PA_CPU_X86_MMXEXT) ? "MMXEXT " : "",
|
||||
(*flags & PA_CPU_X86_3DNOW) ? "3DNOW " : "",
|
||||
(*flags & PA_CPU_X86_3DNOWEXT) ? "3DNOWEXT " : "");
|
||||
#endif /* defined (__i386__) || defined (__amd64__) */
|
||||
#endif /* (defined(__i386__) || defined(__amd64__)) && defined(HAVE_CPUID_H) */
|
||||
}
|
||||
|
||||
bool pa_cpu_init_x86(pa_cpu_x86_flag_t *flags) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue