]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/record: add support for AVX conversion instructions.
authorGuinevere Larsen <guinevere@redhat.com>
Fri, 13 Jun 2025 17:39:50 +0000 (14:39 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Fri, 11 Jul 2025 14:55:34 +0000 (11:55 -0300)
WIP

This commit adds support for instructions to convert from one type to
another, which are in the form:
* VCVTDQ2[PS|PD]
* VCVTPS2[DQ|PD]
* VCVTPD2[PS|DQ]
* VCVTSD2[SI|SS]
* VCVTSI2[SS|SD]
* VCVTSS2[SD|SI]
* VCVTTP[S|D]2DQ
* VCVTTS[S|D]2SI

It also adds support to vpsadbw, since it was trivial and only one
instruction. Finally, I have slightly reorder the case statements to
keep them in numerical order.

gdb/i386-tdep.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.c
gdb/testsuite/gdb.reverse/i386-avx-reverse.exp

index 0fd5efd436d8c1a21bb0fefc90915d91c3451e93..103bec4054ec78ee0a36c1bdc40f842af35c4f7d 100644 (file)
@@ -5108,6 +5108,14 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
        break;
       }
 
+    case 0x2c: /* VCVTTSD2SI and VCVTTSS2SI.  */
+    case 0x2d: /* VCVTSD2SI and VCVTSS2SI.  */
+      i386_record_modrm (ir);
+      record_full_arch_list_add_reg (ir->regcache,
+                                    ir->regmap[X86_RECORD_REAX_REGNUM
+                                               + ir->reg]);
+      break;
+
     case 0x00: /* VSHUFB and VPERMQ.  */
     case 0x01: /* VPERMPD.  */
     case 0x02: /* VPBLENDD.  */
@@ -5118,6 +5126,7 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
     case 0x0d: /* VPERMILPD with register and VBLENDPD.  */
     case 0x0e: /* VPBLENDW.  */
     case 0x1a: /* VBROADCASTF128.  */
+    case 0x2a: /* VCVTSI2SS.  */
     case 0x2b: /* VPACKUSDW.  */
     case 0x36: /* VPERMD.  */
     case 0x40: /* VPMULLD  */
@@ -5128,6 +5137,8 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
     case 0x57: /* VXORP[S|D]  */
     case 0x58: /* VPBROADCASTD and VADD[P|S][S|D]  */
     case 0x59: /* VPBROADCASTQ and VMUL[P|S][S|D]  */
+    case 0x5a: /* VCVTPS2PD, VCVTSD2SS, VCVTSS2SD and VCVTPD2PS.  */
+    case 0x5b: /* VCVTDQ2PS, VCVTTPS2PD and VCVTPS2DQ.  */
     case 0x5c: /* VSUB[P|S][S|D]  */
     case 0x5d: /* VMIN[P|S][S|D]  */
     case 0x5e: /* VDIV[P|S][S|D]  */
@@ -5148,12 +5159,14 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
     case 0xdf: /* VPANDN  */
     case 0xe1: /* VPSRAW, dynamic shift.  */
     case 0xe2: /* VPSRAD, dynamic shift.  */
-    case 0xe5: /* VPMULHW  */
     case 0xe4: /* VPMULHUW  */
+    case 0xe5: /* VPMULHW  */
+    case 0xe6: /* VCVTDQ2PD, VCVTTPD2DQ and VCVTPD2DQ.  */
     case 0xf1: /* VPSLLW, dynamic shift.  */
     case 0xf2: /* VPSLLD, dynamic shift.  */
     case 0xf3: /* VPSLLQ, dynamic shift.  */
     case 0xf4: /* VPMULUDQ  */
+    case 0xf6: /* VPSADBW.  */
     case 0xfc: /* VPADDB  */
     case 0xfd: /* VPADDW  */
     case 0xfe: /* VPADDD  */
index 7ae6d83a6e906963aa3f47d3f1a24927d9dde6d4..d514bf0f222894670d034f6929beb8311bd57142 100644 (file)
@@ -442,6 +442,9 @@ arith_test ()
   asm volatile ("vpand %xmm0, %xmm1, %xmm15");
   asm volatile ("vpandn %ymm0, %ymm1, %ymm15");
 
+  asm volatile ("vpsadbw %xmm0, %xmm1, %xmm2");
+  asm volatile ("vpsadbw %ymm0, %ymm1, %ymm15");
+
   return 0; /* end arith_test  */
 }
 
@@ -699,6 +702,41 @@ pack_test ()
   return 0; /* end pack_test  */
 }
 
+int
+convert_test ()
+{
+  /* start convert_test.  */
+  /* Using GDB, load these values onto registers for testing.
+     xmm0.v2_int128 = {0, 0}
+     xmm1.v4_float = {0, 1, 2.5, 10}
+     xmm15.v2_int128 = {0, 0}
+     ecx = -1
+     ebx = 0
+     this way it's easy to confirm we're undoing things correctly.  */
+
+  asm volatile ("vcvtdq2ps %xmm1, %xmm0");
+  asm volatile ("vcvtdq2pd %xmm1, %xmm15");
+
+  asm volatile ("vcvtps2dq %xmm1, %xmm15");
+  asm volatile ("vcvtps2pd %xmm1, %xmm0");
+  asm volatile ("vcvtpd2ps %xmm1, %xmm15");
+  asm volatile ("vcvtpd2dq %xmm1, %xmm0");
+
+  asm volatile ("vcvtsd2si %xmm1, %rbx");
+  asm volatile ("vcvtsd2ss %xmm0, %xmm1, %xmm15");
+  asm volatile ("vcvtsi2sd %rcx, %xmm1, %xmm0");
+  asm volatile ("vcvtsi2ss %rcx, %xmm1, %xmm15");
+  asm volatile ("vcvtss2sd %xmm15, %xmm1, %xmm0");
+  asm volatile ("vcvtss2si %xmm1, %rbx");
+
+  asm volatile ("vcvttpd2dq %xmm1, %xmm0");
+  asm volatile ("vcvttps2dq %xmm1, %xmm15");
+  asm volatile ("vcvttsd2si %xmm0, %rbx");
+  asm volatile ("vcvttss2si %xmm1, %ecx");
+
+  return 0; /* end convert_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.  */
@@ -738,5 +776,6 @@ main ()
   blend_test ();
   compare_test ();
   pack_test ();
+  convert_test ();
   return 0;    /* end of main */
 }
index f8e8ad1ad46e70b9a6d558d7e346bd0286e52570..601ed4b0f2a56cac8d1f848845809e67f262e512 100644 (file)
@@ -549,6 +549,10 @@ gdb_test_no_output "set \$ymm2.v2_int128 = {0,0}"
 gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}"
 
 if {[record_full_function "arith"] == true} {
+    test_one_register "vpsadbw" "ymm15" \
+       "0x20000000200000004000003f000000, 0x100000001000000010000000100000"
+    test_one_register "vpsadbw" "ymm2" \
+       "0x20000000200000004000003f000000, 0x100000001000000010000000100000"
     test_one_register "vpandn" "ymm15" \
        "0x40400000400000003f80000000000000, 0x0"
     test_one_register "vpand" "ymm15" \
@@ -1113,3 +1117,54 @@ if {[record_full_function "pack"] == true} {
 }
 gdb_test "finish" "Run till exit from.*pack_test.*" \
     "leaving pack"
+
+# Preparation and testing converting instructions.
+gdb_test_no_output \
+    "set \$ymm0.v2_int128 = {0,0}" \
+    "set ymm0 for convert test"
+gdb_test_no_output \
+    "set \$ymm1.v8_float = {0, 1, 2.5, 10, -1, -2.5, 0}" \
+    "set ymm1 for convert test"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" \
+    "set ymm15 for convert test"
+gdb_test_no_output "set \$ecx = -1" "set ecx for convert test"
+gdb_test_no_output "set \$ebx = 1" "set ebx for convert test"
+
+if {[record_full_function "convert"] == true} {
+    gdb_test "maint print record-instruction" ".*"
+    test_one_general_register "vcvttss2si" "ecx" "0xffffffff"
+    test_one_general_register "vcvttsd2si" "ebx" "0x0"
+    test_one_register "vcvttps2dq" "ymm15" \
+       "0x41200000402000003f8000004f800000, 0x0"
+    test_one_register "vcvttpd2dq" "ymm0" \
+       "0x412000004020000041f0000000000000, 0x0"
+    test_one_general_register "vcvtss2si" "ebx" "0x0"
+
+    test_one_register "vcvtss2sd" "ymm0" \
+       "0x412000004020000041efffffffe00000, 0x0"
+    test_one_register "vcvtsi2ss" "ymm15" \
+       "0x41200000402000003f80000000000000, 0x0"
+    test_one_register "vcvtsi2sd" "ymm0" \
+       "0x8000000000000, 0x0"
+    test_one_register "vcvtsd2ss" "ymm15" \
+       "0x490000023c000000, 0x0"
+    test_one_general_register "vcvtsd2si" "ebx" "0x1"
+
+    test_one_register "vcvtpd2dq" "ymm0" \
+       "0x3ff00000000000000000000000000000, 0x0"
+    test_one_register "vcvtpd2ps" "ymm15" \
+       "0xa000000020000000100000000, 0x0"
+    test_one_register "vcvtps2pd" "ymm0" \
+       "0x4e8240004e8040004e7e000000000000, 0x0"
+    test_one_register "vcvtps2dq" "ymm15" \
+       "0x41cfc000000000000000000000000000, 0x0"
+    test_one_register "vcvtdq2pd" "ymm15" "0x0, 0x0"
+    test_one_register "vcvtdq2ps" "ymm0" "0x0, 0x0"
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for convert_test"
+} else {
+    untested "couldn't run convert tests"
+}
+gdb_test "finish" "Run till exit from.*convert_test.*" \
+    "leaving convert"