[3/3] gdb/record: add support for AVX floating point arithmetic instructions

Message ID 20250109193844.3267494-4-guinevere@redhat.com
State New
Headers
Series More AVX support improvements |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Guinevere Larsen Jan. 9, 2025, 7:38 p.m. UTC
  This commit adds support for the following types of instructions
relating to floating poitn values: add, mul, sub, min, div, max.
These are supported with packed or single values, and single or double
precision.

Some of the instructions had opcode clashes, however, considering the
mechanics of recording the registers is the same on both instructions,
this is just marked with a comment.
---
 gdb/i386-tdep.c                               |  10 +-
 gdb/testsuite/gdb.reverse/i386-avx-reverse.c  |  56 ++++++++++
 .../gdb.reverse/i386-avx-reverse.exp          | 105 ++++++++++++++++++
 3 files changed, 169 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 44123979186..5f585b2ca7e 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -5003,9 +5003,15 @@  i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
 
     case 0x78:	/* VPBROADCASTB  */
     case 0x79:	/* VPBROADCASTW  */
-    case 0x58:	/* VPBROADCASTD  */
-    case 0x59:	/* VPBROADCASTQ  */
+    case 0x58:	/* VPBROADCASTD and VADD[P|S][S|D]  */
+    case 0x59:	/* VPBROADCASTQ and VMUL[P|S][S|D]  */
+    case 0x5c:	/* VSUB[P|S][S|D]  */
+    case 0x5d:	/* VMIN[P|S][S|D]  */
+    case 0x5e:	/* VDIV[P|S][S|D]  */
+    case 0x5f:	/* VMAX[P|S][S|D]  */
       {
+	/* vpbroadcast and arithmethic operations are differentiated
+	   by map_select, but it doesn't change the recording mechanics.  */
 	i386_record_modrm (ir);
 	int reg_offset = ir->reg + vex_r * 8;
 	gdb_assert (tdep->num_ymm_regs > reg_offset);
diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
index f41c7ff2933..0c26bcd8e85 100644
--- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
+++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c
@@ -364,6 +364,61 @@  vpmovmskb_test ()
   return 0; /* end vpmovmskb_test  */
 }
 
+/* Test record arithmetic instructions.  */
+int
+arith_test ()
+{
+  /* start arith_test.  */
+  /* Using GDB, load these values onto registers for testing.
+     ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5}
+     ymm1.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5}
+     ymm15.v2_int128 = {0x0, 0x0}
+     this way it's easy to confirm we're undoing things correctly.  */
+  asm volatile ("vaddps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vaddps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vaddpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vaddpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vaddss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vaddsd %xmm0, %xmm1, %xmm15");
+
+  asm volatile ("vmulps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmulps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vmulpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmulpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vmulss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmulsd %xmm0, %xmm1, %xmm15");
+
+  asm volatile ("vsubps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vsubps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vsubpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vsubpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vsubss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vsubsd %xmm0, %xmm1, %xmm15");
+
+  asm volatile ("vdivps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vdivps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vdivpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vdivpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vdivss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vdivsd %xmm0, %xmm1, %xmm15");
+
+  asm volatile ("vminps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vminps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vminpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vminpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vminss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vminsd %xmm0, %xmm1, %xmm15");
+
+  asm volatile ("vmaxps %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmaxps %ymm0, %ymm1, %ymm15");
+  asm volatile ("vmaxpd %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmaxpd %ymm0, %ymm1, %ymm15");
+  asm volatile ("vmaxss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vmaxsd %xmm0, %xmm1, %xmm15");
+
+  return 0; /* end arith_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.  */
@@ -392,5 +447,6 @@  main ()
   vpor_xor_test ();
   vpcmpeq_test ();
   vpmovmskb_test ();
+  arith_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 e3d1bbb3faa..11532afe344 100644
--- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
+++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp
@@ -517,3 +517,108 @@  if {[record_full_function "vpmovmskb"] == true} {
 }
 gdb_test "finish" "Run till exit from.*vpmovmskb_test.*" \
     "leaving vpmovmskb"
+
+# Preparation and testing arithmetic instructions.
+gdb_test_no_output \
+    "set \$ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5}"
+gdb_test_no_output \
+    "set \$ymm1.v8_float = {0, 1, 2, 3, 4, 5, 6, 7}"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}"
+
+if {[record_full_function "arith"] == true} {
+    test_one_register "vmaxsd" "ymm15" \
+	"0x40400000400000003f8000003f000000, 0x0" "ymm operation: "
+    test_one_register "vmaxss" "ymm15" \
+	"0x40600000402000003fc000003f000000, 0x40f0000040d0000040b0000040900000" \
+	"xmm operation: "
+    test_one_register "vmaxpd" "ymm15" \
+	"0x40600000402000003fc000003f000000, 0x0" "ymm operation: "
+    test_one_register "vmaxpd" "ymm15" \
+	"0x40600000402000003fc000003f000000, 0x40f0000040d0000040b0000040900000" \
+	"xmm operation: "
+    test_one_register "vmaxps" "ymm15" \
+	"0x40600000402000003fc000003f000000, 0x0" "ymm operation: "
+    test_one_register "vmaxps" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "xmm operation: "
+
+    test_one_register "vminsd" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "ymm operation: "
+    test_one_register "vminss" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x40e0000040c0000040a0000040800000" \
+	"xmm operation: "
+    test_one_register "vminpd" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "ymm operation: "
+    test_one_register "vminpd" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x40e0000040c0000040a0000040800000" \
+	"xmm operation: "
+    test_one_register "vminps" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "ymm operation: "
+    test_one_register "vminps" "ymm15" \
+	"0x40400000400000003fafffff820001f0, 0x0" "xmm operation: "
+
+    test_one_register "vdivsd" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "ymm operation: "
+    test_one_register "vdivss" "ymm15" \
+	"0x3fcfffffffc000013fafffff820001f0, 0x3fdfffffffe000013fdfffffffe00001" \
+	"xmm operation: "
+    test_one_register "vdivpd" "ymm15" \
+	"0x3fcfffffffc000013fafffff820001f0, 0x0" "ymm operation: "
+    test_one_register "vdivpd" "ymm15" \
+	"0x3f5b6db73f4ccccd3f2aaaab00000000, 0x3f6eeeef3f6c4ec53f68ba2f3f638e39" \
+	"xmm operation: "
+    test_one_register "vdivps" "ymm15" \
+	"0x3f5b6db73f4ccccd3f2aaaab00000000, 0x0" "ymm operation: "
+    test_one_register "vdivps" "ymm15" \
+	"0x4040000040000000bfbe00007e000000, 0x0" "xmm operation: "
+
+    test_one_register "vsubsd" "ymm15" \
+	"0x40400000400000003f800000bf000000, 0x0" "ymm operation: "
+    test_one_register "vsubss" "ymm15" \
+	"0xc058000060400000bfbe00007e000000, 0xc0e0000040e00000c0a0000040a00000" \
+	"xmm operation: "
+    test_one_register "vsubpd" "ymm15" \
+	"0xc058000060400000bfbe00007e000000, 0x0" "ymm operation: "
+    test_one_register "vsubpd" "ymm15" \
+	"0xbf000000bf000000bf000000bf000000, 0xbf000000bf000000bf000000bf000000" \
+	"xmm operation: "
+    test_one_register "vsubps" "ymm15" \
+	"0xbf000000bf000000bf000000bf000000, 0x0" "ymm operation: "
+    test_one_register "vsubps" "ymm15" \
+	"0x40400000400000003f5000003f000000, 0x0" "xmm operation: "
+
+    test_one_register "vmulsd" "ymm15" \
+	"0x40400000400000003f80000000000000, 0x0" "ymm operation: "
+    test_one_register "vmulss" "ymm15" \
+	"0x40b00000802001003f5000003f000000, 0x41e00000819001064160000081100104" \
+	"xmm operation: "
+    test_one_register "vmulpd" "ymm15" \
+	"0x40b00000802001003f5000003f000000, 0x0" "ymm operation: "
+    test_one_register "vmulpd" "ymm15" \
+	"0x4128000040a000003fc0000000000000, 0x42520000421c000041dc000041900000" \
+	"xmm operation: "
+    test_one_register "vmulps" "ymm15" \
+	"0x4128000040a000003fc0000000000000, 0x0" "ymm operation: "
+    test_one_register "vmulps" "ymm15" \
+	"0x40400000400000003fc100003f000000, 0x0" "xmm operation: "
+
+    test_one_register "vaddsd" "ymm15" \
+	"0x40400000400000003f8000003f000000, 0x0" "ymm operation: "
+    test_one_register "vaddss" "ymm15" \
+	"0x40640000502000003fc100003f000000, 0x40f800006130000040b8000060d00000" \
+	"xmm operation: "
+    test_one_register "vaddpd" "ymm15" \
+	"0x40640000502000003fc100003f000000, 0x0" "ymm operation: "
+    test_one_register "vaddpd" "ymm15" \
+	"0x40d0000040900000402000003f000000, 0x41680000414800004128000041080000" \
+	"xmm operation: "
+    test_one_register "vaddps" "ymm15" \
+	"0x40d0000040900000402000003f000000, 0x0" "ymm operation: "
+    test_one_register "vaddps" "ymm15" "0x0, 0x0" "xmm operation: "
+
+    gdb_test "record stop" "Process record is stopped.*" \
+	"delete history for arith_test"
+} else {
+    untested "couldn't run arith tests"
+}
+gdb_test "finish" "Run till exit from.*arith_test.*" \
+    "leaving arith"