/// <inheritdoc /> protected override void WriteCodeOpcodeClassProperties(OpcodeSpec spec, TextWriter writer) { X86OpcodeSpec x86spec = (X86OpcodeSpec)spec; WriteCanLock(x86spec, writer); base.WriteCodeOpcodeClassProperties(spec, writer); }
/// <summary> /// Writes the <c>CanLock</c> property. /// </summary> /// <param name="spec">The opcode specification.</param> /// <param name="writer">The <see cref="TextWriter"/> to write to.</param> protected void WriteCanLock(X86OpcodeSpec spec, TextWriter writer) { if (!spec.CanLock) { return; } writer.WriteLine(T + T + "/// <inheritdoc />"); writer.WriteLine(T + T + "public override bool CanLock"); writer.WriteLine(T + T + "{"); writer.WriteLine(T + T + T + "get { return true; }"); writer.WriteLine(T + T + "}"); writer.WriteLine(); }
/// <summary> /// Writes a single opcode variant method. /// </summary> /// <param name="spec">The opcode specification.</param> /// <param name="mnemonic">The mnemonic to use.</param> /// <param name="operands">The operands.</param> /// <param name="writer">The <see cref="TextWriter"/> to write to.</param> void WriteCodeInstrOpcodeVariantMethod(X86OpcodeSpec spec, string mnemonic, IEnumerable <Tuple <X86OperandSpec, string, string> > operands, TextWriter writer) { WriteCodeInstrOpcodeVariantMethodDocumentation(spec, operands, writer); var operandsString = string.Join(", ", operands.Select(o => o.Item2 + " " + AsValidIdentifier(o.Item1.Name))); writer.WriteLine(T + T + "public static X86Instruction {0}({1})", AsValidIdentifier(mnemonic), operandsString); var argumentsString = string.Join(", ", operands.Select(o => string.Format(o.Item3, AsValidIdentifier(o.Item1.Name)))); writer.WriteLine(T + T + "{"); writer.WriteLine(T + T + T + "return X86Opcode.{0}.CreateInstruction({1});", AsValidIdentifier(spec.Name), argumentsString); writer.WriteLine(T + T + "}"); }
/// <summary> /// Writes the documentation for the opcode variant method. /// </summary> /// <param name="spec">The opcode specification.</param> /// <param name="variant">The opcode variant.</param> /// <param name="writer">The <see cref="TextWriter"/> to write to.</param> protected void WriteCodeInstrOpcodeVariantMethodDocumentation(X86OpcodeSpec spec, IEnumerable <Tuple <X86OperandSpec, string, string> > operands, TextWriter writer) { writer.WriteLine(T + T + "/// <summary>"); writer.WriteLine(T + T + "/// Creates a new {0} ({1}) instruction.", spec.Mnemonic.ToUpperInvariant(), spec.ShortDescription); writer.WriteLine(T + T + "/// </summary>"); foreach (var operand in operands) { WriteOperandDocumentation(operand, writer); } writer.WriteLine(T + T + "/// <returns>The created instruction.</returns>"); }
/// <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 + "}"); }