コード例 #1
0
        /// <summary>
        /// Gets a random number generator.
        /// </summary>
        /// <param name="variant">The opcode variant.</param>
        /// <returns>A <see cref="Random"/> object.</returns>
        /// <remarks>
        /// The seed of the RNG depends on the operands used by the opcode variant,
        /// but is constant across uses.
        /// </remarks>
        Random GetRandom(X86OpcodeVariantSpec variant)
        {
            string name = string.Join("_", from o in variant.Operands.Cast <X86OperandSpec>()
                                      select GetOperandManualName(o));

            return(new Random(name.GetHashCode()));
        }
コード例 #2
0
        /// <summary>
        /// Writes a single test for a specific opcode variant.
        /// </summary>
        /// <param name="spec">The opcode spec.</param>
        /// <param name="variant">The opcode variant.</param>
        /// <param name="writer">The text writer to write to.</param>
        void WriteTest(X86OpcodeSpec spec, X86OpcodeVariantSpec variant, TextWriter writer)
        {
            var operandStrings = from o in variant.Operands.Cast <X86OperandSpec>()
                                 select GetOperandStrings(o.Type, o.Size, o.FixedRegister, GetRandom(variant));

            string operands = string.Join(", ", from o in operandStrings select o.Item1);

            string instruction = spec.Mnemonic.ToUpperInvariant();

            if (operandStrings.Any())
            {
                instruction += " " + string.Join(", ", from o in operandStrings select o.Item2);
            }

            string feedback16;

            byte[] bytes16 = GetEncodedInstruction(DataSize.Bit16, instruction, out feedback16);
            string feedback32;

            byte[] bytes32 = GetEncodedInstruction(DataSize.Bit32, instruction, out feedback32);
            string feedback64;

            byte[] bytes64 = GetEncodedInstruction(DataSize.Bit64, instruction, out feedback64);

            string methodName = spec.Mnemonic.ToUpperInvariant();

            if (variant.Operands.Any())
            {
                methodName += "_" + string.Join("_", from o in variant.Operands.Cast <X86OperandSpec>()
                                                select IdentifierValidation.Replace(GetOperandManualName(o), ""));
            }

            writer.WriteLine(T + T + "[Test]");
            writer.WriteLine(T + T + "public void {0}()", AsValidIdentifier(methodName));
            writer.WriteLine(T + T + "{");
            writer.WriteLine(T + T + T + "var instruction = Instr.{0}({1});", AsValidIdentifier(spec.Name), operands);
            writer.WriteLine();
            writer.WriteLine(T + T + T + "// " + instruction);
            if (bytes16 != null)
            {
                writer.WriteLine(T + T + T + "AssertInstruction(instruction, DataSize.Bit16, new byte[] { " +
                                 string.Join(", ", from b in bytes16 select string.Format("0x{0:X2}", b)) + " });");
            }
            else
            {
                writer.WriteLine(T + T + T + "AssertInstructionFail(instruction, DataSize.Bit16);");
            }
            if (bytes32 != null)
            {
                writer.WriteLine(T + T + T + "AssertInstruction(instruction, DataSize.Bit32, new byte[] { " +
                                 string.Join(", ", from b in bytes32 select string.Format("0x{0:X2}", b)) + " });");
            }
            else
            {
                writer.WriteLine(T + T + T + "AssertInstructionFail(instruction, DataSize.Bit32);");
            }
            if (bytes64 != null)
            {
                writer.WriteLine(T + T + T + "AssertInstruction(instruction, DataSize.Bit64, new byte[] { " +
                                 string.Join(", ", from b in bytes64 select string.Format("0x{0:X2}", b)) + " });");
            }
            else
            {
                writer.WriteLine(T + T + T + "AssertInstructionFail(instruction, DataSize.Bit64);");
            }

            if (bytes16 == null && bytes32 == null && bytes64 == null)
            {
                throw new ScriptException(string.Format("Assembling {0} for the tests failed with the following messages:\n" +
                                                        "16-bit: {1}\n32-bit: {2}\n64-bit: {3}",
                                                        instruction, ProcessFeedback(feedback16), ProcessFeedback(feedback32), ProcessFeedback(feedback64)));
            }

            writer.WriteLine(T + T + "}");
        }