|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef builtin_SIMD_h |
|
8 #define builtin_SIMD_h |
|
9 |
|
10 #include "jsapi.h" |
|
11 #include "jsobj.h" |
|
12 #include "builtin/TypedObject.h" |
|
13 #include "vm/GlobalObject.h" |
|
14 |
|
15 /* |
|
16 * JS SIMD functions. |
|
17 * Spec matching polyfill: |
|
18 * https://github.com/johnmccutchan/ecmascript_simd/blob/master/src/ecmascript_simd.js |
|
19 */ |
|
20 |
|
21 #define FLOAT32X4_NULLARY_FUNCTION_LIST(V) \ |
|
22 V(zero, (FuncZero<Float32x4>), 0, 0, Zero) |
|
23 |
|
24 #define FLOAT32X4_UNARY_FUNCTION_LIST(V) \ |
|
25 V(abs, (Func<Float32x4, Abs<float, Float32x4>, Float32x4>), 1, 0, Abs) \ |
|
26 V(bitsToInt32x4, (FuncConvertBits<Float32x4, Int32x4>), 1, 0, BitsToInt32x4) \ |
|
27 V(neg, (Func<Float32x4, Neg<float, Float32x4>, Float32x4>), 1, 0, Neg) \ |
|
28 V(reciprocal, (Func<Float32x4, Rec<float, Float32x4>, Float32x4>), 1, 0, Reciprocal) \ |
|
29 V(reciprocalSqrt, (Func<Float32x4, RecSqrt<float, Float32x4>, Float32x4>), 1, 0, ReciprocalSqrt) \ |
|
30 V(splat, (FuncSplat<Float32x4>), 1, 0, Splat) \ |
|
31 V(sqrt, (Func<Float32x4, Sqrt<float, Float32x4>, Float32x4>), 1, 0, Sqrt) \ |
|
32 V(toInt32x4, (FuncConvert<Float32x4, Int32x4>), 1, 0, ToInt32x4) |
|
33 |
|
34 #define FLOAT32X4_BINARY_FUNCTION_LIST(V) \ |
|
35 V(add, (Func<Float32x4, Add<float, Float32x4>, Float32x4>), 2, 0, Add) \ |
|
36 V(div, (Func<Float32x4, Div<float, Float32x4>, Float32x4>), 2, 0, Div) \ |
|
37 V(equal, (Func<Float32x4, Equal<float, Int32x4>, Int32x4>), 2, 0, Equal) \ |
|
38 V(greaterThan, (Func<Float32x4, GreaterThan<float, Int32x4>, Int32x4>), 2, 0, GreaterThan) \ |
|
39 V(greaterThanOrEqual, (Func<Float32x4, GreaterThanOrEqual<float, Int32x4>, Int32x4>), 2, 0, GreaterThanOrEqual) \ |
|
40 V(lessThan, (Func<Float32x4, LessThan<float, Int32x4>, Int32x4>), 2, 0, LessThan) \ |
|
41 V(lessThanOrEqual, (Func<Float32x4, LessThanOrEqual<float, Int32x4>, Int32x4>), 2, 0, LessThanOrEqual) \ |
|
42 V(max, (Func<Float32x4, Maximum<float, Float32x4>, Float32x4>), 2, 0, Max) \ |
|
43 V(min, (Func<Float32x4, Minimum<float, Float32x4>, Float32x4>), 2, 0, Min) \ |
|
44 V(mul, (Func<Float32x4, Mul<float, Float32x4>, Float32x4>), 2, 0, Mul) \ |
|
45 V(notEqual, (Func<Float32x4, NotEqual<float, Int32x4>, Int32x4>), 2, 0, NotEqual) \ |
|
46 V(shuffle, (FuncShuffle<Float32x4, Shuffle<float, Float32x4>, Float32x4>), 2, 0, Shuffle) \ |
|
47 V(scale, (FuncWith<Float32x4, Scale<float, Float32x4>, Float32x4>), 2, 0, Scale) \ |
|
48 V(sub, (Func<Float32x4, Sub<float, Float32x4>, Float32x4>), 2, 0, Sub) \ |
|
49 V(withX, (FuncWith<Float32x4, WithX<float, Float32x4>, Float32x4>), 2, 0, WithX) \ |
|
50 V(withY, (FuncWith<Float32x4, WithY<float, Float32x4>, Float32x4>), 2, 0, WithY) \ |
|
51 V(withZ, (FuncWith<Float32x4, WithZ<float, Float32x4>, Float32x4>), 2, 0, WithZ) \ |
|
52 V(withW, (FuncWith<Float32x4, WithW<float, Float32x4>, Float32x4>), 2, 0, WithW) |
|
53 |
|
54 #define FLOAT32X4_TERNARY_FUNCTION_LIST(V) \ |
|
55 V(clamp, Float32x4Clamp, 3, 0, Clamp) \ |
|
56 V(shuffleMix, (FuncShuffle<Float32x4, Shuffle<float, Float32x4>, Float32x4>), 3, 0, ShuffleMix) |
|
57 |
|
58 #define FLOAT32X4_FUNCTION_LIST(V) \ |
|
59 FLOAT32X4_NULLARY_FUNCTION_LIST(V) \ |
|
60 FLOAT32X4_UNARY_FUNCTION_LIST(V) \ |
|
61 FLOAT32X4_BINARY_FUNCTION_LIST(V) \ |
|
62 FLOAT32X4_TERNARY_FUNCTION_LIST(V) |
|
63 |
|
64 #define INT32X4_NULLARY_FUNCTION_LIST(V) \ |
|
65 V(zero, (FuncZero<Int32x4>), 0, 0, Zero) |
|
66 |
|
67 #define INT32X4_UNARY_FUNCTION_LIST(V) \ |
|
68 V(bitsToFloat32x4, (FuncConvertBits<Int32x4, Float32x4>), 1, 0, BitsToFloat32x4) \ |
|
69 V(neg, (Func<Int32x4, Neg<int32_t, Int32x4>, Int32x4>), 1, 0, Neg) \ |
|
70 V(not, (Func<Int32x4, Not<int32_t, Int32x4>, Int32x4>), 1, 0, Not) \ |
|
71 V(splat, (FuncSplat<Int32x4>), 0, 0, Splat) \ |
|
72 V(toFloat32x4, (FuncConvert<Int32x4, Float32x4>), 1, 0, ToFloat32x4) |
|
73 |
|
74 #define INT32X4_BINARY_FUNCTION_LIST(V) \ |
|
75 V(add, (Func<Int32x4, Add<int32_t, Int32x4>, Int32x4>), 2, 0, Add) \ |
|
76 V(and, (Func<Int32x4, And<int32_t, Int32x4>, Int32x4>), 2, 0, And) \ |
|
77 V(mul, (Func<Int32x4, Mul<int32_t, Int32x4>, Int32x4>), 2, 0, Mul) \ |
|
78 V(or, (Func<Int32x4, Or<int32_t, Int32x4>, Int32x4>), 2, 0, Or) \ |
|
79 V(sub, (Func<Int32x4, Sub<int32_t, Int32x4>, Int32x4>), 2, 0, Sub) \ |
|
80 V(shuffle, (FuncShuffle<Int32x4, Shuffle<int32_t, Int32x4>, Int32x4>), 2, 0, Shuffle) \ |
|
81 V(withFlagX, (FuncWith<Int32x4, WithFlagX<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagX) \ |
|
82 V(withFlagY, (FuncWith<Int32x4, WithFlagY<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagY) \ |
|
83 V(withFlagZ, (FuncWith<Int32x4, WithFlagZ<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagZ) \ |
|
84 V(withFlagW, (FuncWith<Int32x4, WithFlagW<int32_t, Int32x4>, Int32x4>), 2, 0, WithFlagW) \ |
|
85 V(withX, (FuncWith<Int32x4, WithX<int32_t, Int32x4>, Int32x4>), 2, 0, WithX) \ |
|
86 V(withY, (FuncWith<Int32x4, WithY<int32_t, Int32x4>, Int32x4>), 2, 0, WithY) \ |
|
87 V(withZ, (FuncWith<Int32x4, WithZ<int32_t, Int32x4>, Int32x4>), 2, 0, WithZ) \ |
|
88 V(withW, (FuncWith<Int32x4, WithW<int32_t, Int32x4>, Int32x4>), 2, 0, WithW) \ |
|
89 V(xor, (Func<Int32x4, Xor<int32_t, Int32x4>, Int32x4>), 2, 0, Xor) |
|
90 |
|
91 #define INT32X4_TERNARY_FUNCTION_LIST(V) \ |
|
92 V(select, Int32x4Select, 3, 0, Select) \ |
|
93 V(shuffleMix, (FuncShuffle<Int32x4, Shuffle<int32_t, Int32x4>, Int32x4>), 3, 0, ShuffleMix) |
|
94 |
|
95 #define INT32X4_QUARTERNARY_FUNCTION_LIST(V) \ |
|
96 V(bool, Int32x4Bool, 4, 0, Bool) |
|
97 |
|
98 #define INT32X4_FUNCTION_LIST(V) \ |
|
99 INT32X4_NULLARY_FUNCTION_LIST(V) \ |
|
100 INT32X4_UNARY_FUNCTION_LIST(V) \ |
|
101 INT32X4_BINARY_FUNCTION_LIST(V) \ |
|
102 INT32X4_TERNARY_FUNCTION_LIST(V) \ |
|
103 INT32X4_QUARTERNARY_FUNCTION_LIST(V) |
|
104 |
|
105 namespace js { |
|
106 |
|
107 class SIMDObject : public JSObject |
|
108 { |
|
109 public: |
|
110 static const Class class_; |
|
111 static JSObject* initClass(JSContext *cx, Handle<GlobalObject *> global); |
|
112 static bool toString(JSContext *cx, unsigned int argc, jsval *vp); |
|
113 }; |
|
114 |
|
115 // These classes exist for use with templates below. |
|
116 |
|
117 struct Float32x4 { |
|
118 typedef float Elem; |
|
119 static const int32_t lanes = 4; |
|
120 static const X4TypeDescr::Type type = X4TypeDescr::TYPE_FLOAT32; |
|
121 |
|
122 static TypeDescr &GetTypeDescr(GlobalObject &global) { |
|
123 return global.float32x4TypeDescr().as<TypeDescr>(); |
|
124 } |
|
125 static Elem toType(Elem a) { |
|
126 return a; |
|
127 } |
|
128 static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) { |
|
129 *out = v.toNumber(); |
|
130 return true; |
|
131 } |
|
132 static void setReturn(CallArgs &args, Elem value) { |
|
133 args.rval().setDouble(JS::CanonicalizeNaN(value)); |
|
134 } |
|
135 }; |
|
136 |
|
137 struct Int32x4 { |
|
138 typedef int32_t Elem; |
|
139 static const int32_t lanes = 4; |
|
140 static const X4TypeDescr::Type type = X4TypeDescr::TYPE_INT32; |
|
141 |
|
142 static TypeDescr &GetTypeDescr(GlobalObject &global) { |
|
143 return global.int32x4TypeDescr().as<TypeDescr>(); |
|
144 } |
|
145 static Elem toType(Elem a) { |
|
146 return ToInt32(a); |
|
147 } |
|
148 static bool toType(JSContext *cx, JS::HandleValue v, Elem *out) { |
|
149 return ToInt32(cx, v, out); |
|
150 } |
|
151 static void setReturn(CallArgs &args, Elem value) { |
|
152 args.rval().setInt32(value); |
|
153 } |
|
154 }; |
|
155 |
|
156 template<typename V> |
|
157 JSObject *Create(JSContext *cx, typename V::Elem *data); |
|
158 |
|
159 #define DECLARE_SIMD_FLOAT32X4_FUNCTION(Name, Func, Operands, Flags, MIRId) \ |
|
160 extern bool \ |
|
161 simd_float32x4_##Name(JSContext *cx, unsigned argc, Value *vp); |
|
162 FLOAT32X4_FUNCTION_LIST(DECLARE_SIMD_FLOAT32X4_FUNCTION) |
|
163 #undef DECLARE_SIMD_FLOAT32X4_FUNCTION |
|
164 |
|
165 #define DECLARE_SIMD_INT32x4_FUNCTION(Name, Func, Operands, Flags, MIRId) \ |
|
166 extern bool \ |
|
167 simd_int32x4_##Name(JSContext *cx, unsigned argc, Value *vp); |
|
168 INT32X4_FUNCTION_LIST(DECLARE_SIMD_INT32x4_FUNCTION) |
|
169 #undef DECLARE_SIMD_INT32x4_FUNCTION |
|
170 |
|
171 } /* namespace js */ |
|
172 |
|
173 JSObject * |
|
174 js_InitSIMDClass(JSContext *cx, js::HandleObject obj); |
|
175 |
|
176 #endif /* builtin_SIMD_h */ |