Home | History | Annotate | Download | only in coregrind
      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-2017 Julian Seward
     11      jseward (at) 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 /* Let the linker know we don't need an executable stack */
    155 MARK_STACK_NO_EXEC
    156 
    157 /*--------------------------------------------------------------------*/
    158 /*--- end                                                          ---*/
    159 /*--------------------------------------------------------------------*/
    160