VirtualBox

Changeset 49671 in vbox for trunk/src


Ignore:
Timestamp:
Nov 26, 2013 6:09:07 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
90927
Message:

IEM: Fixed several instances of iEffSeg being accessed before the decoding was over, causing iPXE to guru on us. Implemented DAS and DAA to verify the previous fix.

Location:
trunk/src/VBox/VMM
Files:
2 added
4 edited

Legend:

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

    r49482 r49671  
    51345134 * Implements 'AAD'.
    51355135 *
    5136  * @param   enmEffOpSize    The effective operand size.
     5136 * @param   bImm            The immediate operand.
    51375137 */
    51385138IEM_CIMPL_DEF_1(iemCImpl_aad, uint8_t, bImm)
     
    51705170                              X86_EFL_OF | X86_EFL_AF | X86_EFL_CF);
    51715171
     5172    iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
     5173    return VINF_SUCCESS;
     5174}
     5175
     5176
     5177/**
     5178 * Implements 'DAA'.
     5179 */
     5180IEM_CIMPL_DEF_0(iemCImpl_daa)
     5181{
     5182    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     5183
     5184    uint8_t const  al       = pCtx->al;
     5185    bool const     fCarry   = pCtx->eflags.Bits.u1CF;
     5186
     5187    if (   pCtx->eflags.Bits.u1AF
     5188        || (al & 0xf) >= 10)
     5189    {
     5190        pCtx->al = al + 6;
     5191        pCtx->eflags.Bits.u1AF = 1;
     5192    }
     5193    else
     5194        pCtx->eflags.Bits.u1AF = 0;
     5195
     5196    if (al >= 0x9a || fCarry)
     5197    {
     5198        pCtx->al += 0x60;
     5199        pCtx->eflags.Bits.u1CF = 1;
     5200    }
     5201    else
     5202        pCtx->eflags.Bits.u1CF = 0;
     5203
     5204    iemHlpUpdateArithEFlagsU8(pIemCpu, pCtx->al, X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF, X86_EFL_OF);
     5205    iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
     5206    return VINF_SUCCESS;
     5207}
     5208
     5209
     5210/**
     5211 * Implements 'DAS'.
     5212 */
     5213IEM_CIMPL_DEF_0(iemCImpl_das)
     5214{
     5215    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     5216
     5217    uint8_t const  uInputAL = pCtx->al;
     5218    bool const     fCarry   = pCtx->eflags.Bits.u1CF;
     5219
     5220    if (   pCtx->eflags.Bits.u1AF
     5221        || (uInputAL & 0xf) >= 10)
     5222    {
     5223        pCtx->eflags.Bits.u1AF = 1;
     5224        if (uInputAL < 6)
     5225            pCtx->eflags.Bits.u1CF = 1;
     5226        pCtx->al = uInputAL - 6;
     5227    }
     5228    else
     5229    {
     5230        pCtx->eflags.Bits.u1AF = 0;
     5231        pCtx->eflags.Bits.u1CF = 0;
     5232    }
     5233
     5234    if (uInputAL >= 0x9a || fCarry)
     5235    {
     5236        pCtx->al -= 0x60;
     5237        pCtx->eflags.Bits.u1CF = 1;
     5238    }
     5239
     5240    iemHlpUpdateArithEFlagsU8(pIemCpu, pCtx->al, X86_EFL_SF | X86_EFL_ZF | X86_EFL_PF, X86_EFL_OF);
    51725241    iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
    51735242    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r49482 r49671  
    786786    IEMOP_HLP_64BIT_OP_SIZE();
    787787    IEM_MC_BEGIN(3, 1);
    788     IEM_MC_ARG_CONST(uint8_t,   iEffSeg, /*=*/pIemCpu->iEffSeg,             0);
     788    IEM_MC_ARG(uint8_t,         iEffSeg,                                    0);
    789789    IEM_MC_ARG(RTGCPTR,         GCPtrEffSrc,                                1);
    790790    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSizeArg,/*=*/pIemCpu->enmEffOpSize, 2);
    791791    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
    792792    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     793    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    793794    IEM_MC_CALL_CIMPL_3(iemCImpl_sgdt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
    794795    IEM_MC_END();
     
    835836    IEMOP_HLP_64BIT_OP_SIZE();
    836837    IEM_MC_BEGIN(3, 1);
    837     IEM_MC_ARG_CONST(uint8_t,   iEffSeg, /*=*/pIemCpu->iEffSeg,             0);
     838    IEM_MC_ARG(uint8_t,         iEffSeg,                                    0);
    838839    IEM_MC_ARG(RTGCPTR,         GCPtrEffSrc,                                1);
    839840    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSizeArg,/*=*/pIemCpu->enmEffOpSize, 2);
    840841    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
    841842    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     843    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    842844    IEM_MC_CALL_CIMPL_3(iemCImpl_sidt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
    843845    IEM_MC_END();
     
    868870{
    869871    IEMOP_MNEMONIC("lgdt");
    870     IEMOP_HLP_NO_LOCK_PREFIX();
    871 
    872872    IEMOP_HLP_64BIT_OP_SIZE();
    873873    IEM_MC_BEGIN(3, 1);
    874     IEM_MC_ARG_CONST(uint8_t,   iEffSeg, /*=*/pIemCpu->iEffSeg,             0);
     874    IEM_MC_ARG(uint8_t,         iEffSeg,                                    0);
    875875    IEM_MC_ARG(RTGCPTR,         GCPtrEffSrc,                                1);
    876876    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSizeArg,/*=*/pIemCpu->enmEffOpSize, 2);
    877877    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
     878    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     879    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    878880    IEM_MC_CALL_CIMPL_3(iemCImpl_lgdt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
    879881    IEM_MC_END();
     
    901903FNIEMOP_DEF_1(iemOp_Grp7_lidt, uint8_t, bRm)
    902904{
    903     IEMOP_HLP_NO_LOCK_PREFIX();
    904 
    905905    IEMMODE enmEffOpSize = pIemCpu->enmCpuMode == IEMMODE_64BIT
    906906                         ? IEMMODE_64BIT
    907907                         : pIemCpu->enmEffOpSize;
    908908    IEM_MC_BEGIN(3, 1);
    909     IEM_MC_ARG_CONST(uint8_t,   iEffSeg, /*=*/pIemCpu->iEffSeg,     0);
     909    IEM_MC_ARG(uint8_t,         iEffSeg,                            0);
    910910    IEM_MC_ARG(RTGCPTR,         GCPtrEffSrc,                        1);
    911911    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSizeArg,/*=*/enmEffOpSize,  2);
    912912    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
     913    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     914    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    913915    IEM_MC_CALL_CIMPL_3(iemCImpl_lidt, iEffSeg, GCPtrEffSrc, enmEffOpSizeArg);
    914916    IEM_MC_END();
     
    49224924{
    49234925    IEMOP_MNEMONIC("fxsave m512");
    4924     IEMOP_HLP_NO_LOCK_PREFIX();
    49254926    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
    49264927        return IEMOP_RAISE_INVALID_OPCODE();
    49274928
    49284929    IEM_MC_BEGIN(3, 1);
    4929     IEM_MC_ARG_CONST(uint8_t,   iEffSeg,/*=*/pIemCpu->iEffSeg,           0);
     4930    IEM_MC_ARG(uint8_t,         iEffSeg,                                 0);
    49304931    IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                1);
    49314932    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2);
    49324933    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
     4934    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     4935    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    49334936    IEM_MC_CALL_CIMPL_3(iemCImpl_fxsave, iEffSeg, GCPtrEff, enmEffOpSize);
    49344937    IEM_MC_END();
     
    49414944{
    49424945    IEMOP_MNEMONIC("fxrstor m512");
    4943     IEMOP_HLP_NO_LOCK_PREFIX();
    49444946    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(X86_CPUID_FEATURE_EDX_FXSR))
    49454947        return IEMOP_RAISE_INVALID_OPCODE();
    49464948
    49474949    IEM_MC_BEGIN(3, 1);
    4948     IEM_MC_ARG_CONST(uint8_t,   iEffSeg,/*=*/pIemCpu->iEffSeg,           0);
     4950    IEM_MC_ARG(uint8_t,         iEffSeg,                                 0);
    49494951    IEM_MC_ARG(RTGCPTR,         GCPtrEff,                                1);
    49504952    IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 2);
    49514953    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0);
     4954    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     4955    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    49524956    IEM_MC_CALL_CIMPL_3(iemCImpl_fxrstor, iEffSeg, GCPtrEff, enmEffOpSize);
    49534957    IEM_MC_END();
     
    71887192
    71897193/** Opcode 0x27. */
    7190 FNIEMOP_STUB(iemOp_daa);
     7194FNIEMOP_DEF(iemOp_daa)
     7195{
     7196    IEMOP_MNEMONIC("daa AL");
     7197    IEMOP_HLP_NO_64BIT();
     7198    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     7199    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
     7200    return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_daa);
     7201}
    71917202
    71927203
     
    72527263
    72537264/** Opcode 0x2f. */
    7254 FNIEMOP_STUB(iemOp_das);
     7265FNIEMOP_DEF(iemOp_das)
     7266{
     7267    IEMOP_MNEMONIC("das AL");
     7268    IEMOP_HLP_NO_64BIT();
     7269    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     7270    IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_OF);
     7271    return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_das);
     7272}
    72557273
    72567274
     
    1311013128    IEM_MC_BEGIN(3, 0);
    1311113129    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
    13112     IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     13130    IEM_MC_ARG(uint8_t,                 iEffSeg,                                    1);
    1311313131    IEM_MC_ARG(RTGCPTR,                 GCPtrEffSrc,                                2);
    1311413132    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
    1311513133    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1311613134    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     13135    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    1311713136    IEM_MC_CALL_CIMPL_3(iemCImpl_fldenv, enmEffOpSize, iEffSeg, GCPtrEffSrc);
    1311813137    IEM_MC_END();
     
    1314413163    IEM_MC_BEGIN(3, 0);
    1314513164    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
    13146     IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     13165    IEM_MC_ARG(uint8_t,                 iEffSeg,                                    1);
    1314713166    IEM_MC_ARG(RTGCPTR,                 GCPtrEffDst,                                2);
    1314813167    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
    1314913168    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1315013169    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     13170    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    1315113171    IEM_MC_CALL_CIMPL_3(iemCImpl_fnstenv, enmEffOpSize, iEffSeg, GCPtrEffDst);
    1315213172    IEM_MC_END();
     
    1500615026FNIEMOP_DEF_1(iemOp_frstor,      uint8_t, bRm)
    1500715027{
    15008     IEMOP_MNEMONIC("fxrstor m94/108byte");
     15028    IEMOP_MNEMONIC("frstor m94/108byte");
    1500915029    IEM_MC_BEGIN(3, 0);
    1501015030    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
    15011     IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     15031    IEM_MC_ARG(uint8_t,                 iEffSeg,                                    1);
    1501215032    IEM_MC_ARG(RTGCPTR,                 GCPtrEffSrc,                                2);
    1501315033    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 0);
    1501415034    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1501515035    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     15036    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    1501615037    IEM_MC_CALL_CIMPL_3(iemCImpl_frstor, enmEffOpSize, iEffSeg, GCPtrEffSrc);
    1501715038    IEM_MC_END();
     
    1502615047    IEM_MC_BEGIN(3, 0);
    1502715048    IEM_MC_ARG_CONST(IEMMODE,           enmEffOpSize, /*=*/ pIemCpu->enmEffOpSize,  0);
    15028     IEM_MC_ARG_CONST(uint8_t,           iEffSeg,      /*=*/ pIemCpu->iEffSeg,       1);
     15049    IEM_MC_ARG(uint8_t,                 iEffSeg,                                    1);
    1502915050    IEM_MC_ARG(RTGCPTR,                 GCPtrEffDst,                                2);
    1503015051    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0);
    1503115052    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    1503215053    IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE();
     15054    IEM_MC_ASSIGN(iEffSeg, pIemCpu->iEffSeg);
    1503315055    IEM_MC_CALL_CIMPL_3(iemCImpl_fnsave, enmEffOpSize, iEffSeg, GCPtrEffDst);
    1503415056    IEM_MC_END();
  • trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py

    r48346 r49671  
    137137## @}
    138138
     139## @name EFLAGS/RFLAGS/EFLAGS
     140## @{
     141X86_EFL_CF              = RT_BIT_32(0);
     142X86_EFL_CF_BIT          = 0;
     143X86_EFL_1               = RT_BIT_32(1);
     144X86_EFL_PF              = RT_BIT_32(2);
     145X86_EFL_AF              = RT_BIT_32(4);
     146X86_EFL_AF_BIT          = 4;
     147X86_EFL_ZF              = RT_BIT_32(6);
     148X86_EFL_ZF_BIT          = 6;
     149X86_EFL_SF              = RT_BIT_32(7);
     150X86_EFL_SF_BIT          = 7;
     151X86_EFL_TF              = RT_BIT_32(8);
     152X86_EFL_IF              = RT_BIT_32(9);
     153X86_EFL_DF              = RT_BIT_32(10);
     154X86_EFL_OF              = RT_BIT_32(11);
     155X86_EFL_OF_BIT          = 11;
     156X86_EFL_IOPL            = (RT_BIT_32(12) | RT_BIT_32(13));
     157X86_EFL_NT              = RT_BIT_32(14);
     158X86_EFL_RF              = RT_BIT_32(16);
     159X86_EFL_VM              = RT_BIT_32(17);
     160X86_EFL_AC              = RT_BIT_32(18);
     161X86_EFL_VIF             = RT_BIT_32(19);
     162X86_EFL_VIP             = RT_BIT_32(20);
     163X86_EFL_ID              = RT_BIT_32(21);
     164X86_EFL_LIVE_MASK       = 0x003f7fd5;
     165X86_EFL_RA1_MASK        = RT_BIT_32(1);
     166X86_EFL_IOPL_SHIFT      = 12;
     167X86_EFL_STATUS_BITS     = ( X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF );
     168## @}
    139169
    140170## @name Random
     
    13071337
    13081338
     1339class InstrTest_DaaDas(InstrTestBase):
     1340    """ Tests the DAA and DAS instructions. """
     1341
     1342    def __init__(self, fIsDas):
     1343        InstrTestBase.__init__(self, 'das' if fIsDas else 'daa');
     1344        self.fIsDas = fIsDas;
     1345
     1346    def isApplicable(self, oGen):
     1347        return not oGen.oTarget.is64Bit();
     1348
     1349    def generateTest(self, oGen, sTestFnName):
     1350        if self.fIsDas: from itgTableDas import g_aItgDasResults as aItgResults;
     1351        else:           from itgTableDaa import g_aItgDaaResults as aItgResults;
     1352        cMax = len(aItgResults);
     1353        if oGen.isTiny():
     1354            cMax = 64;
     1355
     1356        oGen.write('VBINSTST_BEGINPROC %s\n' % (sTestFnName,));
     1357        oGen.write('        xor     ebx, ebx\n');
     1358        oGen.write('.das_loop:\n');
     1359        # Save the loop variable so we can load known values.
     1360        oGen.write('        push    ebx\n');
     1361        oGen.newSubTestEx('ebx');
     1362
     1363        # Push the results.
     1364        oGen.write('        movzx   eax, byte [.abAlResults + ebx]\n');
     1365        oGen.write('        or      eax, %#x\n' % (oGen.au32Regs[X86_GREG_xAX] & ~0xff,));
     1366        oGen.write('        push    eax\n');
     1367        oGen.write('        movzx   eax, byte [.aFlagsResults + ebx]\n');
     1368        oGen.write('        push    eax\n');
     1369        # Calc and push the inputs.
     1370        oGen.write('        mov     eax, ebx\n');
     1371        oGen.write('        shr     eax, 2\n');
     1372        oGen.write('        and     eax, 0ffh\n');
     1373        oGen.write('        or      eax, %#x\n' % (oGen.au32Regs[X86_GREG_xAX] & ~0xff,));
     1374        oGen.write('        push    eax\n');
     1375
     1376        oGen.write('        pushfd\n')
     1377        oGen.write('        and     dword [xSP], ~(X86_EFL_CF | X86_EFL_AF)\n');
     1378        oGen.write('        mov     al, bl\n');
     1379        oGen.write('        and     al, 2\n');
     1380        oGen.write('        shl     al, X86_EFL_AF_BIT - 1\n');
     1381        oGen.write('        or      [xSP], al\n');
     1382        oGen.write('        mov     al, bl\n');
     1383        oGen.write('        and     al, X86_EFL_CF\n');
     1384        oGen.write('        or      [xSP], al\n');
     1385
     1386        # Load register values and do the test.
     1387        oGen.write('        call VBINSTST_NAME(Common_LoadKnownValues)\n');
     1388        oGen.write('        popfd\n');
     1389        oGen.write('        pop     eax\n');
     1390        if self.fIsDas:
     1391            oGen.write('        das\n');
     1392        else:
     1393            oGen.write('        daa\n');
     1394
     1395        # Verify the results.
     1396        fFlagsToCheck = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_SF | X86_EFL_ZF;
     1397        oGen.write('        call VBINSTST_NAME(%s)\n' % (oGen.needFlagsGRegChecker(fFlagsToCheck, X86_GREG_xAX),));
     1398
     1399        # Restore the loop variable and advance.
     1400        oGen.write('        pop     ebx\n');
     1401        oGen.write('        inc     ebx\n');
     1402        oGen.write('        cmp     ebx, %#x\n' % (cMax,));
     1403        oGen.write('        jb      .das_loop\n');
     1404
     1405        oGen.write('        ret\n');
     1406
     1407        oGen.write('.abAlResults:\n');
     1408        for i in range(cMax):
     1409            oGen.write('        db %#x\n' % (aItgResults[i][0],));
     1410
     1411        oGen.write('.aFlagsResults:\n');
     1412        for i in range(cMax):
     1413            oGen.write('        db %#x\n' % (aItgResults[i][1],));
     1414
     1415        oGen.write('VBINSTST_ENDPROC   %s\n' % (sTestFnName,));
     1416        return True;
     1417
    13091418
    13101419##
     
    13161425    InstrTest_DivIDiv(fIsIDiv = False),
    13171426    InstrTest_DivIDiv(fIsIDiv = True),
     1427    InstrTest_DaaDas(fIsDas = False),
     1428    InstrTest_DaaDas(fIsDas = True),
    13181429];
    13191430
     
    13351446    kasTestSizes = ( ksTestSize_Large, ksTestSize_Medium, ksTestSize_Tiny );
    13361447
     1448    ## The prefix for the checker functions.
     1449    ksCheckerPrefix   = 'Common_Check_'
    13371450
    13381451
     
    14211534        return True;
    14221535
     1536    def newSubTestEx(self, sIndicator):
     1537        """
     1538        Indicates that a new subtest has started.
     1539        """
     1540        self.write('        mov     dword [VBINSTST_NAME(g_uVBInsTstSubTestIndicator) xWrtRIP], %s\n' % (sIndicator, ));
     1541        return True;
     1542
    14231543    def needGRegChecker(self, iReg1, iReg2 = None, iReg3 = None):
    14241544        """
     
    14391559            self._dCheckFns[sName]  = 1;
    14401560
    1441         return 'Common_Check_' + sName;
     1561        return self.ksCheckerPrefix + sName;
     1562
     1563    def needFlagsGRegChecker(self, fFlagsToCheck, iReg1, iReg2 = None, iReg3 = None):
     1564        """
     1565        Records the need for a given rFLAGS + register checker function, returning its label.
     1566        """
     1567        sWorkerName = self.needGRegChecker(iReg1, iReg2, iReg3);
     1568
     1569        sName = 'eflags_%#x_%s' % (fFlagsToCheck, sWorkerName[len(self.ksCheckerPrefix):]);
     1570        if sName in self._dCheckFns:
     1571            self._dCheckFns[sName] += 1;
     1572        else:
     1573            self._dCheckFns[sName]  = 1;
     1574
     1575        return self.ksCheckerPrefix + sName;
    14421576
    14431577    def needGRegMemSetup(self, cAddrBits, cbEffOp, iBaseReg = None, offDisp = None, iIndexReg = None, iScale = 1):
     
    15231657        """ Checks if we're in tiny mode."""
    15241658        return self.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny;
     1659
     1660    def isMedium(self):
     1661        """ Checks if we're in medium mode."""
     1662        return self.oOptions.sTestSize == InstructionTestGen.ksTestSize_Medium;
    15251663
    15261664
     
    18742012            sPushSize = 'dword';
    18752013
    1876             # Prologue
    1877             self.write('\n\n'
    1878                        '; Checks 1 or more register values, expected values pushed on the stack.\n'
    1879                        '; To save space, the callee cleans up the stack.'
    1880                        '; Ref count: %u\n'
    1881                        'VBINSTST_BEGINPROC Common_Check_%s\n'
    1882                        '        MY_PUSH_FLAGS\n'
    1883                        % ( self._dCheckFns[sName], sName, ) );
    1884 
    1885             # Register checks.
    1886             for i in range(len(asRegs)):
    1887                 sReg = asRegs[i];
    1888                 iReg = self.oTarget.asGRegs.index(sReg);
    1889                 if i == asRegs.index(sReg): # Only check once, i.e. input = output reg.
    1890                     self.write('        cmp     %s, [xSP + MY_PUSH_FLAGS_SIZE + xCB + sCB * %u]\n'
    1891                                '        je      .equal%u\n'
    1892                                '        push    %s %u      ; register number\n'
    1893                                '        push    %s         ; actual\n'
    1894                                '        mov     %s, [xSP + sCB*2 + MY_PUSH_FLAGS_SIZE + xCB + sCB * %u]\n'
    1895                                '        push    %s         ; expected\n'
    1896                                '        call    VBINSTST_NAME(Common_BadValue)\n'
    1897                                '.equal%u:\n'
    1898                            % ( sReg, i, i, sPushSize, iReg, sReg, sReg, i, sReg, i, ) );
    1899 
    1900 
    1901             # Restore known register values and check the other registers.
    1902             for sReg in asRegs:
    1903                 if self.oTarget.is64Bit():
    1904                     self.write('        mov     %s, [g_u64KnownValue_%s wrt rip]\n' % (sReg, sReg,));
    1905                 else:
    1906                     iReg = self.oTarget.asGRegs.index(sReg)
    1907                     self.write('        mov     %s, 0x%x\n' % (sReg, self.au32Regs[iReg],));
    1908             self.write('        MY_POP_FLAGS\n'
    1909                        '        call    VBINSTST_NAME(Common_CheckKnownValues)\n'
    1910                        '        ret     sCB*%u\n'
    1911                        'VBINSTST_ENDPROC   Common_Check_%s\n'
    1912                        % (len(asRegs), sName,));
     2014            # Do we check eflags first.
     2015            if asRegs[0] == 'eflags':
     2016                asRegs.pop(0);
     2017                sFlagsToCheck = asRegs.pop(0);
     2018                self.write('\n\n'
     2019                           '; Check flags and then defers to the register-only checker\n'
     2020                           '; To save space, the callee cleans up the stack.'
     2021                           '; Ref count: %u\n'
     2022                           'VBINSTST_BEGINPROC %s%s\n'
     2023                           '        MY_PUSH_FLAGS\n'
     2024                           '        push    sAX\n'
     2025                           '        mov     sAX, [xSP + sCB]\n'
     2026                           '        and     sAX, %s\n'
     2027                           '        cmp     sAX, [xSP + xCB + sCB*2]\n'
     2028                           '        je      .equal\n'
     2029                           % ( self._dCheckFns[sName], self.ksCheckerPrefix, sName,
     2030                               sFlagsToCheck,));
     2031                self.write('        push    dword 0xef ; register number\n'
     2032                           '        push    sAX        ; actual\n'
     2033                           '        mov     sAX, [xSP + xCB + sCB*4]\n'
     2034                           '        push    sAX        ; expected\n'
     2035                           '        call    VBINSTST_NAME(Common_BadValue)\n');
     2036                self.write('.equal:\n'
     2037                           '        mov     xAX, [xSP + sCB*2]\n'  # Remove the expected eflags value from the stack frame.
     2038                           '        mov     [xSP + sCB*2  + xCB + sCB - xCB], xAX\n'
     2039                           '        pop     sAX\n'
     2040                           '        MY_POP_FLAGS\n'
     2041                           '        lea     xSP, [xSP + sCB]\n'
     2042                           '        jmp     VBINSTST_NAME(Common_Check_%s)\n'
     2043                           'VBINSTST_ENDPROC   %s%s\n'
     2044                           % ( '_'.join(asRegs),
     2045                               self.ksCheckerPrefix, sName,) );
     2046            else:
     2047                # Prologue
     2048                self.write('\n\n'
     2049                           '; Checks 1 or more register values, expected values pushed on the stack.\n'
     2050                           '; To save space, the callee cleans up the stack.'
     2051                           '; Ref count: %u\n'
     2052                           'VBINSTST_BEGINPROC %s%s\n'
     2053                           '        MY_PUSH_FLAGS\n'
     2054                           % ( self._dCheckFns[sName], self.ksCheckerPrefix, sName, ) );
     2055
     2056                # Register checks.
     2057                for i in range(len(asRegs)):
     2058                    sReg = asRegs[i];
     2059                    iReg = self.oTarget.asGRegs.index(sReg);
     2060                    if i == asRegs.index(sReg): # Only check once, i.e. input = output reg.
     2061                        self.write('        cmp     %s, [xSP + MY_PUSH_FLAGS_SIZE + xCB + sCB * %u]\n'
     2062                                   '        je      .equal%u\n'
     2063                                   '        push    %s %u      ; register number\n'
     2064                                   '        push    %s         ; actual\n'
     2065                                   '        mov     %s, [xSP + sCB*2 + MY_PUSH_FLAGS_SIZE + xCB + sCB * %u]\n'
     2066                                   '        push    %s         ; expected\n'
     2067                                   '        call    VBINSTST_NAME(Common_BadValue)\n'
     2068                                   '.equal%u:\n'
     2069                               % ( sReg, i, i, sPushSize, iReg, sReg, sReg, i, sReg, i, ) );
     2070
     2071
     2072                # Restore known register values and check the other registers.
     2073                for sReg in asRegs:
     2074                    if self.oTarget.is64Bit():
     2075                        self.write('        mov     %s, [g_u64KnownValue_%s wrt rip]\n' % (sReg, sReg,));
     2076                    else:
     2077                        iReg = self.oTarget.asGRegs.index(sReg)
     2078                        self.write('        mov     %s, 0x%x\n' % (sReg, self.au32Regs[iReg],));
     2079                self.write('        MY_POP_FLAGS\n'
     2080                           '        call    VBINSTST_NAME(Common_CheckKnownValues)\n'
     2081                           '        ret     sCB*%u\n'
     2082                           'VBINSTST_ENDPROC   %s%s\n'
     2083                           % (len(asRegs), self.ksCheckerPrefix, sName,));
    19132084
    19142085        # memory setup functions
     
    19502121            for iInstrTest in range(iInstrTestStart, iInstrTestEnd):
    19512122                oInstrTest = g_aoInstructionTests[iInstrTest];
    1952                 self.write('\n'
    1953                            '\n'
    1954                            ';\n'
    1955                            '; %s\n'
    1956                            ';\n'
    1957                            % (oInstrTest.sName,));
    1958                 self._randInitIndexes();
    1959                 oInstrTest.generateTest(self, self._calcTestFunctionName(oInstrTest, iInstrTest));
     2123                if oInstrTest.isApplicable(self):
     2124                    self.write('\n'
     2125                               '\n'
     2126                               ';\n'
     2127                               '; %s\n'
     2128                               ';\n'
     2129                               % (oInstrTest.sName,));
     2130                    self._randInitIndexes();
     2131                    oInstrTest.generateTest(self, self._calcTestFunctionName(oInstrTest, iInstrTest));
    19602132
    19612133            # Generate the main function.
  • trunk/src/VBox/VMM/testcase/Instructions/env-common.mac

    r47132 r49671  
    1919%define ___env_common_mac
    2020
     21%include "iprt/x86.mac"
    2122
    2223;*******************************************************************************
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