]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/record: add support for permutation instructions
authorGuinevere Larsen <guinevere@redhat.com>
Wed, 11 Jun 2025 18:20:43 +0000 (15:20 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Fri, 11 Jul 2025 14:55:34 +0000 (11:55 -0300)
This commit adds recording support for the following instructions:
* VPERM2[I|F]128
* VPERM[D|Q|PD|PS]
* VPERMILP[S|D]

And associated tests.

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

index e8e2d6e734b9048d2756bbf7125da4b2fc188e43..ab9ed2f13a3436727141b7f477893d3f57818306 100644 (file)
@@ -5030,8 +5030,17 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
        break;
       }
 
-    case 0x00: /* VSHUFB.  */
+    case 0x00: /* VSHUFB and VPERMQ.  */
+    case 0x01: /* VPERMPD.  */
+    case 0x04: /* VPERMILPS with immediate.  */
+    case 0x05: /* VPERMILPD with immediate.  */
+    case 0x06: /* VMPERM2F128.  */
+    case 0x0c: /* VPERMILPS with register.  */
+    case 0x0d: /* VPERMILPD with register.  */
+    case 0x16: /* VPERMPS.  */
+    case 0x36: /* VPERMD.  */
     case 0x40: /* VPMULLD  */
+    case 0x46: /* VPERM2I128.  */
     case 0x57: /* VXORP[S|D]  */
     case 0x58: /* VPBROADCASTD and VADD[P|S][S|D]  */
     case 0x59: /* VPBROADCASTQ and VMUL[P|S][S|D]  */
index d438a335e914258df498fbe2400e686a0b633a0a..5e0e1a14d74cf137a134a7c6a9c0b8d5231f1e3b 100644 (file)
@@ -543,6 +543,44 @@ shuffle_test ()
   return 0; /* end shuffle_test  */
 }
 
+int
+permute_test ()
+{
+  /* start permute_test.  */
+  /* Using GDB, load these values onto registers for testing.
+     ymm0.v2_int128 = {0, 0}
+     ymm1.v16_int16 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
+     ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}
+     ymm15.v2_int128 = {0x0, 0x0}
+     eax = 0
+     this way it's easy to confirm we're undoing things correctly.  */
+  asm volatile ("vperm2f128 $1, %ymm1, %ymm2, %ymm0");
+  asm volatile ("vperm2f128 $0, %ymm1, %ymm2, %ymm15");
+  asm volatile ("vperm2i128 $1, %ymm2, %ymm1, %ymm0");
+  asm volatile ("vperm2i128 $0, %ymm2, %ymm1, %ymm15");
+
+  asm volatile ("vpermd %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpermd %ymm1, %ymm2, %ymm15");
+  asm volatile ("vpermq $1, %ymm1, %ymm0");
+  asm volatile ("vpermq $0, %ymm2, %ymm15");
+
+  asm volatile ("vpermilpd %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpermilpd %xmm1, %xmm2, %xmm15");
+  asm volatile ("vpermilpd $1, %ymm2, %ymm15");
+  asm volatile ("vpermilpd $0, %xmm2, %xmm0");
+  asm volatile ("vpermilps %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpermilps %xmm1, %xmm2, %xmm15");
+  asm volatile ("vpermilps $1, %ymm2, %ymm15");
+  asm volatile ("vpermilps $0, %xmm2, %xmm0");
+
+  asm volatile ("vpermpd $0, %ymm1, %ymm15");
+  asm volatile ("vpermpd $0, %ymm2, %ymm0");
+  asm volatile ("vpermps %ymm1, %ymm2, %ymm0");
+  asm volatile ("vpermps %ymm1, %ymm2, %ymm15");
+
+  return 0; /* end permute_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.  */
@@ -577,5 +615,6 @@ main ()
   vaddsubps_test ();
   shift_test ();
   shuffle_test ();
+  permute_test ();
   return 0;    /* end of main */
 }
index 4bcafe7c331f8458790f92592408cb516524415b..0a5681385574a31d47278aa1cdad5b5392753199 100644 (file)
@@ -871,3 +871,73 @@ if {[record_full_function "shuffle"] == true} {
 }
 gdb_test "finish" "Run till exit from.*shuffle_test.*" \
     "leaving shuffle"
+
+# Preparation and testing permute instructions.
+gdb_test_no_output \
+    "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for permute"
+gdb_test_no_output \
+    "set \$ymm1.v16_int16 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}" \
+    "set ymm1 for permute"
+gdb_test_no_output "set \$ymm2.v16_int16 = {17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32}" \
+    "set ymm2 for permute"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for permute"
+
+if {[record_full_function "permute"] == true} {
+    test_one_register "vpermps" "ymm15" \
+       "0x40003000200010004000300020001, 0x40003000200010004000300020001"
+    test_one_register "vpermps" "ymm0" \
+       "0x140013001200110014001300120011, 0x140013001200110014001300120011"
+    test_one_register "vpermpd" "ymm0" \
+       "0x120011001200110012001100120011, 0x0"
+    test_one_register "vpermpd" "ymm15" \
+       "0x120011001200110012001100140013, 0x1a0019001a0019001a0019001c001b"
+
+    test_one_register "vpermilps" "ymm0" \
+       "0x180017001400130018001700140013, 0x20001f001c001b0020001f001c001b" \
+       "register version"
+    test_one_register "vpermilps" "ymm15" \
+       "0x180017001400130018001700140013, 0x0" \
+       "register version"
+    test_one_register "vpermilps" "ymm15" \
+       "0x140013001200110018001700160015, 0x1c001b001a0019001c001b001a0019" \
+       "immediate version"
+    test_one_register "vpermilps" "ymm0" \
+       "0x140013001200110014001300120011, 0x0" \
+       "immediate version"
+
+    test_one_register "vpermilpd" "ymm0" \
+       "0x140013001200110014001300120011, 0x1c001b001a0019001c001b001a0019" \
+       "register version"
+    test_one_register "vpermilpd" "ymm15" \
+       "0x140013001200110014001300120011, 0x0" \
+       "register version"
+    test_one_register "vpermilpd" "ymm15" \
+       "0x140013001200110014001300120011, 0x140013001200110014001300120011" \
+       "immediate version"
+    test_one_register "vpermilpd" "ymm0" \
+       "0x40003000200010008000700060005, 0x40003000200010004000300020001" \
+       "immediate version"
+
+    test_one_register "vpermq" "ymm15" \
+       "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003"
+    test_one_register "vpermq" "ymm0" \
+       "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003"
+    test_one_register "vpermd" "ymm15" \
+       "0x80007000600050004000300020001, 0x80007000600050004000300020001"
+    test_one_register "vpermd" "ymm0" \
+       "0x10000f000e000d000c000b000a0009, 0x80007000600050004000300020001"
+
+    test_one_register "vperm2i128" "ymm15" \
+       "0x180017001600150014001300120011, 0x180017001600150014001300120011"
+    test_one_register "vperm2i128" "ymm0" \
+       "0x20001f001e001d001c001b001a0019, 0x180017001600150014001300120011"
+    test_one_register "vperm2f128" "ymm15" "0x0, 0x0"
+    test_one_register "vperm2f128" "ymm0" "0x0, 0x0"
+
+    gdb_test "record stop" "Process record is stopped.*" \
+       "delete history for permute_test"
+} else {
+    untested "couldn't run permute tests"
+}
+gdb_test "finish" "Run till exit from.*permute_test.*" \
+    "leaving permute"