xref: /aosp_15_r20/external/libdav1d/tests/checkasm/x86/checkasm.asm (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
1*c0909341SAndroid Build Coastguard Worker; Copyright © 2018, VideoLAN and dav1d authors
2*c0909341SAndroid Build Coastguard Worker; Copyright © 2018, Two Orioles, LLC
3*c0909341SAndroid Build Coastguard Worker; All rights reserved.
4*c0909341SAndroid Build Coastguard Worker;
5*c0909341SAndroid Build Coastguard Worker; Redistribution and use in source and binary forms, with or without
6*c0909341SAndroid Build Coastguard Worker; modification, are permitted provided that the following conditions are met:
7*c0909341SAndroid Build Coastguard Worker;
8*c0909341SAndroid Build Coastguard Worker; 1. Redistributions of source code must retain the above copyright notice, this
9*c0909341SAndroid Build Coastguard Worker;    list of conditions and the following disclaimer.
10*c0909341SAndroid Build Coastguard Worker;
11*c0909341SAndroid Build Coastguard Worker; 2. Redistributions in binary form must reproduce the above copyright notice,
12*c0909341SAndroid Build Coastguard Worker;    this list of conditions and the following disclaimer in the documentation
13*c0909341SAndroid Build Coastguard Worker;    and/or other materials provided with the distribution.
14*c0909341SAndroid Build Coastguard Worker;
15*c0909341SAndroid Build Coastguard Worker; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16*c0909341SAndroid Build Coastguard Worker; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17*c0909341SAndroid Build Coastguard Worker; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18*c0909341SAndroid Build Coastguard Worker; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19*c0909341SAndroid Build Coastguard Worker; ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20*c0909341SAndroid Build Coastguard Worker; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21*c0909341SAndroid Build Coastguard Worker; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22*c0909341SAndroid Build Coastguard Worker; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*c0909341SAndroid Build Coastguard Worker; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24*c0909341SAndroid Build Coastguard Worker; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*c0909341SAndroid Build Coastguard Worker
26*c0909341SAndroid Build Coastguard Worker%include "config.asm"
27*c0909341SAndroid Build Coastguard Worker%undef private_prefix
28*c0909341SAndroid Build Coastguard Worker%define private_prefix checkasm
29*c0909341SAndroid Build Coastguard Worker%include "ext/x86/x86inc.asm"
30*c0909341SAndroid Build Coastguard Worker
31*c0909341SAndroid Build Coastguard WorkerSECTION_RODATA 16
32*c0909341SAndroid Build Coastguard Worker
33*c0909341SAndroid Build Coastguard Worker%if ARCH_X86_64
34*c0909341SAndroid Build Coastguard Worker; just random numbers to reduce the chance of incidental match
35*c0909341SAndroid Build Coastguard Worker%if WIN64
36*c0909341SAndroid Build Coastguard Workerx6:  dq 0x1a1b2550a612b48c,0x79445c159ce79064
37*c0909341SAndroid Build Coastguard Workerx7:  dq 0x2eed899d5a28ddcd,0x86b2536fcd8cf636
38*c0909341SAndroid Build Coastguard Workerx8:  dq 0xb0856806085e7943,0x3f2bf84fc0fcca4e
39*c0909341SAndroid Build Coastguard Workerx9:  dq 0xacbd382dcf5b8de2,0xd229e1f5b281303f
40*c0909341SAndroid Build Coastguard Workerx10: dq 0x71aeaff20b095fd9,0xab63e2e11fa38ed9
41*c0909341SAndroid Build Coastguard Workerx11: dq 0x89b0c0765892729a,0x77d410d5c42c882d
42*c0909341SAndroid Build Coastguard Workerx12: dq 0xc45ea11a955d8dd5,0x24b3c1d2a024048b
43*c0909341SAndroid Build Coastguard Workerx13: dq 0x2e8ec680de14b47c,0xdd7b8919edd42786
44*c0909341SAndroid Build Coastguard Workerx14: dq 0x135ce6888fa02cbf,0x11e53e2b2ac655ef
45*c0909341SAndroid Build Coastguard Workerx15: dq 0x011ff554472a7a10,0x6de8f4c914c334d5
46*c0909341SAndroid Build Coastguard Workern7:  dq 0x21f86d66c8ca00ce
47*c0909341SAndroid Build Coastguard Workern8:  dq 0x75b6ba21077c48ad
48*c0909341SAndroid Build Coastguard Worker%endif
49*c0909341SAndroid Build Coastguard Workern9:  dq 0xed56bb2dcb3c7736
50*c0909341SAndroid Build Coastguard Workern10: dq 0x8bda43d3fd1a7e06
51*c0909341SAndroid Build Coastguard Workern11: dq 0xb64a9c9e5d318408
52*c0909341SAndroid Build Coastguard Workern12: dq 0xdf9a54b303f1d3a3
53*c0909341SAndroid Build Coastguard Workern13: dq 0x4a75479abd64e097
54*c0909341SAndroid Build Coastguard Workern14: dq 0x249214109d5d1c88
55*c0909341SAndroid Build Coastguard Worker%endif
56*c0909341SAndroid Build Coastguard Worker
57*c0909341SAndroid Build Coastguard Workererrmsg_stack: db "stack corruption", 0
58*c0909341SAndroid Build Coastguard Workererrmsg_register: db "failed to preserve register:%s", 0
59*c0909341SAndroid Build Coastguard Workererrmsg_vzeroupper: db "missing vzeroupper", 0
60*c0909341SAndroid Build Coastguard Worker
61*c0909341SAndroid Build Coastguard WorkerSECTION .bss
62*c0909341SAndroid Build Coastguard Worker
63*c0909341SAndroid Build Coastguard Workercheck_vzeroupper: resd 1
64*c0909341SAndroid Build Coastguard Worker
65*c0909341SAndroid Build Coastguard WorkerSECTION .text
66*c0909341SAndroid Build Coastguard Worker
67*c0909341SAndroid Build Coastguard Workercextern fail_func
68*c0909341SAndroid Build Coastguard Worker
69*c0909341SAndroid Build Coastguard Worker; max number of args used by any asm function.
70*c0909341SAndroid Build Coastguard Worker; (max_args % 4) must equal 3 for stack alignment
71*c0909341SAndroid Build Coastguard Worker%define max_args 15
72*c0909341SAndroid Build Coastguard Worker
73*c0909341SAndroid Build Coastguard Worker%if UNIX64
74*c0909341SAndroid Build Coastguard Worker    DECLARE_REG_TMP 0
75*c0909341SAndroid Build Coastguard Worker%else
76*c0909341SAndroid Build Coastguard Worker    DECLARE_REG_TMP 4
77*c0909341SAndroid Build Coastguard Worker%endif
78*c0909341SAndroid Build Coastguard Worker
79*c0909341SAndroid Build Coastguard Worker;-----------------------------------------------------------------------------
80*c0909341SAndroid Build Coastguard Worker; unsigned checkasm_init_x86(char *name)
81*c0909341SAndroid Build Coastguard Worker;-----------------------------------------------------------------------------
82*c0909341SAndroid Build Coastguard Workercglobal init_x86, 0, 5
83*c0909341SAndroid Build Coastguard Worker%if ARCH_X86_64
84*c0909341SAndroid Build Coastguard Worker    push          rbx
85*c0909341SAndroid Build Coastguard Worker%endif
86*c0909341SAndroid Build Coastguard Worker    movifnidn      t0, r0mp
87*c0909341SAndroid Build Coastguard Worker    mov           eax, 0x80000000
88*c0909341SAndroid Build Coastguard Worker    cpuid
89*c0909341SAndroid Build Coastguard Worker    cmp           eax, 0x80000004
90*c0909341SAndroid Build Coastguard Worker    jb .no_brand ; processor brand string not supported
91*c0909341SAndroid Build Coastguard Worker    mov           eax, 0x80000002
92*c0909341SAndroid Build Coastguard Worker    cpuid
93*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 0], eax
94*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 1], ebx
95*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 2], ecx
96*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 3], edx
97*c0909341SAndroid Build Coastguard Worker    mov           eax, 0x80000003
98*c0909341SAndroid Build Coastguard Worker    cpuid
99*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 4], eax
100*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 5], ebx
101*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 6], ecx
102*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 7], edx
103*c0909341SAndroid Build Coastguard Worker    mov           eax, 0x80000004
104*c0909341SAndroid Build Coastguard Worker    cpuid
105*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 8], eax
106*c0909341SAndroid Build Coastguard Worker    mov     [t0+4* 9], ebx
107*c0909341SAndroid Build Coastguard Worker    mov     [t0+4*10], ecx
108*c0909341SAndroid Build Coastguard Worker    mov     [t0+4*11], edx
109*c0909341SAndroid Build Coastguard Worker    xor           eax, eax
110*c0909341SAndroid Build Coastguard Worker    cpuid
111*c0909341SAndroid Build Coastguard Worker    jmp .check_xcr1
112*c0909341SAndroid Build Coastguard Worker.no_brand: ; use manufacturer id as a fallback
113*c0909341SAndroid Build Coastguard Worker    xor           eax, eax
114*c0909341SAndroid Build Coastguard Worker    mov      [t0+4*3], eax
115*c0909341SAndroid Build Coastguard Worker    cpuid
116*c0909341SAndroid Build Coastguard Worker    mov      [t0+4*0], ebx
117*c0909341SAndroid Build Coastguard Worker    mov      [t0+4*1], edx
118*c0909341SAndroid Build Coastguard Worker    mov      [t0+4*2], ecx
119*c0909341SAndroid Build Coastguard Worker.check_xcr1:
120*c0909341SAndroid Build Coastguard Worker    test          eax, eax
121*c0909341SAndroid Build Coastguard Worker    jz .end2 ; cpuid leaf 1 not supported
122*c0909341SAndroid Build Coastguard Worker    mov           t0d, eax ; max leaf
123*c0909341SAndroid Build Coastguard Worker    mov           eax, 1
124*c0909341SAndroid Build Coastguard Worker    cpuid
125*c0909341SAndroid Build Coastguard Worker    and           ecx, 0x18000000
126*c0909341SAndroid Build Coastguard Worker    cmp           ecx, 0x18000000
127*c0909341SAndroid Build Coastguard Worker    jne .end2 ; osxsave/avx not supported
128*c0909341SAndroid Build Coastguard Worker    cmp           t0d, 13 ; cpuid leaf 13 not supported
129*c0909341SAndroid Build Coastguard Worker    jb .end2
130*c0909341SAndroid Build Coastguard Worker    mov           t0d, eax ; cpuid signature
131*c0909341SAndroid Build Coastguard Worker    mov           eax, 13
132*c0909341SAndroid Build Coastguard Worker    mov           ecx, 1
133*c0909341SAndroid Build Coastguard Worker    cpuid
134*c0909341SAndroid Build Coastguard Worker    test           al, 0x04
135*c0909341SAndroid Build Coastguard Worker    jz .end ; xcr1 not supported
136*c0909341SAndroid Build Coastguard Worker    mov           ecx, 1
137*c0909341SAndroid Build Coastguard Worker    xgetbv
138*c0909341SAndroid Build Coastguard Worker    test           al, 0x04
139*c0909341SAndroid Build Coastguard Worker    jnz .end ; always-dirty ymm state
140*c0909341SAndroid Build Coastguard Worker%if ARCH_X86_64 == 0 && PIC
141*c0909341SAndroid Build Coastguard Worker    LEA           eax, check_vzeroupper
142*c0909341SAndroid Build Coastguard Worker    mov         [eax], ecx
143*c0909341SAndroid Build Coastguard Worker%else
144*c0909341SAndroid Build Coastguard Worker    mov [check_vzeroupper], ecx
145*c0909341SAndroid Build Coastguard Worker%endif
146*c0909341SAndroid Build Coastguard Worker.end:
147*c0909341SAndroid Build Coastguard Worker    mov           eax, t0d
148*c0909341SAndroid Build Coastguard Worker.end2:
149*c0909341SAndroid Build Coastguard Worker%if ARCH_X86_64
150*c0909341SAndroid Build Coastguard Worker    pop           rbx
151*c0909341SAndroid Build Coastguard Worker%endif
152*c0909341SAndroid Build Coastguard Worker    RET
153*c0909341SAndroid Build Coastguard Worker
154*c0909341SAndroid Build Coastguard Worker%if ARCH_X86_64
155*c0909341SAndroid Build Coastguard Worker%if WIN64
156*c0909341SAndroid Build Coastguard Worker    %define stack_param rsp+32 ; shadow space
157*c0909341SAndroid Build Coastguard Worker    %define num_fn_args rsp+stack_offset+17*8
158*c0909341SAndroid Build Coastguard Worker    %assign num_reg_args 4
159*c0909341SAndroid Build Coastguard Worker    %assign free_regs 7
160*c0909341SAndroid Build Coastguard Worker    %assign clobber_mask_stack_bit 16
161*c0909341SAndroid Build Coastguard Worker    DECLARE_REG_TMP 4
162*c0909341SAndroid Build Coastguard Worker%else
163*c0909341SAndroid Build Coastguard Worker    %define stack_param rsp
164*c0909341SAndroid Build Coastguard Worker    %define num_fn_args rsp+stack_offset+11*8
165*c0909341SAndroid Build Coastguard Worker    %assign num_reg_args 6
166*c0909341SAndroid Build Coastguard Worker    %assign free_regs 9
167*c0909341SAndroid Build Coastguard Worker    %assign clobber_mask_stack_bit 64
168*c0909341SAndroid Build Coastguard Worker    DECLARE_REG_TMP 7
169*c0909341SAndroid Build Coastguard Worker%endif
170*c0909341SAndroid Build Coastguard Worker
171*c0909341SAndroid Build Coastguard Worker%macro CLOBBER_UPPER 2 ; reg, mask_bit
172*c0909341SAndroid Build Coastguard Worker    mov          r13d, %1d
173*c0909341SAndroid Build Coastguard Worker    or            r13, r8
174*c0909341SAndroid Build Coastguard Worker    test          r9b, %2
175*c0909341SAndroid Build Coastguard Worker    cmovnz         %1, r13
176*c0909341SAndroid Build Coastguard Worker%endmacro
177*c0909341SAndroid Build Coastguard Worker
178*c0909341SAndroid Build Coastguard Workercglobal checked_call, 2, 15, 16, max_args*8+64+8
179*c0909341SAndroid Build Coastguard Worker    mov          r10d, [num_fn_args]
180*c0909341SAndroid Build Coastguard Worker    mov            r8, 0xdeadbeef00000000
181*c0909341SAndroid Build Coastguard Worker    mov           r9d, [num_fn_args+r10*8+8] ; clobber_mask
182*c0909341SAndroid Build Coastguard Worker    mov            t0, [num_fn_args+r10*8]   ; func
183*c0909341SAndroid Build Coastguard Worker
184*c0909341SAndroid Build Coastguard Worker    ; Clobber the upper halves of 32-bit parameters
185*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r0, 1
186*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r1, 2
187*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r2, 4
188*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r3, 8
189*c0909341SAndroid Build Coastguard Worker%if UNIX64
190*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r4, 16
191*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER  r5, 32
192*c0909341SAndroid Build Coastguard Worker%else ; WIN64
193*c0909341SAndroid Build Coastguard Worker%assign i 6
194*c0909341SAndroid Build Coastguard Worker%rep 16-6
195*c0909341SAndroid Build Coastguard Worker    mova       m %+ i, [x %+ i]
196*c0909341SAndroid Build Coastguard Worker    %assign i i+1
197*c0909341SAndroid Build Coastguard Worker%endrep
198*c0909341SAndroid Build Coastguard Worker%endif
199*c0909341SAndroid Build Coastguard Worker
200*c0909341SAndroid Build Coastguard Worker    xor          r11d, r11d
201*c0909341SAndroid Build Coastguard Worker    sub          r10d, num_reg_args
202*c0909341SAndroid Build Coastguard Worker    cmovs        r10d, r11d ; num stack args
203*c0909341SAndroid Build Coastguard Worker
204*c0909341SAndroid Build Coastguard Worker    ; write stack canaries to the area above parameters passed on the stack
205*c0909341SAndroid Build Coastguard Worker    mov           r12, [rsp+stack_offset] ; return address
206*c0909341SAndroid Build Coastguard Worker    not           r12
207*c0909341SAndroid Build Coastguard Worker%assign i 0
208*c0909341SAndroid Build Coastguard Worker%rep 8 ; 64 bytes
209*c0909341SAndroid Build Coastguard Worker    mov [stack_param+(r10+i)*8], r12
210*c0909341SAndroid Build Coastguard Worker    %assign i i+1
211*c0909341SAndroid Build Coastguard Worker%endrep
212*c0909341SAndroid Build Coastguard Worker
213*c0909341SAndroid Build Coastguard Worker    test         r10d, r10d
214*c0909341SAndroid Build Coastguard Worker    jz .stack_setup_done ; no stack parameters
215*c0909341SAndroid Build Coastguard Worker.copy_stack_parameter:
216*c0909341SAndroid Build Coastguard Worker    mov           r12, [stack_param+stack_offset+8+r11*8]
217*c0909341SAndroid Build Coastguard Worker    CLOBBER_UPPER r12, clobber_mask_stack_bit
218*c0909341SAndroid Build Coastguard Worker    shr           r9d, 1
219*c0909341SAndroid Build Coastguard Worker    mov [stack_param+r11*8], r12
220*c0909341SAndroid Build Coastguard Worker    inc          r11d
221*c0909341SAndroid Build Coastguard Worker    cmp          r11d, r10d
222*c0909341SAndroid Build Coastguard Worker    jl .copy_stack_parameter
223*c0909341SAndroid Build Coastguard Worker.stack_setup_done:
224*c0909341SAndroid Build Coastguard Worker
225*c0909341SAndroid Build Coastguard Worker%assign i 14
226*c0909341SAndroid Build Coastguard Worker%rep 15-free_regs
227*c0909341SAndroid Build Coastguard Worker    mov        r %+ i, [n %+ i]
228*c0909341SAndroid Build Coastguard Worker    %assign i i-1
229*c0909341SAndroid Build Coastguard Worker%endrep
230*c0909341SAndroid Build Coastguard Worker    call           t0
231*c0909341SAndroid Build Coastguard Worker
232*c0909341SAndroid Build Coastguard Worker    ; check for stack corruption
233*c0909341SAndroid Build Coastguard Worker    mov           r0d, [num_fn_args]
234*c0909341SAndroid Build Coastguard Worker    xor           r3d, r3d
235*c0909341SAndroid Build Coastguard Worker    sub           r0d, num_reg_args
236*c0909341SAndroid Build Coastguard Worker    cmovs         r0d, r3d ; num stack args
237*c0909341SAndroid Build Coastguard Worker
238*c0909341SAndroid Build Coastguard Worker    mov            r3, [rsp+stack_offset]
239*c0909341SAndroid Build Coastguard Worker    mov            r4, [stack_param+r0*8]
240*c0909341SAndroid Build Coastguard Worker    not            r3
241*c0909341SAndroid Build Coastguard Worker    xor            r4, r3
242*c0909341SAndroid Build Coastguard Worker%assign i 1
243*c0909341SAndroid Build Coastguard Worker%rep 6
244*c0909341SAndroid Build Coastguard Worker    mov            r5, [stack_param+(r0+i)*8]
245*c0909341SAndroid Build Coastguard Worker    xor            r5, r3
246*c0909341SAndroid Build Coastguard Worker    or             r4, r5
247*c0909341SAndroid Build Coastguard Worker    %assign i i+1
248*c0909341SAndroid Build Coastguard Worker%endrep
249*c0909341SAndroid Build Coastguard Worker    xor            r3, [stack_param+(r0+7)*8]
250*c0909341SAndroid Build Coastguard Worker    or             r4, r3
251*c0909341SAndroid Build Coastguard Worker    jz .stack_ok
252*c0909341SAndroid Build Coastguard Worker    ; Save the return value located in rdx:rax first to prevent clobbering.
253*c0909341SAndroid Build Coastguard Worker    mov           r10, rax
254*c0909341SAndroid Build Coastguard Worker    mov           r11, rdx
255*c0909341SAndroid Build Coastguard Worker    lea            r0, [errmsg_stack]
256*c0909341SAndroid Build Coastguard Worker    jmp .fail
257*c0909341SAndroid Build Coastguard Worker.stack_ok:
258*c0909341SAndroid Build Coastguard Worker
259*c0909341SAndroid Build Coastguard Worker    ; check for failure to preserve registers
260*c0909341SAndroid Build Coastguard Worker%assign i 14
261*c0909341SAndroid Build Coastguard Worker%rep 15-free_regs
262*c0909341SAndroid Build Coastguard Worker    cmp        r %+ i, [n %+ i]
263*c0909341SAndroid Build Coastguard Worker    setne         r4b
264*c0909341SAndroid Build Coastguard Worker    lea           r3d, [r4+r3*2]
265*c0909341SAndroid Build Coastguard Worker    %assign i i-1
266*c0909341SAndroid Build Coastguard Worker%endrep
267*c0909341SAndroid Build Coastguard Worker%if WIN64
268*c0909341SAndroid Build Coastguard Worker    lea            r0, [rsp+32] ; account for shadow space
269*c0909341SAndroid Build Coastguard Worker    mov            r5, r0
270*c0909341SAndroid Build Coastguard Worker    test          r3d, r3d
271*c0909341SAndroid Build Coastguard Worker    jz .gpr_ok
272*c0909341SAndroid Build Coastguard Worker%else
273*c0909341SAndroid Build Coastguard Worker    test          r3d, r3d
274*c0909341SAndroid Build Coastguard Worker    jz .gpr_xmm_ok
275*c0909341SAndroid Build Coastguard Worker    mov            r0, rsp
276*c0909341SAndroid Build Coastguard Worker%endif
277*c0909341SAndroid Build Coastguard Worker%assign i free_regs
278*c0909341SAndroid Build Coastguard Worker%rep 15-free_regs
279*c0909341SAndroid Build Coastguard Worker%if i < 10
280*c0909341SAndroid Build Coastguard Worker    mov    dword [r0], " r0" + (i << 16)
281*c0909341SAndroid Build Coastguard Worker    lea            r4, [r0+3]
282*c0909341SAndroid Build Coastguard Worker%else
283*c0909341SAndroid Build Coastguard Worker    mov    dword [r0], " r10" + ((i - 10) << 24)
284*c0909341SAndroid Build Coastguard Worker    lea            r4, [r0+4]
285*c0909341SAndroid Build Coastguard Worker%endif
286*c0909341SAndroid Build Coastguard Worker    test          r3b, 1 << (i - free_regs)
287*c0909341SAndroid Build Coastguard Worker    cmovnz         r0, r4
288*c0909341SAndroid Build Coastguard Worker    %assign i i+1
289*c0909341SAndroid Build Coastguard Worker%endrep
290*c0909341SAndroid Build Coastguard Worker%if WIN64 ; xmm registers
291*c0909341SAndroid Build Coastguard Worker.gpr_ok:
292*c0909341SAndroid Build Coastguard Worker%assign i 6
293*c0909341SAndroid Build Coastguard Worker%rep 16-6
294*c0909341SAndroid Build Coastguard Worker    pxor       m %+ i, [x %+ i]
295*c0909341SAndroid Build Coastguard Worker    %assign i i+1
296*c0909341SAndroid Build Coastguard Worker%endrep
297*c0909341SAndroid Build Coastguard Worker    packsswb       m6, m7
298*c0909341SAndroid Build Coastguard Worker    packsswb       m8, m9
299*c0909341SAndroid Build Coastguard Worker    packsswb      m10, m11
300*c0909341SAndroid Build Coastguard Worker    packsswb      m12, m13
301*c0909341SAndroid Build Coastguard Worker    packsswb      m14, m15
302*c0909341SAndroid Build Coastguard Worker    packsswb       m6, m6
303*c0909341SAndroid Build Coastguard Worker    packsswb       m8, m10
304*c0909341SAndroid Build Coastguard Worker    packsswb      m12, m14
305*c0909341SAndroid Build Coastguard Worker    packsswb       m6, m6
306*c0909341SAndroid Build Coastguard Worker    packsswb       m8, m12
307*c0909341SAndroid Build Coastguard Worker    packsswb       m6, m8
308*c0909341SAndroid Build Coastguard Worker    pxor           m7, m7
309*c0909341SAndroid Build Coastguard Worker    pcmpeqb        m6, m7
310*c0909341SAndroid Build Coastguard Worker    pmovmskb      r3d, m6
311*c0909341SAndroid Build Coastguard Worker    cmp           r3d, 0xffff
312*c0909341SAndroid Build Coastguard Worker    je .xmm_ok
313*c0909341SAndroid Build Coastguard Worker    mov           r7d, " xmm"
314*c0909341SAndroid Build Coastguard Worker%assign i 6
315*c0909341SAndroid Build Coastguard Worker%rep 16-6
316*c0909341SAndroid Build Coastguard Worker    mov        [r0+0], r7d
317*c0909341SAndroid Build Coastguard Worker%if i < 10
318*c0909341SAndroid Build Coastguard Worker    mov   byte [r0+4], "0" + i
319*c0909341SAndroid Build Coastguard Worker    lea            r4, [r0+5]
320*c0909341SAndroid Build Coastguard Worker%else
321*c0909341SAndroid Build Coastguard Worker    mov   word [r0+4], "10" + ((i - 10) << 8)
322*c0909341SAndroid Build Coastguard Worker    lea            r4, [r0+6]
323*c0909341SAndroid Build Coastguard Worker%endif
324*c0909341SAndroid Build Coastguard Worker    test          r3d, 1 << i
325*c0909341SAndroid Build Coastguard Worker    cmovz          r0, r4
326*c0909341SAndroid Build Coastguard Worker    %assign i i+1
327*c0909341SAndroid Build Coastguard Worker%endrep
328*c0909341SAndroid Build Coastguard Worker.xmm_ok:
329*c0909341SAndroid Build Coastguard Worker    cmp            r0, r5
330*c0909341SAndroid Build Coastguard Worker    je .gpr_xmm_ok
331*c0909341SAndroid Build Coastguard Worker    mov     byte [r0], 0
332*c0909341SAndroid Build Coastguard Worker    mov           r11, rdx
333*c0909341SAndroid Build Coastguard Worker    mov            r1, r5
334*c0909341SAndroid Build Coastguard Worker%else
335*c0909341SAndroid Build Coastguard Worker    mov     byte [r0], 0
336*c0909341SAndroid Build Coastguard Worker    mov           r11, rdx
337*c0909341SAndroid Build Coastguard Worker    mov            r1, rsp
338*c0909341SAndroid Build Coastguard Worker%endif
339*c0909341SAndroid Build Coastguard Worker    mov           r10, rax
340*c0909341SAndroid Build Coastguard Worker    lea            r0, [errmsg_register]
341*c0909341SAndroid Build Coastguard Worker    jmp .fail
342*c0909341SAndroid Build Coastguard Worker.gpr_xmm_ok:
343*c0909341SAndroid Build Coastguard Worker    ; Check for dirty YMM state, i.e. missing vzeroupper
344*c0909341SAndroid Build Coastguard Worker    mov           ecx, [check_vzeroupper]
345*c0909341SAndroid Build Coastguard Worker    test          ecx, ecx
346*c0909341SAndroid Build Coastguard Worker    jz .ok ; not supported, skip
347*c0909341SAndroid Build Coastguard Worker    mov           r10, rax
348*c0909341SAndroid Build Coastguard Worker    mov           r11, rdx
349*c0909341SAndroid Build Coastguard Worker    xgetbv
350*c0909341SAndroid Build Coastguard Worker    test           al, 0x04
351*c0909341SAndroid Build Coastguard Worker    jz .restore_retval ; clean ymm state
352*c0909341SAndroid Build Coastguard Worker    lea            r0, [errmsg_vzeroupper]
353*c0909341SAndroid Build Coastguard Worker    vzeroupper
354*c0909341SAndroid Build Coastguard Worker.fail:
355*c0909341SAndroid Build Coastguard Worker    ; Call fail_func() with a descriptive message to mark it as a failure.
356*c0909341SAndroid Build Coastguard Worker    xor           eax, eax
357*c0909341SAndroid Build Coastguard Worker    call fail_func
358*c0909341SAndroid Build Coastguard Worker.restore_retval:
359*c0909341SAndroid Build Coastguard Worker    mov           rax, r10
360*c0909341SAndroid Build Coastguard Worker    mov           rdx, r11
361*c0909341SAndroid Build Coastguard Worker.ok:
362*c0909341SAndroid Build Coastguard Worker    RET
363*c0909341SAndroid Build Coastguard Worker
364*c0909341SAndroid Build Coastguard Worker; trigger a warmup of vector units
365*c0909341SAndroid Build Coastguard Worker%macro WARMUP 0
366*c0909341SAndroid Build Coastguard Workercglobal warmup, 0, 0
367*c0909341SAndroid Build Coastguard Worker    xorps          m0, m0
368*c0909341SAndroid Build Coastguard Worker    mulps          m0, m0
369*c0909341SAndroid Build Coastguard Worker    RET
370*c0909341SAndroid Build Coastguard Worker%endmacro
371*c0909341SAndroid Build Coastguard Worker
372*c0909341SAndroid Build Coastguard WorkerINIT_YMM avx2
373*c0909341SAndroid Build Coastguard WorkerWARMUP
374*c0909341SAndroid Build Coastguard WorkerINIT_ZMM avx512
375*c0909341SAndroid Build Coastguard WorkerWARMUP
376*c0909341SAndroid Build Coastguard Worker
377*c0909341SAndroid Build Coastguard Worker%else
378*c0909341SAndroid Build Coastguard Worker
379*c0909341SAndroid Build Coastguard Worker; just random numbers to reduce the chance of incidental match
380*c0909341SAndroid Build Coastguard Worker%assign n3 0x6549315c
381*c0909341SAndroid Build Coastguard Worker%assign n4 0xe02f3e23
382*c0909341SAndroid Build Coastguard Worker%assign n5 0xb78d0d1d
383*c0909341SAndroid Build Coastguard Worker%assign n6 0x33627ba7
384*c0909341SAndroid Build Coastguard Worker
385*c0909341SAndroid Build Coastguard Worker;-----------------------------------------------------------------------------
386*c0909341SAndroid Build Coastguard Worker; void checkasm_checked_call(void *func, ...)
387*c0909341SAndroid Build Coastguard Worker;-----------------------------------------------------------------------------
388*c0909341SAndroid Build Coastguard Workercglobal checked_call, 1, 7
389*c0909341SAndroid Build Coastguard Worker    mov            r3, [esp+stack_offset]      ; return address
390*c0909341SAndroid Build Coastguard Worker    mov            r1, [esp+stack_offset+17*4] ; num_stack_params
391*c0909341SAndroid Build Coastguard Worker    mov            r2, 27
392*c0909341SAndroid Build Coastguard Worker    not            r3
393*c0909341SAndroid Build Coastguard Worker    sub            r2, r1
394*c0909341SAndroid Build Coastguard Worker.push_canary:
395*c0909341SAndroid Build Coastguard Worker    push           r3
396*c0909341SAndroid Build Coastguard Worker    dec            r2
397*c0909341SAndroid Build Coastguard Worker    jg .push_canary
398*c0909341SAndroid Build Coastguard Worker.push_parameter:
399*c0909341SAndroid Build Coastguard Worker    push dword [esp+32*4]
400*c0909341SAndroid Build Coastguard Worker    dec            r1
401*c0909341SAndroid Build Coastguard Worker    jg .push_parameter
402*c0909341SAndroid Build Coastguard Worker    mov            r3, n3
403*c0909341SAndroid Build Coastguard Worker    mov            r4, n4
404*c0909341SAndroid Build Coastguard Worker    mov            r5, n5
405*c0909341SAndroid Build Coastguard Worker    mov            r6, n6
406*c0909341SAndroid Build Coastguard Worker    call           r0
407*c0909341SAndroid Build Coastguard Worker
408*c0909341SAndroid Build Coastguard Worker    ; check for failure to preserve registers
409*c0909341SAndroid Build Coastguard Worker    cmp            r3, n3
410*c0909341SAndroid Build Coastguard Worker    setne         r3h
411*c0909341SAndroid Build Coastguard Worker    cmp            r4, n4
412*c0909341SAndroid Build Coastguard Worker    setne         r3b
413*c0909341SAndroid Build Coastguard Worker    shl           r3d, 16
414*c0909341SAndroid Build Coastguard Worker    cmp            r5, n5
415*c0909341SAndroid Build Coastguard Worker    setne         r3h
416*c0909341SAndroid Build Coastguard Worker    cmp            r6, n6
417*c0909341SAndroid Build Coastguard Worker    setne         r3b
418*c0909341SAndroid Build Coastguard Worker    test           r3, r3
419*c0909341SAndroid Build Coastguard Worker    jz .gpr_ok
420*c0909341SAndroid Build Coastguard Worker    lea            r1, [esp+16]
421*c0909341SAndroid Build Coastguard Worker    mov       [esp+4], r1
422*c0909341SAndroid Build Coastguard Worker%assign i 3
423*c0909341SAndroid Build Coastguard Worker%rep 4
424*c0909341SAndroid Build Coastguard Worker    mov    dword [r1], " r0" + (i << 16)
425*c0909341SAndroid Build Coastguard Worker    lea            r4, [r1+3]
426*c0909341SAndroid Build Coastguard Worker    test           r3, 1 << ((6 - i) * 8)
427*c0909341SAndroid Build Coastguard Worker    cmovnz         r1, r4
428*c0909341SAndroid Build Coastguard Worker    %assign i i+1
429*c0909341SAndroid Build Coastguard Worker%endrep
430*c0909341SAndroid Build Coastguard Worker    mov     byte [r1], 0
431*c0909341SAndroid Build Coastguard Worker    mov            r5, eax
432*c0909341SAndroid Build Coastguard Worker    mov            r6, edx
433*c0909341SAndroid Build Coastguard Worker    LEA            r1, errmsg_register
434*c0909341SAndroid Build Coastguard Worker    jmp .fail
435*c0909341SAndroid Build Coastguard Worker.gpr_ok:
436*c0909341SAndroid Build Coastguard Worker    ; check for stack corruption
437*c0909341SAndroid Build Coastguard Worker    mov            r3, [esp+48*4] ; num_stack_params
438*c0909341SAndroid Build Coastguard Worker    mov            r6, [esp+31*4] ; return address
439*c0909341SAndroid Build Coastguard Worker    mov            r4, [esp+r3*4]
440*c0909341SAndroid Build Coastguard Worker    sub            r3, 26
441*c0909341SAndroid Build Coastguard Worker    not            r6
442*c0909341SAndroid Build Coastguard Worker    xor            r4, r6
443*c0909341SAndroid Build Coastguard Worker.check_canary:
444*c0909341SAndroid Build Coastguard Worker    mov            r5, [esp+(r3+27)*4]
445*c0909341SAndroid Build Coastguard Worker    xor            r5, r6
446*c0909341SAndroid Build Coastguard Worker    or             r4, r5
447*c0909341SAndroid Build Coastguard Worker    inc            r3
448*c0909341SAndroid Build Coastguard Worker    jl .check_canary
449*c0909341SAndroid Build Coastguard Worker    mov            r5, eax
450*c0909341SAndroid Build Coastguard Worker    mov            r6, edx
451*c0909341SAndroid Build Coastguard Worker    test           r4, r4
452*c0909341SAndroid Build Coastguard Worker    jz .stack_ok
453*c0909341SAndroid Build Coastguard Worker    LEA            r1, errmsg_stack
454*c0909341SAndroid Build Coastguard Worker    jmp .fail
455*c0909341SAndroid Build Coastguard Worker.stack_ok:
456*c0909341SAndroid Build Coastguard Worker    ; check for dirty YMM state, i.e. missing vzeroupper
457*c0909341SAndroid Build Coastguard Worker    LEA           ecx, check_vzeroupper
458*c0909341SAndroid Build Coastguard Worker    mov           ecx, [ecx]
459*c0909341SAndroid Build Coastguard Worker    test          ecx, ecx
460*c0909341SAndroid Build Coastguard Worker    jz .ok ; not supported, skip
461*c0909341SAndroid Build Coastguard Worker    xgetbv
462*c0909341SAndroid Build Coastguard Worker    test           al, 0x04
463*c0909341SAndroid Build Coastguard Worker    jz .ok ; clean ymm state
464*c0909341SAndroid Build Coastguard Worker    LEA            r1, errmsg_vzeroupper
465*c0909341SAndroid Build Coastguard Worker    vzeroupper
466*c0909341SAndroid Build Coastguard Worker.fail:
467*c0909341SAndroid Build Coastguard Worker    mov         [esp], r1
468*c0909341SAndroid Build Coastguard Worker    call fail_func
469*c0909341SAndroid Build Coastguard Worker.ok:
470*c0909341SAndroid Build Coastguard Worker    add           esp, 27*4
471*c0909341SAndroid Build Coastguard Worker    mov           eax, r5
472*c0909341SAndroid Build Coastguard Worker    mov           edx, r6
473*c0909341SAndroid Build Coastguard Worker    RET
474*c0909341SAndroid Build Coastguard Worker
475*c0909341SAndroid Build Coastguard Worker%endif ; ARCH_X86_64
476