@@ -161,7 +161,7 @@ interface IArithmetic : IComparable
161
161
162
162
__init(int val);
163
163
164
- /// Initialize from the same type.
164
+ /// Initialize from the same type.
165
165
__init(This value);
166
166
}
167
167
@@ -2484,47 +2484,52 @@ ${{{{
2484
2484
2485
2485
for (auto op : intrinsicUnaryOps)
2486
2486
{
2487
- for (auto type : kBaseTypes )
2487
+ if ( ! op . interface )
2488
2488
{
2489
- if ((type .flags & op .flags ) == 0 )
2490
- continue ;
2489
+ for (auto type : kBaseTypes )
2490
+ {
2491
+ if ((type .flags & op .flags ) == 0 )
2492
+ continue ;
2491
2493
2492
- char const * resultType = type .name ;
2493
- if (op .flags & BOOL_RESULT) resultType = " bool" ;
2494
+ char const * resultType = type .name ;
2495
+ if (op .flags & BOOL_RESULT) resultType = " bool" ;
2494
2496
2495
- // scalar version
2496
- sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << type .name << " value);\n " ;
2497
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " __" << op .funcName << " (" << type .name << " value);\n " ;
2497
+ // scalar version
2498
+ sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << type .name << " value);\n " ;
2499
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " __" << op .funcName << " (" << type .name << " value);\n " ;
2498
2500
2499
- // vector version
2500
- sb << " __generic<let N : int> " ;
2501
- sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (" << " vector<" << type .name << " ,N> value);\n " ;
2501
+ // vector version
2502
+ sb << " __generic<let N : int> " ;
2503
+ sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (" << " vector<" << type .name << " ,N> value);\n " ;
2502
2504
2503
- // matrix version
2504
- sb << " __generic<let N : int, let M : int> " ;
2505
- sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (" << " matrix<" << type .name << " ,N,M> value);\n " ;
2505
+ // matrix version
2506
+ sb << " __generic<let N : int, let M : int, let L : int> " ;
2507
+ sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L> operator" << op .opName << " (" << " matrix<" << type .name << " ,N,M,L> value);\n " ;
2508
+ }
2506
2509
}
2507
-
2508
- // Synthesize generic versions
2509
- if (op .interface )
2510
+ else
2510
2511
{
2512
+ // Synthesize generic versions
2511
2513
char const * resultType = " T" ;
2512
2514
if (op .flags & BOOL_RESULT) resultType = " bool" ;
2513
2515
2514
2516
// scalar version
2515
2517
sb << " __generic<T : " << op .interface << " >\n " ;
2516
2518
sb << " [OverloadRank(10)]" ;
2517
- sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << " T value);\n " ;
2519
+ sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (T value);\n " ;
2520
+
2521
+ sb << " __generic<T : " << op .interface << " >\n " ;
2522
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " __" << op .funcName << " (T value);\n " ;
2518
2523
2519
2524
// vector version
2520
2525
sb << " __generic<T : " << op .interface << " , let N : int> " ;
2521
2526
sb << " [OverloadRank(10)]" ;
2522
2527
sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<T,N> value);\n " ;
2523
2528
2524
2529
// matrix version
2525
- sb << " __generic<T : " << op .interface << " , let N : int, let M : int> " ;
2530
+ sb << " __generic<T : " << op .interface << " , let N : int, let M : int, let L : int > " ;
2526
2531
sb << " [OverloadRank(10)]" ;
2527
- sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (matrix<T,N,M> value);\n " ;
2532
+ sb << " __prefix __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L > operator" << op .opName << " (matrix<T,N,M,L > value);\n " ;
2528
2533
}
2529
2534
}
2530
2535
@@ -2612,7 +2617,7 @@ vector<T,N> operator$(op.name)(in out vector<T,N> value)
2612
2617
$(fixity .qual )
2613
2618
__generic < T : __BuiltinArithmeticType, let R : int , let C : int , let L : int >
2614
2619
[__unsafeForceInlineEarly]
2615
- matrix< T,R,C> operator$(op .name )(in out matrix< T,R,C,L> value)
2620
+ matrix< T,R,C,L > operator$(op .name )(in out matrix< T,R,C,L> value)
2616
2621
{$(fixity .bodyPrefix ) value = value $(op .binOp ) T(1 ); return $(fixity .returnVal ); }
2617
2622
2618
2623
$(fixity .qual )
@@ -2626,90 +2631,91 @@ ${{{{
2626
2631
2627
2632
for (auto op : intrinsicBinaryOps)
2628
2633
{
2629
- for (auto type : kBaseTypes )
2634
+ if ( ! op . interface )
2630
2635
{
2631
- if ((type .flags & op .flags ) == 0 )
2632
- continue ;
2633
-
2634
- char const * leftType = type .name ;
2635
- char const * rightType = leftType;
2636
- char const * resultType = leftType;
2637
-
2638
- if (op .flags & BOOL_RESULT) resultType = " bool" ;
2639
-
2640
- // TODO: We should handle a `SHIFT` flag on the op
2641
- // by changing `rightType` to `int` in order to
2642
- // account for the fact that the shift amount should
2643
- // always have a fixed type independent of the LHS.
2644
- //
2645
- // (It is unclear why this change hadn't been made
2646
- // already, so it is possible that such a change
2647
- // breaks overload resolution or other parts of
2648
- // the compiler)
2649
-
2650
- // scalar version
2651
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << leftType << " left, " << rightType << " right);\n " ;
2652
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " __" << op .funcName << " (" << leftType << " left, " << rightType << " right);\n " ;
2653
-
2654
- // vector version
2655
- sb << " __generic<let N : int> " ;
2656
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, vector<" << rightType << " ,N> right);\n " ;
2657
-
2658
- // matrix version
2659
- sb << " __generic<let N : int, let M : int> " ;
2660
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (matrix<" << leftType << " ,N,M> left, matrix<" << rightType << " ,N,M> right);\n " ;
2661
-
2662
- // We currently synthesize addiitonal overloads
2663
- // for the case where one or the other operand
2664
- // is a scalar. This choice serves a few purposes:
2665
- //
2666
- // 1. It avoids introducing scalar-to-vector or
2667
- // scalar-to-matrix promotions before the operator,
2668
- // which might allow some back ends to produce
2669
- // more optimal code.
2670
- //
2671
- // 2. It avoids concerns about making overload resolution
2672
- // and the inference rules for `N` and `M` able to
2673
- // handle the mixed vector/scalar or matrix/scalar case.
2674
- //
2675
- // 3. Having explicit overloads for the matrix/scalar cases
2676
- // here means that we do *not* need to support a general
2677
- // implicit conversion from scalars to matrices, unless
2678
- // we decide we want to.
2679
- //
2680
- // Note: Case (2) of the motivation shouldn't really apply
2681
- // any more, because we end up having to support similar
2682
- // inteference for built-in binary math functions where
2683
- // vectors and scalars might be combined (and where defining
2684
- // additional overloads to cover all the combinations doesn't
2685
- // seem practical or desirable).
2686
- //
2687
- // TODO: We should consider whether dropping these extra
2688
- // overloads is possible and worth it. The optimization
2689
- // concern (1) could possibly be addressed in specific
2690
- // back-ends. The issue (3) about not wanting to support
2691
- // implicit scalar-to-matrix conversion may be moot if
2692
- // we end up needing to support mixed scalar/matrix input
2693
- // for builtin in non-operator functions anyway.
2694
-
2695
- // scalar-vector and scalar-matrix
2696
- sb << " __generic<let N : int> " ;
2697
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (" << leftType << " left, vector<" << rightType << " ,N> right);\n " ;
2698
-
2699
- sb << " __generic<let N : int, let M : int> " ;
2700
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (" << leftType << " left, matrix<" << rightType << " ,N,M> right);\n " ;
2701
-
2702
- // vector-scalar and matrix-scalar
2703
- sb << " __generic<let N : int> " ;
2704
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, " << rightType << " right);\n " ;
2705
-
2706
- sb << " __generic<let N : int, let M : int> " ;
2707
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (matrix<" << leftType << " ,N,M> left, " << rightType << " right);\n " ;
2636
+ for (auto type : kBaseTypes )
2637
+ {
2638
+ if ((type .flags & op .flags ) == 0 )
2639
+ continue ;
2640
+
2641
+ char const * leftType = type .name ;
2642
+ char const * rightType = leftType;
2643
+ char const * resultType = leftType;
2644
+
2645
+ if (op .flags & BOOL_RESULT) resultType = " bool" ;
2646
+
2647
+ // TODO: We should handle a `SHIFT` flag on the op
2648
+ // by changing `rightType` to `int` in order to
2649
+ // account for the fact that the shift amount should
2650
+ // always have a fixed type independent of the LHS.
2651
+ //
2652
+ // (It is unclear why this change hadn't been made
2653
+ // already, so it is possible that such a change
2654
+ // breaks overload resolution or other parts of
2655
+ // the compiler)
2656
+
2657
+ // scalar version
2658
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << leftType << " left, " << rightType << " right);\n " ;
2659
+
2660
+ // vector version
2661
+ sb << " __generic<let N : int> " ;
2662
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, vector<" << rightType << " ,N> right);\n " ;
2663
+
2664
+ // matrix version
2665
+ sb << " __generic<let N : int, let M : int, let L : int> " ;
2666
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L> operator" << op .opName << " (matrix<" << leftType << " ,N,M,L> left, matrix<" << rightType << " ,N,M,L> right);\n " ;
2667
+
2668
+ // We currently synthesize addiitonal overloads
2669
+ // for the case where one or the other operand
2670
+ // is a scalar. This choice serves a few purposes:
2671
+ //
2672
+ // 1. It avoids introducing scalar-to-vector or
2673
+ // scalar-to-matrix promotions before the operator,
2674
+ // which might allow some back ends to produce
2675
+ // more optimal code.
2676
+ //
2677
+ // 2. It avoids concerns about making overload resolution
2678
+ // and the inference rules for `N` and `M` able to
2679
+ // handle the mixed vector/scalar or matrix/scalar case.
2680
+ //
2681
+ // 3. Having explicit overloads for the matrix/scalar cases
2682
+ // here means that we do *not* need to support a general
2683
+ // implicit conversion from scalars to matrices, unless
2684
+ // we decide we want to.
2685
+ //
2686
+ // Note: Case (2) of the motivation shouldn't really apply
2687
+ // any more, because we end up having to support similar
2688
+ // inteference for built-in binary math functions where
2689
+ // vectors and scalars might be combined (and where defining
2690
+ // additional overloads to cover all the combinations doesn't
2691
+ // seem practical or desirable).
2692
+ //
2693
+ // TODO: We should consider whether dropping these extra
2694
+ // overloads is possible and worth it. The optimization
2695
+ // concern (1) could possibly be addressed in specific
2696
+ // back-ends. The issue (3) about not wanting to support
2697
+ // implicit scalar-to-matrix conversion may be moot if
2698
+ // we end up needing to support mixed scalar/matrix input
2699
+ // for builtin in non-operator functions anyway.
2700
+
2701
+ // scalar-vector and scalar-matrix
2702
+ sb << " __generic<let N : int> " ;
2703
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (" << leftType << " left, vector<" << rightType << " ,N> right);\n " ;
2704
+
2705
+ sb << " __generic<let N : int, let M : int, let L : int> " ;
2706
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L> operator" << op .opName << " (" << leftType << " left, matrix<" << rightType << " ,N,M,L> right);\n " ;
2707
+
2708
+ // vector-scalar and matrix-scalar
2709
+ sb << " __generic<let N : int> " ;
2710
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, " << rightType << " right);\n " ;
2711
+
2712
+ sb << " __generic<let N : int, let M : int, let L : int> " ;
2713
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L> operator" << op .opName << " (matrix<" << leftType << " ,N,M,L> left, " << rightType << " right);\n " ;
2714
+ }
2708
2715
}
2709
-
2710
- // Synthesize generic versions
2711
- if (op .interface )
2716
+ else
2712
2717
{
2718
+ // Synthesize generic versions
2713
2719
char const * leftType = " T" ;
2714
2720
char const * rightType = leftType;
2715
2721
char const * resultType = leftType;
@@ -2721,34 +2727,37 @@ for (auto op : intrinsicBinaryOps)
2721
2727
sb << " __generic<T : " << op .interface << " >\n " ;
2722
2728
sb << " [OverloadRank(10)]" ;
2723
2729
sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " operator" << op .opName << " (" << leftType << " left, " << rightType << " right);\n " ;
2730
+
2731
+ sb << " __generic<T : " << op .interface << " >\n " ;
2732
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) " << resultType << " __" << op .funcName << " (" << leftType << " left, " << rightType << " right);\n " ;
2724
2733
2725
2734
// vector version
2726
2735
sb << " __generic<T : " << op .interface << " , let N : int> " ;
2727
2736
sb << " [OverloadRank(10)]" ;
2728
2737
sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, vector<" << rightType << " ,N> right);\n " ;
2729
2738
2730
2739
// matrix version
2731
- sb << " __generic<T : " << op .interface << " , let N : int, let M : int> " ;
2740
+ sb << " __generic<T : " << op .interface << " , let N : int, let M : int, let L : int > " ;
2732
2741
sb << " [OverloadRank(10)]" ;
2733
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (matrix<" << leftType << " ,N,M> left, matrix<" << rightType << " ,N,M> right);\n " ;
2742
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L > operator" << op .opName << " (matrix<" << leftType << " ,N,M,L > left, matrix<" << rightType << " ,N,M,L > right);\n " ;
2734
2743
2735
2744
// scalar-vector and scalar-matrix
2736
2745
sb << " __generic<T : " << op .interface << " , let N : int> " ;
2737
2746
sb << " [OverloadRank(10)]" ;
2738
2747
sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (" << leftType << " left, vector<" << rightType << " ,N> right);\n " ;
2739
2748
2740
- sb << " __generic<T : " << op .interface << " , let N : int, let M : int> " ;
2749
+ sb << " __generic<T : " << op .interface << " , let N : int, let M : int, let L: int > " ;
2741
2750
sb << " [OverloadRank(10)]" ;
2742
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (" << leftType << " left, matrix<" << rightType << " ,N,M> right);\n " ;
2751
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L > operator" << op .opName << " (" << leftType << " left, matrix<" << rightType << " ,N,M,L > right);\n " ;
2743
2752
2744
2753
// vector-scalar and matrix-scalar
2745
2754
sb << " __generic<T : " << op .interface << " , let N : int> " ;
2746
2755
sb << " [OverloadRank(10)]" ;
2747
2756
sb << " __intrinsic_op(" << int (op .opCode ) << " ) vector<" << resultType << " ,N> operator" << op .opName << " (vector<" << leftType << " ,N> left, " << rightType << " right);\n " ;
2748
2757
2749
- sb << " __generic<T : " << op .interface << " , let N : int, let M : int> " ;
2758
+ sb << " __generic<T : " << op .interface << " , let N : int, let M : int, let L : int > " ;
2750
2759
sb << " [OverloadRank(10)]" ;
2751
- sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M> operator" << op .opName << " (matrix<" << leftType << " ,N,M> left, " << rightType << " right);\n " ;
2760
+ sb << " __intrinsic_op(" << int (op .opCode ) << " ) matrix<" << resultType << " ,N,M,L > operator" << op .opName << " (matrix<" << leftType << " ,N,M,L > left, " << rightType << " right);\n " ;
2752
2761
}
2753
2762
}
2754
2763
@@ -2888,17 +2897,17 @@ ${{{{
2888
2897
return left;
2889
2898
}
2890
2899
2891
- __generic < T : $(op .interface ), let R : int , let C : int , let Layout : int >
2900
+ __generic < T : $(op .interface ), let R : int , let C : int , let L : int >
2892
2901
[__unsafeForceInlineEarly]
2893
- matrix< T,R,C> operator$(op .name )= (in out matrix< T,R,C,Layout > left, matrix< T,R,C> right)
2902
+ matrix< T,R,C,L > operator$(op .name )= (in out matrix< T,R,C,L > left, matrix< T,R,C,L > right)
2894
2903
{
2895
2904
left = left $(op .name ) right;
2896
2905
return left;
2897
2906
}
2898
2907
2899
- __generic < T : $(op .interface ), let R : int , let C : int , let Layout : int >
2908
+ __generic < T : $(op .interface ), let R : int , let C : int , let L : int >
2900
2909
[__unsafeForceInlineEarly]
2901
- matrix< T,R,C> operator$(op .name )= (in out matrix< T,R,C, Layout > left, T right)
2910
+ matrix< T,R,C,L > operator$(op .name )= (in out matrix< T,R,C,L > left, T right)
2902
2911
{
2903
2912
left = left $(op .name ) right;
2904
2913
return left;
0 commit comments