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
154
155
156
157
158
159
|
/*--------------------------------------------------------------------*/
/*--- CPUID interface. m_cpuid.S ---*/
/*--------------------------------------------------------------------*/
/*
This file is part of Valgrind, a dynamic binary instrumentation
framework.
Copyright (C) 2000-2010 Julian Seward
jseward@acm.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file COPYING.
*/
#include "pub_core_basics_asm.h"
/*
Bool VG_(has_cpuid)(void)
*/
#if defined(VGA_x86)
.text
.globl VG_(has_cpuid)
VG_(has_cpuid):
pushl %ebp
movl %esp, %ebp
pushl %ecx
pushfl
pushfl
popl %eax
movl %eax, %ecx
xorl $0x200000, %eax
pushl %eax
popfl
pushfl
popl %eax
popfl
xorl %ecx, %eax
andl $0x200000, %eax
shrl $21, %eax
popl %ecx
movl %ebp, %esp
popl %ebp
ret
#elif defined(VGA_amd64)
.text
.globl VG_(has_cpuid)
VG_(has_cpuid):
movq $1, %rax
ret
#endif
/*
void VG_(cpuid)(UInt eax,
UInt* eax_ret, UInt* ebx_ret, UInt* ecx_ret, UInt* edx_ret)
*/
#if defined(VGA_x86)
.text
.globl VG_(cpuid)
VG_(cpuid):
pushl %ebp
movl %esp, %ebp
pushl %eax
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
movl 8(%ebp), %eax
cpuid
movl 12(%ebp), %esi
testl %esi, %esi
jz 1f
movl %eax, (%esi)
1:
movl 16(%ebp), %esi
testl %esi, %esi
jz 2f
movl %ebx, (%esi)
2:
movl 20(%ebp), %esi
testl %esi, %esi
jz 3f
movl %ecx, (%esi)
3:
movl 24(%ebp), %esi
testl %esi, %esi
jz 4f
movl %edx, (%esi)
4:
popl %esi
popl %edx
popl %ecx
popl %ebx
popl %eax
movl %ebp, %esp
popl %ebp
ret
#elif defined(VGA_amd64)
.text
.globl VG_(cpuid)
VG_(cpuid):
pushq %rbp
movq %rsp, %rbp
pushq %rbx
movl %edi, %eax
movq %rdx, %rdi
movq %rcx, %r9
/*
eax_ret now in %rsi
ebx_ret now in %rdi
ecx_ret now in %r9
edx_ret now in %r8
*/
cpuid
testq %rsi, %rsi
jz 1f
movl %eax, (%rsi)
1:
testq %rdi, %rdi
jz 2f
movl %ebx, (%rdi)
2:
testq %r9, %r9
jz 3f
movl %ecx, (%r9)
3:
testq %r8, %r8
jz 4f
movl %edx, (%r8)
4:
popq %rbx
movq %rbp, %rsp
popq %rbp
ret
#endif
#if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
/* Let the linker know we don't need an executable stack */
.section .note.GNU-stack,"",@progbits
#endif
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
|