diff --git a/mps/code/prmci6.h b/mps/code/prmci6.h
new file mode 100644
index 00000000000..e3fbc4f866c
--- /dev/null
+++ b/mps/code/prmci6.h
@@ -0,0 +1,65 @@
+/* prmci3.h: PROTECTION MUTATOR CONTEXT (Intel 386)
+ *
+ * $Id$
+ * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
+ *
+ * .readership: MPS developers.
+ */
+
+#ifndef prmci3_h
+#define prmci3_h
+
+
+#include "mpm.h"
+
+typedef Word *MRef; /* pointer to a machine word */
+
+MRef Prmci3AddressHoldingReg(MutatorFaultContext, unsigned int);
+
+void Prmci3DecodeFaultContext(MRef *, Byte **, MutatorFaultContext);
+
+void Prmci3StepOverIns(MutatorFaultContext, Size);
+
+#endif /* prmci3_h */
+
+
+/* C. COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2001-2002 Ravenbrook Limited .
+ * All rights reserved. This is an open source license. Contact
+ * Ravenbrook for commercial licensing options.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Redistributions in any form must be accompanied by information on how
+ * to obtain complete source code for this software and any accompanying
+ * software that uses this software. The source code must either be
+ * included in the distribution or be available for no more than the cost
+ * of distribution plus a nominal fee, and must be freely redistributable
+ * under reasonable conditions. For an executable file, complete source
+ * code means the source code for all modules it contains. It does not
+ * include source code for modules or files that typically accompany the
+ * major components of the operating system on which the executable file
+ * runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/mps/code/prmci6w3.c b/mps/code/prmci6w3.c
new file mode 100644
index 00000000000..dec14497988
--- /dev/null
+++ b/mps/code/prmci6w3.c
@@ -0,0 +1,120 @@
+/* prmci3w3.c: PROTECTION MUTATOR CONTEXT INTEL 386 (Win32)
+ *
+ * $Id$
+ * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
+ *
+ * PURPOSE
+ *
+ * .purpose: This module implements the part of the protection module
+ * that decodes the MutatorFaultContext.
+ *
+ * SOURCES
+ *
+ * .source.i486: Intel486 Microprocessor Family Programmer's
+ * Reference Manual (book.intel92).
+ *
+ * ASSUMPTIONS
+ *
+ * .assume.regref: The resisters in the context can be modified by
+ * storing into an MRef pointer.
+ */
+
+#include "prmcw3.h"
+#include "prmci3.h"
+#include "mpm.h"
+
+SRCID(prmci3w3, "$Id$");
+
+
+/* Prmci3AddressHoldingReg -- Return an address for a given machine register */
+
+MRef Prmci3AddressHoldingReg(MutatorFaultContext context, unsigned int regnum)
+{
+ PCONTEXT wincont;
+
+ AVER(regnum <= 7);
+ AVER(regnum >= 0);
+
+ wincont = context->ep->ContextRecord;
+
+ switch (regnum) {
+ case 0: return (MRef)&wincont->Eax;
+ case 1: return (MRef)&wincont->Ecx;
+ case 2: return (MRef)&wincont->Edx;
+ case 3: return (MRef)&wincont->Ebx;
+ case 4: return (MRef)&wincont->Esp;
+ case 5: return (MRef)&wincont->Ebp;
+ case 6: return (MRef)&wincont->Esi;
+ case 7: return (MRef)&wincont->Edi;
+ }
+ NOTREACHED;
+ return NULL; /* suppress warning */
+}
+
+
+/* Prmci3DecodeFaultContext -- decode fault context */
+
+void Prmci3DecodeFaultContext(MRef *faultmemReturn, Byte **insvecReturn,
+ MutatorFaultContext context)
+{
+ LPEXCEPTION_RECORD er;
+
+ er = context->ep->ExceptionRecord;
+
+ /* Assert that this is an access violation. The computation of */
+ /* faultmem depends on this. */
+ AVER(er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION);
+
+ *faultmemReturn = (MRef)er->ExceptionInformation[1];
+ *insvecReturn = (Byte*)context->ep->ContextRecord->Eip;
+}
+
+
+/* Prmci3StepOverIns -- skip an instruction by changing the context */
+
+void Prmci3StepOverIns(MutatorFaultContext context, Size inslen)
+{
+ context->ep->ContextRecord->Eip += (DWORD)inslen;
+}
+
+
+/* C. COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2001-2002 Ravenbrook Limited .
+ * All rights reserved. This is an open source license. Contact
+ * Ravenbrook for commercial licensing options.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Redistributions in any form must be accompanied by information on how
+ * to obtain complete source code for this software and any accompanying
+ * software that uses this software. The source code must either be
+ * included in the distribution or be available for no more than the cost
+ * of distribution plus a nominal fee, and must be freely redistributable
+ * under reasonable conditions. For an executable file, complete source
+ * code means the source code for all modules it contains. It does not
+ * include source code for modules or files that typically accompany the
+ * major components of the operating system on which the executable file
+ * runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/mps/code/proti6.c b/mps/code/proti6.c
new file mode 100644
index 00000000000..221fd1376af
--- /dev/null
+++ b/mps/code/proti6.c
@@ -0,0 +1,283 @@
+/* proti3.c: PROTECTION MUTATOR CONTEXT (INTEL 386)
+ *
+ * $Id$
+ * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
+ *
+ * .design: See for the generic design of the interface
+ * which is implemented in this module, including the contracts for the
+ * functions.
+ *
+ * .purpose: This module implements the part of the protection module
+ * that implements the MutatorFaultContext type.
+ *
+ * .requirements: Current requirements are for limited support only, for
+ * stepping the sorts of instructions that the Dylan compiler might
+ * generate for table vector access - i.e., a restricted subset of MOV
+ * addressing modes. This avoids the need to scan entire weak tables at
+ * an inappropriate rank when a page fault occurs.
+ *
+ *
+ * SOURCES
+ *
+ * .source.i486: Intel486 Microprocessor Family Programmer's
+ * Reference Manual
+ *
+ * .source.dylan: Dylan table code implementation. Especially the
+ * following HOPE units:
+ * D-lib-dylan!table.dylan (class , slot entry-element)
+ * D-dfmc-harp-cg!harp-primitives.dylan (method op--repeated-slot-element)
+ * D-harp-pentium-harp!moves.dylan (pentium-template ld-index)
+ *
+ *
+ * ASSUMPTIONS
+ *
+ * .assume.null: It's always safe for Prot*StepInstruction to return
+ * ResUNIMPL. A null implementation of this module would be overly
+ * conservative but otherwise correct.
+ *
+ * .assume.want: The Dylan implementation is likely to access a
+ * weak table vector using either MOV r/m32,r32 or MOV r32,r/m32
+ * instructions, where the r/m32 operand will be of one of the forms
+ * disp8[reg], disp8[reg1][reg2], disp8[reg1][reg2*4] (see .source.dylan
+ * and .source.i486)
+ *
+ * .assume.i3: Assume the following about the i386 environment:
+ * Steppable instructions (.assume.want) use the CS, DS & SS
+ * segment registers only (see .source.i486 Table 2-3).
+ * The procesor runs in 32 bit mode.
+ * The CS, DS and SS segment registers all describe identical 32-
+ * bit flat address spaces.
+ */
+
+#include "mpm.h"
+#include "prmci3.h"
+
+SRCID(proti3, "$Id$");
+
+
+/* DecodeCB -- Decode an Intel x86 control byte into Hi, Medium & Low fields */
+
+static void DecodeCB(unsigned int *hReturn,
+ unsigned int *mReturn,
+ unsigned int *lReturn,
+ Byte op)
+{
+ /* see .source.i486 Figure 26-2 */
+ unsigned int uop = (unsigned int)op;
+ *lReturn = uop & 7;
+ uop = uop >> 3;
+ *mReturn = uop & 7;
+ uop = uop >> 3;
+ *hReturn = uop & 3;
+}
+
+
+/* DecodeSIB -- Decode a Scale Index Base byte for an Intel x86 instruction */
+
+static void DecodeSIB(unsigned int *sReturn,
+ unsigned int *iReturn,
+ unsigned int *bReturn,
+ Byte op)
+{
+ DecodeCB(sReturn, iReturn, bReturn, op);
+}
+
+
+/* DecodeModRM -- Decode a ModR/M byte for an Intel x86 instruction */
+
+static void DecodeModRM(unsigned int *modReturn,
+ unsigned int *rReturn,
+ unsigned int *mReturn,
+ Byte op)
+{
+ DecodeCB(modReturn, rReturn, mReturn, op);
+}
+
+
+/* RegValue -- Return the value of a machine register from a context */
+
+static Word RegValue(MutatorFaultContext context, unsigned int regnum)
+{
+ MRef addr;
+
+ addr = Prmci3AddressHoldingReg(context, regnum);
+ return *addr;
+}
+
+
+/* Return a byte element of an instruction vector as a
+ * Word value, with sign extension
+ */
+static Word SignedInsElt(Byte insvec[], Count i)
+{
+ signed char eltb;
+
+ eltb = ((signed char*)insvec)[i];
+ return (Word)eltb;
+}
+
+
+/* If a MOV instruction is a sufficiently simple example of a
+ * move between a register and memory (in either direction),
+ * then find the register, the effective address and the size
+ * of the instruction. The instruction is considered sufficiently
+ * simple if it uses a single byte displacement, a base register,
+ * and either no index or a (possibly scaled) register.
+ */
+static Bool DecodeSimpleMov(unsigned int *regnumReturn,
+ MRef *memReturn,
+ Size *inslenReturn,
+ MutatorFaultContext context,
+ Byte insvec[])
+{
+ unsigned int mod;
+ unsigned int r;
+ unsigned int m;
+
+ DecodeModRM(&mod, &r, &m, insvec[1]); /* .source.i486 Table 26-3 */
+ if(1 == mod) {
+ /* Only know about single byte displacements, .assume.want */
+ Word base;
+ Word index;
+ Word disp;
+
+ if(4 == m) {
+ /* There is an index. */
+ unsigned int s;
+ unsigned int i;
+ unsigned int b;
+
+ DecodeSIB(&s, &i, &b, insvec[2]); /* .source.i486 Table 26-3 */
+ if(4 == i) {
+ return FALSE; /* degenerate SIB form - unused by Dylan compiler */
+ }
+ disp = SignedInsElt(insvec, 3);
+ base = RegValue(context, b);
+ index = RegValue(context, i) << s;
+ *inslenReturn = 4;
+ } else {
+ /* MOV with reg1 & [reg2+byte] parameters */
+ disp = SignedInsElt(insvec, 2);
+ base = RegValue(context, m);
+ index = 0;
+ *inslenReturn = 3;
+ }
+ *regnumReturn = r;
+ *memReturn = (MRef)(base + index + disp); /* .assume.i3 */
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static Bool IsSimpleMov(Size *inslenReturn,
+ MRef *srcReturn,
+ MRef *destReturn,
+ MutatorFaultContext context)
+{
+ Byte *insvec;
+ unsigned int regnum;
+ MRef mem;
+ MRef faultmem;
+
+ Prmci3DecodeFaultContext(&faultmem, &insvec, context);
+
+ /* .assume.want */
+ /* .source.i486 Page 26-210 */
+ if((Byte)0x8b == insvec[0]) {
+ /* This is an instruction of type MOV reg, r/m32 */
+ if(DecodeSimpleMov(®num, &mem, inslenReturn, context, insvec)) {
+ AVER(faultmem == mem); /* Ensure computed address matches exception */
+ *srcReturn = mem;
+ *destReturn = Prmci3AddressHoldingReg(context, regnum);
+ return TRUE;
+ }
+ } else if((Byte)0x89 == insvec[0]) {
+ /* This is an instruction of type MOV r/m32, reg */
+ if(DecodeSimpleMov(®num, &mem, inslenReturn, context, insvec)) {
+ AVER(faultmem == mem); /* Ensure computed address matches exception */
+ *destReturn = mem;
+ *srcReturn = Prmci3AddressHoldingReg(context, regnum);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+Bool ProtCanStepInstruction(MutatorFaultContext context)
+{
+ Size inslen;
+ MRef src;
+ MRef dest;
+
+ /* .assume.null */
+ /* .assume.want */
+ if(IsSimpleMov(&inslen, &src, &dest, context)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+Res ProtStepInstruction(MutatorFaultContext context)
+{
+ Size inslen;
+ MRef src;
+ MRef dest;
+
+ /* .assume.null */
+ /* .assume.want */
+ if(IsSimpleMov(&inslen, &src, &dest, context)) {
+ *dest = *src;
+ Prmci3StepOverIns(context, inslen);
+ return ResOK;
+ }
+
+ return ResUNIMPL;
+}
+
+
+/* C. COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2001-2002 Ravenbrook Limited .
+ * All rights reserved. This is an open source license. Contact
+ * Ravenbrook for commercial licensing options.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Redistributions in any form must be accompanied by information on how
+ * to obtain complete source code for this software and any accompanying
+ * software that uses this software. The source code must either be
+ * included in the distribution or be available for no more than the cost
+ * of distribution plus a nominal fee, and must be freely redistributable
+ * under reasonable conditions. For an executable file, complete source
+ * code means the source code for all modules it contains. It does not
+ * include source code for modules or files that typically accompany the
+ * major components of the operating system on which the executable file
+ * runs.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */