]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/record: Add support for all vpcmpeq instructions
authorGuinevere Larsen <guinevere@redhat.com>
Tue, 12 Nov 2024 19:37:32 +0000 (16:37 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Fri, 22 Nov 2024 20:40:25 +0000 (17:40 -0300)
This commit adds support to recording instructions of the form
VPCMPEQ[B|W|D]. They are all encoded in the same way and only
differentiated by the opcode, so they are all processed together. This
commit also updates the test to (quite exhaustively) test the new
instruction.

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 38b1e7a1f02b196038637e9e8dd5f0d2be961a36..2a076700a672a3623b11a5afedb018d797b8d3bc 100644 (file)
@@ -4951,6 +4951,17 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
       }
       break;
 
+    case 0x74: /* VPCMPEQB  */
+    case 0x75: /* VPCMPEQB  */
+    case 0x76: /* VPCMPEQB  */
+      {
+       i386_record_modrm (ir);
+       int reg_offset = ir->reg + vex_r * 8;
+       record_full_arch_list_add_reg (ir->regcache,
+                                      tdep->ymm0_regnum + reg_offset);
+      }
+      break;
+
     case 0x78: /* VPBROADCASTB  */
     case 0x79: /* VPBROADCASTW  */
     case 0x58: /* VPBROADCASTD  */
index 9bdc365ed86df71379c719bd14e2d0f295a9ca7a..57b53d1390c9239626432e1dd818dfffb436a8d2 100644 (file)
@@ -229,6 +229,37 @@ vpxor_test ()
   return 0; /* end vpxor_test  */
 }
 
+int
+vpcmpeq_test ()
+{
+  /* start vpcmpeq_test.  */
+  /* Using GDB, load these values onto registers for testing.
+     ymm0.v2_int128  = {0x0, 0x12345}
+     ymm1.v8_int32 = {0xcafe, 0xbeef, 0xff, 0x1234, 0x0, 0xff00, 0xff0000ff, 0xface0f0f}
+     ymm2.v8_int32 = {0xcafe0, 0xbeef, 0xff00, 0x12345678, 0x90abcdef, 0xffff00, 0xff, 0xf}
+     ymm15.v2_int128 = {0xcafeface, 0xcafeface}
+     this way it's easy to confirm we're undoing things correctly.  */
+
+  /* Test all the vpcmpeq variants on a low register (number 0).  */
+  asm volatile ("vpcmpeqb %xmm1, %xmm2, %xmm0");
+  asm volatile ("vpcmpeqw %xmm1, %xmm2, %xmm0");
+  asm volatile ("vpcmpeqd %xmm1, %xmm2, %xmm0");
+
+  asm volatile ("vpcmpeqb %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpcmpeqw %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpcmpeqd %ymm1, %ymm2, %ymm0");
+
+  /* Test all the vpcmpeq variants on a high register (number 15).  */
+  asm volatile ("vpcmpeqb %xmm1, %xmm2, %xmm15");
+  asm volatile ("vpcmpeqw %xmm1, %xmm2, %xmm15");
+  asm volatile ("vpcmpeqd %xmm1, %xmm2, %xmm15");
+
+  asm volatile ("vpcmpeqb %ymm1, %ymm2, %ymm15");
+  asm volatile ("vpcmpeqw %ymm1, %ymm2, %ymm15");
+  asm volatile ("vpcmpeqd %ymm1, %ymm2, %ymm15");
+  return 0; /* end vpcmpeq_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.  */
@@ -255,5 +286,6 @@ main ()
   vpbroadcast_test ();
   vzeroupper_test ();
   vpxor_test ();
+  vpcmpeq_test ();
   return 0;    /* end of main */
 }
index c4a54211592d5da2add0c679f9f5fa306ebef797..b4f0e3b38b52a3242c11917234409040715dfc6f 100644 (file)
@@ -358,3 +358,48 @@ if {[record_full_function "vpxor"] == true} {
 }
 gdb_test "finish" "Run till exit from.*vpxor_test.*" \
     "leaving vpxor"
+
+# Preparation and testing vpcmpeq instructions.
+gdb_test_no_output "set \$ymm0.v2_int128 = {0x12345, 0x12345}" \
+    "set ymm0 for vpcmpeq"
+gdb_test_no_output \
+    "set \$ymm1.v8_int32 = {0xcafe, 0xbeef, 0xff, 0x1234, 0x0, 0xff00, 0xff0000ff, 0xface0f0f}" \
+    "set ymm1 for vpcmpeq"
+gdb_test_no_output \
+    "set \$ymm2.v8_int32 = {0xcafe0, 0xbeef, 0xff00, 0x12345678, 0x90abcdef, 0xffff00, 0xff, 0xf}" \
+    "set ymm2 for vpcmpeq"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0xcafeface, 0xcafeface}" \
+    "set ymm15 for vpcmpeq"
+
+if {[record_full_function "vpcmpeq"] == true} {
+    test_one_register "vpcmpeqd" "ymm15" \
+       "0xffff0000ffffffff00000000, 0xffff0000ffff00000000" "ymm: "
+    test_one_register "vpcmpeqw" "ymm15" \
+       "0xffff0000ffffffffff000000, 0xff00ffffffff00ffff00000000" "ymm: "
+    test_one_register "vpcmpeqb" "ymm15" \
+       "0xffffffff00000000, 0x0" "ymm: "
+    test_one_register "vpcmpeqd" "ymm15" \
+       "0xffff0000ffffffff00000000, 0x0" "xmm: "
+    test_one_register "vpcmpeqw" "ymm15" \
+       "0xffff0000ffffffffff000000, 0x0" "xmm: "
+    test_one_register "vpcmpeqb" "ymm15" "0xcafeface, 0xcafeface" "xmm: "
+
+    test_one_register "vpcmpeqd" "ymm0" \
+       "0xffff0000ffffffff00000000, 0xffff0000ffff00000000" "ymm: "
+    test_one_register "vpcmpeqw" "ymm0" \
+       "0xffff0000ffffffffff000000, 0xff00ffffffff00ffff00000000" "ymm: "
+    test_one_register "vpcmpeqb" "ymm0" \
+       "0xffffffff00000000, 0x0" "ymm: "
+    test_one_register "vpcmpeqd" "ymm0" \
+       "0xffff0000ffffffff00000000, 0x0" "xmm: "
+    test_one_register "vpcmpeqw" "ymm0" \
+       "0xffff0000ffffffffff000000, 0x0" "xmm: "
+    test_one_register "vpcmpeqb" "ymm0" "0x12345, 0x12345" "xmm: "
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for vpcmpeq_test"
+} else {
+    untested "couldn't run vpcmpeq tests"
+}
+gdb_test "finish" "Run till exit from.*vpcmpeq_test.*" \
+    "leaving vpcmpeq"