Example #1
0
        public static string GetArithmeticOperation(
            TernaryArithmeticKind kind,
            ArithmeticBasicValueType type)
        {
            var key = (kind, type);

            return(TernaryArithmeticOperations[key]);
        }
Example #2
0
 /// <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());
 }
Example #3
0
        public static BinaryArithmeticKind GetRightBinaryKind(TernaryArithmeticKind kind)
        {
            switch (kind)
            {
            case TernaryArithmeticKind.MultiplyAdd:
                return(BinaryArithmeticKind.Add);

            default:
                throw new ArgumentOutOfRangeException(nameof(kind));
            }
        }
Example #4
0
 /// <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);
Example #5
0
        /// <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;
        }
Example #6
0
        /// <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)));
        }
Example #7
0
        /// <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)));
        }
Example #8
0
 /// <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);