]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/reverse: Add 2 AVX instructions VADDSUBPS and VADDSUBPD
authorFirst Last <ghodawalaaman2@disroot.org>
Tue, 10 Jun 2025 13:34:50 +0000 (19:04 +0530)
committerGuinevere Larsen <guinevere@redhat.com>
Tue, 8 Jul 2025 20:13:11 +0000 (17:13 -0300)
add support to recording 2 missing AVX instructions: vaddsubps and vaddsubpd, and add associated tests.

Approved-By: Guinevere Larsen <guinevere@redhat.com>
gdb/i386-tdep.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.exp

index 9be4748c88039bfe02d8992c9d8fccdbdd2b290b..dcb7e7b6766fcf8597d23636ea55bf17917fde00 100644 (file)
@@ -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
index a37b65adc306ee01e5c75540ee642b5b02ac5266..f559d69d8e736c31eb5d76208aa62ceb53946e25 100644 (file)
@@ -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 */
 }
index 00f58f8bea53e6fe4a2f908c2f42a1b91ac38199..fbcff4975f84b0decada58ee0275b2f5d7a9997e 100644 (file)
@@ -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"