]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add SSE4.1 PEXTRD instruction for x86 32 bit
authorAlexandra Hájková <ahajkova@redhat.com>
Thu, 30 Apr 2026 14:44:27 +0000 (10:44 -0400)
committerAlexandra Hájková <ahajkova@redhat.com>
Wed, 20 May 2026 16:42:10 +0000 (18:42 +0200)
Support pextrd instruction in guest_x86_toIR.c and
host_x86_isel.c. Add test function to sse4-common.h
and update none/tests/x86/sse4-x86.c to test the
instruction.

BZ: https://bugs.kde.org/show_bug.cgi?id=295974

NEWS
VEX/priv/guest_x86_toIR.c
none/tests/amd64/sse4-64.c
none/tests/sse4-common.h
none/tests/x86/sse4-x86.c
none/tests/x86/sse4-x86.stdout.exp

diff --git a/NEWS b/NEWS
index 668969eb976dca89f6b35f525fb8fcefd0805c0a..cd174283c7dc65d93569145c6e45dbea4bf04242 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,7 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather
 than mailing the developers (or mailing lists) directly -- bugs that
 are not entered into bugzilla tend to get forgotten about or ignored.
 
+295974  Add SSE4.1 PEXTRD instruction for x86 32 bit
 391311  [Patch] Fix arm64 valgrind tests compilation with clang
 519223  Recognize ioctl(UFFDIO_*) operations
 519539  Darwin shm_open mode is optional and depends on oflag
index 3f207b231254ab96875586aea4941c304244aff5..f1637c1870f963532a0ffacf6f271aee3aaf2bdd 100644 (file)
@@ -13167,6 +13167,37 @@ DisResult disInstr_X86_WRK (
       }
    }
 
+   /* 66 0F 3A 16 /r ib = PEXTRD reg/mem32, xmm2, imm8
+      Extract Doubleword int from xmm reg and store in gen.reg or mem. */
+   if ( sz == 2
+       && insn[0] == 0x0F && insn[1] == 0x3A && insn[2] == 0x16 ) {
+     Int    imm8_10;
+     modrm = insn[3];
+
+     if ( epartIsReg( modrm ) ) {
+       imm8_10 = (Int)(insn[3+1] & 3);
+     } else {
+       addr = disAMode( &alen, sorb, delta+3, dis_buf );
+       imm8_10 = (Int)((insn[3+alen]) & 3);
+     }
+
+     if ( epartIsReg( modrm ) ) {
+       putIReg( 4, eregOfRM(modrm), getXMMRegLane32(gregOfRM(modrm), imm8_10) );
+       delta += 1+1+3;
+       DIP( "pextrd $%d, %s,%s\n", imm8_10,
+           nameXMMReg( gregOfRM(modrm) ),
+           nameIReg( 4, eregOfRM(modrm) ) );
+     } else {
+       storeLE( mkexpr(addr), getXMMRegLane32(gregOfRM(modrm), imm8_10) );
+       delta += alen+1+3;
+       DIP( "pextrd $%d, %s,%s\n",
+           imm8_10, nameXMMReg( gregOfRM(modrm) ), dis_buf );
+     }
+
+     goto decode_success;
+   }
+
+
    /* 66 0F 3A 22 /r ib = PINSRD xmm1, r/m32, imm8
       Extract Doubleword int from gen.reg/mem32 and insert into xmm1 */
    if ( sz == 2
index 5aae5f755f5ebbb3616e48e2e829865316f0ca00..f3d546af5258d6225dd3faac179c9a88a79fffb9 100644 (file)
@@ -9,13 +9,8 @@
    gcc -m64 -g -O -Wall -o sse4-64 sse4-64.c
 */
 
-#include "../sse4-common.h"
-
 /* Architecture-specific macros for amd64 (use %r11) */
 
-
-
-
 #define DO_imm_r_to_rscalar(_opname, _imm, _src, _dstsuffix)       \
    {  \
       ULong _scbefore = 0x5555555555555555ULL;  \
       DO_imm_r_to_rscalar( _opname, _imm, _src, _dstsuffix )       \
       DO_imm_r_to_mscalar( _opname, _imm, _src )
 
+#define DO_imm_rscalar_to_r(_opname, _imm, _src, _srcsuffix)       \
+   {  \
+      V128  dstv;         \
+      V128  res;          \
+      ULong src64 = (ULong)(_src); \
+      memcpy(dstv, fives, sizeof(dstv)); \
+      memcpy(res,  zeroes, sizeof(res)); \
+      /* This assumes that gcc won't make any of %0, %1, %2 */ \
+      /* be r11.  That should be ensured (cough, cough) */ \
+      /* by declaring r11 to be clobbered. */ \
+      __asm__ __volatile__(  \
+         "movupd (%0), %%xmm2"    "\n\t"   /*dstv*/   \
+         "movq   (%1), %%r11"     "\n\t"   /*src64*/  \
+         _opname " $" #_imm ", %%r11" _srcsuffix ", %%xmm2"   "\n\t"  \
+         "movupd  %%xmm2, (%2)" "\n" /*res*/                          \
+         : /*out*/ \
+         : /*in*/ "r"(&dstv), "r"(&src64), "r"(&res)  \
+         : "cc", "memory", "xmm2", "r11"  \
+      );  \
+      showIGVV("r", (_opname), (_imm), src64, &dstv, &res); \
+   }
+#define DO_imm_mscalar_to_r(_opname, _imm, _src)       \
+   {  \
+      V128  dstv;         \
+      V128  res;          \
+      ULong src64 = (ULong)(_src); \
+      memcpy(dstv, fives, sizeof(dstv)); \
+      memcpy(res,  zeroes, sizeof(res)); \
+      __asm__ __volatile__(  \
+         "movupd (%0), %%xmm2"    "\n\t"   /*dstv*/   \
+         _opname " $" #_imm ", (%1), %%xmm2"   "\n\t"  \
+         "movupd  %%xmm2, (%2)" "\n" /*res*/                          \
+         : /*out*/ \
+         : /*in*/ "r"(&dstv), "r"(&src64), "r"(&res)  \
+         : "cc", "memory", "xmm2"  \
+      );  \
+      showIGVV("m", (_opname), (_imm), src64, &dstv, &res); \
+   }
+
+#define DO_imm_mandrscalar_to_r(_opname, _imm, _src, _dstsuffix)   \
+      DO_imm_rscalar_to_r( _opname, _imm, _src, _dstsuffix )       \
+      DO_imm_mscalar_to_r( _opname, _imm, _src )
+
+#include "../sse4-common.h"
 
+/* Architecture-specific macros for amd64 (use %r11) */
 
 
 
 
+#define DO_imm_r_to_rscalar(_opname, _imm, _src, _dstsuffix)       \
+   {  \
+      ULong _scbefore = 0x5555555555555555ULL;  \
+      ULong _scafter  = 0xAAAAAAAAAAAAAAAAULL; \
+      /* This assumes that gcc won't make any of %0, %1, %2 */ \
+      /* be r11.  That should be ensured (cough, cough) */ \
+      /* by declaring r11 to be clobbered. */ \
+      __asm__ __volatile__(  \
+         "movupd (%0), %%xmm2"    "\n\t"  \
+         "movq   (%1), %%r11"   "\n\t"  \
+         _opname " $" #_imm ", %%xmm2, %%r11" _dstsuffix  "\n\t"  \
+         "movq   %%r11, (%2)" "\n"  \
+         : /*out*/ \
+         : /*in*/ "r"(&(_src)), "r"(&(_scbefore)), "r"(&(_scafter))  \
+         : "cc", "memory", "xmm2", "r11"  \
+      );  \
+      showIAG("r", (_opname), (_imm), &(_src), (_scbefore), (_scafter));  \
+   }
+
+#define DO_imm_r_to_mscalar(_opname, _imm, _src)   \
+   {  \
+      ULong _scbefore = 0x5555555555555555ULL;  \
+      ULong _scafter = _scbefore; \
+      __asm__ __volatile__(  \
+         "movupd (%0), %%xmm2"    "\n\t"  \
+         _opname " $" #_imm ", %%xmm2, (%1)"  "\n\t"  \
+         : /*out*/ \
+         : /*in*/ "r"(&(_src)), "r"(&(_scafter))  \
+         : "cc", "memory", "xmm2"  \
+      );  \
+      showIAG("m", (_opname), (_imm), &(_src), (_scbefore), (_scafter));  \
+   }
+
+#define DO_imm_r_to_mandrscalar(_opname, _imm, _src, _dstsuffix)   \
+      DO_imm_r_to_rscalar( _opname, _imm, _src, _dstsuffix )       \
+      DO_imm_r_to_mscalar( _opname, _imm, _src )
 
 
 #define DO_imm_rscalar_to_r(_opname, _imm, _src, _srcsuffix)       \
@@ -1038,15 +1114,6 @@ void test_PINSRW ( void )
 }
 
 
-void test_PEXTRD ( void )
-{
-   V128 src;
-   randV128(&src);
-   DO_imm_r_to_mandrscalar("pextrd", 0, src, "d");
-   DO_imm_r_to_mandrscalar("pextrd", 1, src, "d");
-   DO_imm_r_to_mandrscalar("pextrd", 2, src, "d");
-   DO_imm_r_to_mandrscalar("pextrd", 3, src, "d");
-}
 
 void test_PINSRD ( void )
 {
index bb8e72e06e3cbe17115f771aec12d9bdd957d373..1139fe9cd8c801ea6980cb60ecedebf074788654 100644 (file)
@@ -929,6 +929,17 @@ static inline void test_BLENDVPS ( void )
    }
 }
 
+/* ------------ PEXTRD ------------ */
+static inline void test_PEXTRD ( void )
+{
+   V128 src;
+   randV128(&src);
+   DO_imm_r_to_mandrscalar("pextrd", 0, src, "d");
+   DO_imm_r_to_mandrscalar("pextrd", 1, src, "d");
+   DO_imm_r_to_mandrscalar("pextrd", 2, src, "d");
+   DO_imm_r_to_mandrscalar("pextrd", 3, src, "d");
+}
+
 static inline void test_PCMPEQQ ( void )
 {
    V128 src, dst;
index 62821bda54e26f31962bbca6c6fd11eb89197204..781769cd633851a08369d32852299f11c2b0c64a 100644 (file)
@@ -3,23 +3,17 @@
    Copied from amd64 version.
 */
 
-#include "../sse4-common.h"
-
 #define DO_imm_r_to_rscalar(_opname, _imm, _src)       \
    {  \
       ULong _scbefore = 0x5555555555555555ULL;  \
-      ULong _scafter  = 0xAAAAAAAAAAAAAAAAULL; \
-      /* This assumes that gcc won't make any of %0, %1, %2 */ \
-      /* be r11.  That should be ensured (cough, cough) */ \
-      /* by declaring r11 to be clobbered. */ \
+      ULong _scafter  = 0ULL; \
       __asm__ __volatile__(  \
          "movupd (%0), %%xmm2"    "\n\t"  \
-         "movq   (%1), %%r11"   "\n\t"  \
-         _opname " $" #_imm ", %%xmm2, %%r11"  "\n\t"  \
-         "movq   %%r11, (%2)" "\n"  \
+         _opname " $" #_imm ", %%xmm2, %%eax"  "\n\t"  \
+         "movl   %%eax, (%1)" "\n"  \
          : /*out*/ \
-         : /*in*/ "r"(&(_src)), "r"(&(_scbefore)), "r"(&(_scafter))  \
-         : "cc", "memory", "xmm2", "r11"  \
+         : /*in*/ "r"(&(_src)), "r"(&(_scafter))  \
+         : "cc", "memory", "xmm2", "eax"  \
       );  \
       showIAG("r", (_opname), (_imm), &(_src), (_scbefore), (_scafter));  \
    }
@@ -38,8 +32,8 @@
       showIAG("m", (_opname), (_imm), &(_src), (_scbefore), (_scafter));  \
    }
 
-#define DO_imm_r_to_mandrscalar(_opname, _imm, _src )   \
-      DO_imm_r_to_rscalar( _opname, _imm, _src )       \
+#define DO_imm_r_to_mandrscalar(_opname, _imm, _src, ...)   \
+      DO_imm_r_to_rscalar( _opname, _imm, _src )            \
       DO_imm_r_to_mscalar( _opname, _imm, _src )
 
 
@@ -84,6 +78,8 @@
       DO_imm_rscalar_to_r( _opname, _imm, _src )       \
       DO_imm_mscalar_to_r( _opname, _imm, _src )
 
+#include "../sse4-common.h"
+
 
 void test_PINSRD ( void )
 {
@@ -170,6 +166,7 @@ int main(void)
    test_ROUNDSS_w_immediate_rounding();
    test_ROUNDSD_w_mxcsr_rounding();
    test_ROUNDSS_w_mxcsr_rounding();
+   test_PEXTRD();
 
    return 0;
 }
index 2aa71d25ccd7dcca6387952155b120628164a499..6fb6b8807ebfb8ca7a2a06bd228ee9c90c95094e 100644 (file)
@@ -2756,3 +2756,11 @@ r (rm=2) roundss_1XX  a2d26e740dc6f12505ca97443fa66666 544da1105bccb1693018eb4b4
 m (rm=2) roundss_1XX  4632e74945f33bead1f790733fa66666 7439f1dc0f5e498df370c44c40000000    1.300000   2.000000
 r (rm=3) roundss_1XX  b87d4fe8dc8e719783eca8c13fa66666 cf766fe8b0642bae4b353b213f800000    1.300000   1.000000
 m (rm=3) roundss_1XX  54fea2bb6e22ced7f8755d1a3fa66666 c34f179ed96993791434ccb73f800000    1.300000   1.000000
+r     pextrd $0 7703dd30953c90570c5d2a681c677080 5555555555555555 000000001c677080
+m     pextrd $0 7703dd30953c90570c5d2a681c677080 5555555555555555 555555551c677080
+r     pextrd $1 7703dd30953c90570c5d2a681c677080 5555555555555555 000000000c5d2a68
+m     pextrd $1 7703dd30953c90570c5d2a681c677080 5555555555555555 555555550c5d2a68
+r     pextrd $2 7703dd30953c90570c5d2a681c677080 5555555555555555 00000000953c9057
+m     pextrd $2 7703dd30953c90570c5d2a681c677080 5555555555555555 55555555953c9057
+r     pextrd $3 7703dd30953c90570c5d2a681c677080 5555555555555555 000000007703dd30
+m     pextrd $3 7703dd30953c90570c5d2a681c677080 5555555555555555 555555557703dd30