1
2/*--------------------------------------------------------------------*/
3/*--- CPUID interface.                                   m_cpuid.S ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7  This file is part of Valgrind, a dynamic binary instrumentation
8  framework.
9
10  Copyright (C) 2000-2013 Julian Seward
11     jseward@acm.org
12
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.
17
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.
22
23  You should have received a copy of the GNU General Public License
24  along with this program; if not, write to the Free Software
25  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26  02111-1307, USA.
27
28  The GNU General Public License is contained in the file COPYING.
29*/
30
31#include "pub_core_basics_asm.h"
32
33/*
34    Bool VG_(has_cpuid)(void)
35 */
36#if defined(VGA_x86)
37.text
38.globl VG_(has_cpuid)
39    VG_(has_cpuid):
40        pushl   %ebp
41        movl    %esp, %ebp
42        pushl   %ecx
43        pushfl
44        pushfl
45        popl    %eax
46        movl    %eax, %ecx
47        xorl    $0x200000, %eax
48        pushl   %eax
49        popfl
50        pushfl
51        popl    %eax
52        popfl
53        xorl    %ecx, %eax
54        andl    $0x200000, %eax
55        shrl    $21, %eax
56        popl    %ecx
57        movl    %ebp, %esp
58        popl    %ebp
59        ret
60#elif defined(VGA_amd64)
61.text
62.globl VG_(has_cpuid)
63    VG_(has_cpuid):
64        movq    $1, %rax
65        ret
66#endif
67
68/*
69    void VG_(cpuid)(UInt eax, UInt ecx,
70                    UInt* eax_ret, UInt* ebx_ret, UInt* ecx_ret, UInt* edx_ret)
71 */
72#if defined(VGA_x86)
73.text
74.globl VG_(cpuid)
75    VG_(cpuid):
76        pushl   %ebp
77        movl    %esp, %ebp
78        pushl   %eax
79        pushl   %ebx
80        pushl   %ecx
81        pushl   %edx
82        pushl   %esi
83        movl    8(%ebp), %eax
84        movl    12(%ebp), %ecx
85        cpuid
86        movl    16(%ebp), %esi
87        testl   %esi, %esi
88        jz      1f
89        movl    %eax, (%esi)
90    1:
91        movl    20(%ebp), %esi
92        testl   %esi, %esi
93        jz      2f
94        movl    %ebx, (%esi)
95    2:
96        movl    24(%ebp), %esi
97        testl   %esi, %esi
98        jz      3f
99        movl    %ecx, (%esi)
100    3:
101        movl    28(%ebp), %esi
102        testl   %esi, %esi
103        jz      4f
104        movl    %edx, (%esi)
105    4:
106        popl    %esi
107        popl    %edx
108        popl    %ecx
109        popl    %ebx
110        popl    %eax
111        movl    %ebp, %esp
112        popl    %ebp
113        ret
114#elif defined(VGA_amd64)
115.text
116.globl VG_(cpuid)
117    VG_(cpuid):
118        pushq   %rbp
119        movq    %rsp, %rbp
120        pushq   %rbx
121        movl    %edi, %eax
122        movq    %rcx, %rdi
123        movl    %esi, %ecx
124        movq    %rdx, %rsi
125        /*
126           eax_ret now in %rsi
127           ebx_ret now in %rdi
128           ecx_ret now in %r8
129           edx_ret now in %r9
130         */
131        cpuid
132        testq   %rsi, %rsi
133        jz      1f
134        movl    %eax, (%rsi)
135    1:
136        testq   %rdi, %rdi
137        jz      2f
138        movl    %ebx, (%rdi)
139    2:
140        testq   %r8, %r8
141        jz      3f
142        movl    %ecx, (%r8)
143    3:
144        testq   %r9, %r9
145        jz      4f
146        movl    %edx, (%r9)
147    4:
148        popq    %rbx
149        movq    %rbp, %rsp
150        popq    %rbp
151        ret
152#endif
153
154#if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
155/* Let the linker know we don't need an executable stack */
156.section .note.GNU-stack,"",@progbits
157#endif
158
159/*--------------------------------------------------------------------*/
160/*--- end                                                          ---*/
161/*--------------------------------------------------------------------*/
162