少年修仙传客户端基础资源
hch
2024-04-01 d01413b00ef631ac20347716b23818b0b811f65f
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
 * \file
 * x86 hardware feature detection
 *
 * Authors:
 *    Alex Rønne Petersen (alexrp@xamarin.com)
 *    Elijah Taylor (elijahtaylor@google.com)
 *    Miguel de Icaza (miguel@xamarin.com)
 *    Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
 *    Paolo Molaro (lupus@xamarin.com)
 *    Rodrigo Kumpera (kumpera@gmail.com)
 *    Sebastien Pouliot (sebastien@xamarin.com)
 *    Zoltan Varga (vargaz@xamarin.com)
 *
 * Copyright 2003 Ximian, Inc.
 * Copyright 2003-2011 Novell, Inc
 * Copyright 2006 Broadcom
 * Copyright 2007-2008 Andreas Faerber
 * Copyright 2011-2013 Xamarin Inc
 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
 */
 
#include "mono/utils/mono-hwcap.h"
 
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#if defined(_MSC_VER)
#include <intrin.h>
#endif
 
static gboolean
cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx)
{
#if defined(_MSC_VER)
    int info [4];
#endif
 
    /* First, make sure we can use cpuid if we're on 32-bit. */
#if defined(TARGET_X86)
    gboolean have_cpuid = FALSE;
 
#if defined(_MSC_VER)
    __asm {
        pushfd
        pop eax
        mov edx, eax
        xor eax, 0x200000
        push eax
        popfd
        pushfd
        pop eax
        xor eax, edx
        and eax, 0x200000
        mov have_cpuid, eax
    }
#else
    __asm__ __volatile__ (
        "pushfl\n\t"
        "popl\t%%eax\n\t"
        "movl\t%%eax, %%edx\n\t"
        "xorl\t$0x200000, %%eax\n\t"
        "pushl\t%%eax\n\t"
        "popfl\n\t"
        "pushfl\n\t"
        "popl\t%%eax\n\t"
        "xorl\t%%edx, %%eax\n\t"
        "andl\t$0x200000, %%eax\n\t"
        "movl\t%%eax, %0\n\t"
        : "=r" (have_cpuid)
        :
        : "%eax", "%edx"
    );
#endif
 
    if (!have_cpuid)
        return FALSE;
#endif
 
    /* Now issue the actual cpuid instruction. We can use
       MSVC's __cpuid on both 32-bit and 64-bit. */
#if defined(_MSC_VER)
    __cpuid (info, id);
    *p_eax = info [0];
    *p_ebx = info [1];
    *p_ecx = info [2];
    *p_edx = info [3];
#elif defined(TARGET_X86)
    /* This complicated stuff is necessary because EBX
       may be used by the compiler in PIC mode. */
    __asm__ __volatile__ (
        "xchgl\t%%ebx, %k1\n\t"
        "cpuid\n\t"
        "xchgl\t%%ebx, %k1\n\t"
        : "=a" (*p_eax), "=&r" (*p_ebx), "=c" (*p_ecx), "=d" (*p_edx)
        : "0" (id)
    );
#else
    __asm__ __volatile__ (
        "cpuid\n\t"
        : "=a" (*p_eax), "=b" (*p_ebx), "=c" (*p_ecx), "=d" (*p_edx)
        : "a" (id)
    );
#endif
 
    return TRUE;
}
 
void
mono_hwcap_arch_init (void)
{
    int eax, ebx, ecx, edx;
 
    if (cpuid (1, &eax, &ebx, &ecx, &edx)) {
        if (edx & (1 << 15)) {
            mono_hwcap_x86_has_cmov = TRUE;
 
            if (edx & 1)
                mono_hwcap_x86_has_fcmov = TRUE;
        }
 
        if (edx & (1 << 25))
            mono_hwcap_x86_has_sse1 = TRUE;
 
        if (edx & (1 << 26))
            mono_hwcap_x86_has_sse2 = TRUE;
 
        if (ecx & (1 << 0))
            mono_hwcap_x86_has_sse3 = TRUE;
 
        if (ecx & (1 << 9))
            mono_hwcap_x86_has_ssse3 = TRUE;
 
        if (ecx & (1 << 19))
            mono_hwcap_x86_has_sse41 = TRUE;
 
        if (ecx & (1 << 20))
            mono_hwcap_x86_has_sse42 = TRUE;
    }
 
    if (cpuid (0x80000000, &eax, &ebx, &ecx, &edx)) {
        if ((unsigned int) eax >= 0x80000001 && ebx == 0x68747541 && ecx == 0x444D4163 && edx == 0x69746E65) {
            if (cpuid (0x80000001, &eax, &ebx, &ecx, &edx)) {
                if (ecx & (1 << 6))
                    mono_hwcap_x86_has_sse4a = TRUE;
            }
        }
    }
 
#if defined(HAVE_UNISTD_H) && !defined(NO_HAVE_ACCESS)
    mono_hwcap_x86_is_xen = !access ("/proc/xen", F_OK);
#endif
}