1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
*
* Copyright 2016 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This is an INTERNAL header for Wasm baseline compiler: common configuration
// and simple definitions; all include directives.
#ifndef wasm_wasm_baseline_defs_h
#define wasm_wasm_baseline_defs_h
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Maybe.h"
#include "mozilla/ScopeExit.h"
#include <algorithm>
#include <utility>
#include "jit/AtomicOp.h"
#include "jit/IonTypes.h"
#include "jit/JitAllocPolicy.h"
#include "jit/Label.h"
#include "jit/RegisterAllocator.h"
#include "jit/Registers.h"
#include "jit/RegisterSets.h"
#if defined(JS_CODEGEN_ARM)
# include "jit/arm/Assembler-arm.h"
#endif
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
# include "jit/x86-shared/Architecture-x86-shared.h"
# include "jit/x86-shared/Assembler-x86-shared.h"
#endif
#if defined(JS_CODEGEN_MIPS64)
# include "jit/mips-shared/Assembler-mips-shared.h"
# include "jit/mips64/Assembler-mips64.h"
#endif
#if defined(JS_CODEGEN_LOONG64)
# include "jit/loong64/Assembler-loong64.h"
#endif
#if defined(JS_CODEGEN_RISCV64)
# include "jit/riscv64/Assembler-riscv64.h"
#endif
#include "js/ScalarType.h"
#include "util/Memory.h"
#include "wasm/WasmCodegenTypes.h"
#include "wasm/WasmDebugFrame.h"
#include "wasm/WasmGC.h"
#include "wasm/WasmGcObject.h"
#include "wasm/WasmGenerator.h"
#include "wasm/WasmInstance.h"
#include "wasm/WasmOpIter.h"
#include "wasm/WasmSignalHandlers.h"
#include "wasm/WasmStubs.h"
#include "wasm/WasmValidate.h"
using mozilla::DebugOnly;
using mozilla::FloorLog2;
using mozilla::IsPowerOfTwo;
using mozilla::Maybe;
using mozilla::Nothing;
using mozilla::Some;
namespace js {
namespace wasm {
using HandleNaNSpecially = bool;
using InvertBranch = bool;
using IsKnownNotZero = bool;
using IsUnsigned = bool;
using IsRemainder = bool;
using NeedsBoundsCheck = bool;
using WantResult = bool;
using ZeroOnOverflow = bool;
class BaseStackFrame;
// Two flags, useABI and restoreRegisterStateAndRealm, control how calls are
// made.
//
// UseABI::Wasm implies that the Instance/Heap/Global registers are nonvolatile,
// except when RestoreRegisterStateAndRealm::True is also set, when they are
// volatile.
//
// UseABI::Builtin implies that the Instance/Heap/Global registers are volatile.
// In this case, we require RestoreRegisterStateAndRealm::False. The calling
// convention is otherwise like UseABI::Wasm.
//
// UseABI::System implies that the Instance/Heap/Global registers are volatile.
// Additionally, the parameter passing mechanism may be slightly different from
// the UseABI::Wasm convention.
//
// When the Instance/Heap/Global registers are not volatile, the baseline
// compiler will restore the Instance register from its save slot before the
// call, since the baseline compiler uses the Instance register for other
// things.
//
// When those registers are volatile, the baseline compiler will reload them
// after the call (it will restore the Instance register from the save slot and
// load the other two from the Instance data).
enum class UseABI { Wasm, Builtin, System };
enum class RestoreRegisterStateAndRealm { False = false, True = true };
enum class RhsDestOp { True = true };
// Compiler configuration.
//
// The following internal configuration #defines are used. The configuration is
// partly below in this file, partly in WasmBCRegDefs.h.
//
// RABALDR_PIN_INSTANCE
// InstanceReg is not allocatable and always holds the current Instance*,
// except in known contexts where it could have been clobbered, such as after
// certain calls.
//
// RABALDR_ZERO_EXTENDS
// The canonical representation of a 32-bit value in a 64-bit register is
// zero-extended. For 64-bit platforms only. See comment block "64-bit GPRs
// carrying 32-bit values" in MacroAssembler.h.
//
// RABALDR_CHUNKY_STACK
// The platform must allocate the CPU stack in chunks and not word-at-a-time
// due to SP alignment requirements (ARM64 for now).
//
// RABALDR_INT_DIV_I64_CALLOUT
// The platform calls out to the runtime to divide i64/u64.
//
// RABALDR_I64_TO_FLOAT_CALLOUT
// The platform calls out to the runtime for i64 -> fXX conversions.
//
// RABALDR_FLOAT_TO_I64_CALLOUT
// The platform calls out to the runtime for fXX -> i64 conversions.
//
// RABALDR_SCRATCH_<TypeName>
// The baseline compiler has its own scratch registers for the given type, it
// does not use the MacroAssembler's scratch. This is really an anachronism -
// the baseline compiler should never use the MacroAssembler's scratches.
//
// RABALDR_SCRATCH_F32_ALIASES_F64
// On a platform where the baseline compiler has its own F32 and F64
// scratches, these are the same register.
#ifdef JS_CODEGEN_X64
# define RABALDR_ZERO_EXTENDS
# define RABALDR_PIN_INSTANCE
#endif
#ifdef JS_CODEGEN_ARM64
# define RABALDR_CHUNKY_STACK
# define RABALDR_ZERO_EXTENDS
# define RABALDR_PIN_INSTANCE
#endif
#ifdef JS_CODEGEN_X86
# define RABALDR_INT_DIV_I64_CALLOUT
#endif
#ifdef JS_CODEGEN_ARM
# define RABALDR_INT_DIV_I64_CALLOUT
# define RABALDR_I64_TO_FLOAT_CALLOUT
# define RABALDR_FLOAT_TO_I64_CALLOUT
#endif
#ifdef JS_CODEGEN_MIPS64
# define RABALDR_PIN_INSTANCE
#endif
#ifdef JS_CODEGEN_LOONG64
# define RABALDR_PIN_INSTANCE
#endif
#ifdef JS_CODEGEN_RISCV64
# define RABALDR_PIN_INSTANCE
#endif
// Max number of pushes onto the value stack for any opcode or emitter that
// does not push a variable, unbounded amount (anything with multiple
// results). This includes also intermediate pushes such as values pushed as
// parameters for builtin calls.
//
// This limit is set quite high on purpose, so as to avoid brittleness. The
// true max value is likely no more than four or five.
static constexpr size_t MaxPushesPerOpcode = 10;
} // namespace wasm
} // namespace js
#endif // wasm_wasm_baseline_defs_h
|