Commit 266e803e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Liftoff: a baseline compiler for WebAssembly

This CL adds a first implementation of Liftoff, the new wasm baseline
compiler, for x64 and ia32. It currently supports the most important
i32 instructions and control instructions. Whenever it encounters an
instruction it does not support yet, it aborts.
In a subsequent CL, Liftoff will be called from the
WasmCompilationUnit, falling back to Turbofan compilation if the
baseline compiler bails out.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: Ifa78fb9d546dce72c241ff01a251dfa13cb31c1d
Reviewed-on: https://chromium-review.googlesource.com/716480
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48832}
parent 5c2984ab
...@@ -2056,6 +2056,9 @@ v8_source_set("v8_base") { ...@@ -2056,6 +2056,9 @@ v8_source_set("v8_base") {
"src/visitors.h", "src/visitors.h",
"src/vm-state-inl.h", "src/vm-state-inl.h",
"src/vm-state.h", "src/vm-state.h",
"src/wasm/baseline/liftoff-assembler.cc",
"src/wasm/baseline/liftoff-assembler.h",
"src/wasm/baseline/liftoff-compiler.cc",
"src/wasm/compilation-manager.cc", "src/wasm/compilation-manager.cc",
"src/wasm/compilation-manager.h", "src/wasm/compilation-manager.h",
"src/wasm/decoder.h", "src/wasm/decoder.h",
...@@ -2163,6 +2166,8 @@ v8_source_set("v8_base") { ...@@ -2163,6 +2166,8 @@ v8_source_set("v8_base") {
"src/ic/ia32/handler-compiler-ia32.cc", "src/ic/ia32/handler-compiler-ia32.cc",
"src/regexp/ia32/regexp-macro-assembler-ia32.cc", "src/regexp/ia32/regexp-macro-assembler-ia32.cc",
"src/regexp/ia32/regexp-macro-assembler-ia32.h", "src/regexp/ia32/regexp-macro-assembler-ia32.h",
"src/wasm/baseline/ia32/liftoff-assembler-ia32-defs.h",
"src/wasm/baseline/ia32/liftoff-assembler-ia32.h",
] ]
} else if (v8_current_cpu == "x64") { } else if (v8_current_cpu == "x64") {
sources += [ ### gcmole(arch:x64) ### sources += [ ### gcmole(arch:x64) ###
...@@ -2178,6 +2183,8 @@ v8_source_set("v8_base") { ...@@ -2178,6 +2183,8 @@ v8_source_set("v8_base") {
"src/regexp/x64/regexp-macro-assembler-x64.cc", "src/regexp/x64/regexp-macro-assembler-x64.cc",
"src/regexp/x64/regexp-macro-assembler-x64.h", "src/regexp/x64/regexp-macro-assembler-x64.h",
"src/third_party/valgrind/valgrind.h", "src/third_party/valgrind/valgrind.h",
"src/wasm/baseline/x64/liftoff-assembler-x64-defs.h",
"src/wasm/baseline/x64/liftoff-assembler-x64.h",
"src/x64/assembler-x64-inl.h", "src/x64/assembler-x64-inl.h",
"src/x64/assembler-x64.cc", "src/x64/assembler-x64.cc",
"src/x64/assembler-x64.h", "src/x64/assembler-x64.h",
...@@ -2233,6 +2240,8 @@ v8_source_set("v8_base") { ...@@ -2233,6 +2240,8 @@ v8_source_set("v8_base") {
"src/ic/arm/handler-compiler-arm.cc", "src/ic/arm/handler-compiler-arm.cc",
"src/regexp/arm/regexp-macro-assembler-arm.cc", "src/regexp/arm/regexp-macro-assembler-arm.cc",
"src/regexp/arm/regexp-macro-assembler-arm.h", "src/regexp/arm/regexp-macro-assembler-arm.h",
"src/wasm/baseline/arm/liftoff-assembler-arm-defs.h",
"src/wasm/baseline/arm/liftoff-assembler-arm.h",
] ]
} else if (v8_current_cpu == "arm64") { } else if (v8_current_cpu == "arm64") {
sources += [ ### gcmole(arch:arm64) ### sources += [ ### gcmole(arch:arm64) ###
...@@ -2279,6 +2288,8 @@ v8_source_set("v8_base") { ...@@ -2279,6 +2288,8 @@ v8_source_set("v8_base") {
"src/ic/arm64/handler-compiler-arm64.cc", "src/ic/arm64/handler-compiler-arm64.cc",
"src/regexp/arm64/regexp-macro-assembler-arm64.cc", "src/regexp/arm64/regexp-macro-assembler-arm64.cc",
"src/regexp/arm64/regexp-macro-assembler-arm64.h", "src/regexp/arm64/regexp-macro-assembler-arm64.h",
"src/wasm/baseline/arm64/liftoff-assembler-arm64-defs.h",
"src/wasm/baseline/arm64/liftoff-assembler-arm64.h",
] ]
if (use_jumbo_build) { if (use_jumbo_build) {
jumbo_excluded_sources += [ jumbo_excluded_sources += [
...@@ -2316,6 +2327,8 @@ v8_source_set("v8_base") { ...@@ -2316,6 +2327,8 @@ v8_source_set("v8_base") {
"src/mips/simulator-mips.h", "src/mips/simulator-mips.h",
"src/regexp/mips/regexp-macro-assembler-mips.cc", "src/regexp/mips/regexp-macro-assembler-mips.cc",
"src/regexp/mips/regexp-macro-assembler-mips.h", "src/regexp/mips/regexp-macro-assembler-mips.h",
"src/wasm/baseline/mips/liftoff-assembler-mips-defs.h",
"src/wasm/baseline/mips/liftoff-assembler-mips.h",
] ]
} else if (v8_current_cpu == "mips64" || v8_current_cpu == "mips64el") { } else if (v8_current_cpu == "mips64" || v8_current_cpu == "mips64el") {
sources += [ ### gcmole(arch:mips64el) ### sources += [ ### gcmole(arch:mips64el) ###
...@@ -2346,6 +2359,8 @@ v8_source_set("v8_base") { ...@@ -2346,6 +2359,8 @@ v8_source_set("v8_base") {
"src/mips64/simulator-mips64.h", "src/mips64/simulator-mips64.h",
"src/regexp/mips64/regexp-macro-assembler-mips64.cc", "src/regexp/mips64/regexp-macro-assembler-mips64.cc",
"src/regexp/mips64/regexp-macro-assembler-mips64.h", "src/regexp/mips64/regexp-macro-assembler-mips64.h",
"src/wasm/baseline/mips64/liftoff-assembler-mips64-defs.h",
"src/wasm/baseline/mips64/liftoff-assembler-mips64.h",
] ]
} else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") { } else if (v8_current_cpu == "ppc" || v8_current_cpu == "ppc64") {
sources += [ ### gcmole(arch:ppc) ### sources += [ ### gcmole(arch:ppc) ###
...@@ -2376,6 +2391,8 @@ v8_source_set("v8_base") { ...@@ -2376,6 +2391,8 @@ v8_source_set("v8_base") {
"src/ppc/simulator-ppc.h", "src/ppc/simulator-ppc.h",
"src/regexp/ppc/regexp-macro-assembler-ppc.cc", "src/regexp/ppc/regexp-macro-assembler-ppc.cc",
"src/regexp/ppc/regexp-macro-assembler-ppc.h", "src/regexp/ppc/regexp-macro-assembler-ppc.h",
"src/wasm/baseline/ppc/liftoff-assembler-ppc-defs.h",
"src/wasm/baseline/ppc/liftoff-assembler-ppc.h",
] ]
} else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") { } else if (v8_current_cpu == "s390" || v8_current_cpu == "s390x") {
sources += [ ### gcmole(arch:s390) ### sources += [ ### gcmole(arch:s390) ###
......
...@@ -280,6 +280,12 @@ class Register : public CPURegister { ...@@ -280,6 +280,12 @@ class Register : public CPURegister {
return Register::Create(code, kXRegSizeInBits); return Register::Create(code, kXRegSizeInBits);
} }
template <int code>
static Register from_code() {
// Always return an X register.
return Register::Create<code, kXRegSizeInBits>();
}
// End of V8 compatibility section ----------------------- // End of V8 compatibility section -----------------------
// //
private: private:
......
...@@ -505,6 +505,7 @@ DEFINE_BOOL(trace_wasm_streaming, false, ...@@ -505,6 +505,7 @@ DEFINE_BOOL(trace_wasm_streaming, false,
DEFINE_INT(trace_wasm_ast_start, 0, DEFINE_INT(trace_wasm_ast_start, 0,
"start function for wasm AST trace (inclusive)") "start function for wasm AST trace (inclusive)")
DEFINE_INT(trace_wasm_ast_end, 0, "end function for wasm AST trace (exclusive)") DEFINE_INT(trace_wasm_ast_end, 0, "end function for wasm AST trace (exclusive)")
DEFINE_BOOL(trace_liftoff, false, "trace liftoff, the wasm baseline compiler")
DEFINE_UINT(skip_compiling_wasm_funcs, 0, "start compiling at function N") DEFINE_UINT(skip_compiling_wasm_funcs, 0, "start compiling at function N")
DEFINE_BOOL(wasm_break_on_decoder_error, false, DEFINE_BOOL(wasm_break_on_decoder_error, false,
"debug break when wasm decoder encounters an error") "debug break when wasm decoder encounters an error")
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
enum class MachineRepresentation { enum class MachineRepresentation : uint8_t {
kNone, kNone,
kBit, kBit,
kWord8, kWord8,
...@@ -41,7 +41,7 @@ static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) < ...@@ -41,7 +41,7 @@ static_assert(static_cast<int>(MachineRepresentation::kLastRepresentation) <
const char* MachineReprToString(MachineRepresentation); const char* MachineReprToString(MachineRepresentation);
enum class MachineSemantic { enum class MachineSemantic : uint8_t {
kNone, kNone,
kBool, kBool,
kInt32, kInt32,
......
...@@ -1437,6 +1437,9 @@ ...@@ -1437,6 +1437,9 @@
'visitors.h', 'visitors.h',
'vm-state-inl.h', 'vm-state-inl.h',
'vm-state.h', 'vm-state.h',
'wasm/baseline/liftoff-assembler.cc',
'wasm/baseline/liftoff-assembler.h',
'wasm/baseline/liftoff-compiler.cc',
'wasm/compilation-manager.cc', 'wasm/compilation-manager.cc',
'wasm/compilation-manager.h', 'wasm/compilation-manager.h',
'wasm/decoder.h', 'wasm/decoder.h',
...@@ -1532,13 +1535,15 @@ ...@@ -1532,13 +1535,15 @@
'compiler/arm/instruction-codes-arm.h', 'compiler/arm/instruction-codes-arm.h',
'compiler/arm/instruction-scheduler-arm.cc', 'compiler/arm/instruction-scheduler-arm.cc',
'compiler/arm/instruction-selector-arm.cc', 'compiler/arm/instruction-selector-arm.cc',
'compiler/arm/unwinding-info-writer-arm.h',
'compiler/arm/unwinding-info-writer-arm.cc', 'compiler/arm/unwinding-info-writer-arm.cc',
'compiler/arm/unwinding-info-writer-arm.h',
'debug/arm/debug-arm.cc', 'debug/arm/debug-arm.cc',
'ic/arm/access-compiler-arm.cc', 'ic/arm/access-compiler-arm.cc',
'ic/arm/handler-compiler-arm.cc', 'ic/arm/handler-compiler-arm.cc',
'regexp/arm/regexp-macro-assembler-arm.cc', 'regexp/arm/regexp-macro-assembler-arm.cc',
'regexp/arm/regexp-macro-assembler-arm.h', 'regexp/arm/regexp-macro-assembler-arm.h',
'wasm/baseline/arm/liftoff-assembler-arm-defs.h',
'wasm/baseline/arm/liftoff-assembler-arm.h',
], ],
}], }],
['v8_target_arch=="arm64"', { ['v8_target_arch=="arm64"', {
...@@ -1579,13 +1584,15 @@ ...@@ -1579,13 +1584,15 @@
'compiler/arm64/instruction-codes-arm64.h', 'compiler/arm64/instruction-codes-arm64.h',
'compiler/arm64/instruction-scheduler-arm64.cc', 'compiler/arm64/instruction-scheduler-arm64.cc',
'compiler/arm64/instruction-selector-arm64.cc', 'compiler/arm64/instruction-selector-arm64.cc',
'compiler/arm64/unwinding-info-writer-arm64.h',
'compiler/arm64/unwinding-info-writer-arm64.cc', 'compiler/arm64/unwinding-info-writer-arm64.cc',
'compiler/arm64/unwinding-info-writer-arm64.h',
'debug/arm64/debug-arm64.cc', 'debug/arm64/debug-arm64.cc',
'ic/arm64/access-compiler-arm64.cc', 'ic/arm64/access-compiler-arm64.cc',
'ic/arm64/handler-compiler-arm64.cc', 'ic/arm64/handler-compiler-arm64.cc',
'regexp/arm64/regexp-macro-assembler-arm64.cc', 'regexp/arm64/regexp-macro-assembler-arm64.cc',
'regexp/arm64/regexp-macro-assembler-arm64.h', 'regexp/arm64/regexp-macro-assembler-arm64.h',
'wasm/baseline/arm64/liftoff-assembler-arm64-defs.h',
'wasm/baseline/arm64/liftoff-assembler-arm64.h',
], ],
}], }],
['v8_target_arch=="ia32"', { ['v8_target_arch=="ia32"', {
...@@ -1616,6 +1623,8 @@ ...@@ -1616,6 +1623,8 @@
'ic/ia32/handler-compiler-ia32.cc', 'ic/ia32/handler-compiler-ia32.cc',
'regexp/ia32/regexp-macro-assembler-ia32.cc', 'regexp/ia32/regexp-macro-assembler-ia32.cc',
'regexp/ia32/regexp-macro-assembler-ia32.h', 'regexp/ia32/regexp-macro-assembler-ia32.h',
'wasm/baseline/ia32/liftoff-assembler-ia32-defs.h',
'wasm/baseline/ia32/liftoff-assembler-ia32.h',
], ],
}], }],
['v8_target_arch=="mips" or v8_target_arch=="mipsel"', { ['v8_target_arch=="mips" or v8_target_arch=="mipsel"', {
...@@ -1647,6 +1656,8 @@ ...@@ -1647,6 +1656,8 @@
'ic/mips/handler-compiler-mips.cc', 'ic/mips/handler-compiler-mips.cc',
'regexp/mips/regexp-macro-assembler-mips.cc', 'regexp/mips/regexp-macro-assembler-mips.cc',
'regexp/mips/regexp-macro-assembler-mips.h', 'regexp/mips/regexp-macro-assembler-mips.h',
'wasm/baseline/mips/liftoff-assembler-mips-defs.h',
'wasm/baseline/mips/liftoff-assembler-mips.h',
], ],
}], }],
['v8_target_arch=="mips64" or v8_target_arch=="mips64el"', { ['v8_target_arch=="mips64" or v8_target_arch=="mips64el"', {
...@@ -1678,6 +1689,8 @@ ...@@ -1678,6 +1689,8 @@
'ic/mips64/handler-compiler-mips64.cc', 'ic/mips64/handler-compiler-mips64.cc',
'regexp/mips64/regexp-macro-assembler-mips64.cc', 'regexp/mips64/regexp-macro-assembler-mips64.cc',
'regexp/mips64/regexp-macro-assembler-mips64.h', 'regexp/mips64/regexp-macro-assembler-mips64.h',
'wasm/baseline/mips64/liftoff-assembler-mips64-defs.h',
'wasm/baseline/mips64/liftoff-assembler-mips64.h',
], ],
}], }],
['v8_target_arch=="x64"', { ['v8_target_arch=="x64"', {
...@@ -1686,8 +1699,8 @@ ...@@ -1686,8 +1699,8 @@
'compiler/x64/instruction-codes-x64.h', 'compiler/x64/instruction-codes-x64.h',
'compiler/x64/instruction-scheduler-x64.cc', 'compiler/x64/instruction-scheduler-x64.cc',
'compiler/x64/instruction-selector-x64.cc', 'compiler/x64/instruction-selector-x64.cc',
'compiler/x64/unwinding-info-writer-x64.h',
'compiler/x64/unwinding-info-writer-x64.cc', 'compiler/x64/unwinding-info-writer-x64.cc',
'compiler/x64/unwinding-info-writer-x64.h',
'x64/assembler-x64-inl.h', 'x64/assembler-x64-inl.h',
'x64/assembler-x64.cc', 'x64/assembler-x64.cc',
'x64/assembler-x64.h', 'x64/assembler-x64.h',
...@@ -1712,6 +1725,8 @@ ...@@ -1712,6 +1725,8 @@
'regexp/x64/regexp-macro-assembler-x64.cc', 'regexp/x64/regexp-macro-assembler-x64.cc',
'regexp/x64/regexp-macro-assembler-x64.h', 'regexp/x64/regexp-macro-assembler-x64.h',
'third_party/valgrind/valgrind.h', 'third_party/valgrind/valgrind.h',
'wasm/baseline/x64/liftoff-assembler-x64-defs.h',
'wasm/baseline/x64/liftoff-assembler-x64.h',
], ],
}], }],
['v8_target_arch=="x64" and OS=="linux"', { ['v8_target_arch=="x64" and OS=="linux"', {
...@@ -1746,6 +1761,8 @@ ...@@ -1746,6 +1761,8 @@
'ppc/simulator-ppc.h', 'ppc/simulator-ppc.h',
'regexp/ppc/regexp-macro-assembler-ppc.cc', 'regexp/ppc/regexp-macro-assembler-ppc.cc',
'regexp/ppc/regexp-macro-assembler-ppc.h', 'regexp/ppc/regexp-macro-assembler-ppc.h',
'wasm/baseline/ppc/liftoff-assembler-ppc-defs.h',
'wasm/baseline/ppc/liftoff-assembler-ppc.h',
], ],
}], }],
['v8_target_arch=="s390" or v8_target_arch=="s390x"', { ['v8_target_arch=="s390" or v8_target_arch=="s390x"', {
......
# Liftoff (the baseline compiler for WebAssembly) depends on some compiler
# internals, like the linkage location for parameters and returns.
include_rules = [
"+src/compiler/linkage.h",
]
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
// TODO(clemensh): Implement the LiftoffAssembler on this platform.
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = false;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_H_
#include "src/wasm/baseline/liftoff-assembler.h"
namespace v8 {
namespace internal {
namespace wasm {
void LiftoffAssembler::ReserveStackSpace(uint32_t space) { USE(stack_space_); }
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) {}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
// TODO(clemensh): Implement the LiftoffAssembler on this platform.
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = false;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_H_
#include "src/wasm/baseline/liftoff-assembler.h"
namespace v8 {
namespace internal {
namespace wasm {
void LiftoffAssembler::ReserveStackSpace(uint32_t space) { USE(stack_space_); }
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) {}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_ARM64_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = true;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 1 << 0 | // eax
1 << 1 | // ecx
1 << 2 | // edx
1 << 3 | // ebx
1 << 6 | // esi
1 << 7; // edi
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_H_
#include "src/wasm/baseline/liftoff-assembler.h"
#include "src/assembler.h"
#include "src/wasm/wasm-opcodes.h"
namespace v8 {
namespace internal {
namespace wasm {
namespace liftoff {
inline Operand GetStackSlot(uint32_t index) {
// ebp-8 holds the stack marker, first stack slot is located at ebp-16.
return Operand(ebp, -16 - 8 * index);
}
} // namespace liftoff
void LiftoffAssembler::ReserveStackSpace(uint32_t space) {
stack_space_ = space;
sub(esp, Immediate(space));
}
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {
switch (value.type()) {
case kWasmI32:
if (value.to_i32() == 0) {
xor_(reg, reg);
} else {
mov(reg, Immediate(value.to_i32()));
}
break;
default:
UNIMPLEMENTED();
}
}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {
if (reg != eax) mov(eax, reg);
}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {
mov(dst, Operand(reinterpret_cast<uint32_t>(addr), reloc_mode));
}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {
mov(Operand(reinterpret_cast<uint32_t>(addr), reloc_mode), reg);
}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {
mov(dst, Operand(ebp, 4 + 4 * caller_slot_idx));
}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {
DCHECK_NE(dst_index, src_index);
DCHECK_EQ(kWasmI32, type);
if (cache_state_.has_unused_register()) {
Register reg = GetUnusedRegister(type);
Fill(reg, src_index);
Spill(dst_index, reg);
} else {
push(liftoff::GetStackSlot(src_index));
pop(liftoff::GetStackSlot(dst_index));
}
}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {
// TODO(clemensh): Handle different types here.
mov(liftoff::GetStackSlot(index), reg);
}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {
// TODO(clemensh): Handle different types here.
mov(liftoff::GetStackSlot(index), Immediate(value.to_i32()));
}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {
// TODO(clemensh): Handle different types here.
mov(reg, liftoff::GetStackSlot(index));
}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {
if (lhs.code() != dst.code()) {
lea(dst, Operand(lhs, rhs, times_1, 0));
} else {
add(dst, rhs);
}
}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) { \
if (lhs.code() != dst.code()) { \
mov(dst, lhs); \
} \
internal_name(dst, rhs); \
}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and_)
DEFAULT_I32_BINOP(or, or_)
DEFAULT_I32_BINOP(xor, xor_)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {
test(reg, reg);
j(zero, label);
}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_IA32_H_
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
// TODO(clemensh): Implement the LiftoffAssembler on this platform.
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = false;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_H_
#include "src/wasm/baseline/liftoff-assembler.h"
namespace v8 {
namespace internal {
namespace wasm {
void LiftoffAssembler::ReserveStackSpace(uint32_t space) { USE(stack_space_); }
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) {}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
// TODO(clemensh): Implement the LiftoffAssembler on this platform.
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = false;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_H_
#include "src/wasm/baseline/liftoff-assembler.h"
namespace v8 {
namespace internal {
namespace wasm {
void LiftoffAssembler::ReserveStackSpace(uint32_t space) { USE(stack_space_); }
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) {}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_MIPS64_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
// TODO(clemensh): Implement the LiftoffAssembler on this platform.
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = false;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 0xff;
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_H_
#include "src/wasm/baseline/liftoff-assembler.h"
namespace v8 {
namespace internal {
namespace wasm {
void LiftoffAssembler::ReserveStackSpace(uint32_t space) { USE(stack_space_); }
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) {}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_PPC_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_DEFS_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_DEFS_H_
#include "src/reglist.h"
namespace v8 {
namespace internal {
namespace wasm {
static constexpr bool kLiftoffAssemblerImplementedOnThisPlatform = true;
static constexpr RegList kLiftoffAssemblerGpCacheRegs = 1 << 0 | // rax
1 << 1 | // rcx
1 << 2 | // rdx
1 << 3 | // rbx
1 << 6 | // rsi
1 << 7; // rdi
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_DEFS_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_H_
#include "src/wasm/baseline/liftoff-assembler.h"
#include "src/assembler.h"
#include "src/wasm/wasm-opcodes.h"
namespace v8 {
namespace internal {
namespace wasm {
namespace liftoff {
inline Operand GetStackSlot(uint32_t index) {
// rbp-8 holds the stack marker, first stack slot is located at rbp-16.
return Operand(rbp, -16 - 8 * index);
}
} // namespace liftoff
void LiftoffAssembler::ReserveStackSpace(uint32_t space) {
stack_space_ = space;
subl(rsp, Immediate(space));
}
void LiftoffAssembler::LoadConstant(Register reg, WasmValue value) {
switch (value.type()) {
case kWasmI32:
if (value.to_i32() == 0) {
xorl(reg, reg);
} else {
movl(reg, Immediate(value.to_i32()));
}
break;
default:
UNIMPLEMENTED();
}
}
void LiftoffAssembler::Load(Register dst, Address addr,
RelocInfo::Mode reloc_mode) {
movp(dst, bit_cast<void*>(addr), reloc_mode);
movl(dst, Operand(dst, 0));
}
void LiftoffAssembler::Store(Address addr, Register reg,
PinnedRegisterScope pinned_regs,
RelocInfo::Mode reloc_mode) {
// TODO(clemensh): Change this to kPointerSizeT or something.
Register global_addr_reg = GetUnusedRegister(kWasmI32, pinned_regs);
DCHECK_NE(reg, global_addr_reg);
movp(global_addr_reg, static_cast<void*>(addr), reloc_mode);
movl(Operand(global_addr_reg, 0), reg);
}
void LiftoffAssembler::LoadCallerFrameSlot(Register dst,
uint32_t caller_slot_idx) {
movl(dst, Operand(rbp, 8 + 8 * caller_slot_idx));
}
void LiftoffAssembler::MoveStackValue(uint32_t dst_index, uint32_t src_index,
wasm::ValueType type) {
DCHECK_NE(dst_index, src_index);
DCHECK_EQ(kWasmI32, type);
if (cache_state_.has_unused_register()) {
Register reg = GetUnusedRegister(type);
Fill(reg, src_index);
Spill(dst_index, reg);
} else {
pushq(liftoff::GetStackSlot(src_index));
popq(liftoff::GetStackSlot(dst_index));
}
}
void LiftoffAssembler::MoveToReturnRegister(Register reg) {
// TODO(clemensh): Handle different types here.
if (reg != rax) movl(rax, reg);
}
void LiftoffAssembler::Spill(uint32_t index, Register reg) {
// TODO(clemensh): Handle different types here.
movl(liftoff::GetStackSlot(index), reg);
}
void LiftoffAssembler::Spill(uint32_t index, WasmValue value) {
// TODO(clemensh): Handle different types here.
movl(liftoff::GetStackSlot(index), Immediate(value.to_i32()));
}
void LiftoffAssembler::Fill(Register reg, uint32_t index) {
// TODO(clemensh): Handle different types here.
movl(reg, liftoff::GetStackSlot(index));
}
void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {
if (lhs.code() != dst.code()) {
leal(dst, Operand(lhs, rhs, times_1, 0));
} else {
addl(dst, rhs);
}
}
#define DEFAULT_I32_BINOP(name, internal_name) \
void LiftoffAssembler::emit_i32_##name(Register dst, Register lhs, \
Register rhs) { \
if (lhs.code() != dst.code()) { \
movl(dst, lhs); \
} \
internal_name##l(dst, rhs); \
}
// clang-format off
DEFAULT_I32_BINOP(sub, sub)
DEFAULT_I32_BINOP(mul, imul)
DEFAULT_I32_BINOP(and, and)
DEFAULT_I32_BINOP(or, or)
DEFAULT_I32_BINOP(xor, xor)
// clang-format on
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::JumpIfZero(Register reg, Label* label) {
testl(reg, reg);
j(zero, label);
}
} // namespace wasm
} // namespace internal
} // namespace v8
#endif // V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_X64_H_
...@@ -459,6 +459,8 @@ struct ControlBase { ...@@ -459,6 +459,8 @@ struct ControlBase {
bool merge_reached = false) bool merge_reached = false)
: kind(kind), stack_depth(stack_depth), pc(pc), merge(merge_reached) {} : kind(kind), stack_depth(stack_depth), pc(pc), merge(merge_reached) {}
uint32_t break_arity() const { return is_loop() ? 0 : merge.arity; }
// Check whether the current block is reachable. // Check whether the current block is reachable.
bool reachable() const { return reachability == kReachable; } bool reachable() const { return reachability == kReachable; }
...@@ -1221,6 +1223,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1221,6 +1223,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
inline uint32_t stack_size() const { inline uint32_t stack_size() const {
DCHECK_GE(kMaxUInt32, stack_.size());
return static_cast<uint32_t>(stack_.size()); return static_cast<uint32_t>(stack_.size());
} }
...@@ -1520,7 +1523,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -1520,7 +1523,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
} }
// Check that label types match up. // Check that label types match up.
Control* c = control_at(target); Control* c = control_at(target);
uint32_t arity = c->is_loop() ? 0 : c->merge.arity; uint32_t arity = c->break_arity();
if (i == 0) { if (i == 0) {
br_arity = arity; br_arity = arity;
} else if (!VALIDATE(br_arity == arity)) { } else if (!VALIDATE(br_arity == arity)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment