VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py@ 101908

Last change on this file since 101908 was 101849, checked in by vboxsync, 15 months ago

VMM/IEM: Enabled native translation of IEM_MC_CALL_CIMPL_2. Fixed some related bugs. bugref:10371

  • Property svn:eol-style set to LF
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 16.0 KB
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# $Id: IEMAllN8vePython.py 101849 2023-11-06 09:48:15Z vboxsync $
4# pylint: disable=invalid-name
5
6"""
7Native recompiler side-kick for IEMAllThrdPython.py.
8
9Analyzes the each threaded function variant to see if we can we're able to
10recompile it, then provides modifies MC block code for doing so.
11"""
12
13from __future__ import print_function;
14
15__copyright__ = \
16"""
17Copyright (C) 2023 Oracle and/or its affiliates.
18
19This file is part of VirtualBox base platform packages, as
20available from https://www.virtualbox.org.
21
22This program is free software; you can redistribute it and/or
23modify it under the terms of the GNU General Public License
24as published by the Free Software Foundation, in version 3 of the
25License.
26
27This program is distributed in the hope that it will be useful, but
28WITHOUT ANY WARRANTY; without even the implied warranty of
29MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30General Public License for more details.
31
32You should have received a copy of the GNU General Public License
33along with this program; if not, see <https://www.gnu.org/licenses>.
34
35SPDX-License-Identifier: GPL-3.0-only
36"""
37__version__ = "$Revision: 101849 $"
38
39# Standard python imports:
40import copy;
41
42# Out python imports:
43import IEMAllInstPython as iai;
44
45
46## Supplememnts g_dMcStmtParsers.
47g_dMcStmtThreaded = {
48 'IEM_MC_DEFER_TO_CIMPL_0_RET_THREADED': (None, True, True, ),
49 'IEM_MC_DEFER_TO_CIMPL_1_RET_THREADED': (None, True, True, ),
50 'IEM_MC_DEFER_TO_CIMPL_2_RET_THREADED': (None, True, True, ),
51 'IEM_MC_DEFER_TO_CIMPL_3_RET_THREADED': (None, True, True, ),
52
53 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16': (None, True, True, ),
54 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32': (None, True, True, ),
55 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64': (None, True, True, ),
56
57 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16_WITH_FLAGS': (None, True, True, ),
58 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32_WITH_FLAGS': (None, True, True, ),
59 'IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64_WITH_FLAGS': (None, True, True, ),
60
61 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_16_ADDR32': (None, False, False, ),
62 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_16_PRE386': (None, False, False, ),
63 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_16': (None, False, False, ),
64 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_32_ADDR16': (None, False, False, ),
65 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_32_FLAT': (None, False, False, ),
66 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_32': (None, False, False, ),
67 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32': (None, False, False, ),
68 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS': (None, False, False, ),
69 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64': (None, False, False, ),
70
71 'IEM_MC_CALL_CIMPL_1_THREADED': (None, True, True, ),
72 'IEM_MC_CALL_CIMPL_2_THREADED': (None, True, True, ),
73 'IEM_MC_CALL_CIMPL_3_THREADED': (None, True, False, ),
74 'IEM_MC_CALL_CIMPL_4_THREADED': (None, True, False, ),
75 'IEM_MC_CALL_CIMPL_5_THREADED': (None, True, False, ),
76
77 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16': (None, True, True, ),
78 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32': (None, True, True, ),
79 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64': (None, True, True, ),
80 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16': (None, True, True, ),
81 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32': (None, True, True, ),
82 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64': (None, True, True, ),
83 'IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32': (None, True, True, ),
84 'IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64': (None, True, True, ),
85
86 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16_WITH_FLAGS': (None, True, True, ),
87 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32_WITH_FLAGS': (None, True, True, ),
88 'IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64_WITH_FLAGS': (None, True, True, ),
89 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16_WITH_FLAGS': (None, True, True, ),
90 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32_WITH_FLAGS': (None, True, True, ),
91 'IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64_WITH_FLAGS': (None, True, True, ),
92 'IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32_WITH_FLAGS': (None, True, True, ),
93 'IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64_WITH_FLAGS': (None, True, True, ),
94
95 'IEM_MC_STORE_GREG_U8_THREADED': (None, True, False, ),
96 'IEM_MC_STORE_GREG_U8_CONST_THREADED': (None, True, True, ),
97 'IEM_MC_FETCH_GREG_U8_THREADED': (None, False, False, ),
98 'IEM_MC_FETCH_GREG_U8_SX_U16_THREADED': (None, False, False, ),
99 'IEM_MC_FETCH_GREG_U8_SX_U32_THREADED': (None, False, False, ),
100 'IEM_MC_FETCH_GREG_U8_SX_U64_THREADED': (None, False, False, ),
101 'IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED': (None, False, False, ),
102 'IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED': (None, False, False, ),
103 'IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED': (None, False, False, ),
104 'IEM_MC_REF_GREG_U8_THREADED': (None, True, False, ),
105
106 # Flat Mem:
107 'IEM_MC_FETCH_MEM16_FLAT_U8': (None, True, False, ),
108 'IEM_MC_FETCH_MEM32_FLAT_U8': (None, True, False, ),
109 'IEM_MC_FETCH_MEM_FLAT_D80': (None, True, False, ),
110 'IEM_MC_FETCH_MEM_FLAT_I16': (None, True, False, ),
111 'IEM_MC_FETCH_MEM_FLAT_I32': (None, True, False, ),
112 'IEM_MC_FETCH_MEM_FLAT_I64': (None, True, False, ),
113 'IEM_MC_FETCH_MEM_FLAT_R32': (None, True, False, ),
114 'IEM_MC_FETCH_MEM_FLAT_R64': (None, True, False, ),
115 'IEM_MC_FETCH_MEM_FLAT_R80': (None, True, False, ),
116 'IEM_MC_FETCH_MEM_FLAT_U128_ALIGN_SSE': (None, True, False, ),
117 'IEM_MC_FETCH_MEM_FLAT_U128_NO_AC': (None, True, False, ),
118 'IEM_MC_FETCH_MEM_FLAT_U128': (None, True, False, ),
119 'IEM_MC_FETCH_MEM_FLAT_U16_DISP': (None, True, False, ),
120 'IEM_MC_FETCH_MEM_FLAT_U16_SX_U32': (None, True, False, ),
121 'IEM_MC_FETCH_MEM_FLAT_U16_SX_U64': (None, True, False, ),
122 'IEM_MC_FETCH_MEM_FLAT_U16': (None, True, False, ),
123 'IEM_MC_FETCH_MEM_FLAT_U16_ZX_U32': (None, True, False, ),
124 'IEM_MC_FETCH_MEM_FLAT_U16_ZX_U64': (None, True, False, ),
125 'IEM_MC_FETCH_MEM_FLAT_U256_ALIGN_AVX': (None, True, False, ),
126 'IEM_MC_FETCH_MEM_FLAT_U256_NO_AC': (None, True, False, ),
127 'IEM_MC_FETCH_MEM_FLAT_U256': (None, True, False, ),
128 'IEM_MC_FETCH_MEM_FLAT_U32_DISP': (None, True, False, ),
129 'IEM_MC_FETCH_MEM_FLAT_U32_SX_U64': (None, True, False, ),
130 'IEM_MC_FETCH_MEM_FLAT_U32': (None, True, False, ),
131 'IEM_MC_FETCH_MEM_FLAT_U32_ZX_U64': (None, True, False, ),
132 'IEM_MC_FETCH_MEM_FLAT_U64': (None, True, False, ),
133 'IEM_MC_FETCH_MEM_FLAT_U8_SX_U16': (None, True, False, ),
134 'IEM_MC_FETCH_MEM_FLAT_U8_SX_U32': (None, True, False, ),
135 'IEM_MC_FETCH_MEM_FLAT_U8_SX_U64': (None, True, False, ),
136 'IEM_MC_FETCH_MEM_FLAT_U8': (None, True, False, ),
137 'IEM_MC_FETCH_MEM_FLAT_U8_ZX_U16': (None, True, False, ),
138 'IEM_MC_FETCH_MEM_FLAT_U8_ZX_U32': (None, True, False, ),
139 'IEM_MC_FETCH_MEM_FLAT_U8_ZX_U64': (None, True, False, ),
140 'IEM_MC_FETCH_MEM_FLAT_XMM_ALIGN_SSE': (None, True, False, ),
141 'IEM_MC_FETCH_MEM_FLAT_XMM_U32': (None, True, False, ),
142 'IEM_MC_FETCH_MEM_FLAT_XMM_U64': (None, True, False, ),
143 'IEM_MC_MEM_FLAT_MAP_EX': (None, True, False, ),
144 'IEM_MC_MEM_FLAT_MAP': (None, True, False, ),
145 'IEM_MC_MEM_FLAT_MAP_U16_RO': (None, True, False, ),
146 'IEM_MC_MEM_FLAT_MAP_U16_RW': (None, True, False, ),
147 'IEM_MC_MEM_FLAT_MAP_U32_RO': (None, True, False, ),
148 'IEM_MC_MEM_FLAT_MAP_U32_RW': (None, True, False, ),
149 'IEM_MC_MEM_FLAT_MAP_U64_RO': (None, True, False, ),
150 'IEM_MC_MEM_FLAT_MAP_U64_RW': (None, True, False, ),
151 'IEM_MC_MEM_FLAT_MAP_U8_RO': (None, True, False, ),
152 'IEM_MC_MEM_FLAT_MAP_U8_RW': (None, True, False, ),
153 'IEM_MC_STORE_MEM_FLAT_U128_ALIGN_SSE': (None, True, False, ),
154 'IEM_MC_STORE_MEM_FLAT_U128': (None, True, False, ),
155 'IEM_MC_STORE_MEM_FLAT_U16': (None, True, False, ),
156 'IEM_MC_STORE_MEM_FLAT_U256_ALIGN_AVX': (None, True, False, ),
157 'IEM_MC_STORE_MEM_FLAT_U256': (None, True, False, ),
158 'IEM_MC_STORE_MEM_FLAT_U32': (None, True, False, ),
159 'IEM_MC_STORE_MEM_FLAT_U64': (None, True, False, ),
160 'IEM_MC_STORE_MEM_FLAT_U8_CONST': (None, True, False, ),
161 'IEM_MC_STORE_MEM_FLAT_U8': (None, True, False, ),
162
163 # Flat Stack:
164 'IEM_MC_FLAT64_PUSH_U16': (None, True, False, ),
165 'IEM_MC_FLAT64_PUSH_U64': (None, True, False, ),
166 'IEM_MC_FLAT64_POP_U16': (None, True, False, ),
167 'IEM_MC_FLAT64_POP_U64': (None, True, False, ),
168 'IEM_MC_FLAT32_PUSH_U16': (None, True, False, ),
169 'IEM_MC_FLAT32_PUSH_U32': (None, True, False, ),
170 'IEM_MC_FLAT32_POP_U16': (None, True, False, ),
171 'IEM_MC_FLAT32_POP_U32': (None, True, False, ),
172};
173
174class NativeRecompFunctionVariation(object):
175 """
176 Class that deals with transforming a threaded function variation into a
177 native recompiler function.
178
179 This base class doesn't do any transforming and just renders the same
180 code as for the threaded function.
181 """
182
183 def __init__(self, oVariation, sHostArch):
184 self.oVariation = oVariation # type: ThreadedFunctionVariation
185 self.sHostArch = sHostArch;
186
187 def isRecompilable(self):
188 """
189 Predicate that returns whether the variant can be recompiled natively
190 (for the selected host architecture).
191 """
192 return True;
193
194 def renderCode(self, cchIndent):
195 """
196 Returns the native recompiler function body for this threaded variant.
197 """
198 # Take the threaded function statement list and add detected
199 # IEM_CIMPL_F_XXX flags to the IEM_MC_BEGIN statement.
200 aoStmts = list(self.oVariation.aoStmtsForThreadedFunction) # type: list(McStmt)
201 for iStmt, oStmt in enumerate(aoStmts):
202 if oStmt.sName == 'IEM_MC_BEGIN' and self.oVariation.oParent.dsCImplFlags:
203 oNewStmt = copy.deepcopy(oStmt);
204 oNewStmt.asParams[3] = ' | '.join(sorted(self.oVariation.oParent.dsCImplFlags.keys()));
205 aoStmts[iStmt] = oNewStmt;
206
207 return iai.McStmt.renderCodeForList(aoStmts, cchIndent);
208
209 @staticmethod
210 def checkStatements(aoStmts, sHostArch):
211 """
212 Checks that all the given statements are supported by the native recompiler.
213 Returns dictionary with the unsupported statments.
214 """
215 dRet = {};
216 _ = sHostArch;
217 for oStmt in aoStmts: # type: McStmt
218 if not oStmt.isCppStmt():
219 aInfo = iai.g_dMcStmtParsers.get(oStmt.sName);
220 if not aInfo:
221 aInfo = g_dMcStmtThreaded.get(oStmt.sName);
222 if not aInfo:
223 raise Exception('Unknown statement: %s' % (oStmt.sName, ));
224 if aInfo[2] is False:
225 dRet[oStmt.sName] = 1;
226 elif aInfo[2] is not True:
227 if isinstance(aInfo[2], str):
228 if aInfo[2] != sHostArch:
229 dRet[oStmt.sName] = 1;
230 elif sHostArch not in aInfo[2]:
231 dRet[oStmt.sName] = 1;
232 #elif not self.fDecode:
233
234 if isinstance(oStmt, iai.McStmtCond):
235 dRet.update(NativeRecompFunctionVariation.checkStatements(oStmt.aoIfBranch, sHostArch));
236 dRet.update(NativeRecompFunctionVariation.checkStatements(oStmt.aoElseBranch, sHostArch));
237
238 return dRet;
239
240
241## Statistics: Number of MC blocks (value) depending on each unsupported statement (key).
242g_dUnsupportedMcStmtStats = {}
243
244## Statistics: List of variations (value) that is only missing this one statement (key).
245g_dUnsupportedMcStmtLastOneStats = {}
246
247## Statistics: List of variations (value) with vars/args that is only missing this one statement (key).
248g_dUnsupportedMcStmtLastOneVarStats = {}
249
250
251def analyzeVariantForNativeRecomp(oVariation,
252 sHostArch): # type: (ThreadedFunctionVariation, str) -> NativeRecompFunctionVariation
253 """
254 This function analyzes the threaded function variant and returns an
255 NativeRecompFunctionVariation instance for it, unless it's not
256 possible to recompile at present.
257
258 Returns NativeRecompFunctionVariation or the number of unsupported MCs.
259 """
260
261 #
262 # Analyze the statements.
263 #
264 aoStmts = oVariation.aoStmtsForThreadedFunction # type: list(McStmt)
265 dUnsupportedStmts = NativeRecompFunctionVariation.checkStatements(aoStmts, sHostArch);
266 if not dUnsupportedStmts:
267 return NativeRecompFunctionVariation(oVariation, sHostArch);
268
269 #
270 # Update the statistics.
271 #
272 for sStmt in dUnsupportedStmts:
273 g_dUnsupportedMcStmtStats[sStmt] = 1 + g_dUnsupportedMcStmtStats.get(sStmt, 0);
274
275 if len(dUnsupportedStmts) == 1:
276 for sStmt in dUnsupportedStmts:
277 if sStmt in g_dUnsupportedMcStmtLastOneStats:
278 g_dUnsupportedMcStmtLastOneStats[sStmt].append(oVariation);
279 else:
280 g_dUnsupportedMcStmtLastOneStats[sStmt] = [oVariation,];
281
282 if ( len(dUnsupportedStmts) in (1,2)
283 and iai.McStmt.findStmtByNames(aoStmts,
284 { 'IEM_MC_LOCAL': 1, 'IEM_MC_LOCAL_CONST': 1, 'IEM_MC_ARG': 1, 'IEM_MC_ARG_CONST': 1,
285 'IEM_MC_ARG_LOCAL_REF': 1, 'IEM_MC_ARG_LOCAL_EFLAGS': 1, })):
286 for sStmt in dUnsupportedStmts:
287 if sStmt in g_dUnsupportedMcStmtLastOneVarStats:
288 g_dUnsupportedMcStmtLastOneVarStats[sStmt].append(oVariation);
289 else:
290 g_dUnsupportedMcStmtLastOneVarStats[sStmt] = [oVariation,];
291
292
293
294 return None;
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette