aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/X86/HardwareCapabilities.cs
blob: 7f930d6b9c8ac53bcb655a2600f6e0cd7ac9c3fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;

namespace ARMeilleure.CodeGen.X86
{
    static class HardwareCapabilities
    {
        private delegate ulong GetFeatureInfo();

        private static ulong _featureInfo;

        public static bool SupportsSse3      => (_featureInfo & (1UL << 0))  != 0;
        public static bool SupportsPclmulqdq => (_featureInfo & (1UL << 1))  != 0;
        public static bool SupportsSsse3     => (_featureInfo & (1UL << 9))  != 0;
        public static bool SupportsFma       => (_featureInfo & (1UL << 12)) != 0;
        public static bool SupportsCx16      => (_featureInfo & (1UL << 13)) != 0;
        public static bool SupportsSse41     => (_featureInfo & (1UL << 19)) != 0;
        public static bool SupportsSse42     => (_featureInfo & (1UL << 20)) != 0;
        public static bool SupportsPopcnt    => (_featureInfo & (1UL << 23)) != 0;
        public static bool SupportsAesni     => (_featureInfo & (1UL << 25)) != 0;
        public static bool SupportsAvx       => (_featureInfo & (1UL << 28)) != 0;
        public static bool SupportsF16c      => (_featureInfo & (1UL << 29)) != 0;

        public static bool SupportsSse  => (_featureInfo & (1UL << 32 + 25)) != 0;
        public static bool SupportsSse2 => (_featureInfo & (1UL << 32 + 26)) != 0;

        public static bool ForceLegacySse { get; set; }

        public static bool SupportsVexEncoding => !ForceLegacySse && SupportsAvx;

        static HardwareCapabilities()
        {
            EmitterContext context = new EmitterContext();

            Operand featureInfo = context.CpuId();

            context.Return(featureInfo);

            ControlFlowGraph cfg = context.GetControlFlowGraph();

            OperandType[] argTypes = new OperandType[0];

            GetFeatureInfo getFeatureInfo = Compiler.Compile<GetFeatureInfo>(
                cfg,
                argTypes,
                OperandType.I64,
                CompilerOptions.HighCq);

            _featureInfo = getFeatureInfo();
        }
    }
}