InstructionTestGen.py revision ac91d9d0626a52f79cf554c81b1fdf5f262092bb
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync# -*- coding: utf-8 -*-
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncInstruction Test Generator.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncCopyright (C) 2012-2013 Oracle Corporation
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncOracle Corporation confidential
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncAll rights reserved
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync# Standard python imports.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name Exit codes
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name Various C macros we're used to.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ 32-bit one bit mask. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ 64-bit one bit mask. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name ModR/M
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name SIB
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name PRefixes
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name Register names.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs64NoSp = ('rax', 'rcx', 'rdx', 'rbx', None, 'rbp', 'rsi', 'rdi', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs64 = ('rax', 'rcx', 'rdx', 'rbx', 'rsp', 'rbp', 'rsi', 'rdi', 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs32NoSp = ('eax', 'ecx', 'edx', 'ebx', None, 'ebp', 'esi', 'edi',
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'r8d', 'r9d', 'r10d', 'r11d', 'r12d', 'r13d', 'r14d', 'r15d');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs32 = ('eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi',
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'r8d', 'r9d', 'r10d', 'r11d', 'r12d', 'r13d', 'r14d', 'r15d');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs16NoSp = ('ax', 'cx', 'dx', 'bx', None, 'bp', 'si', 'di',
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'r8w', 'r9w', 'r10w', 'r11w', 'r12w', 'r13w', 'r14w', 'r15w');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncg_asGRegs16 = ('ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di',
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'r8w', 'r9w', 'r10w', 'r11w', 'r12w', 'r13w', 'r14w', 'r15w');
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsyncg_asGRegs8 = ('al', 'cl', 'dl', 'bl', 'ah', 'ah', 'dh', 'bh');
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsyncg_asGRegs8Rex = ('al', 'cl', 'dl', 'bl', 'spl', 'bpl', 'sil', 'dil',
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'r8b', 'r9b', 'r10b', 'r11b', 'r12b', 'r13b', 'r14b', 'r15b');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name Random
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Unsigned 16-bit random number. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Unsigned 32-bit random number. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Unsigned 64-bit random number. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Unsigned 8-, 16-, 32-, or 64-bit random number. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ List of nsigned 8-, 16-, 32-, or 64-bit random numbers. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## @name Instruction Emitter Helpers
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncdef calcRexPrefixForTwoModRmRegs(iReg, iRm, bOtherRexPrefixes = 0):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Calculates a rex prefix if neccessary given the two registers
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync and optional rex size prefixes.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Returns an empty array if not necessary.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Calculate the RM byte for two registers.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Returns an array with one byte in it.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync | ((iReg << X86_MODRM_REG_SHIFT) & X86_MODRM_REG_MASK) \
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync## @name Misc
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync """ Converts a 32-bit unsigned value to 32-bit signed. """
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync """ Gets the name of a general register by index and width. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Target Runtime Environment.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ## @name CPU Modes
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ## @name Instruction set.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.asGRegs = g_asGRegs64 if self.is64Bit() else g_asGRegs32;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.asGRegsNoSp = g_asGRegs64NoSp if self.is64Bit() else g_asGRegs32NoSp;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Whether it's an IPRT environment or not. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Whether it's a 64-bit environment or not. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Get the default operand size as a bit count. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Get the default operand size as a byte count. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Get the max operand size as a bit count. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Get the max operand size as a byte count. """
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync """ Get the default address size as a bit count. """
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync """ Get the default address size as a byte count. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Get the number of general registers. """
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync """ Returns a random general register number, excluding the SP register. """
270236340676d2385b27ea992e07fcb643bb78b6vboxsync """ Gets a list of addressing mode (16, 32, or/and 64). """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## Target environments.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'iprt-r3-32': TargetEnv('iprt-r3-32', TargetEnv.ksInstrSet_32, TargetEnv.ksCpuMode_Protect, 3),
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'iprt-r3-64': TargetEnv('iprt-r3-64', TargetEnv.ksInstrSet_64, TargetEnv.ksCpuMode_Long, 3),
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Base class for testing one instruction.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.sInstr = sInstr if sInstr else sName.split()[0];
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync Tests if the instruction test is applicable to the selected environment.
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync Emits the test assembly code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oGen.write(';; @todo not implemented. This is for the linter: %s, %s\n' % (oGen, sTestFnName));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync def generateInputs(self, cbEffOp, cbMaxOp, oGen, fLong = False):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Generate a list of inputs. """
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync # Try do extremes as well as different ranges of random numbers.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auRet += [ UINT8_MAX / 2, UINT8_MAX / 2 + 1, UINT8_MAX ];
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auRet += [ UINT16_MAX / 2, UINT16_MAX / 2 + 1, UINT16_MAX ];
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auRet += [ UINT32_MAX / 2, UINT32_MAX / 2 + 1, UINT32_MAX ];
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auRet += [ UINT64_MAX / 2, UINT64_MAX / 2 + 1, UINT64_MAX ];
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync for cBits, cValues in ( (8, 4), (16, 4), (32, 8), (64, 8) ):
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync elif oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Medium:
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync for cBits, cValues in ( (8, 8), (16, 8), (24, 2), (32, 16), (40, 1), (48, 1), (56, 1), (64, 16) ):
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync for cBits, cValues in ( (8, 16), (16, 16), (24, 4), (32, 64), (40, 4), (48, 4), (56, 4), (64, 64) ):
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auRet += randUxxList(cbEffOp * 8, cWanted - len(auRet));
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync # Short list, just do some random numbers.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync elif oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Medium:
270236340676d2385b27ea992e07fcb643bb78b6vboxsync Instruction reading memory or general register and writing the result to a
270236340676d2385b27ea992e07fcb643bb78b6vboxsync general register.
270236340676d2385b27ea992e07fcb643bb78b6vboxsync def __init__(self, sName, fnCalcResult, sInstr = None, acbOpVars = None):
270236340676d2385b27ea992e07fcb643bb78b6vboxsync self.acbOpVars = [ 1, 2, 4, 8 ] if not acbOpVars else list(acbOpVars);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync def writeInstrGregGreg(self, cbEffOp, iOp1, iOp2, oGen):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Writes the instruction with two general registers as operands. """
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' %s %s, %s\n' % (self.sInstr, g_asGRegs64[iOp1], g_asGRegs64[iOp2]));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' %s %s, %s\n' % (self.sInstr, g_asGRegs32[iOp1], g_asGRegs32[iOp2]));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' %s %s, %s\n' % (self.sInstr, g_asGRegs16[iOp1], g_asGRegs16[iOp2]));
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync oGen.write(' %s %s, %s\n' % (self.sInstr, g_asGRegs8Rex[iOp1], g_asGRegs8Rex[iOp2]));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync def writeInstrGregPureRM(self, cbEffOp, iOp1, cAddrBits, iOp2, iMod, offDisp, oGen):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync """ Writes the instruction with two general registers as operands. """
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' %s %s, [' % (self.sInstr, g_asGRegs64[iOp1],));
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync oGen.write(' %s %s, [' % (self.sInstr, g_asGRegs32[iOp1],));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' %s %s, [' % (self.sInstr, g_asGRegs16[iOp1],));
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync oGen.write(' %s %s, [' % (self.sInstr, g_asGRegs8Rex[iOp1],));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write('VBINSTST_NAME(g_u%sData)' % (cbEffOp * 8,))
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync assert False; ## @todo implement 16-bit addressing.
270236340676d2385b27ea992e07fcb643bb78b6vboxsync def generateOneStdTestGregGreg(self, oGen, cbEffOp, cbMaxOp, iOp1, iOp2, uInput, uResult):
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync """ Generate one standard test. """
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n');
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync oGen.write(' mov %s, 0x%x\n' % (oGen.oTarget.asGRegs[iOp2], uInput,));
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync oGen.write(' push %s\n' % (oGen.oTarget.asGRegs[iOp2],));
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync self.writeInstrGregGreg(cbEffOp, iOp1, iOp2, oGen);
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1, iOp2),));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync def generateMemSetupPureRM(self, oGen, cAddrBits, cbEffOp, iOp2, iMod, uInput, offDisp = None):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync """ Sets up memory for a pure R/M addressed read, iOp2 being the R/M value. """
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync % (oGen.needGRegMemSetup(cAddrBits, cbEffOp, iOp2, offDisp),));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync ## @todo generate REX.B=1 variant.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync oGen.write(' call VBINSTST_NAME(Common_SetupMemReadU%u)\n' % (cbEffOp*8,));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' push %s\n' % (oGen.oTarget.asGRegs[iOp2],));
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync def generateOneStdTestGregMemNoSib(self, oGen, cAddrBits, cbEffOp, cbMaxOp, iOp1, iOp2, uInput, uResult):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync """ Generate mode 0, 1 and 2 test for the R/M=iOp2. """
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n');
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync self.generateMemSetupPureRM(oGen, cAddrBits, cbEffOp, iOp2, iMod, uInput);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync self.writeInstrGregPureRM(cbEffOp, iOp1, cAddrBits, iOp2, iMod, None, oGen);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1, iOp2),));
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n');
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync self.generateMemSetupPureRM(oGen, cAddrBits, cbEffOp, iOp2, iMod, uInput, offDisp);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync self.writeInstrGregPureRM(cbEffOp, iOp1, cAddrBits, iOp2, iMod, offDisp, oGen);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1, iOp2),));
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync oGen.write(' call VBINSTST_NAME(Common_LoadKnownValues)\n');
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync self.generateMemSetupPureRM(oGen, cAddrBits, cbEffOp, iOp2, iMod, uInput, offDisp);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync self.writeInstrGregPureRM(cbEffOp, iOp1, cAddrBits, iOp2, iMod, offDisp, oGen);
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync oGen.write(' call VBINSTST_NAME(%s)\n' % (oGen.needGRegChecker(iOp1, iOp2),));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Generate standard tests. """
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync # Parameters.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auShortInputs = self.generateInputs(cbDefOp, cbMaxOp, oGen);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync auLongInputs = self.generateInputs(cbDefOp, cbMaxOp, oGen, fLong = True);
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync if oGen.oOptions.sTestSize == InstructionTestGen.ksTestSize_Tiny:
270236340676d2385b27ea992e07fcb643bb78b6vboxsync # Register tests
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync for uInput in (auLongInputs if iOp1 == iLongOp1 and iOp2 == iLongOp2 else auShortInputs):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync oGen.auRegValues[iOp1] if iOp1 != iOp2 else uInput, oGen);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync self.generateOneStdTestGregGreg(oGen, cbEffOp, cbMaxOp, iOp1, iOp2, uInput, uResult);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync # Memory test.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync for uInput in (auLongInputs if iOp1 == iLongOp1 and False else auShortInputs):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync if iOp1 == iOp2 and iOp2 != 5 and iOp2 != 13 and cbEffOp != cbMaxOp:
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync continue; # Don't know the high bit of the address ending up the result - skip it.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync uResult = self.fnCalcResult(cbEffOp, uInput, oGen.auRegValues[iOp1], oGen);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync self.generateOneStdTestGregMemNoSib(oGen, cAddrBits, cbEffOp, cbMaxOp,
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync pass; # SIB
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oGen.write('VBINSTST_BEGINPROC %s\n' % (sTestFnName,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync #oGen.write(' int3\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync #oGen.write(' int3\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oGen.write('VBINSTST_ENDPROC %s\n' % (sTestFnName,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsyncclass InstrTest_Mov_Gv_Ev(InstrTest_MemOrGreg_2_Greg):
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync Tests MOV Gv,Ev.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync InstrTest_MemOrGreg_2_Greg.__init__(self, 'mov Gv,Ev', self.calc_mov);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync """ Calculates the result of a mov instruction."""
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync return (uCur & 0xffffffffffff0000) | (uInput & UINT16_MAX);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync return (uCur & 0xffffffffffffff00) | (uInput & UINT8_MAX);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsyncclass InstrTest_MovSxD_Gv_Ev(InstrTest_MemOrGreg_2_Greg):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Tests MOVSXD Gv,Ev.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync InstrTest_MemOrGreg_2_Greg.__init__(self, 'movsxd Gv,Ev', self.calc_movsxd, acbOpVars = [ 8, 4, 2, ]);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync def writeInstrGregGreg(self, cbEffOp, iOp1, iOp2, oGen):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oGen.write(' %s %s, %s\n' % (self.sInstr, g_asGRegs64[iOp1], g_asGRegs32[iOp2]));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync abInstr += calcRexPrefixForTwoModRmRegs(iOp1, iOp2);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Calculates the result of a movxsd instruction.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Returns the result value (cbMaxOp sized).
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return (uCur & 0xffffffffffff0000) | (uInput & 0xffff);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync## Instruction Tests.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync #InstrTest_MovSxD_Gv_Ev(),
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Instruction Test Generator.
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync ## @name Test size
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync kasTestSizes = ( ksTestSize_Large, ksTestSize_Medium, ksTestSize_Tiny );
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Calculate the number of output files.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync if len(g_aoInstructionTests) > self.oOptions.cInstrPerFile:
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.cFiles = len(g_aoInstructionTests) / self.oOptions.cInstrPerFile;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync if self.cFiles * self.oOptions.cInstrPerFile < len(g_aoInstructionTests):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Fix the known register values.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.au32Regs = [(self.au64Regs[i] & UINT32_MAX) for i in range(8)];
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.au16Regs = [(self.au64Regs[i] & UINT16_MAX) for i in range(8)];
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync self.auRegValues = self.au64Regs if self.oTarget.is64Bit() else self.au32Regs;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Declare state variables used while generating.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Methods used by instruction tests.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Writes to the current output file. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync """ Writes a line to the current output file. """
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Emits an instruction given as a sequence of bytes values.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Indicates that a new subtest has started.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov dword [VBINSTST_NAME(g_uVBInsTstSubTestIndicator) xWrtRIP], __LINE__\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Records the need for a given register checker function, returning its label.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return 'Common_Check_%s_%s' % (self.oTarget.asGRegs[iReg1], self.oTarget.asGRegs[iReg2]);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync def needGRegMemSetup(self, cAddrBits, cbEffOp, iReg1, offDisp = None):
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync Records the need for a given register checker function, returning its label.
ac91d9d0626a52f79cf554c81b1fdf5f262092bbvboxsync sName = '%ubit_U%u_%s' % (cAddrBits, cbEffOp * 8, gregName(iReg1, cAddrBits),);
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync if offDisp is not None:
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Records the need for a 64-bit constant, returning its label.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync These constants are pooled to attempt reduce the size of the whole thing.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Emits a push constant value, taking care of high values on 64-bit hosts.
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync if self.oTarget.is64Bit() and uResult >= 0x80000000:
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' push qword [%s wrt rip]\n' % (self.need64BitConstant(uResult),));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Internal machinery.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync def _calcTestFunctionName(self, oInstrTest, iInstrTest):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Calc a test function name for the given instruction test.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync sName = 'TestInstr%03u_%s' % (iInstrTest, oInstrTest.sName);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync return sName.replace(',', '_').replace(' ', '_').replace('%', '_');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Writes the file header.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Raises exception on trouble.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ';; @file %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; Autogenerate by %s %s. DO NOT EDIT\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; Headers\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '%%include "env-%s.mac"\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Target environment specific init stuff.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Global variables.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; Globals\n'
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync 'VBINSTST_GLOBALNAME_EX g_pvLow16Mem4K, data hidden\n'
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync 'VBINSTST_GLOBALNAME_EX g_pvLow32Mem4K, data hidden\n'
f372af8e6ee2a011213b11cc69f4a29530ff7ce5vboxsync 'VBINSTST_GLOBALNAME_EX g_pvMem4K, data hidden\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_GLOBALNAME_EX g_uVBInsTstSubTestIndicator, data hidden\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_BEGINCODE\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write('g_u64KnownValue_%s: dq 0x%x\n' % (g_asGRegs64[i], self.au64Regs[i]));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Common functions.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Loading common values.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_BEGINPROC Common_LoadKnownValues\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '%ifdef RT_ARCH_AMD64\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, 0x%x\n' % (g_asGRegs64NoSp[i], self.au64Regs[i],));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, 0x%x\n' % (g_asGRegs32NoSp[i], self.au32Regs[i],));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_ENDPROC Common_LoadKnownValues\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write('VBINSTST_BEGINPROC Common_CheckKnownValues\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '%ifdef RT_ARCH_AMD64\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' cmp %s, [g_u64KnownValue_%s wrt rip]\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' je .ok_%u\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %u ; register number\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; actual\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push qword [g_u64KnownValue_%s wrt rip] ; expected\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' call VBINSTST_NAME(Common_BadValue)\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '.ok_%u:\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync % ( g_asGRegs64NoSp[i], g_asGRegs64NoSp[i], i, i, g_asGRegs64NoSp[i], g_asGRegs64NoSp[i], i,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' je .ok_%u\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %u ; register number\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; actual\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push dword 0x%x ; expected\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' call VBINSTST_NAME(Common_BadValue)\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '.ok_%u:\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync % ( g_asGRegs32NoSp[i], self.au32Regs[i], i, i, g_asGRegs32NoSp[i], self.au32Regs[i], i,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_ENDPROC Common_CheckKnownValues\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync Generates the memory setup functions.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Unpack it.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync iScale = int(asParams[i]); assert iScale in [2, 4, 8];
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync assert i == len(asParams), 'i=%d len=%d len[i]=%d (%s)' % (i, len(asParams), len(asParams[i]), asParams[i],);
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Prologue.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync 'VBINSTST_BEGINPROC Common_MemSetup_%s\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync ' MY_PUSH_FLAGS\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync ' push %s\n'
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync self.write('; cAddrBits=%s cEffOpBits=%s iBaseReg=%s u32Disp=%s iIndexReg=%s iScale=%s\n'
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync % (cAddrBits, cEffOpBits, iBaseReg, u32Disp, iIndexReg, iScale,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Figure out what to use.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Load the value and mem address, sorting the value there.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov %s, [xSP + sCB + MY_PUSH_FLAGS_SIZE + xCB]\n' % (sTmpReg1,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov [%s xWrtRIP], %s\n' % (sDataVar, sTmpReg1,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' lea %s, [%s xWrtRIP]\n' % (sBaseReg, sDataVar,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov %s, [VBINSTST_NAME(g_pvLow16Mem4K) xWrtRIP]\n' % (sBaseReg,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov %s, [VBINSTST_NAME(g_pvLow32Mem4K) xWrtRIP]\n' % (sBaseReg,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' add %s, %s\n' % (sBaseReg, (randU16() << cEffOpBits) & 0xfff, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov [%s], %s\n' % (sBaseReg, sTmpReg1, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Adjust for disposition and scaling.
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync if u32Disp is not None:
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' sub %s, %d\n' % ( sBaseReg, convU32ToSigned(u32Disp), ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync if iIndexReg is not None:
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' mov %s, %u\n' % ( sIndexReg, uIdxRegVal,));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' sub %s, %#06x\n' % ( sBaseReg, uIdxRegVal * iScale, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' sub %s, %#06x\n' % ( sBaseReg, (uIdxRegVal * iScale) & UINT32_MAX, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync self.write(' sub %s, %#06x\n' % ( sBaseReg, (uIdxRegVal * iScale) & UINT16_MAX, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Set upper bits that's supposed to be unused.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync ' or %s, %s\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync % ( g_asGRegs64[iTmpReg1], randU64() & 0xffffffff00000000,
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync if iIndexReg is not None:
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync ' or %s, %s\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync % ( g_asGRegs64[iTmpReg1], randU64() & 0xffffffff00000000,
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync % ( g_asGRegs32[iBaseReg], randU32() & 0xffff0000, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync if iIndexReg is not None:
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync % ( g_asGRegs32[iIndexReg], randU32() & 0xffff0000, ));
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # Epilogue.
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync ' MY_POP_FLAGS\n'
bec4d1c0274e4712fe01426313aab120b5ad1c17vboxsync ' ret sCB\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync 'VBINSTST_ENDPROC Common_MemSetup_%s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Generates file footer.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Register checking functions.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; Checks two register values, expected values pushed on the stack.\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; To save space, the callee cleans up the stack.'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; Ref count: %u\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_BEGINPROC Common_Check_%s_%s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' MY_PUSH_FLAGS\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' cmp %s, [xSP + MY_PUSH_FLAGS_SIZE + xCB]\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' je .equal1\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s %u ; register number\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; actual\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' mov %s, [xSP + sCB*2 + MY_PUSH_FLAGS_SIZE + xCB]\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; expected\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' call VBINSTST_NAME(Common_BadValue)\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '.equal1:\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync % ( sReg1, sPushSize, iReg1, sReg1, sReg1, sReg1, sReg1, sReg1, sReg1, ) );
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync if iReg1 != iReg2: # If input and result regs are the same, only check the result.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' cmp %s, [xSP + sCB + MY_PUSH_FLAGS_SIZE + xCB]\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' je .equal2\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s %u ; register number\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; actual\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' mov %s, [xSP + sCB*3 + MY_PUSH_FLAGS_SIZE + xCB]\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' push %s ; expected\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' call VBINSTST_NAME(Common_BadValue)\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' pop %s\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '.equal2:\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync % ( sReg2, sPushSize, iReg2, sReg2, sReg2, sReg2, sReg2, sReg2, sReg2, ) );
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, [g_u64KnownValue_%s wrt rip]\n' % (sReg1, sReg1,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, [g_u64KnownValue_%s wrt rip]\n' % (sReg2, sReg2,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, 0x%x\n' % (sReg1, self.au32Regs[iReg1],));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write(' mov %s, 0x%x\n' % (sReg2, self.au32Regs[iReg2],));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' call VBINSTST_NAME(Common_CheckKnownValues)\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' ret sCB*2\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_ENDPROC Common_Check_%s_%s\n'
c6383709c15c809f8cfb09b5cfe670760f06e2b9vboxsync # memory setup functions
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # 64-bit constants.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync '; 64-bit constants\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write('g_u64Const_0x%016x: dq 0x%016x ; Ref count: %d\n' % (uVal, uVal, self.d64BitConsts[uVal], ) );
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Generate the test cases.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.sFile = '%s.asm' % (self.oOptions.sOutputBase,)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.sFile = '%s-%u.asm' % (self.oOptions.sOutputBase, self.iFile)
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.oFile = io.open(self.sFile, 'w', encoding = 'utf-8');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Calc the range.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync iInstrTestStart = self.iFile * self.oOptions.cInstrPerFile;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync iInstrTestEnd = iInstrTestStart + self.oOptions.cInstrPerFile;
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Generate the instruction tests.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync for iInstrTest in range(iInstrTestStart, iInstrTestEnd):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oInstrTest.generateTest(self, self._calcTestFunctionName(oInstrTest, iInstrTest));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Generate the main function.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'VBINSTST_BEGINPROC TestInstrMain\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' MY_PUSH_ALL\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' sub xSP, 40h\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync for iInstrTest in range(iInstrTestStart, iInstrTestEnd):
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' lea rdi, [.szInstr%03u wrt rip]\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync '%%elifdef ASM_CALL64_MSC\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' lea rcx, [.szInstr%03u wrt rip]\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' mov xAX, .szInstr%03u\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' mov [xSP], xAX\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync '%%endif\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' VBINSTST_CALL_FN_SUB_TEST\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync ' call VBINSTST_NAME(%s)\n'
51ef69064b4ea4d571ed129ab883b0c08967c901vboxsync % ( iInstrTest, iInstrTest, iInstrTest, self._calcTestFunctionName(oInstrTest, iInstrTest)));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' add xSP, 40h\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' MY_POP_ALL\n'
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync ' ret\n\n');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync for iInstrTest in range(iInstrTestStart, iInstrTestEnd):
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync self.write('.szInstr%03u: db \'%s\', 0\n' % (iInstrTest, g_aoInstructionTests[iInstrTest].sName,));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Generate a list of output files on standard output.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync print(' '.join('%s-%s.asm' % (self.oOptions.sOutputBase, i) for i in range(self.cFiles)));
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Generates the tests or whatever is required.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync Main function a la C/C++. Returns exit code.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Parse the command line.
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oParser = OptionParser(version = __version__[11:-1].strip());
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oParser.add_option('--makefile-mode', dest = 'fMakefileMode', action = 'store_true', default = False,
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync help = 'Special mode for use to output a list of output files for the benefit of '
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync 'the make program (kmk).');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oParser.add_option('--split', dest = 'cInstrPerFile', metavar = '<instr-per-file>', type = 'int', default = 9999999,
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync help = 'Number of instruction to test per output file.');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oParser.add_option('--output-base', dest = 'sOutputBase', metavar = '<file>', default = None,
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync help = 'The output file base name, no suffix please. Required.');
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync oParser.add_option('--target', dest = 'sTargetEnv', metavar = '<target>',
0ab80a5f847b8c908ee2d9db5cc37da8e8dd5697vboxsync oParser.add_option('--test-size', dest = 'sTestSize', default = InstructionTestGen.ksTestSize_Medium,
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync print('syntax error: Missing required option --output-base.', file = sys.stderr);
917f4ee9f101c9786cf09ea0fe7923a7f6dfe40cvboxsync # Instantiate the program class and run it.