1 | #!/usr/bin/env python
|
---|
2 | # -*- coding: utf-8 -*-
|
---|
3 | # $Id: bs3-cpu-generated-1-data.py 65926 2017-03-03 11:00:27Z vboxsync $
|
---|
4 |
|
---|
5 | """
|
---|
6 | Generates testcases from @optest specifications in IEM.
|
---|
7 | """
|
---|
8 |
|
---|
9 | from __future__ import print_function;
|
---|
10 |
|
---|
11 | __copyright__ = \
|
---|
12 | """
|
---|
13 | Copyright (C) 2017 Oracle Corporation
|
---|
14 |
|
---|
15 | This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
16 | available from http://www.215389.xyz. This file is free software;
|
---|
17 | you can redistribute it and/or modify it under the terms of the GNU
|
---|
18 | General Public License (GPL) as published by the Free Software
|
---|
19 | Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
20 | VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
21 | hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
22 |
|
---|
23 | The contents of this file may alternatively be used under the terms
|
---|
24 | of the Common Development and Distribution License Version 1.0
|
---|
25 | (CDDL) only, as it comes in the "COPYING.CDDL" file of the
|
---|
26 | VirtualBox OSE distribution, in which case the provisions of the
|
---|
27 | CDDL are applicable instead of those of the GPL.
|
---|
28 |
|
---|
29 | You may elect to license modified versions of this file under the
|
---|
30 | terms and conditions of either the GPL or the CDDL or both.
|
---|
31 | """
|
---|
32 | __version__ = "$Revision: 65926 $"
|
---|
33 |
|
---|
34 | # Standard python imports.
|
---|
35 | import os;
|
---|
36 | import re;
|
---|
37 | import sys;
|
---|
38 | import time;
|
---|
39 |
|
---|
40 | # Only the main script needs to modify the path.
|
---|
41 | g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)));
|
---|
42 | g_ksVmmAllDir = os.path.join(os.path.dirname(g_ksValidationKitDir), 'VMM', 'VMMAll')
|
---|
43 | sys.path.extend([g_ksValidationKitDir, g_ksVmmAllDir]);
|
---|
44 |
|
---|
45 | from common import utils;
|
---|
46 | import IEMAllInstructionsPython as iai;
|
---|
47 |
|
---|
48 | # Python 3 hacks:
|
---|
49 | if sys.version_info[0] >= 3:
|
---|
50 | long = int; # pylint: disable=redefined-builtin,invalid-name
|
---|
51 |
|
---|
52 |
|
---|
53 | class Bs3Cg1TestEncoder(object):
|
---|
54 | """
|
---|
55 | Does the encoding of a single test.
|
---|
56 | """
|
---|
57 |
|
---|
58 | def __init__(self, fLast):
|
---|
59 | self.fLast = fLast;
|
---|
60 | # Each list member (in all lists) are C expression of a byte.
|
---|
61 | self.asHdr = [];
|
---|
62 | self.asSelectors = [];
|
---|
63 | self.asInputs = [];
|
---|
64 | self.asOutputs = [];
|
---|
65 |
|
---|
66 | @staticmethod
|
---|
67 | def _compileSelectors(aoSelectors): # (list(iai.TestSelector)) -> list(str)
|
---|
68 | """
|
---|
69 | Compiles a list of iai.TestSelector predicate checks.
|
---|
70 | Returns C byte expression strings.
|
---|
71 | """
|
---|
72 | asRet = [];
|
---|
73 | for oSelector in aoSelectors:
|
---|
74 | sConstant = oSelector.kdVariables[oSelector.sVariable][oSelector.sValue];
|
---|
75 | sConstant = sConstant.upper().replace('.', '_');
|
---|
76 | if oSelector.sValue.sOp == '==':
|
---|
77 | sByte = '(BS3CG1PRED_%s << BS3CG1SEL_OP_PRED_SHIFT) | BS3CG1SEL_OP_IS_TRUE' % (sConstant,);
|
---|
78 | elif oSelector.sValue.sOp == '!=':
|
---|
79 | sByte = '(BS3CG1PRED_%s << BS3CG1SEL_OP_PRED_SHIFT) | BS3CG1SEL_OP_IS_FALSE' % (sConstant,);
|
---|
80 | else:
|
---|
81 | raise Exception('Unknown selector operator: %s' % (oSelector.sOp,));
|
---|
82 | asRet.append(sByte);
|
---|
83 | return asRet;
|
---|
84 |
|
---|
85 | kdSmallFields = {
|
---|
86 | 'op1': 'BS3CG1_CTXOP_OP1',
|
---|
87 | 'op2': 'BS3CG1_CTXOP_OP2',
|
---|
88 | 'efl': 'BS3CG1_CTXOP_EFL',
|
---|
89 | };
|
---|
90 | kdOperators = {
|
---|
91 | '=': 'BS3CG1_CTXOP_ASSIGN',
|
---|
92 | '|=': 'BS3CG1_CTXOP_OR',
|
---|
93 | '&=': 'BS3CG1_CTXOP_AND',
|
---|
94 | '&~=': 'BS3CG1_CTXOP_AND_INV',
|
---|
95 | };
|
---|
96 | kdSmallSizes = {
|
---|
97 | 1: 'BS3CG1_CTXOP_1_BYTE',
|
---|
98 | 2: 'BS3CG1_CTXOP_2_BYTES',
|
---|
99 | 4: 'BS3CG1_CTXOP_4_BYTES',
|
---|
100 | 8: 'BS3CG1_CTXOP_8_BYTES',
|
---|
101 | 16: 'BS3CG1_CTXOP_16_BYTES',
|
---|
102 | 32: 'BS3CG1_CTXOP_32_BYTES',
|
---|
103 | 12: 'BS3CG1_CTXOP_12_BYTES',
|
---|
104 | };
|
---|
105 |
|
---|
106 | @staticmethod
|
---|
107 | def _compileContextModifers(aoOperations): # (list(iai.TestInOut))
|
---|
108 | """
|
---|
109 | Compile a list of iai.TestInOut context modifiers.
|
---|
110 | """
|
---|
111 | asRet = [];
|
---|
112 | for oOperation in aoOperations:
|
---|
113 | oType = iai.TestInOut.kdTypes[oOperation.sType];
|
---|
114 | aaoValues = oType.get(oOperation.sValue);
|
---|
115 | assert len(aaoValues) == 1 or len(aaoValues) == 2;
|
---|
116 |
|
---|
117 | sOp = oOperation.sOp;
|
---|
118 | if sOp == '&|=':
|
---|
119 | sOp = '|=' if len(aaoValues) == 1 else '&~=';
|
---|
120 |
|
---|
121 | for fSignExtend, abValue in aaoValues:
|
---|
122 | cbValue = len(abValue);
|
---|
123 |
|
---|
124 | # The opcode byte.
|
---|
125 | sOpcode = Bs3Cg1TestEncoder.kdOperators[sOp];
|
---|
126 | sOpcode += ' | ';
|
---|
127 | if oOperation.sField in Bs3Cg1TestEncoder.kdSmallFields:
|
---|
128 | sOpcode += Bs3Cg1TestEncoder.kdSmallFields[oOperation.sField];
|
---|
129 | else:
|
---|
130 | sOpcode += 'BS3CG1_CTXOP_DST_ESC';
|
---|
131 | sOpcode += ' | ';
|
---|
132 | if cbValue in Bs3Cg1TestEncoder.kdSmallSizes:
|
---|
133 | sOpcode += Bs3Cg1TestEncoder.kdSmallSizes[cbValue];
|
---|
134 | else:
|
---|
135 | sOpcode += 'BS3CG1_CTXOP_SIZE_ESC';
|
---|
136 | if fSignExtend:
|
---|
137 | sOpcode += '| BS3CG1_CTXOP_SIGN_EXT';
|
---|
138 | asRet.append(sOpcode);
|
---|
139 |
|
---|
140 | # Escaped size byte?
|
---|
141 | if cbValue not in Bs3Cg1TestEncoder.kdSmallSizes:
|
---|
142 | if cbValue >= 256 or cbValue not in [ 1, 2, 4, 6, 8, 12, 16, 32, 64, 128, ]:
|
---|
143 | raise Exception('Invalid value size: %s' % (cbValue,));
|
---|
144 | asRet.append('0x%02x' % (cbValue,));
|
---|
145 |
|
---|
146 | # Escaped field identifier.
|
---|
147 | if oOperation.sField not in Bs3Cg1TestEncoder.kdSmallFields:
|
---|
148 | asRet.append('BS3CG1DST_%s' % (oOperation.sField.upper().replace('.', '_'),));
|
---|
149 |
|
---|
150 | # The value bytes.
|
---|
151 | for b in abValue:
|
---|
152 | asRet.append('0x%02x' % (b,));
|
---|
153 |
|
---|
154 | sOp = '|=';
|
---|
155 |
|
---|
156 | return asRet;
|
---|
157 |
|
---|
158 | def _constructHeader(self):
|
---|
159 | """
|
---|
160 | Returns C byte expression strings for BS3CG1TESTHDR.
|
---|
161 | """
|
---|
162 | cbSelectors = len(self.asSelectors);
|
---|
163 | if cbSelectors >= 256:
|
---|
164 | raise Exception('Too many selectors: %s bytes, max 255 bytes' % (cbSelectors,))
|
---|
165 |
|
---|
166 | cbInputs = len(self.asInputs);
|
---|
167 | if cbInputs >= 4096:
|
---|
168 | raise Exception('Too many input context modifiers: %s bytes, max 4095 bytes' % (cbInputs,))
|
---|
169 |
|
---|
170 | cbOutputs = len(self.asOutputs);
|
---|
171 | if cbOutputs >= 2048:
|
---|
172 | raise Exception('Too many output context modifiers: %s bytes, max 2047 bytes' % (cbOutputs,))
|
---|
173 |
|
---|
174 | return [
|
---|
175 | '%#04x' % (cbSelectors,), # 8-bit
|
---|
176 | '%#05x & 0xff' % (cbInputs,), # first 8 bits of cbInputs
|
---|
177 | '(%#05x >> 8) | ((%#05x & 0xf) << 4)' % (cbInputs, cbOutputs,), # last 4 bits of cbInputs, lower 4 bits of cbOutputs.
|
---|
178 | '(%#05x >> 4) | (%#05x << 7)' % (cbOutputs, self.fLast), # last 7 bits of cbOutputs and 1 bit fLast.
|
---|
179 | ];
|
---|
180 |
|
---|
181 | def encodeTest(self, oTest): # type: (iai.InstructionTest)
|
---|
182 | """
|
---|
183 | Does the encoding.
|
---|
184 | """
|
---|
185 | self.asSelectors = self._compileSelectors(oTest.aoSelectors);
|
---|
186 | self.asInputs = self._compileContextModifers(oTest.aoInputs);
|
---|
187 | self.asOutputs = self._compileContextModifers(oTest.aoOutputs);
|
---|
188 | self.asHdr = self._constructHeader();
|
---|
189 |
|
---|
190 |
|
---|
191 | class Bs3Cg1EncodedTests(object):
|
---|
192 | """
|
---|
193 | Encodes the tests for an instruction.
|
---|
194 | """
|
---|
195 |
|
---|
196 | def __init__(self, oInstr):
|
---|
197 | self.offTests = -1;
|
---|
198 | self.cbTests = 0;
|
---|
199 | self.asLines = [];
|
---|
200 |
|
---|
201 | # Encode the tests.
|
---|
202 | for iTest, oTest in enumerate(oInstr.aoTests):
|
---|
203 | oEncodedTest = Bs3Cg1TestEncoder(iTest + 1 == len(oInstr.aoTests));
|
---|
204 | oEncodedTest.encodeTest(oTest);
|
---|
205 |
|
---|
206 | self.cbTests += len(oEncodedTest.asHdr) + len(oEncodedTest.asSelectors) \
|
---|
207 | + len(oEncodedTest.asInputs) + len(oEncodedTest.asOutputs);
|
---|
208 |
|
---|
209 | self.asLines += self.bytesToLines(' /*hdr:*/ ', oEncodedTest.asHdr);
|
---|
210 | if oEncodedTest.asSelectors:
|
---|
211 | self.asLines += self.bytesToLines(' /*sel:*/ ', oEncodedTest.asSelectors);
|
---|
212 | if oEncodedTest.asInputs:
|
---|
213 | self.asLines += self.bytesToLines(' /* in:*/ ', oEncodedTest.asInputs);
|
---|
214 | if oEncodedTest.asOutputs:
|
---|
215 | self.asLines += self.bytesToLines(' /*out:*/ ', oEncodedTest.asOutputs);
|
---|
216 |
|
---|
217 | @staticmethod
|
---|
218 | def bytesToLines(sPrefix, asBytes):
|
---|
219 | """
|
---|
220 | Formats a series of bytes into one or more lines.
|
---|
221 | A byte ending with a newline indicates that we should start a new line,
|
---|
222 | and prefix it by len(sPrefix) spaces.
|
---|
223 |
|
---|
224 | Returns list of lines.
|
---|
225 | """
|
---|
226 | asRet = [];
|
---|
227 | sLine = sPrefix;
|
---|
228 | for sByte in asBytes:
|
---|
229 | if sByte[-1] == '\n':
|
---|
230 | sLine += sByte[:-1] + ',';
|
---|
231 | asRet.append(sLine);
|
---|
232 | sLine = ' ' * len(sPrefix);
|
---|
233 | else:
|
---|
234 | if len(sLine) + 2 + len(sByte) > 132 and len(sLine) > len(sPrefix):
|
---|
235 | asRet.append(sLine[:-1]);
|
---|
236 | sLine = ' ' * len(sPrefix);
|
---|
237 | sLine += sByte + ', ';
|
---|
238 |
|
---|
239 |
|
---|
240 | if len(sLine) > len(sPrefix):
|
---|
241 | asRet.append(sLine);
|
---|
242 | return asRet;
|
---|
243 |
|
---|
244 |
|
---|
245 | def isEqual(self, oOther):
|
---|
246 | """ Compares two encoded tests. """
|
---|
247 | if self.cbTests != oOther.cbTests:
|
---|
248 | return False;
|
---|
249 | if len(self.asLines) != len(oOther.asLines):
|
---|
250 | return False;
|
---|
251 | for iLine, sLines in enumerate(self.asLines):
|
---|
252 | if sLines != oOther.asLines[iLine]:
|
---|
253 | return False;
|
---|
254 | return True;
|
---|
255 |
|
---|
256 |
|
---|
257 |
|
---|
258 | class Bs3Cg1Instruction(object):
|
---|
259 | """
|
---|
260 | An instruction with tests.
|
---|
261 | """
|
---|
262 |
|
---|
263 | def __init__(self, oMap, oInstr, oTests):
|
---|
264 | self.oMap = oMap; # type: iai.InstructionMap
|
---|
265 | self.oInstr = oInstr; # type: iai.Instruction
|
---|
266 | self.oTests = oTests; # type: Bs3Cg1EncodedTests
|
---|
267 |
|
---|
268 | self.asOpcodes = oMap.asLeadOpcodes + [ '0x%02x' % (oInstr.getOpcodeByte(),) ];
|
---|
269 | self.sEncoding = iai.g_kdEncodings[oInstr.sEncoding][0];
|
---|
270 | for oOp in oInstr.aoOperands:
|
---|
271 | self.sEncoding += '_' + oOp.sType;
|
---|
272 | self.asFlags = [];
|
---|
273 | self.fAdvanceMnemonic = True; ##< Set by the caller.
|
---|
274 |
|
---|
275 | def getOperands(self):
|
---|
276 | """ Returns comma separated string of operand values for g_abBs3Cg1Operands. """
|
---|
277 | return ', '.join(['(uint8_t)BS3CG1OP_%s' % (oOp.sType,) for oOp in self.oInstr.aoOperands]);
|
---|
278 |
|
---|
279 | def getInstructionEntry(self):
|
---|
280 | """ Returns an array of BS3CG1INSTR member initializers. """
|
---|
281 | return [
|
---|
282 | ' /* cbOpcode = */ %s,' % (len(self.asOpcodes),),
|
---|
283 | ' /* cOperands = */ %s,' % (len(self.oInstr.aoOperands),),
|
---|
284 | ' /* cchMnemonic = */ %s,' % (len(self.oInstr.sMnemonic),),
|
---|
285 | ' /* fAdvanceMnemonic = */ %s,' % ('true' if self.fAdvanceMnemonic else 'false',),
|
---|
286 | ' /* offTests = */ %s,' % (self.oTests.offTests,),
|
---|
287 | ' /* enmEncoding = */ (unsigned)%s,' % (self.sEncoding,),
|
---|
288 | ' /* uUnused = */ 0,',
|
---|
289 | ' /* fFlags = */ %s' % (' | '.join(self.asFlags) if self.asFlags else '0'),
|
---|
290 | ];
|
---|
291 |
|
---|
292 |
|
---|
293 | class Bs3CpuGenerated1Generator(object):
|
---|
294 | """
|
---|
295 | The generator code for bs3-cpu-generated-1.
|
---|
296 | """
|
---|
297 |
|
---|
298 | def __init__(self):
|
---|
299 | self.aoInstructions = []; # type: Bs3Cg1Instruction
|
---|
300 | self.aoTests = []; # type: Bs3Cg1EncodedTests
|
---|
301 | self.cbTests = 0;
|
---|
302 |
|
---|
303 | def addTests(self, oTests):
|
---|
304 | """
|
---|
305 | Adds oTests to self.aoTests, setting the oTests.offTests member.
|
---|
306 | Checks for and eliminates duplicates.
|
---|
307 | Returns the tests to use.
|
---|
308 | """
|
---|
309 | # Check for duplicates.
|
---|
310 | for oExisting in self.aoTests:
|
---|
311 | if oTests.isEqual(oExisting):
|
---|
312 | return oExisting;
|
---|
313 |
|
---|
314 | # New test, so add it.
|
---|
315 | oTests.offTests = self.cbTests;
|
---|
316 | self.aoTests.append(oTests);
|
---|
317 | self.cbTests += oTests.cbTests;
|
---|
318 |
|
---|
319 | return oTests;
|
---|
320 |
|
---|
321 | def processInstruction(self):
|
---|
322 | """
|
---|
323 | Processes the IEM specified instructions.
|
---|
324 | Returns success indicator.
|
---|
325 | """
|
---|
326 |
|
---|
327 | #
|
---|
328 | # Group instructions by mnemonic to reduce the number of sub-tests.
|
---|
329 | #
|
---|
330 | for oInstr in sorted(iai.g_aoAllInstructions,
|
---|
331 | key = lambda(oInstr): oInstr.sMnemonic + ''.join([oOp.sType for oOp in oInstr.aoOperands])
|
---|
332 | + (oInstr.sOpcode if oInstr.sOpcode else 'zz')):
|
---|
333 | if len(oInstr.aoTests) > 0:
|
---|
334 | oTests = Bs3Cg1EncodedTests(oInstr);
|
---|
335 | oTests = self.addTests(oTests);
|
---|
336 |
|
---|
337 | for oMap in oInstr.aoMaps:
|
---|
338 | self.aoInstructions.append(Bs3Cg1Instruction(oMap, oInstr, oTests));
|
---|
339 |
|
---|
340 | # Set fAdvanceMnemonic.
|
---|
341 | for iInstr, oInstr in enumerate(self.aoInstructions):
|
---|
342 | oInstr.fAdvanceMnemonic = iInstr + 1 >= len(self.aoInstructions) \
|
---|
343 | or oInstr.oInstr.sMnemonic != self.aoInstructions[iInstr + 1].oInstr.sMnemonic;
|
---|
344 |
|
---|
345 | return True;
|
---|
346 |
|
---|
347 | def generateCode(self, oOut):
|
---|
348 | """
|
---|
349 | Generates the C code.
|
---|
350 | Returns success indicator.
|
---|
351 | """
|
---|
352 |
|
---|
353 | # First, a file header.
|
---|
354 | asLines = [
|
---|
355 | '/*',
|
---|
356 | ' * Autogenerated by $Id: bs3-cpu-generated-1-data.py 65926 2017-03-03 11:00:27Z vboxsync $ ',
|
---|
357 | ' * Do not edit!',
|
---|
358 | ' */',
|
---|
359 | '',
|
---|
360 | '/*',
|
---|
361 | ' * Copyright (C) 2017 Oracle Corporation',
|
---|
362 | ' *',
|
---|
363 | ' * This file is part of VirtualBox Open Source Edition (OSE), as',
|
---|
364 | ' * available from http://www.215389.xyz. This file is free software;',
|
---|
365 | ' * you can redistribute it and/or modify it under the terms of the GNU',
|
---|
366 | ' * General Public License (GPL) as published by the Free Software',
|
---|
367 | ' * Foundation, in version 2 as it comes in the "COPYING" file of the',
|
---|
368 | ' * VirtualBox OSE distribution. VirtualBox OSE is distributed in the',
|
---|
369 | ' * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.',
|
---|
370 | ' * ',
|
---|
371 | ' * The contents of this file may alternatively be used under the terms',
|
---|
372 | ' * of the Common Development and Distribution License Version 1.0',
|
---|
373 | ' * (CDDL) only, as it comes in the "COPYING.CDDL" file of the',
|
---|
374 | ' * VirtualBox OSE distribution, in which case the provisions of the',
|
---|
375 | ' * CDDL are applicable instead of those of the GPL.',
|
---|
376 | ' * ',
|
---|
377 | ' * You may elect to license modified versions of this file under the',
|
---|
378 | ' * terms and conditions of either the GPL or the CDDL or both.',
|
---|
379 | ' */',
|
---|
380 | '',
|
---|
381 | '',
|
---|
382 | '#include "bs3-cpu-generated-1.h"',
|
---|
383 | '',
|
---|
384 | '',
|
---|
385 | ];
|
---|
386 |
|
---|
387 | # Generate the g_achBs3Cg1Mnemonics array.
|
---|
388 | asLines += [
|
---|
389 | 'const char BS3_FAR_DATA g_achBs3Cg1Mnemonics[] = ',
|
---|
390 | '{',
|
---|
391 | ];
|
---|
392 | for oInstr in self.aoInstructions:
|
---|
393 | asLines.append(' \"%s\"' % (oInstr.oInstr.sMnemonic,));
|
---|
394 | asLines += [
|
---|
395 | '};',
|
---|
396 | '',
|
---|
397 | '',
|
---|
398 | ];
|
---|
399 |
|
---|
400 | # Generate the g_abBs3Cg1Opcodes array.
|
---|
401 | asLines += [
|
---|
402 | 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Opcodes[] = ',
|
---|
403 | '{',
|
---|
404 | ];
|
---|
405 | for oInstr in self.aoInstructions:
|
---|
406 | asLines.append(' ' + ', '.join(oInstr.asOpcodes) + ',');
|
---|
407 | asLines += [
|
---|
408 | '};',
|
---|
409 | '',
|
---|
410 | '',
|
---|
411 | ];
|
---|
412 |
|
---|
413 | # Generate the g_abBs3Cg1Opcodes array.
|
---|
414 | asLines += [
|
---|
415 | 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Operands[] = ',
|
---|
416 | '{',
|
---|
417 | ];
|
---|
418 | for oInstr in self.aoInstructions:
|
---|
419 | asLines.append(' ' + oInstr.getOperands() + ',');
|
---|
420 | asLines += [
|
---|
421 | '};',
|
---|
422 | '',
|
---|
423 | '',
|
---|
424 | ];
|
---|
425 |
|
---|
426 | # Generate the g_abBs3Cg1Operands array.
|
---|
427 | asLines += [
|
---|
428 | 'const BS3CG1INSTR BS3_FAR_DATA g_aBs3Cg1Instructions[] = ',
|
---|
429 | '{',
|
---|
430 | ];
|
---|
431 | for oInstr in self.aoInstructions:
|
---|
432 | asLines.append(' {');
|
---|
433 | asLines += oInstr.getInstructionEntry();
|
---|
434 | asLines.append(' },');
|
---|
435 | asLines += [
|
---|
436 | '};',
|
---|
437 | 'const uint16_t BS3_FAR_DATA g_cBs3Cg1Instructions = RT_ELEMENTS(g_aBs3Cg1Instructions);',
|
---|
438 | '',
|
---|
439 | '',
|
---|
440 | ];
|
---|
441 |
|
---|
442 | # Generate the g_abBs3Cg1Tests array.
|
---|
443 | asLines += [
|
---|
444 | 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Tests[] = ',
|
---|
445 | '{',
|
---|
446 | ];
|
---|
447 | for oTests in self.aoTests:
|
---|
448 | asLines.append(' /* offTests=%s */' % (oTests.offTests,));
|
---|
449 | asLines += oTests.asLines;
|
---|
450 | asLines += [
|
---|
451 | '};',
|
---|
452 | '',
|
---|
453 | ];
|
---|
454 |
|
---|
455 |
|
---|
456 | #/** The test data that BS3CG1INSTR.
|
---|
457 | # * In order to simplify generating these, we use a byte array. */
|
---|
458 | #extern const uint8_t BS3_FAR_DATA g_abBs3Cg1Tests[];
|
---|
459 |
|
---|
460 |
|
---|
461 | oOut.write('\n'.join(asLines));
|
---|
462 | return True;
|
---|
463 |
|
---|
464 |
|
---|
465 | def usage(self):
|
---|
466 | """ Prints usage. """
|
---|
467 | print('usage: bs3-cpu-generated-1-data.py [output file|-]');
|
---|
468 | return 0;
|
---|
469 |
|
---|
470 | def main(self, asArgs):
|
---|
471 | """
|
---|
472 | C-like main function.
|
---|
473 | Returns exit code.
|
---|
474 | """
|
---|
475 |
|
---|
476 | #
|
---|
477 | # Quick argument parsing.
|
---|
478 | #
|
---|
479 | if len(asArgs) == 1:
|
---|
480 | sOutFile = '-';
|
---|
481 | elif len(asArgs) != 2:
|
---|
482 | print('syntax error! Expected exactly one argument.');
|
---|
483 | return 2;
|
---|
484 | elif asArgs[1] in [ '-h', '-?', '--help' ]:
|
---|
485 | return self.usage();
|
---|
486 | else:
|
---|
487 | sOutFile = asArgs[1];
|
---|
488 |
|
---|
489 | #
|
---|
490 | # Process the instructions specified in the IEM sources.
|
---|
491 | #
|
---|
492 | if self.processInstruction():
|
---|
493 |
|
---|
494 | #
|
---|
495 | # Open the output file and generate the code.
|
---|
496 | #
|
---|
497 | if sOutFile == '-':
|
---|
498 | oOut = sys.stdout;
|
---|
499 | else:
|
---|
500 | try:
|
---|
501 | oOut = open(sOutFile, 'wt');
|
---|
502 | except Exception as oXcpt:
|
---|
503 | print('error! Failed open "%s" for writing: %s' % (sOutFile, oXcpt,));
|
---|
504 | return 1;
|
---|
505 | if self.generateCode(oOut):
|
---|
506 | return 0;
|
---|
507 |
|
---|
508 | return 1;
|
---|
509 |
|
---|
510 |
|
---|
511 | if __name__ == '__main__':
|
---|
512 | sys.exit(Bs3CpuGenerated1Generator().main(sys.argv));
|
---|
513 |
|
---|
514 |
|
---|