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