VirtualBox

Changeset 66159 in vbox


Ignore:
Timestamp:
Mar 17, 2017 10:16:24 PM (8 years ago)
Author:
vboxsync
Message:

IEM,bs3-cpu-generated-1: Implemented the BOUND instruction and prepared for EVEX prefix (AVX-512).

Location:
trunk/src/VBox
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r66104 r66159  
    52845284    IEM_GET_CTX(pVCpu)->dr[7] &= ~X86_DR7_GD;
    52855285    return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_DB, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
     5286}
     5287
     5288
     5289/** \#BR - 05.  */
     5290DECL_NO_INLINE(IEM_STATIC, VBOXSTRICTRC) iemRaiseBoundRangeExceeded(PVMCPU pVCpu)
     5291{
     5292    return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_BR, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0);
    52865293}
    52875294
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r66137 r66159  
    65316531
    65326532
     6533/**
     6534 * Implements the 16-bit version of 'BOUND'.
     6535 *
     6536 * @note    We have separate 16-bit and 32-bit variants of this function due to
     6537 *          the decoder using unsigned parameters, whereas we want signed one to
     6538 *          do the job.  This is significant for a recompiler.
     6539 */
     6540IEM_CIMPL_DEF_3(iemCImpl_bound_16, int16_t, idxArray, int16_t, idxLowerBound, int16_t, idxUpperBound)
     6541{
     6542    /*
     6543     * Check if the index is inside the bounds, otherwise raise #BR.
     6544     */
     6545    if (   idxArray >= idxLowerBound
     6546        && idxArray <= idxUpperBound)
     6547    {
     6548        iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     6549        return VINF_SUCCESS;
     6550    }
     6551
     6552    return iemRaiseBoundRangeExceeded(pVCpu);
     6553}
     6554
     6555
     6556/**
     6557 * Implements the 32-bit version of 'BOUND'.
     6558 */
     6559IEM_CIMPL_DEF_3(iemCImpl_bound_32, int32_t, idxArray, int32_t, idxLowerBound, int32_t, idxUpperBound)
     6560{
     6561    /*
     6562     * Check if the index is inside the bounds, otherwise raise #BR.
     6563     */
     6564    if (   idxArray >= idxLowerBound
     6565        && idxArray <= idxUpperBound)
     6566    {
     6567        iemRegAddToRipAndClearRF(pVCpu, cbInstr);
     6568        return VINF_SUCCESS;
     6569    }
     6570
     6571    return iemRaiseBoundRangeExceeded(pVCpu);
     6572}
    65336573
    65346574
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r65778 r66159  
    566566#endif
    567567        uint8_t bImm8;  IEM_OPCODE_GET_NEXT_U8(&bImm8);  RT_NOREF(bRm);
    568         IEMOP_HLP_DONE_DECODING();
    569     }
     568    }
     569    IEMOP_HLP_DONE_DECODING();
    570570    return IEMOP_RAISE_INVALID_OPCODE();
    571571}
     
    588588        }
    589589#endif
    590         IEMOP_HLP_DONE_DECODING();
    591     }
     590    }
     591    IEMOP_HLP_DONE_DECODING();
    592592    return IEMOP_RAISE_INVALID_OPCODE();
    593593}
     
    612612#endif
    613613        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm); RT_NOREF(bImm);
    614         IEMOP_HLP_DONE_DECODING();
    615     }
     614    }
     615    IEMOP_HLP_DONE_DECODING();
    616616    return IEMOP_RAISE_INVALID_OPCODE();
    617617}
     
    636636        }
    637637#endif
    638         IEMOP_HLP_DONE_DECODING();
    639     }
     638    }
     639    IEMOP_HLP_DONE_DECODING();
    640640    return IEMOP_RAISE_INVALID_OPCODE();
    641641}
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h

    r66138 r66159  
    18241824 * @opmincpu    80186
    18251825 * @ophints     harmless invalid_64
    1826  */
    1827 FNIEMOP_STUB(iemOp_bound_Gv_Ma__evex);
    1828 //    IEMOP_HLP_MIN_186();
     1826 * @optest      op1=0 op2=0 ->
     1827 * @optest      op1=1 op2=0 -> value.xcpt=5
     1828 * @optest      o16 / op1=0xffff op2=0x0000fffe ->
     1829 * @optest      o16 / op1=0xfffe op2=0x0000fffe ->
     1830 * @optest      o16 / op1=0x7fff op2=0x0000fffe -> value.xcpt=5
     1831 * @optest      o16 / op1=0x7fff op2=0x7ffffffe ->
     1832 * @optest      o16 / op1=0x7fff op2=0xfffe8000 -> value.xcpt=5
     1833 * @optest      o16 / op1=0x8000 op2=0xfffe8000 ->
     1834 * @optest      o16 / op1=0xffff op2=0xfffe8000 -> value.xcpt=5
     1835 * @optest      o16 / op1=0xfffe op2=0xfffe8000 ->
     1836 * @optest      o16 / op1=0xfffe op2=0x8000fffe -> value.xcpt=5
     1837 * @optest      o16 / op1=0x8000 op2=0x8000fffe -> value.xcpt=5
     1838 * @optest      o16 / op1=0x0000 op2=0x8000fffe -> value.xcpt=5
     1839 * @optest      o16 / op1=0x0001 op2=0x8000fffe -> value.xcpt=5
     1840 * @optest      o16 / op1=0xffff op2=0x0001000f -> value.xcpt=5
     1841 * @optest      o16 / op1=0x0000 op2=0x0001000f -> value.xcpt=5
     1842 * @optest      o16 / op1=0x0001 op2=0x0001000f -> value.xcpt=5
     1843 * @optest      o16 / op1=0x0002 op2=0x0001000f -> value.xcpt=5
     1844 * @optest      o16 / op1=0x0003 op2=0x0001000f -> value.xcpt=5
     1845 * @optest      o16 / op1=0x0004 op2=0x0001000f -> value.xcpt=5
     1846 * @optest      o16 / op1=0x000e op2=0x0001000f -> value.xcpt=5
     1847 * @optest      o16 / op1=0x000f op2=0x0001000f -> value.xcpt=5
     1848 * @optest      o16 / op1=0x0010 op2=0x0001000f -> value.xcpt=5
     1849 * @optest      o16 / op1=0x0011 op2=0x0001000f -> value.xcpt=5
     1850 * @optest      o32 / op1=0xffffffff op2=0x00000000fffffffe ->
     1851 * @optest      o32 / op1=0xfffffffe op2=0x00000000fffffffe ->
     1852 * @optest      o32 / op1=0x7fffffff op2=0x00000000fffffffe -> value.xcpt=5
     1853 * @optest      o32 / op1=0x7fffffff op2=0x7ffffffffffffffe ->
     1854 * @optest      o32 / op1=0x7fffffff op2=0xfffffffe80000000 -> value.xcpt=5
     1855 * @optest      o32 / op1=0x80000000 op2=0xfffffffe80000000 ->
     1856 * @optest      o32 / op1=0xffffffff op2=0xfffffffe80000000 -> value.xcpt=5
     1857 * @optest      o32 / op1=0xfffffffe op2=0xfffffffe80000000 ->
     1858 * @optest      o32 / op1=0xfffffffe op2=0x80000000fffffffe -> value.xcpt=5
     1859 * @optest      o32 / op1=0x80000000 op2=0x80000000fffffffe -> value.xcpt=5
     1860 * @optest      o32 / op1=0x00000000 op2=0x80000000fffffffe -> value.xcpt=5
     1861 * @optest      o32 / op1=0x00000002 op2=0x80000000fffffffe -> value.xcpt=5
     1862 * @optest      o32 / op1=0x00000001 op2=0x0000000100000003 -> value.xcpt=5
     1863 * @optest      o32 / op1=0x00000002 op2=0x0000000100000003 -> value.xcpt=5
     1864 * @optest      o32 / op1=0x00000003 op2=0x0000000100000003 -> value.xcpt=5
     1865 * @optest      o32 / op1=0x00000004 op2=0x0000000100000003 -> value.xcpt=5
     1866 * @optest      o32 / op1=0x00000005 op2=0x0000000100000003 -> value.xcpt=5
     1867 * @optest      o32 / op1=0x0000000e op2=0x0000000100000003 -> value.xcpt=5
     1868 * @optest      o32 / op1=0x0000000f op2=0x0000000100000003 -> value.xcpt=5
     1869 * @optest      o32 / op1=0x00000010 op2=0x0000000100000003 -> value.xcpt=5
     1870 */
     1871FNIEMOP_DEF(iemOp_bound_Gv_Ma__evex)
     1872{
     1873    /* The BOUND instruction is invalid 64-bit mode. In legacy and
     1874       compatability mode it is invalid with MOD=3.
     1875
     1876       In 32-bit mode, the EVEX prefix works by having the top two bits (MOD)
     1877       both be set.  In the Intel EVEX documentation (sdm vol 2) these are simply
     1878       given as R and X without an exact description, so we assume it builds on
     1879       the VEX one and means they are inverted wrt REX.R and REX.X.  Thus, just
     1880       like with the 3-byte VEX, 32-bit code is restrict wrt addressable registers. */
     1881    uint8_t bRm;
     1882    if (pVCpu->iem.s.enmCpuMode != IEMMODE_64BIT)
     1883    {
     1884        IEMOP_MNEMONIC2(RM_MEM, BOUND, bound, Gv, Ma, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);
     1885        IEMOP_HLP_MIN_186();
     1886        IEM_OPCODE_GET_NEXT_U8(&bRm);
     1887        if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
     1888        {
     1889            /** @todo testcase: check that there are two memory accesses involved.  Check
     1890             *        whether they're both read before the \#BR triggers. */
     1891            if (pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT)
     1892            {
     1893                IEM_MC_BEGIN(3, 1);
     1894                IEM_MC_ARG(uint16_t,    u16Index,       0); /* Note! All operands are actually signed. Lazy unsigned bird. */
     1895                IEM_MC_ARG(uint16_t,    u16LowerBounds, 1);
     1896                IEM_MC_ARG(uint16_t,    u16UpperBounds, 2);
     1897                IEM_MC_LOCAL(RTGCPTR,   GCPtrEffSrc);
     1898
     1899                IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
     1900                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     1901
     1902                IEM_MC_FETCH_GREG_U16(u16Index, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
     1903                IEM_MC_FETCH_MEM_U16(u16LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
     1904                IEM_MC_FETCH_MEM_U16_DISP(u16UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 2);
     1905
     1906                IEM_MC_CALL_CIMPL_3(iemCImpl_bound_16, u16Index, u16LowerBounds, u16UpperBounds); /* returns */
     1907                IEM_MC_END();
     1908            }
     1909            else /* 32-bit operands */
     1910            {
     1911                IEM_MC_BEGIN(3, 1);
     1912                IEM_MC_ARG(uint32_t,    u32Index,       0); /* Note! All operands are actually signed. Lazy unsigned bird. */
     1913                IEM_MC_ARG(uint32_t,    u32LowerBounds, 1);
     1914                IEM_MC_ARG(uint32_t,    u32UpperBounds, 2);
     1915                IEM_MC_LOCAL(RTGCPTR,   GCPtrEffSrc);
     1916
     1917                IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
     1918                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     1919
     1920                IEM_MC_FETCH_GREG_U32(u32Index, (bRm >> X86_MODRM_REG_SHIFT) & X86_MODRM_REG_SMASK);
     1921                IEM_MC_FETCH_MEM_U32(u32LowerBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
     1922                IEM_MC_FETCH_MEM_U32_DISP(u32UpperBounds, pVCpu->iem.s.iEffSeg, GCPtrEffSrc, 4);
     1923
     1924                IEM_MC_CALL_CIMPL_3(iemCImpl_bound_32, u32Index, u32LowerBounds, u32UpperBounds); /* returns */
     1925                IEM_MC_END();
     1926            }
     1927        }
     1928
     1929        /*
     1930         * @opdone
     1931         */
     1932        if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
     1933        {
     1934            /* Note that there is no need for the CPU to fetch further bytes
     1935               here because MODRM.MOD == 3. */
     1936            Log(("evex not supported by the guest CPU!\n"));
     1937            return IEMOP_RAISE_INVALID_OPCODE();
     1938        }
     1939    }
     1940    else
     1941    {
     1942        /** @todo check how this is decoded in 64-bit mode w/o EVEX. Intel probably
     1943         *        does modr/m read, whereas AMD probably doesn't... */
     1944        if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx512Foundation)
     1945        {
     1946            Log(("evex not supported by the guest CPU!\n"));
     1947            return FNIEMOP_CALL(iemOp_InvalidNeedRM);
     1948        }
     1949        IEM_OPCODE_GET_NEXT_U8(&bRm);
     1950    }
     1951
     1952    IEMOP_MNEMONIC(evex, "evex");
     1953    uint8_t bP2; IEM_OPCODE_GET_NEXT_U8(&bP2);
     1954    uint8_t bP3; IEM_OPCODE_GET_NEXT_U8(&bP3);
     1955    Log(("evex prefix is not implemented!\n"));
     1956    return VERR_IEM_INSTR_NOT_IMPLEMENTED;
     1957}
    18291958
    18301959
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py

    r66138 r66159  
    685685    ## CPU context fields.
    686686    kdFields = {
    687         # name:     ( default type, tbd, )
     687        # name:         ( default type, [both|input|output], )
    688688        # Operands.
    689         'op1':      ( 'uint', '', ), ## \@op1
    690         'op2':      ( 'uint', '', ), ## \@op2
    691         'op3':      ( 'uint', '', ), ## \@op3
    692         'op4':      ( 'uint', '', ), ## \@op4
     689        'op1':          ( 'uint', 'both',  ), ## \@op1
     690        'op2':          ( 'uint', 'both',  ), ## \@op2
     691        'op3':          ( 'uint', 'both',  ), ## \@op3
     692        'op4':          ( 'uint', 'both',  ), ## \@op4
    693693        # Flags.
    694         'efl':      ( 'efl',  '', ),
    695         'efl_undef': ( 'uint',  '', ),
     694        'efl':          ( 'efl',  'both',  ),
     695        'efl_undef':    ( 'uint', 'output', ),
    696696        # 8-bit GPRs.
    697         'al':       ( 'uint', '', ),
    698         'cl':       ( 'uint', '', ),
    699         'dl':       ( 'uint', '', ),
    700         'bl':       ( 'uint', '', ),
    701         'ah':       ( 'uint', '', ),
    702         'ch':       ( 'uint', '', ),
    703         'dh':       ( 'uint', '', ),
    704         'bh':       ( 'uint', '', ),
    705         'r8l':      ( 'uint', '', ),
    706         'r9l':      ( 'uint', '', ),
    707         'r10l':     ( 'uint', '', ),
    708         'r11l':     ( 'uint', '', ),
    709         'r12l':     ( 'uint', '', ),
    710         'r13l':     ( 'uint', '', ),
    711         'r14l':     ( 'uint', '', ),
    712         'r15l':     ( 'uint', '', ),
     697        'al':           ( 'uint', 'both',  ),
     698        'cl':           ( 'uint', 'both',  ),
     699        'dl':           ( 'uint', 'both',  ),
     700        'bl':           ( 'uint', 'both',  ),
     701        'ah':           ( 'uint', 'both',  ),
     702        'ch':           ( 'uint', 'both',  ),
     703        'dh':           ( 'uint', 'both',  ),
     704        'bh':           ( 'uint', 'both',  ),
     705        'r8l':          ( 'uint', 'both',  ),
     706        'r9l':          ( 'uint', 'both',  ),
     707        'r10l':         ( 'uint', 'both',  ),
     708        'r11l':         ( 'uint', 'both',  ),
     709        'r12l':         ( 'uint', 'both',  ),
     710        'r13l':         ( 'uint', 'both',  ),
     711        'r14l':         ( 'uint', 'both',  ),
     712        'r15l':         ( 'uint', 'both',  ),
    713713        # 16-bit GPRs.
    714         'ax':       ( 'uint', '', ),
    715         'dx':       ( 'uint', '', ),
    716         'cx':       ( 'uint', '', ),
    717         'bx':       ( 'uint', '', ),
    718         'sp':       ( 'uint', '', ),
    719         'bp':       ( 'uint', '', ),
    720         'si':       ( 'uint', '', ),
    721         'di':       ( 'uint', '', ),
    722         'r8w':      ( 'uint', '', ),
    723         'r9w':      ( 'uint', '', ),
    724         'r10w':     ( 'uint', '', ),
    725         'r11w':     ( 'uint', '', ),
    726         'r12w':     ( 'uint', '', ),
    727         'r13w':     ( 'uint', '', ),
    728         'r14w':     ( 'uint', '', ),
    729         'r15w':     ( 'uint', '', ),
     714        'ax':           ( 'uint', 'both',  ),
     715        'dx':           ( 'uint', 'both',  ),
     716        'cx':           ( 'uint', 'both',  ),
     717        'bx':           ( 'uint', 'both',  ),
     718        'sp':           ( 'uint', 'both',  ),
     719        'bp':           ( 'uint', 'both',  ),
     720        'si':           ( 'uint', 'both',  ),
     721        'di':           ( 'uint', 'both',  ),
     722        'r8w':          ( 'uint', 'both',  ),
     723        'r9w':          ( 'uint', 'both',  ),
     724        'r10w':         ( 'uint', 'both',  ),
     725        'r11w':         ( 'uint', 'both',  ),
     726        'r12w':         ( 'uint', 'both',  ),
     727        'r13w':         ( 'uint', 'both',  ),
     728        'r14w':         ( 'uint', 'both',  ),
     729        'r15w':         ( 'uint', 'both',  ),
    730730        # 32-bit GPRs.
    731         'eax':      ( 'uint', '', ),
    732         'edx':      ( 'uint', '', ),
    733         'ecx':      ( 'uint', '', ),
    734         'ebx':      ( 'uint', '', ),
    735         'esp':      ( 'uint', '', ),
    736         'ebp':      ( 'uint', '', ),
    737         'esi':      ( 'uint', '', ),
    738         'edi':      ( 'uint', '', ),
    739         'r8d':      ( 'uint', '', ),
    740         'r9d':      ( 'uint', '', ),
    741         'r10d':     ( 'uint', '', ),
    742         'r11d':     ( 'uint', '', ),
    743         'r12d':     ( 'uint', '', ),
    744         'r13d':     ( 'uint', '', ),
    745         'r14d':     ( 'uint', '', ),
    746         'r15d':     ( 'uint', '', ),
     731        'eax':          ( 'uint', 'both',  ),
     732        'edx':          ( 'uint', 'both',  ),
     733        'ecx':          ( 'uint', 'both',  ),
     734        'ebx':          ( 'uint', 'both',  ),
     735        'esp':          ( 'uint', 'both',  ),
     736        'ebp':          ( 'uint', 'both',  ),
     737        'esi':          ( 'uint', 'both',  ),
     738        'edi':          ( 'uint', 'both',  ),
     739        'r8d':          ( 'uint', 'both',  ),
     740        'r9d':          ( 'uint', 'both',  ),
     741        'r10d':         ( 'uint', 'both',  ),
     742        'r11d':         ( 'uint', 'both',  ),
     743        'r12d':         ( 'uint', 'both',  ),
     744        'r13d':         ( 'uint', 'both',  ),
     745        'r14d':         ( 'uint', 'both',  ),
     746        'r15d':         ( 'uint', 'both',  ),
    747747        # 64-bit GPRs.
    748         'rax':      ( 'uint', '', ),
    749         'rdx':      ( 'uint', '', ),
    750         'rcx':      ( 'uint', '', ),
    751         'rbx':      ( 'uint', '', ),
    752         'rsp':      ( 'uint', '', ),
    753         'rbp':      ( 'uint', '', ),
    754         'rsi':      ( 'uint', '', ),
    755         'rdi':      ( 'uint', '', ),
    756         'r8':       ( 'uint', '', ),
    757         'r9':       ( 'uint', '', ),
    758         'r10':      ( 'uint', '', ),
    759         'r11':      ( 'uint', '', ),
    760         'r12':      ( 'uint', '', ),
    761         'r13':      ( 'uint', '', ),
    762         'r14':      ( 'uint', '', ),
    763         'r15':      ( 'uint', '', ),
     748        'rax':          ( 'uint', 'both',  ),
     749        'rdx':          ( 'uint', 'both',  ),
     750        'rcx':          ( 'uint', 'both',  ),
     751        'rbx':          ( 'uint', 'both',  ),
     752        'rsp':          ( 'uint', 'both',  ),
     753        'rbp':          ( 'uint', 'both',  ),
     754        'rsi':          ( 'uint', 'both',  ),
     755        'rdi':          ( 'uint', 'both',  ),
     756        'r8':           ( 'uint', 'both',  ),
     757        'r9':           ( 'uint', 'both',  ),
     758        'r10':          ( 'uint', 'both',  ),
     759        'r11':          ( 'uint', 'both',  ),
     760        'r12':          ( 'uint', 'both',  ),
     761        'r13':          ( 'uint', 'both',  ),
     762        'r14':          ( 'uint', 'both',  ),
     763        'r15':          ( 'uint', 'both',  ),
    764764        # 16-bit, 32-bit or 64-bit registers according to operand size.
    765         'oz.rax':   ( 'uint', '', ),
    766         'oz.rdx':   ( 'uint', '', ),
    767         'oz.rcx':   ( 'uint', '', ),
    768         'oz.rbx':   ( 'uint', '', ),
    769         'oz.rsp':   ( 'uint', '', ),
    770         'oz.rbp':   ( 'uint', '', ),
    771         'oz.rsi':   ( 'uint', '', ),
    772         'oz.rdi':   ( 'uint', '', ),
    773         'oz.r8':    ( 'uint', '', ),
    774         'oz.r9':    ( 'uint', '', ),
    775         'oz.r10':   ( 'uint', '', ),
    776         'oz.r11':   ( 'uint', '', ),
    777         'oz.r12':   ( 'uint', '', ),
    778         'oz.r13':   ( 'uint', '', ),
    779         'oz.r14':   ( 'uint', '', ),
    780         'oz.r15':   ( 'uint', '', ),
     765        'oz.rax':       ( 'uint', 'both',   ),
     766        'oz.rdx':       ( 'uint', 'both',   ),
     767        'oz.rcx':       ( 'uint', 'both',   ),
     768        'oz.rbx':       ( 'uint', 'both',   ),
     769        'oz.rsp':       ( 'uint', 'both',   ),
     770        'oz.rbp':       ( 'uint', 'both',   ),
     771        'oz.rsi':       ( 'uint', 'both',   ),
     772        'oz.rdi':       ( 'uint', 'both',   ),
     773        'oz.r8':        ( 'uint', 'both',   ),
     774        'oz.r9':        ( 'uint', 'both',   ),
     775        'oz.r10':       ( 'uint', 'both',   ),
     776        'oz.r11':       ( 'uint', 'both',   ),
     777        'oz.r12':       ( 'uint', 'both',   ),
     778        'oz.r13':       ( 'uint', 'both',   ),
     779        'oz.r14':       ( 'uint', 'both',   ),
     780        'oz.r15':       ( 'uint', 'both',   ),
     781        # Special ones.
     782        'value.xcpt':   ( 'uint', 'output', ),
    781783    };
    782784
     
    20762078            #
    20772079            for asItems, sDesc, aoDst in [ (asInputs, 'input', oTest.aoInputs), (asOutputs, 'output', oTest.aoOutputs)]:
     2080                asValidFieldKinds = [ 'both', sDesc, ];
    20782081                for sItem in asItems:
    20792082                    oItem = None;
    20802083                    for sOp in TestInOut.kasOperators:
    20812084                        off = sItem.find(sOp);
    2082                         if off >= 0:
    2083                             sField     = sItem[:off];
    2084                             sValueType = sItem[off + len(sOp):];
    2085                             if sField in TestInOut.kdFields:
    2086                                 asSplit = sValueType.split(':', 1);
    2087                                 sValue  = asSplit[0];
    2088                                 sType   = asSplit[1] if len(asSplit) > 1 else TestInOut.kdFields[sField][0];
    2089                                 if sType in TestInOut.kdTypes:
    2090                                     oValid = TestInOut.kdTypes[sType].validate(sValue);
    2091                                     if oValid is True:
    2092                                         if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == '&|=':
    2093                                             oItem = TestInOut(sField, sOp, sValue, sType);
    2094                                         else:
    2095                                             self.errorComment(iTagLine, '%s: and-or %s value "%s" can only be used with "&|="'
    2096                                                                         % ( sTag, sDesc, sItem, ));
     2085                        if off < 0:
     2086                            continue;
     2087                        sField     = sItem[:off];
     2088                        sValueType = sItem[off + len(sOp):];
     2089                        if     sField in TestInOut.kdFields \
     2090                           and TestInOut.kdFields[sField][1] in asValidFieldKinds:
     2091                            asSplit = sValueType.split(':', 1);
     2092                            sValue  = asSplit[0];
     2093                            sType   = asSplit[1] if len(asSplit) > 1 else TestInOut.kdFields[sField][0];
     2094                            if sType in TestInOut.kdTypes:
     2095                                oValid = TestInOut.kdTypes[sType].validate(sValue);
     2096                                if oValid is True:
     2097                                    if not TestInOut.kdTypes[sType].isAndOrPair(sValue) or sOp == '&|=':
     2098                                        oItem = TestInOut(sField, sOp, sValue, sType);
    20972099                                    else:
    2098                                         self.errorComment(iTagLine, '%s: invalid %s value "%s" in "%s" (type: %s): %s'
    2099                                                                     % ( sTag, sDesc, sValue, sItem, sType, oValid, ));
     2100                                        self.errorComment(iTagLine, '%s: and-or %s value "%s" can only be used with "&|="'
     2101                                                                    % ( sTag, sDesc, sItem, ));
    21002102                                else:
    2101                                     self.errorComment(iTagLine, '%s: invalid %s type "%s" in "%s" (valid types: %s)'
    2102                                                                  % ( sTag, sDesc, sType, sItem, TestInOut.kdTypes.keys(),));
     2103                                    self.errorComment(iTagLine, '%s: invalid %s value "%s" in "%s" (type: %s): %s'
     2104                                                                % ( sTag, sDesc, sValue, sItem, sType, oValid, ));
    21032105                            else:
    2104                                 self.errorComment(iTagLine, '%s: invalid %s field "%s" in "%s" (valid fields: %s)'
    2105                                                              % ( sTag, sDesc, sField, sItem, TestInOut.kdFields.keys(),));
    2106                             break;
     2106                                self.errorComment(iTagLine, '%s: invalid %s type "%s" in "%s" (valid types: %s)'
     2107                                                             % ( sTag, sDesc, sType, sItem, TestInOut.kdTypes.keys(),));
     2108                        else:
     2109                            self.errorComment(iTagLine, '%s: invalid %s field "%s" in "%s"\nvalid fields: %s'
     2110                                                         % ( sTag, sDesc, sField, sItem,
     2111                                                             ', '.join([sKey for sKey in TestInOut.kdFields.keys()
     2112                                                                        if TestInOut.kdFields[sKey][1] in asValidFieldKinds]),));
     2113                        break;
    21072114                    if oItem is not None:
    21082115                        for oExisting in aoDst:
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c

    r66134 r66159  
    175175        uint8_t             enmLocation;
    176176        /** The BS3CG1DST value for this field.
    177          * Set to BS3CG1DST_INVALID if memory.  */
     177         * Set to BS3CG1DST_INVALID if memory or immediate.  */
    178178        uint8_t             idxField;
    179179        /** Depends on enmLocation.
    180180         * - BS3CG1OPLOC_IMM: offset relative to start of the instruction.
     181         * - BS3CG1OPLOC_MEM: offset should be subtracted from &pbDataPg[_4K].
     182         * - BS3CG1OPLOC_CTX: not used (use idxField instead).
    181183         */
    182184        uint8_t             off;
     
    193195    uint8_t BS3_FAR        *pbDataPg;
    194196
     197    /** The name corresponding to bMode. */
     198    const char BS3_FAR     *pszMode;
     199
     200    /** @name Expected result (modifiable by output program).
     201     * @{ */
     202    /** The expected exception based on operand values or result.
     203     * UINT8_MAX if no special exception expected. */
     204    uint8_t                 bValueXcpt;
     205    /** @} */
     206
    195207    /** The context we're working on. */
    196208    BS3REGCTX               Ctx;
     
    208220        uint64_t            au64[128 / sizeof(uint64_t)];
    209221    } MemOp;
     222
     223    /** Array parallel to aInitialCtxs for saving segment registers. */
     224    struct
     225    {
     226        RTSEL               ds;
     227    } aSavedSegRegs[4];
     228
    210229} BS3CG1STATE;
    211230/** Pointer to the generated test state. */
     
    344363    /* [BS3CG1DST_OZ_R14] = */  BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
    345364    /* [BS3CG1DST_OZ_R15] = */  BS3CG1DSTSIZE_OPERAND_SIZE_GRP,
     365
     366    /* [BS3CG1DST_VALUE_XCPT] = */ 1,
     367
    346368};
    347369
     
    446468    /* [BS3CG1DST_OZ_R14] = */  RT_OFFSETOF(BS3REGCTX, r14),
    447469    /* [BS3CG1DST_OZ_R15] = */  RT_OFFSETOF(BS3REGCTX, r15),
     470
     471    /* [BS3CG1DST_VALUE_XCPT] = */ ~0U,
    448472};
    449473
     
    523547    { "RSI" },
    524548    { "RDI" },
    525     { "R8" },
    526     { "R9" },
     549    { "R8"  },
     550    { "R9"  },
    527551    { "R10" },
    528552    { "R11" },
     
    540564    { "OZ_RSI" },
    541565    { "OZ_RDI" },
    542     { "OZ_R8" },
    543     { "OZ_R9" },
     566    { "OZ_R8"  },
     567    { "OZ_R9"  },
    544568    { "OZ_R10" },
    545569    { "OZ_R11" },
     
    548572    { "OZ_R14" },
    549573    { "OZ_R15" },
     574
     575    { "VALXCPT" },
    550576};
    551577
     
    615641
    616642
     643/**
     644 * Cleans up state and context changes made by the encoder.
     645 *
     646 * @param   pThis       The state.
     647 */
     648static void Bs3Cg1EncodeCleanup(PBS3CG1STATE pThis)
     649{
     650    /* Restore the DS registers in the contexts. */
     651    unsigned iRing = 4;
     652    while (iRing-- > 0)
     653        pThis->aInitialCtxs[iRing].ds = pThis->aSavedSegRegs[iRing].ds;
     654
     655    switch (pThis->enmEncoding)
     656    {
     657        /* Most encodings currently doesn't need any special cleaning up. */
     658        default:
     659            return;
     660    }
     661}
     662
     663
     664/**
     665 * Encodes the next instruction.
     666 *
     667 * @returns Next iEncoding value.  Returns @a iEncoding unchanged to indicate
     668 *          that there are no more encodings to test.
     669 * @param   pThis       The state.
     670 * @param   iEncoding   The encoding to produce.  Meaning is specific to each
     671 *                      BS3CG1ENC_XXX value and should be considered internal.
     672 */
    617673static unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
    618674{
     
    767823            pThis->cbCurInstr = off;
    768824            iEncoding++;
     825            break;
     826
     827        case BS3CG1ENC_MODRM_Gv_Ma:
     828            if (iEncoding < 2)
     829            {
     830                /** @todo need to figure out a more flexible way to do all this crap. */
     831                uint8_t cbAddr = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
     832                uint8_t cbOp   = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
     833
     834                off = 0;
     835                if (iEncoding == 1)
     836                {
     837                    pThis->abCurInstr[off++] = P_OZ;
     838                    cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
     839                }
     840
     841                off = Bs3Cg1InsertOpcodes(pThis, off);
     842
     843                if (cbAddr == 2)
     844                {
     845                    pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, X86_GREG_xBP, 6 /*disp16*/);
     846                    *(uint16_t *)&pThis->abCurInstr[off] = BS3_FP_OFF(pThis->pbDataPg) + X86_PAGE_SIZE - cbOp * 2;
     847                }
     848                else
     849                {
     850                    pThis->abCurInstr[off++] = X86_MODRM_MAKE(0, X86_GREG_xBP, 5 /*disp32*/);
     851                    *(uint32_t *)&pThis->abCurInstr[off] = BS3_FP_OFF(pThis->pbDataPg) + X86_PAGE_SIZE - cbOp * 2;
     852                }
     853                off += cbAddr;
     854
     855                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBP;
     856                pThis->aOperands[pThis->iRegOp].cbOp     = cbOp;
     857                pThis->aOperands[pThis->iRmOp ].cbOp     = cbOp * 2;
     858                pThis->aOperands[pThis->iRmOp ].off      = cbOp * 2;
     859                pThis->cbOperand                         = cbOp;
     860
     861#if ARCH_BITS == 16 /** @todo fixme */
     862                if (cbAddr == 2)
     863                {
     864                    unsigned iRing = 4;
     865                    if (BS3_MODE_IS_RM_OR_V86(pThis->bMode))
     866                        while (iRing-- > 0)
     867                            pThis->aInitialCtxs[iRing].ds = BS3_FP_SEG(pThis->pbDataPg);
     868                    else
     869                        while (iRing-- > 0)
     870                            pThis->aInitialCtxs[iRing].ds = BS3_FP_SEG(pThis->pbDataPg) | iRing;
     871                }
     872#endif
     873                pThis->cbCurInstr = off;
     874                iEncoding++;
     875            }
    769876            break;
    770877
     
    791898static bool Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
    792899{
     900    unsigned iRing = 4;
     901    while (iRing-- > 0)
     902        pThis->aSavedSegRegs[iRing].ds = pThis->aInitialCtxs[iRing].ds;
     903
    793904    pThis->iRmOp         = RT_ELEMENTS(pThis->aOperands) - 1;
    794905    pThis->iRegOp        = RT_ELEMENTS(pThis->aOperands) - 1;
     
    833944            break;
    834945
     946        case BS3CG1ENC_MODRM_Gv_Ma:
     947            pThis->iRmOp  = 1;
     948            pThis->iRegOp = 0;
     949            pThis->aOperands[0].cbOp = 2;
     950            pThis->aOperands[1].cbOp = 4;
     951            pThis->aOperands[0].enmLocation = BS3CG1OPLOC_CTX;
     952            pThis->aOperands[1].enmLocation = BS3CG1OPLOC_MEM;
     953            pThis->aOperands[1].idxField    = BS3CG1DST_INVALID;
     954            break;
     955
    835956        case BS3CG1ENC_FIXED:
    836957            /* nothing to do here */
     
    856977
    857978        default:
    858             return Bs3TestFailedF("Invalid enmEncoding for instruction #%u (%.*s): %d",
     979            return Bs3TestFailedF("Invalid/unimplemented enmEncoding for instruction #%RU32 (%.*s): %d",
    859980                                  pThis->iInstr, pThis->cchMnemonic, pThis->pchMnemonic, pThis->enmEncoding);
    860981    }
     
    10821203                        break;
    10831204
     1205                    case BS3CG1OPLOC_MEM:
     1206                        if (pbInstr)
     1207                            PtrField.pu8 = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[idxOp].off];
     1208                        else
     1209                            return Bs3TestFailedF("TODO: Implement output memory operands!");
     1210                        break;
     1211
    10841212                    default:
    10851213                        return Bs3TestFailedF("Internal error: cbDst=%u idxField=%d (%d) offField=%#x: enmLocation=%u off=%#x idxField=%u",
     
    10961224                uValue = (*PtrField.pu32 & ~(uint32_t)uValue) | (pEflCtx->rflags.u32 & (uint32_t)uValue);
    10971225            }
    1098             //@todo else if (idxField <= BS3CG1DST_OP4)
    1099             //@todo {
    1100             //@todo
    1101             //@todo }
     1226            /* Special field: Expected value (in/result) exception. */
     1227            else if (idxField == BS3CG1DST_VALUE_XCPT)
     1228            {
     1229                if (!pEflCtx || (bOpcode & BS3CG1_CTXOP_OPERATOR_MASK) != BS3CG1_CTXOP_ASSIGN || cbDst != 1)
     1230                    return Bs3TestFailed("Invalid BS3CG1DST_VALUE_XCPT usage");
     1231                PtrField.pu8 = &pThis->bValueXcpt;
     1232            }
     1233            /// @todo else if (idxField <= BS3CG1DST_OP4)
     1234            /// @todo {
     1235            /// @todo
     1236            /// @todo }
    11021237            else
    11031238                return Bs3TestFailedF("Todo implement me: cbDst=%u idxField=%d offField=%#x", cbDst, idxField, offField);
     
    12101345
    12111346
     1347/**
     1348 * Checks the result of a run.
     1349 *
     1350 * @returns true if successful, false if not.
     1351 * @param   pThis               The state.
     1352 * @param   fInvalidInstr       Whether this is an invalid instruction.
     1353 * @param   bTestXcptExpected   The exception causing the test code to stop
     1354 *                              executing.
     1355 * @param   iEncoding           For error reporting.
     1356 */
     1357static bool Bs3Cg1CheckResult(PBS3CG1STATE pThis, bool fInvalidInstr, uint8_t bTestXcptExpected, unsigned iEncoding)
     1358{
     1359    unsigned iOperand;
     1360
     1361    /*
     1362     * Check the exception state first.
     1363     */
     1364    uint8_t bExpectedXcpt;
     1365    uint8_t cbAdjustPc;
     1366    if (!fInvalidInstr)
     1367    {
     1368        bExpectedXcpt = pThis->bValueXcpt;
     1369        if (bExpectedXcpt == UINT8_MAX)
     1370        {
     1371            cbAdjustPc    = pThis->cbCurInstr;
     1372            bExpectedXcpt = bTestXcptExpected;
     1373            if (bTestXcptExpected == X86_XCPT_PF)
     1374                pThis->Ctx.cr2.u = pThis->uCodePgFlat + X86_PAGE_SIZE;
     1375        }
     1376        else
     1377            cbAdjustPc = 0;
     1378    }
     1379    else
     1380    {
     1381        cbAdjustPc = 0;
     1382        bExpectedXcpt = bTestXcptExpected;
     1383    }
     1384    if (RT_LIKELY(   pThis->TrapFrame.bXcpt     == bExpectedXcpt
     1385                  && pThis->TrapFrame.Ctx.rip.u == pThis->Ctx.rip.u + cbAdjustPc))
     1386    {
     1387        if (RT_LIKELY(Bs3TestCheckRegCtxEx(&pThis->TrapFrame.Ctx, &pThis->Ctx,
     1388                                           cbAdjustPc, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/,
     1389                                           pThis->pszMode, iEncoding)))
     1390            return true;
     1391
     1392        /*
     1393         * Report failure.
     1394         */
     1395        Bs3TestFailedF("%RU32[%u]: encoding#%u: %.*Rhxs",
     1396                       pThis->iInstr, pThis->iTest, iEncoding, pThis->cbCurInstr, pThis->abCurInstr);
     1397    }
     1398    else
     1399        Bs3TestFailedF("%RU32[%u]: bXcpt=%#x expected %#x; rip=%RX64 expected %RX64; encoding#%u: %.*Rhxs",
     1400                       pThis->iInstr, pThis->iTest,
     1401                       pThis->TrapFrame.bXcpt, bExpectedXcpt,
     1402                       pThis->TrapFrame.Ctx.rip.u, pThis->Ctx.rip.u + cbAdjustPc,
     1403                       iEncoding, pThis->cbCurInstr, pThis->abCurInstr);
     1404    Bs3TestPrintf("cpl=%u cbOperands=%u\n", pThis->uCpl, pThis->cbOperand);
     1405
     1406    /* Display memory operands. */
     1407    for (iOperand = 0; iOperand < pThis->cOperands; iOperand++)
     1408    {
     1409        BS3PTRUNION PtrUnion;
     1410        switch (pThis->aOperands[iOperand].enmLocation)
     1411        {
     1412            case BS3CG1OPLOC_CTX:
     1413            {
     1414                uint8_t  idxField = pThis->aOperands[iOperand].idxField;
     1415                unsigned offField = g_aoffBs3Cg1DstFields[idxField];
     1416                if (offField <= sizeof(BS3REGCTX))
     1417                    PtrUnion.pb = (uint8_t BS3_FAR *)&pThis->Ctx + offField;
     1418                else
     1419                {
     1420                    Bs3TestPrintf("op%u: imm%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
     1421                                  pThis->aOperands[iOperand].cbOp, *PtrUnion.pu64);
     1422                    break;
     1423                }
     1424                switch (pThis->aOperands[iOperand].cbOp)
     1425                {
     1426                    case 1: Bs3TestPrintf("op%u: ctx08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
     1427                    case 2: Bs3TestPrintf("op%u: ctx16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
     1428                    case 4: Bs3TestPrintf("op%u: ctx32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
     1429                    case 8: Bs3TestPrintf("op%u: ctx64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
     1430                    default:
     1431                        Bs3TestPrintf("op%u: ctx%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
     1432                                      pThis->aOperands[iOperand].cbOp, *PtrUnion.pu64);
     1433                        break;
     1434                }
     1435                break;
     1436            }
     1437
     1438            case BS3CG1OPLOC_IMM:
     1439                PtrUnion.pb = &pThis->pbCodePg[pThis->aOperands[iOperand].off];
     1440                switch (pThis->aOperands[iOperand].cbOp)
     1441                {
     1442                    case 1: Bs3TestPrintf("op%u: imm08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
     1443                    case 2: Bs3TestPrintf("op%u: imm16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
     1444                    case 4: Bs3TestPrintf("op%u: imm32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
     1445                    case 8: Bs3TestPrintf("op%u: imm64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
     1446                    default:
     1447                        Bs3TestPrintf("op%u: imm%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
     1448                                      pThis->aOperands[iOperand].cbOp, *PtrUnion.pu64);
     1449                        break;
     1450                }
     1451                break;
     1452
     1453            case BS3CG1OPLOC_MEM:
     1454                PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
     1455                switch (pThis->aOperands[iOperand].cbOp)
     1456                {
     1457                    case 1: Bs3TestPrintf("op%u: mem08: %#04RX8\n", iOperand, *PtrUnion.pu8); break;
     1458                    case 2: Bs3TestPrintf("op%u: mem16: %#06RX16\n", iOperand, *PtrUnion.pu16); break;
     1459                    case 4: Bs3TestPrintf("op%u: mem32: %#010RX32\n", iOperand, *PtrUnion.pu32); break;
     1460                    case 8: Bs3TestPrintf("op%u: mem64: %#018RX64\n", iOperand, *PtrUnion.pu64); break;
     1461                    default:
     1462                        Bs3TestPrintf("op%u: mem%u: %.*Rhxs\n", iOperand, pThis->aOperands[iOperand].cbOp * 8,
     1463                                      pThis->aOperands[iOperand].cbOp, *PtrUnion.pu64);
     1464                        break;
     1465                }
     1466                break;
     1467        }
     1468    }
     1469
     1470    /* Display contexts: */
     1471    Bs3TestPrintf("-- Expected context:\n");
     1472    Bs3RegCtxPrint(&pThis->Ctx);
     1473    Bs3TestPrintf("-- Actual context:\n");
     1474    Bs3TrapPrintFrame(&pThis->TrapFrame);
     1475    Bs3TestPrintf("\n");
     1476    return false;
     1477}
     1478
    12121479
    12131480BS3_DECL_FAR(uint8_t) BS3_CMN_NM(Bs3Cg1Worker)(uint8_t bMode)
     
    12181485    uint8_t                     iRing;
    12191486    unsigned                    iInstr;
    1220     const char BS3_FAR * const  pszMode    = Bs3GetModeName(bMode);
    12211487    BS3MEMKIND const            enmMemKind = BS3_MODE_IS_RM_OR_V86(bMode) ? BS3MEMKIND_REAL
    12221488                                           : BS3_MODE_IS_16BIT_CODE(bMode) ? BS3MEMKIND_TILED : BS3MEMKIND_FLAT32;
     1489
     1490#if 0
     1491    if (bMode != BS3_MODE_PP16_V86)
     1492        return BS3TESTDOMODE_SKIPPED;
     1493#endif
    12231494
    12241495    /*
     
    12281499
    12291500    This.bMode              = bMode;
     1501    This.pszMode            = Bs3GetModeName(bMode);
    12301502    This.pchMnemonic        = g_achBs3Cg1Mnemonics;
    12311503    This.pabOperands        = g_abBs3Cg1Operands;
     
    13041576        unsigned iEncodingNext;
    13051577        bool     fInvalidInstr = false;
    1306         uint8_t  bXcptExpected = BS3_MODE_IS_PAGED(bMode) ? X86_XCPT_PF : X86_XCPT_UD;
     1578        uint8_t  bTestXcptExpected = BS3_MODE_IS_PAGED(bMode) ? X86_XCPT_PF : X86_XCPT_UD;
    13071579
    13081580        /*
     
    13401612        {
    13411613            fInvalidInstr = true;
    1342             bXcptExpected = X86_XCPT_UD;
     1614            bTestXcptExpected = X86_XCPT_UD;
    13431615        }
    13441616
     
    14031675                            BS3CG1_DPRINTF(("dbg:  bXcpt=%#x rip=%RX64 -> %RX64\n", This.TrapFrame.bXcpt, This.Ctx.rip.u, This.TrapFrame.Ctx.rip.u));
    14041676
    1405                             /* Check the control exception result first. */
    1406                             if (   This.TrapFrame.bXcpt     == bXcptExpected
    1407                                 && This.TrapFrame.Ctx.rip.u == This.Ctx.rip.u + (!fInvalidInstr ? This.cbCurInstr : 0))
     1677                            /*
     1678                             * Apply the output modification program to the context.
     1679                             */
     1680                            This.Ctx.rflags.u32 &= ~X86_EFL_RF;
     1681                            This.Ctx.rflags.u32 |= This.TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
     1682                            This.bValueXcpt      = UINT8_MAX;
     1683                            if (   fInvalidInstr
     1684                                || Bs3Cg1RunContextModifier(&This, &This.Ctx, pHdr,
     1685                                                            pHdr->cbSelector + pHdr->cbInput, pHdr->cbOutput,
     1686                                                            &This.TrapFrame.Ctx, NULL /*pbCode*/))
    14081687                            {
    1409                                 /* Apply output modifications and compare the contexts. */
    1410                                 if (bXcptExpected == X86_XCPT_PF)
    1411                                     This.Ctx.cr2.u = This.uCodePgFlat + X86_PAGE_SIZE;
    1412                                 This.Ctx.rflags.u32 &= ~X86_EFL_RF;
    1413                                 This.Ctx.rflags.u32 |= This.TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
    1414                                 if (   fInvalidInstr
    1415                                     || Bs3Cg1RunContextModifier(&This, &This.Ctx, pHdr,
    1416                                                                 pHdr->cbSelector + pHdr->cbInput, pHdr->cbOutput,
    1417                                                                 &This.TrapFrame.Ctx, NULL /*pbCode*/))
    1418                                 {
    1419                                     if (!Bs3TestCheckRegCtxEx(&This.TrapFrame.Ctx, &This.Ctx,
    1420                                                               !fInvalidInstr ? This.cbCurInstr : 0,  0 /*cbSpAdjust*/,
    1421                                                               0 /*fExtraEfl*/, pszMode, iEncoding))
    1422                                         Bs3TestFailedF("encoding#%u: %.*Rhxs", iEncoding, This.cbCurInstr, This.abCurInstr);
    1423                                 }
    1424                             }
    1425                             else
    1426                             {
    1427                                 Bs3TestFailedF("bXcpt=%#x expected %#x; rip=%RX64 expected %RX64; encoding#%u: %.*Rhxs",
    1428                                                This.TrapFrame.bXcpt, bXcptExpected,
    1429                                                This.TrapFrame.Ctx.rip.u, This.Ctx.rip.u + (!fInvalidInstr ? This.cbCurInstr : 0),
    1430                                                iEncoding, This.cbCurInstr, This.abCurInstr);
     1688                                Bs3Cg1CheckResult(&This, fInvalidInstr, bTestXcptExpected, iEncoding);
    14311689                            }
    14321690                        }
     
    14461704        }
    14471705
     1706        /*
     1707         * Clean up (segment registers, etc).
     1708         */
     1709        Bs3Cg1EncodeCleanup(&This);
    14481710    }
    14491711
     
    14641726    Bs3TestSubDone();
    14651727#if 0
    1466     Bs3TestTerm();
    1467     Bs3Shutdown();
     1728    if (bMode >= BS3_MODE_PP16)
     1729    {
     1730        Bs3TestTerm();
     1731        Bs3Shutdown();
     1732    }
    14681733#endif
    14691734
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h

    r66134 r66159  
    5454    BS3CG1OP_rAX,
    5555
     56    BS3CG1OP_Ma,
     57
    5658    BS3CG1OP_END
    5759} BS3CG1OP;
     
    7577    BS3CG1ENC_MODRM_Gb_Eb,
    7678    BS3CG1ENC_MODRM_Gv_Ev,
     79    BS3CG1ENC_MODRM_Gv_Ma, /**< bound instruction */
    7780
    7881    BS3CG1ENC_FIXED,
     
    298301    BS3CG1DST_OZ_R15,
    299302
     303    /* Special fields: */
     304    BS3CG1DST_SPECIAL_START,
     305    BS3CG1DST_VALUE_XCPT = BS3CG1DST_SPECIAL_START, /**< Expected exception based on input or result. */
     306
    300307    BS3CG1DST_END
    301308} BS3CG1DST;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette