/// <summary> /// Gets the name of the operand as used in the manuals. /// </summary> /// <param name="operand">The operand.</param> /// <returns>The operand name.</returns> string GetOperandManualName(X86OperandSpec operand) { switch (operand.Type) { case X86OperandType.RegisterOperand: return("reg" + operand.Size.GetBitCount()); case X86OperandType.FixedRegister: return(Enum.GetName(typeof(Register), operand.FixedRegister).ToUpperInvariant()); case X86OperandType.Immediate: return("imm" + operand.Size.GetBitCount()); case X86OperandType.MemoryOperand: return("mem" + operand.Size.GetBitCount()); case X86OperandType.MemoryOffset: return("moffset" + operand.Size.GetBitCount()); case X86OperandType.FarPointer: return("pntr16:" + operand.Size.GetBitCount()); case X86OperandType.RegisterOrMemoryOperand: return("reg/mem" + operand.Size.GetBitCount()); case X86OperandType.RelativeOffset: return("rel" + operand.Size.GetBitCount() + "off"); default: throw new NotSupportedException("The operand type is not supported."); } }
/// <summary> /// Writes the operand descriptor. /// </summary> /// <param name="operand">The operand specification.</param> /// <param name="writer">The <see cref="TextWriter"/> to write to.</param> void WriteOperandDescriptor(X86OperandSpec operand, TextWriter writer) { string encodingStr = string.Empty; if (operand.Encoding != X86OperandEncoding.Default) { encodingStr = ", OperandEncoding." + Enum.GetName(typeof(X86OperandEncoding), operand.Encoding); } switch (operand.Type) { case X86OperandType.RegisterOperand: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.RegisterOperand, RegisterType.GeneralPurpose{0}Bit" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.FixedRegister: writer.Write(T + T + T + T + T + "new OperandDescriptor(Register.{0})", Enum.GetName(typeof(Register), operand.FixedRegister).ToUpperInvariant()); break; case X86OperandType.Immediate: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.Immediate, DataSize.Bit{0}" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.MemoryOperand: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.MemoryOperand, DataSize.Bit{0}" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.MemoryOffset: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.MemoryOffset, DataSize.Bit{0}" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.FarPointer: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.FarPointer, DataSize.Bit{0}" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.RegisterOrMemoryOperand: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.RegisterOrMemoryOperand, RegisterType.GeneralPurpose{0}Bit" + encodingStr + ")", operand.Size.GetBitCount()); break; case X86OperandType.RelativeOffset: writer.Write(T + T + T + T + T + "new OperandDescriptor(OperandType.RelativeOffset, DataSize.Bit{0}" + encodingStr + ")", operand.Size.GetBitCount()); break; default: throw new NotSupportedException("The operand type is not supported."); } }
/// <summary> /// Gets the arguments for the specified operand. /// </summary> /// <param name="operand">The operand.</param> /// <param name="clsCompliant">Whether the resulting method is CLS compliant.</param> /// <returns>An array of tuples. Each tuple specifies the type of the argument and the /// implementation as an operand. The latter uses <c>{0}</c> in place of the argument name.</returns> IEnumerable <Tuple <X86OperandSpec, string, string> > GetOperandArguments(X86OperandSpec operand) { switch (operand.Type) { case X86OperandType.Immediate: if (operand.Size == DataSize.Bit8) { return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "byte", "new Immediate({0}, DataSize.Bit8)"), new Tuple <X86OperandSpec, string, string>(operand, "sbyte", "new Immediate({0}, DataSize.Bit8)"), }); } else if (operand.Size == DataSize.Bit16) { return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "short", "new Immediate({0}, DataSize.Bit16)"), new Tuple <X86OperandSpec, string, string>(operand, "ushort", "new Immediate({0}, DataSize.Bit16)"), }); } else if (operand.Size == DataSize.Bit32) { return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "int", "new Immediate({0}, DataSize.Bit32)"), new Tuple <X86OperandSpec, string, string>(operand, "uint", "new Immediate({0}, DataSize.Bit32)"), }); } else if (operand.Size == DataSize.Bit64) { return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "long", "new Immediate({0}, DataSize.Bit64)"), new Tuple <X86OperandSpec, string, string>(operand, "ulong", "new Immediate({0}, DataSize.Bit64)"), }); } else { throw new NotSupportedException("The operand size is not supported."); } case X86OperandType.MemoryOperand: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "EffectiveAddress", "{0}"), }); case X86OperandType.MemoryOffset: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "MemoryOffset", "{0}"), }); case X86OperandType.FarPointer: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "FarPointer", "{0}"), new Tuple <X86OperandSpec, string, string>(operand, "EffectiveAddress", "{0}"), }); case X86OperandType.RegisterOrMemoryOperand: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "Register", "new RegisterOperand({0})"), new Tuple <X86OperandSpec, string, string>(operand, "EffectiveAddress", "{0}"), }); case X86OperandType.RelativeOffset: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "RelativeOffset", "{0}"), }); case X86OperandType.RegisterOperand: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "Register", "new RegisterOperand({0})"), }); case X86OperandType.FixedRegister: return(new Tuple <X86OperandSpec, string, string>[] { new Tuple <X86OperandSpec, string, string>(operand, "Register", "new RegisterOperand({0})"), }); //return Enumerable.Empty<Tuple<X86OperandSpec, String, String>>(); default: throw new NotSupportedException("The operand type is not supported."); } }
/// <inheritdoc /> public override OperandSpec CreateOperandSpec(string type, object defaultValue) { var operandSpec = new X86OperandSpec(); if (type.Equals("void")) { operandSpec.Type = X86OperandType.FixedRegister; operandSpec.FixedRegister = ToRegister(defaultValue); } else { DataSize size; if (type.EndsWith("128")) { size = DataSize.Bit128; type = type.Substring(0, type.Length - 3); } else if (type.EndsWith("64")) { size = DataSize.Bit64; type = type.Substring(0, type.Length - 2); } else if (type.EndsWith("32")) { size = DataSize.Bit32; type = type.Substring(0, type.Length - 2); } else if (type.EndsWith("16")) { size = DataSize.Bit16; type = type.Substring(0, type.Length - 2); } else if (type.EndsWith("8")) { size = DataSize.Bit8; type = type.Substring(0, type.Length - 1); } else { throw new ScriptException(string.Format("Malformatted type {0}", type)); } operandSpec.Size = size; switch (type) { case "reg/mem": operandSpec.Type = X86OperandType.RegisterOrMemoryOperand; break; case "reg": operandSpec.Type = X86OperandType.RegisterOperand; break; case "moffset": operandSpec.Type = X86OperandType.MemoryOffset; break; case "imm": operandSpec.Type = X86OperandType.Immediate; break; case "mem": operandSpec.Type = X86OperandType.MemoryOperand; break; case "reloff": operandSpec.Type = X86OperandType.RelativeOffset; break; case "pntr16:": operandSpec.Type = X86OperandType.FarPointer; break; default: throw new ScriptException(string.Format("Unknown operand type {0}", type)); } } return(operandSpec); }