public static string GetArithmeticOperation( TernaryArithmeticKind kind, ArithmeticBasicValueType type) { var key = (kind, type); return(TernaryArithmeticOperations[key]); }
/// <summary> /// Resolves a ternary arithmetic operation. /// </summary> /// <param name="kind">The arithmetic kind.</param> /// <param name="type">The operation type.</param> /// <returns>The resolved arithmetic operation.</returns> public static string GetArithmeticOperation( TernaryArithmeticKind kind, ArithmeticBasicValueType type) { if (TernaryArithmeticOperations.TryGetValue((kind, type), out string operation)) { return(operation); } throw new NotSupportedIntrinsicException(kind.ToString()); }
public static BinaryArithmeticKind GetRightBinaryKind(TernaryArithmeticKind kind) { switch (kind) { case TernaryArithmeticKind.MultiplyAdd: return(BinaryArithmeticKind.Add); default: throw new ArgumentOutOfRangeException(nameof(kind)); } }
/// <summary> /// Creates a ternary arithmetic operation. /// </summary> /// <param name="location">The current location.</param> /// <param name="first">The first operand.</param> /// <param name="second">The second operand.</param> /// <param name="third">The second operand.</param> /// <param name="kind">The operation kind.</param> /// <returns>A node that represents the arithmetic operation.</returns> public ValueReference CreateArithmetic( Location location, Value first, Value second, Value third, TernaryArithmeticKind kind) => CreateArithmetic( location, first, second, third, kind, ArithmeticFlags.None);
/// <summary> /// Constructs a new ternary arithmetic value. /// </summary> /// <param name="basicBlock">The parent basic block.</param> /// <param name="first">The first operand.</param> /// <param name="second">The second operand.</param> /// <param name="third">The third operand.</param> /// <param name="kind">The operation kind.</param> /// <param name="flags">The operation flags.</param> internal TernaryArithmeticValue( BasicBlock basicBlock, ValueReference first, ValueReference second, ValueReference third, TernaryArithmeticKind kind, ArithmeticFlags flags) : base( basicBlock, ImmutableArray.Create(first, second, third), flags, ComputeType(first)) { Debug.Assert( first.Type == second.Type && second.Type == third.Type, "Invalid types"); Kind = kind; }
/// <summary> /// Creates a ternary arithmetic operation. /// </summary> /// <param name="location">The current location.</param> /// <param name="first">The first operand.</param> /// <param name="second">The second operand.</param> /// <param name="third">The second operand.</param> /// <param name="kind">The operation kind.</param> /// <param name="flags">Operation flags.</param> /// <returns>A node that represents the arithmetic operation.</returns> public ValueReference CreateArithmetic( Location location, Value first, Value second, Value third, TernaryArithmeticKind kind, ArithmeticFlags flags) { if (UseConstantPropagation) { // Check for constants if (first is PrimitiveValue firstValue && second is PrimitiveValue secondValue) { var value = BinaryArithmeticFoldConstants( location, firstValue, secondValue, TernaryArithmeticValue.GetLeftBinaryKind(kind), flags); // Try to fold right hand side as well var rightOperation = TernaryArithmeticValue.GetRightBinaryKind(kind); return(CreateArithmetic( location, value, third, rightOperation)); } } return(Append(new TernaryArithmeticValue( GetInitializer(location), first, second, third, kind, flags))); }
/// <summary> /// Creates a ternary arithmetic operation. /// </summary> /// <param name="first">The first operand.</param> /// <param name="second">The second operand.</param> /// <param name="third">The second operand.</param> /// <param name="kind">The operation kind.</param> /// <param name="flags">Operation flags.</param> /// <returns>A node that represents the arithmetic operation.</returns> public ValueReference CreateArithmetic( Value first, Value second, Value third, TernaryArithmeticKind kind, ArithmeticFlags flags) { Debug.Assert(first != null, "Invalid first node"); Debug.Assert(second != null, "Invalid second node"); Debug.Assert(third != null, "Invalid third node"); if (UseConstantPropagation) { // Check for constants if (first is PrimitiveValue firstValue && second is PrimitiveValue secondValue) { var value = BinaryArithmeticFoldConstants( firstValue, secondValue, TernaryArithmeticValue.GetLeftBinaryKind(kind), flags); // Try to fold right hand side as well var rightOperation = TernaryArithmeticValue.GetRightBinaryKind(kind); return(CreateArithmetic(value, third, rightOperation)); } } return(Append(new TernaryArithmeticValue( BasicBlock, first, second, third, kind, flags))); }
/// <summary> /// Tries to resolve a ternary arithmetic operation. /// </summary> /// <param name="kind">The arithmetic kind.</param> /// <param name="isFloat">True, if this is a floating-point operation.</param> /// <param name="operation">The resolved operation.</param> /// <returns>True, if the operation could be resolved.</returns> public static bool TryGetArithmeticOperation( TernaryArithmeticKind kind, bool isFloat, out string operation) => TernaryArithmeticOperations.TryGetValue((kind, isFloat), out operation);