From: Guinevere Larsen Date: Fri, 13 Jun 2025 17:39:50 +0000 (-0300) Subject: gdb/record: add support for AVX conversion instructions. X-Git-Tag: binutils-2_45~76 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cb37efef5b02c81e73226cac0dfea0ef00b1c8b3;p=thirdparty%2Fbinutils-gdb.git gdb/record: add support for AVX conversion instructions. 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. --- diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 0fd5efd436d..103bec4054e 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -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 */ diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index 7ae6d83a6e9..d514bf0f222 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -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 */ } diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp index f8e8ad1ad46..601ed4b0f2a 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -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"