[WHLSL] Make length, clamp, operator+, operator-, operator*, operator/, operator...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Aug 2019 18:01:16 +0000 (18:01 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Aug 2019 18:01:16 +0000 (18:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200700

Reviewed by Robin Morisset.

Source/WebCore:

This makes us 50% faster in compute_boids.

Tests: webgpu/whlsl/clamp-stdlib.html
       webgpu/whlsl/length-stdlib.html
       webgpu/whlsl/operator-div.html
       webgpu/whlsl/operator-minus.html
       webgpu/whlsl/operator-plus.html
       webgpu/whlsl/operator-times.html
       webgpu/whlsl/operator-vector-assign.html
       webgpu/whlsl/operator-vector-load.html
       webgpu/whlsl/operator-xy.html

* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::inlineNativeFunction):
* Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
* Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
(WebCore::WHLSL::includeStandardLibrary):

LayoutTests:

* webgpu/whlsl/clamp-stdlib-expected.txt: Added.
* webgpu/whlsl/clamp-stdlib.html: Added.
* webgpu/whlsl/length-stdlib-expected.txt: Added.
* webgpu/whlsl/length-stdlib.html: Added.
* webgpu/whlsl/operator-div-expected.txt: Added.
* webgpu/whlsl/operator-div.html: Added.
* webgpu/whlsl/operator-minus-expected.txt: Added.
* webgpu/whlsl/operator-minus.html: Added.
* webgpu/whlsl/operator-plus-expected.txt: Added.
* webgpu/whlsl/operator-plus.html: Added.
* webgpu/whlsl/operator-times-expected.txt: Added.
* webgpu/whlsl/operator-times.html: Added.
* webgpu/whlsl/operator-vector-assign-expected.txt: Added.
* webgpu/whlsl/operator-vector-assign.html: Added.
* webgpu/whlsl/operator-vector-load-expected.txt: Added.
* webgpu/whlsl/operator-vector-load.html: Added.
* webgpu/whlsl/operator-xy-expected.txt: Added.
* webgpu/whlsl/operator-xy.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248730 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/whlsl/clamp-stdlib-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/clamp-stdlib.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/length-stdlib-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/length-stdlib.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-div-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-div.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-minus-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-minus.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-plus-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-plus.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-times-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-times.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-vector-assign-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-vector-assign.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-vector-load-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-vector-load.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-xy-expected.txt [new file with mode: 0644]
LayoutTests/webgpu/whlsl/operator-xy.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp

index 25234c5..04511c4 100644 (file)
@@ -1,3 +1,29 @@
+2019-08-15  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Make length, clamp, operator+, operator-, operator*, operator/, operator[], operator[]=, operator.xy, operator.xy=, native
+        https://bugs.webkit.org/show_bug.cgi?id=200700
+
+        Reviewed by Robin Morisset.
+
+        * webgpu/whlsl/clamp-stdlib-expected.txt: Added.
+        * webgpu/whlsl/clamp-stdlib.html: Added.
+        * webgpu/whlsl/length-stdlib-expected.txt: Added.
+        * webgpu/whlsl/length-stdlib.html: Added.
+        * webgpu/whlsl/operator-div-expected.txt: Added.
+        * webgpu/whlsl/operator-div.html: Added.
+        * webgpu/whlsl/operator-minus-expected.txt: Added.
+        * webgpu/whlsl/operator-minus.html: Added.
+        * webgpu/whlsl/operator-plus-expected.txt: Added.
+        * webgpu/whlsl/operator-plus.html: Added.
+        * webgpu/whlsl/operator-times-expected.txt: Added.
+        * webgpu/whlsl/operator-times.html: Added.
+        * webgpu/whlsl/operator-vector-assign-expected.txt: Added.
+        * webgpu/whlsl/operator-vector-assign.html: Added.
+        * webgpu/whlsl/operator-vector-load-expected.txt: Added.
+        * webgpu/whlsl/operator-vector-load.html: Added.
+        * webgpu/whlsl/operator-xy-expected.txt: Added.
+        * webgpu/whlsl/operator-xy.html: Added.
+
 2019-08-15  Antti Koivisto  <antti@apple.com>
 
         Negative size box with border radius causes hang under WebCore::approximateAsRegion
diff --git a/LayoutTests/webgpu/whlsl/clamp-stdlib-expected.txt b/LayoutTests/webgpu/whlsl/clamp-stdlib-expected.txt
new file mode 100644 (file)
index 0000000..8ad5bda
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS vectorClamp 
+PASS matrixClamp 
+
diff --git a/LayoutTests/webgpu/whlsl/clamp-stdlib.html b/LayoutTests/webgpu/whlsl/clamp-stdlib.html
new file mode 100644 (file)
index 0000000..31f346b
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Clamp.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorClamp = async () => {
+    const program = `
+        float foo(float a, float b) {
+            float2 x;
+            x[0] = a;
+            x[1] = b;
+            float2 bottom = float2(1, 5);
+            float2 top = float2(10, 7);
+            x = clamp(x, bottom, top);
+            return x.x / x.y;
+        }
+    `;
+
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(12), makeFloat(20)]), 10 / 7, epsilon);
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(8), makeFloat(6)]), 8 / 6, epsilon);
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(-10), makeFloat(6)]), 1 / 6, epsilon);
+};
+
+whlslTests.matrixClamp = async () => {
+    const program = `
+        float foo(float a, float b, float c, float d) {
+            float2x2 x;
+            x[0] = float2(a, b);
+            x[1] = float2(c, d);
+
+            float2x2 bottom = float2x2(float2(1, 2), float2(3, 4));
+            float2x2 top = float2x2(float2(10, 11), float2(12, 13));
+
+            x = clamp(x, bottom, top);
+
+            return x[0][0] / 1 + x[0][1] / 2 + x[1][0] / 3 + x[1][1] / 4;
+        }
+    `;
+
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(2), makeFloat(-1), makeFloat(4), makeFloat(10)]), 2/1 + 2/2 + 4/3 + 10/4, epsilon);
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(100), makeFloat(100), makeFloat(100), makeFloat(100)]), 10/1 + 11/2 + 12/3 + 13/4, epsilon);
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(-100), makeFloat(-100), makeFloat(-100), makeFloat(-100)]), 1/1 + 2/2 + 3/3 + 4/4, epsilon);
+    assert_approx_equals(await callFloatFunction(program, "foo", [makeFloat(NaN), makeFloat(NaN), makeFloat(NaN), makeFloat(NaN)]), 1/1 + 2/2 + 3/3 + 4/4, epsilon);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/length-stdlib-expected.txt b/LayoutTests/webgpu/whlsl/length-stdlib-expected.txt
new file mode 100644 (file)
index 0000000..f49f5e1
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS vectorIndexAssign 
+
diff --git a/LayoutTests/webgpu/whlsl/length-stdlib.html b/LayoutTests/webgpu/whlsl/length-stdlib.html
new file mode 100644 (file)
index 0000000..d047444
--- /dev/null
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Length.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorIndexAssign = async () => {
+    const program = `
+        float foo(float a, float b) {
+            float2 x;
+            x[0] = a;
+            x[1] = b;
+            return length(x);
+        }
+    `;
+
+    const data = [
+        [NaN, 10],
+        [10, NaN],
+        [20, 10],
+        [0, 0],
+    ];
+
+    for (const [x, y] of data) {
+        const result = await callFloatFunction(program,  "foo", [makeFloat(x), makeFloat(y)]);
+        if (isNaN(x) || isNaN(y)) {
+            if (!isNaN(result))
+                throw new Error("Result should be NaN.");
+        } else
+            assert_approx_equals(result, Math.sqrt(x*x + y*y), epsilon);
+    }
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-div-expected.txt b/LayoutTests/webgpu/whlsl/operator-div-expected.txt
new file mode 100644 (file)
index 0000000..a208d95
--- /dev/null
@@ -0,0 +1,8 @@
+
+PASS vectorDiv 
+PASS vectorDivWithScalar 
+PASS vectorDivWithScalar2 
+PASS matrixDiv 
+PASS matrixDivScalar 
+PASS matrixDivScalar2 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-div.html b/LayoutTests/webgpu/whlsl/operator-div.html
new file mode 100644 (file)
index 0000000..7e6a9b9
--- /dev/null
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Div.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorDiv = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 30);
+            float2 y = float2(5, 10);
+            float2 r = x / y;
+            return r.x / r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 2/3, epsilon);
+};
+
+whlslTests.vectorDivWithScalar = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 25);
+            float2 r = x / 5.0;
+            return r.x / r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 2/5, epsilon);
+};
+
+whlslTests.vectorDivWithScalar2 = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 25);
+            float2 r = 100 / x;
+            return r.x / r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 10/4, epsilon);
+};
+
+whlslTests.matrixDiv = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            float2x2 m2;
+            m2[0] = float2(-1.0, -1.0);
+            m2[1] = float2(-1.0, -1.0);
+
+            m = m / m2;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixDivScalar = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = m / -1.0;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixDivScalar2 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(10, 20);
+            m[1] = float2(25, 50);
+
+            m = 100.0 / m;
+
+            if (m[0][0] == 10.0 && m[0][1] == 5.0 && m[1][0] == 4.0 && m[1][1] == 2.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-minus-expected.txt b/LayoutTests/webgpu/whlsl/operator-minus-expected.txt
new file mode 100644 (file)
index 0000000..c062678
--- /dev/null
@@ -0,0 +1,10 @@
+
+PASS vectorMinus 
+PASS vectorNegate 
+PASS vectorMinusScalar 
+PASS vectorMinusScalar2 
+PASS matrixMinus 
+PASS matrixMinusScalar 
+PASS matrixMinusScalar2 
+PASS matrixNegate 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-minus.html b/LayoutTests/webgpu/whlsl/operator-minus.html
new file mode 100644 (file)
index 0000000..7f00dd6
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Minus.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorMinus = async () => {
+    const program = `
+        int foo() {
+            int2 x = int2(10, 25);
+            int2 y = int2(20, 30);
+            int2 r = y - x;
+            return r.x / r.y;
+        }
+    `;
+    assert_equals(await callIntFunction(program,  "foo", []), 2);
+};
+
+whlslTests.vectorNegate = async () => {
+    const program = `
+        int foo() {
+            int2 x = int2(10, 25);
+            x = -x;
+            return x.x + x.y;
+        }
+    `;
+    assert_equals(await callIntFunction(program,  "foo", []), -35);
+};
+
+whlslTests.vectorMinusScalar = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10.0, 25.0);
+            x = x - 5.0;
+            return x.y / x.x;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program,  "foo", []), 20/5, epsilon);
+};
+
+whlslTests.vectorMinusScalar2 = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(-10.0, -25.0);
+            x = 5.0 - x;
+            return x.y / x.x;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program,  "foo", []), 30/15, epsilon);
+};
+
+whlslTests.matrixMinus = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+            m = m - m;
+            if (m[0][0] == 0 && m[0][1] == 0 && m[1][0] == 0 && m[1][1] == 0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixMinusScalar = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = m - 1.0;
+
+            if (m[0][0] == 19.0 && m[0][1] == 29.0 && m[1][0] == 39.0 && m[1][1] == 49.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixMinusScalar2 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = 0.0 - m;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixNegate = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = -m;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-plus-expected.txt b/LayoutTests/webgpu/whlsl/operator-plus-expected.txt
new file mode 100644 (file)
index 0000000..1e7ade2
--- /dev/null
@@ -0,0 +1,8 @@
+
+PASS vectorPlus 
+PASS vectorPlusScalar 
+PASS vectorPlusScalar2 
+PASS matrixPlus 
+PASS matrixTimesScalar 
+PASS matrixTimesScalar2 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-plus.html b/LayoutTests/webgpu/whlsl/operator-plus.html
new file mode 100644 (file)
index 0000000..6846be5
--- /dev/null
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Plus.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorPlus = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 25);
+            float2 y = float2(20, 30);
+            float2 r = y + x;
+            return r.x / r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 30/55, epsilon);
+};
+
+whlslTests.vectorPlusScalar = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 20);
+            float2 r = x + 10.0;
+            return r.y / r.x;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 30/20, epsilon);
+};
+
+whlslTests.vectorPlusScalar2 = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 20);
+            float2 r = 10.0 + x;
+            return r.y / r.x;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 30/20, epsilon);
+};
+
+whlslTests.matrixPlus = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+            float2x2 m2;
+            m2[0] = float2(-20, -30);
+            m2[1] = float2(-40, -50);
+            m = m + m2;
+            if (m[0][0] == 0 && m[0][1] == 0 && m[1][0] == 0 && m[1][1] == 0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixTimesScalar = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = m + 10.0;
+
+            if (m[0][0] == 30.0 && m[0][1] == 40.0 && m[1][0] == 50.0 && m[1][1] == 60.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixTimesScalar2 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = 10.0 + m;
+
+            if (m[0][0] == 30.0 && m[0][1] == 40.0 && m[1][0] == 50.0 && m[1][1] == 60.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-times-expected.txt b/LayoutTests/webgpu/whlsl/operator-times-expected.txt
new file mode 100644 (file)
index 0000000..e3a13f7
--- /dev/null
@@ -0,0 +1,8 @@
+
+PASS vectorTimes 
+PASS vectorTimesWithScalar 
+PASS vectorTimesWithScalar2 
+PASS matrixTimes 
+PASS matrixTimesScalar 
+PASS matrixTimesScalar2 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-times.html b/LayoutTests/webgpu/whlsl/operator-times.html
new file mode 100644 (file)
index 0000000..d647e02
--- /dev/null
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Times.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorTimes = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(2, 5);
+            float2 y = float2(3, 10);
+            float2 r = y * x;
+            return r.x / r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 6/50, epsilon);
+};
+
+whlslTests.vectorTimesWithScalar = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 20);
+            float2 r = x * 2.0;
+            return r.x * r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 20 * 40, epsilon);
+};
+
+whlslTests.vectorTimesWithScalar2 = async () => {
+    const program = `
+        float foo() {
+            float2 x = float2(10, 20);
+            float2 r = 2.0 * x;
+            return r.x * r.y;
+        }
+    `;
+    assert_approx_equals(await callFloatFunction(program, "foo", []), 20 * 40, epsilon);
+};
+
+whlslTests.matrixTimes = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            float2x2 m2;
+            m2[0] = float2(-1.0, -1.0);
+            m2[1] = float2(-1.0, -1.0);
+
+            m = m * m2;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixTimesScalar = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = m * -1.0;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+whlslTests.matrixTimesScalar2 = async () => {
+    const program = `
+        bool foo() {
+            float2x2 m;
+            m[0] = float2(20, 30);
+            m[1] = float2(40, 50);
+
+            m = -1.0 * m;
+
+            if (m[0][0] == -20.0 && m[0][1] == -30.0 && m[1][0] == -40.0 && m[1][1] == -50.0)
+                return true;
+            return false;
+        }
+    `;
+    assert_equals(await callBoolFunction(program,  "foo", []), true);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-vector-assign-expected.txt b/LayoutTests/webgpu/whlsl/operator-vector-assign-expected.txt
new file mode 100644 (file)
index 0000000..f49f5e1
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS vectorIndexAssign 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-vector-assign.html b/LayoutTests/webgpu/whlsl/operator-vector-assign.html
new file mode 100644 (file)
index 0000000..f2aa007
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test prefix/postfix.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorIndexAssign = async () => {
+    const program = `
+        int foo() {
+            int2 x;
+            x[0] = 20;
+            x[1] = 10;
+            x[5000] = 20;
+            return x.x / x.y + x[5000];
+        }
+    `;
+    assert_equals(await callIntFunction(program,  "foo", []), 2);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-vector-load-expected.txt b/LayoutTests/webgpu/whlsl/operator-vector-load-expected.txt
new file mode 100644 (file)
index 0000000..eee984b
--- /dev/null
@@ -0,0 +1,3 @@
+
+PASS vectorIndexLoad 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-vector-load.html b/LayoutTests/webgpu/whlsl/operator-vector-load.html
new file mode 100644 (file)
index 0000000..a650905
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test prefix/postfix.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.vectorIndexLoad = async () => {
+    const program = `
+        int foo() {
+            int2 x;
+            x.x = 20;
+            x.y = 10;
+            x[5000] = 20;
+            return x[0] / x[1] + x[5000];
+        }
+    `;
+    assert_equals(await callIntFunction(program,  "foo", []), 2);
+};
+
+runTests(whlslTests);
+</script>
+</html>
diff --git a/LayoutTests/webgpu/whlsl/operator-xy-expected.txt b/LayoutTests/webgpu/whlsl/operator-xy-expected.txt
new file mode 100644 (file)
index 0000000..f8ac9f0
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS operatorXY 
+PASS assignOperatorXY 
+
diff --git a/LayoutTests/webgpu/whlsl/operator-xy.html b/LayoutTests/webgpu/whlsl/operator-xy.html
new file mode 100644 (file)
index 0000000..37ca5a8
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>xy.</title>
+<script src="js/test-harness.js"></script>
+<script src="../js/webgpu-functions.js"></script>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+const epsilon = 0.0001;
+
+whlslTests.operatorXY = async () => {
+    const program = `
+        int foo() {
+            if (bool2(true, false).xy.x)
+                return 42;
+            return 0;
+        }
+        int bar() {
+            if (bool2(true, false).yx.y)
+                return 24;
+            return 0;
+        }
+        int baz() {
+            int2 x = int2(20, 10);
+            x = x.xy;
+            return x.x - x.y;
+        }
+    `;
+
+    assert_equals(await callIntFunction(program, "foo", []), 42);
+    assert_equals(await callIntFunction(program, "bar", []), 24);
+    assert_equals(await callIntFunction(program, "baz", []), 10);
+};
+
+whlslTests.assignOperatorXY = async () => {
+    const program = `
+        int foo(int a, int b) {
+            int2 x;
+            x.xy = int2(a, b);
+            return x.x - x.y;
+        }
+    `;
+
+    assert_equals(await callIntFunction(program, "foo", [makeInt(20), makeInt(10)]), 10);
+    assert_equals(await callIntFunction(program, "foo", [makeInt(10), makeInt(20)]), -10);
+};
+
+runTests(whlslTests);
+</script>
+</html>
index 4a140e8..f958e5b 100644 (file)
@@ -1,3 +1,28 @@
+2019-08-15  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Make length, clamp, operator+, operator-, operator*, operator/, operator[], operator[]=, operator.xy, operator.xy=, native
+        https://bugs.webkit.org/show_bug.cgi?id=200700
+
+        Reviewed by Robin Morisset.
+
+        This makes us 50% faster in compute_boids.
+
+        Tests: webgpu/whlsl/clamp-stdlib.html
+               webgpu/whlsl/length-stdlib.html
+               webgpu/whlsl/operator-div.html
+               webgpu/whlsl/operator-minus.html
+               webgpu/whlsl/operator-plus.html
+               webgpu/whlsl/operator-times.html
+               webgpu/whlsl/operator-vector-assign.html
+               webgpu/whlsl/operator-vector-load.html
+               webgpu/whlsl/operator-xy.html
+
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::inlineNativeFunction):
+        * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp:
+        (WebCore::WHLSL::includeStandardLibrary):
+
 2019-08-15  Robin Morisset  <rmorisset@apple.com>
 
         [WHLSL] Trivial clean-up of the MSL code generated
index d199d30..54946a0 100644 (file)
@@ -249,6 +249,13 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         return;
     }
 
+    auto vectorSize = [&] () -> unsigned {
+        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
+        auto& vectorType = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType());
+        ASSERT(vectorType.name() == "vector");
+        ASSERT(matrixType.typeArguments().size() == 2);
+        return WTF::get<AST::ConstantExpression>(vectorType.typeArguments()[1]).integerLiteral().value();
+    };
     auto matrixDimension = [&] (unsigned typeArgumentIndex) -> unsigned {
         auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
         auto& matrixType = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType());
@@ -265,67 +272,156 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
 
     if (nativeFunctionDeclaration.name() == "operator[]") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
+        size_t numTypeArguments = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType()).typeArguments().size();
+        if (numTypeArguments == 3) {
+            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
 
-        unsigned numberOfRows = numberOfMatrixRows();
-        unsigned numberOfColumns = numberOfMatrixColumns();
-        stringBuilder.flexibleAppend("do {\n", metalReturnName, " result;\n");
+            unsigned numberOfRows = numberOfMatrixRows();
+            unsigned numberOfColumns = numberOfMatrixColumns();
+            stringBuilder.flexibleAppend("do {\n", metalReturnName, " result;\n");
 
-        stringBuilder.flexibleAppend(
-            "    if (", args[1], " >= ", numberOfRows, ") {", returnName, " = ", metalReturnName, "(0); break;}\n",
-            "    result[0] = ", args[0], '[', args[1], "];\n",
-            "    result[1] = ", args[0], '[', args[1], " + ", numberOfRows, "];\n");
+            stringBuilder.flexibleAppend(
+                "    if (", args[1], " >= ", numberOfRows, ") {", returnName, " = ", metalReturnName, "(0); break;}\n",
+                "    result[0] = ", args[0], '[', args[1], "];\n",
+                "    result[1] = ", args[0], '[', args[1], " + ", numberOfRows, "];\n");
 
-        if (numberOfColumns >= 3)
-            stringBuilder.flexibleAppend("    result[2] = ", args[0], '[', args[1], " + ", numberOfRows * 2, "];\n");
-        if (numberOfColumns >= 4)
-            stringBuilder.flexibleAppend("    result[3] = ", args[0], '[', args[1], " + ", numberOfRows * 3, "];\n");
+            if (numberOfColumns >= 3)
+                stringBuilder.flexibleAppend("    result[2] = ", args[0], '[', args[1], " + ", numberOfRows * 2, "];\n");
+            if (numberOfColumns >= 4)
+                stringBuilder.flexibleAppend("    result[3] = ", args[0], '[', args[1], " + ", numberOfRows * 3, "];\n");
 
-        stringBuilder.flexibleAppend(
-            "    ", returnName, " = result;\n",
-            "} while (0);\n");
+            stringBuilder.flexibleAppend(
+                "    ", returnName, " = result;\n",
+                "} while (0);\n");
+        } else {
+            RELEASE_ASSERT(numTypeArguments == 2);
+            unsigned numElements = vectorSize();
+
+            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+
+            stringBuilder.flexibleAppend("do {\n", metalReturnName, " result;\n");
+
+            stringBuilder.flexibleAppend(
+                "    if (", args[1], " >= ", numElements, ") {", returnName, " = ", metalReturnName, "(0); break;}\n",
+                "    result = ", args[0], "[", args[1], "];\n");
+            stringBuilder.flexibleAppend(
+                "    ", returnName, " = result;\n",
+                "} while (0);\n");
+        }
 
         return;
     }
 
     if (nativeFunctionDeclaration.name() == "operator[]=") {
-        ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
-        auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
-        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+        auto& typeReference = downcast<AST::TypeReference>(*nativeFunctionDeclaration.parameters()[0]->type());
+        size_t numTypeArguments = downcast<AST::NativeTypeDeclaration>(downcast<AST::TypeReference>(downcast<AST::TypeDefinition>(typeReference.resolvedType()).type()).resolvedType()).typeArguments().size();
+        if (numTypeArguments == 3) {
+            ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
+            auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
+            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
 
-        unsigned numberOfRows = numberOfMatrixRows();
-        unsigned numberOfColumns = numberOfMatrixColumns();
+            unsigned numberOfRows = numberOfMatrixRows();
+            unsigned numberOfColumns = numberOfMatrixColumns();
 
-        stringBuilder.flexibleAppend("do {\n", metalReturnName, " m = ", args[0], ";\n",
-            metalParameter2Name, " i = ", args[1], ";\n");
+            stringBuilder.flexibleAppend("do {\n", metalReturnName, " m = ", args[0], ";\n",
+                metalParameter2Name, " i = ", args[1], ";\n");
+
+            stringBuilder.flexibleAppend(
+                "    if (i >= ", numberOfRows, ") {", returnName, " = m;\nbreak;}\n",
+                "    m[i] = ", args[2], "[0];\n",
+                "    m[i + ", numberOfRows, "] = ", args[2], "[1];\n");
+            if (numberOfColumns >= 3)
+                stringBuilder.flexibleAppend("    m[i + ", numberOfRows * 2, "] = ", args[2], "[2];\n");
+            if (numberOfColumns >= 4)
+                stringBuilder.flexibleAppend("    m[i + ", numberOfRows * 3, "] = ", args[2], "[3];\n");
+            stringBuilder.flexibleAppend(
+                "    ", returnName, " = m;\n",
+                "} while(0);\n");
+        } else {
+            RELEASE_ASSERT(numTypeArguments == 2);
+
+            ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
+            auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
+            auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+
+            unsigned numElements = vectorSize();
+
+            stringBuilder.flexibleAppend("do {\n", metalReturnName, " v = ", args[0], ";\n",
+                metalParameter2Name, " i = ", args[1], ";\n");
+
+            stringBuilder.flexibleAppend(
+                "    if (i >= ", numElements, ") {", returnName, " = v;\nbreak;}\n",
+                "    v[i] = ", args[2], ";\n");
+            stringBuilder.flexibleAppend(
+                "    ", returnName, " = v;\n",
+                "} while(0);\n");
+        }
 
-        stringBuilder.flexibleAppend(
-            "    if (i >= ", numberOfRows, ") {", returnName, " = m;\nbreak;}\n",
-            "    m[i] = ", args[2], "[0];\n",
-            "    m[i + ", numberOfRows, "] = ", args[2], "[1];\n");
-        if (numberOfColumns >= 3)
-            stringBuilder.flexibleAppend("    m[i + ", numberOfRows * 2, "] = ", args[2], "[2];\n");
-        if (numberOfColumns >= 4)
-            stringBuilder.flexibleAppend("    m[i + ", numberOfRows * 3, "] = ", args[2], "[3];\n");
-        stringBuilder.flexibleAppend(
-            "    ", returnName, " = m;\n",
-            "} while(0);\n");
         return;
     }
 
+    auto asMatrixType = [&] (AST::UnnamedType& unnamedType) -> AST::NativeTypeDeclaration* {
+        auto& realType = unnamedType.unifyNode();
+        if (!realType.isNativeTypeDeclaration())
+            return nullptr;
+
+        auto& maybeMatrixType = downcast<AST::NativeTypeDeclaration>(realType);
+        if (maybeMatrixType.isMatrix())
+            return &maybeMatrixType;
+
+        return nullptr;
+    };
+
     if (nativeFunctionDeclaration.isOperator()) {
         auto operatorName = nativeFunctionDeclaration.name().substring("operator"_str.length());
+        auto firstParameterType = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
         if (nativeFunctionDeclaration.parameters().size() == 1) {
-            auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
-            stringBuilder.flexibleAppend(
-                "{\n", metalParameterName, " x = ", args[0], ";\n", 
-                returnName, " = ", operatorName, "x;\n}\n");
+            if (auto* matrixType = asMatrixType(nativeFunctionDeclaration.type())) {
+                stringBuilder.flexibleAppend(
+                    "{\n", firstParameterType, " x = ", args[0], ";\n",
+                    "for (size_t i = 0; i < x.size(); ++i) x[i] = ", operatorName, "x[i];\n",
+                    returnName, " = x;\n}\n");
+            } else {
+                stringBuilder.flexibleAppend(
+                    "{\n", firstParameterType, " x = ", args[0], ";\n", 
+                    returnName, " = ", operatorName, "x;\n}\n");
+            }
             return;
         }
 
         ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
-        stringBuilder.flexibleAppend(
-            returnName, " = ", args[0], ' ', operatorName, ' ', args[1], ";\n");
+        auto secondParameterType = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
+        if (auto* leftMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[0]->type())) {
+            if (auto* rightMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[1]->type())) {
+                // matrix <op> matrix
+                stringBuilder.flexibleAppend(
+                    "{\n", firstParameterType, " x;\n",
+                    "for (size_t i = 0; i < x.size(); ++i) x[i] = ", args[0], "[i] ", operatorName, ' ', args[1], "[i];\n",
+                    returnName, " = x;\n}\n");
+            } else {
+                // matrix <op> scalar
+                stringBuilder.flexibleAppend(
+                    "{\n", firstParameterType, " x;\n",
+                    "for (size_t i = 0; i < x.size(); ++i) x[i] = ", args[0], "[i] ", operatorName, ' ', args[1], ";\n",
+                    returnName, " = x;\n}\n");
+            }
+        } else if (auto* rightMatrix = asMatrixType(*nativeFunctionDeclaration.parameters()[1]->type())) {
+            ASSERT(!asMatrixType(*nativeFunctionDeclaration.parameters()[0]->type()));
+            // scalar <op> matrix
+            stringBuilder.flexibleAppend(
+                "{\n", secondParameterType, " x;\n",
+                "for (size_t i = 0; i < x.size(); ++i) x[i] = ", args[0], ' ', operatorName, ' ', args[1], "[i];\n",
+                returnName, " = x;\n}\n");
+        } else {
+            // scalar <op> scalar
+            // vector <op> vector
+            // vector <op> scalar
+            // scalar <op> vector
+            stringBuilder.flexibleAppend(
+                returnName, " = ", args[0], ' ', operatorName, ' ', args[1], ";\n");
+        }
+
         return;
     }
 
@@ -352,7 +448,8 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         || nativeFunctionDeclaration.name() == "isnan"
         || nativeFunctionDeclaration.name() == "asint"
         || nativeFunctionDeclaration.name() == "asuint"
-        || nativeFunctionDeclaration.name() == "asfloat") {
+        || nativeFunctionDeclaration.name() == "asfloat"
+        || nativeFunctionDeclaration.name() == "length") {
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
         stringBuilder.flexibleAppend(
             returnName, " = ", mapFunctionName(nativeFunctionDeclaration.name()), '(', args[0], ");\n");
@@ -366,6 +463,21 @@ void inlineNativeFunction(StringBuilder& stringBuilder, AST::NativeFunctionDecla
         return;
     }
 
+    if (nativeFunctionDeclaration.name() == "clamp") {
+        ASSERT(nativeFunctionDeclaration.parameters().size() == 3);
+        if (asMatrixType(nativeFunctionDeclaration.type())) {
+            auto metalReturnType = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+            stringBuilder.flexibleAppend(
+                "{\n", metalReturnType, " x;\n",
+                "for (size_t i = 0; i < x.size(); ++i) x[i] = clamp(", args[0], "[i], ", args[1], "[i], ", args[2], "[i]);",
+                returnName, " = x;\n}\n");
+        } else {
+            stringBuilder.flexibleAppend(
+                returnName, " = clamp(", args[0], ", ", args[1], ", ", args[2], ");\n");
+        }
+        return;
+    }
+
     if (nativeFunctionDeclaration.name() == "AllMemoryBarrierWithGroupSync") {
         ASSERT(!nativeFunctionDeclaration.parameters().size());
         stringBuilder.append(
index bdf0a25..724c9d4 100644 (file)
@@ -2448,199 +2448,18 @@ float4 operator.wy=(float4 v, float2 c) {
 }
 
 /* Functions named operator[]= */
-bool2 operator[]=(bool2 v, uint index, bool a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-bool3 operator[]=(bool3 v, uint index, bool a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-bool4 operator[]=(bool4 v, uint index, bool a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        case 3:
-            v.w = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-uint2 operator[]=(uint2 v, uint index, uint a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-uint3 operator[]=(uint3 v, uint index, uint a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-uint4 operator[]=(uint4 v, uint index, uint a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        case 3:
-            v.w = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-int2 operator[]=(int2 v, uint index, int a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-int3 operator[]=(int3 v, uint index, int a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-int4 operator[]=(int4 v, uint index, int a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        case 3:
-            v.w = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-float2 operator[]=(float2 v, uint index, float a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-float3 operator[]=(float3 v, uint index, float a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-float4 operator[]=(float4 v, uint index, float a) {
-    switch (index) {
-        case 0:
-            v.x = a;
-            break;
-        case 1:
-            v.y = a;
-            break;
-        case 2:
-            v.z = a;
-            break;
-        case 3:
-            v.w = a;
-            break;
-        default:
-            break;
-    }
-    return v;
-}
-
+native bool2 operator[]=(bool2, uint, bool);
+native bool3 operator[]=(bool3, uint, bool);
+native bool4 operator[]=(bool4, uint, bool);
+native uint2 operator[]=(uint2, uint, uint);
+native uint3 operator[]=(uint3, uint, uint);
+native uint4 operator[]=(uint4, uint, uint);
+native int2 operator[]=(int2, uint, int);
+native int3 operator[]=(int3, uint, int);
+native int4 operator[]=(int4, uint, int);
+native float2 operator[]=(float2, uint, float);
+native float3 operator[]=(float3, uint, float);
+native float4 operator[]=(float4, uint, float);
 native float2x2 operator[]=(float2x2, uint, float2);
 native float2x3 operator[]=(float2x3, uint, float3);
 native float2x4 operator[]=(float2x4, uint, float4);
@@ -3157,18 +2976,10 @@ native void InterlockedMin(threadgroup atomic_uint*, uint, threadgroup uint*);
 native void InterlockedMin(threadgroup atomic_int*, int, threadgroup int*);
 
 /* Functions named length */
-float length(float x) {
-    return sqrt(dot(x, x));
-}
-float length(float2 x) {
-    return sqrt(dot(x, x));
-}
-float length(float3 x) {
-    return sqrt(dot(x, x));
-}
-float length(float4 x) {
-    return sqrt(dot(x, x));
-}
+native float length(float);
+native float length(float2);
+native float length(float3);
+native float length(float4);
 
 
 /* Functions named operator.xwzy */
@@ -11187,174 +10998,18 @@ float2 operator.ww(float4 v) {
 }
 
 /* Functions named operator[] */
-bool operator[](bool2 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        default:
-            break;
-    }
-    bool result;
-    return result;
-}
-bool operator[](bool3 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        default:
-            break;
-    }
-    bool result;
-    return result;
-}
-bool operator[](bool4 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        case 3:
-            return v.w;
-        default:
-            break;
-    }
-    bool result;
-    return result;
-}
-uint operator[](uint2 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        default:
-            break;
-    }
-    uint result;
-    return result;
-}
-uint operator[](uint3 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        default:
-            break;
-    }
-    uint result;
-    return result;
-}
-uint operator[](uint4 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        case 3:
-            return v.w;
-        default:
-            break;
-    }
-    uint result;
-    return result;
-}
-int operator[](int2 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        default:
-            break;
-    }
-    int result;
-    return result;
-}
-int operator[](int3 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        default:
-            break;
-    }
-    int result;
-    return result;
-}
-int operator[](int4 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        case 3:
-            return v.w;
-        default:
-            break;
-    }
-    int result;
-    return result;
-}
-float operator[](float2 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        default:
-            break;
-    }
-    float result;
-    return result;
-}
-float operator[](float3 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        default:
-            break;
-    }
-    float result;
-    return result;
-}
-float operator[](float4 v, uint index) {
-    switch (index) {
-        case 0:
-            return v.x;
-        case 1:
-            return v.y;
-        case 2:
-            return v.z;
-        case 3:
-            return v.w;
-        default:
-            break;
-    }
-    float result;
-    return result;
-}
+native bool operator[](bool2, uint);
+native bool operator[](bool3, uint);
+native bool operator[](bool4, uint);
+native uint operator[](uint2, uint);
+native uint operator[](uint3, uint);
+native uint operator[](uint4, uint);
+native int operator[](int2, uint);
+native int operator[](int3, uint);
+native int operator[](int4, uint);
+native float operator[](float2, uint);
+native float operator[](float3, uint);
+native float operator[](float4, uint);
 native float2 operator[](float2x2, uint);
 native float3 operator[](float2x3, uint);
 native float4 operator[](float2x4, uint);
@@ -16085,546 +15740,60 @@ float4 operator.wxzy=(float4 v, float4 c) {
 native int operator*(int, int);
 native uint operator*(uint, uint);
 native float operator*(float, float);
-uint2 operator*(uint2 a, uint2 b) {
-    uint2 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    return result;
-}
-uint2 operator*(uint2 a, uint b) {
-    uint2 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    return result;
-}
-uint2 operator*(uint a, uint2 b) {
-    uint2 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    return result;
-}
-uint3 operator*(uint3 a, uint3 b) {
-    uint3 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    return result;
-}
-uint3 operator*(uint3 a, uint b) {
-    uint3 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    return result;
-}
-uint3 operator*(uint a, uint3 b) {
-    uint3 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    return result;
-}
-uint4 operator*(uint4 a, uint4 b) {
-    uint4 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    result[3] = a[3] * b[3];
-    return result;
-}
-uint4 operator*(uint4 a, uint b) {
-    uint4 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    result[3] = a[3] * b;
-    return result;
-}
-uint4 operator*(uint a, uint4 b) {
-    uint4 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    result[3] = a * b[3];
-    return result;
-}
-int2 operator*(int2 a, int2 b) {
-    int2 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    return result;
-}
-int2 operator*(int2 a, int b) {
-    int2 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    return result;
-}
-int2 operator*(int a, int2 b) {
-    int2 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    return result;
-}
-int3 operator*(int3 a, int3 b) {
-    int3 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    return result;
-}
-int3 operator*(int3 a, int b) {
-    int3 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    return result;
-}
-int3 operator*(int a, int3 b) {
-    int3 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    return result;
-}
-int4 operator*(int4 a, int4 b) {
-    int4 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    result[3] = a[3] * b[3];
-    return result;
-}
-int4 operator*(int4 a, int b) {
-    int4 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    result[3] = a[3] * b;
-    return result;
-}
-int4 operator*(int a, int4 b) {
-    int4 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    result[3] = a * b[3];
-    return result;
-}
-float2 operator*(float2 a, float2 b) {
-    float2 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    return result;
-}
-float2 operator*(float2 a, float b) {
-    float2 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    return result;
-}
-float2 operator*(float a, float2 b) {
-    float2 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    return result;
-}
-float3 operator*(float3 a, float3 b) {
-    float3 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    return result;
-}
-float3 operator*(float3 a, float b) {
-    float3 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    return result;
-}
-float3 operator*(float a, float3 b) {
-    float3 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    return result;
-}
-float4 operator*(float4 a, float4 b) {
-    float4 result;
-    result[0] = a[0] * b[0];
-    result[1] = a[1] * b[1];
-    result[2] = a[2] * b[2];
-    result[3] = a[3] * b[3];
-    return result;
-}
-float4 operator*(float4 a, float b) {
-    float4 result;
-    result[0] = a[0] * b;
-    result[1] = a[1] * b;
-    result[2] = a[2] * b;
-    result[3] = a[3] * b;
-    return result;
-}
-float4 operator*(float a, float4 b) {
-    float4 result;
-    result[0] = a * b[0];
-    result[1] = a * b[1];
-    result[2] = a * b[2];
-    result[3] = a * b[3];
-    return result;
-}
-float2x2 operator*(float2x2 a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    return result;
-}
-float2x2 operator*(float2x2 a, float b) {
-    float2x2 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    return result;
-}
-float2x2 operator*(float a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    return result;
-}
-float2x3 operator*(float2x3 a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    return result;
-}
-float2x3 operator*(float2x3 a, float b) {
-    float2x3 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    return result;
-}
-float2x3 operator*(float a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    return result;
-}
-float2x4 operator*(float2x4 a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[0][3] = a[0][3] * b[0][3];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    result[1][3] = a[1][3] * b[1][3];
-    return result;
-}
-float2x4 operator*(float2x4 a, float b) {
-    float2x4 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[0][3] = a[0][3] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    result[1][3] = a[1][3] * b;
-    return result;
-}
-float2x4 operator*(float a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[0][3] = a * b[0][3];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    result[1][3] = a * b[1][3];
-    return result;
-}
-float3x2 operator*(float3x2 a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    return result;
-}
-float3x2 operator*(float3x2 a, float b) {
-    float3x2 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    return result;
-}
-float3x2 operator*(float a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    return result;
-}
-float3x3 operator*(float3x3 a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    result[2][2] = a[2][2] * b[2][2];
-    return result;
-}
-float3x3 operator*(float3x3 a, float b) {
-    float3x3 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    result[2][2] = a[2][2] * b;
-    return result;
-}
-float3x3 operator*(float a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    result[2][2] = a * b[2][2];
-    return result;
-}
-float3x4 operator*(float3x4 a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[0][3] = a[0][3] * b[0][3];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    result[1][3] = a[1][3] * b[1][3];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    result[2][2] = a[2][2] * b[2][2];
-    result[2][3] = a[2][3] * b[2][3];
-    return result;
-}
-float3x4 operator*(float3x4 a, float b) {
-    float3x4 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[0][3] = a[0][3] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    result[1][3] = a[1][3] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    result[2][2] = a[2][2] * b;
-    result[2][3] = a[2][3] * b;
-    return result;
-}
-float3x4 operator*(float a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[0][3] = a * b[0][3];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    result[1][3] = a * b[1][3];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    result[2][2] = a * b[2][2];
-    result[2][3] = a * b[2][3];
-    return result;
-}
-float4x2 operator*(float4x2 a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    result[3][0] = a[3][0] * b[3][0];
-    result[3][1] = a[3][1] * b[3][1];
-    return result;
-}
-float4x2 operator*(float4x2 a, float b) {
-    float4x2 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    result[3][0] = a[3][0] * b;
-    result[3][1] = a[3][1] * b;
-    return result;
-}
-float4x2 operator*(float a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    result[3][0] = a * b[3][0];
-    result[3][1] = a * b[3][1];
-    return result;
-}
-float4x3 operator*(float4x3 a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    result[2][2] = a[2][2] * b[2][2];
-    result[3][0] = a[3][0] * b[3][0];
-    result[3][1] = a[3][1] * b[3][1];
-    result[3][2] = a[3][2] * b[3][2];
-    return result;
-}
-float4x3 operator*(float4x3 a, float b) {
-    float4x3 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    result[2][2] = a[2][2] * b;
-    result[3][0] = a[3][0] * b;
-    result[3][1] = a[3][1] * b;
-    result[3][2] = a[3][2] * b;
-    return result;
-}
-float4x3 operator*(float a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    result[2][2] = a * b[2][2];
-    result[3][0] = a * b[3][0];
-    result[3][1] = a * b[3][1];
-    result[3][2] = a * b[3][2];
-    return result;
-}
-float4x4 operator*(float4x4 a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a[0][0] * b[0][0];
-    result[0][1] = a[0][1] * b[0][1];
-    result[0][2] = a[0][2] * b[0][2];
-    result[0][3] = a[0][3] * b[0][3];
-    result[1][0] = a[1][0] * b[1][0];
-    result[1][1] = a[1][1] * b[1][1];
-    result[1][2] = a[1][2] * b[1][2];
-    result[1][3] = a[1][3] * b[1][3];
-    result[2][0] = a[2][0] * b[2][0];
-    result[2][1] = a[2][1] * b[2][1];
-    result[2][2] = a[2][2] * b[2][2];
-    result[2][3] = a[2][3] * b[2][3];
-    result[3][0] = a[3][0] * b[3][0];
-    result[3][1] = a[3][1] * b[3][1];
-    result[3][2] = a[3][2] * b[3][2];
-    result[3][3] = a[3][3] * b[3][3];
-    return result;
-}
-float4x4 operator*(float4x4 a, float b) {
-    float4x4 result;
-    result[0][0] = a[0][0] * b;
-    result[0][1] = a[0][1] * b;
-    result[0][2] = a[0][2] * b;
-    result[0][3] = a[0][3] * b;
-    result[1][0] = a[1][0] * b;
-    result[1][1] = a[1][1] * b;
-    result[1][2] = a[1][2] * b;
-    result[1][3] = a[1][3] * b;
-    result[2][0] = a[2][0] * b;
-    result[2][1] = a[2][1] * b;
-    result[2][2] = a[2][2] * b;
-    result[2][3] = a[2][3] * b;
-    result[3][0] = a[3][0] * b;
-    result[3][1] = a[3][1] * b;
-    result[3][2] = a[3][2] * b;
-    result[3][3] = a[3][3] * b;
-    return result;
-}
-float4x4 operator*(float a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a * b[0][0];
-    result[0][1] = a * b[0][1];
-    result[0][2] = a * b[0][2];
-    result[0][3] = a * b[0][3];
-    result[1][0] = a * b[1][0];
-    result[1][1] = a * b[1][1];
-    result[1][2] = a * b[1][2];
-    result[1][3] = a * b[1][3];
-    result[2][0] = a * b[2][0];
-    result[2][1] = a * b[2][1];
-    result[2][2] = a * b[2][2];
-    result[2][3] = a * b[2][3];
-    result[3][0] = a * b[3][0];
-    result[3][1] = a * b[3][1];
-    result[3][2] = a * b[3][2];
-    result[3][3] = a * b[3][3];
-    return result;
-}
+native uint2 operator*(uint2, uint2);
+native uint2 operator*(uint2, uint);
+native uint2 operator*(uint, uint2);
+native uint3 operator*(uint3, uint3);
+native uint3 operator*(uint3, uint);
+native uint3 operator*(uint, uint3);
+native uint4 operator*(uint4, uint4);
+native uint4 operator*(uint4, uint);
+native uint4 operator*(uint, uint4);
+native int2 operator*(int2, int2);
+native int2 operator*(int2, int);
+native int2 operator*(int, int2);
+native int3 operator*(int3, int3);
+native int3 operator*(int3, int);
+native int3 operator*(int, int3);
+native int4 operator*(int4, int4);
+native int4 operator*(int4, int);
+native int4 operator*(int, int4);
+native float2 operator*(float2, float2);
+native float2 operator*(float2, float);
+native float2 operator*(float, float2);
+native float3 operator*(float3, float3);
+native float3 operator*(float3, float);
+native float3 operator*(float, float3);
+native float4 operator*(float4, float4);
+native float4 operator*(float4, float);
+native float4 operator*(float, float4);
+native float2x2 operator*(float2x2, float2x2);
+native float2x2 operator*(float2x2, float);
+native float2x2 operator*(float, float2x2);
+native float2x3 operator*(float2x3, float2x3);
+native float2x3 operator*(float2x3, float);
+native float2x3 operator*(float, float2x3);
+native float2x4 operator*(float2x4, float2x4);
+native float2x4 operator*(float2x4, float);
+native float2x4 operator*(float, float2x4);
+native float3x2 operator*(float3x2, float3x2);
+native float3x2 operator*(float3x2, float);
+native float3x2 operator*(float, float3x2);
+native float3x3 operator*(float3x3, float3x3);
+native float3x3 operator*(float3x3, float);
+native float3x3 operator*(float, float3x3);
+native float3x4 operator*(float3x4, float3x4);
+native float3x4 operator*(float3x4, float);
+native float3x4 operator*(float, float3x4);
+native float4x2 operator*(float4x2, float4x2);
+native float4x2 operator*(float4x2, float);
+native float4x2 operator*(float, float4x2);
+native float4x3 operator*(float4x3, float4x3);
+native float4x3 operator*(float4x3, float);
+native float4x3 operator*(float, float4x3);
+native float4x4 operator*(float4x4, float4x4);
+native float4x4 operator*(float4x4, float);
+native float4x4 operator*(float, float4x4);
 
 /* Functions named cos */
 native float cos(float);
@@ -24037,346 +23206,75 @@ native uint operator-(uint, uint);
 native float operator-(float, float);
 native int operator-(int);
 native float operator-(float);
-
-uint2 operator-(uint2 a, uint2 b) {
-    uint2 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    return result;
-}
-uint3 operator-(uint3 a, uint3 b) {
-    uint3 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    return result;
-}
-uint4 operator-(uint4 a, uint4 b) {
-    uint4 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    result[3] = a[3] - b[3];
-    return result;
-}
-int2 operator-(int2 a, int2 b) {
-    int2 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    return result;
-}
-int3 operator-(int3 a, int3 b) {
-    int3 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    return result;
-}
-int4 operator-(int4 a, int4 b) {
-    int4 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    result[3] = a[3] - b[3];
-    return result;
-}
-float2 operator-(float2 a, float2 b) {
-    float2 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    return result;
-}
-float3 operator-(float3 a, float3 b) {
-    float3 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    return result;
-}
-float4 operator-(float4 a, float4 b) {
-    float4 result;
-    result[0] = a[0] - b[0];
-    result[1] = a[1] - b[1];
-    result[2] = a[2] - b[2];
-    result[3] = a[3] - b[3];
-    return result;
-}
-int2 operator-(int2 a) {
-    int2 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    return result;
-}
-int3 operator-(int3 a) {
-    int3 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    result[2] = -a[2];
-    return result;
-}
-int4 operator-(int4 a) {
-    int4 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    result[2] = -a[2];
-    result[3] = -a[3];
-    return result;
-}
-float2 operator-(float2 a) {
-    float2 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    return result;
-}
-float3 operator-(float3 a) {
-    float3 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    result[2] = -a[2];
-    return result;
-}
-float4 operator-(float4 a) {
-    float4 result;
-    result[0] = -a[0];
-    result[1] = -a[1];
-    result[2] = -a[2];
-    result[3] = -a[3];
-    return result;
-}
-float2x2 operator-(float2x2 a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    return result;
-}
-float2x2 operator-(float2x2 a) {
-    float2x2 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    return result;
-}
-float2x3 operator-(float2x3 a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    return result;
-}
-float2x3 operator-(float2x3 a) {
-    float2x3 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    return result;
-}
-float2x4 operator-(float2x4 a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[0][3] = a[0][3] - b[0][3];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    result[1][3] = a[1][3] - b[1][3];
-    return result;
-}
-float2x4 operator-(float2x4 a) {
-    float2x4 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[0][3] = -a[0][3];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    result[1][3] = -a[1][3];
-    return result;
-}
-float3x2 operator-(float3x2 a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    return result;
-}
-float3x2 operator-(float3x2 a) {
-    float3x2 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    return result;
-}
-float3x3 operator-(float3x3 a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    result[2][2] = a[2][2] - b[2][2];
-    return result;
-}
-float3x3 operator-(float3x3 a) {
-    float3x3 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    result[2][2] = -a[2][2];
-    return result;
-}
-float3x4 operator-(float3x4 a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[0][3] = a[0][3] - b[0][3];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    result[1][3] = a[1][3] - b[1][3];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    result[2][2] = a[2][2] - b[2][2];
-    result[2][3] = a[2][3] - b[2][3];
-    return result;
-}
-float3x4 operator-(float3x4 a) {
-    float3x4 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[0][3] = -a[0][3];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    result[1][3] = -a[1][3];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    result[2][2] = -a[2][2];
-    result[2][3] = -a[2][3];
-    return result;
-}
-float4x2 operator-(float4x2 a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    result[3][0] = a[3][0] - b[3][0];
-    result[3][1] = a[3][1] - b[3][1];
-    return result;
-}
-float4x2 operator-(float4x2 a) {
-    float4x2 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    result[3][0] = -a[3][0];
-    result[3][1] = -a[3][1];
-    return result;
-}
-float4x3 operator-(float4x3 a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    result[2][2] = a[2][2] - b[2][2];
-    result[3][0] = a[3][0] - b[3][0];
-    result[3][1] = a[3][1] - b[3][1];
-    result[3][2] = a[3][2] - b[3][2];
-    return result;
-}
-float4x3 operator-(float4x3 a) {
-    float4x3 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    result[2][2] = -a[2][2];
-    result[3][0] = -a[3][0];
-    result[3][1] = -a[3][1];
-    result[3][2] = -a[3][2];
-    return result;
-}
-float4x4 operator-(float4x4 a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a[0][0] - b[0][0];
-    result[0][1] = a[0][1] - b[0][1];
-    result[0][2] = a[0][2] - b[0][2];
-    result[0][3] = a[0][3] - b[0][3];
-    result[1][0] = a[1][0] - b[1][0];
-    result[1][1] = a[1][1] - b[1][1];
-    result[1][2] = a[1][2] - b[1][2];
-    result[1][3] = a[1][3] - b[1][3];
-    result[2][0] = a[2][0] - b[2][0];
-    result[2][1] = a[2][1] - b[2][1];
-    result[2][2] = a[2][2] - b[2][2];
-    result[2][3] = a[2][3] - b[2][3];
-    result[3][0] = a[3][0] - b[3][0];
-    result[3][1] = a[3][1] - b[3][1];
-    result[3][2] = a[3][2] - b[3][2];
-    result[3][3] = a[3][3] - b[3][3];
-    return result;
-}
-float4x4 operator-(float4x4 a) {
-    float4x4 result;
-    result[0][0] = -a[0][0];
-    result[0][1] = -a[0][1];
-    result[0][2] = -a[0][2];
-    result[0][3] = -a[0][3];
-    result[1][0] = -a[1][0];
-    result[1][1] = -a[1][1];
-    result[1][2] = -a[1][2];
-    result[1][3] = -a[1][3];
-    result[2][0] = -a[2][0];
-    result[2][1] = -a[2][1];
-    result[2][2] = -a[2][2];
-    result[2][3] = -a[2][3];
-    result[3][0] = -a[3][0];
-    result[3][1] = -a[3][1];
-    result[3][2] = -a[3][2];
-    result[3][3] = -a[3][3];
-    return result;
-}
+native uint2 operator-(uint2, uint2);
+native uint2 operator-(uint, uint2);
+native uint2 operator-(uint2, uint);
+native uint3 operator-(uint3, uint3);
+native uint3 operator-(uint, uint3);
+native uint3 operator-(uint3, uint);
+native uint4 operator-(uint4, uint4);
+native uint4 operator-(uint, uint4);
+native uint4 operator-(uint4, uint);
+native int2 operator-(int2, int2);
+native int2 operator-(int, int2);
+native int2 operator-(int2, int);
+native int3 operator-(int3, int3);
+native int3 operator-(int, int3);
+native int3 operator-(int3, int);
+native int4 operator-(int4, int4);
+native int4 operator-(int, int4);
+native int4 operator-(int4, int);
+native float2 operator-(float2, float2);
+native float2 operator-(float, float2);
+native float2 operator-(float2, float);
+native float3 operator-(float3, float3);
+native float3 operator-(float, float3);
+native float3 operator-(float3, float);
+native float4 operator-(float4, float4);
+native float4 operator-(float, float4);
+native float4 operator-(float4, float);
+native int2 operator-(int2);
+native int3 operator-(int3);
+native int4 operator-(int4);
+native float2 operator-(float2);
+native float3 operator-(float3);
+native float4 operator-(float4);
+native float2x2 operator-(float2x2, float2x2);
+native float2x2 operator-(float2x2, float);
+native float2x2 operator-(float, float2x2);
+native float2x2 operator-(float2x2);
+native float2x3 operator-(float2x3, float2x3);
+native float2x3 operator-(float, float2x3);
+native float2x3 operator-(float2x3, float);
+native float2x3 operator-(float2x3);
+native float2x4 operator-(float2x4, float2x4);
+native float2x4 operator-(float, float2x4);
+native float2x4 operator-(float2x4, float);
+native float2x4 operator-(float2x4);
+native float3x2 operator-(float3x2, float3x2);
+native float3x2 operator-(float, float3x2);
+native float3x2 operator-(float3x2, float);
+native float3x2 operator-(float3x2);
+native float3x3 operator-(float3x3, float3x3);
+native float3x3 operator-(float, float3x3);
+native float3x3 operator-(float3x3, float);
+native float3x3 operator-(float3x3);
+native float3x4 operator-(float3x4, float3x4);
+native float3x4 operator-(float, float3x4);
+native float3x4 operator-(float3x4, float);
+native float3x4 operator-(float3x4);
+native float4x2 operator-(float4x2, float4x2);
+native float4x2 operator-(float, float4x2);
+native float4x2 operator-(float4x2, float);
+native float4x2 operator-(float4x2);
+native float4x3 operator-(float4x3, float4x3);
+native float4x3 operator-(float, float4x3);
+native float4x3 operator-(float4x3, float);
+native float4x3 operator-(float4x3);
+native float4x4 operator-(float4x4, float4x4);
+native float4x4 operator-(float, float4x4);
+native float4x4 operator-(float4x4, float);
+native float4x4 operator-(float4x4);
 
 /* Functions named min */
 uint min(uint x, uint y) {
@@ -27575,203 +26473,27 @@ float3 operator.zyw(float4 v) {
 }
 
 /* Functions named clamp */
-
-
-uint clamp(uint x, uint lower, uint upper) {
-    return max(min(upper, x), lower);
-}
-uint2 clamp(uint2 x, uint2 y, uint2 z) {
-    uint2 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    return result;
-}
-uint3 clamp(uint3 x, uint3 y, uint3 z) {
-    uint3 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    return result;
-}
-uint4 clamp(uint4 x, uint4 y, uint4 z) {
-    uint4 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    result[3] = clamp(x[3], y[3], z[3]);
-    return result;
-}
-
-
-
-int clamp(int x, int lower, int upper) {
-    return max(min(upper, x), lower);
-}
-int2 clamp(int2 x, int2 y, int2 z) {
-    int2 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    return result;
-}
-int3 clamp(int3 x, int3 y, int3 z) {
-    int3 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    return result;
-}
-int4 clamp(int4 x, int4 y, int4 z) {
-    int4 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    result[3] = clamp(x[3], y[3], z[3]);
-    return result;
-}
-
-
-float clamp(float x, float lower, float upper) {
-    return max(min(upper, x), lower);
-}
-float2 clamp(float2 x, float2 y, float2 z) {
-    float2 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    return result;
-}
-float3 clamp(float3 x, float3 y, float3 z) {
-    float3 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    return result;
-}
-float4 clamp(float4 x, float4 y, float4 z) {
-    float4 result;
-    result[0] = clamp(x[0], y[0], z[0]);
-    result[1] = clamp(x[1], y[1], z[1]);
-    result[2] = clamp(x[2], y[2], z[2]);
-    result[3] = clamp(x[3], y[3], z[3]);
-    return result;
-}
-float2x2 clamp(float2x2 x, float2x2 y, float2x2 z) {
-    float2x2 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    return result;
-}
-float2x3 clamp(float2x3 x, float2x3 y, float2x3 z) {
-    float2x3 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    return result;
-}
-float2x4 clamp(float2x4 x, float2x4 y, float2x4 z) {
-    float2x4 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[0][3] = clamp(x[0][3], y[0][3], z[0][3]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    result[1][3] = clamp(x[1][3], y[1][3], z[1][3]);
-    return result;
-}
-float3x2 clamp(float3x2 x, float3x2 y, float3x2 z) {
-    float3x2 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    return result;
-}
-float3x3 clamp(float3x3 x, float3x3 y, float3x3 z) {
-    float3x3 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    result[2][2] = clamp(x[2][2], y[2][2], z[2][2]);
-    return result;
-}
-float3x4 clamp(float3x4 x, float3x4 y, float3x4 z) {
-    float3x4 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[0][3] = clamp(x[0][3], y[0][3], z[0][3]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    result[1][3] = clamp(x[1][3], y[1][3], z[1][3]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    result[2][2] = clamp(x[2][2], y[2][2], z[2][2]);
-    result[2][3] = clamp(x[2][3], y[2][3], z[2][3]);
-    return result;
-}
-float4x2 clamp(float4x2 x, float4x2 y, float4x2 z) {
-    float4x2 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    result[3][0] = clamp(x[3][0], y[3][0], z[3][0]);
-    result[3][1] = clamp(x[3][1], y[3][1], z[3][1]);
-    return result;
-}
-float4x3 clamp(float4x3 x, float4x3 y, float4x3 z) {
-    float4x3 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    result[2][2] = clamp(x[2][2], y[2][2], z[2][2]);
-    result[3][0] = clamp(x[3][0], y[3][0], z[3][0]);
-    result[3][1] = clamp(x[3][1], y[3][1], z[3][1]);
-    result[3][2] = clamp(x[3][2], y[3][2], z[3][2]);
-    return result;
-}
-float4x4 clamp(float4x4 x, float4x4 y, float4x4 z) {
-    float4x4 result;
-    result[0][0] = clamp(x[0][0], y[0][0], z[0][0]);
-    result[0][1] = clamp(x[0][1], y[0][1], z[0][1]);
-    result[0][2] = clamp(x[0][2], y[0][2], z[0][2]);
-    result[0][3] = clamp(x[0][3], y[0][3], z[0][3]);
-    result[1][0] = clamp(x[1][0], y[1][0], z[1][0]);
-    result[1][1] = clamp(x[1][1], y[1][1], z[1][1]);
-    result[1][2] = clamp(x[1][2], y[1][2], z[1][2]);
-    result[1][3] = clamp(x[1][3], y[1][3], z[1][3]);
-    result[2][0] = clamp(x[2][0], y[2][0], z[2][0]);
-    result[2][1] = clamp(x[2][1], y[2][1], z[2][1]);
-    result[2][2] = clamp(x[2][2], y[2][2], z[2][2]);
-    result[2][3] = clamp(x[2][3], y[2][3], z[2][3]);
-    result[3][0] = clamp(x[3][0], y[3][0], z[3][0]);
-    result[3][1] = clamp(x[3][1], y[3][1], z[3][1]);
-    result[3][2] = clamp(x[3][2], y[3][2], z[3][2]);
-    result[3][3] = clamp(x[3][3], y[3][3], z[3][3]);
-    return result;
-}
-
+native uint clamp(uint, uint, uint);
+native uint2 clamp(uint2, uint2, uint2);
+native uint3 clamp(uint3, uint3, uint3);
+native uint4 clamp(uint4, uint4, uint4);
+native int clamp(int, int, int);
+native int2 clamp(int2, int2, int2);
+native int3 clamp(int3, int3, int3);
+native int4 clamp(int4, int4, int4);
+native float clamp(float, float, float);
+native float2 clamp(float2, float2, float2);
+native float3 clamp(float3, float3, float3);
+native float4 clamp(float4, float4, float4);
+native float2x2 clamp(float2x2, float2x2, float2x2);
+native float2x3 clamp(float2x3, float2x3, float2x3);
+native float2x4 clamp(float2x4, float2x4, float2x4);
+native float3x2 clamp(float3x2, float3x2, float3x2);
+native float3x3 clamp(float3x3, float3x3, float3x3);
+native float3x4 clamp(float3x4, float3x4, float3x4);
+native float4x2 clamp(float4x2, float4x2, float4x2);
+native float4x3 clamp(float4x3, float4x3, float4x3);
+native float4x4 clamp(float4x4, float4x4, float4x4);
 
 /* Functions named operator.wxxy */
 bool4 operator.wxxy(bool4 v) {
@@ -34192,186 +32914,60 @@ float4 operator.xwyw(float4 v) {
 native int operator+(int, int);
 native uint operator+(uint, uint);
 native float operator+(float, float);
-uint2 operator+(uint2 a, uint2 b) {
-    uint2 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    return result;
-}
-uint3 operator+(uint3 a, uint3 b) {
-    uint3 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    return result;
-}
-uint4 operator+(uint4 a, uint4 b) {
-    uint4 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    result[3] = a[3] + b[3];
-    return result;
-}
-int2 operator+(int2 a, int2 b) {
-    int2 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    return result;
-}
-int3 operator+(int3 a, int3 b) {
-    int3 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    return result;
-}
-int4 operator+(int4 a, int4 b) {
-    int4 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    result[3] = a[3] + b[3];
-    return result;
-}
-float2 operator+(float2 a, float2 b) {
-    float2 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    return result;
-}
-float3 operator+(float3 a, float3 b) {
-    float3 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    return result;
-}
-float4 operator+(float4 a, float4 b) {
-    float4 result;
-    result[0] = a[0] + b[0];
-    result[1] = a[1] + b[1];
-    result[2] = a[2] + b[2];
-    result[3] = a[3] + b[3];
-    return result;
-}
-float2x2 operator+(float2x2 a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    return result;
-}
-float2x3 operator+(float2x3 a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    return result;
-}
-float2x4 operator+(float2x4 a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[0][3] = a[0][3] + b[0][3];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    result[1][3] = a[1][3] + b[1][3];
-    return result;
-}
-float3x2 operator+(float3x2 a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    return result;
-}
-float3x3 operator+(float3x3 a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    result[2][2] = a[2][2] + b[2][2];
-    return result;
-}
-float3x4 operator+(float3x4 a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[0][3] = a[0][3] + b[0][3];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    result[1][3] = a[1][3] + b[1][3];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    result[2][2] = a[2][2] + b[2][2];
-    result[2][3] = a[2][3] + b[2][3];
-    return result;
-}
-float4x2 operator+(float4x2 a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    result[3][0] = a[3][0] + b[3][0];
-    result[3][1] = a[3][1] + b[3][1];
-    return result;
-}
-float4x3 operator+(float4x3 a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    result[2][2] = a[2][2] + b[2][2];
-    result[3][0] = a[3][0] + b[3][0];
-    result[3][1] = a[3][1] + b[3][1];
-    result[3][2] = a[3][2] + b[3][2];
-    return result;
-}
-float4x4 operator+(float4x4 a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a[0][0] + b[0][0];
-    result[0][1] = a[0][1] + b[0][1];
-    result[0][2] = a[0][2] + b[0][2];
-    result[0][3] = a[0][3] + b[0][3];
-    result[1][0] = a[1][0] + b[1][0];
-    result[1][1] = a[1][1] + b[1][1];
-    result[1][2] = a[1][2] + b[1][2];
-    result[1][3] = a[1][3] + b[1][3];
-    result[2][0] = a[2][0] + b[2][0];
-    result[2][1] = a[2][1] + b[2][1];
-    result[2][2] = a[2][2] + b[2][2];
-    result[2][3] = a[2][3] + b[2][3];
-    result[3][0] = a[3][0] + b[3][0];
-    result[3][1] = a[3][1] + b[3][1];
-    result[3][2] = a[3][2] + b[3][2];
-    result[3][3] = a[3][3] + b[3][3];
-    return result;
-}
+native uint2 operator+(uint2, uint2);
+native uint2 operator+(uint, uint2);
+native uint2 operator+(uint2, uint);
+native uint3 operator+(uint3, uint3);
+native uint3 operator+(uint, uint3);
+native uint3 operator+(uint3, uint);
+native uint4 operator+(uint4, uint4);
+native uint4 operator+(uint, uint4);
+native uint4 operator+(uint4, uint);
+native int2 operator+(int2, int2);
+native int2 operator+(int, int2);
+native int2 operator+(int2, int);
+native int3 operator+(int3, int3);
+native int3 operator+(int, int3);
+native int3 operator+(int3, int);
+native int4 operator+(int4, int4);
+native int4 operator+(int, int4);
+native int4 operator+(int4, int);
+native float2 operator+(float2, float2);
+native float2 operator+(float, float2);
+native float2 operator+(float2, float);
+native float3 operator+(float3, float3);
+native float3 operator+(float, float3);
+native float3 operator+(float3, float);
+native float4 operator+(float4, float4);
+native float4 operator+(float, float4);
+native float4 operator+(float4, float);
+native float2x2 operator+(float2x2, float2x2);
+native float2x2 operator+(float, float2x2);
+native float2x2 operator+(float2x2, float);
+native float2x3 operator+(float2x3, float2x3);
+native float2x3 operator+(float, float2x3);
+native float2x3 operator+(float2x3, float);
+native float2x4 operator+(float2x4, float2x4);
+native float2x4 operator+(float, float2x4);
+native float2x4 operator+(float2x4, float);
+native float3x2 operator+(float3x2, float3x2);
+native float3x2 operator+(float, float3x2);
+native float3x2 operator+(float3x2, float);
+native float3x3 operator+(float3x3, float3x3);
+native float3x3 operator+(float, float3x3);
+native float3x3 operator+(float3x3, float);
+native float3x4 operator+(float3x4, float3x4);
+native float3x4 operator+(float, float3x4);
+native float3x4 operator+(float3x4, float);
+native float4x2 operator+(float4x2, float4x2);
+native float4x2 operator+(float, float4x2);
+native float4x2 operator+(float4x2, float);
+native float4x3 operator+(float4x3, float4x3);
+native float4x3 operator+(float, float4x3);
+native float4x3 operator+(float4x3, float);
+native float4x4 operator+(float4x4, float4x4);
+native float4x4 operator+(float, float4x4);
+native float4x4 operator+(float4x4, float);
 
 /* Functions named operator.zxx */
 bool3 operator.zxx(bool3 v) {
@@ -35187,546 +33783,60 @@ float4x4 log10(float4x4 x) {
 native int operator/(int, int);
 native uint operator/(uint, uint);
 native float operator/(float, float);
-uint2 operator/(uint2 a, uint2 b) {
-    uint2 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    return result;
-}
-uint2 operator/(uint2 a, uint b) {
-    uint2 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    return result;
-}
-uint2 operator/(uint a, uint2 b) {
-    uint2 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    return result;
-}
-uint3 operator/(uint3 a, uint3 b) {
-    uint3 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    return result;
-}
-uint3 operator/(uint3 a, uint b) {
-    uint3 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    return result;
-}
-uint3 operator/(uint a, uint3 b) {
-    uint3 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    return result;
-}
-uint4 operator/(uint4 a, uint4 b) {
-    uint4 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    result[3] = a[3] / b[3];
-    return result;
-}
-uint4 operator/(uint4 a, uint b) {
-    uint4 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    result[3] = a[3] / b;
-    return result;
-}
-uint4 operator/(uint a, uint4 b) {
-    uint4 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    result[3] = a / b[3];
-    return result;
-}
-int2 operator/(int2 a, int2 b) {
-    int2 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    return result;
-}
-int2 operator/(int2 a, int b) {
-    int2 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    return result;
-}
-int2 operator/(int a, int2 b) {
-    int2 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    return result;
-}
-int3 operator/(int3 a, int3 b) {
-    int3 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    return result;
-}
-int3 operator/(int3 a, int b) {
-    int3 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    return result;
-}
-int3 operator/(int a, int3 b) {
-    int3 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    return result;
-}
-int4 operator/(int4 a, int4 b) {
-    int4 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    result[3] = a[3] / b[3];
-    return result;
-}
-int4 operator/(int4 a, int b) {
-    int4 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    result[3] = a[3] / b;
-    return result;
-}
-int4 operator/(int a, int4 b) {
-    int4 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    result[3] = a / b[3];
-    return result;
-}
-float2 operator/(float2 a, float2 b) {
-    float2 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    return result;
-}
-float2 operator/(float2 a, float b) {
-    float2 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    return result;
-}
-float2 operator/(float a, float2 b) {
-    float2 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    return result;
-}
-float3 operator/(float3 a, float3 b) {
-    float3 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    return result;
-}
-float3 operator/(float3 a, float b) {
-    float3 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    return result;
-}
-float3 operator/(float a, float3 b) {
-    float3 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    return result;
-}
-float4 operator/(float4 a, float4 b) {
-    float4 result;
-    result[0] = a[0] / b[0];
-    result[1] = a[1] / b[1];
-    result[2] = a[2] / b[2];
-    result[3] = a[3] / b[3];
-    return result;
-}
-float4 operator/(float4 a, float b) {
-    float4 result;
-    result[0] = a[0] / b;
-    result[1] = a[1] / b;
-    result[2] = a[2] / b;
-    result[3] = a[3] / b;
-    return result;
-}
-float4 operator/(float a, float4 b) {
-    float4 result;
-    result[0] = a / b[0];
-    result[1] = a / b[1];
-    result[2] = a / b[2];
-    result[3] = a / b[3];
-    return result;
-}
-float2x2 operator/(float2x2 a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    return result;
-}
-float2x2 operator/(float2x2 a, float b) {
-    float2x2 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    return result;
-}
-float2x2 operator/(float a, float2x2 b) {
-    float2x2 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    return result;
-}
-float2x3 operator/(float2x3 a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    return result;
-}
-float2x3 operator/(float2x3 a, float b) {
-    float2x3 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    return result;
-}
-float2x3 operator/(float a, float2x3 b) {
-    float2x3 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    return result;
-}
-float2x4 operator/(float2x4 a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[0][3] = a[0][3] / b[0][3];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    result[1][3] = a[1][3] / b[1][3];
-    return result;
-}
-float2x4 operator/(float2x4 a, float b) {
-    float2x4 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[0][3] = a[0][3] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    result[1][3] = a[1][3] / b;
-    return result;
-}
-float2x4 operator/(float a, float2x4 b) {
-    float2x4 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[0][3] = a / b[0][3];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    result[1][3] = a / b[1][3];
-    return result;
-}
-float3x2 operator/(float3x2 a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    return result;
-}
-float3x2 operator/(float3x2 a, float b) {
-    float3x2 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    return result;
-}
-float3x2 operator/(float a, float3x2 b) {
-    float3x2 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    return result;
-}
-float3x3 operator/(float3x3 a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    result[2][2] = a[2][2] / b[2][2];
-    return result;
-}
-float3x3 operator/(float3x3 a, float b) {
-    float3x3 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    result[2][2] = a[2][2] / b;
-    return result;
-}
-float3x3 operator/(float a, float3x3 b) {
-    float3x3 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    result[2][2] = a / b[2][2];
-    return result;
-}
-float3x4 operator/(float3x4 a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[0][3] = a[0][3] / b[0][3];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    result[1][3] = a[1][3] / b[1][3];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    result[2][2] = a[2][2] / b[2][2];
-    result[2][3] = a[2][3] / b[2][3];
-    return result;
-}
-float3x4 operator/(float3x4 a, float b) {
-    float3x4 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[0][3] = a[0][3] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    result[1][3] = a[1][3] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    result[2][2] = a[2][2] / b;
-    result[2][3] = a[2][3] / b;
-    return result;
-}
-float3x4 operator/(float a, float3x4 b) {
-    float3x4 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[0][3] = a / b[0][3];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    result[1][3] = a / b[1][3];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    result[2][2] = a / b[2][2];
-    result[2][3] = a / b[2][3];
-    return result;
-}
-float4x2 operator/(float4x2 a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    result[3][0] = a[3][0] / b[3][0];
-    result[3][1] = a[3][1] / b[3][1];
-    return result;
-}
-float4x2 operator/(float4x2 a, float b) {
-    float4x2 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    result[3][0] = a[3][0] / b;
-    result[3][1] = a[3][1] / b;
-    return result;
-}
-float4x2 operator/(float a, float4x2 b) {
-    float4x2 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    result[3][0] = a / b[3][0];
-    result[3][1] = a / b[3][1];
-    return result;
-}
-float4x3 operator/(float4x3 a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    result[2][2] = a[2][2] / b[2][2];
-    result[3][0] = a[3][0] / b[3][0];
-    result[3][1] = a[3][1] / b[3][1];
-    result[3][2] = a[3][2] / b[3][2];
-    return result;
-}
-float4x3 operator/(float4x3 a, float b) {
-    float4x3 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    result[2][2] = a[2][2] / b;
-    result[3][0] = a[3][0] / b;
-    result[3][1] = a[3][1] / b;
-    result[3][2] = a[3][2] / b;
-    return result;
-}
-float4x3 operator/(float a, float4x3 b) {
-    float4x3 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    result[2][2] = a / b[2][2];
-    result[3][0] = a / b[3][0];
-    result[3][1] = a / b[3][1];
-    result[3][2] = a / b[3][2];
-    return result;
-}
-float4x4 operator/(float4x4 a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a[0][0] / b[0][0];
-    result[0][1] = a[0][1] / b[0][1];
-    result[0][2] = a[0][2] / b[0][2];
-    result[0][3] = a[0][3] / b[0][3];
-    result[1][0] = a[1][0] / b[1][0];
-    result[1][1] = a[1][1] / b[1][1];
-    result[1][2] = a[1][2] / b[1][2];
-    result[1][3] = a[1][3] / b[1][3];
-    result[2][0] = a[2][0] / b[2][0];
-    result[2][1] = a[2][1] / b[2][1];
-    result[2][2] = a[2][2] / b[2][2];
-    result[2][3] = a[2][3] / b[2][3];
-    result[3][0] = a[3][0] / b[3][0];
-    result[3][1] = a[3][1] / b[3][1];
-    result[3][2] = a[3][2] / b[3][2];
-    result[3][3] = a[3][3] / b[3][3];
-    return result;
-}
-float4x4 operator/(float4x4 a, float b) {
-    float4x4 result;
-    result[0][0] = a[0][0] / b;
-    result[0][1] = a[0][1] / b;
-    result[0][2] = a[0][2] / b;
-    result[0][3] = a[0][3] / b;
-    result[1][0] = a[1][0] / b;
-    result[1][1] = a[1][1] / b;
-    result[1][2] = a[1][2] / b;
-    result[1][3] = a[1][3] / b;
-    result[2][0] = a[2][0] / b;
-    result[2][1] = a[2][1] / b;
-    result[2][2] = a[2][2] / b;
-    result[2][3] = a[2][3] / b;
-    result[3][0] = a[3][0] / b;
-    result[3][1] = a[3][1] / b;
-    result[3][2] = a[3][2] / b;
-    result[3][3] = a[3][3] / b;
-    return result;
-}
-float4x4 operator/(float a, float4x4 b) {
-    float4x4 result;
-    result[0][0] = a / b[0][0];
-    result[0][1] = a / b[0][1];
-    result[0][2] = a / b[0][2];
-    result[0][3] = a / b[0][3];
-    result[1][0] = a / b[1][0];
-    result[1][1] = a / b[1][1];
-    result[1][2] = a / b[1][2];
-    result[1][3] = a / b[1][3];
-    result[2][0] = a / b[2][0];
-    result[2][1] = a / b[2][1];
-    result[2][2] = a / b[2][2];
-    result[2][3] = a / b[2][3];
-    result[3][0] = a / b[3][0];
-    result[3][1] = a / b[3][1];
-    result[3][2] = a / b[3][2];
-    result[3][3] = a / b[3][3];
-    return result;
-}
+native uint2 operator/(uint2, uint2);
+native uint2 operator/(uint2, uint);
+native uint2 operator/(uint, uint2);
+native uint3 operator/(uint3, uint3);
+native uint3 operator/(uint3, uint);
+native uint3 operator/(uint, uint3);
+native uint4 operator/(uint4, uint4);
+native uint4 operator/(uint4, uint);
+native uint4 operator/(uint, uint4);
+native int2 operator/(int2, int2);
+native int2 operator/(int2, int);
+native int2 operator/(int, int2);
+native int3 operator/(int3, int3);
+native int3 operator/(int3, int);
+native int3 operator/(int, int3);
+native int4 operator/(int4, int4);
+native int4 operator/(int4, int);
+native int4 operator/(int, int4);
+native float2 operator/(float2, float2);
+native float2 operator/(float2, float);
+native float2 operator/(float, float2);
+native float3 operator/(float3, float3);
+native float3 operator/(float3, float);
+native float3 operator/(float, float3);
+native float4 operator/(float4, float4);
+native float4 operator/(float4, float);
+native float4 operator/(float, float4);
+native float2x2 operator/(float2x2, float2x2);
+native float2x2 operator/(float2x2, float);
+native float2x2 operator/(float, float2x2);
+native float2x3 operator/(float2x3, float2x3);
+native float2x3 operator/(float2x3, float);
+native float2x3 operator/(float, float2x3);
+native float2x4 operator/(float2x4, float2x4);
+native float2x4 operator/(float2x4, float);
+native float2x4 operator/(float, float2x4);
+native float3x2 operator/(float3x2, float3x2);
+native float3x2 operator/(float3x2, float);
+native float3x2 operator/(float, float3x2);
+native float3x3 operator/(float3x3, float3x3);
+native float3x3 operator/(float3x3, float);
+native float3x3 operator/(float, float3x3);
+native float3x4 operator/(float3x4, float3x4);
+native float3x4 operator/(float3x4, float);
+native float3x4 operator/(float, float3x4);
+native float4x2 operator/(float4x2, float4x2);
+native float4x2 operator/(float4x2, float);
+native float4x2 operator/(float, float4x2);
+native float4x3 operator/(float4x3, float4x3);
+native float4x3 operator/(float4x3, float);
+native float4x3 operator/(float, float4x3);
+native float4x4 operator/(float4x4, float4x4);
+native float4x4 operator/(float4x4, float);
+native float4x4 operator/(float, float4x4);
 
 /* Functions named operator.xwzx */
 bool4 operator.xwzx(bool4 v) {
@@ -38604,78 +36714,18 @@ native float3 operator.x=(float3, float);
 native float4 operator.x=(float4, float);
 
 /* Functions named operator.xy= */
-bool2 operator.xy=(bool2 v, bool2 c) {
-    bool2 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-bool3 operator.xy=(bool3 v, bool2 c) {
-    bool3 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-bool4 operator.xy=(bool4 v, bool2 c) {
-    bool4 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-uint2 operator.xy=(uint2 v, uint2 c) {
-    uint2 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-uint3 operator.xy=(uint3 v, uint2 c) {
-    uint3 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-uint4 operator.xy=(uint4 v, uint2 c) {
-    uint4 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-int2 operator.xy=(int2 v, int2 c) {
-    int2 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-int3 operator.xy=(int3 v, int2 c) {
-    int3 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-int4 operator.xy=(int4 v, int2 c) {
-    int4 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-float2 operator.xy=(float2 v, float2 c) {
-    float2 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-float3 operator.xy=(float3 v, float2 c) {
-    float3 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
-float4 operator.xy=(float4 v, float2 c) {
-    float4 result = v;
-    result.x = c.x;
-    result.y = c.y;
-    return result;
-}
+native bool2 operator.xy=(bool2, bool2);
+native bool3 operator.xy=(bool3, bool2);
+native bool4 operator.xy=(bool4, bool2);
+native uint2 operator.xy=(uint2, uint2);
+native uint3 operator.xy=(uint3, uint2);
+native uint4 operator.xy=(uint4, uint2);
+native int2 operator.xy=(int2, int2);
+native int3 operator.xy=(int3, int2);
+native int4 operator.xy=(int4, int2);
+native float2 operator.xy=(float2, float2);
+native float3 operator.xy=(float3, float2);
+native float4 operator.xy=(float4, float2);
 
 /* Functions named operator.yxw */
 bool3 operator.yxw(bool4 v) {
@@ -39518,75 +37568,15 @@ float4 operator.wwxz(float4 v) {
 }
 
 /* Functions named operator.xy */
-bool2 operator.xy(bool2 v) {
-    bool2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-bool2 operator.xy(bool3 v) {
-    bool2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-bool2 operator.xy(bool4 v) {
-    bool2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-uint2 operator.xy(uint2 v) {
-    uint2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-uint2 operator.xy(uint3 v) {
-    uint2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-uint2 operator.xy(uint4 v) {
-    uint2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-int2 operator.xy(int2 v) {
-    int2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-int2 operator.xy(int3 v) {
-    int2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-int2 operator.xy(int4 v) {
-    int2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-float2 operator.xy(float2 v) {
-    float2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-float2 operator.xy(float3 v) {
-    float2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
-float2 operator.xy(float4 v) {
-    float2 result;
-    result.x = v.x;
-    result.y = v.y;
-    return result;
-}
+native bool2 operator.xy(bool2);
+native bool2 operator.xy(bool3);
+native bool2 operator.xy(bool4);
+native uint2 operator.xy(uint2);
+native uint2 operator.xy(uint3);
+native uint2 operator.xy(uint4);
+native int2 operator.xy(int2);
+native int2 operator.xy(int3);
+native int2 operator.xy(int4);
+native float2 operator.xy(float2);
+native float2 operator.xy(float3);
+native float2 operator.xy(float4);
index b09791b..24069ec 100644 (file)
@@ -42,6 +42,8 @@ namespace WebCore {
 
 namespace WHLSL {
 
+constexpr bool verbose = false;
+
 static String decompressAndDecodeStandardLibrary()
 {
     auto decompressedStandardLibrary = gunzip(WHLSLStandardLibrary, sizeof(WHLSLStandardLibrary));
@@ -110,12 +112,22 @@ void includeStandardLibrary(Program& program, Parser& parser, bool parseFullStan
             if (iterator == standardLibraryFunctionMap.get().end())
                 continue;
             auto stringView = StringView(standardLibrary.get()).substring(iterator->value.start, iterator->value.end - iterator->value.start);
+            if (verbose) {
+                dataLogLn("---------------------------");
+                dataLogLn(stringView);
+                dataLogLn("---------------------------");
+            }
+            auto start = program.functionDefinitions().size();
             auto parseResult = parser.parse(program, stringView, ParsingMode::StandardLibrary);
             if (!parseResult) {
                 dataLogLn("failed to parse the (partial) standard library: ", Lexer::errorString(stringView, parseResult.error()));
                 ASSERT_NOT_REACHED();
                 return;
             }
+            if (verbose) {
+                if (program.functionDefinitions().size() != start)
+                    dataLogLn("non native stdlib function: '", name, "'");
+            }
             allFunctionNames.add(name);
         }
         for ( ; nativeFunctionDeclarationsCount < program.nativeFunctionDeclarations().size(); ++nativeFunctionDeclarationsCount)