}
break;
+ case 0x60: /* VPUNPCKLBW */
+ case 0x61: /* VPUNPCKLWD */
+ case 0x62: /* VPUNPCKLDQ */
+ case 0x6c: /* VPUNPCKLQDQ */
+ case 0x68: /* VPUNPCKHBW */
+ case 0x69: /* VPUNPCKHWD */
+ case 0x6a: /* VPUNPCKHDQ */
+ case 0x6d: /* VPUNPCKHQDQ */
+ {
+ 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;
+
default:
gdb_printf (gdb_stderr,
_("Process record does not support VEX instruction 0x%02x "
return 0; /* end vmov_test */
}
+/* Test if we can properly record (and undo) vpunpck style instructions.
+ Most tests will use xmm0 and xmm1 as sources. The registers xmm15 and xmm2
+ are used as destination to ensure we're reading the VEX.R bit correctly. */
+int
+vpunpck_test ()
+{
+ /* Using GDB, load these values onto registers, for ease of testing.
+ ymm0.v2_int128 = {0x1f1e1d1c1b1a19181716151413121110, 0x2f2e2d2c2b2a29282726252423222120}
+ ymm1.v2_int128 = {0x4f4e4d4c4b4a49484746454443424140, 0x3f3e3d3c3b3a39383736353433323130}
+ ymm15.v2_int128 = {0xdead, 0xbeef}
+ so that's easy to confirm that the unpacking went as expected. */
+
+ /* start vpunpck_test. */
+
+ /* First try all low bit unpack instructions with xmm registers. */
+ /* 17 27 16 26 15 25 14 24 ...*/
+ asm volatile ("vpunpcklbw %xmm0, %xmm1, %xmm15");
+ /* 17 16 27 26 15 14 25 24 ...*/
+ asm volatile ("vpunpcklwd %0, %%xmm1, %%xmm15"
+ : : "m" (global_buf0));
+ /* 17 16 15 14 27 26 25 24 ...*/
+ asm volatile ("vpunpckldq %0, %%xmm1, %%xmm2"
+ : : "m" (global_buf0));
+ /* 17 16 15 14 13 12 11 10 ...*/
+ asm volatile ("vpunpcklqdq %xmm0, %xmm1, %xmm2");
+
+ /* Then try all high bit unpack instructions with xmm registers. */
+ /* 17 27 16 26 15 25 14 24 ...*/
+ asm volatile ("vpunpckhbw %xmm0, %xmm1, %xmm15");
+ /* 17 16 27 26 15 14 25 24 ...*/
+ asm volatile ("vpunpckhwd %0, %%xmm1, %%xmm15"
+ : : "m" (global_buf0));
+ /* 17 16 15 14 27 26 25 24 ...*/
+ asm volatile ("vpunpckhdq %0, %%xmm1, %%xmm2"
+ : : "m" (global_buf0));
+ /* 17 16 15 14 13 12 11 10 ...*/
+ asm volatile ("vpunpckhqdq %xmm0, %xmm1, %xmm2");
+
+ /* Lastly, lets test a few unpack instructions with ymm registers. */
+ /* 17 27 16 26 15 25 14 24 ...*/
+ asm volatile ("vpunpcklbw %ymm0, %ymm1, %ymm15");
+ /* 17 16 27 26 15 14 25 24 ...*/
+ asm volatile ("vpunpcklwd %ymm0, %ymm1, %ymm15");
+ /* 17 16 15 14 27 26 25 24 ...*/
+ asm volatile ("vpunpckhdq %ymm0, %ymm1, %ymm15");
+ /* 17 16 15 14 13 12 11 10 ...*/
+ asm volatile ("vpunpckhqdq %ymm0, %ymm1, %ymm15");
+ /* We have a return statement to deal with
+ epilogue in different compilers. */
+ return 0; /* end vpunpck_test */
+}
+
int
main ()
{
}
/* Zero relevant xmm registers, se we know what to look for. */
asm volatile ("vmovq %0, %%xmm0": : "m" (global_buf1));
+ asm volatile ("vmovq %0, %%xmm1": : "m" (global_buf1));
+ asm volatile ("vmovq %0, %%xmm2": : "m" (global_buf1));
asm volatile ("vmovq %0, %%xmm15": : "m" (global_buf1));
vmov_test ();
+ vpunpck_test ();
return 0; /* end of main */
}
gdb_test "reverse-step" "$insn.*" \
"${prefix}reverse-step from $insn to test register $register"
+ if {[regexp {^ymm} $register]} {
+ set value "\\\{$value\\\}"
+ }
+
gdb_test "info register $register" \
- "$register.*uint128 = $value.*" \
+ "$register.*int128 = $value.*" \
"${prefix}verify $register before $insn"
}
# Move to the end of vmov_test to set up next.
gdb_test "finish" "Run till exit from.*vmov_test.*" "leaving vmov_test"
+
+# Starting vpunpck tests.
+gdb_test_no_output \
+ "set \$ymm0.v4_int64 = {0x1716151413121110, 0x1f1e1d1c1b1a1918, 0x2726252423222120, 0x2f2e2d2c2b2a2928}"
+gdb_test_no_output \
+ "set \$ymm1.v4_int64 = {0x3736353433323130, 0x3f3e3d3c3b3a3938, 0x4746454443424140, 0x4f4e4d4c4b4a4948}"
+gdb_test_no_output "set \$ymm2.v2_int128 = {0x0, 0x0}"
+gdb_test_no_output "set \$ymm15.v2_int128 = {0xdead, 0xbeef}"
+if {[record_full_function "vpunpck"] == true} {
+ test_one_register "vpunpckhqdq" "ymm15" \
+ "0x1f1e1d1c3f3e3d3c1b1a19183b3a3938, 0x2f2e2d2c4f4e4d4c2b2a29284b4a4948" \
+ "ymm: "
+ test_one_register "vpunpckhdq" "ymm15" \
+ "0x17163736151435341312333211103130, 0x27264746252445442322434221204140" \
+ "ymm: "
+ test_one_register "vpunpcklwd" "ymm15" \
+ "0x17371636153514341333123211311030, 0x27472646254524442343224221412040" \
+ "ymm: "
+ test_one_register "vpunpcklbw" "ymm15" \
+ "0x1f1e3f3e1d1c3d3c1b1a3b3a19183938, 0x0" "ymm: "
+
+ test_one_register "vpunpckhqdq" "ymm2" \
+ "0x1f1e1d1c3f3e3d3c1b1a19183b3a3938, 0x0"
+ test_one_register "vpunpckhdq" "ymm2" \
+ "0x17161514131211103736353433323130, 0x0"
+ test_one_register "vpunpckhwd" "ymm15" \
+ "0x1f3f1e3e1d3d1c3c1b3b1a3a19391838, 0x0"
+ test_one_register "vpunpckhbw" "ymm15" \
+ "0x17163736151435341312333211103130, 0x0"
+
+ test_one_register "vpunpcklqdq" "ymm2" \
+ "0x17161514373635341312111033323130, 0x0"
+ test_one_register "vpunpckldq" "ymm2" "0x0, 0x0"
+ test_one_register "vpunpcklwd" "ymm15" \
+ "0x17371636153514341333123211311030, 0x0"
+ test_one_register "vpunpcklbw" "ymm15" "0xdead, 0xbeef"
+} else {
+ untested "couldn't test vpunpck tests"
+}
+
+# Move to the end of vmov_test to set up next.
+# Stop recording in case of recording errors.
+gdb_test "record stop" "Process record is stopped.*" \
+ "delete history for vpunpck_test"
+gdb_test "finish" "Run till exit from.*vpunpck_test.*" "leaving vpunpck_test"