[3/3] gdb/record: add support to AVX unpack instructions
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Testing passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Testing passed
|
Commit Message
This commit adds support to recording instructions to unpack high
or low data from XMM registers, identified by the mnemonics in the
form: VPUNPCK [L|H] [BW|WD|DQ|QDQ].
All these instructions are encoded the exact same way, and only affect
the destination register, making them trivial to implement together.
It also updates the test gdb.reverse/i386-avx-reverse.exp to test these
new instructions.
---
gdb/i386-tdep.c | 12 ++++++
gdb/testsuite/gdb.reverse/i386-avx-reverse.c | 37 +++++++++++++++++++
.../gdb.reverse/i386-avx-reverse.exp | 26 +++++++++++++
3 files changed, 75 insertions(+)
@@ -5057,6 +5057,18 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r,
}
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);
+ record_full_arch_list_add_reg (ir->regcache, ir->regmap[X86_RECORD_XMM0_REGNUM] + ir->reg + vex_r * 8);
+ break;
+
default:
gdb_printf (gdb_stderr,
_("Process record does not support VEX instruction 0x%02x "
@@ -70,6 +70,40 @@ vmov_test ()
asm volatile ("vmovq %0, %%xmm15": "=m" (buf1));
} /* 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. */
+void
+vpunpck_test ()
+{
+ /* Using GDB, load these values onto registers, for ease of testing.
+ xmm0.uint128 = 0x1f1e1d1c1b1a19181716151413121110
+ xmm1.uint128 = 0x2f2e2d2c2b2a29282726252423222120
+ so that's easy to confirm that the unpacking went as expected. */
+
+ /* 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");
+
+ /* 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");
+} /* end vpunpck_test */
+
int
main ()
{
@@ -82,9 +116,12 @@ 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));
/* Start recording. */
vmov_test ();
+ vpunpck_test ();
return 0; /* end of main */
}
@@ -169,3 +169,29 @@ if {[record_full_function "vmov"] == true} {
gdb_test "record stop" "Process record is stopped.*" \
"delete history for vmov_test"
gdb_test "finish" "Run till exit from.*vmov_test.*" "leaving vmov_test"
+
+# Starting vpunpck tests.
+gdb_test "step" "vpunpck_test \\\(\\\) at .*" "entering vpunpck_test function"
+gdb_test_no_output "set \$xmm0.v2_int64 = {0x1716151413121110, 0x1f1e1d1c1b1a1918}"
+gdb_test_no_output "set \$xmm1.v2_int64 = {0x2726252423222120, 0x2f2e2d2c2b2a2928}"
+gdb_test_no_output "set \$xmm2.uint128 = 0x0"
+gdb_test_no_output "set \$xmm15.uint128 = 0x0"
+if {[record_full_function "vpunpck"] == true} {
+ test_one_register "vpunpckhqdq" "xmm2" "0x"
+ test_one_register "vpunpckhdq" "xmm2" "0x"
+ test_one_register "vpunpckhwd" "xmm15" "0x"
+ test_one_register "vpunpckhbw" "xmm15" "0x"
+
+ test_one_register "vpunpcklqdq" "xmm2" "0x17161514272625241312111023222120"
+ test_one_register "vpunpckldq" "xmm2" "0x0"
+ test_one_register "vpunpcklwd" "xmm15" "0x17271626152514241323122211211020"
+ test_one_register "vpunpcklbw" "xmm15" "0x0"
+} 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"