]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Added VG_(cpuid) to replace the various bits of inline assembler used
authorTom Hughes <tom@compton.nu>
Wed, 16 Jun 2004 20:51:45 +0000 (20:51 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 16 Jun 2004 20:51:45 +0000 (20:51 +0000)
to query the CPU characteristics as the use of four implicit registers
causes havoc when GCC tries to inline and optimise the assembler.

Fix to bug #79696.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2421

cachegrind/cg_main.c
coregrind/Makefile.am
coregrind/vg_cpuid.S [new file with mode: 0644]
coregrind/vg_to_ucode.c
include/vg_skin.h.base

index a0641dd4cc27c5433d73926fa540f8f203051d77..8d72ff42f4784d1370695c5f43b823c8565a2735 100644 (file)
@@ -1177,15 +1177,6 @@ static cache_t clo_L2_cache = UNDEFINED_CACHE;
  * them. 
  */
 
-static __inline__ void cpuid(Int n, UInt *a, UInt *b, UInt *c, UInt *d)
-{
-   __asm__ __volatile__ (
-    "cpuid"
-    : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)      /* output */
-    : "0" (n)         /* input */
-    );
-}
-
 static void micro_ops_warn(Int actual_size, Int used_size, Int line_size)
 {
     VG_(message)(Vg_DebugMsg, 
@@ -1214,8 +1205,8 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
       return -1;
    }
 
-   cpuid(2, (Int*)&info[0], (Int*)&info[4], 
-            (Int*)&info[8], (Int*)&info[12]);
+   VG_(cpuid)(2, (Int*)&info[0], (Int*)&info[4], 
+                 (Int*)&info[8], (Int*)&info[12]);
    trials  = info[0] - 1;   /* AL register - bits 0..7 of %eax */
    info[0] = 0x0;           /* reset AL */
 
@@ -1358,10 +1349,10 @@ static
 Int AMD_cache_info(cache_t* I1c, cache_t* D1c, cache_t* L2c)
 {
    UInt ext_level;
-   Int dummy, model;
-   Int I1i, D1i, L2i;
+   UInt dummy, model;
+   UInt I1i, D1i, L2i;
    
-   cpuid(0x80000000, &ext_level, &dummy, &dummy, &dummy);
+   VG_(cpuid)(0x80000000, &ext_level, &dummy, &dummy, &dummy);
 
    if (0 == (ext_level & 0x80000000) || ext_level < 0x80000006) {
       VG_(message)(Vg_UserMsg, 
@@ -1370,10 +1361,10 @@ Int AMD_cache_info(cache_t* I1c, cache_t* D1c, cache_t* L2c)
       return -1;
    }
 
-   cpuid(0x80000005, &dummy, &dummy, &D1i, &I1i);
-   cpuid(0x80000006, &dummy, &dummy, &L2i, &dummy);
+   VG_(cpuid)(0x80000005, &dummy, &dummy, &D1i, &I1i);
+   VG_(cpuid)(0x80000006, &dummy, &dummy, &L2i, &dummy);
 
-   cpuid(0x1, &model, &dummy, &dummy, &dummy);
+   VG_(cpuid)(0x1, &model, &dummy, &dummy, &dummy);
    /*VG_(message)(Vg_UserMsg,"CPU model %04x",model);*/
 
    /* Check for Duron bug */
@@ -1426,8 +1417,8 @@ Int get_caches_from_CPUID(cache_t* I1c, cache_t* D1c, cache_t* L2c)
    /* Trap for illegal instruction, in case it's a really old processor that
     * doesn't support CPUID. */
    if (__builtin_setjmp(cpuid_jmpbuf) == 0) {
-      cpuid(0, &level, (int*)&vendor_id[0], 
-                       (int*)&vendor_id[8], (int*)&vendor_id[4]);    
+      VG_(cpuid)(0, &level, (int*)&vendor_id[0], 
+                            (int*)&vendor_id[8], (int*)&vendor_id[4]);    
       vendor_id[12] = '\0';
 
       /* Restore old SIGILL handler */
index 720cc4a5dc1e85d11443d79131e2e64586febad4..fcd1f8803b669ede6fb757f5e9df048d9d6442b8 100644 (file)
@@ -75,7 +75,8 @@ stage2_SOURCES = \
        vg_toolint.c \
        vg_translate.c \
        vg_transtab.c \
-       vg_ldt.c
+       vg_ldt.c \
+       vg_cpuid.S
 stage2_DEPENDENCIES = $(srcdir)/valgrind.vs x86/stage2.lds
 stage2_LDFLAGS=-Wl,--export-dynamic -Wl,-e,_ume_entry  -g \
        -Wl,-defsym,kickstart_base=0xb8000000 \
diff --git a/coregrind/vg_cpuid.S b/coregrind/vg_cpuid.S
new file mode 100644 (file)
index 0000000..a5386f9
--- /dev/null
@@ -0,0 +1,77 @@
+
+##--------------------------------------------------------------------##
+##--- Support for determining CPU characteristics.                 ---##
+##---                                                   vg_cpuid.S ---##
+##--------------------------------------------------------------------##
+
+/*
+  This file is part of Valgrind, an extensible x86 protected-mode
+  emulator for monitoring program execution on x86-Unixes.
+
+  Copyright (C) 2000-2004 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 "vg_constants.h"
+#include "vg_unistd.h"
+
+/*
+    int VG_(cpuid)(UInt eax,
+                   UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret)
+ */
+.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
index c55282c989db9a34a6f32f8d862bbb4ef62f2c5d..4a0e3cff48addbb6c376fd27ba3b2629912d2e5d 100644 (file)
@@ -95,29 +95,6 @@ static Bool has_cpuid(void)
    return flag_is_changeable(EFlagID);
 }
 
-static inline UInt cpuid_eax(UInt eax)
-{
-   asm("cpuid" : "=a" (eax) : "0" (eax) : "bx", "cx", "dx");
-   return eax;
-}
-
-static inline void cpuid(UInt eax, 
-                        UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret)
-{
-   UInt ebx, ecx, edx;
-
-   asm("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) : "0" (eax));
-
-   if (eax_ret)
-      *eax_ret = eax;
-   if (ebx_ret)
-      *ebx_ret = ebx;
-   if (ecx_ret)
-      *ecx_ret = ecx;
-   if (edx_ret)
-      *edx_ret = edx;
-}
-
 static void get_cpu_features(void)
 {
    Char vendorstr[13];
@@ -130,7 +107,7 @@ static void get_cpu_features(void)
 
    cpu_features[VG_INT_FEAT] |= (1 << (VG_X86_FEAT_CPUID%32));
 
-   cpuid(0, &cpuid_level, (UInt *)&vendorstr[0], (UInt *)&vendorstr[8], (UInt *)&vendorstr[4]);
+   VG_(cpuid)(0, &cpuid_level, (UInt *)&vendorstr[0], (UInt *)&vendorstr[8], (UInt *)&vendorstr[4]);
    vendorstr[12] = '\0';
 
    for(i = 0; i < sizeof(cpu_vendors)/sizeof(*cpu_vendors); i++)
@@ -140,12 +117,12 @@ static void get_cpu_features(void)
       }
 
    if (cpuid_level >= 1)
-      cpuid(1, NULL, NULL, &cpu_features[VG_EXT_FEAT], &cpu_features[VG_X86_FEAT]);
+      VG_(cpuid)(1, NULL, NULL, &cpu_features[VG_EXT_FEAT], &cpu_features[VG_X86_FEAT]);
 
    switch(cpu_vendor) {
    case VG_CPU_VENDOR_AMD:
       /* get AMD-specific flags */
-      cpuid(0x80000001, NULL, NULL, NULL, &cpu_features[VG_AMD_FEAT]);
+      VG_(cpuid)(0x80000001, NULL, NULL, NULL, &cpu_features[VG_AMD_FEAT]);
       break;
 
    default:
@@ -259,7 +236,7 @@ void VG_(helperc_CPUID)(UInt op, UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UI
    if (cpuid_level == -2)
       get_cpu_features();      /* for cpu_vendor */
 
-   cpuid(op, &eax, &ebx, &ecx, &edx);
+   VG_(cpuid)(op, &eax, &ebx, &ecx, &edx);
 
    /* Common mangling */
    switch(op) {
index 2a682996f4a3fd7e02316da5d3465185862b1d5e..71bca4a47cec145a2aaa12600fadfa93eb0a7a73 100644 (file)
@@ -585,6 +585,10 @@ extern Int VG_(getsockopt) ( Int sd, Int level, Int optname, void *optval,
 /* other, randomly useful functions */
 extern UInt VG_(read_millisecond_timer) ( void );
 
+extern void VG_(cpuid) ( UInt eax,
+                         UInt *eax_ret, UInt *ebx_ret,
+                         UInt *ecx_ret, UInt *edx_ret );
+
 /*====================================================================*/
 /*=== UCode definition                                             ===*/
 /*====================================================================*/