VirtualBox

Changeset 66159 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Mar 17, 2017 10:16:24 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
114068
Message:

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

Location:
trunk/src/VBox/VMM/VMMAll
Files:
5 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:
Note: See TracChangeset for help on using the changeset viewer.

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