xref: /aosp_15_r20/external/libjpeg-turbo/simd/i386/jsimdcpu.asm (revision dfc6aa5c1cfd4bc4e2018dc74aa96e29ee49c6da)
1*dfc6aa5cSAndroid Build Coastguard Worker;
2*dfc6aa5cSAndroid Build Coastguard Worker; jsimdcpu.asm - SIMD instruction support check
3*dfc6aa5cSAndroid Build Coastguard Worker;
4*dfc6aa5cSAndroid Build Coastguard Worker; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5*dfc6aa5cSAndroid Build Coastguard Worker; Copyright (C) 2016, D. R. Commander.
6*dfc6aa5cSAndroid Build Coastguard Worker;
7*dfc6aa5cSAndroid Build Coastguard Worker; Based on the x86 SIMD extension for IJG JPEG library
8*dfc6aa5cSAndroid Build Coastguard Worker; Copyright (C) 1999-2006, MIYASAKA Masaru.
9*dfc6aa5cSAndroid Build Coastguard Worker; For conditions of distribution and use, see copyright notice in jsimdext.inc
10*dfc6aa5cSAndroid Build Coastguard Worker;
11*dfc6aa5cSAndroid Build Coastguard Worker; This file should be assembled with NASM (Netwide Assembler),
12*dfc6aa5cSAndroid Build Coastguard Worker; can *not* be assembled with Microsoft's MASM or any compatible
13*dfc6aa5cSAndroid Build Coastguard Worker; assembler (including Borland's Turbo Assembler).
14*dfc6aa5cSAndroid Build Coastguard Worker; NASM is available from http://nasm.sourceforge.net/ or
15*dfc6aa5cSAndroid Build Coastguard Worker; http://sourceforge.net/project/showfiles.php?group_id=6208
16*dfc6aa5cSAndroid Build Coastguard Worker
17*dfc6aa5cSAndroid Build Coastguard Worker%include "jsimdext.inc"
18*dfc6aa5cSAndroid Build Coastguard Worker
19*dfc6aa5cSAndroid Build Coastguard Worker; --------------------------------------------------------------------------
20*dfc6aa5cSAndroid Build Coastguard Worker    SECTION     SEG_TEXT
21*dfc6aa5cSAndroid Build Coastguard Worker    BITS        32
22*dfc6aa5cSAndroid Build Coastguard Worker;
23*dfc6aa5cSAndroid Build Coastguard Worker; Check if the CPU supports SIMD instructions
24*dfc6aa5cSAndroid Build Coastguard Worker;
25*dfc6aa5cSAndroid Build Coastguard Worker; GLOBAL(unsigned int)
26*dfc6aa5cSAndroid Build Coastguard Worker; jpeg_simd_cpu_support(void)
27*dfc6aa5cSAndroid Build Coastguard Worker;
28*dfc6aa5cSAndroid Build Coastguard Worker
29*dfc6aa5cSAndroid Build Coastguard Worker    align       32
30*dfc6aa5cSAndroid Build Coastguard Worker    GLOBAL_FUNCTION(jpeg_simd_cpu_support)
31*dfc6aa5cSAndroid Build Coastguard Worker
32*dfc6aa5cSAndroid Build Coastguard WorkerEXTN(jpeg_simd_cpu_support):
33*dfc6aa5cSAndroid Build Coastguard Worker    push        ebx
34*dfc6aa5cSAndroid Build Coastguard Worker;   push        ecx                     ; need not be preserved
35*dfc6aa5cSAndroid Build Coastguard Worker;   push        edx                     ; need not be preserved
36*dfc6aa5cSAndroid Build Coastguard Worker;   push        esi                     ; unused
37*dfc6aa5cSAndroid Build Coastguard Worker    push        edi
38*dfc6aa5cSAndroid Build Coastguard Worker
39*dfc6aa5cSAndroid Build Coastguard Worker    xor         edi, edi                ; simd support flag
40*dfc6aa5cSAndroid Build Coastguard Worker
41*dfc6aa5cSAndroid Build Coastguard Worker    pushfd
42*dfc6aa5cSAndroid Build Coastguard Worker    pop         eax
43*dfc6aa5cSAndroid Build Coastguard Worker    mov         edx, eax
44*dfc6aa5cSAndroid Build Coastguard Worker    xor         eax, 1<<21              ; flip ID bit in EFLAGS
45*dfc6aa5cSAndroid Build Coastguard Worker    push        eax
46*dfc6aa5cSAndroid Build Coastguard Worker    popfd
47*dfc6aa5cSAndroid Build Coastguard Worker    pushfd
48*dfc6aa5cSAndroid Build Coastguard Worker    pop         eax
49*dfc6aa5cSAndroid Build Coastguard Worker    xor         eax, edx
50*dfc6aa5cSAndroid Build Coastguard Worker    jz          near .return            ; CPUID is not supported
51*dfc6aa5cSAndroid Build Coastguard Worker
52*dfc6aa5cSAndroid Build Coastguard Worker    ; Check whether CPUID leaf 07H is supported
53*dfc6aa5cSAndroid Build Coastguard Worker    ; (leaf 07H is used to check for AVX2 instruction support)
54*dfc6aa5cSAndroid Build Coastguard Worker    xor         eax, eax
55*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
56*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, eax
57*dfc6aa5cSAndroid Build Coastguard Worker    jz          near .return
58*dfc6aa5cSAndroid Build Coastguard Worker    cmp         eax, 7
59*dfc6aa5cSAndroid Build Coastguard Worker    jl          short .no_avx2          ; Maximum leaf < 07H
60*dfc6aa5cSAndroid Build Coastguard Worker
61*dfc6aa5cSAndroid Build Coastguard Worker    ; Check for AVX2 instruction support
62*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, 7
63*dfc6aa5cSAndroid Build Coastguard Worker    xor         ecx, ecx
64*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
65*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, ebx
66*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, 1<<5               ; bit5:AVX2
67*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_avx2
68*dfc6aa5cSAndroid Build Coastguard Worker
69*dfc6aa5cSAndroid Build Coastguard Worker    ; Check for AVX2 O/S support
70*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, 1
71*dfc6aa5cSAndroid Build Coastguard Worker    xor         ecx, ecx
72*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
73*dfc6aa5cSAndroid Build Coastguard Worker    test        ecx, 1<<27
74*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_avx2          ; O/S does not support XSAVE
75*dfc6aa5cSAndroid Build Coastguard Worker    test        ecx, 1<<28
76*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_avx2          ; CPU does not support AVX2
77*dfc6aa5cSAndroid Build Coastguard Worker
78*dfc6aa5cSAndroid Build Coastguard Worker    xor         ecx, ecx
79*dfc6aa5cSAndroid Build Coastguard Worker    xgetbv
80*dfc6aa5cSAndroid Build Coastguard Worker    and         eax, 6
81*dfc6aa5cSAndroid Build Coastguard Worker    cmp         eax, 6                  ; O/S does not manage XMM/YMM state
82*dfc6aa5cSAndroid Build Coastguard Worker                                        ; using XSAVE
83*dfc6aa5cSAndroid Build Coastguard Worker    jnz         short .no_avx2
84*dfc6aa5cSAndroid Build Coastguard Worker
85*dfc6aa5cSAndroid Build Coastguard Worker    or          edi, JSIMD_AVX2
86*dfc6aa5cSAndroid Build Coastguard Worker.no_avx2:
87*dfc6aa5cSAndroid Build Coastguard Worker
88*dfc6aa5cSAndroid Build Coastguard Worker    ; Check CPUID leaf 01H for MMX, SSE, and SSE2 support
89*dfc6aa5cSAndroid Build Coastguard Worker    xor         eax, eax
90*dfc6aa5cSAndroid Build Coastguard Worker    inc         eax
91*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
92*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, edx                ; eax = Standard feature flags
93*dfc6aa5cSAndroid Build Coastguard Worker
94*dfc6aa5cSAndroid Build Coastguard Worker    ; Check for MMX instruction support
95*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, 1<<23              ; bit23:MMX
96*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_mmx
97*dfc6aa5cSAndroid Build Coastguard Worker    or          edi, byte JSIMD_MMX
98*dfc6aa5cSAndroid Build Coastguard Worker.no_mmx:
99*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, 1<<25              ; bit25:SSE
100*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_sse
101*dfc6aa5cSAndroid Build Coastguard Worker    or          edi, byte JSIMD_SSE
102*dfc6aa5cSAndroid Build Coastguard Worker.no_sse:
103*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, 1<<26              ; bit26:SSE2
104*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_sse2
105*dfc6aa5cSAndroid Build Coastguard Worker    or          edi, byte JSIMD_SSE2
106*dfc6aa5cSAndroid Build Coastguard Worker.no_sse2:
107*dfc6aa5cSAndroid Build Coastguard Worker
108*dfc6aa5cSAndroid Build Coastguard Worker    ; Check for 3DNow! instruction support
109*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, 0x80000000
110*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
111*dfc6aa5cSAndroid Build Coastguard Worker    cmp         eax, 0x80000000
112*dfc6aa5cSAndroid Build Coastguard Worker    jbe         short .return
113*dfc6aa5cSAndroid Build Coastguard Worker
114*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, 0x80000001
115*dfc6aa5cSAndroid Build Coastguard Worker    cpuid
116*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, edx                ; eax = Extended feature flags
117*dfc6aa5cSAndroid Build Coastguard Worker
118*dfc6aa5cSAndroid Build Coastguard Worker    test        eax, 1<<31              ; bit31:3DNow!(vendor independent)
119*dfc6aa5cSAndroid Build Coastguard Worker    jz          short .no_3dnow
120*dfc6aa5cSAndroid Build Coastguard Worker    or          edi, byte JSIMD_3DNOW
121*dfc6aa5cSAndroid Build Coastguard Worker.no_3dnow:
122*dfc6aa5cSAndroid Build Coastguard Worker
123*dfc6aa5cSAndroid Build Coastguard Worker.return:
124*dfc6aa5cSAndroid Build Coastguard Worker    mov         eax, edi
125*dfc6aa5cSAndroid Build Coastguard Worker
126*dfc6aa5cSAndroid Build Coastguard Worker    pop         edi
127*dfc6aa5cSAndroid Build Coastguard Worker;   pop         esi                     ; unused
128*dfc6aa5cSAndroid Build Coastguard Worker;   pop         edx                     ; need not be preserved
129*dfc6aa5cSAndroid Build Coastguard Worker;   pop         ecx                     ; need not be preserved
130*dfc6aa5cSAndroid Build Coastguard Worker    pop         ebx
131*dfc6aa5cSAndroid Build Coastguard Worker    ret
132*dfc6aa5cSAndroid Build Coastguard Worker
133*dfc6aa5cSAndroid Build Coastguard Worker; For some reason, the OS X linker does not honor the request to align the
134*dfc6aa5cSAndroid Build Coastguard Worker; segment unless we do this.
135*dfc6aa5cSAndroid Build Coastguard Worker    align       32
136