diff options
author | 2024-11-12 16:37:32 -0300 | |
---|---|---|
committer | 2024-11-22 17:40:25 -0300 | |
commit | f21055a4e9a2c3c2c7769e4ff7de246555dcd9be (patch) | |
tree | 3835ee8eb33130224bae8306a9ef9aa3998fcdaf | |
parent | gdb/record: add support for vpxor instruction (diff) | |
download | binutils-gdb-f21055a4e9a2c3c2c7769e4ff7de246555dcd9be.tar.gz binutils-gdb-f21055a4e9a2c3c2c7769e4ff7de246555dcd9be.tar.bz2 binutils-gdb-f21055a4e9a2c3c2c7769e4ff7de246555dcd9be.zip |
gdb/record: Add support for all vpcmpeq instructions
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>
-rw-r--r-- | gdb/i386-tdep.c | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/i386-avx-reverse.c | 32 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/i386-avx-reverse.exp | 45 |
3 files changed, 88 insertions, 0 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 38b1e7a1f02..2a076700a67 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -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 */ diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index 9bdc365ed86..57b53d1390c 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -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 */ } diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp index c4a54211592..b4f0e3b38b5 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -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" |