From: Guinevere Larsen Date: Thu, 12 Jun 2025 19:55:28 +0000 (-0300) Subject: gdb/record: add support for AVX blend instructions X-Git-Tag: binutils-2_45~79 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f129dba1dc0795aa810b2a8c246fd92a198f7e2;p=thirdparty%2Fbinutils-gdb.git gdb/record: add support for AVX blend instructions This commit supports for the following instructions: * VBLENDP[S|D] * VBLENDVP[S|D] * VPBLEND[D|W|VB] and test them. --- diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 45ae8b65e3d..863872dcb9f 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -5110,15 +5110,20 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, case 0x00: /* VSHUFB and VPERMQ. */ case 0x01: /* VPERMPD. */ + case 0x02: /* VPBLENDD. */ case 0x04: /* VPERMILPS with immediate. */ case 0x05: /* VPERMILPD with immediate. */ case 0x06: /* VMPERM2F128. */ - case 0x0c: /* VPERMILPS with register. */ - case 0x0d: /* VPERMILPD with register. */ + case 0x0c: /* VPERMILPS with register and VBLENDPS. */ + case 0x0d: /* VPERMILPD with register and VBLENDPD. */ + case 0x0e: /* VPBLENDW. */ case 0x1a: /* VBROADCASTF128. */ case 0x36: /* VPERMD. */ case 0x40: /* VPMULLD */ case 0x46: /* VPERM2I128. */ + case 0x4a: /* VBLENDVPS. */ + case 0x4b: /* VBLENDVPD. */ + case 0x4c: /* VPBLENDVB. */ case 0x57: /* VXORP[S|D] */ case 0x58: /* VPBROADCASTD and VADD[P|S][S|D] */ case 0x59: /* VPBROADCASTQ and VMUL[P|S][S|D] */ diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index ef7d0d86f50..c4148033f59 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -628,6 +628,32 @@ extract_insert_test () return 0; /* end extract_insert_test */ } +int +blend_test () +{ + /* start blend_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} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vblendps $5, %xmm1, %xmm2, %xmm0"); + asm volatile ("vblendpd $10, %ymm1, %ymm2, %ymm15"); + asm volatile ("vblendvps %ymm15, %ymm1, %ymm2, %ymm0"); + asm volatile ("vblendvpd %xmm0, %xmm1, %xmm2, %xmm15"); + + asm volatile ("vpblendw $94, %ymm1, %ymm2, %ymm15"); + asm volatile ("vpblendw $47, %xmm1, %xmm2, %xmm0"); + asm volatile ("vpblendd $22, %ymm1, %ymm2, %ymm0"); + asm volatile ("vpblendd $11, %xmm1, %xmm2, %xmm15"); + asm volatile ("vpblendvb %xmm0, %xmm1, %xmm2, %xmm15"); + asm volatile ("vpblendvb %ymm0, %ymm1, %ymm2, %ymm0"); + + return 0; /* end blend_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. */ @@ -664,5 +690,6 @@ main () shuffle_test (); permute_test (); extract_insert_test (); + blend_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 36e611fe0dd..7307f88fe07 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -1014,3 +1014,43 @@ if {[record_full_function "extract_insert"] == true} { } gdb_test "finish" "Run till exit from.*extract_insert_test.*" \ "leaving extract_insert" + +# Preparation and testing blend instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for blend" +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 blend" +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 blend" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for blend" + +if {[record_full_function "blend"] == true} { + test_one_register "vpblendvb" "ymm0" \ + "0x180017000600050004000300120011, 0x20001f001e001d001c001b000a0009" + test_one_register "vpblendvb" "ymm15" \ + "0x80007001600150004000300020001, 0x0" + test_one_register "vpblendd" "ymm15" \ + "0x180007001600050004000300020011, 0x20000f001e000d000c000b000a0019" + test_one_register "vpblendd" "ymm0" \ + "0x180017000600150004000300020001, 0x0" + test_one_register "vpblendw" "ymm0" \ + "0x180017001600150014001300120011, 0x20001f001e001d001c001b001a0019" + test_one_register "vpblendw" "ymm15" \ + "0x180017001600150014001300120011, 0x0" + + test_one_register "vblendvpd" "ymm15" \ + "0x80007000600050014001300120011, 0x10000f000e000d001c001b001a0019" + test_one_register "vblendvps" "ymm0" \ + "0x180017000600050014001300020001, 0x0" + test_one_register "vblendpd" "ymm15" "0x0, 0x0" + test_one_register "vblendps" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for blend_test" +} else { + untested "couldn't run blend tests" +} +gdb_test "finish" "Run till exit from.*blend_test.*" \ + "leaving blend"