diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/i386-tdep.c | 197 | ||||
-rw-r--r-- | gdb/solib-dsbt.c | 1 | ||||
-rw-r--r-- | gdb/solib-frv.c | 1 | ||||
-rw-r--r-- | gdb/solib-svr4.c | 5 | ||||
-rw-r--r-- | gdb/solib.c | 98 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/i386-avx-reverse.c | 326 | ||||
-rw-r--r-- | gdb/testsuite/gdb.reverse/i386-avx-reverse.exp | 499 |
7 files changed, 1060 insertions, 67 deletions
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index dcb7e7b..b50a7c3 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -4800,7 +4800,7 @@ static int i386_record_floats (struct gdbarch *gdbarch, static int i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, - int opcode, struct gdbarch *gdbarch) + struct gdbarch *gdbarch) { /* We need this to find YMM (and once AVX-512 is supported, ZMM) registers. We should always save the largest available register, since an @@ -4814,6 +4814,11 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, SCOPE_EXIT { inferior_thread ()->set_executing (true); }; inferior_thread () -> set_executing (false); + uint8_t opcode; + if (record_read_memory (gdbarch, ir->addr, &opcode, 1)) + return -1; + ir->addr++; + switch (opcode) { case 0x10: /* VMOVS[S|D] XMM, mem. */ @@ -4854,12 +4859,6 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, i386_record_lea_modrm (ir); } break; - case 0x14: /* VUNPCKL[PS|PD]. */ - case 0x15: /* VUNPCKH [PS|PD]. */ - i386_record_modrm (ir); - record_full_arch_list_add_reg (ir->regcache, - tdep->ymm0_regnum + ir->reg + vex_r * 8); - break; case 0x6e: /* VMOVD XMM, reg/mem */ /* This is moving from a regular register or memory region into an XMM register. */ @@ -4989,6 +4988,27 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, } break; + case 0x19: /* VBROADCASTSD and VEXTRACTF128. */ + case 0x39: /* VEXTRACTI128. */ + i386_record_modrm (ir); + /* vextract instructions use ModRM.R/M and VEX.B to address the + output register, while vbroadcast use ModRM.Reg and VEX.R. + They are differentiated through map_select. */ + if (ir->map_select == 2) + record_full_arch_list_add_reg (ir->regcache, + tdep->ymm0_regnum + ir->reg + + 8 * vex_r); + else + record_full_arch_list_add_reg (ir->regcache, + tdep->ymm0_regnum + ir->rm + + 8 * ir->rex_b); + break; + + case 0x18: /* VBROADCASTSS and VINSERTI128. */ + case 0x20: /* VPINSRB. */ + case 0x21: /* VINSERTPS. */ + case 0x22: /* VINSR[D|Q]. */ + case 0x38: /* VINSERTF128. */ case 0x60: /* VPUNPCKLBW */ case 0x61: /* VPUNPCKLWD */ case 0x62: /* VPUNPCKLDQ */ @@ -4997,6 +5017,7 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, case 0x69: /* VPUNPCKHWD */ case 0x6a: /* VPUNPCKHDQ */ case 0x6d: /* VPUNPCKHQDQ */ + case 0xc4: /* VPINSRW. */ { i386_record_modrm (ir); int reg_offset = ir->reg + vex_r * 8; @@ -5005,6 +5026,61 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, } break; + case 0x14: /* VPEXTRB and VUNPCKL[PS|PD]. */ + case 0x15: /* VPEXTRW (to memory) and VUNPCKH [PS|PD]. */ + case 0x16: /* VPEXTR[D|Q], VPERMPS, VMOVLHPS and VMOVHP[S|D] to reg. */ + { + i386_record_modrm (ir); + /* All vpextr instructions in this case use map_select == 3, + while vpermps has map_select == 2 and the other instructions + have map_select == 1. The opcode 0xc5 is for vpextr, but also + uses map_select == 1, but due to other inconsistencies with + the other vpextr instructions, it is in a separate case to + avoid making this even more of a mess. */ + if (ir->map_select == 3) + { + if (ir->mod == 3) + { + /* ModRM.Mod being equal to 3 means this ModRM encodes + a register. */ + record_full_arch_list_add_reg (ir->regcache, + ir->regmap[X86_RECORD_REAX_REGNUM + + ir->rm]); + } + else + { + /* Even though the test only generated ModRM.Mod == 0, + in theory all values != 3 are viable to encode a memory + address, so all of them are passed along. */ + /* Size is mostly based on the opcode, except for + double/quadword difference. */ + ir->ot = opcode - 0x14; + if (opcode == 0x16 && vex_w == 1) + ir->ot ++; + /* I'm not sure if this is the original use, but in here + rip_offset is used to indicate that the RIP pointer will + be 1 byte away from where the instruction expects it to + be, because the immediate will not have been read by the + time the address changed is calculated. */ + ir->rip_offset = 1; + i386_record_lea_modrm (ir); + } + } + else + { + record_full_arch_list_add_reg (ir->regcache, + tdep->ymm0_regnum + ir->reg + + vex_r * 8); + } + break; + } + case 0xc5: /* VPEXTRW to register. */ + i386_record_modrm (ir); + record_full_arch_list_add_reg (ir->regcache, + ir->regmap[X86_RECORD_REAX_REGNUM + + ir->reg]); + break; + case 0x74: /* VPCMPEQB */ case 0x75: /* VPCMPEQB */ case 0x76: /* VPCMPEQB */ @@ -5016,17 +5092,96 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, } break; - case 0x78: /* VPBROADCASTB */ - case 0x79: /* VPBROADCASTW */ + case 0x71: /* VPS[LL|RA|RL]W with constant shift. */ + case 0x72: /* VPS[LL|RA|RL]D with constant shift. */ + case 0x73: /* VPS[LL|RL][Q|DQ] with constant shift. */ + { + record_full_arch_list_add_reg (ir->regcache, + tdep->ymm0_regnum + ir->vvvv); + 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 0x17: /* VEXTRACTPS and VMOVHP[S|D] to memory. */ + case 0x13: /* VMOVLPD to memory. */ + i386_record_modrm (ir); + if (ir->map_select == 1) /* This is the VMOV family. */ + { + ir->ot = 3; + i386_record_lea_modrm (ir); + } + else + record_full_arch_list_add_reg (ir->regcache, + ir->regmap[X86_RECORD_REAX_REGNUM + + ir->rm]); + break; + + 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 and VBLENDPS. */ + case 0x0d: /* VPERMILPD with register and VBLENDPD. */ + case 0x0e: /* VPBLENDW. */ + case 0x12: /* VMOVDDUP, VMOVHLPS and VMOVLPD to register. */ + case 0x1a: /* VBROADCASTF128. */ + case 0x2a: /* VCVTSI2SS. */ + case 0x2b: /* VPACKUSDW. */ + 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] */ + 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] */ case 0x5f: /* VMAX[P|S][S|D] */ + case 0x63: /* VPACKSSWB. */ + case 0X67: /* VPACKUSWB. */ + case 0x6b: /* VPACKSSDW. */ + case 0x70: /* VPSHUF[B|D|HW|LW]. */ + case 0x78: /* VPBROADCASTB */ + case 0x79: /* VPBROADCASTW */ + case 0xc6: /* VSHUFP[S|D]. */ + case 0xd1: /* VPSRLW, dynamic shift. */ + case 0xd2: /* VPSRLD, dynamic shift. */ + case 0xd3: /* VPSRLQ, dynamic shift. */ + case 0xd4: /* VPADDQ */ + case 0xd5: /* VPMULLW */ + case 0xdb: /* VPAND */ + case 0xdf: /* VPANDN */ + case 0xe1: /* VPSRAW, dynamic shift. */ + case 0xe2: /* VPSRAD, dynamic shift. */ + 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 */ { - /* vpbroadcast and arithmetic operations are differentiated - by map_select, but it doesn't change the recording mechanics. */ + /* This set of instructions all share the same exact way to encode + the destination register, so there's no reason to try and + differentiate them. */ i386_record_modrm (ir); int reg_offset = ir->reg + vex_r * 8; gdb_assert (tdep->num_ymm_regs > reg_offset); @@ -5035,6 +5190,17 @@ i386_record_vex (struct i386_record_s *ir, uint8_t vex_w, uint8_t vex_r, } break; + case 0x2e: /* VUCOMIS[S|D]. */ + case 0x2f: /* VCOMIS[S|D]. */ + { + /* Despite what the manual implies, saying that the first register + will be written to, actual testing shows that the only register + changed is EFLAGS. */ + record_full_arch_list_add_reg (ir->regcache, + ir->regmap[X86_RECORD_EFLAGS_REGNUM]); + break; + } + case 0x77:/* VZEROUPPER */ { int num_regs = tdep->num_ymm_regs; @@ -5127,8 +5293,11 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, "addr = %s\n", paddress (gdbarch, ir.addr)); - /* prefixes */ - while (1) + /* Process the prefixes. This used to be an infinite loop, but since + a VEX prefix is always the last one before the opcode, according to + Intel's manual anyway, and some AVX opcodes may conflict with + prefixes, it's safe to leave the loop as soon as we see VEX. */ + while (!vex_prefix) { if (record_read_memory (gdbarch, ir.addr, &opcode8, 1)) return -1; @@ -5268,7 +5437,7 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, { /* If we found the VEX prefix, i386 will either record or warn that the instruction isn't supported, so we can return the VEX result. */ - return i386_record_vex (&ir, rex_w, rex_r, opcode, gdbarch); + return i386_record_vex (&ir, rex_w, rex_r, gdbarch); } reswitch: switch (opcode) diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index f18d9a2..13623fc 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -19,7 +19,6 @@ #include "extract-store-integer.h" #include "inferior.h" -#include "gdbcore.h" #include "solib.h" #include "objfiles.h" #include "symtab.h" diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index 6165d0b..b48efe5 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -18,7 +18,6 @@ #include "extract-store-integer.h" -#include "gdbcore.h" #include "solib.h" #include "frv-tdep.h" #include "objfiles.h" diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 9b4cabf..e454254 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -3582,7 +3582,10 @@ find_debug_base_for_solib (const solib *solib) if (solib == nullptr) return 0; - svr4_info *info = get_svr4_info (current_program_space); + /* This is always called for solibs with an associated objfile. */ + gdb_assert (solib->objfile != nullptr); + + svr4_info *info = get_svr4_info (solib->objfile->pspace ()); gdb_assert (info != nullptr); auto *lm_info diff --git a/gdb/solib.c b/gdb/solib.c index e43b1a3..676688b 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -62,8 +62,8 @@ show_solib_search_path (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { gdb_printf (file, - _ ("The search path for loading non-absolute " - "shared library symbol files is %s.\n"), + _("The search path for loading non-absolute " + "shared library symbol files is %s.\n"), value); } @@ -420,7 +420,7 @@ solib_bfd_fopen (const char *pathname, int fd) if (abfd == NULL) { /* Arrange to free PATHNAME when the error is thrown. */ - error (_ ("Could not open `%s' as an executable file: %s"), pathname, + error (_("Could not open `%s' as an executable file: %s"), pathname, bfd_errmsg (bfd_get_error ())); } @@ -453,14 +453,14 @@ solib_bfd_open (const char *pathname) /* Check bfd format. */ if (!bfd_check_format (abfd.get (), bfd_object)) - error (_ ("`%s': not in executable format: %s"), + error (_("`%s': not in executable format: %s"), bfd_get_filename (abfd.get ()), bfd_errmsg (bfd_get_error ())); /* Check bfd arch. */ b = gdbarch_bfd_arch_info (current_inferior ()->arch ()); if (!b->compatible (b, bfd_get_arch_info (abfd.get ()))) - error (_ ("`%s': Shared library architecture %s is not compatible " - "with target architecture %s."), + error (_("`%s': Shared library architecture %s is not compatible " + "with target architecture %s."), bfd_get_filename (abfd.get ()), bfd_get_arch_info (abfd.get ())->printable_name, b->printable_name); @@ -534,7 +534,7 @@ solib_map_sections (solib &so) if (abfd == nullptr && mismatch) { - warning (_ ("Build-id of %ps does not match core file."), + warning (_("Build-id of %ps does not match core file."), styled_string (file_name_style.style (), filename.get ())); abfd = nullptr; @@ -658,8 +658,8 @@ solib_read_symbols (solib &so, symfile_add_flags flags) catch (const gdb_exception_error &e) { exception_fprintf (gdb_stderr, e, - _ ("Error while reading shared" - " library symbols for %s:\n"), + _("Error while reading shared" + " library symbols for %s:\n"), so.name.c_str ()); } @@ -843,8 +843,8 @@ update_solib_list (int from_tty) catch (const gdb_exception_error &e) { exception_fprintf (gdb_stderr, e, - _ ("Error while mapping shared " - "library sections:\n")); + _("Error while mapping shared " + "library sections:\n")); } /* Notify any observer that the shared object has been @@ -863,15 +863,15 @@ update_solib_list (int from_tty) stand out well. */ if (not_found == 1) - warning (_ ("Could not load shared library symbols for %ps.\n" - "Do you need \"%ps\" or \"%ps\"?"), + warning (_("Could not load shared library symbols for %ps.\n" + "Do you need \"%ps\" or \"%ps\"?"), styled_string (file_name_style.style (), not_found_filename), styled_string (command_style.style (), "set solib-search-path"), styled_string (command_style.style (), "set sysroot")); else if (not_found > 1) - warning (_ ("\ + warning (_("\ Could not load shared library symbols for %d libraries, e.g. %ps.\n\ Use the \"%ps\" command to see the complete listing.\n\ Do you need \"%ps\" or \"%ps\"?"), @@ -929,11 +929,11 @@ solib_add (const char *pattern, int from_tty, int readsyms) { if (pattern != NULL) { - gdb_printf (_ ("Loading symbols for shared libraries: %s\n"), + gdb_printf (_("Loading symbols for shared libraries: %s\n"), pattern); } else - gdb_printf (_ ("Loading symbols for shared libraries.\n")); + gdb_printf (_("Loading symbols for shared libraries.\n")); } current_program_space->solib_add_generation++; @@ -943,7 +943,7 @@ solib_add (const char *pattern, int from_tty, int readsyms) char *re_err = re_comp (pattern); if (re_err) - error (_ ("Invalid regexp: %s"), re_err); + error (_("Invalid regexp: %s"), re_err); } update_solib_list (from_tty); @@ -977,7 +977,7 @@ solib_add (const char *pattern, int from_tty, int readsyms) /* If no pattern was given, be quiet for shared libraries we have already loaded. */ if (pattern && (from_tty || info_verbose)) - gdb_printf (_ ("Symbols already loaded for %ps\n"), + gdb_printf (_("Symbols already loaded for %ps\n"), styled_string (file_name_style.style (), gdb.name.c_str ())); } @@ -1097,8 +1097,8 @@ print_solib_list_table (std::vector<const solib *> solib_list, } if (so_missing_debug_info) - uiout->message (_ ("(*): Shared library is missing " - "debugging information.\n")); + uiout->message (_("(*): Shared library is missing " + "debugging information.\n")); } /* Implement the "info sharedlibrary" command. Walk through the @@ -1116,7 +1116,7 @@ info_sharedlibrary_command (const char *pattern, int from_tty) char *re_err = re_comp (pattern); if (re_err) - error (_ ("Invalid regexp: %s"), re_err); + error (_("Invalid regexp: %s"), re_err); } update_solib_list (from_tty); @@ -1140,9 +1140,9 @@ info_sharedlibrary_command (const char *pattern, int from_tty) if (print_libs.size () == 0) { if (pattern) - uiout->message (_ ("No shared libraries matched.\n")); + uiout->message (_("No shared libraries matched.\n")); else - uiout->message (_ ("No shared libraries loaded at this time.\n")); + uiout->message (_("No shared libraries loaded at this time.\n")); } } @@ -1173,7 +1173,7 @@ info_linker_namespace_command (const char *pattern, int from_tty) if (pattern == nullptr || pattern[0] == '\0') { - uiout->message (_ ("There are %d linker namespaces loaded\n"), + uiout->message (_("There are %d linker namespaces loaded\n"), ops->num_active_namespaces ()); int printed = 0; @@ -1203,7 +1203,7 @@ info_linker_namespace_command (const char *pattern, int from_tty) char * end = nullptr; ns = strtol (pattern, &end, 10); if (end[0] != '\0') - error (_ ("Invalid linker namespace identifier: %s"), pattern); + error (_("Invalid linker namespace identifier: %s"), pattern); } all_solibs_to_print.push_back @@ -1228,10 +1228,10 @@ info_linker_namespace_command (const char *pattern, int from_tty) break; } uiout->message - (_ ("There are %zu libraries loaded in linker namespace [[%d]]\n"), + (_("There are %zu libraries loaded in linker namespace [[%d]]\n"), solibs_to_print.size (), ns); uiout->message - (_ ("Displaying libraries for linker namespace [[%d]]:\n"), ns); + (_("Displaying libraries for linker namespace [[%d]]:\n"), ns); print_solib_list_table (solibs_to_print, false); } @@ -1402,7 +1402,7 @@ static void reload_shared_libraries_1 (int from_tty) { if (print_symbol_loading_p (from_tty, 0, 0)) - gdb_printf (_ ("Loading symbols for shared libraries.\n")); + gdb_printf (_("Loading symbols for shared libraries.\n")); for (solib &so : current_program_space->solibs ()) { @@ -1449,8 +1449,8 @@ reload_shared_libraries_1 (int from_tty) catch (const gdb_exception_error &e) { exception_fprintf (gdb_stderr, e, - _ ("Error while mapping " - "shared library sections:\n")); + _("Error while mapping " + "shared library sections:\n")); got_error = true; } @@ -1530,9 +1530,9 @@ gdb_sysroot_changed (const char *ignored, int from_tty, if (!warning_issued) { - warning (_ ("\"%s\" is deprecated, use \"%s\" instead."), old_prefix, + warning (_("\"%s\" is deprecated, use \"%s\" instead."), old_prefix, new_prefix); - warning (_ ("sysroot set to \"%s\"."), gdb_sysroot.c_str ()); + warning (_("sysroot set to \"%s\"."), gdb_sysroot.c_str ()); warning_issued = true; } @@ -1545,7 +1545,7 @@ static void show_auto_solib_add (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) { - gdb_printf (file, _ ("Autoloading of shared library symbols is %s.\n"), + gdb_printf (file, _("Autoloading of shared library symbols is %s.\n"), value); } @@ -1861,23 +1861,23 @@ INIT_GDB_FILE (solib) add_com ( "sharedlibrary", class_files, sharedlibrary_command, - _ ("Load shared object library symbols for files matching REGEXP.")); + _("Load shared object library symbols for files matching REGEXP.")); cmd_list_element *info_sharedlibrary_cmd = add_info ("sharedlibrary", info_sharedlibrary_command, - _ ("Status of loaded shared object libraries.")); + _("Status of loaded shared object libraries.")); add_info_alias ("dll", info_sharedlibrary_cmd, 1); add_com ("nosharedlibrary", class_files, no_shared_libraries_command, - _ ("Unload all shared object library symbols.")); + _("Unload all shared object library symbols.")); add_info ("linker-namespaces", info_linker_namespace_command, - _ ("Get information about linker namespaces in the inferior.")); + _("Get information about linker namespaces in the inferior.")); add_setshow_boolean_cmd ("auto-solib-add", class_support, &auto_solib_add, - _ ("\ + _("\ Set autoloading of shared library symbols."), - _ ("\ + _("\ Show autoloading of shared library symbols."), - _ ("\ + _("\ If \"on\", symbols from all shared object libraries will be loaded\n\ automatically when the inferior begins execution, when the dynamic linker\n\ informs gdb that a new library has been loaded, or when attaching to the\n\ @@ -1887,11 +1887,11 @@ inferior. Otherwise, symbols must be loaded manually, using \ set_show_commands sysroot_cmds = add_setshow_optional_filename_cmd ("sysroot", class_support, - &gdb_sysroot, _ ("\ + &gdb_sysroot, _("\ Set an alternate system root."), - _ ("\ + _("\ Show the current system root."), - _ ("\ + _("\ The system root is used to load absolute shared library symbol files.\n\ For other (relative) files, you can add directories using\n\ `set solib-search-path'."), @@ -1904,22 +1904,22 @@ For other (relative) files, you can add directories using\n\ &showlist); add_setshow_optional_filename_cmd ("solib-search-path", class_support, - &solib_search_path, _ ("\ + &solib_search_path, _("\ Set the search path for loading non-absolute shared library symbol files."), - _ ("\ + _("\ Show the search path for loading non-absolute shared library symbol files."), - _ ("\ + _("\ This takes precedence over the environment variables \ PATH and LD_LIBRARY_PATH."), reload_shared_libraries, show_solib_search_path, &setlist, &showlist); - add_setshow_boolean_cmd ("solib", class_maintenance, &debug_solib, _ ("\ + add_setshow_boolean_cmd ("solib", class_maintenance, &debug_solib, _("\ Set solib debugging."), - _ ("\ + _("\ Show solib debugging."), - _ ("\ + _("\ When true, solib-related debugging output is enabled."), nullptr, nullptr, &setdebuglist, &showdebuglist); } diff --git a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c index f559d69..a3d6427 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.c +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.c @@ -30,6 +30,18 @@ char global_buf1[] = {0, 0, 0, 0, 0, 0, 0, 0, char *dyn_buf0; char *dyn_buf1; + /* Zero memory regions again, so that future tests can update them + without worry. */ +void +reset_buffers () +{ + for (int i = 0; i < 32; i++) + { + global_buf1[i] = 0; + dyn_buf1[i] = 0; + } +} + int vmov_test () { @@ -168,6 +180,22 @@ vmov_test () asm volatile ("vmovapd %%xmm0, %0" : : "m"(*dyn_buf1)); asm volatile ("vmovaps %%ymm15, %0" : : "m"(*dyn_buf1)); + /* Testing vmov[hl|lh]ps and vmov[h|l]pd. */ + asm volatile ("vmovhlps %xmm1, %xmm8, %xmm0"); + asm volatile ("vmovhlps %xmm1, %xmm2, %xmm15"); + asm volatile ("vmovlhps %xmm1, %xmm8, %xmm0"); + asm volatile ("vmovlhps %xmm1, %xmm2, %xmm15"); + + asm volatile ("vmovhps %0, %%xmm1, %%xmm0" : : "m"(buf0)); + asm volatile ("vmovhps %%xmm0, %0" : "=m" (buf1)); + asm volatile ("vmovhpd %0, %%xmm1, %%xmm15" : : "m"(global_buf0)); + asm volatile ("vmovhpd %%xmm15, %0" : "=m" (global_buf1)); + asm volatile ("vmovlpd %0, %%xmm1, %%xmm15" : : "m"(*dyn_buf0)); + asm volatile ("vmovlpd %%xmm15, %0" : "=m" (*dyn_buf1)); + + asm volatile ("vmovddup %xmm1, %xmm15"); + asm volatile ("vmovddup %ymm2, %ymm0"); + /* We have a return statement to deal with epilogue in different compilers. */ return 0; /* end vmov_test */ @@ -245,7 +273,7 @@ vpunpck_test () return 0; /* end vpunpck_test */ } -/* Test if we can record vpbroadcast instructions. */ +/* Test if we can record vpbroadcast and vbroadcast instructions. */ int vpbroadcast_test () { @@ -268,6 +296,14 @@ vpbroadcast_test () asm volatile ("vpbroadcastq %xmm1, %ymm0"); asm volatile ("vpbroadcastq %xmm1, %ymm15"); + asm volatile ("vbroadcastss %xmm1, %xmm0"); + asm volatile ("vbroadcastss %xmm1, %ymm15"); + asm volatile ("vbroadcastss %0, %%ymm0" : : "m" (global_buf0)); + asm volatile ("vbroadcastss %0, %%xmm15": : "m" (dyn_buf0)); + asm volatile ("vbroadcastsd %xmm1, %ymm0"); + asm volatile ("vbroadcastsd %0, %%ymm15": : "m" (global_buf0)); + asm volatile ("vbroadcastf128 %0, %%ymm0" : : "m" (dyn_buf0)); + /* We have a return statement to deal with epilogue in different compilers. */ return 0; /* end vpbroadcast_test */ @@ -372,6 +408,7 @@ 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} + ymm2.v2_int128 = {0x0, 0x0} ymm15.v2_int128 = {0x0, 0x0} this way it's easy to confirm we're undoing things correctly. */ asm volatile ("vaddps %xmm0, %xmm1, %xmm15"); @@ -416,6 +453,26 @@ arith_test () asm volatile ("vmaxss %xmm0, %xmm1, %xmm15"); asm volatile ("vmaxsd %xmm0, %xmm1, %xmm15"); + /* Some sanity checks for other arithmetic instructions. */ + asm volatile ("vpaddb %xmm0, %xmm1, %xmm2"); + asm volatile ("vpaddw %xmm0, %xmm1, %xmm15"); + asm volatile ("vpaddd %ymm0, %ymm1, %ymm2"); + asm volatile ("vpaddq %ymm0, %ymm1, %ymm15"); + + asm volatile ("vpmullw %xmm0, %xmm1, %xmm2"); + asm volatile ("vpmulld %xmm0, %xmm1, %xmm15"); + asm volatile ("vpmulhw %ymm0, %ymm1, %ymm2"); + asm volatile ("vpmulhuw %ymm0, %ymm1, %ymm15"); + asm volatile ("vpmuludq %ymm0, %ymm1, %ymm15"); + + asm volatile ("vxorps %xmm0, %xmm1, %xmm2"); + asm volatile ("vxorpd %ymm0, %ymm1, %ymm2"); + 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 */ } @@ -450,6 +507,264 @@ vaddsubps_test () } +/* Test record shifting instructions. */ +int +shift_test () +{ + /* start shift_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} + xmm2.uint128 = 1 + ymm15.v2_int128 = {0x0, 0x0} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vpsllw $1, %xmm1, %xmm0"); + asm volatile ("vpsllw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpslld $3, %ymm1, %ymm15"); + asm volatile ("vpslld %xmm2, %xmm1, %xmm15"); + asm volatile ("vpsllq $5, %xmm1, %xmm15"); + asm volatile ("vpsllq %xmm2, %ymm1, %ymm15"); + + asm volatile ("vpsraw $1, %xmm1, %xmm0"); + asm volatile ("vpsraw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpsrad $3, %ymm1, %ymm15"); + asm volatile ("vpsrad %xmm2, %xmm1, %xmm15"); + + asm volatile ("vpsrlw $1, %xmm1, %xmm0"); + asm volatile ("vpsrlw %xmm2, %ymm1, %ymm0"); + asm volatile ("vpsrld $3, %ymm1, %ymm15"); + asm volatile ("vpsrld %xmm2, %xmm1, %xmm15"); + asm volatile ("vpsrlq $5, %xmm1, %xmm15"); + asm volatile ("vpsrlq %xmm2, %ymm1, %ymm15"); + + /* The dq version is treated separately in the manual, so + we test it separately just to be sure. */ + asm volatile ("vpslldq $1, %xmm1, %xmm0"); + asm volatile ("vpslldq $2, %ymm1, %ymm0"); + asm volatile ("vpslldq $3, %xmm1, %xmm15"); + asm volatile ("vpslldq $4, %ymm1, %ymm15"); + + asm volatile ("vpsrldq $1, %xmm1, %xmm0"); + asm volatile ("vpsrldq $2, %ymm1, %ymm0"); + asm volatile ("vpsrldq $3, %xmm1, %xmm15"); + asm volatile ("vpsrldq $4, %ymm1, %ymm15"); + + return 0; /* end shift_test */ +} + +int +shuffle_test () +{ + /* start shuffle_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_int15 = {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 ("vpshufb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpshufb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpshufd $1, %ymm2, %ymm0"); + asm volatile ("vpshufd $2, %xmm2, %xmm15"); + + asm volatile ("vpshufhw $3, %xmm2, %xmm0"); + asm volatile ("vpshufhw $4, %ymm2, %ymm15"); + asm volatile ("vpshuflw $5, %ymm2, %ymm0"); + asm volatile ("vpshuflw $6, %xmm2, %xmm15"); + + asm volatile ("vshufps $1, %xmm1, %xmm2, %xmm0"); + asm volatile ("vshufps $2, %ymm1, %ymm2, %ymm15"); + asm volatile ("vshufpd $4, %ymm1, %ymm2, %ymm0"); + asm volatile ("vshufpd $8, %xmm1, %xmm2, %xmm15"); + + return 0; /* end shuffle_test */ +} + +int +permute_test () +{ + /* start permute_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} + eax = 0 + this way it's easy to confirm we're undoing things correctly. */ + asm volatile ("vperm2f128 $1, %ymm1, %ymm2, %ymm0"); + asm volatile ("vperm2f128 $0, %ymm1, %ymm2, %ymm15"); + asm volatile ("vperm2i128 $1, %ymm2, %ymm1, %ymm0"); + asm volatile ("vperm2i128 $0, %ymm2, %ymm1, %ymm15"); + + asm volatile ("vpermd %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermd %ymm1, %ymm2, %ymm15"); + asm volatile ("vpermq $1, %ymm1, %ymm0"); + asm volatile ("vpermq $0, %ymm2, %ymm15"); + + asm volatile ("vpermilpd %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermilpd %xmm1, %xmm2, %xmm15"); + asm volatile ("vpermilpd $1, %ymm2, %ymm15"); + asm volatile ("vpermilpd $0, %xmm2, %xmm0"); + asm volatile ("vpermilps %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermilps %xmm1, %xmm2, %xmm15"); + asm volatile ("vpermilps $1, %ymm2, %ymm15"); + asm volatile ("vpermilps $0, %xmm2, %xmm0"); + + asm volatile ("vpermpd $0, %ymm1, %ymm15"); + asm volatile ("vpermpd $0, %ymm2, %ymm0"); + asm volatile ("vpermps %ymm1, %ymm2, %ymm0"); + asm volatile ("vpermps %ymm1, %ymm2, %ymm15"); + + return 0; /* end permute_test */ +} + +int +extract_insert_test () +{ + /* start extract_insert_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} + xmm2.uint128 = 0xcafe + ymm15.v2_int128 = {0x0, 0x0} + eax = 0 + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vinserti128 $1, %xmm2, %ymm1, %ymm0"); + asm volatile ("vinsertf128 $0, %xmm2, %ymm1, %ymm15"); + asm volatile ("vextracti128 $1, %ymm1, %xmm0"); + asm volatile ("vextractf128 $0, %ymm1, %xmm15"); + asm volatile ("vinsertps $16, %xmm2, %xmm1, %xmm0"); + asm volatile ("vextractps $0, %xmm2, %rax"); + + asm volatile ("vpextrb $5, %xmm1, %rax"); + asm volatile ("vpextrb $4, %%xmm1, %0" : "=m" (global_buf1)); + asm volatile ("vpextrd $3, %xmm1, %eax"); + asm volatile ("vpextrd $2, %%xmm1, %0" : "=m" (global_buf1)); + asm volatile ("vpextrq $1, %xmm1, %rax"); + asm volatile ("vpextrq $0, %%xmm1, %0" : "=m" (global_buf1)); + + asm volatile ("vpinsrb $3, %rax, %xmm2, %xmm0"); + asm volatile ("vpinsrw $2, %eax, %xmm2, %xmm15"); + asm volatile ("vpinsrd $1, %eax, %xmm2, %xmm0"); + asm volatile ("vpinsrq $0, %rax, %xmm2, %xmm15"); + + /* vpextrw has completely different mechanics to other vpextr + instructions, so separate them for ease of testing later. */ + asm volatile ("vpextrw $1, %xmm1, %eax"); + asm volatile ("vpextrw $1, %%xmm1, %0" : "=m" (global_buf1)); + + 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 */ +} + +int +compare_test () +{ + /* start compare_test. */ + /* Using GDB, load these values onto registers for testing. + xmm0.v4_float = {0, 1.5, 2, 0} + xmm1.v4_float = {0, 1, 2.5, -1} + xmm15.v4_float = {-1, -2, 10, 100} + eflags = 2 + eflags can't be set to some values, if we set it to 0, it'll + be reset to 2, so set it to that directly to make results less + confusing. + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vcomisd %xmm0, %xmm1"); + asm volatile ("vcomiss %xmm15, %xmm1"); + asm volatile ("vucomiss %xmm1, %xmm15"); + asm volatile ("vucomisd %xmm15, %xmm0"); + + return 0; /* end compare_test */ +} + +int +pack_test () +{ + /* start pack_test. */ + /* Using GDB, load these values onto registers for testing. + xmm0.v4_float = {0, 1.5, 2, 0} + xmm1.v4_float = {0, 1, 2.5, -1} + xmm2.v4_float = {0, 1, 2.5, -1} + xmm15.v4_float = {-1, -2, 10, 100} + this way it's easy to confirm we're undoing things correctly. */ + + asm volatile ("vpacksswb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpacksswb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpackssdw %xmm1, %xmm2, %xmm15"); + asm volatile ("vpackssdw %ymm1, %ymm2, %ymm0"); + asm volatile ("vpackuswb %xmm1, %xmm2, %xmm0"); + asm volatile ("vpackuswb %ymm1, %ymm2, %ymm15"); + asm volatile ("vpackusdw %xmm1, %xmm2, %xmm15"); + asm volatile ("vpackusdw %ymm1, %ymm2, %ymm0"); + + 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. */ @@ -473,6 +788,7 @@ main () asm volatile ("vmovq %0, %%xmm15": : "m" (global_buf1)); vmov_test (); + reset_buffers (); vpunpck_test (); vpbroadcast_test (); vzeroupper_test (); @@ -482,5 +798,13 @@ main () arith_test (); vaddsubpd_test (); vaddsubps_test (); + shift_test (); + shuffle_test (); + permute_test (); + extract_insert_test (); + 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 fbcff49..7e75542 100644 --- a/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp +++ b/gdb/testsuite/gdb.reverse/i386-avx-reverse.exp @@ -149,6 +149,33 @@ global decimal if {[record_full_function "vmov"] == true} { # Now execute backwards, checking all instructions. + test_one_register "vmovddup" "ymm0" \ + "0x3736353433323130c004000000000000, 0x0" + test_one_register "vmovddup" "ymm15" \ + "0x2726252423222120, 0x0" + test_one_memory "vmovlpd" "dyn_buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x28" \ + true + test_one_register "vmovlpd" "ymm15" \ + "0x1716151413121110c004000000000000, 0x0" + test_one_memory "vmovhpd" "global_buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18" + test_one_register "vmovhpd" "ymm15" \ + "0xc004000000000000c004000000000000, 0x0" + test_one_memory "vmovhps" "buf1" \ + "\\\{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38" + test_one_register "vmovhps" "ymm0" \ + "0xc004000000000000c004000000000000, 0x0" + + test_one_register "vmovlhps" "ymm15" \ + "0x0, 0x0" + test_one_register "vmovlhps" "ymm0" \ + "0x0, 0x0" + test_one_register "vmovhlps" "ymm15" \ + "0x2f2e2d2c2b2a29280000000000000000, 0x2f2e2d2c2b2a29282726252423222120" + test_one_register "vmovhlps" "ymm0" \ + "0x2f2e2d2c2b2a29282726252423222120, 0x0" + # Explicitly test for the start of the array, since the value repeats. test_one_memory "vmovaps" "dyn_buf1" \ "\\\{0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28" true @@ -365,6 +392,24 @@ gdb_test_no_output "set \$xmm1.v2_int64 = {0x1716151413121110, 0x1f1e1d1c1b1a191 "set xmm1 for vpbroadcast" gdb_test_no_output "set \$ymm15.v2_int128 = {0x0, 0x0}" "set xmm15 for vpbroadcast" if {[record_full_function "vpbroadcast"] == true} { + test_one_register "vbroadcastf128" "ymm0" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vbroadcastsd" "ymm15" \ + "0x404060004040600040406000404060, 0x0" + test_one_register "vbroadcastsd" "ymm0" \ + "0x13121110131211101312111013121110, 0x13121110131211101312111013121110" + + test_one_register "vbroadcastss" "ymm15" \ + "0x13121110131211101312111013121110, 0x13121110131211101312111013121110" \ + "broadcast from memory" + test_one_register "vbroadcastss" "ymm0" \ + "0x13121110131211101312111013121110, 0x0" \ + "broadcast from memory" + test_one_register "vbroadcastss" "ymm15" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vbroadcastss" "ymm0" \ + "0x17161514131211101716151413121110, 0x17161514131211101716151413121110" + test_one_register "vpbroadcastq" "ymm15" "0x13121110131211101312111013121110, 0x0" test_one_register "vpbroadcastq" "ymm0" "0x13121110131211101312111013121110, 0x0" @@ -527,9 +572,43 @@ 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 \$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" \ + "0x10080000000000000000000000000000, 0x10649c00000000001044480000000000" + test_one_register "vxorpd" "ymm2" \ + "0x20000000200000004000003f000000, 0x0" + test_one_register "vxorps" "ymm2" \ + "0x10280000100800000fd0000000000000, 0x10740000106400001054000010440000" + + test_one_register "vpmuludq" "ymm15" \ + "0x10280000100800000fd0000000000000, 0x10740000106400001054000010440000" + test_one_register "vpmulhuw" "ymm15" \ + "0x0, 0x0" + test_one_register "vpmulhw" "ymm2" \ + "0x18000000000000002000000000000000, 0x0" + test_one_register "vpmulld" "ymm15" \ + "0x80a00000802000007f4000003f000000, 0x81d00000819000008150000081100000" + test_one_register "vpmullw" "ymm2" \ + "0x80a00000802000007f4000003f000000, 0x81d00000819000008150000081100000" + + test_one_register "vpaddq" "ymm15" \ + "0x80a00000802000007f4000003f000000, 0x0" + test_one_register "vpaddd" "ymm2" \ + "0x80a00000802000007e4000003f000000, 0x0" + test_one_register "vpaddw" "ymm15" \ + "0x40400000400000003fc000003f000000, 0x0" + test_one_register "vpaddb" "ymm2" \ + "0x0, 0x0" + test_one_register "vmaxsd" "ymm15" \ "0x40400000400000003f8000003f000000, 0x0" "ymm operation: " test_one_register "vmaxss" "ymm15" \ @@ -696,3 +775,423 @@ if {[record_full_function "vaddsubps"] == true} { } gdb_test "finish" "Run till exit from.*vaddsubps_test.*" \ "leaving vaddsubps" + +# Preparation and testing shifting instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for shift" +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 shift" +gdb_test_no_output "set \$xmm2.uint128 = 1" "set ymm2 for shift" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for shift" + +if {[record_full_function "shift"] == true} { + test_one_register "vpsrldq" "ymm15" \ + "0x80007000600050004000300, 0x0" \ + "High ymm register: " + test_one_register "vpsrldq" "ymm15" \ + "0x60005000400030002000100000000, 0xe000d000c000b000a000900000000" \ + "High xmm register: " + test_one_register "vpsrldq" "ymm0" \ + "0x800070006000500040003000200, 0x0" \ + "Low ymm register: " + test_one_register "vpsrldq" "ymm0" \ + "0x70006000500040003000200010000, 0xf000e000d000c000b000a00090000" \ + "Low xmm register: " + + test_one_register "vpslldq" "ymm15" \ + "0x7000600050004000300020001000000, 0x0" \ + "High ymm register: " + test_one_register "vpslldq" "ymm15" \ + "0x40003800300020002000180010000, 0x80007800700060006000580050004" \ + "High xmm register: " + test_one_register "vpslldq" "ymm0" \ + "0x8000700060005000400030002000100, 0x0" \ + "Low ymm register: " + test_one_register "vpslldq" "ymm0" \ + "0x40003000300020002000100010000, 0x80007000700060006000500050004" \ + "Low xmm register: " + + test_one_register "vpsrlq" "ymm15" \ + "0x4000380030000000200018001000, 0x0" \ + "from register: " + test_one_register "vpsrlq" "ymm15" \ + "0x40003000300020002000100010000, 0x0" \ + "from constant: " + test_one_register "vpsrld" "ymm15" \ + "0x100000000c0000000800000004000, 0x200010001c0010001800100014001" \ + "from register: " + test_one_register "vpsrld" "ymm15" \ + "0x40003000300020002000100010000, 0x0" \ + "from constant: " + test_one_register "vpsrlw" "ymm0" \ + "0x40003000300020002000100010000, 0x0" \ + "from register: " + test_one_register "vpsrlw" "ymm0" \ + "0x40003000300020002000100010000, 0x80007000700060006000500050004" \ + "from constant: " + + test_one_register "vpsrad" "ymm15" \ + "0x100000000c0000000800000004000, 0x200010001c0010001800100014001" \ + "from register: " + test_one_register "vpsrad" "ymm15" \ + "0x10000e000c000a0008000600040002, 0x20001e001c001a0018001600140012" \ + "from constant: " + test_one_register "vpsraw" "ymm0" \ + "0x40003000300020002000100010000, 0x0" \ + "from register: " + test_one_register "vpsraw" "ymm0" \ + "0x10000e000c000a0008000600040002, 0x20001e001c001a0018001600140012" \ + "from constant: " + + test_one_register "vpsllq" "ymm15" \ + "0x10000e000c000a00080006000400020, 0x0" \ + "from register: " + test_one_register "vpsllq" "ymm15" \ + "0x10000e000c000a0008000600040002, 0x0" \ + "from constant: " + test_one_register "vpslld" "ymm15" \ + "0x400038003000280020001800100008, 0x800078007000680060005800500048" \ + "from register: " + test_one_register "vpslld" "ymm15" "0x0, 0x0" "from constant: " + test_one_register "vpsllw" "ymm0" \ + "0x10000e000c000a0008000600040002, 0x0" \ + "from register: " + test_one_register "vpsllw" "ymm0" "0x0, 0x0" "from constant: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for shift_test" +} else { + untested "couldn't run shift tests" +} +gdb_test "finish" "Run till exit from.*shift_test.*" \ + "leaving shift" + +# Preparation and testing shuffling instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for shuffle" +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 shuffle" +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 shuffle" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for shuffle" + +if {[record_full_function "shuffle"] == true} { + test_one_register "vshufpd" "ymm15" \ + "0x20001000200010012001100160015, 0xa0009000a0009001a0019001e001d" \ + "high register: " + test_one_register "vshufpd" "ymm0" \ + "0x20001000200010012001100140013, 0x0" \ + "low register: " + test_one_register "vshufps" "ymm15" \ + "0x180017001600150011001100120013, 0x0" \ + "high register: " + test_one_register "vshufps" "ymm0" \ + "0x180017001600150011001100120012, 0x20001f001e001d00190019001a001a" \ + "low register: " + + test_one_register "vpshuflw" "ymm15" \ + "0x150015001600150014001300120011, 0x1d001d001e001d001c001b001a0019" \ + "high register: " + test_one_register "vpshuflw" "ymm0" \ + "0x150015001500180014001300120011, 0x0" \ + "low register: " + test_one_register "vpshufhw" "ymm15" \ + "0x120011001200110012001100160015, 0x0" \ + "high register: " + test_one_register "vpshufhw" "ymm0" \ + "0x120011001200110012001100140013, 0x1a0019001a0019001a0019001c001b" \ + "low register: " + + test_one_register "vpshufd" "ymm15" \ + "0x11151100111411001113110011121100, 0x1919190019201900191f1900191e1900" \ + "high register: " + test_one_register "vpshufd" "ymm0" \ + "0x11151100111411001113110011121100, 0x0" \ + "low register: " + test_one_register "vpshufb" "ymm15" "0x0, 0x0" "high register: " + test_one_register "vpshufb" "ymm0" "0x0, 0x0" "low register: " + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for shuffle_test" +} else { + untested "couldn't run shuffle tests" +} +gdb_test "finish" "Run till exit from.*shuffle_test.*" \ + "leaving shuffle" + +# Preparation and testing permute instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for permute" +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 permute" +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 permute" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for permute" + +if {[record_full_function "permute"] == true} { + test_one_register "vpermps" "ymm15" \ + "0x40003000200010004000300020001, 0x40003000200010004000300020001" + test_one_register "vpermps" "ymm0" \ + "0x140013001200110014001300120011, 0x140013001200110014001300120011" + test_one_register "vpermpd" "ymm0" \ + "0x120011001200110012001100120011, 0x0" + test_one_register "vpermpd" "ymm15" \ + "0x120011001200110012001100140013, 0x1a0019001a0019001a0019001c001b" + + test_one_register "vpermilps" "ymm0" \ + "0x180017001400130018001700140013, 0x20001f001c001b0020001f001c001b" \ + "register version" + test_one_register "vpermilps" "ymm15" \ + "0x180017001400130018001700140013, 0x0" \ + "register version" + test_one_register "vpermilps" "ymm15" \ + "0x140013001200110018001700160015, 0x1c001b001a0019001c001b001a0019" \ + "immediate version" + test_one_register "vpermilps" "ymm0" \ + "0x140013001200110014001300120011, 0x0" \ + "immediate version" + + test_one_register "vpermilpd" "ymm0" \ + "0x140013001200110014001300120011, 0x1c001b001a0019001c001b001a0019" \ + "register version" + test_one_register "vpermilpd" "ymm15" \ + "0x140013001200110014001300120011, 0x0" \ + "register version" + test_one_register "vpermilpd" "ymm15" \ + "0x140013001200110014001300120011, 0x140013001200110014001300120011" \ + "immediate version" + test_one_register "vpermilpd" "ymm0" \ + "0x40003000200010008000700060005, 0x40003000200010004000300020001" \ + "immediate version" + + test_one_register "vpermq" "ymm15" \ + "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003" + test_one_register "vpermq" "ymm0" \ + "0x10000f000c000b0008000700040003, 0x10000f000c000b0008000700040003" + test_one_register "vpermd" "ymm15" \ + "0x80007000600050004000300020001, 0x80007000600050004000300020001" + test_one_register "vpermd" "ymm0" \ + "0x10000f000e000d000c000b000a0009, 0x80007000600050004000300020001" + + test_one_register "vperm2i128" "ymm15" \ + "0x180017001600150014001300120011, 0x180017001600150014001300120011" + test_one_register "vperm2i128" "ymm0" \ + "0x20001f001e001d001c001b001a0019, 0x180017001600150014001300120011" + test_one_register "vperm2f128" "ymm15" "0x0, 0x0" + test_one_register "vperm2f128" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for permute_test" +} else { + untested "couldn't run permute tests" +} +gdb_test "finish" "Run till exit from.*permute_test.*" \ + "leaving permute" + +# Preparation and testing extract_insert instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for extract_insert" +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 extract_insert" +gdb_test_no_output "set \$xmm2.uint128 = 0xcafe" \ + "set ymm2 for extract_insert" +gdb_test_no_output "set \$ymm15.v2_int128 = {0,0}" "set ymm15 for extract_insert" +gdb_test_no_output "set \$rax = 0" "set eax for extract_insert" + +if {[record_full_function "extract_insert"] == true} { + test_one_memory "vpextrw" "global_buf1" \ + "\\\{0x1, 0x0, 0x2, 0x0, 0x3, 0x0, 0x4, 0x0 <repeats 25 times>" + test_one_general_register "vpextrw" "rax" "0x8000700060005" + + test_one_register "vpinsrq" "ymm15" \ + "0x50000cafe, 0x0" + test_one_register "vpinsrd" "ymm0" \ + "0x500cafe, 0x0" + test_one_register "vpinsrw" "ymm15" \ + "0x80007000600050004000300020001, 0x0" + test_one_register "vpinsrb" "ymm0" \ + "0x80007000600050000cafe00020001, 0x0" + + test_one_memory "vpextrq" "global_buf1" \ + "\\\{0x5, 0x0, 0x6, 0x0 <repeats 29 times>" + test_one_general_register "vpextrq" "rax" "0x80007" + test_one_memory "vpextrd" "global_buf1" \ + "\\\{0x3, 0x0 <repeats 31 times>" + test_one_general_register "vpextrd" "rax" "0x0" + test_one_memory "vpextrb" "global_buf1" \ + "\\\{0x0 <repeats 32 times>" + test_one_general_register "vpextrb" "rax" "0xcafe" + + test_one_general_register "vextractps" "eax" "0x0" + test_one_register "vinsertps" "ymm0" \ + "0x10000f000e000d000c000b000a0009, 0x0" + test_one_register "vextractf128" "ymm15" \ + "0xcafe, 0x10000f000e000d000c000b000a0009" + test_one_register "vextracti128" "ymm0" \ + "0x80007000600050004000300020001, 0xcafe" + test_one_register "vinsertf128" "ymm15" \ + "0x0, 0x0" + test_one_register "vinserti128" "ymm0" \ + "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for extract_insert_test" +} else { + untested "couldn't run extract_insert tests" +} +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" + +# Preparation and testing compare instructions. +gdb_test_no_output \ + "set \$xmm0.v4_float = {0, 1.5, 2, 0}" "set ymm0 for compare" +gdb_test_no_output \ + "set \$xmm1.v4_float = {0, 1, 2.5, -1}" "set ymm1 for compare" +gdb_test_no_output \ + "set \$xmm15.v4_float = {-1, -2, 10, 100}" "set ymm15 for compare" +gdb_test_no_output "set \$eflags = 2" + +if {[record_full_function "compare"] == true} { + test_one_general_register "vucomisd" "eflags" "0x203" + test_one_general_register "vucomiss" "eflags" "0x202" + test_one_general_register "vcomiss" "eflags" "0x203" + test_one_general_register "vcomisd" "eflags" "0x202" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for compare_test" +} else { + untested "couldn't run compare tests" +} +gdb_test "finish" "Run till exit from.*compare_test.*" \ + "leaving compare" + +# Preparation and testing pack instructions. +gdb_test_no_output \ + "set \$ymm0.v2_int128 = {0, 0}" "set ymm0 for pack" +gdb_test_no_output \ + "set \$ymm1.v16_int16 = {0x1020, 0x1121, 0x1222, 0x1323, 0x1424, 0x1525, 0x1626, 0x1727, 0x1828, 0x1929, 0x1a2a, 0x1b2b, 0x1c2c, 0x1d2d, 0x1e2e, 0x1f2f}" \ + "set ymm1 for pack" +gdb_test_no_output \ + "set \$ymm2.v16_int16 = {0x3040, 0x3141, 0x3242, 0x3343, 0x3444, 0x3545, 0x3646, 0x3747, 0x3848, 0x3949, 0x3a4a, 0x3b4b, 0x3c4c, 0x3d4d, 0x3e4e, 0x3f4f}" \ + "set ymm2 for pack" +gdb_test_no_output \ + "set \$ymm15.v2_int128 = {0, 0}" "set ymm15 for pack" + +if {[record_full_function "pack"] == true} { + test_one_register "vpackusdw" "ymm0" \ + "0xffffffffffffffffffffffffffffffff, 0x0" + test_one_register "vpackusdw" "ymm15" \ + "0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff" + test_one_register "vpackuswb" "ymm15" \ + "0x7fff7fff7fff7fff7fff7fff7fff7fff, 0x0" + test_one_register "vpackuswb" "ymm0" \ + "0x7fff7fff7fff7fff7fff7fff7fff7fff, 0x7fff7fff7fff7fff7fff7fff7fff7fff" + test_one_register "vpackssdw" "ymm0" \ + "0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f, 0x0" + test_one_register "vpackssdw" "ymm15" \ + "0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f, 0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f" + test_one_register "vpacksswb" "ymm15" "0x0, 0x0" + test_one_register "vpacksswb" "ymm0" "0x0, 0x0" + + gdb_test "record stop" "Process record is stopped.*" \ + "delete history for pack_test" +} else { + untested "couldn't run pack tests" +} +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" |