VirtualBox

Changeset 98904 in vbox for trunk/src


Ignore:
Timestamp:
Mar 10, 2023 3:47:07 PM (22 months ago)
Author:
vboxsync
Message:

VMM/IEM: More work on processing MC blocks. bugref:10369

Location:
trunk/src/VBox/VMM/VMMAll
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py

    r98881 r98904  
    17401740
    17411741
     1742#
     1743# "Microcode" statements and blocks
     1744#
     1745
    17421746class McStmt(object):
    17431747    """
     
    17541758        Renders the code for the statement.
    17551759        """
    1756         return ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ');';
     1760        return ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ');\n';
     1761
     1762    @staticmethod
     1763    def renderCodeForList(aoStmts, cchIndent = 0):
     1764        """
     1765        Renders a list of statements.
     1766        """
     1767        return ''.join([oStmt.renderCode(cchIndent) for oStmt in aoStmts]);
     1768
     1769    def isCppStmt(self):
     1770        """ Checks if this is a C++ statement. """
     1771        return self.sName.startswith('C++');
    17571772
    17581773class McStmtCond(McStmt):
     
    17661781    def renderCode(self, cchIndent = 0):
    17671782        sRet  = ' ' * cchIndent + self.sName + '(' + ', '.join(self.asParams) + ') {\n';
    1768         for oStmt in self.aoIfBranch:
    1769             sRet += oStmt.renderCode(cchIndent + 4);
     1783        sRet += self.renderCodeForList(self.aoIfBranch, cchIndent + 4);
    17701784        if self.aoElseBranch:
    17711785            sRet += ' ' * cchIndent + '} IEM_MC_ELSE() {\n';
    1772             for oStmt in self.aoElseBranch:
    1773                 sRet += oStmt.renderCode(cchIndent + 4);
    1774         sRet += ' ' * cchIndent + '} IEM_MC_ENDIF();';
     1786            sRet += self.renderCodeForList(self.aoElseBranch, cchIndent + 4);
     1787        sRet += ' ' * cchIndent + '} IEM_MC_ENDIF();\n';
    17751788        return sRet;
     1789
     1790class McStmtVar(McStmt):
     1791    """ IEM_MC_LOCAL_VAR* """
     1792    def __init__(self, sName, asParams, sType, sVarName, sConstValue = None):
     1793        McStmt.__init__(self, sName, asParams);
     1794        self.sType       = sType;
     1795        self.sVarName    = sVarName;
     1796        self.sConstValue = sConstValue;     ##< None if not const.
     1797
     1798class McStmtArg(McStmtVar):
     1799    """ IEM_MC_ARG* """
     1800    def __init__(self, sName, asParams, sType, sVarName, iArg, sConstValue = None, sRef = None, sRefType = 'none'):
     1801        McStmtVar.__init__(self, sName, asParams, sType, sVarName, sConstValue);
     1802        self.iArg       = iArg;
     1803        self.sRef       = sRef;       ##< The reference string (local variable, register).
     1804        self.sRefType   = sRefType;   ##< The kind of reference: 'local', 'none'.
     1805        assert sRefType in ('none', 'local');
    17761806
    17771807class McCppGeneric(McStmt):
     
    17801810    """
    17811811
     1812    def __init__(self, sCode, fDecode, sName = 'C++'):
     1813        McStmt.__init__(self, sName, [sCode,]);
     1814        self.fDecode = fDecode;
     1815
     1816    def renderCode(self, cchIndent = 0):
     1817        sRet = ' ' * cchIndent + self.asParams[0] + '\n';
     1818        if self.fDecode:
     1819            sRet = sRet.replace('\n', ' // C++ decode\n');
     1820        else:
     1821            sRet = sRet.replace('\n', ' // C++ normal\n');
     1822        return sRet;
     1823
     1824class McCppCond(McStmtCond):
     1825    """
     1826    C++/C 'if' statement.
     1827    """
     1828    def __init__(self, sCode, fDecode):
     1829        McStmtCond.__init__(self, 'C++/if', [sCode,]);
     1830        self.fDecode = fDecode;
     1831
     1832    def renderCode(self, cchIndent = 0):
     1833        sAnnotation = '// C++ decode' if self.fDecode else '// C++ normal';
     1834        sRet  = ' ' * cchIndent + 'if (' + self.asParams[0] + ') ' + sAnnotation + '\n';
     1835        sRet += ' ' * cchIndent + '{\n';
     1836        sRet += self.renderCodeForList(self.aoIfBranch, cchIndent + 4);
     1837        sRet += ' ' * cchIndent + '}\n';
     1838        if self.aoElseBranch:
     1839            sRet += ' ' * cchIndent + 'else ' + sAnnotation + '\n';
     1840            sRet += ' ' * cchIndent + '{\n';
     1841            sRet += self.renderCodeForList(self.aoElseBranch, cchIndent + 4);
     1842            sRet += ' ' * cchIndent + '}\n';
     1843        return sRet;
     1844
     1845class McCppPreProc(McCppGeneric):
     1846    """
     1847    C++/C Preprocessor directive.
     1848    """
     1849
    17821850    def __init__(self, sCode):
    1783         McStmt.__init__(self, 'C++', [sCode,]);
     1851        McCppGeneric.__init__(self, sCode, False, sName = 'C++/preproc');
    17841852
    17851853    def renderCode(self, cchIndent = 0):
    1786         return ' ' * cchIndent + self.asParams[0];
    1787 
    1788 #class McLocalVar(McStmt):
    1789 #
    1790 #    def __init__(self, sRaw, , ):
     1854        return self.asParams[0] + '\n';
    17911855
    17921856
     
    17961860    """
    17971861
    1798     def __init__(self, sSrcFile, iBeginLine, offBeginLine, sFunction, iInFunction):
     1862    def __init__(self, sSrcFile, iBeginLine, offBeginLine, sFunction, iInFunction, cchIndent = None):
    17991863        self.sSrcFile     = sSrcFile;                           ##< The source file containing the block.
    18001864        self.iBeginLine   = iBeginLine;                         ##< The line with the IEM_MC_BEGIN statement.
     
    18041868        self.sFunction    = sFunction;                          ##< The function the block resides in.
    18051869        self.iInFunction  = iInFunction;                        ##< The block number wihtin the function.
     1870        self.cchIndent    = cchIndent if cchIndent else offBeginLine;
    18061871        self.asLines      = []              # type: list(str)   ##< The raw lines the block is made up of.
    18071872        ## Decoded statements in the block.
     
    18231888        raise ParserException('%s:%d:%d: parsing error: %s'
    18241889                              % (self.sSrcFile, self.iBeginLine + iLine, off - offStartOfLine + 1, sMessage,));
     1890
     1891    def raiseStmtError(self, sName, sMessage):
     1892        """ Raises a statement parser error. """
     1893        raise ParserException('%s:%d: %s: parsing error: %s' % (self.sSrcFile, self.iBeginLine, sName, sMessage,));
     1894
     1895    def checkStmtParamCount(self, sName, asParams, cParamsExpected):
     1896        """ Check the parameter count, raising an error it doesn't match. """
     1897        if len(asParams) != cParamsExpected:
     1898            raise ParserException('%s:%d: %s: Expected %s parameters, found %s!'
     1899                                  % (self.sSrcFile, self.iBeginLine, sName, cParamsExpected, len(asParams),));
     1900        return True;
     1901
    18251902    @staticmethod
    18261903    def parseMcGeneric(oSelf, sName, asParams):
     
    18381915    def parseMcBegin(oSelf, sName, asParams):
    18391916        """ IEM_MC_BEGIN """
     1917        oSelf.checkStmtParamCount(sName, asParams, 2);
    18401918        return McBlock.parseMcGeneric(oSelf, sName, asParams);
     1919
     1920    @staticmethod
     1921    def parseMcArg(oSelf, sName, asParams):
     1922        """ IEM_MC_ARG """
     1923        oSelf.checkStmtParamCount(sName, asParams, 3);
     1924        return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[2]));
     1925
     1926    @staticmethod
     1927    def parseMcArgConst(oSelf, sName, asParams):
     1928        """ IEM_MC_ARG_CONST """
     1929        oSelf.checkStmtParamCount(sName, asParams, 4);
     1930        return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[3]), sConstValue = asParams[2]);
     1931
     1932    @staticmethod
     1933    def parseMcArgLocalRef(oSelf, sName, asParams):
     1934        """ IEM_MC_ARG_LOCAL_REF """
     1935        oSelf.checkStmtParamCount(sName, asParams, 4);
     1936        return McStmtArg(sName, asParams, asParams[0], asParams[1], int(asParams[3]), sRef = asParams[2], sRefType = 'local');
     1937
     1938    @staticmethod
     1939    def parseMcArgLocalEFlags(oSelf, sName, asParams):
     1940        """ IEM_MC_ARG_LOCAL_EFLAGS """
     1941        oSelf.checkStmtParamCount(sName, asParams, 3);
     1942        # Note! We split this one up into IEM_MC_LOCAL_VAR and IEM_MC_ARG_LOCAL_REF.
     1943        return (
     1944            McStmtVar('IEM_MC_LOCAL_VAR', ['uint32_t', asParams[1],], 'uint32_t', asParams[1]),
     1945            McStmtArg('IEM_MC_ARG_LOCAL_REF', ['uint32_t *', asParams[0], asParams[2], asParams[1]],
     1946                      'uint32_t *', asParams[0], int(asParams[2]), sRef = asParams[1], sRefType = 'local'),
     1947        );
     1948
     1949    @staticmethod
     1950    def parseMcLocal(oSelf, sName, asParams):
     1951        """ IEM_MC_LOCAL """
     1952        oSelf.checkStmtParamCount(sName, asParams, 2);
     1953        return McStmtVar(sName, asParams, asParams[0], asParams[1]);
     1954
     1955    @staticmethod
     1956    def parseMcLocalConst(oSelf, sName, asParams):
     1957        """ IEM_MC_LOCAL_CONST """
     1958        oSelf.checkStmtParamCount(sName, asParams, 3);
     1959        return McStmtVar(sName, asParams, asParams[0], asParams[1], sConstValue = asParams[2]);
    18411960
    18421961    @staticmethod
     
    19582077        return sStr[off : off + len(sSubStr)] == sSubStr;
    19592078
    1960     def decodeCode(self, sRawCode, off = 0, offStop = -1, iLevel = 0):
     2079    koReCppCtrlStmts   = re.compile(r'\b(if\s*[(]|else\b|while\s*[(]|for\s*[(]|do\b)');
     2080    koReIemDecoderVars = re.compile(  r'iem\.s\.(fPrefixes|uRexReg|uRexB|uRexIndex|iEffSeg|offModRm|cbOpcode|offOpcode'
     2081                                    + r'|enmEffOpSize|enmDefOpSize|enmDefAddrMode|enmEffAddrMode|idxPrefix'
     2082                                    + r'|uVex3rdReg|uVexLength|fEvxStuff|uFpuOpcode|abOpcode'
     2083                                    + r')');
     2084
     2085    def decodeCode(self, sRawCode, off = 0, offStop = -1, iLevel = 0): # pylint: disable=too-many-statements,too-many-branches
    19612086        """
    19622087        Decodes sRawCode[off : offStop].
     
    20332158                    self.raiseDecodeError(sRawCode, off, 'Unknown MC statement: %s' % (sName,));
    20342159                oStmt = fnParser(self, sName, asParams);
    2035                 aoStmts.append(oStmt);
     2160                if not isinstance(oStmt, (list, tuple)):
     2161                    aoStmts.append(oStmt);
     2162                else:
     2163                    aoStmts.extend(oStmt);
    20362164
    20372165                #
     
    21072235            #
    21082236            else:
    2109                 offEnd = sRawCode.find(';', off);
    2110                 if offEnd < 0:
    2111                     self.raiseDecodeError(sRawCode, off, 'C++ statement without a ";"');
    2112                 aoStmts.append(McCppGeneric(sRawCode[off : offEnd + 1]));
    2113                 off = offEnd + 1;
     2237                # Find the end of the statement.  if and else requires special handling.
     2238                sCondExpr = None;
     2239                oMatch = self.koReCppCtrlStmts.match(sRawCode, off);
     2240                if oMatch:
     2241                    if oMatch.group(1)[-1] == '(':
     2242                        (sCondExpr, offEnd) = self.extractParam(sRawCode, oMatch.end());
     2243                    else:
     2244                        offEnd = oMatch.end();
     2245                    if not oMatch.group(1).startswith('if') and oMatch.group(1) != 'else':
     2246                        self.raiseDecodeError(sRawCode, off, 'Only if/else control statements allowed: %s' % (oMatch.group(1),));
     2247                elif ch == '#':
     2248                    offEnd = sRawCode.find('\n', off, offStop);
     2249                    if offEnd < 0:
     2250                        offEnd = offStop;
     2251                    offEnd -= 1;
     2252                    while offEnd > off and sRawCode[offEnd - 1].isspace():
     2253                        offEnd -= 1;
     2254                else:
     2255                    offEnd = sRawCode.find(';', off);
     2256                    if offEnd < 0:
     2257                        self.raiseDecodeError(sRawCode, off, 'C++ statement without a ";"');
     2258
     2259                # Check this and the following statement whether it might have
     2260                # something to do with decoding.  This is a statement filter
     2261                # criteria when generating the threaded functions blocks.
     2262                offNextEnd = sRawCode.find(';', offEnd + 1);
     2263                fDecode    = (   sRawCode.find('IEM_OPCODE_', off, max(offEnd, offNextEnd)) >= 0
     2264                              or sRawCode.find('IEMOP_HLP_DONE_', off, max(offEnd, offNextEnd)) >= 0);
     2265
     2266                if not oMatch:
     2267                    if ch != '#':
     2268                        aoStmts.append(McCppGeneric(sRawCode[off : offEnd + 1], fDecode));
     2269                    else:
     2270                        aoStmts.append(McCppPreProc(sRawCode[off : offEnd + 1]));
     2271                    off = offEnd + 1;
     2272                elif oMatch.group(1).startswith('if'):
     2273                    #
     2274                    # if () xxx [else yyy] statement.
     2275                    #
     2276                    oStmt = McCppCond(sCondExpr, fDecode);
     2277                    aoStmts.append(oStmt);
     2278                    off = offEnd + 1;
     2279
     2280                    # Following the if () we can either have a {} containing zero or more statements
     2281                    # or we have a single statement.
     2282                    offBlock1 = self.skipSpacesAt(sRawCode, offEnd + 1, offStop);
     2283                    if sRawCode[offBlock1] == '{':
     2284                        offBlock1End = self.findClosingBraces(sRawCode, offBlock1, offStop);
     2285                        if offBlock1End < 0:
     2286                            self.raiseDecodeError(sRawCode, offBlock1, 'No matching "}" closing if block');
     2287                        offBlock1 += 1;
     2288                    else:
     2289                        offBlock1End = sRawCode.find(';', offBlock1, offStop);
     2290                        if offBlock1End < 0:
     2291                            self.raiseDecodeError(sRawCode, off, 'Expected ";" terminating one-line if block"');
     2292
     2293                    oStmt.aoIfBranch = self.decodeCode(sRawCode, offBlock1, offBlock1End, iLevel + 1);
     2294
     2295                    # The else is optional and can likewise be followed by {} or a single statement.
     2296                    off = self.skipSpacesAt(sRawCode, offBlock1End + 1, offStop);
     2297                    if self.isSubstrAt(sRawCode, off, 'else') and sRawCode[off + len('else')].isspace():
     2298                        offBlock2 = self.skipSpacesAt(sRawCode, off + len('else'), offStop);
     2299                        if sRawCode[offBlock2] == '{':
     2300                            offBlock2End = self.findClosingBraces(sRawCode, offBlock2, offStop);
     2301                            if offBlock2End < 0:
     2302                                self.raiseDecodeError(sRawCode, offBlock2, 'No matching "}" closing else block');
     2303                            offBlock2 += 1;
     2304                        else:
     2305                            offBlock2End = sRawCode.find(';', offBlock2, offStop);
     2306                            if offBlock2End < 0:
     2307                                self.raiseDecodeError(sRawCode, off, 'Expected ";" terminating one-line else block"');
     2308
     2309                        oStmt.aoElseBranch = self.decodeCode(sRawCode, offBlock2, offBlock2End, iLevel + 1);
     2310                        off = offBlock2End + 1;
     2311
     2312                elif oMatch.group(1) == 'else':
     2313                    # Problematic 'else' branch, typically involving #ifdefs.
     2314                    self.raiseDecodeError(sRawCode, off, 'Mixed up else/#ifdef or something confusing us.');
     2315
     2316
    21142317        return aoStmts;
    21152318
     
    21602363    'IEM_MC_AND_LOCAL_U64':                                      McBlock.parseMcGeneric,
    21612364    'IEM_MC_AND_LOCAL_U8':                                       McBlock.parseMcGeneric,
    2162     'IEM_MC_ARG':                                                McBlock.parseMcGeneric,
    2163     'IEM_MC_ARG_CONST':                                          McBlock.parseMcGeneric,
    2164     'IEM_MC_ARG_LOCAL_EFLAGS':                                   McBlock.parseMcGeneric,
    2165     'IEM_MC_ARG_LOCAL_REF':                                      McBlock.parseMcGeneric,
     2365    'IEM_MC_ARG':                                                McBlock.parseMcArg,
     2366    'IEM_MC_ARG_CONST':                                          McBlock.parseMcArgConst,
     2367    'IEM_MC_ARG_LOCAL_EFLAGS':                                   McBlock.parseMcArgLocalEFlags,
     2368    'IEM_MC_ARG_LOCAL_REF':                                      McBlock.parseMcArgLocalRef,
    21662369    'IEM_MC_ASSIGN':                                             McBlock.parseMcGeneric,
    21672370    'IEM_MC_ASSIGN_TO_SMALLER':                                  McBlock.parseMcGeneric,
     
    23352538    'IEM_MC_IMPLICIT_AVX_AIMPL_ARGS':                            McBlock.parseMcGeneric,
    23362539    'IEM_MC_INT_CLEAR_ZMM_256_UP':                               McBlock.parseMcGeneric,
    2337     'IEM_MC_LOCAL':                                              McBlock.parseMcGeneric,
    2338     'IEM_MC_LOCAL_CONST':                                        McBlock.parseMcGeneric,
     2540    'IEM_MC_LOCAL':                                              McBlock.parseMcLocal,
     2541    'IEM_MC_LOCAL_CONST':                                        McBlock.parseMcLocalConst,
    23392542    'IEM_MC_MAYBE_RAISE_AESNI_RELATED_XCPT':                     McBlock.parseMcGeneric,
    23402543    'IEM_MC_MAYBE_RAISE_AVX_RELATED_XCPT':                       McBlock.parseMcGeneric,
     
    42184421                                          sForm, sUpper, sLower, sDisHints, sIemHints, asOperands);
    42194422
    4220     def workerIemMcBegin(self, sCode, offBeginStatementInLine):
     4423    def workerIemMcBegin(self, sCode, offBeginStatementInCodeStr, offBeginStatementInLine):
    42214424        """
    42224425        Process a IEM_MC_BEGIN macro invocation.
     
    42244427        if self.fDebugMc:
    42254428            self.debug('IEM_MC_BEGIN on %s off %s' % (self.iLine, offBeginStatementInLine,));
     4429            #self.debug('%s<eos>' % (sCode,));
    42264430
    42274431        # Check preconditions.
     
    42314435            self.raiseError('IEM_MC_BEGIN before IEM_MC_END.  Previous IEM_MC_BEGIN at line %u' % (self.oCurMcBlock.iBeginLine,));
    42324436
     4437        # Figure out the indent level the block starts at, adjusting for expanded multiline macros.
     4438        cchIndent = offBeginStatementInCodeStr;
     4439        offPrevNewline = sCode.rfind('\n', 0, offBeginStatementInCodeStr);
     4440        if offPrevNewline >= 0:
     4441            cchIndent -= offPrevNewline + 1;
     4442        #self.debug('cchIndent=%s offPrevNewline=%s sFunc=%s' % (cchIndent, offPrevNewline, self.sCurFunction));
     4443
    42334444        # Start a new block.
    4234         self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine, self.sCurFunction, self.iMcBlockInFunc);
     4445        self.oCurMcBlock = McBlock(self.sSrcFile, self.iLine, offBeginStatementInLine,
     4446                                   self.sCurFunction, self.iMcBlockInFunc, cchIndent);
    42354447        g_aoMcBlocks.append(self.oCurMcBlock);
    42364448        self.cTotalMcBlocks += 1;
     
    42844496        Checks code for relevant macro invocation.
    42854497        """
     4498
    42864499        #
    42874500        # Scan macro invocations.
     
    43394552                                                 'Missing IEMOPHINT_VEX_L_ZERO! (%s on line %d)' % (sMacro, self.iLine,));
    43404553                            oInstr.dHints['vex_l_zero'] = True;
    4341                 return True;
    43424554
    43434555            #
     
    44164628                        self.workerIemMcEnd(offLine + oMatch.start());
    44174629                    else:
    4418                         self.workerIemMcBegin(sCode, offLine + oMatch.start());
     4630                        self.workerIemMcBegin(sCode, oMatch.start(), offLine + oMatch.start());
    44194631                return True;
    44204632
     
    44894701        if self.fDebugPreProc:
    44904702            self.debug('#define %s on line %u' % (sName, self.iLine,));
    4491         self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody, iLineStart);
     4703        self.dMacros[sName] = SimpleParser.Macro(sName, asArgs, sBody.strip(), iLineStart);
    44924704        return self.workerPreProcessRecreateMacroRegex();
    44934705
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h

    r98880 r98904  
    97689768
    97699769    IEM_MC_BEGIN(0, 0);
    9770 #ifndef RT_ARCH_ARM64
     9770#ifdef RT_ARCH_ARM64
     9771    IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence);
     9772#else
    97719773    if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
    9772 #endif
    97739774        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_lfence);
    9774 #ifndef RT_ARCH_ARM64
    97759775    else
    97769776        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     
    97919791
    97929792    IEM_MC_BEGIN(0, 0);
    9793 #ifndef RT_ARCH_ARM64
     9793#ifdef RT_ARCH_ARM64
     9794    IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence);
     9795#else
    97949796    if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
    9795 #endif
    97969797        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_mfence);
    9797 #ifndef RT_ARCH_ARM64
    97989798    else
    97999799        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     
    98149814
    98159815    IEM_MC_BEGIN(0, 0);
    9816 #ifndef RT_ARCH_ARM64
     9816#ifdef RT_ARCH_ARM64
     9817    IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence);
     9818#else
    98179819    if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fSse2)
    9818 #endif
    98199820        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_sfence);
    9820 #ifndef RT_ARCH_ARM64
    98219821    else
    98229822        IEM_MC_CALL_VOID_AIMPL_0(iemAImpl_alt_mem_fence);
     
    1201912019    if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b)
    1202012020    {
    12021 #if 0
    12022         RT_NOREF(bRm);
    12023         IEMOP_BITCH_ABOUT_STUB();
    12024         return VERR_IEM_INSTR_NOT_IMPLEMENTED;
    12025 #else
    1202612021        IEM_MC_BEGIN(4, 3);
    1202712022        IEM_MC_ARG(PRTUINT128U, pu128MemDst,     0);
     
    1204712042
    1204812043        IEM_MC_FETCH_EFLAGS(EFlags);
    12049 # if defined(RT_ARCH_AMD64) || defined(RT_ARCH_ARM64)
    12050 #  if defined(RT_ARCH_AMD64)
     12044
     12045#ifdef RT_ARCH_AMD64 /* some code duplication here because IEMAllInstructionsPython.py cannot parse if/else/#if spaghetti. */
    1205112046        if (IEM_GET_HOST_CPU_FEATURES(pVCpu)->fMovCmpXchg16b)
    12052 #  endif
    1205312047        {
    1205412048            if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
     
    1205712051                IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_locked, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
    1205812052        }
    12059 #  if defined(RT_ARCH_AMD64)
    1206012053        else
    12061 #  endif
    12062 # endif
    12063 # if !defined(RT_ARCH_ARM64) /** @todo may need this for unaligned accesses... */
    12064         {
    12065             /* Note! The fallback for 32-bit systems and systems without CX16 is multiple
    12066                      accesses and not all all atomic, which works fine on in UNI CPU guest
    12067                      configuration (ignoring DMA).  If guest SMP is active we have no choice
    12068                      but to use a rendezvous callback here.  Sigh. */
     12054        {   /* (see comments in #else case below) */
    1206912055            if (pVCpu->CTX_SUFF(pVM)->cCpus == 1)
    1207012056                IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_fallback, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
    1207112057            else
    12072             {
    1207312058                IEM_MC_CALL_CIMPL_4(iemCImpl_cmpxchg16b_fallback_rendezvous, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
    12074                 /* Does not get here, tail code is duplicated in iemCImpl_cmpxchg16b_fallback_rendezvous. */
    12075             }
    1207612059        }
    12077 # endif
     12060
     12061#elif defined(RT_ARCH_ARM64)
     12062        /** @todo may require fallback for unaligned accesses... */
     12063        if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_LOCK))
     12064            IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
     12065        else
     12066            IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_locked, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
     12067
     12068#else
     12069        /* Note! The fallback for 32-bit systems and systems without CX16 is multiple
     12070                 accesses and not all all atomic, which works fine on in UNI CPU guest
     12071                 configuration (ignoring DMA).  If guest SMP is active we have no choice
     12072                 but to use a rendezvous callback here.  Sigh. */
     12073        if (pVCpu->CTX_SUFF(pVM)->cCpus == 1)
     12074            IEM_MC_CALL_VOID_AIMPL_4(iemAImpl_cmpxchg16b_fallback, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
     12075        else
     12076        {
     12077            IEM_MC_CALL_CIMPL_4(iemCImpl_cmpxchg16b_fallback_rendezvous, pu128MemDst, pu128RaxRdx, pu128RbxRcx, pEFlags);
     12078            /* Does not get here, tail code is duplicated in iemCImpl_cmpxchg16b_fallback_rendezvous. */
     12079        }
     12080#endif
    1207812081
    1207912082        IEM_MC_MEM_COMMIT_AND_UNMAP(pu128MemDst, IEM_ACCESS_DATA_RW);
     
    1208612089
    1208712090        IEM_MC_END();
    12088 #endif
    1208912091    }
    1209012092    Log(("cmpxchg16b -> #UD\n"));
  • trunk/src/VBox/VMM/VMMAll/IEMAllThreadedPython.py

    r98881 r98904  
    4848
    4949
    50 class LocalVar(object):
    51     """
    52     A IEM_MC_LOCAL* variable.
    53     """
    54 
    55     def __init__(self, sName, sType, sConstValue = None):
    56         self.sName       = sName;
    57         self.sType       = sType;
    58         self.sConstValue = sConstValue;     ##< None if not const, otherwise the const value.
    59 
    60 class CallArg(LocalVar):
    61     """
    62     A IEM_MC_ARG* variable.
    63     """
    64 
    65     def __init__(self, sName, sType, iArg, sConstValue = None, oRefLocal = None):
    66         LocalVar.__init__(sName, sType, sConstValue);
    67         self.iArg      = iArg;
    68         self.oRefLocal = oRefLocal;
    69 
    70 
    7150class ThreadedFunction(object):
    7251    """
     
    7655    def __init__(self, oMcBlock):
    7756        self.oMcBlock               = oMcBlock  # type: IEMAllInstructionsPython.McBlock
    78         ### Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*).
    79         #self.dVariables = {}           # type: dict(str,LocalVar)
     57        ## Dictionary of local variables (IEM_MC_LOCAL[_CONST]) and call arguments (IEM_MC_ARG*).
     58        self.dVariables = {}           # type: dict(str,McStmtVar)
    8059        ###
    8160        #self.aoParams    = []          # type:
     
    9473        return 'kIemThreadedFunc_%s_%s' % ( sName, self.oMcBlock.iInFunction, );
    9574
     75    def analyzeFindVariablesAndCallArgs(self, aoStmts):
     76        """ Scans the statements for MC variables and call arguments. """
     77        for oStmt in aoStmts:
     78            if isinstance(oStmt, iai.McStmtVar):
     79                if oStmt.sVarName in self.dVariables:
     80                    raise Exception('Variable %s is defined more than once!' % (oStmt.sVarName,));
     81                self.dVariables[oStmt.sVarName] = oStmt.sVarName;
     82
     83            # There shouldn't be any variables or arguments declared inside if/
     84            # else blocks, but scan them too to be on the safe side.
     85            if isinstance(oStmt, iai.McStmtCond):
     86                cBefore = len(self.dVariables);
     87                self.analyzeFindVariablesAndCallArgs(oStmt.aoIfBranch);
     88                self.analyzeFindVariablesAndCallArgs(oStmt.aoElseBranch);
     89                if len(self.dVariables) != cBefore:
     90                    raise Exception('Variables/arguments defined in conditional branches!');
     91        return True;
     92
    9693    def analyze(self):
    9794        """
     
    10097        """
    10198
    102         #
    103         # First we decode it,
    104         #
     99        # Decode the block into a list/tree of McStmt objects.
    105100        aoStmts = self.oMcBlock.decode();
    106101
     102        # Scan the statements for local variables and call arguments (self.dVariables).
     103        self.analyzeFindVariablesAndCallArgs(aoStmts);
     104
     105
    107106        return True;
    108107
     
    113112        """
    114113        assert len(self.oMcBlock.asLines) > 2, "asLines=%s" % (self.oMcBlock.asLines,);
    115         return ''.join(self.oMcBlock.asLines);
     114        cchIndent = (self.oMcBlock.cchIndent + 3) // 4 * 4;
     115        return iai.McStmt.renderCodeForList(self.oMcBlock.aoStmts, cchIndent = cchIndent).replace('\n', ' /* gen */\n', 1);
    116116
    117117
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