Пример #1
0
        private static ConversionTypes ClassifyTypeConversion(IntrinsicNumericTypeSymbol numericSourceType, IntrinsicNumericTypeSymbol numericTargetType)
        {
            var parameterScalarType = numericTargetType.ScalarType;
            var argumentScalarType = numericSourceType.ScalarType;

            if (argumentScalarType.IsFloat() && !parameterScalarType.IsFloat())
                return ConversionTypes.FloatToIntConversion;

            if (!argumentScalarType.IsFloat() && parameterScalarType.IsFloat())
                return ConversionTypes.IntToFloatConversion;

            switch (argumentScalarType)
            {
                case ScalarType.Float:
                    switch (parameterScalarType)
                    {
                        case ScalarType.Half:
                            return ConversionTypes.FloatTruncation;
                        case ScalarType.Double:
                            return ConversionTypes.FloatPromotion;
                    }
                    break;
                case ScalarType.Half:
                    switch (parameterScalarType)
                    {
                        case ScalarType.Float:
                        case ScalarType.Double:
                            return ConversionTypes.FloatPromotion;
                    }
                    break;
                case ScalarType.Double:
                    switch (parameterScalarType)
                    {
                        case ScalarType.Half:
                        case ScalarType.Float:
                            return ConversionTypes.FloatTruncation;
                    }
                    break;
                case ScalarType.Bool:
                    if (parameterScalarType != ScalarType.Bool)
                        return ConversionTypes.IntToFloatConversion;
                    break;
                case ScalarType.Int:
                    if (parameterScalarType == ScalarType.Uint)
                        return ConversionTypes.SignedToUnsigned;
                    break;
                case ScalarType.Uint:
                    if (parameterScalarType == ScalarType.Int)
                        return ConversionTypes.UnsignedToSigned;
                    break;
            }

            if (argumentScalarType != parameterScalarType)
                return ConversionTypes.SignedToUnsigned; // TODO: Check this. Int/Uint => Bool?

            return ConversionTypes.None;
        }
Пример #2
0
        internal static IntrinsicNumericTypeSymbol GetNumericTypeWithScalarType(this IntrinsicNumericTypeSymbol type, ScalarType scalarType)
        {
            switch (type.Kind)
            {
            case SymbolKind.IntrinsicMatrixType:
                var matrixType = (IntrinsicMatrixTypeSymbol)type;
                return(IntrinsicTypes.GetMatrixType(scalarType, matrixType.Rows, matrixType.Cols));

            case SymbolKind.IntrinsicScalarType:
                return(IntrinsicTypes.GetScalarType(scalarType));

            case SymbolKind.IntrinsicVectorType:
                return(IntrinsicTypes.GetVectorType(scalarType, ((IntrinsicVectorTypeSymbol)type).NumComponents));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #3
0
        internal static int GetDimensionSize(this IntrinsicNumericTypeSymbol type, int dimension)
        {
            switch (type.Kind)
            {
            case SymbolKind.IntrinsicMatrixType:
                var matrixType = (IntrinsicMatrixTypeSymbol)type;
                return(dimension == 0 ? matrixType.Rows : matrixType.Cols);

            case SymbolKind.IntrinsicVectorType:
                var vectorType = (IntrinsicVectorTypeSymbol)type;
                return(dimension == 0 ? vectorType.NumComponents : 1);

            case SymbolKind.IntrinsicScalarType:
                return(1);

            default:
                throw new InvalidOperationException();
            }
        }
Пример #4
0
        private static ConversionTypes ClassifyDimensionConversion(IntrinsicNumericTypeSymbol sourceType, IntrinsicNumericTypeSymbol targetType)
        {
            var targetDim0 = targetType.GetDimensionSize(0);
            var targetDim1 = targetType.GetDimensionSize(1);
            var sourceDim0 = sourceType.GetDimensionSize(0);
            var sourceDim1 = sourceType.GetDimensionSize(1);

            if ((sourceDim0 == targetDim0 && sourceDim1 == targetDim1) || (sourceDim1 == targetDim0 && sourceDim0 == targetDim1))
            {
                switch (sourceType.Kind)
                {
                    case SymbolKind.IntrinsicMatrixType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicVectorType: // float1x1 => float1
                            case SymbolKind.IntrinsicScalarType: // float1x1 => float
                                return ConversionTypes.SameSizeTruncation;
                        }
                        break;
                    case SymbolKind.IntrinsicVectorType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicMatrixType: // float1 => float1x1
                                return ConversionTypes.SameSizePromotion;
                            case SymbolKind.IntrinsicScalarType: // float1 => float
                                return ConversionTypes.SameSizeTruncation;
                        }
                        break;
                    case SymbolKind.IntrinsicScalarType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicMatrixType: // float => float1x1
                            case SymbolKind.IntrinsicVectorType: // float => float1
                                return ConversionTypes.SameSizePromotion;
                        }
                        break;
                }
            }
            else if ((sourceDim0 == targetDim1 && sourceDim1 == targetDim0) || (sourceDim1 == targetDim0 && sourceDim0 == targetDim1))
            {
                switch (sourceType.Kind)
                {
                    case SymbolKind.IntrinsicMatrixType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicVectorType: // float3x1 => float1
                                return ConversionTypes.DimensionTruncation;
                        }
                        break;
                    case SymbolKind.IntrinsicVectorType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicMatrixType: // float3 => float3x1
                                return ConversionTypes.ScalarPromotion;
                        }
                        break;
                }
            }
            else if (sourceDim0 == 1 && sourceDim1 == 1)
            {
                // float => float2x4
                // float => float2
                // float1 => float2
                return ConversionTypes.ScalarPromotion;
            }
            else if ((sourceDim0 >= targetDim0 && sourceDim1 >= targetDim1) || (sourceDim1 >= targetDim0 && sourceDim0 >= targetDim1))
            {
                switch (sourceType.Kind)
                {
                    case SymbolKind.IntrinsicMatrixType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicMatrixType:
                                if (sourceDim0 > targetDim0 && sourceDim1 > targetDim1) // float4x4 => float3x3
                                    return ConversionTypes.RankTruncation2;
                                if (sourceDim0 > targetDim0 || sourceDim1 > targetDim1) // float4x4 => float4x3
                                    return ConversionTypes.RankTruncation;
                                return ConversionTypes.None;
                            case SymbolKind.IntrinsicVectorType: // float4x4 => float3
                                return ConversionTypes.RankTruncation2;
                            case SymbolKind.IntrinsicScalarType: // float3x4 => float
                                return ConversionTypes.RankTruncation2;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                    case SymbolKind.IntrinsicVectorType:
                        switch (targetType.Kind)
                        {
                            case SymbolKind.IntrinsicMatrixType: // float4 => float4x3
                                return ConversionTypes.RankTruncation;
                            case SymbolKind.IntrinsicVectorType: // float4 => float3
                                return ConversionTypes.RankTruncation2;
                            case SymbolKind.IntrinsicScalarType: // float4 => float
                                return ConversionTypes.RankTruncation2;
                            default:
                                throw new ArgumentOutOfRangeException();
                        }
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

            return ConversionTypes.None;
        }