[PATCH] gdb/reverse: Add 2 AVX instructions VADDSUBPS and VADDSUBPD

First Last ghodawalaaman2@disroot.org
Tue Jun 10 13:34:50 GMT 2025


add support to recording 2 missing AVX instructions: vaddsubps and vaddsubpd, and add associated tests.
---
 gdb/i386-tdep.c                               | 10 +++
 gdb/testsuite/gdb.reverse/i386-avx-reverse.c  | 33 +++++++++
 .../gdb.reverse/i386-avx-reverse.exp          | 70 +++++++++++++++++++
 3 files changed, 113 insertions(+)

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 23788b44e92..a17a1b28475 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -4915,6 +4915,16 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
 	  return -1;
 	}
       break;
+    case 0xd0:    /* VADDSUBPD XMM1, XMM2, reg/mem */
+	          /* VADDSUBPS XMM1, XMM2, reg/mem */
+      i386_record_modrm (ir);
+      /* The most significant bit of the register offset
+        is vex_r. */
+      record_full_arch_list_add_reg (ir->regcache,
+                                      tdep->ymm0_regnum
+                                      + ir->reg + vex_r * 8);
+      break;
+
     case 0xd6: /* VMOVQ reg/mem XMM  */
       i386_record_modrm (ir);
       /* This is the vmovq version that stores into a regular register
diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
index a37b65adc30..8adf9a19f80 100644
--- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
+++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
@@ -419,6 +419,37 @@ arith_test ()
   return 0; /* end arith_test  */
 }
 
+int
+vaddsubpd_test ()
+{
+  /* start vaddsubpd_test */
+  // YMM test
+  asm volatile ("vaddsubpd %ymm15,%ymm1,%ymm0");
+  asm volatile ("vaddsubpd %ymm0,%ymm1,%ymm15");
+  asm volatile ("vaddsubpd %ymm2,%ymm3,%ymm4");
+
+  // XMM test
+  asm volatile ("vaddsubpd %xmm15,%xmm1,%xmm2");
+  asm volatile ("vaddsubpd %xmm0,%xmm1,%xmm10");
+  return 0; /* end vaddsubpd_test */
+}
+
+int
+vaddsubps_test ()
+{
+  /* start vaddsubps_test */
+  // YMM test
+  asm volatile ("vaddsubps %ymm15,%ymm1,%ymm2");
+  asm volatile ("vaddsubps %ymm0,%ymm1,%ymm10");
+  asm volatile ("vaddsubps %ymm2,%ymm3,%ymm4");
+
+  // XMM test
+  asm volatile ("vaddsubps %xmm0,%xmm1,%xmm15");
+  asm volatile ("vaddsubps %xmm15,%xmm1,%xmm0");
+  return 0; /* end vaddsubps_test */
+}
+
+
 /* This include is used to allocate the dynamic buffer and have
    the pointers aligned to a 32-bit boundary, so we can test instructions
    that require aligned memory.  */
@@ -449,5 +480,7 @@ main ()
   vpcmpeq_test ();
   vpmovmskb_test ();
   arith_test ();
+  vaddsubpd_test ();
+  vaddsubps_test ();
   return 0;	/* end of main */
 }
diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
index 00f58f8bea5..1b068a2fc75 100644
--- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
@@ -626,3 +626,73 @@ if {[record_full_function "arith"] == true} {
 }
 gdb_test "finish" "Run till exit from.*arith_test.*" \
     "leaving arith"
+
+# Preparation and testing vaddsubpd instructions
+
+gdb_test_no_output "set \$ymm15.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm15 for vaddsubpd"
+gdb_test_no_output "set \$ymm0.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm0 for vaddsubpd"
+gdb_test_no_output "set \$xmm2.uint128 = 0xbeef" \
+    "set xmm2 for vaddsubpd"
+gdb_test_no_output "set \$xmm10.uint128 = 0xbeef" \
+    "set xmm10 for vaddsubpd"
+gdb_test_no_output "set \$ymm3.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm3 for vaddsubpd"
+gdb_test_no_output "set \$ymm4.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm4 for vaddsubpd"
+
+if {[record_full_function "vaddsubpd"] == true} {
+       test_one_register "vaddsubpd" "xmm10" \
+       "0xbeef" "xmm10:"
+       test_one_register "vaddsubpd" "xmm2" \
+       "0xbeef" "xmm2:"
+    test_one_register "vaddsubpd" "ymm4" \
+       "0xcafeface, 0xcafeface" "ymm4: "
+    test_one_register "vaddsubpd" "ymm15" \
+       "0xcafeface, 0xcafeface" "ymm15: "
+    test_one_register "vaddsubpd" "ymm0" \
+       "0xcafeface, 0xcafeface" "ymm0: "
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for vaddsubpd_test"
+} else {
+    untested "couldn't run vaddsubpd tests"
+}
+gdb_test "finish" "Run till exit from.*vaddsubpd_test.*" \
+    "leaving vaddsubpd"
+
+# Preparation and testing vaddsubps instruction
+
+gdb_test_no_output "set \$ymm10.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm10 for vaddsubps"
+gdb_test_no_output "set \$ymm2.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm2 for vaddsubps"
+gdb_test_no_output "set \$xmm15.uint128 = 0xbeef" \
+    "set xmm15 for vaddsubps"
+gdb_test_no_output "set \$xmm0.uint128 = 0xbeef" \
+    "set xmm0 for vaddsubps"
+gdb_test_no_output "set \$ymm3.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm3 for vaddsubps"
+gdb_test_no_output "set \$ymm4.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm4 for vaddsubps"
+
+if {[record_full_function "vaddsubps"] == true} {
+    test_one_register "vaddsubps" "xmm0" \
+       "0xbeef" "xmm0: "
+    test_one_register "vaddsubps" "xmm15" \
+       "0xbeef" "xmm15: "
+    test_one_register "vaddsubps" "ymm4" \
+       "0xcafeface, 0xcafeface" "ymm4: "
+    test_one_register "vaddsubps" "ymm10" \
+       "0xcafeface, 0xcafeface" "ymm10: "
+    test_one_register "vaddsubps" "ymm2" \
+       "0xcafeface, 0xcafeface" "ymm2: "
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for vaddsubps_test"
+} else {
+    untested "couldn't run vaddsubps tests"
+}
+gdb_test "finish" "Run till exit from.*vaddsubps_test.*" \
+    "leaving vaddsubps"
-- 
2.39.5



More information about the Gdb-patches mailing list