diff options
Diffstat (limited to 'src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-data.py')
-rwxr-xr-x | src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-data.py | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-data.py b/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-data.py new file mode 100755 index 00000000..63210b48 --- /dev/null +++ b/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-data.py @@ -0,0 +1,665 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# $Id: bs3-cpu-generated-1-data.py $ +# pylint: disable=invalid-name + +""" +Generates testcases from @optest specifications in IEM. +""" + +from __future__ import print_function; + +__copyright__ = \ +""" +Copyright (C) 2017-2023 Oracle and/or its affiliates. + +This file is part of VirtualBox base platform packages, as +available from https://www.virtualbox.org. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation, in version 3 of the +License. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, see <https://www.gnu.org/licenses>. + +The contents of this file may alternatively be used under the terms +of the Common Development and Distribution License Version 1.0 +(CDDL), a copy of it is provided in the "COPYING.CDDL" file included +in the VirtualBox distribution, in which case the provisions of the +CDDL are applicable instead of those of the GPL. + +You may elect to license modified versions of this file under the +terms and conditions of either the GPL or the CDDL or both. + +SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 +""" +__version__ = "$Revision: 155250 $" + +# Standard python imports. +import datetime; +import os; +import sys; + +# Only the main script needs to modify the path. +g_ksValidationKitDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))); +g_ksVmmAllDir = os.path.join(os.path.dirname(g_ksValidationKitDir), 'VMM', 'VMMAll') +sys.path.append(g_ksVmmAllDir); + +import IEMAllInstructionsPython as iai; # pylint: disable=import-error + + +# Python 3 hacks: +if sys.version_info[0] >= 3: + long = int; # pylint: disable=redefined-builtin,invalid-name + + +class Bs3Cg1TestEncoder(object): + """ + Does the encoding of a single test. + """ + + def __init__(self, fLast): + self.fLast = fLast; + # Each list member (in all lists) are C expression of a byte. + self.asHdr = []; + self.asSelectors = []; + self.asInputs = []; + self.asOutputs = []; + + @staticmethod + def _compileSelectors(aoSelectors): # (list(iai.TestSelector)) -> list(str) + """ + Compiles a list of iai.TestSelector predicate checks. + Returns C byte expression strings. + """ + asRet = []; + for oSelector in aoSelectors: + sConstant = oSelector.kdVariables[oSelector.sVariable][oSelector.sValue]; + sConstant = sConstant.upper().replace('.', '_'); + if oSelector.sOp == '==': + sByte = '(BS3CG1PRED_%s << BS3CG1SEL_OP_PRED_SHIFT) | BS3CG1SEL_OP_IS_TRUE' % (sConstant,); + elif oSelector.sOp == '!=': + sByte = '(BS3CG1PRED_%s << BS3CG1SEL_OP_PRED_SHIFT) | BS3CG1SEL_OP_IS_FALSE' % (sConstant,); + else: + raise Exception('Unknown selector operator: %s' % (oSelector.sOp,)); + asRet.append(sByte); + return asRet; + + kdSmallFields = { + 'op1': 'BS3CG1_CTXOP_OP1', + 'op2': 'BS3CG1_CTXOP_OP2', + 'efl': 'BS3CG1_CTXOP_EFL', + }; + kdOperators = { + '=': 'BS3CG1_CTXOP_ASSIGN', + '|=': 'BS3CG1_CTXOP_OR', + '&=': 'BS3CG1_CTXOP_AND', + '&~=': 'BS3CG1_CTXOP_AND_INV', + }; + kdSmallSizes = { + 1: 'BS3CG1_CTXOP_1_BYTE', + 2: 'BS3CG1_CTXOP_2_BYTES', + 4: 'BS3CG1_CTXOP_4_BYTES', + 8: 'BS3CG1_CTXOP_8_BYTES', + 16: 'BS3CG1_CTXOP_16_BYTES', + 32: 'BS3CG1_CTXOP_32_BYTES', + 12: 'BS3CG1_CTXOP_12_BYTES', + }; + + @staticmethod + def _amendOutputs(aoOutputs, oInstr): # type: (list(iai.TestInOut), iai.Instruction) -> list(iai.TestInOut) + """ + Amends aoOutputs for instructions with special flag behaviour (undefined, + always set, always clear). + + Undefined flags are copied from the result context as the very first + operation so they can be set to CPU vendor specific values later if + desired. + + Always set or cleared flags are applied at the very end of the + modification operations so that we spot incorrect specifications. + """ + if oInstr.asFlUndefined or oInstr.asFlClear or oInstr.asFlSet: + aoOutputs = list(aoOutputs); + + if oInstr.asFlUndefined: + fFlags = oInstr.getUndefinedFlagsMask(); + assert fFlags != 0; + aoOutputs.insert(0, iai.TestInOut('efl_undef', '=', str(fFlags), 'uint')); + + if oInstr.asFlClear: + fFlags = oInstr.getClearedFlagsMask(); + assert fFlags != 0; + aoOutputs.append(iai.TestInOut('efl', '&~=', str(fFlags), 'uint')); + + if oInstr.asFlSet: + fFlags = oInstr.getSetFlagsMask(); + assert fFlags != 0; + aoOutputs.append(iai.TestInOut('efl', '|=', str(fFlags), 'uint')); + + return aoOutputs; + + @staticmethod + def _compileContextModifers(aoOperations): # (list(iai.TestInOut)) + """ + Compile a list of iai.TestInOut context modifiers. + """ + asRet = []; + for oOperation in aoOperations: + oType = iai.TestInOut.kdTypes[oOperation.sType]; + aaoValues = oType.get(oOperation.sValue); + assert len(aaoValues) == 1 or len(aaoValues) == 2; + + sOp = oOperation.sOp; + if sOp == '&|=': + sOp = '|=' if len(aaoValues) == 1 else '&~='; + + for fSignExtend, abValue in aaoValues: + cbValue = len(abValue); + + # The opcode byte. + sOpcode = Bs3Cg1TestEncoder.kdOperators[sOp]; + sOpcode += ' | '; + if oOperation.sField in Bs3Cg1TestEncoder.kdSmallFields: + sOpcode += Bs3Cg1TestEncoder.kdSmallFields[oOperation.sField]; + else: + sOpcode += 'BS3CG1_CTXOP_DST_ESC'; + sOpcode += ' | '; + if cbValue in Bs3Cg1TestEncoder.kdSmallSizes: + sOpcode += Bs3Cg1TestEncoder.kdSmallSizes[cbValue]; + else: + sOpcode += 'BS3CG1_CTXOP_SIZE_ESC'; + if fSignExtend: + sOpcode += ' | BS3CG1_CTXOP_SIGN_EXT'; + asRet.append(sOpcode); + + # Escaped field identifier. + if oOperation.sField not in Bs3Cg1TestEncoder.kdSmallFields: + asRet.append('BS3CG1DST_%s' % (oOperation.sField.upper().replace('.', '_'),)); + + # Escaped size byte? + if cbValue not in Bs3Cg1TestEncoder.kdSmallSizes: + if cbValue >= 256 or cbValue not in [ 1, 2, 4, 6, 8, 12, 16, 32, 64, 128, ]: + raise Exception('Invalid value size: %s' % (cbValue,)); + asRet.append('0x%02x' % (cbValue,)); + + # The value bytes. + for b in abValue: + asRet.append('0x%02x' % (b,)); + + sOp = '|='; + + return asRet; + + def _constructHeader(self): + """ + Returns C byte expression strings for BS3CG1TESTHDR. + """ + cbSelectors = len(self.asSelectors); + if cbSelectors >= 256: + raise Exception('Too many selectors: %s bytes, max 255 bytes' % (cbSelectors,)) + + cbInputs = len(self.asInputs); + if cbInputs >= 4096: + raise Exception('Too many input context modifiers: %s bytes, max 4095 bytes' % (cbInputs,)) + + cbOutputs = len(self.asOutputs); + if cbOutputs >= 2048: + raise Exception('Too many output context modifiers: %s bytes, max 2047 bytes' % (cbOutputs,)) + + return [ + '%#04x' % (cbSelectors,), # 8-bit + '%#05x & 0xff' % (cbInputs,), # first 8 bits of cbInputs + '(%#05x >> 8) | ((%#05x & 0xf) << 4)' % (cbInputs, cbOutputs,), # last 4 bits of cbInputs, lower 4 bits of cbOutputs. + '(%#05x >> 4) | (%#05x << 7)' % (cbOutputs, self.fLast), # last 7 bits of cbOutputs and 1 bit fLast. + ]; + + def encodeTest(self, oTest): # type: (iai.InstructionTest) + """ + Does the encoding. + """ + self.asSelectors = self._compileSelectors(oTest.aoSelectors); + self.asInputs = self._compileContextModifers(oTest.aoInputs); + self.asOutputs = self._compileContextModifers(self._amendOutputs(oTest.aoOutputs, oTest.oInstr)); + self.asHdr = self._constructHeader(); + + +class Bs3Cg1EncodedTests(object): + """ + Encodes the tests for an instruction. + """ + + def __init__(self, oInstr): + self.offTests = -1; + self.cbTests = 0; + self.asLines = [] # type: list(str) + self.aoInstructions = [] # type: list(iai.Instruction) + + # Encode the tests. + for iTest, oTest in enumerate(oInstr.aoTests): + oEncodedTest = Bs3Cg1TestEncoder(iTest + 1 == len(oInstr.aoTests)); + oEncodedTest.encodeTest(oTest); + + self.cbTests += len(oEncodedTest.asHdr) + len(oEncodedTest.asSelectors) \ + + len(oEncodedTest.asInputs) + len(oEncodedTest.asOutputs); + + self.asLines.append(' /* test #%s: %s */' % (iTest, oTest,)); + self.asLines += self.bytesToLines(' ', oEncodedTest.asHdr); + if oEncodedTest.asSelectors: + self.asLines += self.bytesToLines(' /*sel:*/ ', oEncodedTest.asSelectors); + if oEncodedTest.asInputs: + self.asLines += self.bytesToLines(' /* in:*/ ', oEncodedTest.asInputs); + if oEncodedTest.asOutputs: + self.asLines += self.bytesToLines(' /*out:*/ ', oEncodedTest.asOutputs); + + @staticmethod + def bytesToLines(sPrefix, asBytes): + """ + Formats a series of bytes into one or more lines. + A byte ending with a newline indicates that we should start a new line, + and prefix it by len(sPrefix) spaces. + + Returns list of lines. + """ + asRet = []; + sLine = sPrefix; + for sByte in asBytes: + if sByte[-1] == '\n': + sLine += sByte[:-1] + ','; + asRet.append(sLine); + sLine = ' ' * len(sPrefix); + else: + if len(sLine) + 2 + len(sByte) > 132 and len(sLine) > len(sPrefix): + asRet.append(sLine[:-1]); + sLine = ' ' * len(sPrefix); + sLine += sByte + ', '; + + + if len(sLine) > len(sPrefix): + asRet.append(sLine); + return asRet; + + + def isEqual(self, oOther): + """ Compares two encoded tests. """ + if self.cbTests != oOther.cbTests: + return False; + if len(self.asLines) != len(oOther.asLines): + return False; + for iLine, sLines in enumerate(self.asLines): + if sLines != oOther.asLines[iLine]: + return False; + return True; + + + +class Bs3Cg1Instruction(object): + """ + An instruction with tests. + """ + + def __init__(self, oMap, oInstr, oTests): + self.oMap = oMap # type: iai.InstructionMap + self.oInstr = oInstr # type: iai.Instruction + self.oTests = oTests # type: Bs3Cg1EncodedTests + + self.asOpcodes = oMap.asLeadOpcodes + [ '0x%02x' % (oInstr.getOpcodeByte(),) ]; + self.sEncoding = iai.g_kdEncodings[oInstr.sEncoding][0]; + + for oOp in oInstr.aoOperands: + self.sEncoding += '_' + oOp.sType; + if oInstr.sSubOpcode and iai.g_kdSubOpcodes[oInstr.sSubOpcode][1]: + self.sEncoding += '_' + iai.g_kdSubOpcodes[oInstr.sSubOpcode][1]; + + if oInstr.fUnused: + if oInstr.sInvalidStyle == 'immediate' and oInstr.sSubOpcode: + self.sEncoding += '_MOD_EQ_3' if oInstr.sSubOpcode == '11 mr/reg' else '_MOD_NE_3'; + elif oInstr.sInvalidStyle == 'intel-modrm': + if oInstr.sSubOpcode is None: + self.sEncoding = 'BS3CG1ENC_MODRM_Gv_Ev'; + elif oInstr.sSubOpcode == '11 mr/reg': + self.sEncoding = 'BS3CG1ENC_MODRM_MOD_EQ_3'; + elif oInstr.sSubOpcode == '!11 mr/reg': + self.sEncoding = 'BS3CG1ENC_MODRM_MOD_NE_3'; + else: + raise Exception('Unhandled sSubOpcode=%s for sInvalidStyle=%s' % (oInstr.sSubOpcode, oInstr.sInvalidStyle)); + elif oInstr.sInvalidStyle == 'vex.modrm': + self.sEncoding = 'BS3CG1ENC_VEX_MODRM'; + + self.asFlags = []; + if 'invalid_64' in oInstr.dHints: + self.asFlags.append('BS3CG1INSTR_F_INVALID_64BIT'); + if oInstr.fUnused: + self.asFlags.append('BS3CG1INSTR_F_UNUSED'); + elif oInstr.fInvalid: + self.asFlags.append('BS3CG1INSTR_F_INVALID'); + if oInstr.sInvalidStyle and oInstr.sInvalidStyle.startswith('intel-'): + self.asFlags.append('BS3CG1INSTR_F_INTEL_DECODES_INVALID'); + if 'vex_l_zero' in oInstr.dHints: + self.asFlags.append('BS3CG1INSTR_F_VEX_L_ZERO'); + if 'vex_l_ignored' in oInstr.dHints: + self.asFlags.append('BS3CG1INSTR_F_VEX_L_IGNORED'); + + self.fAdvanceMnemonic = True; ##< Set by the caller. + if oInstr.sPrefix: + if oInstr.sPrefix == 'none': + self.sPfxKind = 'BS3CG1PFXKIND_NO_F2_F3_66'; + else: + self.sPfxKind = 'BS3CG1PFXKIND_REQ_' + oInstr.sPrefix[-2:].upper(); + elif oInstr.sEncoding == 'ModR/M': + if 'ignores_op_size' not in oInstr.dHints: + self.sPfxKind = 'BS3CG1PFXKIND_MODRM'; + else: + self.sPfxKind = 'BS3CG1PFXKIND_MODRM_NO_OP_SIZES'; + else: + self.sPfxKind = '0'; + + self.sCpu = 'BS3CG1CPU_'; + assert len(oInstr.asCpuIds) in [0, 1], str(oInstr); + if oInstr.asCpuIds: + self.sCpu += oInstr.asCpuIds[0].upper().replace('.', '_'); + elif oInstr.sMinCpu: + self.sCpu += 'GE_' + oInstr.sMinCpu; + else: + self.sCpu += 'ANY'; + + if oInstr.sXcptType: + self.sXcptType = 'BS3CG1XCPTTYPE_' + oInstr.sXcptType.upper(); + else: + self.sXcptType = 'BS3CG1XCPTTYPE_NONE'; + + def getOperands(self): + """ Returns comma separated string of operand values for g_abBs3Cg1Operands. """ + return ', '.join(['(uint8_t)BS3CG1OP_%s' % (oOp.sType,) for oOp in self.oInstr.aoOperands]); + + def getOpcodeMap(self): + """ Returns the opcode map number for the BS3CG1INSTR structure. """ + sEncoding = self.oInstr.aoMaps[0].sEncoding; + if sEncoding == 'legacy': return 0; + if sEncoding == 'vex1': return 1; + if sEncoding == 'vex2': return 2; + if sEncoding == 'vex3': return 3; + if sEncoding == 'xop8': return 8; + if sEncoding == 'xop9': return 9; + if sEncoding == 'xop10': return 10; + assert False, sEncoding; + return 3; + + def getInstructionEntry(self): + """ Returns an array of BS3CG1INSTR member initializers. """ + assert len(self.oInstr.sMnemonic) < 16; + sOperands = ', '.join([oOp.sType for oOp in self.oInstr.aoOperands]); + if sOperands: + sOperands = ' /* ' + sOperands + ' */'; + return [ + ' /* cbOpcodes = */ %s, /* %s */' % (len(self.asOpcodes), ' '.join(self.asOpcodes),), + ' /* cOperands = */ %s,%s' % (len(self.oInstr.aoOperands), sOperands,), + ' /* cchMnemonic = */ %s, /* %s */' % (len(self.oInstr.sMnemonic), self.oInstr.sMnemonic,), + ' /* fAdvanceMnemonic = */ %s,' % ('true' if self.fAdvanceMnemonic else 'false',), + ' /* offTests = */ %s,' % (self.oTests.offTests,), + ' /* enmEncoding = */ (unsigned)%s,' % (self.sEncoding,), + ' /* uOpcodeMap = */ (unsigned)%s,' % (self.getOpcodeMap(),), + ' /* enmPrefixKind = */ (unsigned)%s,' % (self.sPfxKind,), + ' /* enmCpuTest = */ (unsigned)%s,' % (self.sCpu,), + ' /* enmXcptType = */ (unsigned)%s,' % (self.sXcptType,), + ' /* uUnused = */ 0,', + ' /* fFlags = */ %s' % (' | '.join(self.asFlags) if self.asFlags else '0'), + ]; + + +class Bs3CpuGenerated1Generator(object): + """ + The generator code for bs3-cpu-generated-1. + """ + + def __init__(self): + self.aoInstructions = [] # type: Bs3Cg1Instruction + self.aoTests = [] # type: Bs3Cg1EncodedTests + self.cbTests = 0; + + def addTests(self, oTests, oInstr): # type: (Bs3Cg1EncodedTests, iai.Instruction) -> Bs3Cg1EncodedTests + """ + Adds oTests to self.aoTests, setting the oTests.offTests member. + Checks for and eliminates duplicates. + Returns the tests to use. + """ + # Check for duplicates. + for oExisting in self.aoTests: + if oTests.isEqual(oExisting): + oExisting.aoInstructions.append(oInstr); + return oExisting; + + # New test, so add it. + oTests.offTests = self.cbTests; + self.aoTests.append(oTests); + self.cbTests += oTests.cbTests; + + assert not oTests.aoInstructions; + oTests.aoInstructions.append(oInstr); + + return oTests; + + def processInstruction(self): + """ + Processes the IEM specified instructions. + Returns success indicator. + """ + + # + # Group instructions by mnemonic to reduce the number of sub-tests. + # + for oInstr in sorted(iai.g_aoAllInstructions, + key = lambda oInstr: oInstr.sMnemonic + ''.join([oOp.sType for oOp in oInstr.aoOperands]) + + (oInstr.sOpcode if oInstr.sOpcode else 'zz')): + if oInstr.aoTests: + oTests = Bs3Cg1EncodedTests(oInstr); + oTests = self.addTests(oTests, oInstr); + + for oMap in oInstr.aoMaps: + self.aoInstructions.append(Bs3Cg1Instruction(oMap, oInstr, oTests)); + + # Set fAdvanceMnemonic. + for iInstr, oInstr in enumerate(self.aoInstructions): + oInstr.fAdvanceMnemonic = iInstr + 1 >= len(self.aoInstructions) \ + or oInstr.oInstr.sMnemonic != self.aoInstructions[iInstr + 1].oInstr.sMnemonic; + + return True; + + def generateCode(self, oOut): + """ + Generates the C code. + Returns success indicator. + """ + + # First, a file header. + asLines = [ + '/*', + ' * Autogenerated by $Id: bs3-cpu-generated-1-data.py $ ', + ' * Do not edit!', + ' */', + '', + '/*', + ' * Copyright (C) 2017-' + str(datetime.date.today().year) + ' Oracle and/or its affiliates.', + ' *', + ' * This file is part of VirtualBox base platform packages, as', + ' * available from https://www.virtualbox.org.', + ' *', + ' * This program is free software; you can redistribute it and/or', + ' * modify it under the terms of the GNU General Public License', + ' * as published by the Free Software Foundation, in version 3 of the', + ' * License.', + ' *', + ' * This program is distributed in the hope that it will be useful, but', + ' * WITHOUT ANY WARRANTY; without even the implied warranty of', + ' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU', + ' * General Public License for more details.', + ' *', + ' * You should have received a copy of the GNU General Public License', + ' * along with this program; if not, see <https://www.gnu.org/licenses>.', + ' *', + ' * The contents of this file may alternatively be used under the terms', + ' * of the Common Development and Distribution License Version 1.0', + ' * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included', + ' * in the VirtualBox distribution, in which case the provisions of the', + ' * CDDL are applicable instead of those of the GPL.', + ' *', + ' * You may elect to license modified versions of this file under the', + ' * terms and conditions of either the GPL or the CDDL or both.', + ' *', + ' * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0', + ' */', + '', + '', + '#include "bs3-cpu-generated-1.h"', + '', + '', + '#pragma data_seg ("BS3DATA16")', + ]; + + # Generate the g_achBs3Cg1Mnemonics array. + asLines += [ + 'const char BS3_FAR_DATA g_achBs3Cg1Mnemonics[] = ', + '{', + ]; + fAdvanceMnemonic = True; + for oInstr in self.aoInstructions: + if fAdvanceMnemonic: + asLines.append(' \"%s\"' % (oInstr.oInstr.sMnemonic,)); + fAdvanceMnemonic = oInstr.fAdvanceMnemonic; + asLines += [ + '};', + '', + '', + ]; + + # Generate the g_abBs3Cg1Opcodes array. + asLines += [ + 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Opcodes[] = ', + '{', + ]; + for oInstr in self.aoInstructions: + asLines.append(' ' + ', '.join(oInstr.asOpcodes) + ','); + asLines += [ + '};', + '', + '', + ]; + + # Generate the g_abBs3Cg1Opcodes array. + asLines += [ + 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Operands[] = ', + '{', + ]; + cOperands = 0; + for oInstr in self.aoInstructions: + if oInstr.oInstr.aoOperands: + cOperands += len(oInstr.oInstr.aoOperands); + asLines.append(' ' + oInstr.getOperands() + ', /* %s */' % (oInstr.oInstr.sStats,)); + else: + asLines.append(' /* none */'); + if not cOperands: + asLines.append(' 0 /* dummy */'); + asLines += [ + '};', + '', + '', + ]; + + # Generate the g_abBs3Cg1Operands array. + asLines += [ + 'const BS3CG1INSTR BS3_FAR_DATA g_aBs3Cg1Instructions[] = ', + '{', + ]; + for oInstr in self.aoInstructions: + asLines.append(' {'); + asLines += oInstr.getInstructionEntry(); + asLines.append(' },'); + asLines += [ + '};', + 'const uint16_t BS3_FAR_DATA g_cBs3Cg1Instructions = RT_ELEMENTS(g_aBs3Cg1Instructions);', + '', + '', + ]; + + # Generate the g_abBs3Cg1Tests array. + asLines += [ + 'const uint8_t BS3_FAR_DATA g_abBs3Cg1Tests[] = ', + '{', + ]; + for oTests in self.aoTests: + asLines.append(' /*'); + asLines.append(' * offTests=%s' % (oTests.offTests,)); + asLines.append(' * Instructions: %s' % (', '.join([oInstr.sStats for oInstr in oTests.aoInstructions]),)); + asLines.append(' */'); + asLines += oTests.asLines; + asLines += [ + '};', + '', + ]; + + + #/** The test data that BS3CG1INSTR. + # * In order to simplify generating these, we use a byte array. */ + #extern const uint8_t BS3_FAR_DATA g_abBs3Cg1Tests[]; + + + oOut.write('\n'.join(asLines)); + return True; + + + def usage(self): + """ Prints usage. """ + print('usage: bs3-cpu-generated-1-data.py [output file|-]'); + return 0; + + def main(self, asArgs): + """ + C-like main function. + Returns exit code. + """ + + # + # Quick argument parsing. + # + if len(asArgs) == 1: + sOutFile = '-'; + elif len(asArgs) != 2: + print('syntax error! Expected exactly one argument.'); + return 2; + elif asArgs[1] in [ '-h', '-?', '--help' ]: + return self.usage(); + else: + sOutFile = asArgs[1]; + + # + # Process the instructions specified in the IEM sources. + # + if self.processInstruction(): + + # + # Open the output file and generate the code. + # + if sOutFile == '-': + oOut = sys.stdout; + else: + try: + oOut = open(sOutFile, 'w'); # pylint: disable=consider-using-with,unspecified-encoding + except Exception as oXcpt: + print('error! Failed open "%s" for writing: %s' % (sOutFile, oXcpt,)); + return 1; + if self.generateCode(oOut): + return 0; + + return 1; + + +if __name__ == '__main__': + sys.exit(Bs3CpuGenerated1Generator().main(sys.argv)); + |