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-2010 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,
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        cpuid
85        movl    12(%ebp), %esi
86        testl   %esi, %esi
87        jz      1f
88        movl    %eax, (%esi)
89    1:
90        movl    16(%ebp), %esi
91        testl   %esi, %esi
92        jz      2f
93        movl    %ebx, (%esi)
94    2:
95        movl    20(%ebp), %esi
96        testl   %esi, %esi
97        jz      3f
98        movl    %ecx, (%esi)
99    3:
100        movl    24(%ebp), %esi
101        testl   %esi, %esi
102        jz      4f
103        movl    %edx, (%esi)
104    4:
105        popl    %esi
106        popl    %edx
107        popl    %ecx
108        popl    %ebx
109        popl    %eax
110        movl    %ebp, %esp
111        popl    %ebp
112        ret
113#elif defined(VGA_amd64)
114.text
115.globl VG_(cpuid)
116    VG_(cpuid):
117        pushq   %rbp
118        movq    %rsp, %rbp
119        pushq   %rbx
120        movl    %edi, %eax
121        movq    %rdx, %rdi
122        movq    %rcx, %r9
123        /*
124           eax_ret now in %rsi
125           ebx_ret now in %rdi
126           ecx_ret now in %r9
127           edx_ret now in %r8
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   %r9, %r9
139        jz      3f
140        movl    %ecx, (%r9)
141    3:
142        testq   %r8, %r8
143        jz      4f
144        movl    %edx, (%r8)
145    4:
146        popq    %rbx
147        movq    %rbp, %rsp
148        popq    %rbp
149        ret
150#endif
151
152#if defined(VGP_x86_linux) || defined(VGP_amd64_linux)
153/* Let the linker know we don't need an executable stack */
154.section .note.GNU-stack,"",@progbits
155#endif
156
157/*--------------------------------------------------------------------*/
158/*--- end                                                          ---*/
159/*--------------------------------------------------------------------*/
160