diff options
author | Chris Blume <cblume@chromium.org> | 2019-04-16 15:21:05 -0700 |
---|---|---|
committer | Chris Blume <cblume@chromium.org> | 2019-04-16 22:21:51 +0000 |
commit | bce751521a42889e1cd3988926c6fe0d36c44ca5 (patch) | |
tree | 10fc46271cefd7bf7d508f599b867ff75c297483 /simd | |
parent | 6dcdade8828297e306cabfdae80f3510f3f3eea2 (diff) |
Check maximum CPUID leaf
According to Intel's manual [1] page 3-192, "If a value entered for
CPUID.EAX is higher than the maximum input value for basic or extended
function for that processor then the data for the highest basic
information leaf is returned."
Right now, libjpeg-turbo doesn't first check that leaf 7 is supported
before checking the AVX2 bit of the results. This means we could
potentially be checking that bit in leaf 6 or 5, for example.
This commit fixes this by first checking that CPUID leaf 7 is supported
before making the AVX2 check.
This was submitted & accepted upstream:
https://github.com/libjpeg-turbo/libjpeg-turbo/commit/aa9db616774e24af7ab2fbcddd5711057b8a901e
[1]
https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf
Bug:922430
Change-Id: I7d20e5be28e90aeac26b4bd78ddcd61fd0df9300
Diffstat (limited to 'simd')
-rw-r--r-- | simd/i386/jsimdcpu.asm | 43 | ||||
-rw-r--r-- | simd/x86_64/jsimdcpu.asm | 13 |
2 files changed, 35 insertions, 21 deletions
diff --git a/simd/i386/jsimdcpu.asm b/simd/i386/jsimdcpu.asm index faddd38..b6265d3 100644 --- a/simd/i386/jsimdcpu.asm +++ b/simd/i386/jsimdcpu.asm @@ -51,29 +51,14 @@ EXTN(jpeg_simd_cpu_support): xor eax, edx jz near .return ; CPUID is not supported - ; Check for MMX instruction support + ; Check maximum supported CPUID leaf xor eax, eax cpuid test eax, eax jz near .return - - xor eax, eax - inc eax - cpuid - mov eax, edx ; eax = Standard feature flags - - test eax, 1<<23 ; bit23:MMX - jz short .no_mmx - or edi, byte JSIMD_MMX -.no_mmx: - test eax, 1<<25 ; bit25:SSE - jz short .no_sse - or edi, byte JSIMD_SSE -.no_sse: - test eax, 1<<26 ; bit26:SSE2 - jz short .no_sse2 - or edi, byte JSIMD_SSE2 -.no_sse2: + cmp eax, 7 ; Skip AVX2 check if its leaf + ; is not supported + jl short .no_avx2 ; Check for AVX2 instruction support mov eax, 7 @@ -102,6 +87,26 @@ EXTN(jpeg_simd_cpu_support): or edi, JSIMD_AVX2 .no_avx2: + ; Check CPUID leaf 1 for MMX, SSE, and SSE2 support + xor eax, eax + inc eax + cpuid + mov eax, edx ; eax = Standard feature flags + + ; Check for MMX instruction support + test eax, 1<<23 ; bit23:MMX + jz short .no_mmx + or edi, byte JSIMD_MMX +.no_mmx: + test eax, 1<<25 ; bit25:SSE + jz short .no_sse + or edi, byte JSIMD_SSE +.no_sse: + test eax, 1<<26 ; bit26:SSE2 + jz short .no_sse2 + or edi, byte JSIMD_SSE2 +.no_sse2: + ; Check for 3DNow! instruction support mov eax, 0x80000000 cpuid diff --git a/simd/x86_64/jsimdcpu.asm b/simd/x86_64/jsimdcpu.asm index 38e1a7b..224f3c6 100644 --- a/simd/x86_64/jsimdcpu.asm +++ b/simd/x86_64/jsimdcpu.asm @@ -38,14 +38,23 @@ EXTN(jpeg_simd_cpu_support): xor rdi, rdi ; simd support flag + ; Assume SSE & SSE2 support in all x86-64 processors + or rdi, JSIMD_SSE2 + or rdi, JSIMD_SSE + + ; Check maximum supported CPUID leaf + mov rax, 0 + cpuid + cmp rax, 7 ; Exit if the maximum leaf < AVX2's + ; leaf + jl short .return + ; Check for AVX2 instruction support mov rax, 7 xor rcx, rcx cpuid mov rax, rbx ; rax = Extended feature flags - or rdi, JSIMD_SSE2 - or rdi, JSIMD_SSE test rax, 1<<5 ; bit5:AVX2 jz short .return |