예제 #1
0
 /// <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);
예제 #2
0
        /// <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(",");
        }