diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index a6994aaf12..a9fe290307 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -7385,6 +7385,51 @@ no_support_3dnow_data:
return -1;
break;
+ case 4: /* xsave */
+ {
+ if (ir.mod == 3) {
+ opcode = (opcode << 8) | ir.modrm;
+ goto no_support;
+ }
+
+ ULONGEST rfbm_eax, rfbm_edx;
+
+ regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &rfbm_eax);
+ rfbm_eax &= (1ULL << 32) - 1;
+
+ regcache_raw_read_unsigned (regcache, I386_EDX_REGNUM, &rfbm_edx);
+ rfbm_edx &= (1ULL << 32) - 1;
+
+ uint64_t rfbm = tdep->xcr0 & (rfbm_eax | (rfbm_edx << 32));
+
+ if (rfbm & ~X86_XSTATE_ALL_MASK) {
+ printf_unfiltered (_("Process record does not support XSAVE "
+ "instruction with RFBM=%" PRIx64 ".\n"),
+ rfbm);
+ opcode = (opcode << 8) | ir.modrm;
+ goto no_support;
+ }
+
+ uint64_t tmpu64;
+ if (i386_record_lea_modrm_addr (&ir, &tmpu64))
+ return -1;
+
+ uint64_t legacy_size = 160; /* x87 xsave size */
+ if (rfbm & X86_XSTATE_SSE) {
+ if (ir.regmap[X86_RECORD_R8_REGNUM])
+ legacy_size = 416; /* 64-bit sse xsave size */
+ else
+ legacy_size = 288; /* 32-bit sse xsave size */
+ }
+ if (record_full_arch_list_add_mem (tmpu64, legacy_size))
+ return -1;
+
+ uint64_t size = X86_XSTATE_SIZE (rfbm) - 512;
+ if (record_full_arch_list_add_mem (tmpu64 + 512, size))
+ return -1;
+ }
+ break;
+
case 5: /* lfence */
case 6: /* mfence */
case 7: /* sfence clflush */
diff --git a/gdb/testsuite/gdb.reverse/i386-xsave-reverse.c b/gdb/testsuite/gdb.reverse/i386-xsave-reverse.c
new file mode 100644
index 0000000000..18453405a6
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/i386-xsave-reverse.c
@@ -0,0 +1,53 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2018 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
+
+/* Architecture tests for intel i386 platform. */
+
+#include
+#include
+#include
+
+uint32_t get_xsave_buffer_size (void) {
+ uint32_t size, eax, ecx, edx;
+ __get_cpuid_count (0xd, 0, &eax, &size, &ecx, &edx);
+
+ return size;
+}
+
+void xsave_test (void) {
+ uint32_t xsave_buf_sze = get_xsave_buffer_size ();
+ char buf[xsave_buf_sze] __attribute__ ((aligned (64)));
+ memset (buf, 0, xsave_buf_sze);
+
+ asm ("xsave %0":"=m"(buf) : "a"(~0L), "d"(~0L));
+} /* end xsave_test */
+
+void xsave_no_sse_test (void) {
+ uint32_t xsave_buf_sze = get_xsave_buffer_size ();
+ char buf[xsave_buf_sze] __attribute__ ((aligned (64)));
+ memset (buf, 0, xsave_buf_sze);
+
+ asm ("xsave %0":"=m"(buf): "a"((1 << 1) ^ ~0L), "d"(~0L));
+} /* end xsave_no_sse_test */
+
+int
+main ()
+{
+ xsave_test ();
+ xsave_no_sse_test ();
+ return 0; /* end of main */
+}
diff --git a/gdb/testsuite/gdb.reverse/i386-xsave-reverse.exp b/gdb/testsuite/gdb.reverse/i386-xsave-reverse.exp
new file mode 100644
index 0000000000..f3c0f93bfc
--- /dev/null
+++ b/gdb/testsuite/gdb.reverse/i386-xsave-reverse.exp
@@ -0,0 +1,102 @@
+# Copyright 2018 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+# This file is part of the gdb testsuite.
+
+#
+# This test tests some i386 general instructions for reverse execution.
+#
+
+if {![supports_reverse] || ![supports_process_record]} {
+ return
+}
+
+if ![istarget "*86*-*linux*"] then {
+ verbose "Skipping i386 reverse tests."
+ return
+}
+
+standard_testfile
+
+# some targets have leading underscores on assembly symbols.
+set additional_flags [gdb_target_symbol_prefix_flags]
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile \
+ [list debug $additional_flags]]} {
+ return -1
+}
+
+set end_of_main [gdb_get_line_number " end of main "]
+set end_xsave_test [gdb_get_line_number " end xsave_test "]
+set end_xsave_no_sse_test [gdb_get_line_number " end xsave_no_sse_test "]
+
+if ![runto main] then {
+ fail "run to main"
+ return
+}
+
+# Activate process record/replay
+gdb_test_no_output "record" "turn on process record"
+
+global hex
+global decimal
+
+#xsave_test
+
+gdb_test "break $end_xsave_test" \
+ "Breakpoint $decimal at .* line $end_xsave_test\." \
+ "set breakpoint at end of xsave_test"
+
+set test "continue to end of xsave_test"
+gdb_test_multiple "continue" $test {
+ -re " end xsave_test .*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re " Illegal instruction.*\r\n$gdb_prompt $" {
+ untested i386-xsave-reverse
+ return -1
+ }
+}
+
+gdb_test "reverse-step" "xsave.*" "reverse-step to xsave"
+
+gdb_test "print buf" ".* = '\\\\000' " \
+ "verify xsave buffer after reverse xsave"
+
+#xsave_no_sse_test
+
+gdb_test "continue" \
+ " end xsave_test .*" \
+ "continue to end of xsave_test"
+
+gdb_test "break $end_xsave_no_sse_test" \
+ "Breakpoint $decimal at .* line $end_xsave_no_sse_test\." \
+ "set breakpoint at end of xsave_no_sse_test"
+
+set test "continue to end of xsave_no_sse_test"
+gdb_test_multiple "continue" $test {
+ -re " end xsave_no_sse_test .*\r\n$gdb_prompt $" {
+ pass $test
+ }
+ -re " Illegal instruction.*\r\n$gdb_prompt $" {
+ untested i386-xsave-no-sse-reverse
+ return -1
+ }
+}
+
+gdb_test "reverse-step" "xsave.*" "reverse-step to xsave"
+
+gdb_test "print buf" ".* = '\\\\000' " \
+ "verify xsave buffer after reverse xsave (no sse)"