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"
30 // Value stack: stack elements
34 Stk() : kind_(Unknown
), i64val_(0) {}
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")
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")
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")
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")
76 ConstRef
, // reftype (pointer wide) constant ("refval")
83 static const Kind MemLast
= MemRef
;
84 static const Kind LocalLast
= LocalRef
;
92 #ifdef ENABLE_WASM_SIMD
100 #ifdef ENABLE_WASM_SIMD
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
) {}
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
) {}
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
) {
132 static Stk
StackResult(ValType type
, uint32_t offs
) {
134 switch (type
.kind()) {
142 #ifdef ENABLE_WASM_SIMD
146 MOZ_CRASH("No SIMD");
163 void setOffs(Kind k
, uint32_t v
) {
164 MOZ_ASSERT(k
<= MemLast
);
169 Kind
kind() const { return kind_
; }
170 bool isMem() const { return kind_
<= MemLast
; }
172 RegI32
i32reg() const {
173 MOZ_ASSERT(kind_
== RegisterI32
);
176 RegI64
i64reg() const {
177 MOZ_ASSERT(kind_
== RegisterI64
);
180 RegRef
refReg() const {
181 MOZ_ASSERT(kind_
== RegisterRef
);
184 RegF32
f32reg() const {
185 MOZ_ASSERT(kind_
== RegisterF32
);
188 RegF64
f64reg() const {
189 MOZ_ASSERT(kind_
== RegisterF64
);
192 #ifdef ENABLE_WASM_SIMD
193 RegV128
v128reg() const {
194 MOZ_ASSERT(kind_
== RegisterV128
);
198 int32_t i32val() const {
199 MOZ_ASSERT(kind_
== ConstI32
);
202 int64_t i64val() const {
203 MOZ_ASSERT(kind_
== ConstI64
);
206 intptr_t refval() const {
207 MOZ_ASSERT(kind_
== ConstRef
);
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
);
219 void f64val(double* out
) const {
220 MOZ_ASSERT(kind_
== ConstF64
);
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
);
233 uint32_t slot() const {
234 MOZ_ASSERT(kind_
> MemLast
&& kind_
<= LocalLast
);
237 uint32_t offs() const {
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
247 void showStackElem() const {
250 fprintf(stderr
, "MemI32()");
253 fprintf(stderr
, "MemI64()");
256 fprintf(stderr
, "MemF32()");
259 fprintf(stderr
, "MemF64()");
261 # ifdef ENABLE_WASM_SIMD
263 fprintf(stderr
, "MemV128()");
267 fprintf(stderr
, "MemRef()");
270 fprintf(stderr
, "LocalI32()");
273 fprintf(stderr
, "LocalI64()");
276 fprintf(stderr
, "LocalF32()");
279 fprintf(stderr
, "LocalF64()");
281 # ifdef ENABLE_WASM_SIMD
283 fprintf(stderr
, "LocalV128()");
287 fprintf(stderr
, "LocalRef()");
290 fprintf(stderr
, "RegisterI32()");
293 fprintf(stderr
, "RegisterI64()");
296 fprintf(stderr
, "RegisterF32()");
299 fprintf(stderr
, "RegisterF64()");
301 # ifdef ENABLE_WASM_SIMD
303 fprintf(stderr
, "RegisterV128()");
307 fprintf(stderr
, "RegisterRef()");
310 fprintf(stderr
, "ConstI32(%d)", (int)i32val_
);
313 fprintf(stderr
, "ConstI64()");
316 fprintf(stderr
, "ConstF32()");
319 fprintf(stderr
, "ConstF64()");
321 # ifdef ENABLE_WASM_SIMD
323 fprintf(stderr
, "ConstV128()");
327 fprintf(stderr
, "ConstRef()");
330 fprintf(stderr
, "Unknown()");
333 fprintf(stderr
, "!! Stk::showStackElem !!");
340 using StkVector
= Vector
<Stk
, 0, SystemAllocPolicy
>;
345 #endif // wasm_wasm_baseline_stk_h