/// <summary> /// Checks whether the specified object is valid to be assigned to /// the <see cref="OperandType"/>. /// </summary> /// <param name="operandType">A bitwise combination of <see cref="OperandType"/> members /// for which the operand must be valid.</param> /// <param name="registerType">A bitwise combination of <see cref="RegisterType"/> members /// for which the operand must be valid. The lower 8 bits are ignored.</param> /// <param name="operand">The <see cref="Operand"/> to check.</param> /// <returns><see langword="true"/> when an <paramref name="operand"/> may be assigned /// to an operand with the specified operand type and register type; otherwise, <see langword="false"/>.</returns> /// <remarks> /// When <paramref name="operand"/> is <see langword="null"/>, this method always returns <see langword="true"/> /// because there is no flag in <see cref="OperandType"/> to indicate that <see langword="null"/> operands are /// (dis)allowed. /// </remarks> public static bool IsValidArgument(OperandType operandType, RegisterType registerType, Operand operand) { // Null operands are implicitly allowed. if (operand == null) { return(true); } // Ignore the lower 8 bits. registerType = (RegisterType)((int)registerType & ~0xFF); // TODO: Implement. if (operandType.HasFlag(OperandType.MemoryOffset)) { throw new NotImplementedException(); } // Check the type of operand. if (operand is Immediate) { return(operandType.HasFlag(OperandType.Immediate)); } if (operand is EffectiveAddress) { return(operandType.HasFlag(OperandType.MemoryOperand) || operandType.HasFlag(OperandType.RegisterOrMemoryOperand)); } if (operand is RelativeOffset) { return(operandType.HasFlag(OperandType.RelativeOffset)); } if (operand is FarPointer) { return(operandType.HasFlag(OperandType.FarPointer)); } if (operand is RegisterOperand) { if (!operandType.HasFlag(OperandType.RegisterOperand) && !operandType.HasFlag(OperandType.FixedRegister) && !operandType.HasFlag(OperandType.RegisterOrMemoryOperand)) { return(false); } if (operandType.HasFlag(OperandType.FixedRegister)) { return(true); } // Check the type of register. return(registerType.HasFlag((RegisterType)((int)(operand as RegisterOperand).Register.GetRegisterType() & ~0xFF))); } return(false); }
public bool Match(Operand operand) { switch (operandType) { case OperandType.FixedRegister: { RegisterOperand castoperand = operand as RegisterOperand; if (castoperand != null) { return(castoperand.Register == fixedRegister); } return(false); } case OperandType.Immediate: { Immediate castoperand = operand as Immediate; if (castoperand != null) { return(castoperand.Size == DataSize.None || castoperand.Size == size); } return(false); } case OperandType.RegisterOperand: { RegisterOperand castoperand = operand as RegisterOperand; if (castoperand != null) { return(/*castoperand.Size == size &&*/ registerType.HasFlag(castoperand.Register.GetRegisterType())); } return(false); } case OperandType.RegisterOrMemoryOperand: { RegisterOperand castoperand1 = operand as RegisterOperand; EffectiveAddress castoperand2 = operand as EffectiveAddress; if (castoperand1 != null) { return(/*castoperand1.Size == size &&*/ registerType.HasFlag(castoperand1.Register.GetRegisterType())); } if (castoperand2 != null) { return(/*castoperand2.Size == size*/ registerType.HasFlag(castoperand2.Size)); } return(false); } case OperandType.MemoryOperand: { EffectiveAddress castoperand = operand as EffectiveAddress; if (castoperand != null) { return(castoperand.Size == size); } return(false); } case OperandType.MemoryOffset: // TODO: Implement! return(false); case OperandType.FarPointer: { FarPointer castoperand = operand as FarPointer; if (castoperand != null) { return(castoperand.Size == size); } return(false); } case OperandType.RelativeOffset: { // A relative offset matches when the Size of the operand // equals DataSize.None. The Size will be set when the // operand has been preprocessed, after which it is tested // again. RelativeOffset castoperand = operand as RelativeOffset; if (castoperand != null) { return(castoperand.Size == DataSize.None || castoperand.Size == size); } return(false); } case OperandType.None: return(operand == null); default: throw new NotSupportedException(); } }