From: Guinevere Larsen Date: Thu, 9 Jan 2025 12:47:22 +0000 (-0300) Subject: gdb/record: add support for AVX floating point arithmetic instructions X-Git-Tag: binutils-2_44~140 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=39c219c58c2937b8c78335f46eb0b12c77c3188a;p=thirdparty%2Fbinutils-gdb.git gdb/record: add support for AVX floating point arithmetic instructions This commit adds support for the following types of instructions relating to floating poitn values: add, mul, sub, min, div, max. These are supported with packed or single values, and single or double precision. Some of the instructions had opcode clashes, however, considering the mechanics of recording the registers is the same on both instructions, this is just marked with a comment. Approved-By: Guinevere Larsen --- diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 44123979186..5f585b2ca7e 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -5003,9 +5003,15 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, case 0x78: /* VPBROADCASTB */ case 0x79: /* VPBROADCASTW */ - case 0x58: /* VPBROADCASTD */ - case 0x59: /* VPBROADCASTQ */ + case 0x58: /* VPBROADCASTD and VADD[P|S][S|D] */ + case 0x59: /* VPBROADCASTQ and VMUL[P|S][S|D] */ + case 0x5c: /* VSUB[P|S][S|D] */ + case 0x5d: /* VMIN[P|S][S|D] */ + case 0x5e: /* VDIV[P|S][S|D] */ + case 0x5f: /* VMAX[P|S][S|D] */ { + /* vpbroadcast and arithmethic operations are differentiated + by map_select, but it doesn't change the recording mechanics. */ i386_record_modrm (ir); int reg_offset = ir->reg + vex_r * 8; gdb_assert (tdep->num_ymm_regs > reg_offset); diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index f41c7ff2933..0c26bcd8e85 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -364,6 +364,61 @@ vpmovmskb_test () return 0; /* end vpmovmskb_test */ } +/* Test record arithmetic instructions. */ +int +arith_test () +{ + /* start arith_test. */ + /* Using GDB, load these values onto registers for testing. + ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5} + ymm1.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5} + ymm15.v2_int128 = {0x0, 0x0} + this way it's easy to confirm we're undoing things correctly. */ + asm volatile ("vaddps %xmm0, %xmm1, %xmm15"); + asm volatile ("vaddps %ymm0, %ymm1, %ymm15"); + asm volatile ("vaddpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vaddpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vaddss %xmm0, %xmm1, %xmm15"); + asm volatile ("vaddsd %xmm0, %xmm1, %xmm15"); + + asm volatile ("vmulps %xmm0, %xmm1, %xmm15"); + asm volatile ("vmulps %ymm0, %ymm1, %ymm15"); + asm volatile ("vmulpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vmulpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vmulss %xmm0, %xmm1, %xmm15"); + asm volatile ("vmulsd %xmm0, %xmm1, %xmm15"); + + asm volatile ("vsubps %xmm0, %xmm1, %xmm15"); + asm volatile ("vsubps %ymm0, %ymm1, %ymm15"); + asm volatile ("vsubpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vsubpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vsubss %xmm0, %xmm1, %xmm15"); + asm volatile ("vsubsd %xmm0, %xmm1, %xmm15"); + + asm volatile ("vdivps %xmm0, %xmm1, %xmm15"); + asm volatile ("vdivps %ymm0, %ymm1, %ymm15"); + asm volatile ("vdivpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vdivpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vdivss %xmm0, %xmm1, %xmm15"); + asm volatile ("vdivsd %xmm0, %xmm1, %xmm15"); + + asm volatile ("vminps %xmm0, %xmm1, %xmm15"); + asm volatile ("vminps %ymm0, %ymm1, %ymm15"); + asm volatile ("vminpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vminpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vminss %xmm0, %xmm1, %xmm15"); + asm volatile ("vminsd %xmm0, %xmm1, %xmm15"); + + asm volatile ("vmaxps %xmm0, %xmm1, %xmm15"); + asm volatile ("vmaxps %ymm0, %ymm1, %ymm15"); + asm volatile ("vmaxpd %xmm0, %xmm1, %xmm15"); + asm volatile ("vmaxpd %ymm0, %ymm1, %ymm15"); + asm volatile ("vmaxss %xmm0, %xmm1, %xmm15"); + asm volatile ("vmaxsd %xmm0, %xmm1, %xmm15"); + + return 0; /* end arith_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. */ @@ -392,5 +447,6 @@ main () vpor_xor_test (); vpcmpeq_test (); vpmovmskb_test (); + arith_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 e3d1bbb3faa..11532afe344 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -517,3 +517,108 @@ if {[record_full_function "vpmovmskb"] == true} { } gdb_test "finish" "Run till exit from.*vpmovmskb_test.*" \ "leaving vpmovmskb" + +# Preparation and testing arithmetic instructions. +gdb_test_no_output \ + "set \$ymm0.v8_float = {0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5}" +gdb_test_no_output \ + "set \$ymm1.v8_float = {0, 1, 2, 3, 4, 5, 6, 7}" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" + +if {[record_full_function "arith"] == true} { + test_one_register "vmaxsd" "ymm15" \ + "0x40400000400000003f8000003f000000, 0x0" "ymm operation: " + test_one_register "vmaxss" "ymm15" \ + "0x40600000402000003fc000003f000000, 0x40f0000040d0000040b0000040900000" \ + "xmm operation: " + test_one_register "vmaxpd" "ymm15" \ + "0x40600000402000003fc000003f000000, 0x0" "ymm operation: " + test_one_register "vmaxpd" "ymm15" \ + "0x40600000402000003fc000003f000000, 0x40f0000040d0000040b0000040900000" \ + "xmm operation: " + test_one_register "vmaxps" "ymm15" \ + "0x40600000402000003fc000003f000000, 0x0" "ymm operation: " + test_one_register "vmaxps" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "xmm operation: " + + test_one_register "vminsd" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "ymm operation: " + test_one_register "vminss" "ymm15" \ + "0x40400000400000003f80000000000000, 0x40e0000040c0000040a0000040800000" \ + "xmm operation: " + test_one_register "vminpd" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "ymm operation: " + test_one_register "vminpd" "ymm15" \ + "0x40400000400000003f80000000000000, 0x40e0000040c0000040a0000040800000" \ + "xmm operation: " + test_one_register "vminps" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "ymm operation: " + test_one_register "vminps" "ymm15" \ + "0x40400000400000003fafffff820001f0, 0x0" "xmm operation: " + + test_one_register "vdivsd" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "ymm operation: " + test_one_register "vdivss" "ymm15" \ + "0x3fcfffffffc000013fafffff820001f0, 0x3fdfffffffe000013fdfffffffe00001" \ + "xmm operation: " + test_one_register "vdivpd" "ymm15" \ + "0x3fcfffffffc000013fafffff820001f0, 0x0" "ymm operation: " + test_one_register "vdivpd" "ymm15" \ + "0x3f5b6db73f4ccccd3f2aaaab00000000, 0x3f6eeeef3f6c4ec53f68ba2f3f638e39" \ + "xmm operation: " + test_one_register "vdivps" "ymm15" \ + "0x3f5b6db73f4ccccd3f2aaaab00000000, 0x0" "ymm operation: " + test_one_register "vdivps" "ymm15" \ + "0x4040000040000000bfbe00007e000000, 0x0" "xmm operation: " + + test_one_register "vsubsd" "ymm15" \ + "0x40400000400000003f800000bf000000, 0x0" "ymm operation: " + test_one_register "vsubss" "ymm15" \ + "0xc058000060400000bfbe00007e000000, 0xc0e0000040e00000c0a0000040a00000" \ + "xmm operation: " + test_one_register "vsubpd" "ymm15" \ + "0xc058000060400000bfbe00007e000000, 0x0" "ymm operation: " + test_one_register "vsubpd" "ymm15" \ + "0xbf000000bf000000bf000000bf000000, 0xbf000000bf000000bf000000bf000000" \ + "xmm operation: " + test_one_register "vsubps" "ymm15" \ + "0xbf000000bf000000bf000000bf000000, 0x0" "ymm operation: " + test_one_register "vsubps" "ymm15" \ + "0x40400000400000003f5000003f000000, 0x0" "xmm operation: " + + test_one_register "vmulsd" "ymm15" \ + "0x40400000400000003f80000000000000, 0x0" "ymm operation: " + test_one_register "vmulss" "ymm15" \ + "0x40b00000802001003f5000003f000000, 0x41e00000819001064160000081100104" \ + "xmm operation: " + test_one_register "vmulpd" "ymm15" \ + "0x40b00000802001003f5000003f000000, 0x0" "ymm operation: " + test_one_register "vmulpd" "ymm15" \ + "0x4128000040a000003fc0000000000000, 0x42520000421c000041dc000041900000" \ + "xmm operation: " + test_one_register "vmulps" "ymm15" \ + "0x4128000040a000003fc0000000000000, 0x0" "ymm operation: " + test_one_register "vmulps" "ymm15" \ + "0x40400000400000003fc100003f000000, 0x0" "xmm operation: " + + test_one_register "vaddsd" "ymm15" \ + "0x40400000400000003f8000003f000000, 0x0" "ymm operation: " + test_one_register "vaddss" "ymm15" \ + "0x40640000502000003fc100003f000000, 0x40f800006130000040b8000060d00000" \ + "xmm operation: " + test_one_register "vaddpd" "ymm15" \ + "0x40640000502000003fc100003f000000, 0x0" "ymm operation: " + test_one_register "vaddpd" "ymm15" \ + "0x40d0000040900000402000003f000000, 0x41680000414800004128000041080000" \ + "xmm operation: " + test_one_register "vaddps" "ymm15" \ + "0x40d0000040900000402000003f000000, 0x0" "ymm operation: " + test_one_register "vaddps" "ymm15" "0x0, 0x0" "xmm operation: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for arith_test" +} else { + untested "couldn't run arith tests" +} +gdb_test "finish" "Run till exit from.*arith_test.*" \ + "leaving arith"