TITLE x86cpuid.asm IF @Version LT 800 ECHO MASM version 8.00 or later is strongly recommended. ENDIF .686 .XMM IF @Version LT 800 XMMWORD STRUCT 16 DQ 2 dup (?) XMMWORD ENDS ENDIF .MODEL FLAT OPTION DOTNAME IF @Version LT 800 .text$ SEGMENT PAGE 'CODE' ELSE .text$ SEGMENT ALIGN(64) 'CODE' ENDIF ALIGN 16 _OPENSSL_ia32_cpuid PROC PUBLIC $L_OPENSSL_ia32_cpuid_begin:: push ebp push ebx push esi push edi xor edx,edx pushfd pop eax mov ecx,eax xor eax,2097152 push eax popfd pushfd pop eax xor ecx,eax xor eax,eax bt ecx,21 jnc $L000nocpuid mov esi,DWORD PTR 20[esp] mov DWORD PTR 8[esi],eax cpuid mov edi,eax xor eax,eax cmp ebx,1970169159 setne al mov ebp,eax cmp edx,1231384169 setne al or ebp,eax cmp ecx,1818588270 setne al or ebp,eax jz $L001intel cmp ebx,1752462657 setne al mov esi,eax cmp edx,1769238117 setne al or esi,eax cmp ecx,1145913699 setne al or esi,eax jnz $L001intel mov eax,2147483648 cpuid cmp eax,2147483649 jb $L001intel mov esi,eax mov eax,2147483649 cpuid or ebp,ecx and ebp,2049 cmp esi,2147483656 jb $L001intel mov eax,2147483656 cpuid movzx esi,cl inc esi mov eax,1 xor ecx,ecx cpuid bt edx,28 jnc $L002generic shr ebx,16 and ebx,255 cmp ebx,esi ja $L002generic and edx,4026531839 jmp $L002generic $L001intel: cmp edi,7 jb $L003cacheinfo mov esi,DWORD PTR 20[esp] mov eax,7 xor ecx,ecx cpuid mov DWORD PTR 8[esi],ebx $L003cacheinfo: cmp edi,4 mov edi,-1 jb $L004nocacheinfo mov eax,4 mov ecx,0 cpuid mov edi,eax shr edi,14 and edi,4095 $L004nocacheinfo: mov eax,1 xor ecx,ecx cpuid and edx,3220176895 cmp ebp,0 jne $L005notintel or edx,1073741824 and ah,15 cmp ah,15 jne $L005notintel or edx,1048576 $L005notintel: bt edx,28 jnc $L002generic and edx,4026531839 cmp edi,0 je $L002generic or edx,268435456 shr ebx,16 cmp bl,1 ja $L002generic and edx,4026531839 $L002generic: and ebp,2048 and ecx,4294965247 mov esi,edx or ebp,ecx bt ecx,27 jnc $L006clear_avx xor ecx,ecx DB 15,1,208 and eax,6 cmp eax,6 je $L007done cmp eax,2 je $L006clear_avx $L008clear_xmm: and ebp,4261412861 and esi,4278190079 $L006clear_avx: and ebp,4026525695 mov edi,DWORD PTR 20[esp] and DWORD PTR 8[edi],4294967263 $L007done: mov eax,esi mov edx,ebp $L000nocpuid: pop edi pop esi pop ebx pop ebp ret _OPENSSL_ia32_cpuid ENDP ;EXTERN _OPENSSL_ia32cap_P:NEAR ALIGN 16 _OPENSSL_rdtsc PROC PUBLIC $L_OPENSSL_rdtsc_begin:: xor eax,eax xor edx,edx lea ecx,DWORD PTR _OPENSSL_ia32cap_P bt DWORD PTR [ecx],4 jnc $L009notsc rdtsc $L009notsc: ret _OPENSSL_rdtsc ENDP ALIGN 16 _OPENSSL_instrument_halt PROC PUBLIC $L_OPENSSL_instrument_halt_begin:: lea ecx,DWORD PTR _OPENSSL_ia32cap_P bt DWORD PTR [ecx],4 jnc $L010nohalt DD 2421723150 and eax,3 jnz $L010nohalt pushfd pop eax bt eax,9 jnc $L010nohalt rdtsc push edx push eax hlt rdtsc sub eax,DWORD PTR [esp] sbb edx,DWORD PTR 4[esp] add esp,8 ret $L010nohalt: xor eax,eax xor edx,edx ret _OPENSSL_instrument_halt ENDP ALIGN 16 _OPENSSL_far_spin PROC PUBLIC $L_OPENSSL_far_spin_begin:: pushfd pop eax bt eax,9 jnc $L011nospin mov eax,DWORD PTR 4[esp] mov ecx,DWORD PTR 8[esp] DD 2430111262 xor eax,eax mov edx,DWORD PTR [ecx] jmp $L012spin ALIGN 16 $L012spin: inc eax cmp edx,DWORD PTR [ecx] je $L012spin DD 529567888 ret $L011nospin: xor eax,eax xor edx,edx ret _OPENSSL_far_spin ENDP ALIGN 16 _OPENSSL_wipe_cpu PROC PUBLIC $L_OPENSSL_wipe_cpu_begin:: xor eax,eax xor edx,edx lea ecx,DWORD PTR _OPENSSL_ia32cap_P mov ecx,DWORD PTR [ecx] bt DWORD PTR [ecx],1 jnc $L013no_x87 and ecx,83886080 cmp ecx,83886080 jne $L014no_sse2 pxor xmm0,xmm0 pxor xmm1,xmm1 pxor xmm2,xmm2 pxor xmm3,xmm3 pxor xmm4,xmm4 pxor xmm5,xmm5 pxor xmm6,xmm6 pxor xmm7,xmm7 $L014no_sse2: DD 4007259865,4007259865,4007259865,4007259865 DD 2430851995 $L013no_x87: lea eax,DWORD PTR 4[esp] ret _OPENSSL_wipe_cpu ENDP ALIGN 16 _OPENSSL_atomic_add PROC PUBLIC $L_OPENSSL_atomic_add_begin:: mov edx,DWORD PTR 4[esp] mov ecx,DWORD PTR 8[esp] push ebx nop mov eax,DWORD PTR [edx] $L015spin: lea ebx,DWORD PTR [ecx*1+eax] nop DD 447811568 jne $L015spin mov eax,ebx pop ebx ret _OPENSSL_atomic_add ENDP ALIGN 16 _OPENSSL_indirect_call PROC PUBLIC $L_OPENSSL_indirect_call_begin:: push ebp mov ebp,esp sub esp,28 mov ecx,DWORD PTR 12[ebp] mov DWORD PTR [esp],ecx mov edx,DWORD PTR 16[ebp] mov DWORD PTR 4[esp],edx mov eax,DWORD PTR 20[ebp] mov DWORD PTR 8[esp],eax mov eax,DWORD PTR 24[ebp] mov DWORD PTR 12[esp],eax mov eax,DWORD PTR 28[ebp] mov DWORD PTR 16[esp],eax mov eax,DWORD PTR 32[ebp] mov DWORD PTR 20[esp],eax mov eax,DWORD PTR 36[ebp] mov DWORD PTR 24[esp],eax call DWORD PTR 8[ebp] mov esp,ebp pop ebp ret _OPENSSL_indirect_call ENDP ALIGN 16 _OPENSSL_cleanse PROC PUBLIC $L_OPENSSL_cleanse_begin:: mov edx,DWORD PTR 4[esp] mov ecx,DWORD PTR 8[esp] xor eax,eax cmp ecx,7 jae $L016lot cmp ecx,0 je $L017ret $L018little: mov BYTE PTR [edx],al sub ecx,1 lea edx,DWORD PTR 1[edx] jnz $L018little $L017ret: ret ALIGN 16 $L016lot: test edx,3 jz $L019aligned mov BYTE PTR [edx],al lea ecx,DWORD PTR [ecx-1] lea edx,DWORD PTR 1[edx] jmp $L016lot $L019aligned: mov DWORD PTR [edx],eax lea ecx,DWORD PTR [ecx-4] test ecx,-4 lea edx,DWORD PTR 4[edx] jnz $L019aligned cmp ecx,0 jne $L018little ret _OPENSSL_cleanse ENDP ALIGN 16 _OPENSSL_ia32_rdrand PROC PUBLIC $L_OPENSSL_ia32_rdrand_begin:: mov ecx,8 $L020loop: DB 15,199,240 jc $L021break loop $L020loop $L021break: cmp eax,0 cmove eax,ecx ret _OPENSSL_ia32_rdrand ENDP ALIGN 16 _OPENSSL_ia32_rdseed PROC PUBLIC $L_OPENSSL_ia32_rdseed_begin:: mov ecx,8 $L022loop: DB 15,199,248 jc $L023break loop $L022loop $L023break: cmp eax,0 cmove eax,ecx ret _OPENSSL_ia32_rdseed ENDP .text$ ENDS .bss SEGMENT 'BSS' COMM _OPENSSL_ia32cap_P:DWORD:4 .bss ENDS .CRT$XCU SEGMENT DWORD PUBLIC 'DATA' EXTERN _OPENSSL_cpuid_setup:NEAR DD _OPENSSL_cpuid_setup .CRT$XCU ENDS END