]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/record: Add recording support to vpbroadcast instructions
authorGuinevere Larsen <guinevere@redhat.com>
Thu, 13 Jun 2024 17:32:29 +0000 (14:32 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Mon, 28 Oct 2024 13:46:33 +0000 (10:46 -0300)
This commit adds recording support to all AVX and AVX2 instructions
of the form vpbroadcast. GDB is not yet concerned about AVX512 in
recording mode, so for now we only support the AVX2 registers and
instructions.

This commit also updates the gdb.reverse/i386-avx-reverse.exp to test
broadcast instructions.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/i386-tdep.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.exp

index a0e0181a2c5b4885f55c7973a2f29ff8f61f4e6c..b9ac12edfa34f3e1a37eb4b54ea6c59a04a712f3 100644 (file)
@@ -4902,6 +4902,19 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
       }
       break;
 
+    case 0x78: /* VPBROADCASTB  */
+    case 0x79: /* VPBROADCASTW  */
+    case 0x58: /* VPBROADCASTD  */
+    case 0x59: /* VPBROADCASTQ  */
+      {
+       i386_record_modrm (ir);
+       int reg_offset = ir->reg + vex_r * 8;
+       gdb_assert (tdep->num_ymm_regs > reg_offset);
+       record_full_arch_list_add_reg (ir->regcache,
+                                      tdep->ymm0_regnum + reg_offset);
+      }
+      break;
+
     default:
       gdb_printf (gdb_stderr,
                  _("Process record does not support VEX instruction 0x%02x "
index c897436995ee14010d4fc2391020fd395660dc8c..16303a422489f366ec83d9a4f546de0fc9c918bd 100644 (file)
@@ -130,6 +130,34 @@ vpunpck_test  ()
   return 0; /* end vpunpck_test */
 }
 
+/* Test if we can record vpbroadcast instructions.  */
+int
+vpbroadcast_test ()
+{
+  /* Using GDB, load this value onto the register, for ease of testing.
+     xmm0.uint128  = 0x0
+     xmm1.uint128  = 0x1f1e1d1c1b1a19181716151413121110
+     xmm15.uint128 = 0x0
+     this way it's easy to confirm we're undoing things correctly.  */
+  /* start vpbroadcast_test.  */
+
+  asm volatile ("vpbroadcastb %xmm1, %xmm0");
+  asm volatile ("vpbroadcastb %xmm1, %xmm15");
+
+  asm volatile ("vpbroadcastw %xmm1, %ymm0");
+  asm volatile ("vpbroadcastw %xmm1, %ymm15");
+
+  asm volatile ("vpbroadcastd %xmm1, %xmm0");
+  asm volatile ("vpbroadcastd %xmm1, %xmm15");
+
+  asm volatile ("vpbroadcastq %xmm1, %ymm0");
+  asm volatile ("vpbroadcastq %xmm1, %ymm15");
+
+  /* We have a return statement to deal with
+     epilogue in different compilers.  */
+  return 0; /* end vpbroadcast_test */
+}
+
 int
 main ()
 {
@@ -148,5 +176,6 @@ main ()
 
   vmov_test ();
   vpunpck_test ();
+  vpbroadcast_test ();
   return 0;    /* end of main */
 }
index 718dca3429a2e85bc89370549f2f5b71f2b00ed1..75c313c2225b255e6cf8fab952e524834af0c468 100644 (file)
@@ -237,3 +237,32 @@ if {[record_full_function "vpunpck"] == true} {
 gdb_test "record stop" "Process record is stopped.*" \
     "delete history for vpunpck_test"
 gdb_test "finish" "Run till exit from.*vpunpck_test.*" "leaving vpunpck_test"
+
+# Start vpbroadcast tests
+gdb_test_no_output "set \$ymm0.v2_int128 = {0x0, 0x0}" "set xmm0 for vpbroadcast"
+gdb_test_no_output "set \$xmm1.v2_int64 = {0x1716151413121110, 0x1f1e1d1c1b1a1918}" \
+    "set xmm1 for vpbroadcast"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0x0, 0x0}" "set xmm15 for vpbroadcast"
+if {[record_full_function "vpbroadcast"] == true} {
+    test_one_register "vpbroadcastq" "ymm15" "0x13121110131211101312111013121110, 0x0"
+    test_one_register "vpbroadcastq" "ymm0"  "0x13121110131211101312111013121110, 0x0"
+
+    test_one_register "vpbroadcastd" "ymm15" \
+       "0x11101110111011101110111011101110, 0x11101110111011101110111011101110"
+    test_one_register "vpbroadcastd" "ymm0"  \
+       "0x11101110111011101110111011101110, 0x11101110111011101110111011101110"
+
+    test_one_register "vpbroadcastw" "ymm15" "0x10101010101010101010101010101010, 0x0"
+    test_one_register "vpbroadcastw" "ymm0"  "0x10101010101010101010101010101010, 0x0"
+
+    test_one_register "vpbroadcastb" "ymm15" "0x0, 0x0"
+    test_one_register "vpbroadcastb" "ymm0"  "0x0, 0x0"
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for vpbroadcast_test"
+} else {
+    untested "couldn't run vpbroadcast tests"
+}
+
+gdb_test "finish" "Run till exit from.*vpbroadcast_test.*" \
+    "leaving vpbroadcast"