/// <summary> /// Writes the opcode variant specification in the variants array. /// </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 abstract void WriteCodeOpcodeVariant(OpcodeSpec spec, OpcodeVariantSpec variant, TextWriter writer);
/// <inheritdoc /> protected override void WriteCodeOpcodeVariant(OpcodeSpec spec, OpcodeVariantSpec variant, TextWriter writer) { var x86variant = (X86OpcodeVariantSpec)variant; var operands = x86variant.Operands.Cast <X86OperandSpec>(); var operandNames = from o in operands select GetOperandManualName(o); writer.Write(T + T + T + T + "// {0}", spec.Mnemonic.ToUpperInvariant()); if (operandNames.Any()) { writer.WriteLine(" {0}", string.Join(", ", operandNames)); } else { writer.WriteLine(); } writer.WriteLine(T + T + T + T + "new X86OpcodeVariant("); string opcodeBytes = string.Join(", ", from b in x86variant.OpcodeBytes select string.Format("0x{0:X2}", b)); writer.Write(T + T + T + T + T + "new byte[] {{ {0} }}", opcodeBytes); // Either the fixed REG is not 0, or the opcode has a spot for the REG available as it uses the // ModRM byte (because it has a reg/mem operand) but does not specify the REG part (because it does not // have a reg operand), or the OperandSize is specified, which requires the REG also to be specified. if (x86variant.FixedReg != 0 || (x86variant.OperandSize != DataSize.None && operands.Any()) || (operands.Any(o => o.Type == X86OperandType.RegisterOrMemoryOperand) && !operands.Any(o => o.Type == X86OperandType.RegisterOperand))) { writer.Write(", {0}", x86variant.FixedReg); } if (x86variant.OperandSize != DataSize.None) { writer.Write(", DataSize.{0}", Enum.GetName(typeof(DataSize), x86variant.OperandSize)); } foreach (var operand in operands) { writer.WriteLine(","); WriteOperandDescriptor(operand, writer); } writer.Write(")"); if (x86variant.NoRexPrefix || x86variant.SupportedModes != ProcessorModes.LongProtectedReal) { writer.WriteLine(); writer.Write(T + T + T + T + T + "{ "); List <string> properties = new List <string>(); if (x86variant.NoRexPrefix) { properties.Add("NoRexPrefix = true"); } if (x86variant.SupportedModes != ProcessorModes.LongProtectedReal) { properties.Add("SupportedModes = ProcessorModes." + Enum.GetName(typeof(ProcessorModes), x86variant.SupportedModes)); } writer.Write(string.Join(", ", properties)); writer.Write(" }"); } writer.WriteLine(","); }