Blame SOURCES/valgrind-3.15.0-avx-rdrand-f16c.patch

88cf0f
commit 791fe5ecf909d573bcbf353b677b9404f9da0ed4
88cf0f
Author: Mark Wielaard <mark@klomp.org>
88cf0f
Date:   Mon May 27 22:19:27 2019 +0200
88cf0f
88cf0f
    Expose rdrand and f16c through cpuid also if the host only has avx.
88cf0f
    
88cf0f
    The amd64 CPUID dirtyhelpers are mostly static since they emulate some
88cf0f
    existing CPU "family". The avx2 ("i7-4910MQ") CPUID variant however
88cf0f
    can "dynamicly" enable rdrand and/or f16c if the host supports them.
88cf0f
    Do the same for the avx_and_cx16 ("i5-2300") CPUID variant.
88cf0f
    
88cf0f
    https://bugs.kde.org/show_bug.cgi?id=408009
88cf0f
88cf0f
diff --git a/VEX/priv/guest_amd64_defs.h b/VEX/priv/guest_amd64_defs.h
88cf0f
index 4f34b41..a5de527 100644
88cf0f
--- a/VEX/priv/guest_amd64_defs.h
88cf0f
+++ b/VEX/priv/guest_amd64_defs.h
88cf0f
@@ -165,7 +165,9 @@ extern void  amd64g_dirtyhelper_storeF80le ( Addr/*addr*/, ULong/*data*/ );
88cf0f
 extern void  amd64g_dirtyhelper_CPUID_baseline ( VexGuestAMD64State* st );
88cf0f
 extern void  amd64g_dirtyhelper_CPUID_sse3_and_cx16 ( VexGuestAMD64State* st );
88cf0f
 extern void  amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st );
88cf0f
-extern void  amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st );
88cf0f
+extern void  amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st,
88cf0f
+                                                     ULong hasF16C,
88cf0f
+                                                     ULong hasRDRAND );
88cf0f
 extern void  amd64g_dirtyhelper_CPUID_avx2 ( VexGuestAMD64State* st,
88cf0f
                                              ULong hasF16C, ULong hasRDRAND );
88cf0f
 
88cf0f
diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c
88cf0f
index e4cf7e2..182bae0 100644
88cf0f
--- a/VEX/priv/guest_amd64_helpers.c
88cf0f
+++ b/VEX/priv/guest_amd64_helpers.c
88cf0f
@@ -3141,8 +3141,11 @@ void amd64g_dirtyhelper_CPUID_sse42_and_cx16 ( VexGuestAMD64State* st )
88cf0f
    address sizes   : 36 bits physical, 48 bits virtual
88cf0f
    power management:
88cf0f
 */
88cf0f
-void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st )
88cf0f
+void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st,
88cf0f
+                                             ULong hasF16C, ULong hasRDRAND )
88cf0f
 {
88cf0f
+   vassert((hasF16C >> 1) == 0ULL);
88cf0f
+   vassert((hasRDRAND >> 1) == 0ULL);
88cf0f
 #  define SET_ABCD(_a,_b,_c,_d)                \
88cf0f
       do { st->guest_RAX = (ULong)(_a);        \
88cf0f
            st->guest_RBX = (ULong)(_b);        \
88cf0f
@@ -3157,9 +3160,14 @@ void amd64g_dirtyhelper_CPUID_avx_and_cx16 ( VexGuestAMD64State* st )
88cf0f
       case 0x00000000:
88cf0f
          SET_ABCD(0x0000000d, 0x756e6547, 0x6c65746e, 0x49656e69);
88cf0f
          break;
88cf0f
-      case 0x00000001:
88cf0f
-         SET_ABCD(0x000206a7, 0x00100800, 0x1f9ae3bf, 0xbfebfbff);
88cf0f
+      case 0x00000001: {
88cf0f
+         // As a baseline, advertise neither F16C (ecx:29) nor RDRAND (ecx:30),
88cf0f
+         // but patch in support for them as directed by the caller.
88cf0f
+         UInt ecx_extra
88cf0f
+            = (hasF16C ? (1U << 29) : 0) | (hasRDRAND ? (1U << 30) : 0);
88cf0f
+         SET_ABCD(0x000206a7, 0x00100800, (0x1f9ae3bf | ecx_extra), 0xbfebfbff);
88cf0f
          break;
88cf0f
+      }
88cf0f
       case 0x00000002:
88cf0f
          SET_ABCD(0x76035a01, 0x00f0b0ff, 0x00000000, 0x00ca0000);
88cf0f
          break;
88cf0f
diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c
88cf0f
index 56e992c..96dee38 100644
88cf0f
--- a/VEX/priv/guest_amd64_toIR.c
88cf0f
+++ b/VEX/priv/guest_amd64_toIR.c
88cf0f
@@ -22007,7 +22007,8 @@ Long dis_ESC_0F (
88cf0f
 
88cf0f
       vassert(fName); vassert(fAddr);
88cf0f
       IRExpr** args = NULL;
88cf0f
-      if (fAddr == &amd64g_dirtyhelper_CPUID_avx2) {
88cf0f
+      if (fAddr == &amd64g_dirtyhelper_CPUID_avx2
88cf0f
+          || fAddr == &amd64g_dirtyhelper_CPUID_avx_and_cx16) {
88cf0f
          Bool hasF16C   = (archinfo->hwcaps & VEX_HWCAPS_AMD64_F16C) != 0;
88cf0f
          Bool hasRDRAND = (archinfo->hwcaps & VEX_HWCAPS_AMD64_RDRAND) != 0;
88cf0f
          args = mkIRExprVec_3(IRExpr_GSPTR(),
88cf0f
diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c
88cf0f
index 3536e57..56a28d1 100644
88cf0f
--- a/coregrind/m_machine.c
88cf0f
+++ b/coregrind/m_machine.c
88cf0f
@@ -1076,10 +1076,10 @@ Bool VG_(machine_get_hwcaps)( void )
88cf0f
         have_avx2 = (ebx & (1<<5)) != 0; /* True => have AVX2 */
88cf0f
      }
88cf0f
 
88cf0f
-     /* Sanity check for RDRAND and F16C.  These don't actually *need* AVX2, but
88cf0f
-        it's convenient to restrict them to the AVX2 case since the simulated
88cf0f
-        CPUID we'll offer them on has AVX2 as a base. */
88cf0f
-     if (!have_avx2) {
88cf0f
+     /* Sanity check for RDRAND and F16C.  These don't actually *need* AVX, but
88cf0f
+        it's convenient to restrict them to the AVX case since the simulated
88cf0f
+        CPUID we'll offer them on has AVX as a base. */
88cf0f
+     if (!have_avx) {
88cf0f
         have_f16c   = False;
88cf0f
         have_rdrand = False;
88cf0f
      }