From: First Last Date: Tue, 10 Jun 2025 13:34:50 +0000 (+0530) Subject: gdb/reverse: Add 2 AVX instructions VADDSUBPS and VADDSUBPD X-Git-Tag: binutils-2_45~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5fe1ef6f789440cd30f47a404cd51faaeac8752d;p=thirdparty%2Fbinutils-gdb.git gdb/reverse: Add 2 AVX instructions VADDSUBPS and VADDSUBPD add support to recording 2 missing AVX instructions: vaddsubps and vaddsubpd, and add associated tests. Approved-By: Guinevere Larsen --- diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 9be4748c880..dcb7e7b6766 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..f559d69d8e7 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..fbcff4975f8 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"