1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2019-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 #pragma once
10 
11 #include "types.h"
12 #include "utility.h"
13 #include "UFO/portable_cpuid.h"
14 
15 
16 namespace iSTD
17 {
18 /*****************************************************************************\
19 ENUM: CPU_INSTRUCTION_LEVEL
20 \*****************************************************************************/
21 enum CPU_INSTRUCTION_LEVEL
22 {
23     CPU_INSTRUCTION_LEVEL_UNKNOWN,
24     CPU_INSTRUCTION_LEVEL_MMX,
25     CPU_INSTRUCTION_LEVEL_SSE,
26     CPU_INSTRUCTION_LEVEL_SSE2,
27     CPU_INSTRUCTION_LEVEL_SSE3,
28     CPU_INSTRUCTION_LEVEL_SSE4,
29     CPU_INSTRUCTION_LEVEL_SSE4_1,
30     NUM_CPU_INSTRUCTION_LEVELS
31 };
32 
33 
34 /*****************************************************************************\
35 Inline Function:
36     GetCpuInstructionLevel
37 
38 Description:
39     Returns the highest level of IA32 intruction extensions supported by the CPU
40     ( i.e. SSE, SSE2, SSE4, etc )
41 
42 Output:
43     CPU_INSTRUCTION_LEVEL - highest level of IA32 instruction extension(s) supported
44     by CPU
45 
46 Notes:
47     See Table 3-20 Vol2A SW Dev Manual for bit-field numbering
48 \*****************************************************************************/
GetCpuInstructionLevel(void)49 inline CPU_INSTRUCTION_LEVEL GetCpuInstructionLevel( void )
50 {
51 #if defined(ANDROID) && defined(__SSE4_1__)
52     return CPU_INSTRUCTION_LEVEL_SSE4_1;
53 #else
54     int CPUInfo[4] = { 0, 0, 0, 0 };
55 
56     __cpuid(CPUInfo, 1);
57 
58     CPU_INSTRUCTION_LEVEL CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_UNKNOWN;
59     if( CPUInfo[2] & BIT(19) )
60     {
61         CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_SSE4_1;
62     }
63     else if( CPUInfo[2] & BIT(0) )
64     {
65         CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_SSE3;
66     }
67     else if( CPUInfo[3] & BIT(26) )
68     {
69         CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_SSE2;
70     }
71     else if( CPUInfo[3] & BIT(25) )
72     {
73         CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_SSE;
74     }
75     else if( CPUInfo[3] & BIT(23) )
76     {
77         CpuInstructionLevel = CPU_INSTRUCTION_LEVEL_MMX;
78     }
79 
80     return CpuInstructionLevel;
81 #endif
82 }
83 
84 }//namespace iSTD
85