VirtualBox

Changeset 66419 in vbox


Ignore:
Timestamp:
Apr 4, 2017 3:49:07 PM (8 years ago)
Author:
vboxsync
Message:

IEM: More vstmxcsr work.

Location:
trunk/src/VBox
Files:
7 edited

Legend:

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

    r66160 r66419  
    61736173FNIEMOP_DEF(iemOp_les_Gv_Mp__vex2)
    61746174{
    6175     /* The LES instruction is invalid 64-bit mode. In legacy and
    6176        compatability mode it is invalid with MOD=3.
    6177        The use as a VEX prefix is made possible by assigning the inverted
    6178        REX.R to the top MOD bit, and the top bit in the inverted register
    6179        specifier to the bottom MOD bit, thereby effectively limiting 32-bit
    6180        to accessing registers 0..7 in this VEX form. */
    6181     uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
    6182     if (   pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
    6183         || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
    6184     {
    6185         IEMOP_MNEMONIC(vex2_prefix, "vex2");
    6186         if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
    6187         {
    6188             uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
    6189             if (   (  pVCpu->iem.s.fPrefixes
    6190                     & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
    6191                 == 0)
    6192             {
    6193                 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
    6194                 pVCpu->iem.s.uRexReg    = ~bRm >> (7 - 3);
    6195                 pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
    6196                 pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
    6197                 pVCpu->iem.s.idxPrefix  = bRm & 0x3;
    6198 
    6199                 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
    6200             }
    6201 
    6202             Log(("VEX2: Invalid prefix mix!\n"));
    6203         }
    6204         else
    6205             Log(("VEX2: AVX support disabled!\n"));
    6206 
    6207         /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */
    6208         return IEMOP_RAISE_INVALID_OPCODE();
    6209     }
    6210     IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
    6211     return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
    6212 }
    6213 
    6214 
    6215 /**
    6216  * @opcode      0xc5
    6217  */
    6218 FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3)
    6219 {
    62206175    /* The LDS instruction is invalid 64-bit mode. In legacy and
    62216176       compatability mode it is invalid with MOD=3.
     
    62286183        if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
    62296184        {
    6230             IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
    6231             return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
     6185            IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
     6186            return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
    62326187        }
    62336188        IEMOP_HLP_NO_REAL_OR_V86_MODE();
     
    62816236        Log(("VEX3: AVX support disabled!\n"));
    62826237    return IEMOP_RAISE_INVALID_OPCODE();
     6238}
     6239
     6240
     6241/**
     6242 * @opcode      0xc5
     6243 */
     6244FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3)
     6245{
     6246    /* The LES instruction is invalid 64-bit mode. In legacy and
     6247       compatability mode it is invalid with MOD=3.
     6248       The use as a VEX prefix is made possible by assigning the inverted
     6249       REX.R to the top MOD bit, and the top bit in the inverted register
     6250       specifier to the bottom MOD bit, thereby effectively limiting 32-bit
     6251       to accessing registers 0..7 in this VEX form. */
     6252    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
     6253    if (   pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
     6254        || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
     6255    {
     6256        IEMOP_MNEMONIC(vex2_prefix, "vex2");
     6257        if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
     6258        {
     6259            uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
     6260            if (   (  pVCpu->iem.s.fPrefixes
     6261                    & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
     6262                == 0)
     6263            {
     6264                pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
     6265                pVCpu->iem.s.uRexReg    = ~bRm >> (7 - 3);
     6266                pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
     6267                pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
     6268                pVCpu->iem.s.idxPrefix  = bRm & 0x3;
     6269
     6270                return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
     6271            }
     6272
     6273            Log(("VEX2: Invalid prefix mix!\n"));
     6274        }
     6275        else
     6276            Log(("VEX2: AVX support disabled!\n"));
     6277
     6278        /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */
     6279        return IEMOP_RAISE_INVALID_OPCODE();
     6280    }
     6281
     6282    IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
     6283    return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
    62836284}
    62846285
     
    1175311754    /* 0xbc */  iemOp_eSP_Iv,           iemOp_eBP_Iv,           iemOp_eSI_Iv,           iemOp_eDI_Iv,
    1175411755    /* 0xc0 */  iemOp_Grp2_Eb_Ib,       iemOp_Grp2_Ev_Ib,       iemOp_retn_Iw,          iemOp_retn,
    11755     /* 0xc4 */  iemOp_les_Gv_Mp__vex2,  iemOp_lds_Gv_Mp__vex3,  iemOp_Grp11_Eb_Ib,      iemOp_Grp11_Ev_Iz,
     11756    /* 0xc4 */  iemOp_les_Gv_Mp__vex3,  iemOp_lds_Gv_Mp__vex2,  iemOp_Grp11_Eb_Ib,      iemOp_Grp11_Ev_Iz,
    1175611757    /* 0xc8 */  iemOp_enter_Iw_Ib,      iemOp_leave,            iemOp_retf_Iw,          iemOp_retf,
    1175711758    /* 0xcc */  iemOp_int3,             iemOp_int_Ib,           iemOp_into,             iemOp_iret,
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py

    r66412 r66419  
    268268
    269269## IEMFORM_XXX mappings.
    270 g_kdIemForms = { # sEncoding,   [ sWhere1, ... ]
    271     'RM':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
    272     'RM_REG':   ( 'ModR/M',     [ 'reg', 'rm' ], ),
    273     'RM_MEM':   ( 'ModR/M',     [ 'reg', 'rm' ], ),
    274     'MR':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
    275     'MR_REG':   ( 'ModR/M',     [ 'rm', 'reg' ], ),
    276     'MR_MEM':   ( 'ModR/M',     [ 'rm', 'reg' ], ),
    277     'M':        ( 'ModR/M',     [ 'rm', ], ),
    278     'M_REG':    ( 'ModR/M',     [ 'rm', ], ),
    279     'M_MEM':    ( 'ModR/M',     [ 'rm', ], ),
    280     'R':        ( 'ModR/M',     [ 'reg', ], ),
    281     'RVM':      ( 'ModR/M+VEX', [ 'reg', 'vvvv', 'rm'], ),
    282     'MVR':      ( 'ModR/M+VEX', [ 'rm', 'vvvv', 'reg'], ),
    283     'FIXED':    ( 'fixed',      None, )
     270g_kdIemForms = {     # sEncoding,   [ sWhere1, ... ]
     271    'RM':           ( 'ModR/M',     [ 'reg', 'rm' ], ),
     272    'RM_REG':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
     273    'RM_MEM':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
     274    'MR':           ( 'ModR/M',     [ 'rm', 'reg' ], ),
     275    'MR_REG':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
     276    'MR_MEM':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
     277    'M':            ( 'ModR/M',     [ 'rm', ], ),
     278    'M_REG':        ( 'ModR/M',     [ 'rm', ], ),
     279    'M_MEM':        ( 'ModR/M',     [ 'rm', ], ),
     280    'R':            ( 'ModR/M',     [ 'reg', ], ),
     281
     282    'VEX_RM':       ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
     283    'VEX_RM_REG':   ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
     284    'VEX_RM_MEM':   ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
     285    'VEX_MR':       ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
     286    'VEX_MR_REG':   ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
     287    'VEX_MR_MEM':   ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
     288    'VEX_M':        ( 'VEX.ModR/M', [ 'rm', ], ),
     289    'VEX_M_REG':    ( 'VEX.ModR/M', [ 'rm', ], ),
     290    'VEX_M_MEM':    ( 'VEX.ModR/M', [ 'rm', ], ),
     291    'VEX_R':        ( 'VEX.ModR/M', [ 'reg', ], ),
     292    'VEX_RVM':      ( 'VEX.ModR/M', [ 'reg', 'vvvv', 'rm'], ),
     293    'VEX_MVR':      ( 'VEX.ModR/M', [ 'rm', 'vvvv', 'reg'], ),
     294
     295    'FIXED':        ( 'fixed',      None, )
    284296};
    285297
     
    313325## Valid values for \@openc
    314326g_kdEncodings = {
    315     'ModR/M':   [ 'BS3CG1ENC_MODRM', ],     ##< ModR/M
    316     'fixed':    [ 'BS3CG1ENC_FIXED', ],     ##< Fixed encoding (address, registers, etc).
    317     'prefix':   [ None, ],                  ##< Prefix
     327    'ModR/M':       [ 'BS3CG1ENC_MODRM', ],     ##< ModR/M
     328    'VEX.ModR/M':   [ 'BS3CG1ENC_VEX_MODRM', ], ##< VEX...ModR/M
     329    'fixed':        [ 'BS3CG1ENC_FIXED', ],     ##< Fixed encoding (address, registers, etc).
     330    'prefix':       [ None, ],                  ##< Prefix
    318331};
    319332
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r66414 r66419  
    59035903 * @opcode      !11/3
    59045904 * @oppfx       none
    5905  * @opcpuid     sse
     5905 * @opcpuid     avx
    59065906 * @opgroup     og_avx_mxcsrsm
    5907  * @optestign      mxcsr=0      -> op1=0
    5908  * @optestign      mxcsr=0x2083 -> op1=0x2083
     5907 * @optest         mxcsr=0      -> op1=0
     5908 * @optest         mxcsr=0x2083 -> op1=0x2083
    59095909 * @optestign      mxcsr=0x2084 cr0|=ts -> value.xcpt=0x7
    59105910 * @optestign      mxcsr=0x2085 cr0|=em -> value.xcpt=0x6
     
    59155915 * @optestign      mxcsr=0x208a cr0|=ts,em cr4&~=osfxsr -> value.xcpt=0x6
    59165916 * @optestign      mxcsr=0x208b cr0|=ts,em,mp cr4&~=osfxsr -> value.xcpt=0x6
     5917 * @oponlytest
    59175918 */
    59185919FNIEMOP_DEF_1(iemOp_VGrp15_vstmxcsr,  uint8_t, bRm)
    59195920{
    5920     IEMOP_MNEMONIC1(M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);
     5921    IEMOP_MNEMONIC1(VEX_M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);
    59215922    if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
    59225923        return IEMOP_RAISE_INVALID_OPCODE();
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r66321 r66419  
    867867#define IEMOPFORM_R             3
    868868
    869 /** ModR/M + VEX.vvvv: reg, vvvv, r/m */
    870 #define IEMOPFORM_RVM           4
    871 
    872 /** ModR/M + VEX.vvvv: r/m, vvvv, reg */
    873 #define IEMOPFORM_MVR           5
     869/** VEX+ModR/M: reg, r/m */
     870#define IEMOPFORM_VEX_RM        4
     871/** VEX+ModR/M: reg, r/m (register) */
     872#define IEMOPFORM_VEX_RM_REG        (IEMOPFORM_VEX_RM | IEMOPFORM_MOD3)
     873/** VEX+ModR/M: reg, r/m (memory)   */
     874#define IEMOPFORM_VEX_RM_MEM        (IEMOPFORM_VEX_RM | IEMOPFORM_NOT_MOD3)
     875/** VEX+ModR/M: r/m, reg */
     876#define IEMOPFORM_VEX_MR        5
     877/** VEX+ModR/M: r/m (register), reg */
     878#define IEMOPFORM_VEX_MR_REG        (IEMOPFORM_VEX_MR | IEMOPFORM_MOD3)
     879/** VEX+ModR/M: r/m (memory), reg */
     880#define IEMOPFORM_VEX_MR_MEM        (IEMOPFORM_VEX_MR | IEMOPFORM_NOT_MOD3)
     881/** VEX+ModR/M: r/m only */
     882#define IEMOPFORM_VEX_M         6
     883/** VEX+ModR/M: r/m only (register). */
     884#define IEMOPFORM_VEX_M_REG         (IEMOPFORM_VEX_M | IEMOPFORM_MOD3)
     885/** VEX+ModR/M: r/m only (memory). */
     886#define IEMOPFORM_VEX_M_MEM         (IEMOPFORM_VEX_M | IEMOPFORM_NOT_MOD3)
     887/** VEX+ModR/M: reg only */
     888#define IEMOPFORM_VEX_R         7
     889/** VEX+ModR/M: reg, vvvv, r/m */
     890#define IEMOPFORM_VEX_RVM       8
     891/** VEX+ModR/M: r/m, vvvv, reg */
     892#define IEMOPFORM_VEX_MVR       9
    874893
    875894/** Fixed register instruction, no R/M. */
    876 #define IEMOPFORM_FIXED         6
     895#define IEMOPFORM_FIXED         16
    877896
    878897/** The r/m is a register. */
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c

    r66408 r66419  
    10551055
    10561056
     1057/**
     1058 * Inserts a 2-byte VEX prefix.
     1059 *
     1060 * @returns New offDst value.
     1061 * @param   pThis       The state.
     1062 * @param   offDst      The current instruction offset.
     1063 * @param   uVexL       The VEX.L value.
     1064 * @param   uVexV       The VEX.V value (caller inverted it already).
     1065 * @param   uVexR       The VEX.R value (caller inverted it already).
     1066 */
     1067DECLINLINE(unsigned) Bs3Cg1InsertVex2bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL, uint8_t uVexR)
     1068{
     1069    uint8_t b = uVexR << 7;
     1070    b        |= uVexV << 3;
     1071    b        |= uVexL << 2;
     1072    switch (pThis->enmPrefixKind)
     1073    {
     1074        case BS3CG1PFXKIND_NO_F2_F3_66:     b |= 0; break;
     1075        case BS3CG1PFXKIND_REQ_66:          b |= 1; break;
     1076        case BS3CG1PFXKIND_REQ_F3:          b |= 2; break;
     1077        case BS3CG1PFXKIND_REQ_F2:          b |= 3; break;
     1078        default:
     1079            Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
     1080            break;
     1081    }
     1082
     1083    pThis->abCurInstr[offDst]     = 0xc5; /* vex2 */
     1084    pThis->abCurInstr[offDst + 1] = b;
     1085    return offDst + 2;
     1086}
     1087
     1088
     1089/**
     1090 * Inserts a 3-byte VEX prefix.
     1091 *
     1092 * @returns New offDst value.
     1093 * @param   pThis       The state.
     1094 * @param   offDst      The current instruction offset.
     1095 * @param   uVexL       The VEX.L value.
     1096 * @param   uVexV       The VEX.V value (caller inverted it already).
     1097 * @param   uVexR       The VEX.R value (caller inverted it already).
     1098 * @param   uVexR       The VEX.X value (caller inverted it already).
     1099 * @param   uVexR       The VEX.B value (caller inverted it already).
     1100 * @param   uVexR       The VEX.W value (straight).
     1101 */
     1102DECLINLINE(unsigned) Bs3Cg1InsertVex3bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL,
     1103                                             uint8_t uVexR, uint8_t uVexX, uint8_t uVexB, uint8_t uVexW)
     1104{
     1105    uint8_t b1;
     1106    uint8_t b2;
     1107    b1        = uVexR << 7;
     1108    b1       |= uVexX << 6;
     1109    b1       |= uVexB << 5;
     1110    b1       |= 1; /* VEX.mmmmm = 1*/ /** @todo three byte opcode tables */
     1111    b2        = uVexV << 3;
     1112    b2       |= uVexW << 7;
     1113    b2       |= uVexL << 2;
     1114    switch (pThis->enmPrefixKind)
     1115    {
     1116        case BS3CG1PFXKIND_NO_F2_F3_66:     b2 |= 0; break;
     1117        case BS3CG1PFXKIND_REQ_66:          b2 |= 1; break;
     1118        case BS3CG1PFXKIND_REQ_F3:          b2 |= 2; break;
     1119        case BS3CG1PFXKIND_REQ_F2:          b2 |= 3; break;
     1120        default:
     1121            Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
     1122            break;
     1123    }
     1124
     1125    pThis->abCurInstr[offDst]     = 0xc4; /* vex3 */
     1126    pThis->abCurInstr[offDst + 1] = b1;
     1127    pThis->abCurInstr[offDst + 2] = b2;
     1128    return offDst + 3;
     1129}
     1130
     1131
    10571132DECLINLINE(unsigned) Bs3Cg1InsertReqPrefix(PBS3CG1STATE pThis, unsigned offDst)
    10581133{
     
    11861261
    11871262
     1263unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
     1264{
     1265    unsigned off;
     1266    /* Start by reg,reg encoding. */
     1267    if (iEncoding == 0)
     1268    {
     1269        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1270        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
     1271        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
     1272        pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
     1273    }
     1274    else if (iEncoding == 1)
     1275    {
     1276        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
     1277        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1278        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW);
     1279    }
     1280    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
     1281    {
     1282        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
     1283        pThis->abCurInstr[0] = P_AZ;
     1284        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
     1285        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW);
     1286    }
     1287    else
     1288        return 0;
     1289    pThis->cbCurInstr = off;
     1290    return iEncoding + 1;
     1291}
     1292
     1293
     1294unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
     1295{
     1296    unsigned off;
     1297    /* Start by reg,reg encoding. */
     1298    if (iEncoding == 0)
     1299    {
     1300        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1301        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
     1302        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
     1303        pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
     1304    }
     1305    else if (iEncoding == 1)
     1306    {
     1307        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
     1308        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1309        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM);
     1310    }
     1311    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
     1312    {
     1313        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
     1314        pThis->abCurInstr[0] = P_AZ;
     1315        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
     1316        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM);
     1317    }
     1318    else
     1319        return 0;
     1320    pThis->cbCurInstr = off;
     1321    return iEncoding + 1;
     1322}
     1323
     1324
     1325unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(PBS3CG1STATE pThis,
     1326                                                                           unsigned iEncoding, bool *pfInvalidInstr)
     1327{
     1328    unsigned off;
     1329    unsigned cbOp;
     1330    if (iEncoding == 0)
     1331    {
     1332        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
     1333        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1334        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
     1335        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
     1336        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
     1337    }
     1338    else if (iEncoding == 1)
     1339    {
     1340        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
     1341        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBP;
     1342        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
     1343        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0,
     1344                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
     1345    }
     1346    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
     1347    {
     1348        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
     1349        pThis->abCurInstr[0] = P_OZ;
     1350        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
     1351        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
     1352        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
     1353        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
     1354        pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
     1355    }
     1356    else if (iEncoding == 3)
     1357    {
     1358        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
     1359        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
     1360        pThis->abCurInstr[0] = P_OZ;
     1361        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
     1362        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0,
     1363                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
     1364    }
     1365    else if (iEncoding == 4)
     1366    {
     1367        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
     1368        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RDI;
     1369        pThis->abCurInstr[0] = P_AZ;
     1370        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
     1371        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0,
     1372                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
     1373    }
     1374    else if (iEncoding == 5)
     1375    {
     1376        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
     1377        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
     1378        pThis->abCurInstr[0] = P_OZ;
     1379        pThis->abCurInstr[1] = P_AZ;
     1380        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
     1381        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0,
     1382                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
     1383    }
     1384    else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode))
     1385    {
     1386        cbOp = 8;
     1387        off = Bs3Cg1InsertReqPrefix(pThis, 0);
     1388        pThis->abCurInstr[off++] = REX_W___;
     1389        off = Bs3Cg1InsertOpcodes(pThis, off);
     1390        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
     1391        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_RBX;
     1392        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_RDX;
     1393        pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
     1394    }
     1395    else
     1396        return 0;
     1397    pThis->aOperands[0].cbOp = cbOp;
     1398    pThis->aOperands[1].cbOp = cbOp;
     1399    pThis->cbOperand  = cbOp;
     1400    pThis->cbCurInstr = off;
     1401    return iEncoding + 1;
     1402}
     1403
     1404
     1405
     1406static unsigned Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
     1407{
     1408    unsigned off;
     1409    if (iEncoding == 0)
     1410    {
     1411        /** @todo three by opcode needs some tweaking. */
     1412        off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
     1413        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1414        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1415                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1416                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1417    }
     1418    else if (iEncoding == 1)
     1419    {
     1420        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1421        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1422        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1423                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1424                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1425    }
     1426    else if (iEncoding == 2)
     1427    {
     1428        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0x7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1429        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1430        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1431                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1432                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1433        *pfInvalidInstr = true;
     1434    }
     1435    else if (iEncoding == 3)
     1436    {
     1437        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1438        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1439        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1440                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1441                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1442        *pfInvalidInstr = true;
     1443    }
     1444    else if (iEncoding == 4)
     1445    {
     1446        pThis->abCurInstr[0] = P_OZ;
     1447        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1448        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1449        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1450                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1451                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1452        *pfInvalidInstr = true;
     1453    }
     1454    else if (iEncoding == 5)
     1455    {
     1456        pThis->abCurInstr[0] = P_RZ;
     1457        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1458        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1459        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1460                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1461                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1462        *pfInvalidInstr = true;
     1463    }
     1464    else if (iEncoding == 6)
     1465    {
     1466        pThis->abCurInstr[0] = P_RN;
     1467        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
     1468        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1469        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1470                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1471                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1472        *pfInvalidInstr = true;
     1473    }
     1474    else if (iEncoding == 7)
     1475    {
     1476        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
     1477        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
     1478        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
     1479                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
     1480                                       4, 0, BS3CG1OPLOC_MEM_RW);
     1481    }
     1482    else
     1483        return 0;
     1484    pThis->cbCurInstr = off;
     1485    return iEncoding + 1;
     1486}
     1487
     1488
    11881489/**
    11891490 * Encodes the next instruction.
     
    11911492 * @returns Next iEncoding value.  Returns @a iEncoding unchanged to indicate
    11921493 *          that there are no more encodings to test.
    1193  * @param   pThis       The state.
    1194  * @param   iEncoding   The encoding to produce.  Meaning is specific to each
    1195  *                      BS3CG1ENC_XXX value and should be considered internal.
     1494 * @param   pThis           The state.
     1495 * @param   iEncoding       The encoding to produce.  Meaning is specific to
     1496 *                          each BS3CG1ENC_XXX value and should be considered
     1497 *                          internal.
     1498 * @param   pfInvalidInstr  Pointer to variable to set when generating an
     1499 *                          invalid encoding.  (Never clear this.)
    11961500 */
    1197 static unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
     1501unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
    11981502{
    11991503    unsigned off;
     
    12051509    {
    12061510        case BS3CG1ENC_MODRM_Eb_Gb:
    1207             /* Start by reg,reg encoding. */
    1208             if (iEncoding == 0)
    1209             {
    1210                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1211                 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
    1212                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
    1213                 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
    1214             }
    1215             else if (iEncoding == 1)
    1216             {
    1217                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
    1218                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1219                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW);
    1220             }
    1221             else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
    1222             {
    1223                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
    1224                 pThis->abCurInstr[0] = P_AZ;
    1225                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
    1226                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW);
    1227             }
    1228             else
    1229                 break;
    1230             pThis->cbCurInstr = off;
    1231             iEncoding++;
    1232             break;
    1233 
     1511            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(pThis, iEncoding, pfInvalidInstr);
    12341512        case BS3CG1ENC_MODRM_Gb_Eb:
    1235             /* Start by reg,reg encoding. */
    1236             if (iEncoding == 0)
    1237             {
    1238                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1239                 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
    1240                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
    1241                 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
    1242             }
    1243             else if (iEncoding == 1)
    1244             {
    1245                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
    1246                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1247                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM);
    1248             }
    1249             else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
    1250             {
    1251                 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
    1252                 pThis->abCurInstr[0] = P_AZ;
    1253                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
    1254                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM);
    1255             }
    1256             else
    1257                 break;
    1258             pThis->cbCurInstr = off;
    1259             iEncoding++;
    1260             break;
    1261 
     1513            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(pThis, iEncoding, pfInvalidInstr);
    12621514        case BS3CG1ENC_MODRM_Gv_Ev:
    12631515        case BS3CG1ENC_MODRM_Ev_Gv:
    1264             if (iEncoding == 0)
    1265             {
    1266                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
    1267                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1268                 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
    1269                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
    1270                 pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
    1271             }
    1272             else if (iEncoding == 1)
    1273             {
    1274                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
    1275                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBP;
    1276                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
    1277                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0,
    1278                                                pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
    1279             }
    1280             else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
    1281             {
    1282                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
    1283                 pThis->abCurInstr[0] = P_OZ;
    1284                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
    1285                 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
    1286                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
    1287                 pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
    1288                 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
    1289             }
    1290             else if (iEncoding == 3)
    1291             {
    1292                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
    1293                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
    1294                 pThis->abCurInstr[0] = P_OZ;
    1295                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
    1296                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0,
    1297                                                pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
    1298             }
    1299             else if (iEncoding == 4)
    1300             {
    1301                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
    1302                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RDI;
    1303                 pThis->abCurInstr[0] = P_AZ;
    1304                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
    1305                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0,
    1306                                                pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
    1307             }
    1308             else if (iEncoding == 5)
    1309             {
    1310                 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
    1311                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
    1312                 pThis->abCurInstr[0] = P_OZ;
    1313                 pThis->abCurInstr[1] = P_AZ;
    1314                 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
    1315                 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0,
    1316                                                pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
    1317             }
    1318             else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode))
    1319             {
    1320                 cbOp = 8;
    1321                 off = Bs3Cg1InsertReqPrefix(pThis, 0);
    1322                 pThis->abCurInstr[off++] = REX_W___;
    1323                 off = Bs3Cg1InsertOpcodes(pThis, off);
    1324                 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
    1325                 pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_RBX;
    1326                 pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_RDX;
    1327                 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
    1328             }
    1329             else
    1330                 break;
    1331             pThis->aOperands[0].cbOp = cbOp;
    1332             pThis->aOperands[1].cbOp = cbOp;
    1333             pThis->cbOperand  = cbOp;
    1334             pThis->cbCurInstr = off;
    1335             iEncoding++;
    1336             break;
     1516            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(pThis, iEncoding, pfInvalidInstr);
    13371517
    13381518        case BS3CG1ENC_MODRM_Wss_Vss:
     
    15921772            iEncoding++;
    15931773            break;
     1774
     1775        case BS3CG1ENC_VEX_MODRM_MdWO:
     1776            return Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(pThis, iEncoding, pfInvalidInstr);
    15941777
    15951778        case BS3CG1ENC_FIXED:
     
    17361919 *
    17371920 * @returns Success indicator (true/false).
    1738  * @param   pThis       The state.
     1921 * @param   pThis           The state.
    17391922 */
    17401923static bool Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
     
    18692052
    18702053        case BS3CG1ENC_MODRM_MdWO:
     2054        case BS3CG1ENC_VEX_MODRM_MdWO:
    18712055            pThis->iRmOp             = 0;
    18722056            pThis->aOperands[0].cbOp = 4;
     
    20782262                    case BS3CG1CPU_AVX:
    20792263                        if (fEcx & X86_CPUID_FEATURE_ECX_AVX)
    2080                             return Bs3Cg3SetupSseAndAvx(pThis);
     2264                            return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
    20812265                        return false;
    20822266                    default: BS3_ASSERT(0); /* impossible */
     
    20932277                    case BS3CG1CPU_AVX2:
    20942278                        if (fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2)
    2095                             return Bs3Cg3SetupSseAndAvx(pThis);
     2279                            return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
    20962280                        return false;
    20972281                    default: BS3_ASSERT(0); return false; /* impossible */
     
    26392823    {
    26402824        cbAdjustPc = 0;
    2641         bExpectedXcpt = bTestXcptExpected;
     2825        bExpectedXcpt = X86_XCPT_UD;
    26422826    }
    26432827    if (RT_LIKELY(   pThis->TrapFrame.bXcpt     == bExpectedXcpt
     
    26542838         * Check memory output operands.
    26552839         */
    2656         iOperand = pThis->cOperands;
    2657         while (iOperand-- > 0)
    2658             if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW)
    2659             {
    2660                 BS3PTRUNION PtrUnion;
    2661                 PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
    2662                 switch (pThis->aOperands[iOperand].cbOp)
     2840        if (!fInvalidInstr)
     2841        {
     2842            iOperand = pThis->cOperands;
     2843            while (iOperand-- > 0)
     2844                if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW)
    26632845                {
    2664                     case 1:
    2665                         if (*PtrUnion.pu8 == pThis->MemOp.ab[0])
    2666                             continue;
    2667                         Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]);
    2668                         break;
    2669                     case 2:
    2670                         if (*PtrUnion.pu16 == pThis->MemOp.au16[0])
    2671                             continue;
    2672                         Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16",
    2673                                        iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]);
    2674                         break;
    2675                     case 4:
    2676                         if (*PtrUnion.pu32 == pThis->MemOp.au32[0])
    2677                             continue;
    2678                         Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32",
    2679                                        iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]);
    2680                         break;
    2681                     case 8:
    2682                         if (*PtrUnion.pu64 == pThis->MemOp.au64[0])
    2683                             continue;
    2684                         Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64",
    2685                                        iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]);
    2686                         break;
    2687                     default:
    2688                         if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0)
    2689                             continue;
    2690                         Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs",
    2691                                        iOperand,
    2692                                        pThis->aOperands[iOperand].cbOp, PtrUnion.pb,
    2693                                        pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab);
    2694                         break;
     2846                    BS3PTRUNION PtrUnion;
     2847                    PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
     2848                    switch (pThis->aOperands[iOperand].cbOp)
     2849                    {
     2850                        case 1:
     2851                            if (*PtrUnion.pu8 == pThis->MemOp.ab[0])
     2852                                continue;
     2853                            Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]);
     2854                            break;
     2855                        case 2:
     2856                            if (*PtrUnion.pu16 == pThis->MemOp.au16[0])
     2857                                continue;
     2858                            Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16",
     2859                                           iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]);
     2860                            break;
     2861                        case 4:
     2862                            if (*PtrUnion.pu32 == pThis->MemOp.au32[0])
     2863                                continue;
     2864                            Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32",
     2865                                           iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]);
     2866                            break;
     2867                        case 8:
     2868                            if (*PtrUnion.pu64 == pThis->MemOp.au64[0])
     2869                                continue;
     2870                            Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64",
     2871                                           iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]);
     2872                            break;
     2873                        default:
     2874                            if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0)
     2875                                continue;
     2876                            Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs",
     2877                                           iOperand,
     2878                                           pThis->aOperands[iOperand].cbOp, PtrUnion.pb,
     2879                                           pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab);
     2880                            break;
     2881                    }
     2882                    fOkay = false;
    26952883                }
    2696                 fOkay = false;
    2697             }
     2884        }
    26982885
    26992886        /*
     
    31323319         pThis->pabOpcodes  += pThis->cbOpcodes)
    31333320    {
    3134         bool     fInvalidInstr = false;
     3321        bool     fOuterInvalidInstr = false;
    31353322        unsigned iCpuSetup;
    31363323        uint8_t  bTestXcptExpected = BS3_MODE_IS_PAGED(pThis->bMode) ? X86_XCPT_PF : X86_XCPT_UD;
     
    31753362        if (   !Bs3Cg1CpuSetupFirst(pThis)
    31763363            || (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID)))
    3177         {
    3178             fInvalidInstr = true;
    3179             bTestXcptExpected = X86_XCPT_UD;
    3180         }
     3364            fOuterInvalidInstr = true;
    31813365
    31823366        for (iCpuSetup = 0;; iCpuSetup++)
     
    31993383                 * Encode the next instruction variation.
    32003384                 */
    3201                 iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding);
     3385                bool fInnerInvalidInstr = fOuterInvalidInstr;
     3386                iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding, &fInnerInvalidInstr);
    32023387                if (iEncodingNext <= iEncoding)
    32033388                    break;
    3204                 BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs\n",
    3205                                 iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr));
     3389                BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs  fInnerInvalidInstr=%d\n",
     3390                                iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr, fInnerInvalidInstr));
    32063391
    32073392                /*
     
    32653450                                pThis->Ctx.rflags.u32 |= pThis->TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
    32663451                                pThis->bValueXcpt      = UINT8_MAX;
    3267                                 if (   fInvalidInstr
     3452                                if (   fInnerInvalidInstr
    32683453                                    || pThis->bAlignmentXcpt != UINT8_MAX
    32693454                                    || pThis->bValueXcpt     != UINT8_MAX
     
    32723457                                                                &pThis->TrapFrame.Ctx, NULL /*pbCode*/))
    32733458                                {
    3274                                     Bs3Cg1CheckResult(pThis, fInvalidInstr, bTestXcptExpected, iEncoding);
     3459                                    Bs3Cg1CheckResult(pThis, fInnerInvalidInstr, bTestXcptExpected, iEncoding);
    32753460                                }
    32763461                            }
     
    32943479             */
    32953480            Bs3Cg1EncodeCleanup(pThis);
    3296             if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fInvalidInstr))
     3481            if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fOuterInvalidInstr))
    32973482                break;
    32983483            if (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID))
    3299                 fInvalidInstr = true;
    3300             if (fInvalidInstr)
    3301                 bTestXcptExpected = X86_XCPT_UD;
     3484                fOuterInvalidInstr = true;
    33023485        }
    33033486    }
     
    33123495    BS3CG1STATE This;
    33133496
    3314 #if 0
     3497#if 1
    33153498    /* (for debugging) */
    3316     if (bMode != BS3_MODE_PPV86)
     3499    if (bMode < BS3_MODE_PP16_32)
    33173500        return BS3TESTDOMODE_SKIPPED;
    33183501#endif
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h

    r66404 r66419  
    107107    BS3CG1ENC_MODRM_MdRO,
    108108    BS3CG1ENC_MODRM_MdWO,
     109
     110    BS3CG1ENC_VEX_MODRM_MdWO,
    109111
    110112    BS3CG1ENC_FIXED,
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-ExtCtxGetSize.c

    r66303 r66419  
    4040
    4141    ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, &fEcx, &fEdx);
    42 #if 0 /* To disable xsave/xrstor till IEM groks it... */
     42#if 1 /* To disable xsave/xrstor till IEM groks it... */
    4343    if (fEcx & X86_CPUID_FEATURE_ECX_XSAVE)
    4444    {
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