1 // Copyright 2020 Google LLC
2 //
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 
6 #include "include/private/SkVx.h"
7 #include <emscripten.h>
8 #include <stdio.h>
9 
10 // How to read this file:
11 // - Lines with "//GOOD" are compatible with WASM SIMD and are automatically compiled
12 //   into WASM SIMD operations by emscripten.
13 // - Lines with "//N/A" are operations that are not compatible with this type of data.
14 // - Lines with "GOOD (FIXED)" are compatible with WASM SIMD but are NOT automatically
15 //   compiled into WASM SIMD operations by emscripten. Special WASM SIMD intrinsics have been
16 //   specified in skia/include/private/SkVx.h to tell emscripten how to compile them to WASM SIMD
17 //   operations.
18 // - Lines with "//not available in wasm" do not have compatible WASM SIMD operations. Emscripten
19 //   compiles these operations into non-SIMD WASM.
20 // - Lines with "//???" may be more complex and it is not clear if they have compatible WASM SIMD
21 //   operations. More work could be needed on these operations.
22 
23 // How to use this file for testing WASM SIMDification of operations:
24 // 1. Reference https://github.com/WebAssembly/simd/blob/master/proposals/simd/SIMD.md
25 //   and https://github.com/llvm/llvm-project/blob/master/clang/lib/Headers/wasm_simd128.h
26 //   to check if a WASM SIMD operation exists which correspond to any given line of code.
27 // 2. Uncomment that line of code.
28 // 3. Run `./build_simd_test.sh simd_int_capabilities.cpp` to build and output WASM SIMD operations present
29 //   in the compiled WASM.
30 // 4. Read the output in the console to see if the WASM SIMD operations you expected were present in
31 //   the resulting compiled WASM.
32 
main()33 int main() {
34   auto vec1 = skvx::Vec<4, int>({3, 7, 11, 23});
35   auto vec2 = skvx::Vec<4, int>({1, 9, 27, 41});
36 
37   //auto vec3 = skvx::join(vec1, vec2); //not available in wasm
38   // note: may be possible using "widening"
39 
40   //vec1 = vec1 + vec2; //GOOD
41   //vec1 = vec1 - vec2; //GOOD
42   //vec1 = vec1 * vec2; //GOOD
43   //vec1 = vec1 / vec2; //N/A
44 
45   //vec1 = vec1 ^ vec2; //GOOD
46   //vec1 = vec1 & vec2; //GOOD
47   //vec1 = vec1 | vec2; //GOOD
48 
49   //vec1 = !vec1; //GOOD
50   //vec1 = -vec1; //GOOD
51   //vec1 = ~vec1; //GOOD
52 
53   //vec1 = vec1 << 2; //GOOD
54   //vec1 = vec1 >> 2; //GOOD
55 
56   //auto vec3 = vec1 == vec2; //GOOD
57   //auto vec3  = vec1 != vec2; //GOOD
58   //auto vec3 = vec1 <= vec2; //GOOD
59   //auto vec3 = vec1 >= vec2; //GOOD
60   //auto vec3 = vec1 < vec2; //GOOD
61   //auto vec3 = vec1 > vec2; //GOOD
62 
63   //auto vec3 = skvx::any(vec1); //GOOD (FIXED)
64   //auto vec3 = skvx::all(vec1); //GOOD (FIXED)
65 
66   //auto a = skvx::max(vec1, vec2); //GOOD (FIXED)
67   //auto a = skvx::min(vec1, vec2); //GOOD (FIXED)
68 
69   //vec1 = skvx::pow(vec1, vec2); //not available in wasm
70   //vec1 = skvx::atan(vec1); //not available in wasm
71   //vec1 = ceil(vec1); //not available in wasm
72   //vec1 = skvx::floor(vec1); //not available in wasm
73   //vec1 = skvx::trunc(vec1); //N/A
74   //vec1 = skvx::round(vec1); //N/A
75   //vec1 = skvx::sqrt(vec1); //not available in wasm
76   //vec1 = skvx::abs(vec1); //GOOD (FIXED)
77   //vec1 = skvx::sin(vec1); //not available in wasm
78   //vec1 = skvx::cos(vec1); //not available in wasm
79   //vec1 = skvx::tan(vec1); //not available in wasm
80 
81   //auto vec3 = skvx::lrint(vec1); //???
82 
83   //vec1 = skvx::rcp(vec1); //N/A
84   //vec1 = skvx::rsqrt(vec1); //N/A
85 
86   //vec1 = skvx::if_then_else(vec1, vec1, vec2); //???
87 
88   //vec1 = skvx::shuffle<2,1,0,3>(vec1); //GOOD
89 
90   //vec1 = skvx::fma(vec1, vec2, vec1); //not available in wasm (no fused multiply-add is available)
91   //vec1 = skvx::fract(vec1); //N/A
92 
93   //printf("result: { %i, %i, %i, %i }\n", vec1[0], vec1[1], vec1[2], vec1[3]);
94 
95   return 0;
96 }
97