drd/drd_pthread_intercepts: Add a workaround for what is probably a compiler bug
[valgrind.git] / coregrind / m_cpuid.S
blob4885e2e20a730f5336180cc5da7764ebebc11dff
2 /*--------------------------------------------------------------------*/
3 /*--- CPUID interface.                                   m_cpuid.S ---*/
4 /*--------------------------------------------------------------------*/
6 /*
7   This file is part of Valgrind, a dynamic binary instrumentation
8   framework.
10   Copyright (C) 2000-2017 Julian Seward 
11      jseward@acm.org
13   This program is free software; you can redistribute it and/or
14   modify it under the terms of the GNU General Public License as
15   published by the Free Software Foundation; either version 2 of the
16   License, or (at your option) any later version.
18   This program is distributed in the hope that it will be useful, but
19   WITHOUT ANY WARRANTY; without even the implied warranty of
20   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21   General Public License for more details.
23   You should have received a copy of the GNU General Public License
24   along with this program; if not, see <http://www.gnu.org/licenses/>.
26   The GNU General Public License is contained in the file COPYING.
29 #include "pub_core_basics_asm.h"
32     Bool VG_(has_cpuid)(void)
33  */
34 #if defined(VGA_x86)
35 .text
36 .globl VG_(has_cpuid)
37     VG_(has_cpuid):
38         pushl   %ebp
39         movl    %esp, %ebp
40         pushl   %ecx
41         pushfl
42         pushfl
43         popl    %eax
44         movl    %eax, %ecx
45         xorl    $0x200000, %eax
46         pushl   %eax
47         popfl
48         pushfl
49         popl    %eax
50         popfl
51         xorl    %ecx, %eax
52         andl    $0x200000, %eax
53         shrl    $21, %eax
54         popl    %ecx
55         movl    %ebp, %esp
56         popl    %ebp
57         ret
58 #elif defined(VGA_amd64)
59 .text
60 .globl VG_(has_cpuid)
61     VG_(has_cpuid):
62         movq    $1, %rax
63         ret
64 #endif
67     void VG_(cpuid)(UInt eax, UInt ecx,
68                     UInt* eax_ret, UInt* ebx_ret, UInt* ecx_ret, UInt* edx_ret)
69  */
70 #if defined(VGA_x86)
71 .text
72 .globl VG_(cpuid)
73     VG_(cpuid):
74         pushl   %ebp
75         movl    %esp, %ebp
76         pushl   %eax
77         pushl   %ebx
78         pushl   %ecx
79         pushl   %edx
80         pushl   %esi
81         movl    8(%ebp), %eax
82         movl    12(%ebp), %ecx
83         cpuid
84         movl    16(%ebp), %esi
85         testl   %esi, %esi
86         jz      1f
87         movl    %eax, (%esi)
88     1:
89         movl    20(%ebp), %esi
90         testl   %esi, %esi
91         jz      2f
92         movl    %ebx, (%esi)
93     2:
94         movl    24(%ebp), %esi
95         testl   %esi, %esi
96         jz      3f
97         movl    %ecx, (%esi)
98     3:
99         movl    28(%ebp), %esi
100         testl   %esi, %esi
101         jz      4f
102         movl    %edx, (%esi)
103     4:
104         popl    %esi
105         popl    %edx
106         popl    %ecx
107         popl    %ebx
108         popl    %eax
109         movl    %ebp, %esp
110         popl    %ebp
111         ret
112 #elif defined(VGA_amd64)
113 .text
114 .globl VG_(cpuid)
115     VG_(cpuid):
116         pushq   %rbp
117         movq    %rsp, %rbp
118         pushq   %rbx
119         movl    %edi, %eax
120         movq    %rcx, %rdi
121         movl    %esi, %ecx
122         movq    %rdx, %rsi
123         /*
124            eax_ret now in %rsi
125            ebx_ret now in %rdi
126            ecx_ret now in %r8
127            edx_ret now in %r9
128          */
129         cpuid
130         testq   %rsi, %rsi
131         jz      1f
132         movl    %eax, (%rsi)
133     1:
134         testq   %rdi, %rdi
135         jz      2f
136         movl    %ebx, (%rdi)
137     2:
138         testq   %r8, %r8
139         jz      3f
140         movl    %ecx, (%r8)
141     3:
142         testq   %r9, %r9
143         jz      4f
144         movl    %edx, (%r9)
145     4:
146         popq    %rbx
147         movq    %rbp, %rsp
148         popq    %rbp
149         ret
150 #endif
152 /* Let the linker know we don't need an executable stack */
153 MARK_STACK_NO_EXEC
155 /*--------------------------------------------------------------------*/
156 /*--- end                                                          ---*/
157 /*--------------------------------------------------------------------*/