[WHLSL] Standard library is too big to directly include in WebCore
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2019 22:52:26 +0000 (22:52 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2019 22:52:26 +0000 (22:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=198186
<rdar://problem/51288898>

Reviewed by Saam Barati.

Source/WebCore:

This patch adds almost the entire remainder of the standard library. There are a few
pieces missing:
- step() because of https://bugs.webkit.org/show_bug.cgi?id=199289
- sign() also because of https://bugs.webkit.org/show_bug.cgi?id=199289
- faceforward() because it calls sign()
- Some of the more rarely-used texturing functions (e.g. Gather()) https://bugs.webkit.org/show_bug.cgi?id=195813
- RWTextures https://bugs.webkit.org/show_bug.cgi?id=198985

There were two problems with adding so many standard library functions:
- We didn't want to increase the WebCore binary size that much
- Compiling all the functions at runtime took 7 seconds, which is much too long

This patch addresses the first problem by gzipping the standard library before including it in the binary.
At runtime, we use libcompression to unzip it.

To address the second problem, we did some analysis and found that 14% of that 7 seconds was simply
destroying all the AST nodes. Even if we eliminated all processing of the AST, simply having the AST
of the entire standard library built and destroyed would still be too slow. Therefore, this patch limits
which parts of the standard library get parsed in the first place. All the functions in the standard library
file are sorted by name, and each group of functions with the same name are preceeded by a comment of the
form /* Functions named xyz */. At build time, a Python script looks for all these comments, and builds a
map from function name to character offset inside the file where those functions begin. At run time, we
parse the user program first, look for all function calls within it, and look up those function call names
in the map to see which part of the standard library holds those functions. We then parse just that part.
Because the standard library can call other functions in the standard library, we do this in a loop until
we have exhausted all the functions.

Covered by existing tests.

* DerivedSources-input.xcfilelist:
* DerivedSources-output.xcfilelist:
* DerivedSources.make: gzip the standard library, and add a build step to generate the offset map.
* Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h:
(WebCore::WHLSL::AST::CallExpression::setOverloads):
(WebCore::WHLSL::AST::CallExpression::function): Every caller of this ASSERT()s the result. Might as well
move the ASSERT() into the function.
(WebCore::WHLSL::AST::CallExpression::setFunction):
* Modules/webgpu/WHLSL/Cocoa/WHLSLStandardLibraryUtilities.cpp: Added.
(WebCore::WHLSL::decompressStandardLibrary): Use libcompression. This is why this file is in a Cocoa/
subfolder, and is listed in SourcesCocoa.txt instead of Sources.txt.
(WebCore::WHLSL::decompressAndDecodeStandardLibrary):
(WebCore::WHLSL::NameFinder::takeFunctionNames):
(WebCore::WHLSL::includeStandardLibrary): Include only the bits of the standard library which are relevant,
as described above.
* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp: Only emit MSL code for functions which are actually
reached. The MSL compiler is a significant amount of our compile time, so reducing the size of the emitted
program can significantly improve compile times.
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
(WebCore::WHLSL::Metal::sharedMetalFunctions):
(WebCore::WHLSL::Metal::metalFunctions):
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::writeNativeFunction):
- Change how load() and store() are written. We need explicit functions because we have explicit atomic
  types, which HLSL doesn't have. load() and store() aren't present in HLSL.
- Delete f16tof32 because they're probably not important and are not obvious how to implement. We can re-add
  them again later if necessary.
- Various fixes to make us generate the correct MSL code for each standard library function.
* Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py: Added. Build the function map as described
above.
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::resolveByInstantiation): Previously, the standard library included an operator== for two
pointers. However, that function should be generated by the compiler instead. This fixes the bug in the
compiler which allows the compiler to correctly generate the right function. This also prompted me to file
https://bugs.webkit.org/show_bug.cgi?id=199335
(WebCore::WHLSL::checkOperatorOverload):
(WebCore::WHLSL::Checker::visit):
* Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp: Update to the new function() signature.
* Modules/webgpu/WHLSL/WHLSLLexer.h: Add a new position() method to the lexer. This isn't actually used
in this patch, but it's useful when doing some analysis during parsing.
(WebCore::WHLSL::Lexer::Lexer):
(WebCore::WHLSL::Lexer::consumeToken):
(WebCore::WHLSL::Lexer::peek const):
(WebCore::WHLSL::Lexer::peekFurther const):
(WebCore::WHLSL::Lexer::position const):
(WebCore::WHLSL::Lexer::state const):
(WebCore::WHLSL::Lexer::setState):
(WebCore::WHLSL::Lexer::isFullyConsumed const): Fixes a bug where isFullyConsumed() might return true even
when there is a token in the ring buffer.
(WebCore::WHLSL::Lexer::peek): Deleted.
(WebCore::WHLSL::Lexer::peekFurther): Deleted.
* Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
(WebCore::WHLSL::NameResolver::visit): Drive-by partial fix of https://bugs.webkit.org/show_bug.cgi?id=199347
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp: Call includeStandardLibrary().
(WebCore::WHLSL::prepareShared):
* Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp:
* Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
* Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
* Modules/webgpu/WHLSL/WHLSLStandardLibraryFunctionMap.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp.
* Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp.
* SourcesCocoa.txt:
* WebCore.xcodeproj/project.pbxproj:

LayoutTests:

The standard library doesn't include any matrix constructors that broadcast a single value
to every field in a matrix. https://bugs.webkit.org/show_bug.cgi?id=199333

* webgpu/whlsl-matrix.html:

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

30 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/whlsl-matrix.html
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/cocoa/GunzipCocoa.cpp [new file with mode: 0644]
Source/WTF/wtf/cocoa/GunzipCocoa.h [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/DerivedSources-input.xcfilelist
Source/WebCore/DerivedSources-output.xcfilelist
Source/WebCore/DerivedSources.make
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLIntrinsics.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLLexer.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryFunctionMap.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.cpp [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.h [new file with mode: 0644]
Source/WebCore/Sources.txt
Source/WebCore/SourcesCocoa.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

index bc2c9ac..3a982f8 100644 (file)
@@ -1,3 +1,16 @@
+2019-07-02  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WHLSL] Standard library is too big to directly include in WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=198186
+        <rdar://problem/51288898>
+
+        Reviewed by Saam Barati.
+
+        The standard library doesn't include any matrix constructors that broadcast a single value
+        to every field in a matrix. https://bugs.webkit.org/show_bug.cgi?id=199333
+
+        * webgpu/whlsl-matrix.html:
+
 2019-07-03  Daniel Bates  <dabates@apple.com>
 
         Skip the test added in r246810 as it requires the simulator to be preconfigured with a Pinyin keyboard
index f47b06c..dc3b65c 100644 (file)
@@ -24,19 +24,19 @@ compute void computeShader(device float[] buffer : register(u0), float3 threadID
     if (!allEqual(foo, 0))
         return;
 
-    foo = foo + 1.0;
+    foo = foo + float2x3(float3(1.0, 1.0, 1.0), float3(1.0, 1.0, 1.0));
     if (!allEqual(foo, 1))
         return;
 
-    foo = foo * 8.5;
+    foo = foo * float2x3(float3(8.5, 8.5, 8.5), float3(8.5, 8.5, 8.5));
     if (!allEqual(foo, 8.5))
         return;
 
-    foo = foo - 7.5;
+    foo = foo - float2x3(float3(7.5, 7.5, 7.5), float3(7.5, 7.5, 7.5));
     if (!allEqual(foo, 1))
         return;
 
-    foo = foo + 1.0;
+    foo = foo + float2x3(float3(1.0, 1.0, 1.0), float3(1.0, 1.0, 1.0));
     if (!allEqual(foo, 2))
         return;
 
index ce97d98..24b82a2 100644 (file)
                14F7256614EE265E00B1652B /* WeakHandleOwner.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F7256414EE265E00B1652B /* WeakHandleOwner.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14F79F70216EAFD200046D39 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A28D4A7177B71C80007FA3C /* JSStringRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1C9FF0A522CD0E7800AA6539 /* libcompression.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C9FF0A422CD0E6800AA6539 /* libcompression.tbd */; };
                2600B5A7152BAAA70091EE5F /* JSStringJoiner.h in Headers */ = {isa = PBXBuildFile; fileRef = 2600B5A5152BAAA70091EE5F /* JSStringJoiner.h */; };
                262D85B71C0D650F006ACB61 /* AirFixPartialRegisterStalls.h in Headers */ = {isa = PBXBuildFile; fileRef = 262D85B51C0D650F006ACB61 /* AirFixPartialRegisterStalls.h */; };
                2684D4381C00161C0081D663 /* AirLiveness.h in Headers */ = {isa = PBXBuildFile; fileRef = 2684D4371C00161C0081D663 /* AirLiveness.h */; };
                1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = JavaScriptCore.xcconfig; sourceTree = "<group>"; };
                1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
                1C9051450BA9E8A70081E9D0 /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
+               1C9FF0A422CD0E6800AA6539 /* libcompression.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcompression.tbd; path = usr/lib/libcompression.tbd; sourceTree = SDKROOT; };
                1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScript.h; sourceTree = "<group>"; };
                1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCore.h; sourceTree = "<group>"; };
                20ECB15EFC524624BC2F02D5 /* ModuleNamespaceAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleNamespaceAccessCase.cpp; sourceTree = "<group>"; };
                        files = (
                                932F5BD30822A1C700736975 /* CoreFoundation.framework in Frameworks */,
                                A731B25A130093880040A7FA /* Foundation.framework in Frameworks */,
+                               1C9FF0A522CD0E7800AA6539 /* libcompression.tbd in Frameworks */,
                                932F5BD70822A1C700736975 /* libicucore.dylib in Frameworks */,
                                932F5BD60822A1C700736975 /* libobjc.dylib in Frameworks */,
                                A8A4748E151A8306004123FF /* libWTF.a in Frameworks */,
                        children = (
                                6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */,
                                51F0EB6105C86C6B00E6DF1B /* Foundation.framework */,
+                               1C9FF0A422CD0E6800AA6539 /* libcompression.tbd */,
                                5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */,
                                9322A00306C341D3009067BB /* libicucore.dylib */,
                                51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */,
index 077afbf..f9900f6 100644 (file)
@@ -55,6 +55,7 @@
                1C181C911D307AB800F5FA16 /* UTextProviderLatin1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C181C8B1D307AB800F5FA16 /* UTextProviderLatin1.cpp */; };
                1C181C931D307AB800F5FA16 /* UTextProviderUTF16.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C181C8D1D307AB800F5FA16 /* UTextProviderUTF16.cpp */; };
                1C181C961D30800A00F5FA16 /* TextBreakIteratorInternalICUCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C181C951D30800A00F5FA16 /* TextBreakIteratorInternalICUCocoa.cpp */; };
+               1C9FF0A222CD096B00AA6539 /* GunzipCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C9FF0A022CD096B00AA6539 /* GunzipCocoa.cpp */; };
                1FA47C8A152502DA00568D1B /* WebCoreThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FA47C88152502DA00568D1B /* WebCoreThread.cpp */; };
                2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CCD892915C0390200285083 /* GregorianDateTime.cpp */; };
                2CDED0EF18115C38004DBA70 /* RunLoopCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2CDED0EE18115C38004DBA70 /* RunLoopCF.cpp */; };
                1C181C8D1D307AB800F5FA16 /* UTextProviderUTF16.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UTextProviderUTF16.cpp; sourceTree = "<group>"; };
                1C181C8E1D307AB800F5FA16 /* UTextProviderUTF16.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UTextProviderUTF16.h; sourceTree = "<group>"; };
                1C181C951D30800A00F5FA16 /* TextBreakIteratorInternalICUCocoa.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextBreakIteratorInternalICUCocoa.cpp; sourceTree = "<group>"; };
+               1C9FF0A022CD096B00AA6539 /* GunzipCocoa.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GunzipCocoa.cpp; sourceTree = "<group>"; };
+               1C9FF0A122CD096B00AA6539 /* GunzipCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GunzipCocoa.h; sourceTree = "<group>"; };
                1CCDB1491E566626006C73C0 /* TextBreakIteratorCF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBreakIteratorCF.h; sourceTree = "<group>"; };
                1CCDB14D1E566898006C73C0 /* TextBreakIteratorICU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextBreakIteratorICU.h; sourceTree = "<group>"; };
                1CCDB1511E566BC5006C73C0 /* CFStringSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFStringSPI.h; sourceTree = "<group>"; };
                                143DDE9720C8BE99007F76FA /* Entitlements.h */,
                                143DDE9520C8BC37007F76FA /* Entitlements.mm */,
                                A331D95E21F249F6009F02AA /* FileSystemCocoa.mm */,
+                               1C9FF0A022CD096B00AA6539 /* GunzipCocoa.cpp */,
+                               1C9FF0A122CD096B00AA6539 /* GunzipCocoa.h */,
                                7A6EBA3320746C34004F9C44 /* MachSendRight.cpp */,
                                A8A472C5151A825A004123FF /* MainThreadCocoa.mm */,
                                ADF2CE651E39F106006889DB /* MemoryFootprintCocoa.cpp */,
                                0F5BF1761F23D49A0029D91D /* Gigacage.cpp in Sources */,
                                0F30BA901E78708E002CA847 /* GlobalVersion.cpp in Sources */,
                                2CCD892A15C0390200285083 /* GregorianDateTime.cpp in Sources */,
+                               1C9FF0A222CD096B00AA6539 /* GunzipCocoa.cpp in Sources */,
                                A8A473D8151A825B004123FF /* HashTable.cpp in Sources */,
                                93B5B44E2213D616004B7AA7 /* HexNumber.cpp in Sources */,
                                7A05093F1FB9DCC500B33FB8 /* JSONValues.cpp in Sources */,
diff --git a/Source/WTF/wtf/cocoa/GunzipCocoa.cpp b/Source/WTF/wtf/cocoa/GunzipCocoa.cpp
new file mode 100644 (file)
index 0000000..28c2a0d
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GunzipCocoa.h"
+
+#include <compression.h>
+
+namespace WTF {
+
+Vector<LChar> gunzip(const unsigned char* data, size_t length)
+{
+    Vector<LChar> result;
+
+    // Parse the gzip header.
+    auto checks = [&]() {
+        return length >= 10 && data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x8 && data[3] == 0x0;
+    };
+    ASSERT(checks());
+    if (!checks())
+        return { };
+
+    constexpr auto ignoredByteCount = 10;
+
+    compression_stream stream;
+    auto status = compression_stream_init(&stream, COMPRESSION_STREAM_DECODE, COMPRESSION_ZLIB);
+    ASSERT(status == COMPRESSION_STATUS_OK);
+    if (status != COMPRESSION_STATUS_OK)
+        return { };
+    stream.dst_ptr = result.data();
+    stream.dst_size = result.size();
+    stream.src_ptr = data + ignoredByteCount;
+    stream.src_size = length - ignoredByteCount;
+    size_t offset = 0;
+
+    do {
+        uint8_t* originalDestinationPointer = stream.dst_ptr;
+        status = compression_stream_process(&stream, COMPRESSION_STREAM_FINALIZE);
+        uint8_t* newDestinationPointer = stream.dst_ptr;
+        offset += newDestinationPointer - originalDestinationPointer;
+        switch (status) {
+        case COMPRESSION_STATUS_OK: {
+            auto newSize = offset * 1.5 + 1;
+            // FIXME: We can get better performance if we, instead of resizing the buffer, we allocate distinct chunks and have a postprocessing step which concatenates the chunks together.
+            if (newSize > result.size())
+                result.grow(newSize);
+            stream.dst_ptr = result.data() + offset;
+            stream.dst_size = result.size() - offset;
+            break;
+        }
+        case COMPRESSION_STATUS_END:
+            status = compression_stream_destroy(&stream);
+            ASSERT(status == COMPRESSION_STATUS_OK);
+            if (status == COMPRESSION_STATUS_OK) {
+                result.shrink(stream.dst_ptr - result.data());
+                return result;
+            }
+            return { };
+        case COMPRESSION_STATUS_ERROR:
+        default:
+            ASSERT_NOT_REACHED();
+            compression_stream_destroy(&stream);
+            return { };
+        }
+    } while (true);
+}
+
+} // namespace WTF
diff --git a/Source/WTF/wtf/cocoa/GunzipCocoa.h b/Source/WTF/wtf/cocoa/GunzipCocoa.h
new file mode 100644 (file)
index 0000000..394d573
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Vector.h>
+#include <wtf/text/LChar.h>
+
+namespace WTF {
+
+// This function is only suitable for zip files which are guaranteed to not have any flags set in their headers.
+// See https://tools.ietf.org/html/rfc1952 for more information.
+WTF_EXPORT Vector<LChar> gunzip(const unsigned char* data, size_t length);
+
+}
+
+using WTF::gunzip;
index c84ba21..e531427 100644 (file)
@@ -1,3 +1,103 @@
+2019-07-02  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WHLSL] Standard library is too big to directly include in WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=198186
+        <rdar://problem/51288898>
+
+        Reviewed by Saam Barati.
+
+        This patch adds almost the entire remainder of the standard library. There are a few
+        pieces missing:
+        - step() because of https://bugs.webkit.org/show_bug.cgi?id=199289
+        - sign() also because of https://bugs.webkit.org/show_bug.cgi?id=199289
+        - faceforward() because it calls sign()
+        - Some of the more rarely-used texturing functions (e.g. Gather()) https://bugs.webkit.org/show_bug.cgi?id=195813
+        - RWTextures https://bugs.webkit.org/show_bug.cgi?id=198985
+
+        There were two problems with adding so many standard library functions:
+        - We didn't want to increase the WebCore binary size that much
+        - Compiling all the functions at runtime took 7 seconds, which is much too long
+
+        This patch addresses the first problem by gzipping the standard library before including it in the binary.
+        At runtime, we use libcompression to unzip it.
+
+        To address the second problem, we did some analysis and found that 14% of that 7 seconds was simply
+        destroying all the AST nodes. Even if we eliminated all processing of the AST, simply having the AST
+        of the entire standard library built and destroyed would still be too slow. Therefore, this patch limits
+        which parts of the standard library get parsed in the first place. All the functions in the standard library
+        file are sorted by name, and each group of functions with the same name are preceeded by a comment of the
+        form /* Functions named xyz */. At build time, a Python script looks for all these comments, and builds a
+        map from function name to character offset inside the file where those functions begin. At run time, we
+        parse the user program first, look for all function calls within it, and look up those function call names
+        in the map to see which part of the standard library holds those functions. We then parse just that part.
+        Because the standard library can call other functions in the standard library, we do this in a loop until
+        we have exhausted all the functions.
+
+        Covered by existing tests.
+
+        * DerivedSources-input.xcfilelist:
+        * DerivedSources-output.xcfilelist:
+        * DerivedSources.make: gzip the standard library, and add a build step to generate the offset map.
+        * Modules/webgpu/WHLSL/AST/WHLSLCallExpression.h:
+        (WebCore::WHLSL::AST::CallExpression::setOverloads):
+        (WebCore::WHLSL::AST::CallExpression::function): Every caller of this ASSERT()s the result. Might as well
+        move the ASSERT() into the function.
+        (WebCore::WHLSL::AST::CallExpression::setFunction):
+        * Modules/webgpu/WHLSL/Cocoa/WHLSLStandardLibraryUtilities.cpp: Added.
+        (WebCore::WHLSL::decompressStandardLibrary): Use libcompression. This is why this file is in a Cocoa/
+        subfolder, and is listed in SourcesCocoa.txt instead of Sources.txt.
+        (WebCore::WHLSL::decompressAndDecodeStandardLibrary):
+        (WebCore::WHLSL::NameFinder::takeFunctionNames):
+        (WebCore::WHLSL::includeStandardLibrary): Include only the bits of the standard library which are relevant,
+        as described above.
+        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp: Only emit MSL code for functions which are actually
+        reached. The MSL compiler is a significant amount of our compile time, so reducing the size of the emitted
+        program can significantly improve compile times.
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+        (WebCore::WHLSL::Metal::sharedMetalFunctions):
+        (WebCore::WHLSL::Metal::metalFunctions):
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::writeNativeFunction):
+        - Change how load() and store() are written. We need explicit functions because we have explicit atomic
+          types, which HLSL doesn't have. load() and store() aren't present in HLSL.
+        - Delete f16tof32 because they're probably not important and are not obvious how to implement. We can re-add
+          them again later if necessary.
+        - Various fixes to make us generate the correct MSL code for each standard library function.
+        * Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py: Added. Build the function map as described
+        above.
+        * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+        (WebCore::WHLSL::resolveByInstantiation): Previously, the standard library included an operator== for two
+        pointers. However, that function should be generated by the compiler instead. This fixes the bug in the
+        compiler which allows the compiler to correctly generate the right function. This also prompted me to file
+        https://bugs.webkit.org/show_bug.cgi?id=199335
+        (WebCore::WHLSL::checkOperatorOverload):
+        (WebCore::WHLSL::Checker::visit):
+        * Modules/webgpu/WHLSL/WHLSLFunctionStageChecker.cpp: Update to the new function() signature.
+        * Modules/webgpu/WHLSL/WHLSLLexer.h: Add a new position() method to the lexer. This isn't actually used
+        in this patch, but it's useful when doing some analysis during parsing. 
+        (WebCore::WHLSL::Lexer::Lexer):
+        (WebCore::WHLSL::Lexer::consumeToken):
+        (WebCore::WHLSL::Lexer::peek const):
+        (WebCore::WHLSL::Lexer::peekFurther const):
+        (WebCore::WHLSL::Lexer::position const):
+        (WebCore::WHLSL::Lexer::state const):
+        (WebCore::WHLSL::Lexer::setState):
+        (WebCore::WHLSL::Lexer::isFullyConsumed const): Fixes a bug where isFullyConsumed() might return true even
+        when there is a token in the ring buffer.
+        (WebCore::WHLSL::Lexer::peek): Deleted.
+        (WebCore::WHLSL::Lexer::peekFurther): Deleted.
+        * Modules/webgpu/WHLSL/WHLSLNameResolver.cpp:
+        (WebCore::WHLSL::NameResolver::visit): Drive-by partial fix of https://bugs.webkit.org/show_bug.cgi?id=199347
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp: Call includeStandardLibrary().
+        (WebCore::WHLSL::prepareShared):
+        * Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp:
+        * Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
+        * Modules/webgpu/WHLSL/WHLSLStandardLibraryFunctionMap.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp.
+        * Modules/webgpu/WHLSL/WHLSLStandardLibraryUtilities.h: Copied from Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp.
+        * SourcesCocoa.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
 2019-07-03  Jer Noble  <jer.noble@apple.com>
 
         Exception thrown from -[AVSampleBufferRenderSynchronizer addRenderer:], not a valid renderer.
index 57c537c..c69d3dd 100644 (file)
@@ -345,6 +345,7 @@ $(PROJECT_DIR)/Modules/webgpu/GPUVertexAttributeDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUVertexBufferDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/GPUVertexInputDescriptor.idl
 $(PROJECT_DIR)/Modules/webgpu/NavigatorGPU.idl
+$(PROJECT_DIR)/Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py
 $(PROJECT_DIR)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
 $(PROJECT_DIR)/Modules/webgpu/WebGPU.idl
 $(PROJECT_DIR)/Modules/webgpu/WebGPUAdapter.idl
index d0e0a8f..37c3c8b 100644 (file)
@@ -2095,6 +2095,7 @@ $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/UserAgentScripts.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/UserAgentScriptsData.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/UserAgentStyleSheets.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WHLSLStandardLibrary.h
+$(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WHLSLStandardLibraryFunctionMap.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCoreJSBuiltinInternals.cpp
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCoreJSBuiltinInternals.h
 $(BUILT_PRODUCTS_DIR)/DerivedSources/WebCore/WebCoreJSBuiltins.cpp
index d88aed4..7eeb427 100644 (file)
@@ -1636,10 +1636,13 @@ $(GENERATE_SETTINGS_PATTERNS) : $(WebCore)/Scripts/GenerateSettings.rb $(GENERAT
 
 # WHLSL Standard Library
 
-all : WHLSLStandardLibrary.h
+all : WHLSLStandardLibrary.h WHLSLStandardLibraryFunctionMap.cpp
 
 WHLSLStandardLibrary.h : $(JavaScriptCore_SCRIPTS_DIR)/xxd.pl $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
-       $(PERL) $< WHLSLStandardLibrary $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt $@
+       bash -c "$(PERL) $< WHLSLStandardLibrary <(gzip -cn $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt) $@"
+
+WHLSLStandardLibraryFunctionMap.cpp : $(WebCore)/Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt
+       $(PYTHON) $< $(WebCore)/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt $@
 
 # --------
 
index 1a0d027..17b94cd 100644 (file)
@@ -71,15 +71,19 @@ public:
     Optional<Vector<std::reference_wrapper<FunctionDeclaration>, 1>>& overloads() { return m_overloads; }
     void setOverloads(const Vector<std::reference_wrapper<FunctionDeclaration>, 1>& overloads)
     {
-        assert(!hasOverloads());
+        ASSERT(!hasOverloads());
         m_overloads = overloads;
     }
 
-    FunctionDeclaration* function() { return m_function; }
+    FunctionDeclaration& function()
+    {
+        ASSERT(m_function);
+        return *m_function;
+    }
 
     void setFunction(FunctionDeclaration& functionDeclaration)
     {
-        assert(!m_function);
+        ASSERT(!m_function);
         m_function = &functionDeclaration;
     }
 
index 94916b6..0b5980f 100644 (file)
@@ -35,6 +35,7 @@
 #include "WHLSLTypeNamer.h"
 #include "WHLSLVisitor.h"
 #include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
 #include <wtf/SetForScope.h>
 #include <wtf/text/StringBuilder.h>
 
@@ -554,8 +555,7 @@ void FunctionDefinitionWriter::visit(AST::CallExpression& callExpression)
         checkErrorAndVisit(argument);
         argumentNames.append(takeLastValue());
     }
-    ASSERT(callExpression.function());
-    auto iterator = m_functionMapping.find(callExpression.function());
+    auto iterator = m_functionMapping.find(&callExpression.function());
     ASSERT(iterator != m_functionMapping.end());
     auto variableName = generateNextVariableName();
     if (!matches(callExpression.resolvedType(), m_intrinsics.voidType()))
@@ -763,7 +763,7 @@ struct SharedMetalFunctionsResult {
     HashMap<AST::FunctionDeclaration*, String> functionMapping;
     String metalFunctions;
 };
-static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNamer& typeNamer)
+static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNamer& typeNamer, const HashSet<AST::FunctionDeclaration*>& reachableFunctions)
 {
     StringBuilder stringBuilder;
 
@@ -780,10 +780,12 @@ static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNam
 
     {
         FunctionDeclarationWriter functionDeclarationWriter(typeNamer, functionMapping);
-        for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations())
-            functionDeclarationWriter.visit(nativeFunctionDeclaration);
+        for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
+            if (reachableFunctions.contains(&nativeFunctionDeclaration))
+                functionDeclarationWriter.visit(nativeFunctionDeclaration);
+        }
         for (auto& functionDefinition : program.functionDefinitions()) {
-            if (!functionDefinition->entryPointType())
+            if (!functionDefinition->entryPointType() && reachableFunctions.contains(&functionDefinition))
                 functionDeclarationWriter.visit(functionDefinition);
         }
         stringBuilder.append(functionDeclarationWriter.toString());
@@ -793,49 +795,89 @@ static SharedMetalFunctionsResult sharedMetalFunctions(Program& program, TypeNam
     return { WTFMove(functionMapping), stringBuilder.toString() };
 }
 
+class ReachableFunctionsGatherer : public Visitor {
+public:
+    void visit(AST::FunctionDeclaration& functionDeclaration) override
+    {
+        Visitor::visit(functionDeclaration);
+        m_reachableFunctions.add(&functionDeclaration);
+    }
+
+    void visit(AST::CallExpression& callExpression) override
+    {
+        Visitor::visit(callExpression);
+        if (is<AST::FunctionDefinition>(callExpression.function()))
+            checkErrorAndVisit(downcast<AST::FunctionDefinition>(callExpression.function()));
+        else
+            checkErrorAndVisit(downcast<AST::NativeFunctionDeclaration>(callExpression.function()));
+    }
+
+    HashSet<AST::FunctionDeclaration*> takeReachableFunctions() { return WTFMove(m_reachableFunctions); }
+
+private:
+    HashSet<AST::FunctionDeclaration*> m_reachableFunctions;
+};
+
 RenderMetalFunctions metalFunctions(Program& program, TypeNamer& typeNamer, MatchedRenderSemantics&& matchedSemantics, Layout& layout)
 {
-    auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer);
+    auto& vertexShaderEntryPoint = *matchedSemantics.vertexShader;
+    auto& fragmentShaderEntryPoint = *matchedSemantics.fragmentShader;
+
+    ReachableFunctionsGatherer reachableFunctionsGatherer;
+    reachableFunctionsGatherer.Visitor::visit(vertexShaderEntryPoint);
+    reachableFunctionsGatherer.Visitor::visit(fragmentShaderEntryPoint);
+    auto reachableFunctions = reachableFunctionsGatherer.takeReachableFunctions();
+
+    auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer, reachableFunctions);
 
     StringBuilder stringBuilder;
     stringBuilder.append(sharedMetalFunctions.metalFunctions);
 
-    auto* vertexShaderEntryPoint = matchedSemantics.vertexShader;
-    auto* fragmentShaderEntryPoint = matchedSemantics.fragmentShader;
-
     RenderFunctionDefinitionWriter functionDefinitionWriter(program.intrinsics(), typeNamer, sharedMetalFunctions.functionMapping, WTFMove(matchedSemantics), layout);
-    for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations())
-        functionDefinitionWriter.visit(nativeFunctionDeclaration);
-    for (auto& functionDefinition : program.functionDefinitions())
-        functionDefinitionWriter.visit(functionDefinition);
+    for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
+        if (reachableFunctions.contains(&nativeFunctionDeclaration))
+            functionDefinitionWriter.visit(nativeFunctionDeclaration);
+    }
+    for (auto& functionDefinition : program.functionDefinitions()) {
+        if (reachableFunctions.contains(&functionDefinition))
+            functionDefinitionWriter.visit(functionDefinition);
+    }
     stringBuilder.append(functionDefinitionWriter.toString());
 
     RenderMetalFunctions result;
     result.metalSource = stringBuilder.toString();
-    result.mangledVertexEntryPointName = sharedMetalFunctions.functionMapping.get(vertexShaderEntryPoint);
-    result.mangledFragmentEntryPointName = sharedMetalFunctions.functionMapping.get(fragmentShaderEntryPoint);
+    result.mangledVertexEntryPointName = sharedMetalFunctions.functionMapping.get(&vertexShaderEntryPoint);
+    result.mangledFragmentEntryPointName = sharedMetalFunctions.functionMapping.get(&fragmentShaderEntryPoint);
     return result;
 }
 
 ComputeMetalFunctions metalFunctions(Program& program, TypeNamer& typeNamer, MatchedComputeSemantics&& matchedSemantics, Layout& layout)
 {
-    auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer);
+    auto& entryPoint = *matchedSemantics.shader;
+
+    ReachableFunctionsGatherer reachableFunctionsGatherer;
+    reachableFunctionsGatherer.Visitor::visit(entryPoint);
+    auto reachableFunctions = reachableFunctionsGatherer.takeReachableFunctions();
+
+    auto sharedMetalFunctions = Metal::sharedMetalFunctions(program, typeNamer, reachableFunctions);
 
     StringBuilder stringBuilder;
     stringBuilder.append(sharedMetalFunctions.metalFunctions);
 
-    auto* entryPoint = matchedSemantics.shader;
-
     ComputeFunctionDefinitionWriter functionDefinitionWriter(program.intrinsics(), typeNamer, sharedMetalFunctions.functionMapping, WTFMove(matchedSemantics), layout);
-    for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations())
-        functionDefinitionWriter.visit(nativeFunctionDeclaration);
-    for (auto& functionDefinition : program.functionDefinitions())
-        functionDefinitionWriter.visit(functionDefinition);
+    for (auto& nativeFunctionDeclaration : program.nativeFunctionDeclarations()) {
+        if (reachableFunctions.contains(&nativeFunctionDeclaration))
+            functionDefinitionWriter.visit(nativeFunctionDeclaration);
+    }
+    for (auto& functionDefinition : program.functionDefinitions()) {
+        if (reachableFunctions.contains(&functionDefinition))
+            functionDefinitionWriter.visit(functionDefinition);
+    }
     stringBuilder.append(functionDefinitionWriter.toString());
 
     ComputeMetalFunctions result;
     result.metalSource = stringBuilder.toString();
-    result.mangledEntryPointName = sharedMetalFunctions.functionMapping.get(entryPoint);
+    result.mangledEntryPointName = sharedMetalFunctions.functionMapping.get(&entryPoint);
     return result;
 }
 
index 3aec9ff..f250faa 100644 (file)
@@ -135,20 +135,6 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
 
         ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
         auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
-        auto& parameterType = nativeFunctionDeclaration.parameters()[0]->type()->unifyNode();
-        if (is<AST::NamedType>(parameterType)) {
-            auto& parameterNamedType = downcast<AST::NamedType>(parameterType);
-            if (is<AST::NativeTypeDeclaration>(parameterNamedType)) {
-                auto& parameterNativeTypeDeclaration = downcast<AST::NativeTypeDeclaration>(parameterNamedType);
-                if (parameterNativeTypeDeclaration.isAtomic()) {
-                    stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n"));
-                    stringBuilder.append("    return atomic_load_explicit(&x, memory_order_relaxed);\n");
-                    stringBuilder.append("}\n");
-                    return stringBuilder.toString();
-                }
-            }
-        }
-
         stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n"));
         stringBuilder.append(makeString("    return static_cast<", metalReturnName, ">(x);\n"));
         stringBuilder.append("}\n");
@@ -363,11 +349,6 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         return stringBuilder.toString();
     }
 
-    if (nativeFunctionDeclaration.name() == "f16tof32" || nativeFunctionDeclaration.name() == "f32tof16") {
-        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195813 Implement this
-        notImplemented();
-    }
-
     if (nativeFunctionDeclaration.name() == "AllMemoryBarrierWithGroupSync") {
         ASSERT(!nativeFunctionDeclaration.parameters().size());
         stringBuilder.append(makeString("void ", outputFunctionName, "() {\n"));
@@ -406,7 +387,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             auto fourthArgumentAddressSpace = fourthArgumentPointer.addressSpace();
             auto fourthArgumentPointee = typeNamer.mangledNameForType(fourthArgumentPointer.elementType());
             stringBuilder.append(makeString("void ", outputFunctionName, '(', toString(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " compare, ", thirdArgument, " desired, ", toString(fourthArgumentAddressSpace), ' ', fourthArgumentPointee, "* out) {\n"));
-            stringBuilder.append("    atomic_compare_exchange_weak_explicit(object, &compare, desired, memory_order_relaxed);\n");
+            stringBuilder.append("    atomic_compare_exchange_weak_explicit(object, &compare, desired, memory_order_relaxed, memory_order_relaxed);\n");
             stringBuilder.append("    *out = compare;\n");
             stringBuilder.append("}\n");
             return stringBuilder.toString();
@@ -422,7 +403,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         auto thirdArgumentPointee = typeNamer.mangledNameForType(thirdArgumentPointer.elementType());
         auto name = atomicName(nativeFunctionDeclaration.name().substring("Interlocked"_str.length()));
         stringBuilder.append(makeString("void ", outputFunctionName, '(', toString(firstArgumentAddressSpace), ' ', firstArgumentPointee, "* object, ", secondArgument, " operand, ", toString(thirdArgumentAddressSpace), ' ', thirdArgumentPointee, "* out) {\n"));
-        stringBuilder.append(makeString("    *out = atomic_fetch_", name, "_explicit(object, operand, memory_order_relaxed);\n"));
+        stringBuilder.append(makeString("    *out = atomic_", name, "_explicit(object, operand, memory_order_relaxed);\n"));
         stringBuilder.append("}\n");
         return stringBuilder.toString();
     }
@@ -509,6 +490,26 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         return stringBuilder.toString();
     }
 
+    if (nativeFunctionDeclaration.name() == "load") {
+        ASSERT(nativeFunctionDeclaration.parameters().size() == 1);
+        auto metalParameterName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
+        auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
+        stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameterName, " x) {\n"));
+        stringBuilder.append("    return atomic_load_explicit(x, memory_order_relaxed);\n");
+        stringBuilder.append("}\n");
+        return stringBuilder.toString();
+    }
+
+    if (nativeFunctionDeclaration.name() == "store") {
+        ASSERT(nativeFunctionDeclaration.parameters().size() == 2);
+        auto metalParameter1Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[0]->type());
+        auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
+        stringBuilder.append(makeString("void ", outputFunctionName, '(', metalParameter1Name, " x, ", metalParameter2Name, " y) {\n"));
+        stringBuilder.append("    atomic_store_explicit(x, y, memory_order_relaxed);\n");
+        stringBuilder.append("}\n");
+        return stringBuilder.toString();
+    }
+
     if (nativeFunctionDeclaration.name() == "GetDimensions") {
         auto& textureType = downcast<AST::NativeTypeDeclaration>(downcast<AST::NamedType>(nativeFunctionDeclaration.parameters()[0]->type()->unifyNode()));
 
@@ -533,7 +534,7 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
             ++index;
         }
         String numberOfLevelsTypeName;
-        if (!textureType.isWritableTexture()) {
+        if (!textureType.isWritableTexture() && textureType.textureDimension() != 1) {
             numberOfLevelsTypeName = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[index]->type());
             ++index;
         }
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLBuildStandardLibraryFunctionMap.py
new file mode 100644 (file)
index 0000000..8b0189a
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2014 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+import sys
+import re
+
+regularExpression = re.compile("/\* Functions named (.*) \*/")
+
+infile = open(sys.argv[1], "r")
+contents = infile.read()
+infile.close()
+
+outfile = open(sys.argv[2], "w")
+outfile.write("""
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WHLSLStandardLibraryFunctionMap.h"
+
+#if ENABLE(WEBGPU)
+
+namespace WebCore {
+
+namespace WHLSL {
+
+HashMap<String, SubstringLocation> computeStandardLibraryFunctionMap()
+{
+    HashMap<String, SubstringLocation> result;
+""")
+
+# FIXME: Compute StandardLibraryFunctionMap at build-time https://bugs.webkit.org/show_bug.cgi?id=199448
+
+previous = 0
+previousName = ""
+boundary = 0
+for match in regularExpression.finditer(contents):
+    if previous == 0:
+        previous = match.start()
+        boundary = previous
+        previousName = match.group(1)
+        continue
+    outfile.write("    result.add(\"" + previousName + "\"_str, SubstringLocation { " + str(previous) + ", " + str(match.start()) + " });\n")
+    previous = match.start()
+    previousName = match.group(1)
+outfile.write("    result.add(\"" + previousName + "\"_str, SubstringLocation { " + str(previous) + ", " + str(len(contents)) + " });\n")
+outfile.write("""
+    return result;
+}
+
+unsigned firstFunctionOffsetInStandardLibrary()
+{
+""")
+
+outfile.write("    return " + str(boundary) + ";\n")
+
+outfile.write("""
+}
+
+}
+
+}
+
+#endif
+""")
+outfile.close()
index eb1fa98..63985d9 100644 (file)
@@ -194,7 +194,8 @@ static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const Str
     } else if (name == "operator==" && types.size() == 2) {
         auto acceptability = [](ResolvingType& resolvingType) -> Acceptability {
             return resolvingType.visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> Acceptability {
-                return is<AST::ReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) ? Acceptability::Yes : Acceptability::No;
+                auto& unifyNode = unnamedType->unifyNode();
+                return is<AST::UnnamedType>(unifyNode) && is<AST::ReferenceType>(downcast<AST::UnnamedType>(unifyNode)) ? Acceptability::Yes : Acceptability::No;
             }, [](RefPtr<ResolvableTypeReference>& resolvableTypeReference) -> Acceptability {
                 return is<AST::NullLiteralType>(resolvableTypeReference->resolvableType()) ? Acceptability::Maybe : Acceptability::No;
             }));
@@ -416,7 +417,7 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit
         || functionDefinition.name() == "operator|"
         || functionDefinition.name() == "operator^"
         || functionDefinition.name() == "operator<<"
-        || functionDefinition.name() == "opreator>>")
+        || functionDefinition.name() == "operator>>")
         return functionDefinition.parameters().size() == 2;
     if (functionDefinition.name() == "operator~")
         return functionDefinition.parameters().size() == 1;
@@ -1137,7 +1138,6 @@ void Checker::visit(AST::VariableReference& variableReference)
 
 void Checker::visit(AST::Return& returnStatement)
 {
-    ASSERT(returnStatement.function());
     if (returnStatement.value()) {
         auto valueInfo = recurseAndGetInfo(*returnStatement.value());
         if (!valueInfo)
index f4ce762..aa33e5b 100644 (file)
@@ -49,18 +49,16 @@ public:
 public:
     void visit(AST::CallExpression& callExpression) override
     {
-        ASSERT(callExpression.function());
-        if ((callExpression.function() == &m_intrinsics.ddx() || callExpression.function() == &m_intrinsics.ddy()) && m_entryPointType != AST::EntryPointType::Fragment) {
+        if ((&callExpression.function() == m_intrinsics.ddx() || &callExpression.function() == m_intrinsics.ddy()) && m_entryPointType != AST::EntryPointType::Fragment) {
             setError();
             return;
         }
-        if ((callExpression.function() == &m_intrinsics.allMemoryBarrier() || callExpression.function() == &m_intrinsics.deviceMemoryBarrier() || callExpression.function() == &m_intrinsics.groupMemoryBarrier())
+        if ((&callExpression.function() == m_intrinsics.allMemoryBarrier() || &callExpression.function() == m_intrinsics.deviceMemoryBarrier() || &callExpression.function() == m_intrinsics.groupMemoryBarrier())
             && m_entryPointType != AST::EntryPointType::Compute) {
             setError();
             return;
         }
-        ASSERT(callExpression.function());
-        Visitor::visit(*callExpression.function());
+        Visitor::visit(callExpression.function());
     }
 
     AST::EntryPointType m_entryPointType;
index f08022c..ab4f198 100644 (file)
@@ -196,34 +196,30 @@ public:
         return *m_vectorFloat[2];
     }
 
-    AST::NativeFunctionDeclaration& ddx() const
+    // These functions may have been pruned from the AST if they are unused.
+    AST::NativeFunctionDeclaration* ddx() const
     {
-        ASSERT(m_ddx);
-        return *m_ddx;
+        return m_ddx;
     }
 
-    AST::NativeFunctionDeclaration& ddy() const
+    AST::NativeFunctionDeclaration* ddy() const
     {
-        ASSERT(m_ddy);
-        return *m_ddy;
+        return m_ddy;
     }
 
-    AST::NativeFunctionDeclaration& allMemoryBarrier() const
+    AST::NativeFunctionDeclaration* allMemoryBarrier() const
     {
-        ASSERT(m_allMemoryBarrier);
-        return *m_allMemoryBarrier;
+        return m_allMemoryBarrier;
     }
 
-    AST::NativeFunctionDeclaration& deviceMemoryBarrier() const
+    AST::NativeFunctionDeclaration* deviceMemoryBarrier() const
     {
-        ASSERT(m_deviceMemoryBarrier);
-        return *m_deviceMemoryBarrier;
+        return m_deviceMemoryBarrier;
     }
 
-    AST::NativeFunctionDeclaration& groupMemoryBarrier() const
+    AST::NativeFunctionDeclaration* groupMemoryBarrier() const
     {
-        ASSERT(m_groupMemoryBarrier);
-        return *m_groupMemoryBarrier;
+        return m_groupMemoryBarrier;
     }
 
 private:
index bbde9fe..4f213d1 100644 (file)
@@ -46,7 +46,9 @@ public:
         : m_stringView(stringView)
     {
         skipWhitespaceAndComments();
+        m_offsetRingBuffer[0] = m_offset;
         m_ringBuffer[0] = consumeTokenFromStream();
+        m_offsetRingBuffer[1] = m_offset;
         m_ringBuffer[1] = consumeTokenFromStream();
     }
 
@@ -180,25 +182,29 @@ public:
     Optional<Token> consumeToken()
     {
         auto result = m_ringBuffer[m_ringBufferIndex];
+        m_offsetRingBuffer[m_ringBufferIndex] = m_offset;
         m_ringBuffer[m_ringBufferIndex] = consumeTokenFromStream();
         m_ringBufferIndex = (m_ringBufferIndex + 1) % 2;
         return result;
     }
 
-    Optional<Token> peek()
+    Optional<Token> peek() const
     {
         return m_ringBuffer[m_ringBufferIndex];
     }
 
-    Optional<Token> peekFurther()
+    Optional<Token> peekFurther() const
     {
         return m_ringBuffer[(m_ringBufferIndex + 1) % 2];
     }
 
+    Optional<unsigned> position() const { return m_offsetRingBuffer[m_ringBufferIndex]; }
+
     // FIXME: We should not need this
     // https://bugs.webkit.org/show_bug.cgi?id=198357
     struct State {
         Optional<Token> ringBuffer[2];
+        Optional<unsigned> m_offsetRingBuffer[2];
         unsigned ringBufferIndex;
         unsigned offset;
         unsigned lineNumber;
@@ -209,6 +215,8 @@ public:
         State state;
         state.ringBuffer[0] = m_ringBuffer[0];
         state.ringBuffer[1] = m_ringBuffer[1];
+        state.m_offsetRingBuffer[0] = m_offsetRingBuffer[0];
+        state.m_offsetRingBuffer[1] = m_offsetRingBuffer[1];
         state.ringBufferIndex = m_ringBufferIndex;
         state.offset = m_offset;
         state.lineNumber = m_lineNumber;
@@ -219,6 +227,8 @@ public:
     {
         m_ringBuffer[0] = state.ringBuffer[0];
         m_ringBuffer[1] = state.ringBuffer[1];
+        m_offsetRingBuffer[0] = state.m_offsetRingBuffer[0];
+        m_offsetRingBuffer[1] = state.m_offsetRingBuffer[1];
         m_ringBufferIndex = state.ringBufferIndex;
         m_offset = state.offset;
         m_lineNumber = state.lineNumber;
@@ -229,6 +239,8 @@ public:
     {
         m_ringBuffer[0] = WTFMove(state.ringBuffer[0]);
         m_ringBuffer[1] = WTFMove(state.ringBuffer[1]);
+        m_offsetRingBuffer[0] = WTFMove(state.m_offsetRingBuffer[0]);
+        m_offsetRingBuffer[1] = WTFMove(state.m_offsetRingBuffer[1]);
         m_ringBufferIndex = WTFMove(state.ringBufferIndex);
         m_offset = WTFMove(state.offset);
         m_lineNumber = WTFMove(state.lineNumber);
@@ -236,7 +248,7 @@ public:
 
     bool isFullyConsumed() const
     {
-        return m_offset == m_stringView.length();
+        return !peek();
     }
 
     String errorString(const Token& token, const String& message)
@@ -276,6 +288,7 @@ private:
 
     StringView m_stringView;
     Optional<Token> m_ringBuffer[2];
+    Optional<unsigned> m_offsetRingBuffer[2];
     unsigned m_ringBufferIndex { 0 };
     unsigned m_offset { 0 };
     unsigned m_lineNumber { 0 };
index 0067478..072f5c9 100644 (file)
@@ -83,6 +83,8 @@ void NameResolver::visit(AST::TypeReference& typeReference)
     }
 
     Visitor::visit(typeReference);
+    if (error())
+        return;
     if (typeReference.maybeResolvedType()) // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198161 Shouldn't we know by now whether the type has been resolved or not?
         return;
 
@@ -106,6 +108,8 @@ void NameResolver::visit(AST::FunctionDefinition& functionDefinition)
     NameContext newNameContext(&m_nameContext);
     NameResolver newNameResolver(*this, newNameContext);
     checkErrorAndVisit(functionDefinition.type());
+    if (error())
+        return;
     for (auto& parameter : functionDefinition.parameters())
         newNameResolver.checkErrorAndVisit(parameter);
     newNameResolver.checkErrorAndVisit(functionDefinition.block());
index ed9930b..228a48f 100644 (file)
@@ -46,7 +46,7 @@
 #include "WHLSLRecursionChecker.h"
 #include "WHLSLRecursiveTypeChecker.h"
 #include "WHLSLSemanticMatcher.h"
-#include "WHLSLStandardLibrary.h"
+#include "WHLSLStandardLibraryUtilities.h"
 #include "WHLSLStatementBehaviorChecker.h"
 #include "WHLSLSynthesizeArrayOperatorLength.h"
 #include "WHLSLSynthesizeConstructors.h"
@@ -110,17 +110,12 @@ static Optional<Program> prepareShared(String& whlslSource)
 {
     Program program;
     Parser parser;
-    auto standardLibrary = String::fromUTF8(WHLSLStandardLibrary, sizeof(WHLSLStandardLibrary));
-    auto parseStdLibFailure = parser.parse(program, standardLibrary, Parser::Mode::StandardLibrary);
-    if (!ASSERT_DISABLED && parseStdLibFailure) {
-        dataLogLn("failed to parse the standard library: ", *parseStdLibFailure);
-        RELEASE_ASSERT_NOT_REACHED();
-    }
     if (auto parseFailure = parser.parse(program, whlslSource, Parser::Mode::User)) {
         if (dumpPassFailure)
             dataLogLn("failed to parse the program: ", *parseFailure);
         return WTF::nullopt;
     }
+    includeStandardLibrary(program, parser);
 
     if (!dumpASTBetweenEachPassIfNeeded(program, "AST after parsing"))
         dumpASTAfterParsingIfNeeded(program);
index 99d8d1e..3c2eb10 100644 (file)
@@ -189,7 +189,7 @@ public:
 
         // This works because it's illegal to call an entrypoint. Therefore, we can only
         // call functions where we've already appended this struct as its final parameter.
-        if (!callExpression.function()->isNativeFunctionDeclaration())
+        if (!callExpression.function().isNativeFunctionDeclaration())
             callExpression.arguments().append(makeStructVariableReference());
     }
 
index 43cf9cb..cd0800d 100644 (file)
@@ -56,8 +56,7 @@ private:
 
     void visit(AST::CallExpression& callExpression) override
     {
-        ASSERT(callExpression.function());
-        Visitor::visit(*callExpression.function());
+        Visitor::visit(callExpression.function());
     }
 
     HashSet<AST::FunctionDefinition*> m_visitingSet;
index 4ca1311..2ba93af 100644 (file)
@@ -1,5 +1,9 @@
-// https://github.com/gpuweb/WHLSL/blob/9528f19aaa71fd5c3c706d2873f4b8c8cce857b5/Spec/source/Generate_Standard_Library.js
-// This was autogenerated from Generate_Standard_Library.js! Do not edit!!
+// This was autogenerated from Generate_Standard_Library.js.
+// This standard library has been processed such that functions which share a name are next to each other,
+// and before each group of functions, there's a prefix that has to be in a particular form.
+// The WebKit build process exploits this structure to build a map of which function name corresponds to which
+// part of this file. Then, when we parse WHLSL programs, we can only parse the pieces of this standard library
+// which correspond to functions that are actually used in the user program.
 
 native typedef void;
 native typedef bool;
@@ -253,677 +257,61958 @@ native typedef TextureDepth2D<float>;
 native typedef TextureDepth2DArray<float>;
 native typedef TextureDepthCube<float>;
 
-native operator uchar(ushort);
-native operator uchar(uint);
-native operator uchar(char);
-native operator uchar(short);
-native operator uchar(int);
-native operator uchar(half);
-native operator uchar(float);
-native operator ushort(uchar);
-native operator ushort(uint);
-native operator ushort(char);
-native operator ushort(short);
-native operator ushort(int);
-native operator ushort(half);
-native operator ushort(float);
-native operator uint(uchar);
-native operator uint(ushort);
-native operator uint(char);
-native operator uint(short);
-native operator uint(int);
-native operator uint(half);
-native operator uint(float);
-native operator char(uchar);
-native operator char(ushort);
-native operator char(uint);
-native operator char(short);
-native operator char(int);
-native operator char(half);
-native operator char(float);
-native operator short(uchar);
-native operator short(ushort);
-native operator short(uint);
-native operator short(char);
-native operator short(int);
-native operator short(half);
-native operator short(float);
-native operator int(uchar);
-native operator int(ushort);
-native operator int(uint);
-native operator int(char);
-native operator int(short);
-native operator int(half);
-native operator int(float);
-native operator half(uchar);
-native operator half(ushort);
-native operator half(uint);
-native operator half(char);
-native operator half(short);
-native operator half(int);
-native operator half(float);
-native operator float(uchar);
-native operator float(ushort);
-native operator float(uint);
-native operator float(char);
-native operator float(short);
-native operator float(int);
-native operator float(half);
-
-// FIXME: These should be auto generated by the compiler.
-// https://bugs.webkit.org/show_bug.cgi?id=198861
-native bool operator==(thread int*, thread int*);
-
-native bool operator.x(bool2);
-native bool operator.y(bool2);
-native bool operator.x(bool3);
-native bool operator.y(bool3);
-native bool operator.z(bool3);
-native bool operator.x(bool4);
-native bool operator.y(bool4);
-native bool operator.z(bool4);
-native bool operator.w(bool4);
-native bool2 operator.x=(bool2, bool);
-native bool2 operator.y=(bool2, bool);
-native bool3 operator.x=(bool3, bool);
-native bool3 operator.y=(bool3, bool);
-native bool3 operator.z=(bool3, bool);
-native bool4 operator.x=(bool4, bool);
-native bool4 operator.y=(bool4, bool);
-native bool4 operator.z=(bool4, bool);
-native bool4 operator.w=(bool4, bool);
-native uchar operator.x(uchar2);
-native uchar operator.y(uchar2);
-native uchar operator.x(uchar3);
-native uchar operator.y(uchar3);
-native uchar operator.z(uchar3);
-native uchar operator.x(uchar4);
-native uchar operator.y(uchar4);
-native uchar operator.z(uchar4);
-native uchar operator.w(uchar4);
-native uchar2 operator.x=(uchar2, uchar);
-native uchar2 operator.y=(uchar2, uchar);
-native uchar3 operator.x=(uchar3, uchar);
-native uchar3 operator.y=(uchar3, uchar);
-native uchar3 operator.z=(uchar3, uchar);
-native uchar4 operator.x=(uchar4, uchar);
-native uchar4 operator.y=(uchar4, uchar);
-native uchar4 operator.z=(uchar4, uchar);
-native uchar4 operator.w=(uchar4, uchar);
-native ushort operator.x(ushort2);
-native ushort operator.y(ushort2);
-native ushort operator.x(ushort3);
-native ushort operator.y(ushort3);
-native ushort operator.z(ushort3);
-native ushort operator.x(ushort4);
-native ushort operator.y(ushort4);
-native ushort operator.z(ushort4);
-native ushort operator.w(ushort4);
-native ushort2 operator.x=(ushort2, ushort);
-native ushort2 operator.y=(ushort2, ushort);
-native ushort3 operator.x=(ushort3, ushort);
-native ushort3 operator.y=(ushort3, ushort);
-native ushort3 operator.z=(ushort3, ushort);
-native ushort4 operator.x=(ushort4, ushort);
-native ushort4 operator.y=(ushort4, ushort);
-native ushort4 operator.z=(ushort4, ushort);
-native ushort4 operator.w=(ushort4, ushort);
-native uint operator.x(uint2);
-native uint operator.y(uint2);
-native uint operator.x(uint3);
-native uint operator.y(uint3);
-native uint operator.z(uint3);
-native uint operator.x(uint4);
-native uint operator.y(uint4);
-native uint operator.z(uint4);
-native uint operator.w(uint4);
-native uint2 operator.x=(uint2, uint);
-native uint2 operator.y=(uint2, uint);
-native uint3 operator.x=(uint3, uint);
-native uint3 operator.y=(uint3, uint);
-native uint3 operator.z=(uint3, uint);
-native uint4 operator.x=(uint4, uint);
-native uint4 operator.y=(uint4, uint);
-native uint4 operator.z=(uint4, uint);
-native uint4 operator.w=(uint4, uint);
-native char operator.x(char2);
-native char operator.y(char2);
-native char operator.x(char3);
-native char operator.y(char3);
-native char operator.z(char3);
-native char operator.x(char4);
-native char operator.y(char4);
-native char operator.z(char4);
-native char operator.w(char4);
-native char2 operator.x=(char2, char);
-native char2 operator.y=(char2, char);
-native char3 operator.x=(char3, char);
-native char3 operator.y=(char3, char);
-native char3 operator.z=(char3, char);
-native char4 operator.x=(char4, char);
-native char4 operator.y=(char4, char);
-native char4 operator.z=(char4, char);
-native char4 operator.w=(char4, char);
-native short operator.x(short2);
-native short operator.y(short2);
-native short operator.x(short3);
-native short operator.y(short3);
-native short operator.z(short3);
-native short operator.x(short4);
-native short operator.y(short4);
-native short operator.z(short4);
-native short operator.w(short4);
-native short2 operator.x=(short2, short);
-native short2 operator.y=(short2, short);
-native short3 operator.x=(short3, short);
-native short3 operator.y=(short3, short);
-native short3 operator.z=(short3, short);
-native short4 operator.x=(short4, short);
-native short4 operator.y=(short4, short);
-native short4 operator.z=(short4, short);
-native short4 operator.w=(short4, short);
-native int operator.x(int2);
-native int operator.y(int2);
-native int operator.x(int3);
-native int operator.y(int3);
-native int operator.z(int3);
-native int operator.x(int4);
-native int operator.y(int4);
-native int operator.z(int4);
-native int operator.w(int4);
-native int2 operator.x=(int2, int);
-native int2 operator.y=(int2, int);
-native int3 operator.x=(int3, int);
-native int3 operator.y=(int3, int);
-native int3 operator.z=(int3, int);
-native int4 operator.x=(int4, int);
-native int4 operator.y=(int4, int);
-native int4 operator.z=(int4, int);
-native int4 operator.w=(int4, int);
-native half operator.x(half2);
-native half operator.y(half2);
-native half operator.x(half3);
-native half operator.y(half3);
-native half operator.z(half3);
-native half operator.x(half4);
-native half operator.y(half4);
-native half operator.z(half4);
-native half operator.w(half4);
-native half2 operator.x=(half2, half);
-native half2 operator.y=(half2, half);
-native half3 operator.x=(half3, half);
-native half3 operator.y=(half3, half);
-native half3 operator.z=(half3, half);
-native half4 operator.x=(half4, half);
-native half4 operator.y=(half4, half);
-native half4 operator.z=(half4, half);
-native half4 operator.w=(half4, half);
-native float operator.x(float2);
-native float operator.y(float2);
-native float operator.x(float3);
-native float operator.y(float3);
-native float operator.z(float3);
-native float operator.x(float4);
-native float operator.y(float4);
-native float operator.z(float4);
-native float operator.w(float4);
-native float2 operator.x=(float2, float);
-native float2 operator.y=(float2, float);
-native float3 operator.x=(float3, float);
-native float3 operator.y=(float3, float);
-native float3 operator.z=(float3, float);
-native float4 operator.x=(float4, float);
-native float4 operator.y=(float4, float);
-native float4 operator.z=(float4, float);
-native float4 operator.w=(float4, float);
+/* Functions named reversebits */
+uchar reversebits(uchar x) {
+    return uchar(((x & uchar(1 << 0)) << 7) |
+           ((x & uchar(1 << 1)) << 5) |
+           ((x & uchar(1 << 2)) << 3) |
+           ((x & uchar(1 << 3)) << 1) |
+           ((x & uchar(1 << 4)) >> 1) |
+           ((x & uchar(1 << 5)) >> 3) |
+           ((x & uchar(1 << 6)) >> 5) |
+           ((x & uchar(1 << 7)) >> 7));
+}
+ushort reversebits(ushort x) {
+    return ushort(((x & ushort(1 << 0)) << 15) |
+           ((x & ushort(1 << 1)) << 13) |
+           ((x & ushort(1 << 2)) << 11) |
+           ((x & ushort(1 << 3)) << 9) |
+           ((x & ushort(1 << 4)) << 7) |
+           ((x & ushort(1 << 5)) << 5) |
+           ((x & ushort(1 << 6)) << 3) |
+           ((x & ushort(1 << 7)) << 1) |
+           ((x & ushort(1 << 8)) >> 1) |
+           ((x & ushort(1 << 9)) >> 3) |
+           ((x & ushort(1 << 10)) >> 5) |
+           ((x & ushort(1 << 11)) >> 7) |
+           ((x & ushort(1 << 12)) >> 9) |
+           ((x & ushort(1 << 13)) >> 11) |
+           ((x & ushort(1 << 14)) >> 13) |
+           ((x & ushort(1 << 15)) >> 15));
+}
+uint reversebits(uint x) {
+    return uint(((x & uint(1 << 0)) << 31) |
+           ((x & uint(1 << 1)) << 29) |
+           ((x & uint(1 << 2)) << 27) |
+           ((x & uint(1 << 3)) << 25) |
+           ((x & uint(1 << 4)) << 23) |
+           ((x & uint(1 << 5)) << 21) |
+           ((x & uint(1 << 6)) << 19) |
+           ((x & uint(1 << 7)) << 17) |
+           ((x & uint(1 << 8)) << 15) |
+           ((x & uint(1 << 9)) << 13) |
+           ((x & uint(1 << 10)) << 11) |
+           ((x & uint(1 << 11)) << 9) |
+           ((x & uint(1 << 12)) << 7) |
+           ((x & uint(1 << 13)) << 5) |
+           ((x & uint(1 << 14)) << 3) |
+           ((x & uint(1 << 15)) << 1) |
+           ((x & uint(1 << 16)) >> 1) |
+           ((x & uint(1 << 17)) >> 3) |
+           ((x & uint(1 << 18)) >> 5) |
+           ((x & uint(1 << 19)) >> 7) |
+           ((x & uint(1 << 20)) >> 9) |
+           ((x & uint(1 << 21)) >> 11) |
+           ((x & uint(1 << 22)) >> 13) |
+           ((x & uint(1 << 23)) >> 15) |
+           ((x & uint(1 << 24)) >> 17) |
+           ((x & uint(1 << 25)) >> 19) |
+           ((x & uint(1 << 26)) >> 21) |
+           ((x & uint(1 << 27)) >> 23) |
+           ((x & uint(1 << 28)) >> 25) |
+           ((x & uint(1 << 29)) >> 27) |
+           ((x & uint(1 << 30)) >> 29) |
+           ((x & uint(1 << 31)) >> 31));
+}
+uchar2 reversebits(uchar2 x) {
+    uchar2 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    return result;
+}
+uchar3 reversebits(uchar3 x) {
+    uchar3 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    return result;
+}
+uchar4 reversebits(uchar4 x) {
+    uchar4 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    result[3] = reversebits(x[3]);
+    return result;
+}
+ushort2 reversebits(ushort2 x) {
+    ushort2 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    return result;
+}
+ushort3 reversebits(ushort3 x) {
+    ushort3 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    return result;
+}
+ushort4 reversebits(ushort4 x) {
+    ushort4 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    result[3] = reversebits(x[3]);
+    return result;
+}
+uint2 reversebits(uint2 x) {
+    uint2 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    return result;
+}
+uint3 reversebits(uint3 x) {
+    uint3 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    return result;
+}
+uint4 reversebits(uint4 x) {
+    uint4 result;
+    result[0] = reversebits(x[0]);
+    result[1] = reversebits(x[1]);
+    result[2] = reversebits(x[2]);
+    result[3] = reversebits(x[3]);
+    return result;
+}
 
-native float ddx(float);
-native float ddy(float);
-native void AllMemoryBarrierWithGroupSync();
-native void DeviceMemoryBarrierWithGroupSync();
-native void GroupMemoryBarrierWithGroupSync();
 
-operator float4(float x, float y, float z, float w) {
-    float4 result;
-    result.x = x;
-    result.y = y;
-    result.z = z;
-    result.w = w;
+/* Functions named operator.yww */
+bool3 operator.yww(bool4 v) {
+    bool3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     return result;
 }
-
-native float3 operator[](float2x3, uint);
-native float2x3 operator[]=(float2x3, uint, float3);
-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;
-    }
-    return 0.0;
+uchar3 operator.yww(uchar4 v) {
+    uchar3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
 }
-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;
+ushort3 operator.yww(ushort4 v) {
+    ushort3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    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];
+uint3 operator.yww(uint4 v) {
+    uint3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     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;
+char3 operator.yww(char4 v) {
+    char3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     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;
+short3 operator.yww(short4 v) {
+    short3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     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;
+int3 operator.yww(int4 v) {
+    int3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     return result;
 }
-
-typedef float4x4 = matrix<float, 4, 4>;
-native float4 operator[](float4x4, uint);
-native float4x4 operator[]=(float4x4, uint, float4);
-
-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;
+half3 operator.yww(half4 v) {
+    half3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
     return result;
 }
-
-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;
+float3 operator.yww(float4 v) {
+    float3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
 }
 
-float4 mul(float4x4 x, float4 y) {
+/* Functions named operator.yzzy */
+bool4 operator.yzzy(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+bool4 operator.yzzy(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yzzy(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yzzy(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yzzy(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yzzy(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yzzy(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yzzy(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yzzy(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yzzy(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yzzy(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yzzy(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yzzy(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yzzy(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yzzy(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yzzy(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yzzy(float3 v) {
     float4 result;
-    result[0] = 0;
-    result[0] += x[0][0] * y[0];
-    result[0] += x[0][1] * y[1];
-    result[0] += x[0][2] * y[2];
-    result[0] += x[0][3] * y[3];
-    result[1] = 0;
-    result[1] += x[1][0] * y[0];
-    result[1] += x[1][1] * y[1];
-    result[1] += x[1][2] * y[2];
-    result[1] += x[1][3] * y[3];
-    result[2] = 0;
-    result[2] += x[2][0] * y[0];
-    result[2] += x[2][1] * y[1];
-    result[2] += x[2][2] * y[2];
-    result[2] += x[2][3] * y[3];
-    result[3] = 0;
-    result[3] += x[3][0] * y[0];
-    result[3] += x[3][1] * y[1];
-    result[3] += x[3][2] * y[2];
-    result[3] += x[3][3] * y[3];
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
     return result;
 }
-
-float4x4 mul(float4x4 x, float4x4 y) {
-    float4x4 result;
-    result[0][0] = 0;
-    result[0][0] += x[0][0] * y[0][0];
-    result[0][0] += x[0][1] * y[1][0];
-    result[0][0] += x[0][2] * y[2][0];
-    result[0][0] += x[0][3] * y[3][0];
-    result[0][1] = 0;
-    result[0][1] += x[0][0] * y[0][1];
-    result[0][1] += x[0][1] * y[1][1];
-    result[0][1] += x[0][2] * y[2][1];
-    result[0][1] += x[0][3] * y[3][1];
-    result[0][2] = 0;
-    result[0][2] += x[0][0] * y[0][2];
-    result[0][2] += x[0][1] * y[1][2];
-    result[0][2] += x[0][2] * y[2][2];
-    result[0][2] += x[0][3] * y[3][2];
-    result[0][3] = 0;
-    result[0][3] += x[0][0] * y[0][3];
-    result[0][3] += x[0][1] * y[1][3];
-    result[0][3] += x[0][2] * y[2][3];
-    result[0][3] += x[0][3] * y[3][3];
-    result[1][0] = 0;
-    result[1][0] += x[1][0] * y[0][0];
-    result[1][0] += x[1][1] * y[1][0];
-    result[1][0] += x[1][2] * y[2][0];
-    result[1][0] += x[1][3] * y[3][0];
-    result[1][1] = 0;
-    result[1][1] += x[1][0] * y[0][1];
-    result[1][1] += x[1][1] * y[1][1];
-    result[1][1] += x[1][2] * y[2][1];
-    result[1][1] += x[1][3] * y[3][1];
-    result[1][2] = 0;
-    result[1][2] += x[1][0] * y[0][2];
-    result[1][2] += x[1][1] * y[1][2];
-    result[1][2] += x[1][2] * y[2][2];
-    result[1][2] += x[1][3] * y[3][2];
-    result[1][3] = 0;
-    result[1][3] += x[1][0] * y[0][3];
-    result[1][3] += x[1][1] * y[1][3];
-    result[1][3] += x[1][2] * y[2][3];
-    result[1][3] += x[1][3] * y[3][3];
-    result[2][0] = 0;
-    result[2][0] += x[2][0] * y[0][0];
-    result[2][0] += x[2][1] * y[1][0];
-    result[2][0] += x[2][2] * y[2][0];
-    result[2][0] += x[2][3] * y[3][0];
-    result[2][1] = 0;
-    result[2][1] += x[2][0] * y[0][1];
-    result[2][1] += x[2][1] * y[1][1];
-    result[2][1] += x[2][2] * y[2][1];
-    result[2][1] += x[2][3] * y[3][1];
-    result[2][2] = 0;
-    result[2][2] += x[2][0] * y[0][2];
-    result[2][2] += x[2][1] * y[1][2];
-    result[2][2] += x[2][2] * y[2][2];
-    result[2][2] += x[2][3] * y[3][2];
-    result[2][3] = 0;
-    result[2][3] += x[2][0] * y[0][3];
-    result[2][3] += x[2][1] * y[1][3];
-    result[2][3] += x[2][2] * y[2][3];
-    result[2][3] += x[2][3] * y[3][3];
-    result[3][0] = 0;
-    result[3][0] += x[3][0] * y[0][0];
-    result[3][0] += x[3][1] * y[1][0];
-    result[3][0] += x[3][2] * y[2][0];
-    result[3][0] += x[3][3] * y[3][0];
-    result[3][1] = 0;
-    result[3][1] += x[3][0] * y[0][1];
-    result[3][1] += x[3][1] * y[1][1];
-    result[3][1] += x[3][2] * y[2][1];
-    result[3][1] += x[3][3] * y[3][1];
-    result[3][2] = 0;
-    result[3][2] += x[3][0] * y[0][2];
-    result[3][2] += x[3][1] * y[1][2];
-    result[3][2] += x[3][2] * y[2][2];
-    result[3][2] += x[3][3] * y[3][2];
-    result[3][3] = 0;
-    result[3][3] += x[3][0] * y[0][3];
-    result[3][3] += x[3][1] * y[1][3];
-    result[3][3] += x[3][2] * y[2][3];
-    result[3][3] += x[3][3] * y[3][3];
+float4 operator.yzzy(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.y;
     return result;
 }
 
-operator float2(float x, float y) {
-    float2 result;
-    result.x = x;
-    result.y = y;
+/* Functions named operator.zyxy */
+bool4 operator.zyxy(bool3 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
     return result;
 }
-
-operator int3(int x, int y, int z) {
-    int3 result;
-    result.x = x;
-    result.y = y;
-    result.z = z;
+bool4 operator.zyxy(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
     return result;
 }
-
-operator int2(int x, int y) {
-    int2 result;
-    result.x = x;
-    result.y = y;
+uchar4 operator.zyxy(uchar3 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
     return result;
 }
-
-operator uint2(uint x, uint y) {
-    uint2 result;
-    result.x = x;
-    result.y = y;
+uchar4 operator.zyxy(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.zyxy(ushort3 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.zyxy(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.zyxy(uint3 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.zyxy(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.zyxy(char3 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.zyxy(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.zyxy(short3 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.zyxy(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.zyxy(int3 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.zyxy(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.zyxy(half3 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.zyxy(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.zyxy(float3 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.zyxy(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
     return result;
 }
 
-native bool operator==(uchar, uchar);
-native bool operator==(ushort, ushort);
-native bool operator==(char, char);
-native bool operator==(short, short);
-native bool operator==(half, half);
-
-native int operator+(int, int);
-native int operator-(int, int);
-native int operator*(int, int);
-native int operator/(int, int);
-native bool operator==(int, int);
-native bool operator<(int, int);
-native bool operator<=(int, int);
-native bool operator>(int, int);
-native bool operator>=(int, int);
-native uint operator+(uint, uint);
-native uint operator-(uint, uint);
-native uint operator*(uint, uint);
-native uint operator/(uint, uint);
-native bool operator==(uint, uint);
-native bool operator<(uint, uint);
-native bool operator<=(uint, uint);
-native bool operator>(uint, uint);
-native bool operator>=(uint, uint);
-
-native float operator+(float, float);
-native float operator-(float, float);
-native float operator*(float, float);
-native float operator/(float, float);
-native bool operator==(float, float);
-native bool operator<(float, float);
-native bool operator<=(float, float);
-native bool operator>(float, float);
-native bool operator>=(float, float);
+/* Functions named operator.wxzy */
+bool4 operator.wxzy(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.wxzy(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.wxzy(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.wxzy(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+char4 operator.wxzy(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+short4 operator.wxzy(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+int4 operator.wxzy(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+half4 operator.wxzy(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+float4 operator.wxzy(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
 
-native int operator&(int, int);
-native int operator|(int, int);
-native int operator^(int, int);
-native int operator~(int);
-native int operator<<(int, uint);
-native int operator>>(int, uint);
-native uint operator&(uint, uint);
-native uint operator|(uint, uint);
-native uint operator^(uint, uint);
-native uint operator~(uint);
-native uint operator<<(uint, uint);
-native uint operator>>(uint, uint);
+/* Functions named operator.yxxz */
+bool4 operator.yxxz(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+bool4 operator.yxxz(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yxxz(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yxxz(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yxxz(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yxxz(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yxxz(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yxxz(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yxxz(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yxxz(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yxxz(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yxxz(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yxxz(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yxxz(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yxxz(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yxxz(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yxxz(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yxxz(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
 
-int operator++(int value) {
-    return value + 1;
+/* Functions named operator.zxwy= */
+bool4 operator.zxwy=(bool4 v, bool4 c) {
+    bool4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
 }
-int operator--(int value) {
-    return value - 1;
+uchar4 operator.zxwy=(uchar4 v, uchar4 c) {
+    uchar4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
 }
-uint operator++(uint value) {
-    return value + 1;
+ushort4 operator.zxwy=(ushort4 v, ushort4 c) {
+    ushort4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
 }
-uint operator--(uint value) {
-    return value - 1;
+uint4 operator.zxwy=(uint4 v, uint4 c) {
+    uint4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
+}
+char4 operator.zxwy=(char4 v, char4 c) {
+    char4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
+}
+short4 operator.zxwy=(short4 v, short4 c) {
+    short4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
+}
+int4 operator.zxwy=(int4 v, int4 c) {
+    int4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
+}
+half4 operator.zxwy=(half4 v, half4 c) {
+    half4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
+}
+float4 operator.zxwy=(float4 v, float4 c) {
+    float4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    result.w = c.z;
+    result.y = c.w;
+    return result;
 }
 
-native ushort Sample(Texture1D<ushort>, sampler, float location);
-native ushort Sample(Texture1DArray<ushort>, sampler, float2 location);
-native ushort Sample(Texture2D<ushort>, sampler, float2 location);
-native ushort Sample(Texture2D<ushort>, sampler, float2 location, int2 offset);
-native ushort Sample(Texture2DArray<ushort>, sampler, float3 location);
-native ushort Sample(Texture2DArray<ushort>, sampler, float3 location, int2 offset);
-native ushort Sample(Texture3D<ushort>, sampler, float3 location);
-native ushort Sample(Texture3D<ushort>, sampler, float3 location, int3 offset);
-native ushort Sample(TextureCube<ushort>, sampler, float3 location);
-native ushort2 Sample(Texture1D<ushort2>, sampler, float location);
-native ushort2 Sample(Texture1DArray<ushort2>, sampler, float2 location);
-native ushort2 Sample(Texture2D<ushort2>, sampler, float2 location);
-native ushort2 Sample(Texture2D<ushort2>, sampler, float2 location, int2 offset);
-native ushort2 Sample(Texture2DArray<ushort2>, sampler, float3 location);
-native ushort2 Sample(Texture2DArray<ushort2>, sampler, float3 location, int2 offset);
-native ushort2 Sample(Texture3D<ushort2>, sampler, float3 location);
-native ushort2 Sample(Texture3D<ushort2>, sampler, float3 location, int3 offset);
-native ushort2 Sample(TextureCube<ushort2>, sampler, float3 location);
-native ushort3 Sample(Texture1D<ushort3>, sampler, float location);
-native ushort3 Sample(Texture1DArray<ushort3>, sampler, float2 location);
-native ushort3 Sample(Texture2D<ushort3>, sampler, float2 location);
-native ushort3 Sample(Texture2D<ushort3>, sampler, float2 location, int2 offset);
-native ushort3 Sample(Texture2DArray<ushort3>, sampler, float3 location);
-native ushort3 Sample(Texture2DArray<ushort3>, sampler, float3 location, int2 offset);
-native ushort3 Sample(Texture3D<ushort3>, sampler, float3 location);
-native ushort3 Sample(Texture3D<ushort3>, sampler, float3 location, int3 offset);
-native ushort3 Sample(TextureCube<ushort3>, sampler, float3 location);
-native ushort4 Sample(Texture1D<ushort4>, sampler, float location);
-native ushort4 Sample(Texture1DArray<ushort4>, sampler, float2 location);
-native ushort4 Sample(Texture2D<ushort4>, sampler, float2 location);
-native ushort4 Sample(Texture2D<ushort4>, sampler, float2 location, int2 offset);
-native ushort4 Sample(Texture2DArray<ushort4>, sampler, float3 location);
-native ushort4 Sample(Texture2DArray<ushort4>, sampler, float3 location, int2 offset);
-native ushort4 Sample(Texture3D<ushort4>, sampler, float3 location);
-native ushort4 Sample(Texture3D<ushort4>, sampler, float3 location, int3 offset);
-native ushort4 Sample(TextureCube<ushort4>, sampler, float3 location);
-native uint Sample(Texture1D<uint>, sampler, float location);
-native uint Sample(Texture1DArray<uint>, sampler, float2 location);
-native uint Sample(Texture2D<uint>, sampler, float2 location);
-native uint Sample(Texture2D<uint>, sampler, float2 location, int2 offset);
-native uint Sample(Texture2DArray<uint>, sampler, float3 location);
-native uint Sample(Texture2DArray<uint>, sampler, float3 location, int2 offset);
-native uint Sample(Texture3D<uint>, sampler, float3 location);
-native uint Sample(Texture3D<uint>, sampler, float3 location, int3 offset);
-native uint Sample(TextureCube<uint>, sampler, float3 location);
-native uint2 Sample(Texture1D<uint2>, sampler, float location);
-native uint2 Sample(Texture1DArray<uint2>, sampler, float2 location);
-native uint2 Sample(Texture2D<uint2>, sampler, float2 location);
-native uint2 Sample(Texture2D<uint2>, sampler, float2 location, int2 offset);
-native uint2 Sample(Texture2DArray<uint2>, sampler, float3 location);
-native uint2 Sample(Texture2DArray<uint2>, sampler, float3 location, int2 offset);
-native uint2 Sample(Texture3D<uint2>, sampler, float3 location);
-native uint2 Sample(Texture3D<uint2>, sampler, float3 location, int3 offset);
-native uint2 Sample(TextureCube<uint2>, sampler, float3 location);
-native uint3 Sample(Texture1D<uint3>, sampler, float location);
-native uint3 Sample(Texture1DArray<uint3>, sampler, float2 location);
-native uint3 Sample(Texture2D<uint3>, sampler, float2 location);
-native uint3 Sample(Texture2D<uint3>, sampler, float2 location, int2 offset);
-native uint3 Sample(Texture2DArray<uint3>, sampler, float3 location);
-native uint3 Sample(Texture2DArray<uint3>, sampler, float3 location, int2 offset);
-native uint3 Sample(Texture3D<uint3>, sampler, float3 location);
-native uint3 Sample(Texture3D<uint3>, sampler, float3 location, int3 offset);
-native uint3 Sample(TextureCube<uint3>, sampler, float3 location);
-native uint4 Sample(Texture1D<uint4>, sampler, float location);
-native uint4 Sample(Texture1DArray<uint4>, sampler, float2 location);
-native uint4 Sample(Texture2D<uint4>, sampler, float2 location);
-native uint4 Sample(Texture2D<uint4>, sampler, float2 location, int2 offset);
-native uint4 Sample(Texture2DArray<uint4>, sampler, float3 location);
-native uint4 Sample(Texture2DArray<uint4>, sampler, float3 location, int2 offset);
-native uint4 Sample(Texture3D<uint4>, sampler, float3 location);
-native uint4 Sample(Texture3D<uint4>, sampler, float3 location, int3 offset);
-native uint4 Sample(TextureCube<uint4>, sampler, float3 location);
-native short Sample(Texture1D<short>, sampler, float location);
-native short Sample(Texture1DArray<short>, sampler, float2 location);
-native short Sample(Texture2D<short>, sampler, float2 location);
-native short Sample(Texture2D<short>, sampler, float2 location, int2 offset);
-native short Sample(Texture2DArray<short>, sampler, float3 location);
-native short Sample(Texture2DArray<short>, sampler, float3 location, int2 offset);
-native short Sample(Texture3D<short>, sampler, float3 location);
-native short Sample(Texture3D<short>, sampler, float3 location, int3 offset);
-native short Sample(TextureCube<short>, sampler, float3 location);
-native short2 Sample(Texture1D<short2>, sampler, float location);
-native short2 Sample(Texture1DArray<short2>, sampler, float2 location);
-native short2 Sample(Texture2D<short2>, sampler, float2 location);
-native short2 Sample(Texture2D<short2>, sampler, float2 location, int2 offset);
-native short2 Sample(Texture2DArray<short2>, sampler, float3 location);
-native short2 Sample(Texture2DArray<short2>, sampler, float3 location, int2 offset);
-native short2 Sample(Texture3D<short2>, sampler, float3 location);
-native short2 Sample(Texture3D<short2>, sampler, float3 location, int3 offset);
-native short2 Sample(TextureCube<short2>, sampler, float3 location);
-native short3 Sample(Texture1D<short3>, sampler, float location);
-native short3 Sample(Texture1DArray<short3>, sampler, float2 location);
-native short3 Sample(Texture2D<short3>, sampler, float2 location);
-native short3 Sample(Texture2D<short3>, sampler, float2 location, int2 offset);
-native short3 Sample(Texture2DArray<short3>, sampler, float3 location);
-native short3 Sample(Texture2DArray<short3>, sampler, float3 location, int2 offset);
-native short3 Sample(Texture3D<short3>, sampler, float3 location);
-native short3 Sample(Texture3D<short3>, sampler, float3 location, int3 offset);
-native short3 Sample(TextureCube<short3>, sampler, float3 location);
-native short4 Sample(Texture1D<short4>, sampler, float location);
-native short4 Sample(Texture1DArray<short4>, sampler, float2 location);
-native short4 Sample(Texture2D<short4>, sampler, float2 location);
-native short4 Sample(Texture2D<short4>, sampler, float2 location, int2 offset);
-native short4 Sample(Texture2DArray<short4>, sampler, float3 location);
-native short4 Sample(Texture2DArray<short4>, sampler, float3 location, int2 offset);
-native short4 Sample(Texture3D<short4>, sampler, float3 location);
-native short4 Sample(Texture3D<short4>, sampler, float3 location, int3 offset);
-native short4 Sample(TextureCube<short4>, sampler, float3 location);
-native int Sample(Texture1D<int>, sampler, float location);
-native int Sample(Texture1DArray<int>, sampler, float2 location);
-native int Sample(Texture2D<int>, sampler, float2 location);
-native int Sample(Texture2D<int>, sampler, float2 location, int2 offset);
-native int Sample(Texture2DArray<int>, sampler, float3 location);
-native int Sample(Texture2DArray<int>, sampler, float3 location, int2 offset);
-native int Sample(Texture3D<int>, sampler, float3 location);
-native int Sample(Texture3D<int>, sampler, float3 location, int3 offset);
-native int Sample(TextureCube<int>, sampler, float3 location);
-native int2 Sample(Texture1D<int2>, sampler, float location);
-native int2 Sample(Texture1DArray<int2>, sampler, float2 location);
+/* Functions named operator.xwww */
+bool4 operator.xwww(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.xwww(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.xwww(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.xwww(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+char4 operator.xwww(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+short4 operator.xwww(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+int4 operator.xwww(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+half4 operator.xwww(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+float4 operator.xwww(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.zwyz */
+bool4 operator.zwyz(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.zwyz(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.zwyz(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.zwyz(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+char4 operator.zwyz(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+short4 operator.zwyz(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+int4 operator.zwyz(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+half4 operator.zwyz(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+float4 operator.zwyz(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named isordered */
+bool isordered(half x, half y) {
+    return (x == x) && (y == y);
+}
+bool2 isordered(half2 x, half2 y) {
+    bool2 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    return result;
+}
+bool3 isordered(half3 x, half3 y) {
+    bool3 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    result[2] = isordered(x[2], y[2]);
+    return result;
+}
+bool4 isordered(half4 x, half4 y) {
+    bool4 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    result[2] = isordered(x[2], y[2]);
+    result[3] = isordered(x[3], y[3]);
+    return result;
+}
+bool isordered(float x, float y) {
+    return (x == x) && (y == y);
+}
+bool2 isordered(float2 x, float2 y) {
+    bool2 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    return result;
+}
+bool3 isordered(float3 x, float3 y) {
+    bool3 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    result[2] = isordered(x[2], y[2]);
+    return result;
+}
+bool4 isordered(float4 x, float4 y) {
+    bool4 result;
+    result[0] = isordered(x[0], y[0]);
+    result[1] = isordered(x[1], y[1]);
+    result[2] = isordered(x[2], y[2]);
+    result[3] = isordered(x[3], y[3]);
+    return result;
+}
+
+/* Functions named operator.x */
+native bool operator.x(bool2);
+native bool operator.x(bool3);
+native bool operator.x(bool4);
+native uchar operator.x(uchar2);
+native uchar operator.x(uchar3);
+native uchar operator.x(uchar4);
+native ushort operator.x(ushort2);
+native ushort operator.x(ushort3);
+native ushort operator.x(ushort4);
+native uint operator.x(uint2);
+native uint operator.x(uint3);
+native uint operator.x(uint4);
+native char operator.x(char2);
+native char operator.x(char3);
+native char operator.x(char4);
+native short operator.x(short2);
+native short operator.x(short3);
+native short operator.x(short4);
+native int operator.x(int2);
+native int operator.x(int3);
+native int operator.x(int4);
+native half operator.x(half2);
+native half operator.x(half3);
+native half operator.x(half4);
+native float operator.x(float2);
+native float operator.x(float3);
+native float operator.x(float4);
+
+/* Functions named operator.xywx */
+bool4 operator.xywx(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.xywx(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.xywx(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.xywx(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+char4 operator.xywx(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+short4 operator.xywx(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+int4 operator.xywx(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+half4 operator.xywx(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+float4 operator.xywx(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.y;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.wyxy */
+bool4 operator.wyxy(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.wyxy(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.wyxy(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.wyxy(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.wyxy(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.wyxy(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.wyxy(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.wyxy(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.wyxy(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named transpose */
+half transpose(half x) {
+    return x;
+}
+half2x2 transpose(half2x2 x) {
+    half2x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    return result;
+}
+half2x3 transpose(half3x2 x) {
+    half2x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    return result;
+}
+half2x4 transpose(half4x2 x) {
+    half2x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    return result;
+}
+half3x2 transpose(half2x3 x) {
+    half3x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    return result;
+}
+half3x3 transpose(half3x3 x) {
+    half3x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    return result;
+}
+half3x4 transpose(half4x3 x) {
+    half3x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[2][3] = x[3][2];
+    return result;
+}
+half4x2 transpose(half2x4 x) {
+    half4x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    return result;
+}
+half4x3 transpose(half3x4 x) {
+    half4x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    result[3][2] = x[2][3];
+    return result;
+}
+half4x4 transpose(half4x4 x) {
+    half4x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[2][3] = x[3][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    result[3][2] = x[2][3];
+    result[3][3] = x[3][3];
+    return result;
+}
+float transpose(float x) {
+    return x;
+}
+float2x2 transpose(float2x2 x) {
+    float2x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    return result;
+}
+float2x3 transpose(float3x2 x) {
+    float2x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    return result;
+}
+float2x4 transpose(float4x2 x) {
+    float2x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    return result;
+}
+float3x2 transpose(float2x3 x) {
+    float3x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    return result;
+}
+float3x3 transpose(float3x3 x) {
+    float3x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    return result;
+}
+float3x4 transpose(float4x3 x) {
+    float3x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[2][3] = x[3][2];
+    return result;
+}
+float4x2 transpose(float2x4 x) {
+    float4x2 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    return result;
+}
+float4x3 transpose(float3x4 x) {
+    float4x3 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    result[3][2] = x[2][3];
+    return result;
+}
+float4x4 transpose(float4x4 x) {
+    float4x4 result;
+    result[0][0] = x[0][0];
+    result[0][1] = x[1][0];
+    result[0][2] = x[2][0];
+    result[0][3] = x[3][0];
+    result[1][0] = x[0][1];
+    result[1][1] = x[1][1];
+    result[1][2] = x[2][1];
+    result[1][3] = x[3][1];
+    result[2][0] = x[0][2];
+    result[2][1] = x[1][2];
+    result[2][2] = x[2][2];
+    result[2][3] = x[3][2];
+    result[3][0] = x[0][3];
+    result[3][1] = x[1][3];
+    result[3][2] = x[2][3];
+    result[3][3] = x[3][3];
+    return result;
+}
+
+
+/* Functions named operator.wyxz= */
+bool4 operator.wyxz=(bool4 v, bool4 c) {
+    bool4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+uchar4 operator.wyxz=(uchar4 v, uchar4 c) {
+    uchar4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+ushort4 operator.wyxz=(ushort4 v, ushort4 c) {
+    ushort4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+uint4 operator.wyxz=(uint4 v, uint4 c) {
+    uint4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+char4 operator.wyxz=(char4 v, char4 c) {
+    char4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+short4 operator.wyxz=(short4 v, short4 c) {
+    short4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+int4 operator.wyxz=(int4 v, int4 c) {
+    int4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+half4 operator.wyxz=(half4 v, half4 c) {
+    half4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+float4 operator.wyxz=(float4 v, float4 c) {
+    float4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.z = c.w;
+    return result;
+}
+
+/* Functions named operator.yyxz */
+bool4 operator.yyxz(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+bool4 operator.yyxz(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yyxz(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yyxz(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yyxz(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yyxz(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yyxz(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yyxz(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yyxz(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yyxz(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yyxz(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yyxz(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yyxz(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yyxz(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yyxz(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yyxz(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yyxz(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yyxz(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named operator.zx */
+bool2 operator.zx(bool3 v) {
+    bool2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+bool2 operator.zx(bool4 v) {
+    bool2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+uchar2 operator.zx(uchar3 v) {
+    uchar2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+uchar2 operator.zx(uchar4 v) {
+    uchar2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+ushort2 operator.zx(ushort3 v) {
+    ushort2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+ushort2 operator.zx(ushort4 v) {
+    ushort2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+uint2 operator.zx(uint3 v) {
+    uint2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+uint2 operator.zx(uint4 v) {
+    uint2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+char2 operator.zx(char3 v) {
+    char2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+char2 operator.zx(char4 v) {
+    char2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+short2 operator.zx(short3 v) {
+    short2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+short2 operator.zx(short4 v) {
+    short2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+int2 operator.zx(int3 v) {
+    int2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+int2 operator.zx(int4 v) {
+    int2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+half2 operator.zx(half3 v) {
+    half2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+half2 operator.zx(half4 v) {
+    half2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+float2 operator.zx(float3 v) {
+    float2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+float2 operator.zx(float4 v) {
+    float2 result;
+    result.x = v.z;
+    result.y = v.x;
+    return result;
+}
+
+/* Functions named InterlockedAdd */
+native void InterlockedAdd(device atomic_uint*, uint, thread uint*);
+native void InterlockedAdd(device atomic_int*, int, thread int*);
+native void InterlockedAdd(device atomic_uint*, uint, device uint*);
+native void InterlockedAdd(device atomic_int*, int, device int*);
+native void InterlockedAdd(device atomic_uint*, uint, threadgroup uint*);
+native void InterlockedAdd(device atomic_int*, int, threadgroup int*);
+native void InterlockedAdd(threadgroup atomic_uint*, uint, thread uint*);
+native void InterlockedAdd(threadgroup atomic_int*, int, thread int*);
+native void InterlockedAdd(threadgroup atomic_uint*, uint, device uint*);
+native void InterlockedAdd(threadgroup atomic_int*, int, device int*);
+native void InterlockedAdd(threadgroup atomic_uint*, uint, threadgroup uint*);
+native void InterlockedAdd(threadgroup atomic_int*, int, threadgroup int*);
+
+/* Functions named operator.xzyx */
+bool4 operator.xzyx(bool3 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+bool4 operator.xzyx(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.xzyx(uchar3 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.xzyx(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.xzyx(ushort3 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.xzyx(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.xzyx(uint3 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.xzyx(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.xzyx(char3 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.xzyx(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.xzyx(short3 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.xzyx(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.xzyx(int3 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.xzyx(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.xzyx(half3 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.xzyx(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.xzyx(float3 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.xzyx(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.wwzw */
+bool4 operator.wwzw(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.wwzw(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.wwzw(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.wwzw(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+char4 operator.wwzw(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+short4 operator.wwzw(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+int4 operator.wwzw(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+half4 operator.wwzw(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+float4 operator.wwzw(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.ywwy */
+bool4 operator.ywwy(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.ywwy(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.ywwy(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.ywwy(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+char4 operator.ywwy(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+short4 operator.ywwy(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+int4 operator.ywwy(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+half4 operator.ywwy(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+float4 operator.ywwy(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.xzwx */
+bool4 operator.xzwx(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.xzwx(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.xzwx(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.xzwx(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+char4 operator.xzwx(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+short4 operator.xzwx(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+int4 operator.xzwx(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+half4 operator.xzwx(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+float4 operator.xzwx(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named saturate */
+half saturate(half x) {
+    return clamp(x, 0, 1);
+}
+half2 saturate(half2 x) {
+    half2 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    return result;
+}
+half3 saturate(half3 x) {
+    half3 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    result[2] = saturate(x[2]);
+    return result;
+}
+half4 saturate(half4 x) {
+    half4 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    result[2] = saturate(x[2]);
+    result[3] = saturate(x[3]);
+    return result;
+}
+half2x2 saturate(half2x2 x) {
+    half2x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    return result;
+}
+half2x3 saturate(half2x3 x) {
+    half2x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    return result;
+}
+half2x4 saturate(half2x4 x) {
+    half2x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    return result;
+}
+half3x2 saturate(half3x2 x) {
+    half3x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    return result;
+}
+half3x3 saturate(half3x3 x) {
+    half3x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    return result;
+}
+half3x4 saturate(half3x4 x) {
+    half3x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[2][3] = saturate(x[2][3]);
+    return result;
+}
+half4x2 saturate(half4x2 x) {
+    half4x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    return result;
+}
+half4x3 saturate(half4x3 x) {
+    half4x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    result[3][2] = saturate(x[3][2]);
+    return result;
+}
+half4x4 saturate(half4x4 x) {
+    half4x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[2][3] = saturate(x[2][3]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    result[3][2] = saturate(x[3][2]);
+    result[3][3] = saturate(x[3][3]);
+    return result;
+}
+float saturate(float x) {
+    return clamp(x, 0, 1);
+}
+float2 saturate(float2 x) {
+    float2 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    return result;
+}
+float3 saturate(float3 x) {
+    float3 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    result[2] = saturate(x[2]);
+    return result;
+}
+float4 saturate(float4 x) {
+    float4 result;
+    result[0] = saturate(x[0]);
+    result[1] = saturate(x[1]);
+    result[2] = saturate(x[2]);
+    result[3] = saturate(x[3]);
+    return result;
+}
+float2x2 saturate(float2x2 x) {
+    float2x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    return result;
+}
+float2x3 saturate(float2x3 x) {
+    float2x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    return result;
+}
+float2x4 saturate(float2x4 x) {
+    float2x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    return result;
+}
+float3x2 saturate(float3x2 x) {
+    float3x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    return result;
+}
+float3x3 saturate(float3x3 x) {
+    float3x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    return result;
+}
+float3x4 saturate(float3x4 x) {
+    float3x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[2][3] = saturate(x[2][3]);
+    return result;
+}
+float4x2 saturate(float4x2 x) {
+    float4x2 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    return result;
+}
+float4x3 saturate(float4x3 x) {
+    float4x3 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    result[3][2] = saturate(x[3][2]);
+    return result;
+}
+float4x4 saturate(float4x4 x) {
+    float4x4 result;
+    result[0][0] = saturate(x[0][0]);
+    result[0][1] = saturate(x[0][1]);
+    result[0][2] = saturate(x[0][2]);
+    result[0][3] = saturate(x[0][3]);
+    result[1][0] = saturate(x[1][0]);
+    result[1][1] = saturate(x[1][1]);
+    result[1][2] = saturate(x[1][2]);
+    result[1][3] = saturate(x[1][3]);
+    result[2][0] = saturate(x[2][0]);
+    result[2][1] = saturate(x[2][1]);
+    result[2][2] = saturate(x[2][2]);
+    result[2][3] = saturate(x[2][3]);
+    result[3][0] = saturate(x[3][0]);
+    result[3][1] = saturate(x[3][1]);
+    result[3][2] = saturate(x[3][2]);
+    result[3][3] = saturate(x[3][3]);
+    return result;
+}
+
+/* Functions named mad */
+half mad(half x, half y, half z) {
+    return x * y + z;
+}
+half2 mad(half2 x, half2 y, half2 z) {
+    half2 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    return result;
+}
+half3 mad(half3 x, half3 y, half3 z) {
+    half3 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    result[2] = mad(x[2], y[2], z[2]);
+    return result;
+}
+half4 mad(half4 x, half4 y, half4 z) {
+    half4 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    result[2] = mad(x[2], y[2], z[2]);
+    result[3] = mad(x[3], y[3], z[3]);
+    return result;
+}
+half2x2 mad(half2x2 x, half2x2 y, half2x2 z) {
+    half2x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    return result;
+}
+half2x3 mad(half2x3 x, half2x3 y, half2x3 z) {
+    half2x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    return result;
+}
+half2x4 mad(half2x4 x, half2x4 y, half2x4 z) {
+    half2x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    return result;
+}
+half3x2 mad(half3x2 x, half3x2 y, half3x2 z) {
+    half3x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    return result;
+}
+half3x3 mad(half3x3 x, half3x3 y, half3x3 z) {
+    half3x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    return result;
+}
+half3x4 mad(half3x4 x, half3x4 y, half3x4 z) {
+    half3x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[2][3] = mad(x[2][3], y[2][3], z[2][3]);
+    return result;
+}
+half4x2 mad(half4x2 x, half4x2 y, half4x2 z) {
+    half4x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    return result;
+}
+half4x3 mad(half4x3 x, half4x3 y, half4x3 z) {
+    half4x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    result[3][2] = mad(x[3][2], y[3][2], z[3][2]);
+    return result;
+}
+half4x4 mad(half4x4 x, half4x4 y, half4x4 z) {
+    half4x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[2][3] = mad(x[2][3], y[2][3], z[2][3]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    result[3][2] = mad(x[3][2], y[3][2], z[3][2]);
+    result[3][3] = mad(x[3][3], y[3][3], z[3][3]);
+    return result;
+}
+
+float mad(float x, float y, float z) {
+    return x * y + z;
+}
+float2 mad(float2 x, float2 y, float2 z) {
+    float2 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    return result;
+}
+float3 mad(float3 x, float3 y, float3 z) {
+    float3 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    result[2] = mad(x[2], y[2], z[2]);
+    return result;
+}
+float4 mad(float4 x, float4 y, float4 z) {
+    float4 result;
+    result[0] = mad(x[0], y[0], z[0]);
+    result[1] = mad(x[1], y[1], z[1]);
+    result[2] = mad(x[2], y[2], z[2]);
+    result[3] = mad(x[3], y[3], z[3]);
+    return result;
+}
+float2x2 mad(float2x2 x, float2x2 y, float2x2 z) {
+    float2x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    return result;
+}
+float2x3 mad(float2x3 x, float2x3 y, float2x3 z) {
+    float2x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    return result;
+}
+float2x4 mad(float2x4 x, float2x4 y, float2x4 z) {
+    float2x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    return result;
+}
+float3x2 mad(float3x2 x, float3x2 y, float3x2 z) {
+    float3x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    return result;
+}
+float3x3 mad(float3x3 x, float3x3 y, float3x3 z) {
+    float3x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    return result;
+}
+float3x4 mad(float3x4 x, float3x4 y, float3x4 z) {
+    float3x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[2][3] = mad(x[2][3], y[2][3], z[2][3]);
+    return result;
+}
+float4x2 mad(float4x2 x, float4x2 y, float4x2 z) {
+    float4x2 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    return result;
+}
+float4x3 mad(float4x3 x, float4x3 y, float4x3 z) {
+    float4x3 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    result[3][2] = mad(x[3][2], y[3][2], z[3][2]);
+    return result;
+}
+float4x4 mad(float4x4 x, float4x4 y, float4x4 z) {
+    float4x4 result;
+    result[0][0] = mad(x[0][0], y[0][0], z[0][0]);
+    result[0][1] = mad(x[0][1], y[0][1], z[0][1]);
+    result[0][2] = mad(x[0][2], y[0][2], z[0][2]);
+    result[0][3] = mad(x[0][3], y[0][3], z[0][3]);
+    result[1][0] = mad(x[1][0], y[1][0], z[1][0]);
+    result[1][1] = mad(x[1][1], y[1][1], z[1][1]);
+    result[1][2] = mad(x[1][2], y[1][2], z[1][2]);
+    result[1][3] = mad(x[1][3], y[1][3], z[1][3]);
+    result[2][0] = mad(x[2][0], y[2][0], z[2][0]);
+    result[2][1] = mad(x[2][1], y[2][1], z[2][1]);
+    result[2][2] = mad(x[2][2], y[2][2], z[2][2]);
+    result[2][3] = mad(x[2][3], y[2][3], z[2][3]);
+    result[3][0] = mad(x[3][0], y[3][0], z[3][0]);
+    result[3][1] = mad(x[3][1], y[3][1], z[3][1]);
+    result[3][2] = mad(x[3][2], y[3][2], z[3][2]);
+    result[3][3] = mad(x[3][3], y[3][3], z[3][3]);
+    return result;
+}
+
+
+/* Functions named modf */
+half modf(half x, thread half* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - half(result);
+    return half(result);
+}
+half2 modf(half2 x, thread half2* y) {
+    half2 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+half3 modf(half3 x, thread half3* y) {
+    half3 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+half4 modf(half4 x, thread half4* y) {
+    half4 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+half2x2 modf(half2x2 x, thread half2x2* y) {
+    half2x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+half2x3 modf(half2x3 x, thread half2x3* y) {
+    half2x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+half2x4 modf(half2x4 x, thread half2x4* y) {
+    half2x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+half3x2 modf(half3x2 x, thread half3x2* y) {
+    half3x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+half3x3 modf(half3x3 x, thread half3x3* y) {
+    half3x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+half3x4 modf(half3x4 x, thread half3x4* y) {
+    half3x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+half4x2 modf(half4x2 x, thread half4x2* y) {
+    half4x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+half4x3 modf(half4x3 x, thread half4x3* y) {
+    half4x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+half4x4 modf(half4x4 x, thread half4x4* y) {
+    half4x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+float modf(float x, thread float* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - float(result);
+    return float(result);
+}
+float2 modf(float2 x, thread float2* y) {
+    float2 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+float3 modf(float3 x, thread float3* y) {
+    float3 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+float4 modf(float4 x, thread float4* y) {
+    float4 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+float2x2 modf(float2x2 x, thread float2x2* y) {
+    float2x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+float2x3 modf(float2x3 x, thread float2x3* y) {
+    float2x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+float2x4 modf(float2x4 x, thread float2x4* y) {
+    float2x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+float3x2 modf(float3x2 x, thread float3x2* y) {
+    float3x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+float3x3 modf(float3x3 x, thread float3x3* y) {
+    float3x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+float3x4 modf(float3x4 x, thread float3x4* y) {
+    float3x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+float4x2 modf(float4x2 x, thread float4x2* y) {
+    float4x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+float4x3 modf(float4x3 x, thread float4x3* y) {
+    float4x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+float4x4 modf(float4x4 x, thread float4x4* y) {
+    float4x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+half modf(half x, device half* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - half(result);
+    return half(result);
+}
+half2 modf(half2 x, device half2* y) {
+    half2 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+half3 modf(half3 x, device half3* y) {
+    half3 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+half4 modf(half4 x, device half4* y) {
+    half4 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+half2x2 modf(half2x2 x, device half2x2* y) {
+    half2x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+half2x3 modf(half2x3 x, device half2x3* y) {
+    half2x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+half2x4 modf(half2x4 x, device half2x4* y) {
+    half2x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+half3x2 modf(half3x2 x, device half3x2* y) {
+    half3x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+half3x3 modf(half3x3 x, device half3x3* y) {
+    half3x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+half3x4 modf(half3x4 x, device half3x4* y) {
+    half3x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+half4x2 modf(half4x2 x, device half4x2* y) {
+    half4x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+half4x3 modf(half4x3 x, device half4x3* y) {
+    half4x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+half4x4 modf(half4x4 x, device half4x4* y) {
+    half4x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+float modf(float x, device float* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - float(result);
+    return float(result);
+}
+float2 modf(float2 x, device float2* y) {
+    float2 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+float3 modf(float3 x, device float3* y) {
+    float3 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+float4 modf(float4 x, device float4* y) {
+    float4 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+float2x2 modf(float2x2 x, device float2x2* y) {
+    float2x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+float2x3 modf(float2x3 x, device float2x3* y) {
+    float2x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+float2x4 modf(float2x4 x, device float2x4* y) {
+    float2x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+float3x2 modf(float3x2 x, device float3x2* y) {
+    float3x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+float3x3 modf(float3x3 x, device float3x3* y) {
+    float3x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+float3x4 modf(float3x4 x, device float3x4* y) {
+    float3x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+float4x2 modf(float4x2 x, device float4x2* y) {
+    float4x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+float4x3 modf(float4x3 x, device float4x3* y) {
+    float4x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+float4x4 modf(float4x4 x, device float4x4* y) {
+    float4x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+half modf(half x, threadgroup half* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - half(result);
+    return half(result);
+}
+half2 modf(half2 x, threadgroup half2* y) {
+    half2 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+half3 modf(half3 x, threadgroup half3* y) {
+    half3 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+half4 modf(half4 x, threadgroup half4* y) {
+    half4 result;
+    half buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+half2x2 modf(half2x2 x, threadgroup half2x2* y) {
+    half2x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+half2x3 modf(half2x3 x, threadgroup half2x3* y) {
+    half2x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+half2x4 modf(half2x4 x, threadgroup half2x4* y) {
+    half2x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+half3x2 modf(half3x2 x, threadgroup half3x2* y) {
+    half3x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+half3x3 modf(half3x3 x, threadgroup half3x3* y) {
+    half3x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+half3x4 modf(half3x4 x, threadgroup half3x4* y) {
+    half3x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+half4x2 modf(half4x2 x, threadgroup half4x2* y) {
+    half4x2 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+half4x3 modf(half4x3 x, threadgroup half4x3* y) {
+    half4x3 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+half4x4 modf(half4x4 x, threadgroup half4x4* y) {
+    half4x4 result;
+    half buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+float modf(float x, threadgroup float* ip) {
+    uint result = uint(x);
+    if (ip != null)
+        *ip = x - float(result);
+    return float(result);
+}
+float2 modf(float2 x, threadgroup float2* y) {
+    float2 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    return result;
+}
+float3 modf(float3 x, threadgroup float3* y) {
+    float3 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    return result;
+}
+float4 modf(float4 x, threadgroup float4* y) {
+    float4 result;
+    float buffer;
+    result[0] = modf(x[0], &buffer);
+    if (y != null)
+        (*y)[0] = buffer;
+    result[1] = modf(x[1], &buffer);
+    if (y != null)
+        (*y)[1] = buffer;
+    result[2] = modf(x[2], &buffer);
+    if (y != null)
+        (*y)[2] = buffer;
+    result[3] = modf(x[3], &buffer);
+    if (y != null)
+        (*y)[3] = buffer;
+    return result;
+}
+float2x2 modf(float2x2 x, threadgroup float2x2* y) {
+    float2x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    return result;
+}
+float2x3 modf(float2x3 x, threadgroup float2x3* y) {
+    float2x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    return result;
+}
+float2x4 modf(float2x4 x, threadgroup float2x4* y) {
+    float2x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    return result;
+}
+float3x2 modf(float3x2 x, threadgroup float3x2* y) {
+    float3x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    return result;
+}
+float3x3 modf(float3x3 x, threadgroup float3x3* y) {
+    float3x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    return result;
+}
+float3x4 modf(float3x4 x, threadgroup float3x4* y) {
+    float3x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    return result;
+}
+float4x2 modf(float4x2 x, threadgroup float4x2* y) {
+    float4x2 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    return result;
+}
+float4x3 modf(float4x3 x, threadgroup float4x3* y) {
+    float4x3 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    return result;
+}
+float4x4 modf(float4x4 x, threadgroup float4x4* y) {
+    float4x4 result;
+    float buffer;
+    result[0][0] = modf(x[0][0], &buffer);
+    if (y != null)
+        (*y)[0][0] = buffer;
+    result[0][1] = modf(x[0][1], &buffer);
+    if (y != null)
+        (*y)[0][1] = buffer;
+    result[0][2] = modf(x[0][2], &buffer);
+    if (y != null)
+        (*y)[0][2] = buffer;
+    result[0][3] = modf(x[0][3], &buffer);
+    if (y != null)
+        (*y)[0][3] = buffer;
+    result[1][0] = modf(x[1][0], &buffer);
+    if (y != null)
+        (*y)[1][0] = buffer;
+    result[1][1] = modf(x[1][1], &buffer);
+    if (y != null)
+        (*y)[1][1] = buffer;
+    result[1][2] = modf(x[1][2], &buffer);
+    if (y != null)
+        (*y)[1][2] = buffer;
+    result[1][3] = modf(x[1][3], &buffer);
+    if (y != null)
+        (*y)[1][3] = buffer;
+    result[2][0] = modf(x[2][0], &buffer);
+    if (y != null)
+        (*y)[2][0] = buffer;
+    result[2][1] = modf(x[2][1], &buffer);
+    if (y != null)
+        (*y)[2][1] = buffer;
+    result[2][2] = modf(x[2][2], &buffer);
+    if (y != null)
+        (*y)[2][2] = buffer;
+    result[2][3] = modf(x[2][3], &buffer);
+    if (y != null)
+        (*y)[2][3] = buffer;
+    result[3][0] = modf(x[3][0], &buffer);
+    if (y != null)
+        (*y)[3][0] = buffer;
+    result[3][1] = modf(x[3][1], &buffer);
+    if (y != null)
+        (*y)[3][1] = buffer;
+    result[3][2] = modf(x[3][2], &buffer);
+    if (y != null)
+        (*y)[3][2] = buffer;
+    result[3][3] = modf(x[3][3], &buffer);
+    if (y != null)
+        (*y)[3][3] = buffer;
+    return result;
+}
+
+
+/* Functions named operator.wy= */
+bool4 operator.wy=(bool4 v, bool2 c) {
+    bool4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+uchar4 operator.wy=(uchar4 v, uchar2 c) {
+    uchar4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+ushort4 operator.wy=(ushort4 v, ushort2 c) {
+    ushort4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+uint4 operator.wy=(uint4 v, uint2 c) {
+    uint4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+char4 operator.wy=(char4 v, char2 c) {
+    char4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+short4 operator.wy=(short4 v, short2 c) {
+    short4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+int4 operator.wy=(int4 v, int2 c) {
+    int4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+half4 operator.wy=(half4 v, half2 c) {
+    half4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+float4 operator.wy=(float4 v, float2 c) {
+    float4 result = v;
+    result.w = c.x;
+    result.y = c.y;
+    return result;
+}
+
+/* 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;
+}
+uchar2 operator[]=(uchar2 v, uint index, uchar a) {
+    switch (index) {
+        case 0:
+            v.x = a;
+            break;
+        case 1:
+            v.y = a;
+            break;
+        default:
+            break;
+    }
+    return v;
+}
+uchar3 operator[]=(uchar3 v, uint index, uchar 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;
+}
+uchar4 operator[]=(uchar4 v, uint index, uchar 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;
+}
+ushort2 operator[]=(ushort2 v, uint index, ushort a) {
+    switch (index) {
+        case 0:
+            v.x = a;
+            break;
+        case 1:
+            v.y = a;
+            break;
+        default:
+            break;
+    }
+    return v;
+}
+ushort3 operator[]=(ushort3 v, uint index, ushort 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;
+}
+ushort4 operator[]=(ushort4 v, uint index, ushort 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;
+}
+char2 operator[]=(char2 v, uint index, char a) {
+    switch (index) {
+        case 0:
+            v.x = a;
+            break;
+        case 1:
+            v.y = a;
+            break;
+        default:
+            break;
+    }
+    return v;
+}
+char3 operator[]=(char3 v, uint index, char 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;
+}
+char4 operator[]=(char4 v, uint index, char 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;
+}
+short2 operator[]=(short2 v, uint index, short a) {
+    switch (index) {
+        case 0:
+            v.x = a;
+            break;
+        case 1:
+            v.y = a;
+            break;
+        default:
+            break;
+    }
+    return v;
+}
+short3 operator[]=(short3 v, uint index, short 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;
+}
+short4 operator[]=(short4 v, uint index, short 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;
+}
+half2 operator[]=(half2 v, uint index, half a) {
+    switch (index) {
+        case 0:
+            v.x = a;
+            break;
+        case 1:
+            v.y = a;
+            break;
+        default:
+            break;
+    }
+    return v;
+}
+half3 operator[]=(half3 v, uint index, half 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;
+}
+half4 operator[]=(half4 v, uint index, half 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 half2x2 operator[]=(half2x2, uint, half2);
+native half2x3 operator[]=(half2x3, uint, half3);
+native half2x4 operator[]=(half2x4, uint, half4);
+native half3x2 operator[]=(half3x2, uint, half2);
+native half3x3 operator[]=(half3x3, uint, half3);
+native half3x4 operator[]=(half3x4, uint, half4);
+native half4x2 operator[]=(half4x2, uint, half2);
+native half4x3 operator[]=(half4x3, uint, half3);
+native half4x4 operator[]=(half4x4, uint, half4);
+native float2x2 operator[]=(float2x2, uint, float2);
+native float2x3 operator[]=(float2x3, uint, float3);
+native float2x4 operator[]=(float2x4, uint, float4);
+native float3x2 operator[]=(float3x2, uint, float2);
+native float3x3 operator[]=(float3x3, uint, float3);
+native float3x4 operator[]=(float3x4, uint, float4);
+native float4x2 operator[]=(float4x2, uint, float2);
+native float4x3 operator[]=(float4x3, uint, float3);
+native float4x4 operator[]=(float4x4, uint, float4);
+
+
+/* Functions named operator.yxyx */
+bool4 operator.yxyx(bool2 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+bool4 operator.yxyx(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+bool4 operator.yxyx(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.yxyx(uchar2 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.yxyx(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.yxyx(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.yxyx(ushort2 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.yxyx(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.yxyx(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.yxyx(uint2 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.yxyx(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.yxyx(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.yxyx(char2 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.yxyx(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.yxyx(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.yxyx(short2 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.yxyx(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.yxyx(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.yxyx(int2 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.yxyx(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.yxyx(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.yxyx(half2 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.yxyx(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.yxyx(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.yxyx(float2 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.yxyx(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.yxyx(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.zwxy */
+bool4 operator.zwxy(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.zwxy(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.zwxy(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.zwxy(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.zwxy(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.zwxy(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.zwxy(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.zwxy(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.zwxy(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.wyyw */
+bool4 operator.wyyw(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.wyyw(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.wyyw(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.wyyw(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+char4 operator.wyyw(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+short4 operator.wyyw(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+int4 operator.wyyw(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+half4 operator.wyyw(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+float4 operator.wyyw(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.xxxw */
+bool4 operator.xxxw(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.xxxw(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.xxxw(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.xxxw(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+char4 operator.xxxw(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+short4 operator.xxxw(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+int4 operator.xxxw(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+half4 operator.xxxw(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+float4 operator.xxxw(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.x;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.ywy */
+bool3 operator.ywy(bool4 v) {
+    bool3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+uchar3 operator.ywy(uchar4 v) {
+    uchar3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+ushort3 operator.ywy(ushort4 v) {
+    ushort3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+uint3 operator.ywy(uint4 v) {
+    uint3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+char3 operator.ywy(char4 v) {
+    char3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+short3 operator.ywy(short4 v) {
+    short3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+int3 operator.ywy(int4 v) {
+    int3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+half3 operator.ywy(half4 v) {
+    half3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+float3 operator.ywy(float4 v) {
+    float3 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+
+/* Functions named operator.xyzw= */
+bool4 operator.xyzw=(bool4 v, bool4 c) {
+    bool4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+uchar4 operator.xyzw=(uchar4 v, uchar4 c) {
+    uchar4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+ushort4 operator.xyzw=(ushort4 v, ushort4 c) {
+    ushort4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+uint4 operator.xyzw=(uint4 v, uint4 c) {
+    uint4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+char4 operator.xyzw=(char4 v, char4 c) {
+    char4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+short4 operator.xyzw=(short4 v, short4 c) {
+    short4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+int4 operator.xyzw=(int4 v, int4 c) {
+    int4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+half4 operator.xyzw=(half4 v, half4 c) {
+    half4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+float4 operator.xyzw=(float4 v, float4 c) {
+    float4 result = v;
+    result.x = c.x;
+    result.y = c.y;
+    result.z = c.z;
+    result.w = c.w;
+    return result;
+}
+
+/* Functions named operator.xzww */
+bool4 operator.xzww(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.xzww(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.xzww(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.xzww(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+char4 operator.xzww(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+short4 operator.xzww(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+int4 operator.xzww(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+half4 operator.xzww(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+float4 operator.xzww(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.xzwy */
+bool4 operator.xzwy(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.xzwy(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.xzwy(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.xzwy(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+char4 operator.xzwy(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+short4 operator.xzwy(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+int4 operator.xzwy(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+half4 operator.xzwy(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+float4 operator.xzwy(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.z;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.wwwz */
+bool4 operator.wwwz(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.wwwz(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.wwwz(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.wwwz(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+char4 operator.wwwz(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+short4 operator.wwwz(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+int4 operator.wwwz(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+half4 operator.wwwz(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+float4 operator.wwwz(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named operator.zxzx */
+bool4 operator.zxzx(bool3 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+bool4 operator.zxzx(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.zxzx(uchar3 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.zxzx(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.zxzx(ushort3 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.zxzx(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.zxzx(uint3 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.zxzx(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+char4 operator.zxzx(char3 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+char4 operator.zxzx(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+short4 operator.zxzx(short3 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+short4 operator.zxzx(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+int4 operator.zxzx(int3 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+int4 operator.zxzx(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+half4 operator.zxzx(half3 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+half4 operator.zxzx(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+float4 operator.zxzx(float3 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+float4 operator.zxzx(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.zyx= */
+bool3 operator.zyx=(bool3 v, bool3 c) {
+    bool3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+bool4 operator.zyx=(bool4 v, bool3 c) {
+    bool4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+uchar3 operator.zyx=(uchar3 v, uchar3 c) {
+    uchar3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+uchar4 operator.zyx=(uchar4 v, uchar3 c) {
+    uchar4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+ushort3 operator.zyx=(ushort3 v, ushort3 c) {
+    ushort3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+ushort4 operator.zyx=(ushort4 v, ushort3 c) {
+    ushort4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+uint3 operator.zyx=(uint3 v, uint3 c) {
+    uint3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+uint4 operator.zyx=(uint4 v, uint3 c) {
+    uint4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+char3 operator.zyx=(char3 v, char3 c) {
+    char3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+char4 operator.zyx=(char4 v, char3 c) {
+    char4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+short3 operator.zyx=(short3 v, short3 c) {
+    short3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+short4 operator.zyx=(short4 v, short3 c) {
+    short4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+int3 operator.zyx=(int3 v, int3 c) {
+    int3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+int4 operator.zyx=(int4 v, int3 c) {
+    int4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+half3 operator.zyx=(half3 v, half3 c) {
+    half3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+half4 operator.zyx=(half4 v, half3 c) {
+    half4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+float3 operator.zyx=(float3 v, float3 c) {
+    float3 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+float4 operator.zyx=(float4 v, float3 c) {
+    float4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    return result;
+}
+
+/* Functions named InterlockedMin */
+native void InterlockedMin(device atomic_uint*, uint, thread uint*);
+native void InterlockedMin(device atomic_int*, int, thread int*);
+native void InterlockedMin(device atomic_uint*, uint, device uint*);
+native void InterlockedMin(device atomic_int*, int, device int*);
+native void InterlockedMin(device atomic_uint*, uint, threadgroup uint*);
+native void InterlockedMin(device atomic_int*, int, threadgroup int*);
+native void InterlockedMin(threadgroup atomic_uint*, uint, thread uint*);
+native void InterlockedMin(threadgroup atomic_int*, int, thread int*);
+native void InterlockedMin(threadgroup atomic_uint*, uint, device uint*);
+native void InterlockedMin(threadgroup atomic_int*, int, device int*);
+native void InterlockedMin(threadgroup atomic_uint*, uint, threadgroup uint*);
+native void InterlockedMin(threadgroup atomic_int*, int, threadgroup int*);
+
+/* Functions named length */
+half length(half x) {
+    return sqrt(dot(x, x));
+}
+half length(half2 x) {
+    return sqrt(dot(x, x));
+}
+half length(half3 x) {
+    return sqrt(dot(x, x));
+}
+half length(half4 x) {
+    return sqrt(dot(x, x));
+}
+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));
+}
+
+
+/* Functions named operator.xwzy */
+bool4 operator.xwzy(bool4 v) {
+    bool4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.xwzy(uchar4 v) {
+    uchar4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.xwzy(ushort4 v) {
+    ushort4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.xwzy(uint4 v) {
+    uint4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+char4 operator.xwzy(char4 v) {
+    char4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+short4 operator.xwzy(short4 v) {
+    short4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+int4 operator.xwzy(int4 v) {
+    int4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+half4 operator.xwzy(half4 v) {
+    half4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+float4 operator.xwzy(float4 v) {
+    float4 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator-- */
+uchar operator--(uchar value) {
+    return value - 1;
+}
+ushort operator--(ushort value) {
+    return value - 1;
+}
+uint operator--(uint value) {
+    return value - 1;
+}
+char operator--(char value) {
+    return value - 1;
+}
+short operator--(short value) {
+    return value - 1;
+}
+int operator--(int value) {
+    return value - 1;
+}
+half operator--(half value) {
+    return value - 1;
+}
+float operator--(float value) {
+    return value - 1;
+}
+
+/* Functions named operator<< */
+native int operator<<(int, uint);
+native uint operator<<(uint, uint);
+uchar operator<<(uchar a, uint b) {
+    return uchar(uint(a) << (b & 255));
+}
+ushort operator<<(ushort a, uint b) {
+    return ushort(uint(a) << (b & 65535));
+}
+char operator<<(char a, uint b) {
+    return char(int(a) << (b & 255));
+}
+short operator<<(short a, uint b) {
+    return short(int(a) << (b & 65535));
+}
+
+/* Functions named operator.wwyz */
+bool4 operator.wwyz(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.wwyz(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.wwyz(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.wwyz(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+char4 operator.wwyz(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+short4 operator.wwyz(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+int4 operator.wwyz(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+half4 operator.wwyz(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+float4 operator.wwyz(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named operator.xxy */
+bool3 operator.xxy(bool2 v) {
+    bool3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+bool3 operator.xxy(bool3 v) {
+    bool3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+bool3 operator.xxy(bool4 v) {
+    bool3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uchar3 operator.xxy(uchar2 v) {
+    uchar3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uchar3 operator.xxy(uchar3 v) {
+    uchar3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uchar3 operator.xxy(uchar4 v) {
+    uchar3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+ushort3 operator.xxy(ushort2 v) {
+    ushort3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+ushort3 operator.xxy(ushort3 v) {
+    ushort3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+ushort3 operator.xxy(ushort4 v) {
+    ushort3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uint3 operator.xxy(uint2 v) {
+    uint3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uint3 operator.xxy(uint3 v) {
+    uint3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+uint3 operator.xxy(uint4 v) {
+    uint3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+char3 operator.xxy(char2 v) {
+    char3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+char3 operator.xxy(char3 v) {
+    char3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+char3 operator.xxy(char4 v) {
+    char3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+short3 operator.xxy(short2 v) {
+    short3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+short3 operator.xxy(short3 v) {
+    short3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+short3 operator.xxy(short4 v) {
+    short3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+int3 operator.xxy(int2 v) {
+    int3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+int3 operator.xxy(int3 v) {
+    int3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+int3 operator.xxy(int4 v) {
+    int3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+half3 operator.xxy(half2 v) {
+    half3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+half3 operator.xxy(half3 v) {
+    half3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+half3 operator.xxy(half4 v) {
+    half3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+float3 operator.xxy(float2 v) {
+    float3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+float3 operator.xxy(float3 v) {
+    float3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+float3 operator.xxy(float4 v) {
+    float3 result;
+    result.x = v.x;
+    result.y = v.x;
+    result.z = v.y;
+    return result;
+}
+
+/* Functions named operator.xww */
+bool3 operator.xww(bool4 v) {
+    bool3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+uchar3 operator.xww(uchar4 v) {
+    uchar3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+ushort3 operator.xww(ushort4 v) {
+    ushort3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+uint3 operator.xww(uint4 v) {
+    uint3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+char3 operator.xww(char4 v) {
+    char3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+short3 operator.xww(short4 v) {
+    short3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+int3 operator.xww(int4 v) {
+    int3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+half3 operator.xww(half4 v) {
+    half3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+float3 operator.xww(float4 v) {
+    float3 result;
+    result.x = v.x;
+    result.y = v.w;
+    result.z = v.w;
+    return result;
+}
+
+/* Functions named operator.zyxw= */
+bool4 operator.zyxw=(bool4 v, bool4 c) {
+    bool4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+uchar4 operator.zyxw=(uchar4 v, uchar4 c) {
+    uchar4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+ushort4 operator.zyxw=(ushort4 v, ushort4 c) {
+    ushort4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+uint4 operator.zyxw=(uint4 v, uint4 c) {
+    uint4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+char4 operator.zyxw=(char4 v, char4 c) {
+    char4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+short4 operator.zyxw=(short4 v, short4 c) {
+    short4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+int4 operator.zyxw=(int4 v, int4 c) {
+    int4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+half4 operator.zyxw=(half4 v, half4 c) {
+    half4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+float4 operator.zyxw=(float4 v, float4 c) {
+    float4 result = v;
+    result.z = c.x;
+    result.y = c.y;
+    result.x = c.z;
+    result.w = c.w;
+    return result;
+}
+
+/* Functions named operator.ywwz */
+bool4 operator.ywwz(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.ywwz(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.ywwz(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.ywwz(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+char4 operator.ywwz(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+short4 operator.ywwz(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+int4 operator.ywwz(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+half4 operator.ywwz(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+float4 operator.ywwz(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named operator.wyzz */
+bool4 operator.wyzz(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.wyzz(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.wyzz(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.wyzz(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+char4 operator.wyzz(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+short4 operator.wyzz(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+int4 operator.wyzz(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+half4 operator.wyzz(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+float4 operator.wyzz(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named exp2 */
+half exp2(half x) {
+    return exp(x * log(half(2)));
+}
+half2 exp2(half2 x) {
+    half2 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    return result;
+}
+half3 exp2(half3 x) {
+    half3 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    result[2] = exp2(x[2]);
+    return result;
+}
+half4 exp2(half4 x) {
+    half4 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    result[2] = exp2(x[2]);
+    result[3] = exp2(x[3]);
+    return result;
+}
+half2x2 exp2(half2x2 x) {
+    half2x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    return result;
+}
+half2x3 exp2(half2x3 x) {
+    half2x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    return result;
+}
+half2x4 exp2(half2x4 x) {
+    half2x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    return result;
+}
+half3x2 exp2(half3x2 x) {
+    half3x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    return result;
+}
+half3x3 exp2(half3x3 x) {
+    half3x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    return result;
+}
+half3x4 exp2(half3x4 x) {
+    half3x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[2][3] = exp2(x[2][3]);
+    return result;
+}
+half4x2 exp2(half4x2 x) {
+    half4x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    return result;
+}
+half4x3 exp2(half4x3 x) {
+    half4x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    result[3][2] = exp2(x[3][2]);
+    return result;
+}
+half4x4 exp2(half4x4 x) {
+    half4x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[2][3] = exp2(x[2][3]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    result[3][2] = exp2(x[3][2]);
+    result[3][3] = exp2(x[3][3]);
+    return result;
+}
+float exp2(float x) {
+    return exp(x * log(float(2)));
+}
+float2 exp2(float2 x) {
+    float2 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    return result;
+}
+float3 exp2(float3 x) {
+    float3 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    result[2] = exp2(x[2]);
+    return result;
+}
+float4 exp2(float4 x) {
+    float4 result;
+    result[0] = exp2(x[0]);
+    result[1] = exp2(x[1]);
+    result[2] = exp2(x[2]);
+    result[3] = exp2(x[3]);
+    return result;
+}
+float2x2 exp2(float2x2 x) {
+    float2x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    return result;
+}
+float2x3 exp2(float2x3 x) {
+    float2x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    return result;
+}
+float2x4 exp2(float2x4 x) {
+    float2x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    return result;
+}
+float3x2 exp2(float3x2 x) {
+    float3x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    return result;
+}
+float3x3 exp2(float3x3 x) {
+    float3x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    return result;
+}
+float3x4 exp2(float3x4 x) {
+    float3x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[2][3] = exp2(x[2][3]);
+    return result;
+}
+float4x2 exp2(float4x2 x) {
+    float4x2 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    return result;
+}
+float4x3 exp2(float4x3 x) {
+    float4x3 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    result[3][2] = exp2(x[3][2]);
+    return result;
+}
+float4x4 exp2(float4x4 x) {
+    float4x4 result;
+    result[0][0] = exp2(x[0][0]);
+    result[0][1] = exp2(x[0][1]);
+    result[0][2] = exp2(x[0][2]);
+    result[0][3] = exp2(x[0][3]);
+    result[1][0] = exp2(x[1][0]);
+    result[1][1] = exp2(x[1][1]);
+    result[1][2] = exp2(x[1][2]);
+    result[1][3] = exp2(x[1][3]);
+    result[2][0] = exp2(x[2][0]);
+    result[2][1] = exp2(x[2][1]);
+    result[2][2] = exp2(x[2][2]);
+    result[2][3] = exp2(x[2][3]);
+    result[3][0] = exp2(x[3][0]);
+    result[3][1] = exp2(x[3][1]);
+    result[3][2] = exp2(x[3][2]);
+    result[3][3] = exp2(x[3][3]);
+    return result;
+}
+
+/* Functions named operator.zyx */
+bool3 operator.zyx(bool3 v) {
+    bool3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+bool3 operator.zyx(bool4 v) {
+    bool3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+uchar3 operator.zyx(uchar3 v) {
+    uchar3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+uchar3 operator.zyx(uchar4 v) {
+    uchar3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+ushort3 operator.zyx(ushort3 v) {
+    ushort3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+ushort3 operator.zyx(ushort4 v) {
+    ushort3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+uint3 operator.zyx(uint3 v) {
+    uint3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+uint3 operator.zyx(uint4 v) {
+    uint3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+char3 operator.zyx(char3 v) {
+    char3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+char3 operator.zyx(char4 v) {
+    char3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+short3 operator.zyx(short3 v) {
+    short3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+short3 operator.zyx(short4 v) {
+    short3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+int3 operator.zyx(int3 v) {
+    int3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+int3 operator.zyx(int4 v) {
+    int3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+half3 operator.zyx(half3 v) {
+    half3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+half3 operator.zyx(half4 v) {
+    half3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+float3 operator.zyx(float3 v) {
+    float3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+float3 operator.zyx(float4 v) {
+    float3 result;
+    result.x = v.z;
+    result.y = v.y;
+    result.z = v.x;
+    return result;
+}
+
+/* Functions named operator.wwww */
+bool4 operator.wwww(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.wwww(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.wwww(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.wwww(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+char4 operator.wwww(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+short4 operator.wwww(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+int4 operator.wwww(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+half4 operator.wwww(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+float4 operator.wwww(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.wyzw */
+bool4 operator.wyzw(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.wyzw(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.wyzw(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.wyzw(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+char4 operator.wyzw(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+short4 operator.wyzw(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+int4 operator.wyzw(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+half4 operator.wyzw(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+float4 operator.wyzw(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.yzzw */
+bool4 operator.yzzw(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.yzzw(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.yzzw(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.yzzw(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+char4 operator.yzzw(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+short4 operator.yzzw(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+int4 operator.yzzw(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+half4 operator.yzzw(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+float4 operator.yzzw(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.wwy */
+bool3 operator.wwy(bool4 v) {
+    bool3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+uchar3 operator.wwy(uchar4 v) {
+    uchar3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+ushort3 operator.wwy(ushort4 v) {
+    ushort3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+uint3 operator.wwy(uint4 v) {
+    uint3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+char3 operator.wwy(char4 v) {
+    char3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+short3 operator.wwy(short4 v) {
+    short3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+int3 operator.wwy(int4 v) {
+    int3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+half3 operator.wwy(half4 v) {
+    half3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+float3 operator.wwy(float4 v) {
+    float3 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.y;
+    return result;
+}
+
+/* Functions named operator.wz */
+bool2 operator.wz(bool4 v) {
+    bool2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+uchar2 operator.wz(uchar4 v) {
+    uchar2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+ushort2 operator.wz(ushort4 v) {
+    ushort2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+uint2 operator.wz(uint4 v) {
+    uint2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+char2 operator.wz(char4 v) {
+    char2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+short2 operator.wz(short4 v) {
+    short2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+int2 operator.wz(int4 v) {
+    int2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+half2 operator.wz(half4 v) {
+    half2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+float2 operator.wz(float4 v) {
+    float2 result;
+    result.x = v.w;
+    result.y = v.z;
+    return result;
+}
+
+/* Functions named operator.zx= */
+bool3 operator.zx=(bool3 v, bool2 c) {
+    bool3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+bool4 operator.zx=(bool4 v, bool2 c) {
+    bool4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+uchar3 operator.zx=(uchar3 v, uchar2 c) {
+    uchar3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+uchar4 operator.zx=(uchar4 v, uchar2 c) {
+    uchar4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+ushort3 operator.zx=(ushort3 v, ushort2 c) {
+    ushort3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+ushort4 operator.zx=(ushort4 v, ushort2 c) {
+    ushort4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+uint3 operator.zx=(uint3 v, uint2 c) {
+    uint3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+uint4 operator.zx=(uint4 v, uint2 c) {
+    uint4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+char3 operator.zx=(char3 v, char2 c) {
+    char3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+char4 operator.zx=(char4 v, char2 c) {
+    char4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+short3 operator.zx=(short3 v, short2 c) {
+    short3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+short4 operator.zx=(short4 v, short2 c) {
+    short4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+int3 operator.zx=(int3 v, int2 c) {
+    int3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+int4 operator.zx=(int4 v, int2 c) {
+    int4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+half3 operator.zx=(half3 v, half2 c) {
+    half3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+half4 operator.zx=(half4 v, half2 c) {
+    half4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+float3 operator.zx=(float3 v, float2 c) {
+    float3 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+float4 operator.zx=(float4 v, float2 c) {
+    float4 result = v;
+    result.z = c.x;
+    result.x = c.y;
+    return result;
+}
+
+/* Functions named operator.yxyy */
+bool4 operator.yxyy(bool2 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+bool4 operator.yxyy(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+bool4 operator.yxyy(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yxyy(uchar2 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yxyy(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yxyy(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yxyy(ushort2 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yxyy(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yxyy(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yxyy(uint2 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yxyy(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yxyy(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yxyy(char2 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yxyy(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yxyy(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yxyy(short2 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yxyy(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yxyy(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yxyy(int2 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yxyy(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yxyy(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yxyy(half2 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yxyy(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yxyy(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yxyy(float2 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yxyy(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yxyy(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.wyyx */
+bool4 operator.wyyx(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.wyyx(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.wyyx(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.wyyx(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.wyyx(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.wyyx(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.wyyx(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.wyyx(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.wyyx(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.y;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.y */
+native bool operator.y(bool2);
+native bool operator.y(bool3);
+native bool operator.y(bool4);
+native uchar operator.y(uchar2);
+native uchar operator.y(uchar3);
+native uchar operator.y(uchar4);
+native ushort operator.y(ushort2);
+native ushort operator.y(ushort3);
+native ushort operator.y(ushort4);
+native uint operator.y(uint2);
+native uint operator.y(uint3);
+native uint operator.y(uint4);
+native char operator.y(char2);
+native char operator.y(char3);
+native char operator.y(char4);
+native short operator.y(short2);
+native short operator.y(short3);
+native short operator.y(short4);
+native int operator.y(int2);
+native int operator.y(int3);
+native int operator.y(int4);
+native half operator.y(half2);
+native half operator.y(half3);
+native half operator.y(half4);
+native float operator.y(float2);
+native float operator.y(float3);
+native float operator.y(float4);
+
+/* Functions named operator.wwzx */
+bool4 operator.wwzx(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.wwzx(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.wwzx(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.wwzx(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+char4 operator.wwzx(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+short4 operator.wwzx(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+int4 operator.wwzx(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+half4 operator.wwzx(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+float4 operator.wwzx(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.w;
+    result.z = v.z;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.yxzz */
+bool4 operator.yxzz(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+bool4 operator.yxzz(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yxzz(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.yxzz(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yxzz(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.yxzz(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yxzz(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.yxzz(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yxzz(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+char4 operator.yxzz(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yxzz(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+short4 operator.yxzz(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yxzz(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+int4 operator.yxzz(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yxzz(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+half4 operator.yxzz(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yxzz(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+float4 operator.yxzz(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named operator.wxzw */
+bool4 operator.wxzw(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.wxzw(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.wxzw(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.wxzw(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+char4 operator.wxzw(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+short4 operator.wxzw(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+int4 operator.wxzw(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+half4 operator.wxzw(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+float4 operator.wxzw(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.x;
+    result.z = v.z;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.zxyx */
+bool4 operator.zxyx(bool3 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+bool4 operator.zxyx(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.zxyx(uchar3 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uchar4 operator.zxyx(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.zxyx(ushort3 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+ushort4 operator.zxyx(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.zxyx(uint3 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+uint4 operator.zxyx(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.zxyx(char3 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+char4 operator.zxyx(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.zxyx(short3 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+short4 operator.zxyx(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.zxyx(int3 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+int4 operator.zxyx(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.zxyx(half3 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+half4 operator.zxyx(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.zxyx(float3 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+float4 operator.zxyx(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.x;
+    result.z = v.y;
+    result.w = v.x;
+    return result;
+}
+
+/* Functions named operator.wxyz= */
+bool4 operator.wxyz=(bool4 v, bool4 c) {
+    bool4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+uchar4 operator.wxyz=(uchar4 v, uchar4 c) {
+    uchar4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+ushort4 operator.wxyz=(ushort4 v, ushort4 c) {
+    ushort4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+uint4 operator.wxyz=(uint4 v, uint4 c) {
+    uint4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+char4 operator.wxyz=(char4 v, char4 c) {
+    char4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+short4 operator.wxyz=(short4 v, short4 c) {
+    short4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+int4 operator.wxyz=(int4 v, int4 c) {
+    int4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+half4 operator.wxyz=(half4 v, half4 c) {
+    half4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+float4 operator.wxyz=(float4 v, float4 c) {
+    float4 result = v;
+    result.w = c.x;
+    result.x = c.y;
+    result.y = c.z;
+    result.z = c.w;
+    return result;
+}
+
+/* Functions named operator.yyxy */
+bool4 operator.yyxy(bool2 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+bool4 operator.yyxy(bool3 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+bool4 operator.yyxy(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yyxy(uchar2 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yyxy(uchar3 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.yyxy(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yyxy(ushort2 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yyxy(ushort3 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.yyxy(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yyxy(uint2 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yyxy(uint3 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.yyxy(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yyxy(char2 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yyxy(char3 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+char4 operator.yyxy(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yyxy(short2 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yyxy(short3 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+short4 operator.yyxy(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yyxy(int2 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yyxy(int3 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+int4 operator.yyxy(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yyxy(half2 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yyxy(half3 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+half4 operator.yyxy(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yyxy(float2 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yyxy(float3 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+float4 operator.yyxy(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.y;
+    result.z = v.x;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.xz */
+bool2 operator.xz(bool3 v) {
+    bool2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+bool2 operator.xz(bool4 v) {
+    bool2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+uchar2 operator.xz(uchar3 v) {
+    uchar2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+uchar2 operator.xz(uchar4 v) {
+    uchar2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+ushort2 operator.xz(ushort3 v) {
+    ushort2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+ushort2 operator.xz(ushort4 v) {
+    ushort2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+uint2 operator.xz(uint3 v) {
+    uint2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+uint2 operator.xz(uint4 v) {
+    uint2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+char2 operator.xz(char3 v) {
+    char2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+char2 operator.xz(char4 v) {
+    char2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+short2 operator.xz(short3 v) {
+    short2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+short2 operator.xz(short4 v) {
+    short2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+int2 operator.xz(int3 v) {
+    int2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+int2 operator.xz(int4 v) {
+    int2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+half2 operator.xz(half3 v) {
+    half2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+half2 operator.xz(half4 v) {
+    half2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+float2 operator.xz(float3 v) {
+    float2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+float2 operator.xz(float4 v) {
+    float2 result;
+    result.x = v.x;
+    result.y = v.z;
+    return result;
+}
+
+/* Functions named operator.ywyw */
+bool4 operator.ywyw(bool4 v) {
+    bool4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+uchar4 operator.ywyw(uchar4 v) {
+    uchar4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+ushort4 operator.ywyw(ushort4 v) {
+    ushort4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+uint4 operator.ywyw(uint4 v) {
+    uint4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+char4 operator.ywyw(char4 v) {
+    char4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+short4 operator.ywyw(short4 v) {
+    short4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+int4 operator.ywyw(int4 v) {
+    int4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+half4 operator.ywyw(half4 v) {
+    half4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+float4 operator.ywyw(float4 v) {
+    float4 result;
+    result.x = v.y;
+    result.y = v.w;
+    result.z = v.y;
+    result.w = v.w;
+    return result;
+}
+
+/* Functions named operator.wzzz */
+bool4 operator.wzzz(bool4 v) {
+    bool4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.wzzz(uchar4 v) {
+    uchar4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.wzzz(ushort4 v) {
+    ushort4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.wzzz(uint4 v) {
+    uint4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+char4 operator.wzzz(char4 v) {
+    char4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+short4 operator.wzzz(short4 v) {
+    short4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+int4 operator.wzzz(int4 v) {
+    int4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+half4 operator.wzzz(half4 v) {
+    half4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+float4 operator.wzzz(float4 v) {
+    float4 result;
+    result.x = v.w;
+    result.y = v.z;
+    result.z = v.z;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named isunordered */
+bool isunordered(half x, half y) {
+    return isnan(x) || isnan(y);
+}
+bool2 isunordered(half2 x, half2 y) {
+    bool2 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    return result;
+}
+bool3 isunordered(half3 x, half3 y) {
+    bool3 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    result[2] = isunordered(x[2], y[2]);
+    return result;
+}
+bool4 isunordered(half4 x, half4 y) {
+    bool4 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    result[2] = isunordered(x[2], y[2]);
+    result[3] = isunordered(x[3], y[3]);
+    return result;
+}
+
+bool isunordered(float x, float y) {
+    return isnan(x) || isnan(y);
+}
+bool2 isunordered(float2 x, float2 y) {
+    bool2 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    return result;
+}
+bool3 isunordered(float3 x, float3 y) {
+    bool3 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    result[2] = isunordered(x[2], y[2]);
+    return result;
+}
+bool4 isunordered(float4 x, float4 y) {
+    bool4 result;
+    result[0] = isunordered(x[0], y[0]);
+    result[1] = isunordered(x[1], y[1]);
+    result[2] = isunordered(x[2], y[2]);
+    result[3] = isunordered(x[3], y[3]);
+    return result;
+}
+
+
+/* Functions named operator.zwwy */
+bool4 operator.zwwy(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uchar4 operator.zwwy(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+ushort4 operator.zwwy(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+uint4 operator.zwwy(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+char4 operator.zwwy(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+short4 operator.zwwy(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+int4 operator.zwwy(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+half4 operator.zwwy(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+float4 operator.zwwy(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.w;
+    result.z = v.w;
+    result.w = v.y;
+    return result;
+}
+
+/* Functions named operator.zzxz */
+bool4 operator.zzxz(bool3 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+bool4 operator.zzxz(bool4 v) {
+    bool4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.zzxz(uchar3 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uchar4 operator.zzxz(uchar4 v) {
+    uchar4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.zzxz(ushort3 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+ushort4 operator.zzxz(ushort4 v) {
+    ushort4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.zzxz(uint3 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+uint4 operator.zzxz(uint4 v) {
+    uint4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.zzxz(char3 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+char4 operator.zzxz(char4 v) {
+    char4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.zzxz(short3 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+short4 operator.zzxz(short4 v) {
+    short4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.zzxz(int3 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+int4 operator.zzxz(int4 v) {
+    int4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.zzxz(half3 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+half4 operator.zzxz(half4 v) {
+    half4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.zzxz(float3 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+float4 operator.zzxz(float4 v) {
+    float4 result;
+    result.x = v.z;
+    result.y = v.z;
+    result.z = v.x;
+    result.w = v.z;
+    return result;
+}
+
+/* Functions named atan */
+native float atan(float);
+half atan(half x) {
+    return half(atan(float(x)));
+}
+half2 atan(half2 x) {
+    half2 result;
+    result[0] = atan(x[0]);
+    result[1] = atan(x[1]);
+    return result;
+}
+half3 atan(half3 x) {
+    half3 result;
+    result[0] = atan(x[0]);
+    result[1] = atan(x[1]);
+    result[2] = atan(x[2]);
+    return result;
+}
+half4 atan(half4 x) {
+    half4 result;
+    result[0] = atan(x[0]);
+    result[1] = atan(x[1]);
+    result[2] = atan(x[2]);
+    result[3] = atan(x[3]);
+    return result;
+}
+half2x2 atan(half2x2 x) {
+    half2x2 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    return result;
+}
+half2x3 atan(half2x3 x) {
+    half2x3 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    return result;
+}
+half2x4 atan(half2x4 x) {
+    half2x4 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[0][3] = atan(x[0][3]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    result[1][3] = atan(x[1][3]);
+    return result;
+}
+half3x2 atan(half3x2 x) {
+    half3x2 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    return result;
+}
+half3x3 atan(half3x3 x) {
+    half3x3 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    result[2][2] = atan(x[2][2]);
+    return result;
+}
+half3x4 atan(half3x4 x) {
+    half3x4 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[0][3] = atan(x[0][3]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    result[1][3] = atan(x[1][3]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    result[2][2] = atan(x[2][2]);
+    result[2][3] = atan(x[2][3]);
+    return result;
+}
+half4x2 atan(half4x2 x) {
+    half4x2 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    result[3][0] = atan(x[3][0]);
+    result[3][1] = atan(x[3][1]);
+    return result;
+}
+half4x3 atan(half4x3 x) {
+    half4x3 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    result[2][2] = atan(x[2][2]);
+    result[3][0] = atan(x[3][0]);
+    result[3][1] = atan(x[3][1]);
+    result[3][2] = atan(x[3][2]);
+    return result;
+}
+half4x4 atan(half4x4 x) {
+    half4x4 result;
+    result[0][0] = atan(x[0][0]);
+    result[0][1] = atan(x[0][1]);
+    result[0][2] = atan(x[0][2]);
+    result[0][3] = atan(x[0][3]);
+    result[1][0] = atan(x[1][0]);
+    result[1][1] = atan(x[1][1]);
+    result[1][2] = atan(x[1][2]);
+    result[1][3] = atan(x[1][3]);
+    result[2][0] = atan(x[2][0]);
+    result[2][1] = atan(x[2][1]);
+    result[2][2] = atan(x[2][2]);
+    result[2][3] = atan(x[2][3]);