]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make Valgrind work again on x86 CPUs which don't have SSE. This is a
authorJulian Seward <jseward@acm.org>
Mon, 8 Aug 2005 00:35:46 +0000 (00:35 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 8 Aug 2005 00:35:46 +0000 (00:35 +0000)
bit of an ugly hack (see comments in m_machine.c) which is suitable
for merging into 3_0_BRANCH, but should be cleaned up once that's
done.

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

coregrind/m_dispatch/dispatch-x86.S
coregrind/m_machine.c
coregrind/m_translate.c
coregrind/pub_core_machine.h

index 6d20d4c36c3eab1985ae3add6f9e46b834867f03..5b751c8ebd05fb7b8ec089d0c1beba64100250e4 100644 (file)
@@ -71,10 +71,12 @@ VG_(run_innerloop):
        
        /* set host SSE control word to the default mode expected 
           by VEX-generated code. */
+       cmpl    $0, VG_(have_mxcsr_x86)
+       jz      L1
        pushl   $0x1F80
        ldmxcsr (%esp)
        addl    $4, %esp
-
+L1:
        /* set dir flag to known value */
        cld
        
@@ -136,13 +138,15 @@ run_innerloop_exit:
        cmpl    $0x027F, (%esp)
        popl    %esi /* get rid of the word without trashing %eflags */
        jnz     invariant_violation
+       cmpl    $0, VG_(have_mxcsr_x86)
+       jz      L2
        pushl   $0
        stmxcsr (%esp)
        andl    $0xFFFFFFC0, (%esp)  /* mask out status flags */
        cmpl    $0x1F80, (%esp)
        popl    %esi
        jnz     invariant_violation
-       /* otherwise we're OK */
+L2:    /* otherwise we're OK */
        jmp     run_innerloop_exit_REALLY
 
 invariant_violation:
index e3be88f8cf1ac6ecfd12fd17f13187b141bcc50f..43ed1e2dc8169bd72e32cde9d66ae50c58ccb90e 100644 (file)
@@ -196,16 +196,36 @@ ThreadId VG_(first_matching_thread_stack)
    return VG_INVALID_THREADID;
 }
 
+
 //////////////////////////////////////////////////////////////////
 // Architecture specifics
 
-// PPC: what is the cache line size (for dcbz etc) ?
-// This info is harvested on Linux at startup from the AT_SYSINFO
-// entries.  0 means not-yet-set.
+// PPC: what is the cache line size (for dcbz etc) ?  This info is
+// harvested on Linux at startup from the AT_SYSINFO entries.  0 means
+// not-yet-set.
 #if defined(VGA_ppc32)
 Int VG_(cache_line_size_ppc32) = 0;
 #endif
 
+// X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store
+// the SSE control/status register.  For most modern CPUs this will be
+// 1.  It is set to 1, if possible, by m_translate.getArchAndArchInfo.
+// The value is read by m_dispatch.dispatch-x86.S, which is why it
+// is an Int rather than a Bool.
+//
+// Ugly hack: this has to start as 0 and be set to 1 in the normal
+// case, rather than the other way round, because the dispatch
+// loop needs it, and it runs before the first translation is 
+// made.  Yet it is the act of making that first translation which
+// causes getArchAndArchInfo to set this value to its final value.
+// So it is necessary to start this value off at 0 as only that
+// guarantees that the dispatch loop will not SIGILL on its first
+// attempt.
+#if defined(VGA_x86)
+Int VG_(have_mxcsr_x86) = 0;
+#endif
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index dbebb6471254ebbcf3e8591773969dc7ccad9b74..2e0e028bf78d7919215f4da4fa2577d6767e9755 100644 (file)
@@ -35,6 +35,7 @@
 #include "pub_core_cpuid.h"
 #include "pub_core_machine.h"       // For VG_(cache_line_size_ppc32)
                                     // and VG_(get_SP)
+                                    // and VG_(have_mxcsr_x86)
 #include "pub_core_libcbase.h"
 #include "pub_core_libcassert.h"
 #include "pub_core_libcprint.h"
@@ -53,7 +54,7 @@
 /*------------------------------------------------------------*/
 
 // Returns the architecture and auxiliary information, or indicates
-// that this subarchitecture is unable to run Valgrind Returns False
+// that this subarchitecture is unable to run Valgrind Returns False
 // to indicate we cannot proceed further.
 
 static Bool getArchAndArchInfo( /*OUT*/VexArch*     vex_arch, 
@@ -64,7 +65,7 @@ static Bool getArchAndArchInfo( /*OUT*/VexArch*     vex_arch,
    LibVEX_default_VexArchInfo(vai);
 
 #if defined(VGA_x86)
-   Bool have_sse0, have_sse1, have_sse2;
+   Bool have_sse1, have_sse2;
    UInt eax, ebx, ecx, edx;
 
    if (!VG_(has_cpuid)())
@@ -79,31 +80,30 @@ static Bool getArchAndArchInfo( /*OUT*/VexArch*     vex_arch,
    /* get capabilities bits into edx */
    VG_(cpuid)(1, &eax, &ebx, &ecx, &edx);
 
-   have_sse0 = (edx & (1<<24)) != 0; /* True => have fxsave/fxrstor */
    have_sse1 = (edx & (1<<25)) != 0; /* True => have sse insns */
    have_sse2 = (edx & (1<<26)) != 0; /* True => have sse2 insns */
 
-   if (have_sse2 && have_sse1 && have_sse0) {
+   VG_(have_mxcsr_x86) = 1;
+
+   if (have_sse2 && have_sse1) {
       *vex_arch    = VexArchX86;
       vai->subarch = VexSubArchX86_sse2;
       return True;
    }
 
-   if (have_sse1 && have_sse0) {
+   if (have_sse1) {
       *vex_arch    = VexArchX86;
       vai->subarch = VexSubArchX86_sse1;
       return True;
    }
 
-   if (have_sse0) {
+   {
       *vex_arch    = VexArchX86;
       vai->subarch = VexSubArchX86_sse0;
+      VG_(have_mxcsr_x86) = 0;
       return True;
    }
 
-   /* we need at least SSE state to operate. */
-   return False;
-
 #elif defined(VGA_amd64)
    vg_assert(VG_(has_cpuid)());
    *vex_arch    = VexArchAMD64;
@@ -459,7 +459,7 @@ Bool VG_(translate) ( ThreadId tid,
          VG_(printf)("\n");
          VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
          VG_(printf)("   Supported CPUs are:\n");
-         VG_(printf)("   * x86 with SSE (Pentium III or above, "
+         VG_(printf)("   * x86 (practically any; Pentium-I or above), "
                      "AMD Athlon or above)\n");
          VG_(printf)("   * AMD Athlon64/Opteron\n");
          VG_(printf)("   * PowerPC with Altivec\n");
index 8b9cdba27f2392f0b49cc981fd2343f57982cf32..ed448814dab8176b930a4e282a001470a8b37c75 100644 (file)
 #  error Unknown arch
 #endif
 
+
 // Offsets for the Vex state
 #define VG_O_STACK_PTR        (offsetof(VexGuestArchState, VG_STACK_PTR))
 
+
 // Architecture specifics
 
 // PPC: what is the cache line size (for dcbz etc) ?
 extern Int VG_(cache_line_size_ppc32);
 #endif
 
+// X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store
+// the SSE control/status register. 
+#if defined(VGA_x86)
+extern Int VG_(have_mxcsr_x86);
+#endif
+
+
 #endif   // __PUB_CORE_MACHINE_H
 
 /*--------------------------------------------------------------------*/