VirtualBox

Changeset 46853 in vbox


Ignore:
Timestamp:
Jun 27, 2013 5:53:01 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
86806
Message:

NMI -> laptop.

File:
1 edited

Legend:

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

    r46771 r46853  
    392392        return True;
    393393
    394 
    395394    def writeInstrGregPureRM(self, cbEffOp, iOp1, cAddrBits, iOp2, iMod, offDisp, oGen):
    396395        """ Writes the instruction with two general registers as operands. """
    397         if iOp2 == 13 and iMod == 0 and cAddrBits == 64: # Alt rip encoding, yasm isn't helping, do what we can.
    398             if cbEffOp == 2:
    399                 oGen.write('        db %#04x\n' % (X86_OP_PRF_SIZE_OP,));
    400             bRex = X86_OP_REX_B;
    401             if iOp1 >= 8:
    402                 bRex |= X86_OP_REX_R;
    403             if cbEffOp == 8:
    404                 bRex |= X86_OP_REX_W;
    405             oGen.write('        db %#04x\n' % (bRex,));
    406             if cbEffOp == 1:
    407                 oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs8[iOp1 & 0x7],));
    408             else:
    409                 oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs32[iOp1 & 0x7],));
    410         elif cbEffOp == 8:
    411             oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs64[iOp1],));
     396        oGen.write('        ');
     397        if iOp2 == 13 and iMod == 0 and cAddrBits == 64:
     398            oGen.write('altrexb '); # Alternative encoding for rip relative addressing.
     399        if cbEffOp == 8:
     400            oGen.write('%s %s, [' % (self.sInstr, g_asGRegs64[iOp1],));
    412401        elif cbEffOp == 4:
    413             oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs32[iOp1],));
     402            oGen.write('%s %s, [' % (self.sInstr, g_asGRegs32[iOp1],));
    414403        elif cbEffOp == 2:
    415             oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs16[iOp1],));
     404            oGen.write('%s %s, [' % (self.sInstr, g_asGRegs16[iOp1],));
    416405        elif cbEffOp == 1:
    417             oGen.write('        %s %s, [' % (self.sInstr, g_asGRegs8Rex[iOp1],));
     406            oGen.write('%s %s, [' % (self.sInstr, g_asGRegs8Rex[iOp1],));
    418407        else:
    419408            assert False;
     
    443432        return True;
    444433
    445     def writeInstrGregSibLabel(self, cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, oGen):
    446         """ Writes the instruction taking a register and a lable, SIB form. """
    447         ## @todo Dunno how to convince yasm to generate these. Considering patching it.
    448         oGen.write('        %s %s, [VBINSTST_NAME(g_u%sData) xWrtRIP]\n'
    449                    % (self.sInstr, gregName(iOp1, cbEffOp * 8),));
     434    def writeInstrGregSibLabel(self, cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, offDisp, oGen):
     435        """ Writes the instruction taking a register and a label (base only w/o reg), SIB form. """
     436        assert offDisp is None; assert iBaseReg in [5, 13]; assert iIndexReg == 4; assert cAddrBits != 16;
     437        if cAddrBits == 64:
     438            # Note! Cannot test this in 64-bit mode in any sensible way because the disp is 32-bit
     439            #       and we cannot (yet) make assumtions about where we're loaded.
     440            ## @todo Enable testing this in environments where we can make assumptions (boot sector).
     441            oGen.write('        %s %s, [VBINSTST_NAME(g_u%sData) xWrtRIP]\n'
     442                       % ( self.sInstr, gregName(iOp1, cbEffOp * 8), cbEffOp * 8,));
     443        else:
     444            oGen.write('        altsibx%u %s %s, [VBINSTST_NAME(g_u%sData) xWrtRIP]\n'
     445                       % ( iScale, self.sInstr, gregName(iOp1, cbEffOp * 8), cbEffOp * 8,));
    450446        return True;
    451447
    452448    def writeInstrGregSibScaledReg(self, cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, offDisp, oGen):
    453         ## @todo Dunno how to convince yasm to generate SIB variants for iScale == 1 here. Considering patching it.
    454         oGen.write('        %s %s, [%s * %#x'
    455                    % (self.sInstr, gregName(iOp1, cbEffOp * 8), gregName(iIndexReg, cAddrBits), iScale,));
     449        """ Writes the instruction taking a register and disp+scaled register (no base reg), SIB form. """
     450        assert iBaseReg in [5, 13]; assert iIndexReg != 4;  assert cAddrBits != 16;
     451        # Note! Using altsibxN to force scaled encoding. This is only really a
     452        #       necessity for iScale=1, but doesn't hurt for the rest.
     453        oGen.write('        altsibx%u %s %s, [%s * %#x'
     454                   % (iScale, self.sInstr, gregName(iOp1, cbEffOp * 8), gregName(iIndexReg, cAddrBits), iScale,));
    456455        if offDisp is not None:
    457456            oGen.write(' + %#x' % (offDisp,));
    458         oGen.write('] ; iScale=%s\n' % (iScale,));
     457        oGen.write(']\n');
    459458        _ = iBaseReg;
    460459        return True;
    461460
    462461    def writeInstrGregSibBase(self, cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, offDisp, oGen):
    463         ## @todo Dunno how to convince yasm to generate SIB variants for iScale == 1 here. Considering patching it.
    464         oGen.write('        %s %s, [%s'
    465                    % (self.sInstr, gregName(iOp1, cbEffOp * 8), gregName(iBaseReg, cAddrBits), iScale,));
     462        """ Writes the instruction taking a register and base only (with reg), SIB form. """
     463        oGen.write('        altsibx%u %s %s, [%s'
     464                   % (iScale, self.sInstr, gregName(iOp1, cbEffOp * 8), gregName(iBaseReg, cAddrBits),));
    466465        if offDisp is not None:
    467466            oGen.write(' + %#x' % (offDisp,));
    468         oGen.write('] ; iScale=%s\n' % (iScale,));
     467        oGen.write(']\n');
    469468        _ = iIndexReg;
    470469        return True;
    471470
    472471    def writeInstrGregSibBaseAndScaledReg(self, cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, offDisp, oGen):
     472        """ Writes tinstruction taking a register and full featured SIB form address. """
     473        # Note! From the looks of things, yasm will encode the following instructions the same way:
     474        #           mov eax, [rsi*1 + rbx]
     475        #           mov eax, [rbx + rsi*1]
     476        #       So, when there are two registers involved, the '*1' selects
     477        #       which is index and which is base.
     478        oGen.write('        %s %s, [%s + %s * %u'
     479                   % ( self.sInstr, gregName(iOp1, cbEffOp * 8),
     480                       gregName(iBaseReg, cAddrBits), gregName(iIndexReg, cAddrBits), iScale,));
     481        if offDisp is not None:
     482            oGen.write(' + %#x' % (offDisp,));
     483        oGen.write(']\n');
    473484        return True;
    474485
     
    478489    ## @name Memory setups
    479490    ## @{
    480     def generateMemSetupReadByLabel(self, oGen, cAddrBits, uInput):
     491    def generateMemSetupReadByLabel(self, oGen, cbEffOp, uInput):
    481492        """ Sets up memory for a memory read. """
    482493        oGen.pushConst(uInput);
     
    488499        oGen.pushConst(uInput);
    489500        oGen.write('        call    VBINSTST_NAME(%s)\n'
    490                    % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iReg1, offDisp),));
     501                   % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iBaseReg = iReg1, offDisp = offDisp),));
    491502        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iReg1],));
    492503        return True;
    493504
    494     def generateMemSetupReadByScaledReg(self, oGen, cAddrBits, cbEffOp, iReg2, iScale, uInput, offDisp = None):
     505    def generateMemSetupReadByScaledReg(self, oGen, cAddrBits, cbEffOp, iIndexReg, iScale, uInput, offDisp = None):
    495506        """ Sets up memory for a memory read indirectly addressed thru one register and optional displacement. """
    496507        oGen.pushConst(uInput);
    497508        oGen.write('        call    VBINSTST_NAME(%s)\n'
    498                    % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iReg2, offDisp, iScale = iScale),));
    499         oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iReg1],));
     509                   % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, offDisp = offDisp, iIndexReg = iIndexReg, iScale = iScale),));
     510        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iIndexReg],));
    500511        return True;
    501512
     
    503514        """ Sets up memory for a memory read indirectly addressed thru two registers with optional displacement. """
    504515        oGen.pushConst(uInput);
    505         if iScale == 1:
    506516        oGen.write('        call    VBINSTST_NAME(%s)\n'
    507                    % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iReg1, offDisp),));
    508         oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iReg1],));
     517                   % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iBaseReg = iBaseReg, offDisp = offDisp,
     518                                            iIndexReg = iIndexReg, iScale = iScale),));
     519        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iBaseReg],));
     520        oGen.write('        push    %s\n' % (oGen.oTarget.asGRegs[iIndexReg],));
    509521        return True;
    510522
     
    565577        return True;
    566578
    567     def generateOneStdTestGregMemNoSib(self, oGen, cAddrBits, cbEffOp, cbMaxOp, iOp1, iMod,
    568                                        iBaseReg, iIndexReg, iScale, uInput, uResult):
     579    def generateOneStdTestGregMemSib(self, oGen, cAddrBits, cbEffOp, cbMaxOp, iOp1, iMod, # pylint: disable=R0913
     580                                     iBaseReg, iIndexReg, iScale, uInput, uResult):
    569581        """ Generate one SIB variations. """
    570582        for offDisp in oGen.getDispForMod(iMod, cbEffOp):
     
    574586                        continue; # skipping.
    575587                    oGen.write('        call    VBINSTST_NAME(Common_LoadKnownValues)\n');
    576                     self.generateMemSetupReadByLabel(oGen, cAddrBits, uInput);
    577                     self.writeInstrGregSibLabel(cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, oGen);
     588                    self.generateMemSetupReadByLabel(oGen, cbEffOp, uInput);
     589                    self.writeInstrGregSibLabel(cbEffOp, iOp1, cAddrBits, iBaseReg, iIndexReg, iScale, offDisp, oGen);
    578590                    sChecker = oGen.needGRegChecker(iOp1);
    579591                else:
     
    595607            oGen.pushConst(uResult);
    596608            oGen.write('        call    VBINSTST_NAME(%s)\n' % (sChecker,));
     609        _ = cbMaxOp;
    597610        return True;
    598611
     
    659672                        continue;
    660673                    for cAddrBits in oGen.oTarget.getAddrModes():
     674                        auInputs = auLongInputs if iOp1 == iLongOp1 and False else auShortInputs;
    661675                        for iOp2 in range(len(oGen.oTarget.asGRegs)):
    662676                            if iOp2 != 4 or cAddrBits == 16:
    663                                 for uInput in (auLongInputs if iOp1 == iLongOp1 and False else auShortInputs):
     677                                for uInput in auInputs:
    664678                                    oGen.newSubTest();
    665679                                    if iOp1 == iOp2 and iOp2 != 5 and iOp2 != 13 and cbEffOp != cbMaxOp:
     
    828842        Records the need for a given register checker function, returning its label.
    829843        """
    830         assert iReg1 < 32; assert iReg2 < 32;
    831         iRegs = iReg1 + iReg2 * 32;
    832         if iRegs in self.dCheckFns:
    833             self.dCheckFns[iRegs] += 1;
     844        if iReg2 is not None:
     845            if iReg3 is not None:
     846                sName = '%s_%s_%s' % (self.oTarget.asGRegs[iReg1], self.oTarget.asGRegs[iReg2], self.oTarget.asGRegs[iReg3],);
     847            else:
     848                sName = '%s_%s' % (self.oTarget.asGRegs[iReg1], self.oTarget.asGRegs[iReg2],);
    834849        else:
    835             self.dCheckFns[iRegs]  = 1;
    836         return 'Common_Check_%s_%s' % (self.oTarget.asGRegs[iReg1], self.oTarget.asGRegs[iReg2]);
    837 
    838     def needGRegMemSetup(self, cAddrBits, cbEffOp, iBaseReg, offDisp = None, iIndexReg = None, iScale = 1):
     850            sName = '%s' % (self.oTarget.asGRegs[iReg1],);
     851            assert iReg3 is None;
     852
     853        if sName in self.dCheckFns:
     854            self.dCheckFns[sName] += 1;
     855        else:
     856            self.dCheckFns[sName]  = 1;
     857
     858        return 'Common_Check_' + sName;
     859
     860    def needGRegMemSetup(self, cAddrBits, cbEffOp, iBaseReg = None, offDisp = None, iIndexReg = None, iScale = 1):
    839861        """
    840862        Records the need for a given register checker function, returning its label.
     
    848870        if offDisp is not None:
    849871            sName += '_%#010x' % (offDisp & UINT32_MAX, );
    850         if sName in self.dCheckFns:
     872        if sName in self.dMemSetupFns:
    851873            self.dMemSetupFns[sName] += 1;
    852874        else:
     
    11271149
    11281150        # Register checking functions.
    1129         for iRegs in self.dCheckFns:
     1151        for sName in self.dCheckFns:
     1152            # Decode the name.
     1153            asRegs = sName.split('_');
     1154            sReg1 = asRegs[0];
     1155            iReg1 = self.oTarget.index(sReg1);
     1156            if len(asRegs) >= 2:
     1157                sReg2 = None;
     1158                iReg2 = None;
     1159
    11301160            iReg1 = iRegs & 0x1f;
    11311161            sReg1 = self.oTarget.asGRegs[iReg1];
     
    11341164            sPushSize = 'dword';
    11351165
     1166            # Write the test
    11361167            self.write('\n\n'
    11371168                       '; Checks two register values, expected values pushed on the stack.\n'
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