no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / js / src / wasm / WasmBCStk.h
blob330e8abd06b0e8fd0cf2c883fc66b07084100922
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
4 * Copyright 2016 Mozilla Foundation
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 // This is an INTERNAL header for Wasm baseline compiler: Wasm value stack.
21 #ifndef wasm_wasm_baseline_stk_h
22 #define wasm_wasm_baseline_stk_h
24 #include "wasm/WasmBCDefs.h"
25 #include "wasm/WasmBCRegDefs.h"
27 namespace js {
28 namespace wasm {
30 // Value stack: stack elements
32 struct Stk {
33 private:
34 Stk() : kind_(Unknown), i64val_(0) {}
36 public:
37 enum Kind {
38 // The Mem opcodes are all clustered at the beginning to
39 // allow for a quick test within sync().
40 MemI32, // 32-bit integer stack value ("offs")
41 MemI64, // 64-bit integer stack value ("offs")
42 MemF32, // 32-bit floating stack value ("offs")
43 MemF64, // 64-bit floating stack value ("offs")
44 #ifdef ENABLE_WASM_SIMD
45 MemV128, // 128-bit vector stack value ("offs")
46 #endif
47 MemRef, // reftype (pointer wide) stack value ("offs")
49 // The Local opcodes follow the Mem opcodes for a similar
50 // quick test within hasLocal().
51 LocalI32, // Local int32 var ("slot")
52 LocalI64, // Local int64 var ("slot")
53 LocalF32, // Local float32 var ("slot")
54 LocalF64, // Local double var ("slot")
55 #ifdef ENABLE_WASM_SIMD
56 LocalV128, // Local v128 var ("slot")
57 #endif
58 LocalRef, // Local reftype (pointer wide) var ("slot")
60 RegisterI32, // 32-bit integer register ("i32reg")
61 RegisterI64, // 64-bit integer register ("i64reg")
62 RegisterF32, // 32-bit floating register ("f32reg")
63 RegisterF64, // 64-bit floating register ("f64reg")
64 #ifdef ENABLE_WASM_SIMD
65 RegisterV128, // 128-bit vector register ("v128reg")
66 #endif
67 RegisterRef, // reftype (pointer wide) register ("refReg")
69 ConstI32, // 32-bit integer constant ("i32val")
70 ConstI64, // 64-bit integer constant ("i64val")
71 ConstF32, // 32-bit floating constant ("f32val")
72 ConstF64, // 64-bit floating constant ("f64val")
73 #ifdef ENABLE_WASM_SIMD
74 ConstV128, // 128-bit vector constant ("v128val")
75 #endif
76 ConstRef, // reftype (pointer wide) constant ("refval")
78 Unknown,
81 Kind kind_;
83 static const Kind MemLast = MemRef;
84 static const Kind LocalLast = LocalRef;
86 union {
87 RegI32 i32reg_;
88 RegI64 i64reg_;
89 RegRef refReg_;
90 RegF32 f32reg_;
91 RegF64 f64reg_;
92 #ifdef ENABLE_WASM_SIMD
93 RegV128 v128reg_;
94 #endif
95 int32_t i32val_;
96 int64_t i64val_;
97 intptr_t refval_;
98 float f32val_;
99 double f64val_;
100 #ifdef ENABLE_WASM_SIMD
101 V128 v128val_;
102 #endif
103 uint32_t slot_;
104 uint32_t offs_;
107 explicit Stk(RegI32 r) : kind_(RegisterI32), i32reg_(r) {}
108 explicit Stk(RegI64 r) : kind_(RegisterI64), i64reg_(r) {}
109 explicit Stk(RegRef r) : kind_(RegisterRef), refReg_(r) {}
110 explicit Stk(RegF32 r) : kind_(RegisterF32), f32reg_(r) {}
111 explicit Stk(RegF64 r) : kind_(RegisterF64), f64reg_(r) {}
112 #ifdef ENABLE_WASM_SIMD
113 explicit Stk(RegV128 r) : kind_(RegisterV128), v128reg_(r) {}
114 #endif
115 explicit Stk(int32_t v) : kind_(ConstI32), i32val_(v) {}
116 explicit Stk(uint32_t v) : kind_(ConstI32), i32val_(int32_t(v)) {}
117 explicit Stk(int64_t v) : kind_(ConstI64), i64val_(v) {}
118 explicit Stk(float v) : kind_(ConstF32), f32val_(v) {}
119 explicit Stk(double v) : kind_(ConstF64), f64val_(v) {}
120 #ifdef ENABLE_WASM_SIMD
121 explicit Stk(V128 v) : kind_(ConstV128), v128val_(v) {}
122 #endif
123 explicit Stk(Kind k, uint32_t v) : kind_(k), slot_(v) {
124 MOZ_ASSERT(k > MemLast && k <= LocalLast);
126 static Stk StkRef(intptr_t v) {
127 Stk s;
128 s.kind_ = ConstRef;
129 s.refval_ = v;
130 return s;
132 static Stk StackResult(ValType type, uint32_t offs) {
133 Kind k;
134 switch (type.kind()) {
135 case ValType::I32:
136 k = Stk::MemI32;
137 break;
138 case ValType::I64:
139 k = Stk::MemI64;
140 break;
141 case ValType::V128:
142 #ifdef ENABLE_WASM_SIMD
143 k = Stk::MemV128;
144 break;
145 #else
146 MOZ_CRASH("No SIMD");
147 #endif
148 case ValType::F32:
149 k = Stk::MemF32;
150 break;
151 case ValType::F64:
152 k = Stk::MemF64;
153 break;
154 case ValType::Ref:
155 k = Stk::MemRef;
156 break;
158 Stk s;
159 s.setOffs(k, offs);
160 return s;
163 void setOffs(Kind k, uint32_t v) {
164 MOZ_ASSERT(k <= MemLast);
165 kind_ = k;
166 offs_ = v;
169 Kind kind() const { return kind_; }
170 bool isMem() const { return kind_ <= MemLast; }
172 RegI32 i32reg() const {
173 MOZ_ASSERT(kind_ == RegisterI32);
174 return i32reg_;
176 RegI64 i64reg() const {
177 MOZ_ASSERT(kind_ == RegisterI64);
178 return i64reg_;
180 RegRef refReg() const {
181 MOZ_ASSERT(kind_ == RegisterRef);
182 return refReg_;
184 RegF32 f32reg() const {
185 MOZ_ASSERT(kind_ == RegisterF32);
186 return f32reg_;
188 RegF64 f64reg() const {
189 MOZ_ASSERT(kind_ == RegisterF64);
190 return f64reg_;
192 #ifdef ENABLE_WASM_SIMD
193 RegV128 v128reg() const {
194 MOZ_ASSERT(kind_ == RegisterV128);
195 return v128reg_;
197 #endif
198 int32_t i32val() const {
199 MOZ_ASSERT(kind_ == ConstI32);
200 return i32val_;
202 int64_t i64val() const {
203 MOZ_ASSERT(kind_ == ConstI64);
204 return i64val_;
206 intptr_t refval() const {
207 MOZ_ASSERT(kind_ == ConstRef);
208 return refval_;
211 // For these two, use an out-param instead of simply returning, to
212 // use the normal stack and not the x87 FP stack (which has effect on
213 // NaNs with the signaling bit set).
215 void f32val(float* out) const {
216 MOZ_ASSERT(kind_ == ConstF32);
217 *out = f32val_;
219 void f64val(double* out) const {
220 MOZ_ASSERT(kind_ == ConstF64);
221 *out = f64val_;
224 #ifdef ENABLE_WASM_SIMD
225 // For SIMD, do the same as for floats since we're using float registers to
226 // hold vectors; this is just conservative.
227 void v128val(V128* out) const {
228 MOZ_ASSERT(kind_ == ConstV128);
229 *out = v128val_;
231 #endif
233 uint32_t slot() const {
234 MOZ_ASSERT(kind_ > MemLast && kind_ <= LocalLast);
235 return slot_;
237 uint32_t offs() const {
238 MOZ_ASSERT(isMem());
239 return offs_;
242 #ifdef DEBUG
243 // Print a stack element (Stk) to stderr. Skip the trailing \n. Printing
244 // of the actual contents of each stack element (see case ConstI32) can be
245 // filled in on demand -- even printing just the element `kind_` fields can
246 // be very useful.
247 void showStackElem() const {
248 switch (kind_) {
249 case MemI32:
250 fprintf(stderr, "MemI32()");
251 break;
252 case MemI64:
253 fprintf(stderr, "MemI64()");
254 break;
255 case MemF32:
256 fprintf(stderr, "MemF32()");
257 break;
258 case MemF64:
259 fprintf(stderr, "MemF64()");
260 break;
261 # ifdef ENABLE_WASM_SIMD
262 case MemV128:
263 fprintf(stderr, "MemV128()");
264 break;
265 # endif
266 case MemRef:
267 fprintf(stderr, "MemRef()");
268 break;
269 case LocalI32:
270 fprintf(stderr, "LocalI32()");
271 break;
272 case LocalI64:
273 fprintf(stderr, "LocalI64()");
274 break;
275 case LocalF32:
276 fprintf(stderr, "LocalF32()");
277 break;
278 case LocalF64:
279 fprintf(stderr, "LocalF64()");
280 break;
281 # ifdef ENABLE_WASM_SIMD
282 case LocalV128:
283 fprintf(stderr, "LocalV128()");
284 break;
285 # endif
286 case LocalRef:
287 fprintf(stderr, "LocalRef()");
288 break;
289 case RegisterI32:
290 fprintf(stderr, "RegisterI32()");
291 break;
292 case RegisterI64:
293 fprintf(stderr, "RegisterI64()");
294 break;
295 case RegisterF32:
296 fprintf(stderr, "RegisterF32()");
297 break;
298 case RegisterF64:
299 fprintf(stderr, "RegisterF64()");
300 break;
301 # ifdef ENABLE_WASM_SIMD
302 case RegisterV128:
303 fprintf(stderr, "RegisterV128()");
304 break;
305 # endif
306 case RegisterRef:
307 fprintf(stderr, "RegisterRef()");
308 break;
309 case ConstI32:
310 fprintf(stderr, "ConstI32(%d)", (int)i32val_);
311 break;
312 case ConstI64:
313 fprintf(stderr, "ConstI64()");
314 break;
315 case ConstF32:
316 fprintf(stderr, "ConstF32()");
317 break;
318 case ConstF64:
319 fprintf(stderr, "ConstF64()");
320 break;
321 # ifdef ENABLE_WASM_SIMD
322 case ConstV128:
323 fprintf(stderr, "ConstV128()");
324 break;
325 # endif
326 case ConstRef:
327 fprintf(stderr, "ConstRef()");
328 break;
329 case Unknown:
330 fprintf(stderr, "Unknown()");
331 break;
332 default:
333 fprintf(stderr, "!! Stk::showStackElem !!");
334 break;
337 #endif
340 using StkVector = Vector<Stk, 0, SystemAllocPolicy>;
342 } // namespace wasm
343 } // namespace js
345 #endif // wasm_wasm_baseline_stk_h