VirtualBox

Ignore:
Timestamp:
Jun 29, 2013 2:15:38 AM (11 years ago)
Author:
vboxsync
Message:

yeah, finally getting somewhere...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/testcase/Instructions/InstructionTestGen.py

    r46856 r46875  
    583583                   % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iBaseReg = iBaseReg, offDisp = offDisp,
    584584                                            iIndexReg = iIndexReg, iScale = iScale),));
     585        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iIndexReg],));
    585586        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iBaseReg],));
    586         oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iIndexReg],));
    587587        return True;
    588588
     
    605605        oGen.write('        call VBINSTST_NAME(Common_LoadKnownValues)\n');
    606606        oGen.write('        mov     %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2X], uInput,));
    607         oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iOp2X],));
     607        if iOp1X != iOp2X:
     608            oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iOp2X],));
    608609        self.writeInstrGregGreg(cbEffOp, iOp1, iOp2, oGen);
    609610        oGen.pushConst(uResult);
    610         oGen.write('        call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1X, iOp2X),));
     611        oGen.write('        call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1X, iOp2X if iOp1X != iOp2X else None),));
    611612        _ = cbMaxOp;
    612613        return True;
     
    700701                    sChecker = oGen.needGRegChecker(iOp1, iBaseReg);
    701702                else:
     703                    if iIndexReg == iBaseReg and iScale == 1 and offDisp is not None and (offDisp & 1):
     704                        if offDisp < 0: offDisp += 1;
     705                        else:           offDisp -= 1;
    702706                    self.generateMemSetupReadByBaseAndScaledReg(oGen, cAddrBits, cbEffOp, iBaseReg,
    703707                                                                iIndexReg, iScale, uInput, offDisp);
     
    712716        """ Generate all SIB variations for the given iOp1 (reg) value. """
    713717        assert cAddrBits in [32, 64];
    714         for iBaseReg in range(len(oGen.oTarget.asGRegs)):
    715             for iIndexReg in range(len(oGen.oTarget.asGRegs)):
     718        for iBaseReg in range(oGen.oTarget.getGRegCount(cAddrBits / 8)):
     719            for iIndexReg in range(oGen.oTarget.getGRegCount(cAddrBits / 8)):
    716720                if iBaseReg == 4 or iIndexReg == 4: # no RSP testing atm.
    717721                    continue;
    718722                for iMod in [0, 1, 2]:
    719723                    if iBaseReg == iOp1 and ((iBaseReg != 5 and iBaseReg != 13) or iMod != 0) and cAddrBits != cbMaxOp:
     724                        continue; # Don't know the high bit of the address ending up the result - skip it for now.
     725                    if iIndexReg == iOp1 and iIndexReg != 4 and cAddrBits != cbMaxOp:
    720726                        continue; # Don't know the high bit of the address ending up the result - skip it for now.
    721727                    for iScale in (1, 2, 4, 8):
     
    746752
    747753        # Register tests
    748         if True:
     754        if False:
    749755            for cbEffOp in self.acbOpVars:
    750756                if cbEffOp > cbMaxOp:
     
    777783
    778784        # Memory test.
    779         if False:
     785        if True:
    780786            for cbEffOp in self.acbOpVars:
    781787                if cbEffOp > cbMaxOp:
     
    786792                    for cAddrBits in oGen.oTarget.getAddrModes():
    787793                        auInputs = auLongInputs if iOp1 == iLongOp1 and False else auShortInputs;
    788                         for iOp2 in range(len(oGen.oTarget.asGRegs)):
     794                        for iOp2 in range(oGen.oTarget.getGRegCount(cAddrBits / 8)):
    789795                            if iOp2 != 4 or cAddrBits == 16:
    790796                                for uInput in auInputs:
     
    798804                                # SIB.
    799805                                self.generateStdTestGregMemSib(oGen, cAddrBits, cbEffOp, cbMaxOp, iOp1, auInputs);
     806                    break;
     807                break;
     808
    800809
    801810        return True;
     
    10201029            aoffDisp = [ None, ];
    10211030        elif iMod == 1:
    1022             aoffDisp = [ 127 & ~cbAlignment, -128 ];
     1031            aoffDisp = [ 127 & ~(cbAlignment - 1), -128 ];
    10231032        elif iMod == 2:
    10241033            aoffDisp = [ 2147483647 & ~(cbAlignment - 1), -2147483648 ];
     
    11391148            # Unpack it.
    11401149            asParams = sName.split('_');
    1141             cAddrBits  = int(asParams[0][:-3]);
    1142             cEffOpBits = int(asParams[1][1:]);
     1150            cAddrBits  = int(asParams[0][:-3]); assert asParams[0][-3:] == 'bit';
     1151            cEffOpBits = int(asParams[1][1:]);  assert asParams[1][0]   == 'U';
    11431152            if cAddrBits == 64:   asAddrGRegs = g_asGRegs64;
    11441153            elif cAddrBits == 32: asAddrGRegs = g_asGRegs32;
     
    11461155
    11471156            i = 2;
    1148             if i < len(asParams[i]) and asParams[i]:
     1157            iBaseReg = None;
     1158            sBaseReg = None;
     1159            if i < len(asParams) and asParams[i] in asAddrGRegs:
    11491160                sBaseReg = asParams[i];
     1161                iBaseReg = asAddrGRegs.index(sBaseReg);
    11501162                i += 1
    1151                 try:
    1152                     iBaseReg = asAddrGRegs.index(sBaseReg);
    1153                 except ValueError:
    1154                     assert False, 'sBaseReg=%s' % (sBaseReg,);
    1155                     raise;
     1163
     1164            assert i < len(asParams); assert asParams[i][0] == 'x';
     1165            iScale = iScale = int(asParams[i][1:]); assert iScale in [1, 2, 4, 8];
     1166            i += 1;
     1167
     1168            sIndexReg = None;
     1169            iIndexReg = None;
     1170            if i < len(asParams) and asParams[i] in asAddrGRegs:
     1171                sIndexReg = asParams[i];
     1172                iIndexReg  = asAddrGRegs.index(sIndexReg);
     1173                i += 1;
    11561174
    11571175            u32Disp = None;
     
    11601178                i += 1;
    11611179
    1162             sIndexReg = None;
    1163             iIndexReg = None;
    1164             if i < len(asParams):
    1165                 sIndexReg = asParams[i];
    1166                 iBaseReg  = asAddrGRegs.index(sBaseReg);
    1167                 i += 1;
    1168 
    1169             iScale = 1;
    1170             if i < len(asParams):
    1171                 iScale = int(asParams[i]); assert iScale in [2, 4, 8];
    1172                 i += 1;
    1173 
    11741180            assert i == len(asParams), 'i=%d len=%d len[i]=%d (%s)' % (i, len(asParams), len(asParams[i]), asParams[i],);
     1181            assert iScale == 1 or iIndexReg is not None;
     1182
     1183            # Find a temporary register.
     1184            iTmpReg1 = X86_GREG_xCX;
     1185            while iTmpReg1 in [iBaseReg, iIndexReg]:
     1186                iTmpReg1 += 1;
    11751187
    11761188            # Prologue.
    1177             iTmpReg1 = 0 if iBaseReg != 0 else 1;
    11781189            self.write('\n\n'
     1190                       '; cAddrBits=%s cEffOpBits=%s iBaseReg=%s u32Disp=%s iIndexReg=%s iScale=%s\n'
    11791191                       'VBINSTST_BEGINPROC Common_MemSetup_%s\n'
    11801192                       '        MY_PUSH_FLAGS\n'
    11811193                       '        push    %s\n'
    1182                        % (sName, self.oTarget.asGRegs[iTmpReg1], ));
    1183             self.write('; cAddrBits=%s cEffOpBits=%s iBaseReg=%s u32Disp=%s iIndexReg=%s iScale=%s\n'
    1184                        % (cAddrBits, cEffOpBits, iBaseReg, u32Disp, iIndexReg, iScale,));
     1194                       % ( cAddrBits, cEffOpBits, iBaseReg, u32Disp, iIndexReg, iScale,
     1195                           sName, self.oTarget.asGRegs[iTmpReg1], ));
    11851196
    11861197            # Figure out what to use.
     
    11951206                sDataVar = 'VBINSTST_NAME(g_u16Data)';
    11961207            else:
    1197                 assert cEffOpBits == 8;
     1208                assert cEffOpBits == 8; assert iTmpReg1 < 4;
    11981209                sTmpReg1 = g_asGRegs8Rex[iTmpReg1];
    11991210                sDataVar = 'VBINSTST_NAME(g_u8Data)';
    12001211
    1201             # Load the value and mem address, sorting the value there.
    1202             self.write('        mov     %s, [xSP + sCB + MY_PUSH_FLAGS_SIZE + xCB]\n' % (sTmpReg1,));
    1203             if cAddrBits >= cDefAddrBits:
    1204                 self.write('        mov     [%s xWrtRIP], %s\n' % (sDataVar, sTmpReg1,));
    1205                 self.write('        lea     %s, [%s xWrtRIP]\n' % (sBaseReg, sDataVar,));
     1212            # Special case: reg + reg * [2,4,8]
     1213            if iBaseReg == iIndexReg and iBaseReg is not None and iScale != 1:
     1214                iTmpReg2 = X86_GREG_xBP;
     1215                while iTmpReg2 in [iBaseReg, iIndexReg, iTmpReg1]:
     1216                    iTmpReg2 += 1;
     1217                sTmpReg2 = gregName(iTmpReg2, cAddrBits);
     1218                self.write('        push    sAX\n'
     1219                           '        push    %s\n'
     1220                           '        push    sDX\n'
     1221                           % (self.oTarget.asGRegs[iTmpReg2],));
     1222                if cAddrBits == 16:
     1223                    self.write('        mov     %s, [VBINSTST_NAME(g_pvLow16Mem4K) xWrtRIP]\n' % (sTmpReg2,));
     1224                else:
     1225                    self.write('        mov     %s, [VBINSTST_NAME(g_pvLow32Mem4K) xWrtRIP]\n' % (sTmpReg2,));
     1226                self.write('        add     %s, 0x200\n' % (sTmpReg2,));
     1227                self.write('        mov     %s, %s\n' % (gregName(X86_GREG_xAX, cAddrBits), sTmpReg2,));
     1228                if u32Disp is not None:
     1229                    self.write('        sub     %s, %d\n' % ( gregName(X86_GREG_xAX, cAddrBits), convU32ToSigned(u32Disp), ));
     1230                self.write('        xor     edx, edx\n'
     1231                           '%if xCB == 2\n'
     1232                           '        push    0\n'
     1233                           '%endif\n');
     1234                self.write('        push    %u\n' % (iScale + 1,));
     1235                self.write('        div     %s [xSP]\n' % ('qword' if cAddrBits == 64 else 'dword',));
     1236                self.write('        sub     %s, %s\n' % (sTmpReg2, gregName(X86_GREG_xDX, cAddrBits),));
     1237                self.write('        pop     sDX\n'
     1238                           '        pop     sDX\n'); # sTmpReg2 is eff address; sAX is sIndexReg value.
     1239                # Note! sTmpReg1 can be xDX and that's no problem now.
     1240                self.write('        mov     %s, [xSP + sCB*3 + MY_PUSH_FLAGS_SIZE + xCB]\n' % (sTmpReg1,));
     1241                self.write('        mov     [%s], %s\n' % (sTmpReg2, sTmpReg1,)); # Value in place.
     1242                self.write('        pop     %s\n' % (self.oTarget.asGRegs[iTmpReg2],));
     1243                if iBaseReg == X86_GREG_xAX:
     1244                    self.write('        pop     %s\n' % (self.oTarget.asGRegs[iTmpReg1],));
     1245                else:
     1246                    self.write('        mov     %s, %s\n' % (sBaseReg, gregName(X86_GREG_xAX, cAddrBits),));
     1247                    self.write('        pop     sAX\n');
     1248
    12061249            else:
    1207 
    1208                 if cAddrBits == 16:
    1209                     self.write('        mov     %s, [VBINSTST_NAME(g_pvLow16Mem4K) xWrtRIP]\n' % (sBaseReg,));
     1250                # Load the value and mem address, storing the value there.
     1251                # Note! ASSUMES that the scale and disposition works fine together.
     1252                sAddrReg = sBaseReg if sBaseReg is not None else sIndexReg;
     1253                self.write('        mov     %s, [xSP + sCB + MY_PUSH_FLAGS_SIZE + xCB]\n' % (sTmpReg1,));
     1254                if cAddrBits >= cDefAddrBits:
     1255                    self.write('        mov     [%s xWrtRIP], %s\n' % (sDataVar, sTmpReg1,));
     1256                    self.write('        lea     %s, [%s xWrtRIP]\n' % (sAddrReg, sDataVar,));
    12101257                else:
    1211                     self.write('        mov     %s, [VBINSTST_NAME(g_pvLow32Mem4K) xWrtRIP]\n' % (sBaseReg,));
    1212                 self.write('        add     %s, %s\n' % (sBaseReg, (randU16() << cEffOpBits) & 0xfff, ));
    1213                 self.write('        mov     [%s], %s\n' % (sBaseReg, sTmpReg1, ));
    1214 
    1215             # Adjust for disposition and scaling.
    1216             if u32Disp is not None:
    1217                 self.write('        sub     %s, %d\n' % ( sBaseReg, convU32ToSigned(u32Disp), ));
    1218             if iIndexReg is not None:
    1219                 uIdxRegVal = randUxx(cAddrBits);
    1220                 self.write('        mov     %s, %u\n' % ( sIndexReg, uIdxRegVal,));
    1221                 if cAddrBits == 64:
    1222                     self.write('        sub     %s, %#06x\n' % ( sBaseReg, uIdxRegVal * iScale, ));
    1223                 elif cAddrBits == 16:
    1224                     self.write('        sub     %s, %#06x\n' % ( sBaseReg, (uIdxRegVal * iScale) & UINT32_MAX, ));
    1225                 else:
    1226                     assert cAddrBits == 16;
    1227                     self.write('        sub     %s, %#06x\n' % ( sBaseReg, (uIdxRegVal * iScale) & UINT16_MAX, ));
     1258                    if cAddrBits == 16:
     1259                        self.write('        mov     %s, [VBINSTST_NAME(g_pvLow16Mem4K) xWrtRIP]\n' % (sAddrReg,));
     1260                    else:
     1261                        self.write('        mov     %s, [VBINSTST_NAME(g_pvLow32Mem4K) xWrtRIP]\n' % (sAddrReg,));
     1262                    self.write('        add     %s, %s\n' % (sAddrReg, (randU16() << cEffOpBits) & 0xfff, ));
     1263                    self.write('        mov     [%s], %s\n' % (sAddrReg, sTmpReg1, ));
     1264
     1265                # Adjust for disposition and scaling.
     1266                if u32Disp is not None:
     1267                    self.write('        sub     %s, %d\n' % ( sAddrReg, convU32ToSigned(u32Disp), ));
     1268                if iIndexReg is not None:
     1269                    if iBaseReg == iIndexReg:
     1270                        assert iScale == 1;
     1271                        assert u32Disp is None or (u32Disp & 1) == 0;
     1272                        self.write('        shr     %s, 1\n' % (sIndexReg,));
     1273                    elif sBaseReg is not None:
     1274                        uIdxRegVal = randUxx(cAddrBits);
     1275                        if cAddrBits == 64:
     1276                            self.write('        mov     %s, %u\n'
     1277                                       '        sub     %s, %s\n'
     1278                                       '        mov     %s, %u\n'
     1279                                       % ( sIndexReg, (uIdxRegVal * iScale) & UINT64_MAX,
     1280                                           sBaseReg, sIndexReg,
     1281                                           sIndexReg, uIdxRegVal, ));
     1282                        else:
     1283                            assert cAddrBits == 32;
     1284                            self.write('        mov     %s, %u\n'
     1285                                       '        sub     %s, %#06x\n'
     1286                                       % ( sIndexReg, uIdxRegVal, sBaseReg, (uIdxRegVal * iScale) & UINT32_MAX, ));
     1287                    elif iScale == 2:
     1288                        assert u32Disp is None or (u32Disp & 1) == 0;
     1289                        self.write('        shr     %s, 1\n' % (sIndexReg,));
     1290                    elif iScale == 4:
     1291                        assert u32Disp is None or (u32Disp & 3) == 0;
     1292                        self.write('        shr     %s, 2\n' % (sIndexReg,));
     1293                    elif iScale == 8:
     1294                        assert u32Disp is None or (u32Disp & 7) == 0;
     1295                        self.write('        shr     %s, 3\n' % (sIndexReg,));
     1296                    else:
     1297                        assert iScale == 1;
    12281298
    12291299            # Set upper bits that's supposed to be unused.
     
    12311301                if cDefAddrBits == 64:
    12321302                    assert cAddrBits == 32;
    1233                     self.write('        mov     %s, %#018x\n'
    1234                                '        or      %s, %s\n'
    1235                                % ( g_asGRegs64[iTmpReg1], randU64() & 0xffffffff00000000,
    1236                                    g_asGRegs64[iBaseReg], g_asGRegs64[iTmpReg1],));
    1237                     if iIndexReg is not None:
     1303                    if iBaseReg is not None:
     1304                        self.write('        mov     %s, %#018x\n'
     1305                                   '        or      %s, %s\n'
     1306                                   % ( g_asGRegs64[iTmpReg1], randU64() & 0xffffffff00000000,
     1307                                       g_asGRegs64[iBaseReg], g_asGRegs64[iTmpReg1],));
     1308                    if iIndexReg is not None and iIndexReg != iBaseReg:
    12381309                        self.write('        mov     %s, %#018x\n'
    12391310                                   '        or      %s, %s\n'
     
    12411312                                       g_asGRegs64[iIndexReg], g_asGRegs64[iTmpReg1],));
    12421313                else:
    1243                     assert cDefAddrBits == 32; assert cAddrBits == 16;
    1244                     self.write('        or      %s, %#010x\n'
    1245                                % ( g_asGRegs32[iBaseReg], randU32() & 0xffff0000, ));
    1246                     if iIndexReg is not None:
     1314                    assert cDefAddrBits == 32; assert cAddrBits == 16; assert iIndexReg is None;
     1315                    if iBaseReg is not None:
    12471316                        self.write('        or      %s, %#010x\n'
    1248                                    % ( g_asGRegs32[iIndexReg], randU32() & 0xffff0000, ));
     1317                                   % ( g_asGRegs32[iBaseReg], randU32() & 0xffff0000, ));
    12491318
    12501319            # Epilogue.
     
    12761345
    12771346            # Register checks.
    1278             iRegPrev = -1;
    12791347            for i in range(len(asRegs)):
    12801348                sReg = asRegs[i];
     
    13331401            self.oFile = sys.stdout;
    13341402            if self.oOptions.sOutputBase != '-':
    1335                 self.oFile = io.open(self.sFile, 'w', encoding = 'utf-8');
     1403                self.oFile = io.open(self.sFile, 'w', buffering = 65536, encoding = 'utf-8');
    13361404
    13371405            self._generateFileHeader();
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