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; }
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(); } }
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(); } }
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; }