Index: trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py	(revision 47047)
+++ trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py	(revision 47132)
@@ -944,4 +944,50 @@
         self.fIsIDiv = fIsIDiv;
 
+    def generateInputEdgeCases(self, cbEffOp, fLong, fXcpt):
+        """ Generate edge case inputs for cbEffOp. Returns a list of pairs, dividen + divisor. """
+        # Test params.
+        uStep = 1 << (cbEffOp * 8);
+        if self.fIsIDiv:
+            uStep /= 2;
+
+        # edge tests
+        auRet = [];
+
+        uDivisor  = 1 if fLong else 3;
+        uDividend = uStep * uDivisor - 1;
+        for i in range(5 if fLong else 3):
+            auRet.append([uDividend + fXcpt, uDivisor]);
+            if self.fIsIDiv:
+                auRet.append([-uDividend - fXcpt, -uDivisor]);
+                auRet.append([-(uDividend + uDivisor + fXcpt), uDivisor]);
+                auRet.append([ (uDividend + uDivisor + fXcpt), -uDivisor]);
+            if i <= 3 and fLong:
+                auRet.append([uDividend - 1 + fXcpt*3, uDivisor]);
+                if self.fIsIDiv:
+                    auRet.append([-(uDividend - 1 + fXcpt*3), -uDivisor]);
+            uDivisor += 1;
+            uDividend += uStep;
+
+        uDivisor  = uStep - 1;
+        uDividend = uStep * uDivisor - 1;
+        for _ in range(3 if fLong else 1):
+            auRet.append([uDividend + fXcpt, uDivisor]);
+            if self.fIsIDiv:
+                auRet.append([-uDividend - fXcpt, -uDivisor]);
+            uDivisor  -= 1;
+            uDividend -= uStep;
+
+        if self.fIsIDiv:
+            uDivisor = -uStep;
+            for _ in range(3 if fLong else 1):
+                auRet.append([uDivisor * (-uStep - 1) - (not fXcpt), uDivisor]);
+                uDivisor += 1
+            uDivisor = uStep - 1;
+            for _ in range(3 if fLong else 1):
+                auRet.append([-(uDivisor * (uStep + 1) - (not fXcpt)), uDivisor]);
+                uDivisor -= 1
+
+        return auRet;
+
     def generateInputsNoXcpt(self, cbEffOp, fLong = False):
         """ Generate inputs for cbEffOp. Returns a list of pairs, dividen + divisor. """
@@ -952,39 +998,5 @@
 
         # edge tests
-        auRet = [];
-
-        uDivisor  = 1 if fLong else 3;
-        uDividend = uStep * uDivisor - 1;
-        for i in range(5 if fLong else 3):
-            auRet.append([uDividend, uDivisor]);
-            if self.fIsIDiv:
-                auRet.append([-uDividend, -uDivisor]);
-                auRet.append([-(uDividend + uDivisor - 1), uDivisor]);
-                auRet.append([ (uDividend + uDivisor - 1), -uDivisor]);
-            if i <= 3 and fLong:
-                auRet.append([uDividend - 1, uDivisor]);
-                if self.fIsIDiv:
-                    auRet.append([-(uDividend - 1), -uDivisor]);
-            uDivisor += 1;
-            uDividend += uStep;
-
-        uDivisor  = uStep - 1;
-        uDividend = uStep * uDivisor - 1;
-        for _ in range(3 if fLong else 1):
-            auRet.append([uDividend, uDivisor]);
-            if self.fIsIDiv:
-                auRet.append([-uDividend, -uDivisor]);
-            uDivisor  -= 1;
-            uDividend -= uStep;
-
-        if self.fIsIDiv:
-            uDivisor = -uStep;
-            for _ in range(3 if fLong else 1):
-                auRet.append([uDivisor * (uDivisor - 1) - 1, uDivisor]);
-                uDivisor += 1
-            uDivisor = uStep - 1;
-            for _ in range(3 if fLong else 1):
-                auRet.append([-(uDivisor * (uDivisor + 1) - 1), uDivisor]);
-                uDivisor -= 1
+        auRet = self.generateInputEdgeCases(cbEffOp, fLong, False)
 
         # random tests.
@@ -992,8 +1004,8 @@
             for _ in range(6 if fLong else 2):
                 while True:
-                    uDivisor  = randSxx(cbEffOp * 4);
+                    uDivisor  = randSxx(cbEffOp * 8);
                     if uDivisor == 0 or uDivisor >= uStep or uDivisor < -uStep:
                         continue;
-                    uDividend = randSxx(cbEffOp * 8);
+                    uDividend = randSxx(cbEffOp * 16);
                     uResult = uDividend / uDivisor;
                     if uResult >= uStep or uResult <= -uStep: # exclude difficulties
@@ -1004,8 +1016,8 @@
             for _ in range(6 if fLong else 2):
                 while True:
-                    uDivisor  = randUxx(cbEffOp * 4);
+                    uDivisor  = randUxx(cbEffOp * 8);
                     if uDivisor == 0 or uDivisor >= uStep:
                         continue;
-                    uDividend = randUxx(cbEffOp * 8);
+                    uDividend = randUxx(cbEffOp * 16);
                     uResult = uDividend / uDivisor;
                     if uResult >= uStep:
@@ -1155,4 +1167,132 @@
         return True;
 
+    def generateInputsXcpt(self, cbEffOp, fLong = False):
+        """
+        Generate inputs for cbEffOp that will overflow or underflow.
+        Returns a list of pairs, dividen + divisor.
+        """
+        # Test params.
+        uStep = 1 << (cbEffOp * 8);
+        if self.fIsIDiv:
+            uStep /= 2;
+
+        # edge tests
+        auRet = self.generateInputEdgeCases(cbEffOp, fLong, True);
+        auRet.extend([[0, 0], [1, 0], [ uStep * uStep / 2 - 1, 0]]);
+
+        # random tests.
+        if self.fIsIDiv:
+            for _ in range(6 if fLong else 2):
+                while True:
+                    uDivisor  = randSxx(cbEffOp * 8);
+                    uDividend = randSxx(cbEffOp * 16);
+                    if uDivisor >= uStep or uDivisor < -uStep:
+                        continue;
+                    if uDivisor != 0:
+                        uResult = uDividend / uDivisor;
+                        if (uResult <= uStep and uResult >= 0) or (uResult >= -uStep and uResult < 0):
+                            continue;  # exclude difficulties
+                    break;
+                auRet.append([uDividend, uDivisor]);
+        else:
+            for _ in range(6 if fLong else 2):
+                while True:
+                    uDivisor  = randUxx(cbEffOp * 8);
+                    uDividend = randUxx(cbEffOp * 16);
+                    if uDivisor >= uStep:
+                        continue;
+                    if uDivisor != 0:
+                        uResult = uDividend / uDivisor;
+                        if uResult < uStep:
+                            continue;
+                    break;
+                auRet.append([uDividend, uDivisor]);
+
+        return auRet;
+
+    def generateOneDivideErrorTestGreg(self, oGen, cbEffOp, iOp2, iDividend, iDivisor):
+        """ Generate code of one '[I]DIV rDX:rAX,<GREG>' test that causes #DE. """
+        cbMaxOp   = oGen.oTarget.getMaxOpBytes();
+        fEffOp    = ((1 << (cbEffOp *8) ) - 1);
+        fMaxOp    = UINT64_MAX if cbMaxOp == 8 else UINT32_MAX; assert cbMaxOp in [8, 4];
+        fTopOp    = fMaxOp - fEffOp;
+        fFullOp1  = ((1 << (cbEffOp*16)) - 1);
+
+        uAX       = iDividend & fFullOp1;       # full with unsigned
+        uDX       = uAX >> (cbEffOp*8);
+        uAX      &= fEffOp;
+        uOp2Val   = iDivisor & fEffOp;
+
+        if cbEffOp < cbMaxOp:
+            uAX     |= randUxx(cbMaxOp * 8) & fTopOp;
+            uDX     |= randUxx(cbMaxOp * 8) & fTopOp;
+            uOp2Val |= randUxx(cbMaxOp * 8) & fTopOp;
+        oGen.write('        ; iDividend=%#x (%d) iDivisor=%#x (%d)\n'
+                   % ( iDividend & fFullOp1, iDividend, iDivisor & fEffOp, iDivisor,));
+        oGen.write('        call VBINSTST_NAME(Common_LoadKnownValues)\n');
+        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xDX], uDX,));
+        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xAX], uAX,));
+        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2],         uOp2Val,));
+        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iOp2],));
+        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[X86_GREG_xDX],));
+        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[X86_GREG_xAX],));
+        oGen.write('        VBINSTST_TRAP_INSTR X86_XCPT_DE, 0, %-4s    %s\n'
+                   % (self.sInstr, gregName(iOp2, cbEffOp * 8),));
+        oGen.write('        call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(X86_GREG_xAX, X86_GREG_xDX, iOp2),));
+        return True;
+
+    def generateOneDivideErrorTestGreg8Bit(self, oGen, cbEffOp, iOp2, iDividend, iDivisor):
+        """ Generate code of one '[I]DIV AX,<GREG>' test that causes #DE (8-bit). """
+        cbMaxOp   = oGen.oTarget.getMaxOpBytes();
+        fMaxOp    = UINT64_MAX if cbMaxOp == 8 else UINT32_MAX; assert cbMaxOp in [8, 4];
+        iOp2X     = (iOp2 & 3) if oGen.oTarget.is8BitHighGReg(cbEffOp, iOp2) else iOp2;
+        assert iOp2X != X86_GREG_xAX;
+
+        uAX       = iDividend & UINT16_MAX;     # full with unsigned
+        uOp2Val   = iDivisor  & UINT8_MAX;
+
+        uAX       |= randUxx(cbMaxOp * 8) & (fMaxOp - UINT16_MAX);
+        uOp2Val   |= randUxx(cbMaxOp * 8) & (fMaxOp - UINT8_MAX);
+        if iOp2X != iOp2:
+            uOp2Val = rotateLeftUxx(cbMaxOp * 8, uOp2Val, 8);
+        oGen.write('        ; iDividend=%#x (%d) iDivisor=%#x (%d)\n'
+                   % ( iDividend & UINT16_MAX, iDividend, iDivisor & UINT8_MAX, iDivisor,));
+        oGen.write('        call VBINSTST_NAME(Common_LoadKnownValues)\n');
+        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[X86_GREG_xAX], uAX,));
+        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2X], uOp2Val,));
+        oGen.write('        push    %s\n'       % (oGen.oTarget.asGRegs[iOp2X],));
+        oGen.write('        push    sAX\n');
+        oGen.write('        VBINSTST_TRAP_INSTR X86_XCPT_DE, 0, %-4s    %s\n'
+                   % (self.sInstr, gregName(iOp2, cbEffOp * 8),));
+        oGen.write('        call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(X86_GREG_xAX, iOp2X),));
+        return;
+
+    def generateDivideErrorTests(self, oGen):
+        """ Generate divide error tests (raises X86_XCPT_DE). """
+        oGen.write('%ifdef VBINSTST_CAN_DO_TRAPS\n');
+
+        # We do one register variation here, assuming the standard test has got them covered.
+        # Register tests
+        if True:
+            iOp2 = oGen.oTarget.randGRegNoSp();
+            while iOp2 == X86_GREG_xAX or iOp2 == X86_GREG_xDX:
+                iOp2 = oGen.oTarget.randGRegNoSp();
+
+            for cbEffOp in ( 8, 4, 2, 1 ):
+                if cbEffOp > oGen.oTarget.getMaxOpBytes():
+                    continue;
+                oGen.write('; cbEffOp=%u iOp2=%u\n' % (cbEffOp, iOp2,));
+
+                for iDividend, iDivisor in self.generateInputsXcpt(cbEffOp, fLong = not oGen.isTiny()):
+                    oGen.newSubTest();
+                    if cbEffOp > 1:
+                        self.generateOneDivideErrorTestGreg(oGen, cbEffOp, iOp2, iDividend, iDivisor);
+                    else:
+                        self.generateOneDivideErrorTestGreg8Bit(oGen, cbEffOp, iOp2, iDividend, iDivisor);
+
+        oGen.write('%endif ; VBINSTST_CAN_DO_TRAPS\n');
+        return True;
+
+
     def generateTest(self, oGen, sTestFnName):
         oGen.write('VBINSTST_BEGINPROC %s\n' % (sTestFnName,));
@@ -1160,4 +1300,5 @@
 
         self.generateStandardTests(oGen);
+        self.generateDivideErrorTests(oGen);
 
         #oGen.write('        int3\n');
@@ -1381,4 +1522,8 @@
         return self._cSibIndexPerRun;
 
+    def isTiny(self):
+        """ Checks if we're in tiny mode."""
+        return self.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny;
+
 
     #
@@ -1446,4 +1591,7 @@
                    'VBINSTST_GLOBALNAME_EX g_uVBInsTstSubTestIndicator, data hidden\n'
                    '        dd      0\n'
+                   '%ifdef VBINSTST_CAN_DO_TRAPS\n'
+                   'VBINSTST_TRAP_RECS_BEGIN\n'
+                   '%endif\n'
                    'VBINSTST_BEGINCODE\n'
                    );
@@ -1693,4 +1841,15 @@
         """
 
+        # Terminate the trap records.
+        self.write('\n\n'
+                   ';\n'
+                   '; Terminate the trap records\n'
+                   ';\n'
+                   'VBINSTST_BEGINDATA\n'
+                   '%ifdef VBINSTST_CAN_DO_TRAPS\n'
+                   'VBINSTST_TRAP_RECS_END\n'
+                   '%endif\n'
+                   'VBINSTST_BEGINCODE\n');
+
         # Register checking functions.
         for sName in self._dCheckFns:
@@ -1788,4 +1947,7 @@
                        '        MY_PUSH_ALL\n'
                        '        sub xSP, 40h\n'
+                       '%ifdef VBINSTST_CAN_DO_TRAPS\n'
+                       '        VBINSTST_TRAP_RECS_INSTALL\n'
+                       '%endif\n'
                        '\n');
 
@@ -1806,4 +1968,7 @@
 
             self.write('\n'
+                       '%ifdef VBINSTST_CAN_DO_TRAPS\n'
+                       '        VBINSTST_TRAP_RECS_UNINSTALL\n'
+                       '%endif\n'
                        '        add  xSP, 40h\n'
                        '        MY_POP_ALL\n'
Index: trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-big.mac
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-big.mac	(revision 47047)
+++ trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-big.mac	(revision 47132)
@@ -25,31 +25,4 @@
 
 
-;; Same as BEGINPROC in asmdefs.mac.
-%macro VBINSTST_BEGINPROC 1
-VBINSTST_GLOBALNAME_EX %1, function hidden
-%endm
-
-;; Same as ENDPROC in asmdefs.mac.
-%macro VBINSTST_ENDPROC 1,
-VBINSTST_GLOBALNAME_EX %1 %+ _EndProc, function hidden
-%endm
-
-;; Same as NAME in asmdefs.mac.
-%define VBINSTST_NAME(a_Name)   TMPL_NM(a_Name)
-
-;; Same as GLOBALNAME_EX in asmdefs.mac.
-%macro VBINSTST_GLOBALNAME_EX 2,
-VBINSTST_NAME(%1):
-%endmacro
-
-;; Same as BEGINCODE in asmdefs.mac.
-%macro VBINSTST_BEGINCODE 0,
-%endmacro
-
-;; Same as BEGINDATA in asmdefs.mac.
-%macro VBINSTST_BEGINDATA 0,
-%endmacro
-
-
 ;; Call RTTestISub like function.
 %define VBINSTST_CALL_FN_SUB_TEST   call [TMPL_NM_CMN(g_pfnTestSub) xWrtRIP]
@@ -70,9 +43,14 @@
 %define VBINSTST_CALL_FN_FAILURE_4  call [TMPL_NM_CMN(g_pfnTestFailedF) xWrtRIP]
 
+;; The image base label (used by the trap macros).
+%define VBINSTST_IMAGE_BASE_LABLE bs2_big_image_start
+
+;; Wrapper for calling TestInstallTrapRecs (used by the trap macros).
+%define VBINSTST_CALL_TEST_INSTALL_TRAP_RECS  call [TMPL_NM_CMN(g_pfnTestInstallTrapRecs) xWrtRIP]
 
 ;
 ; Include the common bits (contains code using above macros)
 ;
-%include "env-common.mac"
+%include "env-bs2-r0-common.mac"
 
 %endif
Index: trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-common.mac
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-common.mac	(revision 47132)
+++ trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0-common.mac	(revision 47132)
@@ -0,0 +1,115 @@
+; $Id$
+;; @file
+; Instruction Test Environment - Boot Sector Type 2, Ring-0.
+;
+
+;
+; Copyright (C) 2006-2013 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+
+%ifndef ___env_bs2_r0_common_mac
+%define ___env_bs2_r0_common_mac
+
+
+;; Same as BEGINPROC in asmdefs.mac.
+%macro VBINSTST_BEGINPROC 1
+VBINSTST_GLOBALNAME_EX %1, function hidden
+%endm
+
+;; Same as ENDPROC in asmdefs.mac.
+%macro VBINSTST_ENDPROC 1,
+VBINSTST_GLOBALNAME_EX %1 %+ _EndProc, function hidden
+%endm
+
+;; Same as NAME in asmdefs.mac.
+%define VBINSTST_NAME(a_Name)   TMPL_NM(a_Name)
+
+;; Same as GLOBALNAME_EX in asmdefs.mac.
+%macro VBINSTST_GLOBALNAME_EX 2,
+VBINSTST_NAME(%1):
+%endmacro
+
+;; Same as BEGINCODE in asmdefs.mac.
+%macro VBINSTST_BEGINCODE 0,
+BEGINCODE
+%endmacro
+
+;; Same as BEGINDATA in asmdefs.mac.
+%macro VBINSTST_BEGINDATA 0,
+BEGINDATA
+%endmacro
+
+
+;
+; Trap related macros.
+;
+%define VBINSTST_CAN_DO_TRAPS 1
+
+%macro VBINSTST_TRAP_INSTR 3+,
+        section .traprecs
+    istruc BS2TRAPREC
+        at BS2TRAPREC.offWhere,           dd (%%trapinstr - VBINSTST_IMAGE_BASE_LABLE)
+        at BS2TRAPREC.offResumeAddend,    db (%%resume - %%trapinstr)
+        at BS2TRAPREC.u8TrapNo,           db %1
+        at BS2TRAPREC.u16ErrCd,           dw %2
+    iend
+        VBINSTST_BEGINCODE
+ %if %1 != X86_XCPT_BP
+  %%trapinstr:
+        %3
+ %else
+        %3
+  %%trapinstr:
+ %endif
+        call    VBINSTST_NAME(Common_MissingTrap_ %+ %1)
+ %%resume:
+%endmacro
+
+%macro VBINSTST_TRAP_RECS_BEGIN 0,
+        VBINSTST_BEGINDATA
+        section .traprecs progbits valign=8 vfollows=.data align=8 follows=.data
+        dq 0ffffffffeeeeeeeeh
+        dq 0ddddddddcccccccch
+VBINSTST_GLOBALNAME_EX g_aTrapRecs, hidden
+        VBINSTST_BEGINCODE
+%endmacro
+
+%macro VBINSTST_TRAP_RECS_END 0,
+        section .traprecs
+VBINSTST_GLOBALNAME_EX g_aTrapRecsEnd, hidden
+        dq 0ddddddddcccccccch
+        dq 0ffffffffeeeeeeeeh
+        VBINSTST_BEGINCODE
+%endmacro
+
+%macro VBINSTST_TRAP_RECS_INSTALL 0,
+        mov     sAX, VBINSTST_NAME(g_aTrapRecs)
+        mov     edx, VBINSTST_NAME(g_aTrapRecsEnd) - VBINSTST_NAME(g_aTrapRecs)
+        shr     edx, BS2TRAPREC_SIZE_SHIFT
+        mov     sCX, VBINSTST_IMAGE_BASE_LABLE
+        VBINSTST_CALL_TEST_INSTALL_TRAP_RECS
+%endmacro
+
+%macro VBINSTST_TRAP_RECS_UNINSTALL 0,
+        xor     sAX, sAX
+        xor     edx, edx
+        xor     sCX, sCX
+        VBINSTST_CALL_TEST_INSTALL_TRAP_RECS
+%endmacro
+
+
+;
+; Include the common bits (contains code using above macros)
+;
+%include "env-common.mac"
+
+%endif
+
Index: trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0.mac
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0.mac	(revision 47047)
+++ trunk/src/VBox/VMM/testcase/Instructions/env-bs2-r0.mac	(revision 47132)
@@ -20,31 +20,4 @@
 
 
-;; Same as BEGINPROC in asmdefs.mac.
-%macro VBINSTST_BEGINPROC 1
-VBINSTST_GLOBALNAME_EX %1, function hidden
-%endm
-
-;; Same as ENDPROC in asmdefs.mac.
-%macro VBINSTST_ENDPROC 1,
-VBINSTST_GLOBALNAME_EX %1 %+ _EndProc, function hidden
-%endm
-
-;; Same as NAME in asmdefs.mac.
-%define VBINSTST_NAME(a_Name)   TMPL_NM(a_Name)
-
-;; Same as GLOBALNAME_EX in asmdefs.mac.
-%macro VBINSTST_GLOBALNAME_EX 2,
-VBINSTST_NAME(%1):
-%endmacro
-
-;; Same as BEGINCODE in asmdefs.mac.
-%macro VBINSTST_BEGINCODE 0,
-%endmacro
-
-;; Same as BEGINDATA in asmdefs.mac.
-%macro VBINSTST_BEGINDATA 0,
-%endmacro
-
-
 ;; Call RTTestISub like function.
 %define VBINSTST_CALL_FN_SUB_TEST   call TMPL_NM_CMN(TestSub)
@@ -65,9 +38,15 @@
 %define VBINSTST_CALL_FN_FAILURE_4  call TMPL_NM_CMN(TestFailedF)
 
+;; The image base label (used by the trap macros).
+%define VBINSTST_IMAGE_BASE_LABLE start
+
+;; Wrapper for calling TestInstallTrapRecs (used by the trap macros).
+%define VBINSTST_CALL_TEST_INSTALL_TRAP_RECS  call TMPL_NM_CMN(TestInstallTrapRecs)
+
 
 ;
 ; Include the common bits (contains code using above macros)
 ;
-%include "env-common.mac"
+%include "env-bs2-r0-common.mac"
 
 %endif
Index: trunk/src/VBox/VMM/testcase/Instructions/env-common.mac
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/env-common.mac	(revision 47047)
+++ trunk/src/VBox/VMM/testcase/Instructions/env-common.mac	(revision 47132)
@@ -175,4 +175,92 @@
 
 
+%ifdef VBINSTST_CAN_DO_TRAPS
+
+;;
+; Report a missing TRAP.
+;
+; Primary purpose is save all registers and convert from our stack-based to
+; the correct calling convention for the environment.
+;
+; This function will clean up the stack upon return (to save space in the caller).
+;
+; @param    uExpected
+;
+VBINSTST_BEGINPROC Common_MissingTrap
+        MY_PUSH_ALL
+        mov     xAX, xSP                ; 16-byte align the stack and reserve space for arguments and stuff.
+        sub     xSP, 40h
+        and     xSP, ~15
+        mov     [xSP + 38h], xAX
+
+ %ifdef ASM_CALL64_GCC
+        mov     rdx, [VBINSTST_NAME(g_uVBInsTstSubTestIndicator) wrt rip]
+        movzx   rsi, byte [rbp + 10h] ; expected
+        lea     rdi, [.szFmt wrt rip]
+        VBINSTST_CALL_FN_FAILURE_2
+
+ %elifdef ASM_CALL64_MSC
+        mov     r8d, [VBINSTST_NAME(g_uVBInsTstSubTestIndicator) wrt rip]
+        movzx   rdx, byte [rbp + 10h] ; expected
+        lea     rcx, [.szFmt wrt rip]
+        VBINSTST_CALL_FN_FAILURE_2
+
+ %elifdef ASM_CALL64_BS2
+        mov     sBX, [VBINSTST_NAME(g_uVBInsTstSubTestIndicator) xWrtRIP]
+        mov     sDX, [xBP + xCB + xCB]     ; expected
+        lea     sSI, [.szFmt xWrtRIP]
+        mov     qword [xSP + xCB + 1*sCB], sBX
+        mov     qword [xSP + xCB], sDX
+        mov     [xSP], sSI
+        VBINSTST_CALL_FN_FAILURE_2
+
+ %else
+        mov     sBX, [VBINSTST_NAME(g_uVBInsTstSubTestIndicator)]
+        mov     sDX, [xBP + xCB + xCB]     ; expected
+        mov     [xSP + xCB + 1*sCB], sBX
+        mov     [xSP + xCB], sDX
+        mov     [xSP], RTCCPTR_PRE .szFmt
+        VBINSTST_CALL_FN_FAILURE_2
+ %endif
+
+        mov     xSP, [xSP + 38h]
+        MY_POP_ALL
+        ret     1*sCB
+ %if ARCH_BITS == 64
+.szFmt: db 'Missing trap %RX8 (line %RU64)', 13, 0
+ %else
+.szFmt: db 'Missing trap %RX8 (line %RU32)', 13, 0
+ %endif
+VBINSTST_ENDPROC   Common_MissingTrap
+
+ %macro Common_MissingTrapTemplate 1
+    VBINSTST_BEGINPROC Common_MissingTrap_%1
+        push    %1
+        call    VBINSTST_NAME(Common_MissingTrap)
+        ret
+    VBINSTST_ENDPROC   Common_MissingTrap_%1
+ %endmacro
+ Common_MissingTrapTemplate X86_XCPT_DE
+ Common_MissingTrapTemplate X86_XCPT_DB
+ Common_MissingTrapTemplate X86_XCPT_NMI
+ Common_MissingTrapTemplate X86_XCPT_BP
+ Common_MissingTrapTemplate X86_XCPT_OF
+ Common_MissingTrapTemplate X86_XCPT_BR
+ Common_MissingTrapTemplate X86_XCPT_UD
+ Common_MissingTrapTemplate X86_XCPT_NM
+ ;Common_MissingTrapTemplate X86_XCPT_DF
+ ;Common_MissingTrapTemplate X86_XCPT_CO_SEG_OVERRUN
+ Common_MissingTrapTemplate X86_XCPT_TS
+ Common_MissingTrapTemplate X86_XCPT_NP
+ Common_MissingTrapTemplate X86_XCPT_SS
+ Common_MissingTrapTemplate X86_XCPT_GP
+ Common_MissingTrapTemplate X86_XCPT_PF
+ Common_MissingTrapTemplate X86_XCPT_MF
+ Common_MissingTrapTemplate X86_XCPT_AC
+ ;Common_MissingTrapTemplate X86_XCPT_MC
+ Common_MissingTrapTemplate X86_XCPT_XF
+
+%endif ; VBINSTST_CAN_DO_TRAPS
+
 
 ;
Index: trunk/src/VBox/VMM/testcase/Instructions/env-iprt-r3.mac
===================================================================
--- trunk/src/VBox/VMM/testcase/Instructions/env-iprt-r3.mac	(revision 47047)
+++ trunk/src/VBox/VMM/testcase/Instructions/env-iprt-r3.mac	(revision 47132)
@@ -87,4 +87,8 @@
 
 
+;; Cannot do traps yet.
+%undef VBINSTST_CAN_DO_TRAPS
+
+
 ;
 ; Include the common bits (contains code using above macros)
