| ;*! |
| ;* \copy |
| ;* Copyright (c) 2009-2013, Cisco Systems |
| ;* All rights reserved. |
| ;* |
| ;* Redistribution and use in source and binary forms, with or without |
| ;* modification, are permitted provided that the following conditions |
| ;* are met: |
| ;* |
| ;* * Redistributions of source code must retain the above copyright |
| ;* notice, this list of conditions and the following disclaimer. |
| ;* |
| ;* * Redistributions in binary form must reproduce the above copyright |
| ;* notice, this list of conditions and the following disclaimer in |
| ;* the documentation and/or other materials provided with the |
| ;* distribution. |
| ;* |
| ;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| ;* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| ;* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| ;* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| ;* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| ;* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| ;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| ;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| ;* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| ;* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| ;* POSSIBILITY OF SUCH DAMAGE. |
| ;* |
| ;* |
| ;* cpu_mmx.asm |
| ;* |
| ;* Abstract |
| ;* verify cpuid feature support and cpuid detection |
| ;* |
| ;* History |
| ;* 04/29/2009 Created |
| ;* |
| ;*************************************************************************/ |
| |
| %include "asm_inc.asm" |
| |
| ;****************************************************************************************** |
| ; Macros |
| ;****************************************************************************************** |
| |
| |
| ;****************************************************************************************** |
| ; Code |
| ;****************************************************************************************** |
| |
| SECTION .text |
| |
| ; refer to "The IA-32 Intel(R) Architecture Software Developers Manual, Volume 2A A-M" |
| ; section CPUID - CPU Identification |
| |
| ;****************************************************************************************** |
| ; int32_t WelsCPUIdVerify() |
| ;****************************************************************************************** |
| WELS_EXTERN WelsCPUIdVerify |
| push r1 |
| PUSHRFLAGS |
| PUSHRFLAGS |
| |
| pop r1 |
| mov eax, r1d |
| xor eax, 00200000h |
| xor eax, r1d |
| POPRFLAGS |
| pop r1 |
| ret |
| |
| ;**************************************************************************************************** |
| ; void WelsCPUId( int32_t uiIndex, int32_t *pFeatureA, int32_t *pFeatureB, int32_t *pFeatureC, int32_t *pFeatureD ) |
| ;**************************************************************************************************** |
| %ifdef WIN64 |
| |
| WELS_EXTERN WelsCPUId |
| push rbx |
| push rdx |
| |
| mov eax, ecx |
| mov ecx, [r9] |
| cpuid |
| mov [r9], ecx |
| mov [r8], ebx |
| mov rcx, [rsp + 2*8 + 40] |
| mov [rcx], edx |
| pop rdx |
| mov [rdx], eax |
| |
| pop rbx |
| ret |
| |
| %elifdef UNIX64 |
| WELS_EXTERN WelsCPUId |
| push rbx |
| push rcx |
| push rdx |
| |
| mov eax, edi |
| mov ecx, [rcx] |
| cpuid |
| mov [r8], edx |
| pop rdx |
| pop r8 |
| mov [r8], ecx |
| mov [rdx], ebx |
| mov [rsi], eax |
| |
| pop rbx |
| ret |
| |
| %elifdef X86_32 |
| |
| WELS_EXTERN WelsCPUId |
| push ebx |
| push edi |
| |
| mov eax, [esp+12] ; operating index |
| mov edi, [esp+24] |
| mov ecx, [edi] |
| cpuid ; cpuid |
| |
| ; processing various information return |
| mov edi, [esp+16] |
| mov [edi], eax |
| mov edi, [esp+20] |
| mov [edi], ebx |
| mov edi, [esp+24] |
| mov [edi], ecx |
| mov edi, [esp+28] |
| mov [edi], edx |
| |
| pop edi |
| pop ebx |
| ret |
| |
| %endif |
| |
| ; need call after cpuid=1 and eax, ecx flag got then |
| ;**************************************************************************************************** |
| ; int32_t WelsCPUSupportAVX( uint32_t eax, uint32_t ecx ) |
| ;**************************************************************************************************** |
| WELS_EXTERN WelsCPUSupportAVX |
| %ifdef WIN64 |
| mov eax, ecx |
| mov ecx, edx |
| %elifdef UNIX64 |
| mov eax, edi |
| mov ecx, esi |
| %else |
| mov eax, [esp+4] |
| mov ecx, [esp+8] |
| %endif |
| |
| ; refer to detection of AVX addressed in INTEL AVX manual document |
| and ecx, 018000000H |
| cmp ecx, 018000000H ; check both OSXSAVE and AVX feature flags |
| jne avx_not_supported |
| ; processor supports AVX instructions and XGETBV is enabled by OS |
| mov ecx, 0 ; specify 0 for XFEATURE_ENABLED_MASK register |
| XGETBV ; result in EDX:EAX |
| and eax, 06H |
| cmp eax, 06H ; check OS has enabled both XMM and YMM state support |
| jne avx_not_supported |
| mov eax, 1 |
| ret |
| avx_not_supported: |
| mov eax, 0 |
| ret |
| |
| |
| ; need call after cpuid=1 and eax, ecx flag got then |
| ;**************************************************************************************************** |
| ; int32_t WelsCPUSupportFMA( uint32_t eax, uint32_t ecx ) |
| ;**************************************************************************************************** |
| WELS_EXTERN WelsCPUSupportFMA |
| %ifdef WIN64 |
| mov eax, ecx |
| mov ecx, edx |
| %elifdef UNIX64 |
| mov eax, edi |
| mov ecx, esi |
| %else |
| mov eax, [esp+4] |
| mov ecx, [esp+8] |
| %endif |
| ; refer to detection of FMA addressed in INTEL AVX manual document |
| and ecx, 018001000H |
| cmp ecx, 018001000H ; check OSXSAVE, AVX, FMA feature flags |
| jne fma_not_supported |
| ; processor supports AVX,FMA instructions and XGETBV is enabled by OS |
| mov ecx, 0 ; specify 0 for XFEATURE_ENABLED_MASK register |
| XGETBV ; result in EDX:EAX |
| and eax, 06H |
| cmp eax, 06H ; check OS has enabled both XMM and YMM state support |
| jne fma_not_supported |
| mov eax, 1 |
| ret |
| fma_not_supported: |
| mov eax, 0 |
| ret |
| |
| ;****************************************************************************************** |
| ; void WelsEmms() |
| ;****************************************************************************************** |
| WELS_EXTERN WelsEmms |
| emms ; empty mmx technology states |
| ret |
| |
| ;***************************************************************************** |
| ; int32_t WelsCPUDetectAVX512() |
| ;***************************************************************************** |
| WELS_EXTERN WelsCPUDetectAVX512 |
| %ifdef X86_32 |
| push ebx |
| %else |
| push rbx |
| %endif |
| |
| mov eax, 1 |
| mov ecx, 0 |
| cpuid |
| and ecx, 0x08000000 |
| cmp ecx, 0x08000000 ; check CPUID.1:ECX.OSXSAVE[bit 27] |
| jne avx512_not_supported |
| |
| ; check XMM/YMM/zmm/opmask state |
| mov ecx, 0 |
| XGETBV ; result in EDX:EAX |
| and eax, 0x0D6 |
| cmp eax, 0x0D6 |
| jne avx512_not_supported |
| |
| ; check AVX512 flag CPUID.7:EBX.AVX512F[bit 16] |
| ; EBX[bit 16]: AVX512F |
| ; EBX[bit 28]: AVX512CD |
| ; EBX[bit 17]: AVX512DQ |
| ; EBX[bit 30]: AVX512BW |
| ; EBX[bit 31]: AVX512VL |
| mov eax, 7 |
| cpuid |
| and ebx, 0xC0030000 |
| mov eax, ebx |
| |
| %ifdef X86_32 |
| pop ebx |
| %else |
| pop rbx |
| %endif |
| ret |
| |
| avx512_not_supported: |
| mov eax, 0 |
| %ifdef X86_32 |
| pop ebx |
| %else |
| pop rbx |
| %endif |
| ret |
| |