diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h
index 7d3791a..9c1b650 100644
--- a/gdb/amd64-tdep.h
+++ b/gdb/amd64-tdep.h
@@ -57,11 +57,36 @@ enum amd64_regnum
   AMD64_GS_REGNUM,		/* %gs */
   AMD64_ST0_REGNUM = 24,	/* %st0 */
   AMD64_ST1_REGNUM,		/* %st1 */
+  AMD64_ST2_REGNUM,		/* %st2 */
+  AMD64_ST3_REGNUM,		/* %st3 */
+  AMD64_ST4_REGNUM,		/* %st4 */
+  AMD64_ST5_REGNUM,		/* %st5 */
+  AMD64_ST6_REGNUM,		/* %st6 */
+  AMD64_ST7_REGNUM,		/* %st7 */
   AMD64_FCTRL_REGNUM = AMD64_ST0_REGNUM + 8,
   AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9,
   AMD64_FTAG_REGNUM = AMD64_ST0_REGNUM + 10,
+  AMD64_FISEG_REGNUM,
+  AMD64_FIOFF_REGNUM,
+  AMD64_FOSEG_REGNUM,
+  AMD64_FOOFF_REGNUM,
+  AMD64_FOP_REGNUM,
   AMD64_XMM0_REGNUM = 40,	/* %xmm0 */
   AMD64_XMM1_REGNUM,		/* %xmm1 */
+  AMD64_XMM2_REGNUM,		/* %xmm2 */
+  AMD64_XMM3_REGNUM,		/* %xmm3 */
+  AMD64_XMM4_REGNUM,		/* %xmm4 */
+  AMD64_XMM5_REGNUM,		/* %xmm5 */
+  AMD64_XMM6_REGNUM,		/* %xmm6 */
+  AMD64_XMM7_REGNUM,		/* %xmm7 */
+  AMD64_XMM8_REGNUM,		/* %xmm8 */
+  AMD64_XMM9_REGNUM,		/* %xmm9 */
+  AMD64_XMM10_REGNUM,		/* %xmm10 */
+  AMD64_XMM11_REGNUM,		/* %xmm11 */
+  AMD64_XMM12_REGNUM,		/* %xmm12 */
+  AMD64_XMM13_REGNUM,		/* %xmm13 */
+  AMD64_XMM14_REGNUM,		/* %xmm14 */
+  AMD64_XMM15_REGNUM,		/* %xmm15 */
   AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16,
   AMD64_YMM0H_REGNUM,		/* %ymm0h */
   AMD64_YMM15H_REGNUM = AMD64_YMM0H_REGNUM + 15,
diff --git a/gdb/amd64-windows-nat.c b/gdb/amd64-windows-nat.c
index 0c7dbed..61aed8d 100644
--- a/gdb/amd64-windows-nat.c
+++ b/gdb/amd64-windows-nat.c
@@ -22,70 +22,86 @@
 
 #include <windows.h>
 
-#define context_offset(x) (offsetof (CONTEXT, x))
-static const int mappings[] =
+/* See context_register_offset_ftype.  */
+
+static int
+amd64_windows_context_register_offset (int regnum)
 {
-  context_offset (Rax),
-  context_offset (Rbx),
-  context_offset (Rcx),
-  context_offset (Rdx),
-  context_offset (Rsi),
-  context_offset (Rdi),
-  context_offset (Rbp),
-  context_offset (Rsp),
-  context_offset (R8),
-  context_offset (R9),
-  context_offset (R10),
-  context_offset (R11),
-  context_offset (R12),
-  context_offset (R13),
-  context_offset (R14),
-  context_offset (R15),
-  context_offset (Rip),
-  context_offset (EFlags),
-  context_offset (SegCs),
-  context_offset (SegSs),
-  context_offset (SegDs),
-  context_offset (SegEs),
-  context_offset (SegFs),
-  context_offset (SegGs),
-  context_offset (FloatSave.FloatRegisters[0]),
-  context_offset (FloatSave.FloatRegisters[1]),
-  context_offset (FloatSave.FloatRegisters[2]),
-  context_offset (FloatSave.FloatRegisters[3]),
-  context_offset (FloatSave.FloatRegisters[4]),
-  context_offset (FloatSave.FloatRegisters[5]),
-  context_offset (FloatSave.FloatRegisters[6]),
-  context_offset (FloatSave.FloatRegisters[7]),
-  context_offset (FloatSave.ControlWord),
-  context_offset (FloatSave.StatusWord),
-  context_offset (FloatSave.TagWord),
-  context_offset (FloatSave.ErrorSelector),
-  context_offset (FloatSave.ErrorOffset),
-  context_offset (FloatSave.DataSelector),
-  context_offset (FloatSave.DataOffset),
-  context_offset (FloatSave.ErrorSelector)
-  /* XMM0-7 */ ,
-  context_offset (Xmm0),
-  context_offset (Xmm1),
-  context_offset (Xmm2),
-  context_offset (Xmm3),
-  context_offset (Xmm4),
-  context_offset (Xmm5),
-  context_offset (Xmm6),
-  context_offset (Xmm7),
-  context_offset (Xmm8),
-  context_offset (Xmm9),
-  context_offset (Xmm10),
-  context_offset (Xmm11),
-  context_offset (Xmm12),
-  context_offset (Xmm13),
-  context_offset (Xmm14),
-  context_offset (Xmm15),
-  /* MXCSR */
-  context_offset (FloatSave.MxCsr)
-};
+#define context_offset(x) (offsetof (CONTEXT, x))
+  switch (regnum)
+    {
+      case AMD64_RAX_REGNUM: return context_offset (Rax);
+      case AMD64_RBX_REGNUM: return context_offset (Rbx);
+      case AMD64_RCX_REGNUM: return context_offset (Rcx);
+      case AMD64_RDX_REGNUM: return context_offset (Rdx);
+      case AMD64_RSI_REGNUM: return context_offset (Rsi);
+      case AMD64_RDI_REGNUM: return context_offset (Rdi);
+      case AMD64_RBP_REGNUM: return context_offset (Rbp);
+      case AMD64_RSP_REGNUM: return context_offset (Rsp);
+      case AMD64_R8_REGNUM: return context_offset (R8);
+      case AMD64_R9_REGNUM: return context_offset (R9);
+      case AMD64_R10_REGNUM: return context_offset (R10);
+      case AMD64_R11_REGNUM: return context_offset (R11);
+      case AMD64_R12_REGNUM: return context_offset (R12);
+      case AMD64_R13_REGNUM: return context_offset (R13);
+      case AMD64_R14_REGNUM: return context_offset (R14);
+      case AMD64_R15_REGNUM: return context_offset (R15);
+      case AMD64_RIP_REGNUM: return context_offset (Rip);
+      case AMD64_EFLAGS_REGNUM: return context_offset (EFlags);
+      case AMD64_CS_REGNUM: return context_offset (SegCs);
+      case AMD64_SS_REGNUM: return context_offset (SegSs);
+      case AMD64_DS_REGNUM: return context_offset (SegDs);
+      case AMD64_ES_REGNUM: return context_offset (SegEs);
+      case AMD64_FS_REGNUM: return context_offset (SegFs);
+      case AMD64_GS_REGNUM: return context_offset (SegGs);
+      case AMD64_ST0_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[0]);
+      case AMD64_ST1_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[1]);
+      case AMD64_ST2_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[2]);
+      case AMD64_ST3_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[3]);
+      case AMD64_ST4_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[4]);
+      case AMD64_ST5_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[5]);
+      case AMD64_ST6_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[6]);
+      case AMD64_ST7_REGNUM:
+	return context_offset (FloatSave.FloatRegisters[7]);
+      case AMD64_FCTRL_REGNUM: return context_offset (FloatSave.ControlWord);
+      case AMD64_FSTAT_REGNUM: return context_offset (FloatSave.StatusWord);
+      case AMD64_FTAG_REGNUM: return context_offset (FloatSave.TagWord);
+      case AMD64_FISEG_REGNUM: return context_offset (FloatSave.ErrorSelector);
+      case AMD64_FIOFF_REGNUM: return context_offset (FloatSave.ErrorOffset);
+      case AMD64_FOSEG_REGNUM: return context_offset (FloatSave.DataSelector);
+      case AMD64_FOOFF_REGNUM: return context_offset (FloatSave.DataOffset);
+      case AMD64_FOP_REGNUM: return context_offset (FloatSave.ErrorSelector);
+      case AMD64_XMM0_REGNUM: return context_offset (Xmm0);
+      case AMD64_XMM1_REGNUM: return context_offset (Xmm1);
+      case AMD64_XMM2_REGNUM: return context_offset (Xmm2);
+      case AMD64_XMM3_REGNUM: return context_offset (Xmm3);
+      case AMD64_XMM4_REGNUM: return context_offset (Xmm4);
+      case AMD64_XMM5_REGNUM: return context_offset (Xmm5);
+      case AMD64_XMM6_REGNUM: return context_offset (Xmm6);
+      case AMD64_XMM7_REGNUM: return context_offset (Xmm7);
+      case AMD64_XMM8_REGNUM: return context_offset (Xmm8);
+      case AMD64_XMM9_REGNUM: return context_offset (Xmm9);
+      case AMD64_XMM10_REGNUM: return context_offset (Xmm10);
+      case AMD64_XMM11_REGNUM: return context_offset (Xmm11);
+      case AMD64_XMM12_REGNUM: return context_offset (Xmm12);
+      case AMD64_XMM13_REGNUM: return context_offset (Xmm13);
+      case AMD64_XMM14_REGNUM: return context_offset (Xmm14);
+      case AMD64_XMM15_REGNUM: return context_offset (Xmm15);
+      case AMD64_MXCSR_REGNUM: return context_offset (FloatSave.MxCsr);
+      case AMD64_FSBASE_REGNUM: return -1 /* Not in CONTEXT struct.  */;
+      case AMD64_GSBASE_REGNUM: return -1 /* Not in CONTEXT struct.  */;
+   }
 #undef context_offset
+  
+  return -1;
+}
 
 /* segment_register_p_ftype implementation for amd64.  */
 
@@ -98,7 +114,7 @@ amd64_windows_segment_register_p (int regnum)
 void
 _initialize_amd64_windows_nat (void)
 {
-  windows_set_context_register_offsets (mappings);
+  windows_set_context_register_offset (amd64_windows_context_register_offset);
   windows_set_segment_register_p (amd64_windows_segment_register_p);
   x86_set_debug_register_length (8);
 }
diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h
index 81a93f1..8cfa935 100644
--- a/gdb/i386-tdep.h
+++ b/gdb/i386-tdep.h
@@ -285,6 +285,29 @@ enum i386_regnum
   I386_FS_REGNUM,		/* %fs */
   I386_GS_REGNUM,		/* %gs */
   I386_ST0_REGNUM,		/* %st(0) */
+  I386_ST1_REGNUM,		/* %st(1) */
+  I386_ST2_REGNUM,		/* %st(2) */
+  I386_ST3_REGNUM,		/* %st(3) */
+  I386_ST4_REGNUM,		/* %st(4) */
+  I386_ST5_REGNUM,		/* %st(5) */
+  I386_ST6_REGNUM,		/* %st(6) */
+  I386_ST7_REGNUM,		/* %st(7) */
+  I386_FCTRL_REGNUM,
+  I386_FSTAT_REGNUM,
+  I386_FTAG_REGNUM,
+  I386_FISEG_REGNUM,
+  I386_FIOFF_REGNUM,
+  I386_FOSEG_REGNUM,
+  I386_FOOFF_REGNUM,
+  I386_FOP_REGNUM,
+  I386_XMM0_REGNUM,		/* %xmm0 */
+  I386_XMM1_REGNUM,		/* %xmm1 */
+  I386_XMM2_REGNUM,		/* %xmm2 */
+  I386_XMM3_REGNUM,		/* %xmm3 */
+  I386_XMM4_REGNUM,		/* %xmm4 */
+  I386_XMM5_REGNUM,		/* %xmm5 */
+  I386_XMM6_REGNUM,		/* %xmm6 */
+  I386_XMM7_REGNUM,		/* %xmm7 */
   I386_MXCSR_REGNUM = 40,	/* %mxcsr */ 
   I386_YMM0H_REGNUM,		/* %ymm0h */
   I386_YMM7H_REGNUM = I386_YMM0H_REGNUM + 7,
diff --git a/gdb/i386-windows-nat.c b/gdb/i386-windows-nat.c
index 9efe184..1f65774 100644
--- a/gdb/i386-windows-nat.c
+++ b/gdb/i386-windows-nat.c
@@ -22,55 +22,71 @@
 
 #include <windows.h>
 
-#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
-static const int mappings[] =
+/* See context_register_offset_ftype.  */
+
+static int
+i386_windows_context_register_offset (int regnum)
 {
-  context_offset (Eax),
-  context_offset (Ecx),
-  context_offset (Edx),
-  context_offset (Ebx),
-  context_offset (Esp),
-  context_offset (Ebp),
-  context_offset (Esi),
-  context_offset (Edi),
-  context_offset (Eip),
-  context_offset (EFlags),
-  context_offset (SegCs),
-  context_offset (SegSs),
-  context_offset (SegDs),
-  context_offset (SegEs),
-  context_offset (SegFs),
-  context_offset (SegGs),
-  context_offset (FloatSave.RegisterArea[0 * 10]),
-  context_offset (FloatSave.RegisterArea[1 * 10]),
-  context_offset (FloatSave.RegisterArea[2 * 10]),
-  context_offset (FloatSave.RegisterArea[3 * 10]),
-  context_offset (FloatSave.RegisterArea[4 * 10]),
-  context_offset (FloatSave.RegisterArea[5 * 10]),
-  context_offset (FloatSave.RegisterArea[6 * 10]),
-  context_offset (FloatSave.RegisterArea[7 * 10]),
-  context_offset (FloatSave.ControlWord),
-  context_offset (FloatSave.StatusWord),
-  context_offset (FloatSave.TagWord),
-  context_offset (FloatSave.ErrorSelector),
-  context_offset (FloatSave.ErrorOffset),
-  context_offset (FloatSave.DataSelector),
-  context_offset (FloatSave.DataOffset),
-  context_offset (FloatSave.ErrorSelector)
-  /* XMM0-7 */ ,
-  context_offset (ExtendedRegisters[10*16]),
-  context_offset (ExtendedRegisters[11*16]),
-  context_offset (ExtendedRegisters[12*16]),
-  context_offset (ExtendedRegisters[13*16]),
-  context_offset (ExtendedRegisters[14*16]),
-  context_offset (ExtendedRegisters[15*16]),
-  context_offset (ExtendedRegisters[16*16]),
-  context_offset (ExtendedRegisters[17*16]),
-  /* MXCSR */
-  context_offset (ExtendedRegisters[24])
-};
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+  switch (regnum)
+    {
+      case I386_EAX_REGNUM: return context_offset (Eax);
+      case I386_ECX_REGNUM: return context_offset (Ecx);
+      case I386_EDX_REGNUM: return context_offset (Edx);
+      case I386_EBX_REGNUM: return context_offset (Ebx);
+      case I386_ESP_REGNUM: return context_offset (Esp);
+      case I386_EBP_REGNUM: return context_offset (Ebp);
+      case I386_ESI_REGNUM: return context_offset (Esi);
+      case I386_EDI_REGNUM: return context_offset (Edi);
+      case I386_EIP_REGNUM: return context_offset (Eip);
+      case I386_EFLAGS_REGNUM: return context_offset (EFlags);
+      case I386_CS_REGNUM: return context_offset (SegCs);
+      case I386_SS_REGNUM: return context_offset (SegSs);
+      case I386_DS_REGNUM: return context_offset (SegDs);
+      case I386_ES_REGNUM: return context_offset (SegEs);
+      case I386_FS_REGNUM: return context_offset (SegFs);
+      case I386_GS_REGNUM: return context_offset (SegGs);
+      case I386_ST0_REGNUM:
+	return context_offset (FloatSave.RegisterArea[0 * 10]);
+      case I386_ST1_REGNUM:
+	return context_offset (FloatSave.RegisterArea[1 * 10]);
+      case I386_ST2_REGNUM:
+	return context_offset (FloatSave.RegisterArea[2 * 10]);
+      case I386_ST3_REGNUM:
+	return context_offset (FloatSave.RegisterArea[3 * 10]);
+      case I386_ST4_REGNUM:
+	return context_offset (FloatSave.RegisterArea[4 * 10]);
+      case I386_ST5_REGNUM:
+	return context_offset (FloatSave.RegisterArea[5 * 10]);
+      case I386_ST6_REGNUM:
+	return context_offset (FloatSave.RegisterArea[6 * 10]);
+      case I386_ST7_REGNUM:
+	return context_offset (FloatSave.RegisterArea[7 * 10]);
+      case I386_FCTRL_REGNUM: return context_offset (FloatSave.ControlWord);
+      case I386_FSTAT_REGNUM: return context_offset (FloatSave.StatusWord);
+      case I386_FTAG_REGNUM: return context_offset (FloatSave.TagWord);
+      case I386_FISEG_REGNUM: return context_offset (FloatSave.ErrorSelector);
+      case I386_FIOFF_REGNUM: return context_offset (FloatSave.ErrorOffset);
+      case I386_FOSEG_REGNUM: return context_offset (FloatSave.DataSelector);
+      case I386_FOOFF_REGNUM: return context_offset (FloatSave.DataOffset);
+      case I386_FOP_REGNUM: return context_offset (FloatSave.ErrorSelector);
+      /* XMM0-7 */
+      case I386_XMM0_REGNUM: return context_offset (ExtendedRegisters[10*16]);
+      case I386_XMM1_REGNUM: return context_offset (ExtendedRegisters[11*16]);
+      case I386_XMM2_REGNUM: return context_offset (ExtendedRegisters[12*16]);
+      case I386_XMM3_REGNUM: return context_offset (ExtendedRegisters[13*16]);
+      case I386_XMM4_REGNUM: return context_offset (ExtendedRegisters[14*16]);
+      case I386_XMM5_REGNUM: return context_offset (ExtendedRegisters[15*16]);
+      case I386_XMM6_REGNUM: return context_offset (ExtendedRegisters[16*16]);
+      case I386_XMM7_REGNUM: return context_offset (ExtendedRegisters[17*16]);
+      /* MXCSR */
+      case I386_MXCSR_REGNUM: return context_offset (ExtendedRegisters[24]);
+    }
 #undef context_offset
 
+  return -1;
+}
+
 /* segment_register_p_ftype implementation for x86.  */
 
 static int
@@ -82,7 +98,7 @@ i386_windows_segment_register_p (int regnum)
 void
 _initialize_i386_windows_nat (void)
 {
-  windows_set_context_register_offsets (mappings);
+  windows_set_context_register_offset (i386_windows_context_register_offset);
   windows_set_segment_register_p (i386_windows_segment_register_p);
   x86_set_debug_register_length (4);
 }
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index c51ef8f..3d4da60 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -254,15 +254,9 @@ static int debug_memory = 0;		/* show target memory accesses */
 static int debug_exceptions = 0;	/* show target exceptions */
 static int useshell = 0;		/* use shell for subprocesses */
 
-/* This vector maps GDB's idea of a register's number into an offset
-   in the windows exception context vector.
-
-   It also contains the bit mask needed to load the register in question.
-
-   The contents of this table can only be computed by the units
-   that provide CPU-specific support for Windows native debugging.
-   These units should set the table by calling
-   windows_set_context_register_offsets.
+/* A function that returns the offset of a given register inside
+   a thread's CONTEXT structure.  Should be set via a call to
+   windows_set_context_register_offset.
 
    One day we could read a reg, we could inspect the context we
    already have loaded, if it doesn't have the bit set that we need,
@@ -272,7 +266,7 @@ static int useshell = 0;		/* use shell for subprocesses */
    the other regs of the group, and then we copy the info in and set
    out bit.  */
 
-static const int *mappings;
+static context_register_offset_ftype *context_register_offset;
 
 /* The function to use in order to determine whether a register is
    a segment register or not.  */
@@ -354,9 +348,9 @@ static windows_nat_target the_windows_nat_target;
    See the description of MAPPINGS for more details.  */
 
 void
-windows_set_context_register_offsets (const int *offsets)
+windows_set_context_register_offset (context_register_offset_ftype *fun)
 {
-  mappings = offsets;
+  context_register_offset = fun;
 }
 
 /* See windows-nat.h.  */
@@ -545,18 +539,27 @@ windows_fetch_one_register (struct regcache *regcache,
   gdb_assert (r >= 0);
   gdb_assert (!th->reload_context);
 
-  char *context_offset = ((char *) &th->context) + mappings[r];
   struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int reg_offset = context_register_offset (r);
+
+  if (reg_offset < 0)
+    {
+      /* Unsupported register, nothing we can do, so just return.
+         GDB will show it as unavailable.  */
+      return;
+    }
+
+  char *reg_buf = ((char *) &th->context) + reg_offset;
 
   if (r == I387_FISEG_REGNUM (tdep))
     {
-      long l = *((long *) context_offset) & 0xffff;
+      long l = *((long *) reg_buf) & 0xffff;
       regcache->raw_supply (r, (char *) &l);
     }
   else if (r == I387_FOP_REGNUM (tdep))
     {
-      long l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
+      long l = (*((long *) reg_buf) >> 16) & ((1 << 11) - 1);
       regcache->raw_supply (r, (char *) &l);
     }
   else if (segment_register_p (r))
@@ -564,11 +567,11 @@ windows_fetch_one_register (struct regcache *regcache,
       /* GDB treats segment registers as 32bit registers, but they are
 	 in fact only 16 bits long.  Make sure we do not read extra
 	 bits from our source buffer.  */
-      long l = *((long *) context_offset) & 0xffff;
+      long l = *((long *) reg_buf) & 0xffff;
       regcache->raw_supply (r, (char *) &l);
     }
   else
-    regcache->raw_supply (r, context_offset);
+    regcache->raw_supply (r, reg_buf);
 }
 
 void
@@ -629,7 +632,14 @@ windows_store_one_register (const struct regcache *regcache,
 {
   gdb_assert (r >= 0);
 
-  regcache->raw_collect (r, ((char *) &th->context) + mappings[r]);
+  int reg_offset = context_register_offset (r);
+  if (reg_offset < 0)
+    {
+      /* Unsupported register, nothing we can do, so just return.  */
+      return;
+    }
+
+  regcache->raw_collect (r, ((char *) &th->context) + reg_offset);
 }
 
 /* Store a new register value into the context of the thread tied to
diff --git a/gdb/windows-nat.h b/gdb/windows-nat.h
index a6a7f18..f4c9716 100644
--- a/gdb/windows-nat.h
+++ b/gdb/windows-nat.h
@@ -18,7 +18,14 @@
 #ifndef WINDOWS_NAT_H
 #define WINDOWS_NAT_H
 
-extern void windows_set_context_register_offsets (const int *offsets);
+/* A pointer to a function which, given a register number, returns
+   its offset into a thread's CONTEXT structure.
+
+   Returns a negative value if the register is not supported.  */
+typedef int (context_register_offset_ftype) (int regnum);
+
+extern void windows_set_context_register_offset
+  (context_register_offset_ftype *fun);
 
 /* A pointer to a function that should return non-zero iff REGNUM
    corresponds to one of the segment registers.  */
