Commit c73f5c21 authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

[wasm-simd] Prototype load lane and store lane on BE machines

Prototype v128.{load,store}{8,16,32,64}_lane on Big Endian machines.

Lood/Stores need to be reversed manually on BE machines and as such
LoadLane and StoreLane opcodes cannot be done in a single instruction.
Therefore we divide them into separate "Load/Store" and "operation"
nodes.

Bug: v8:10975
Change-Id: If21c9663de41b872fe035d15526830f244605c48
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2577820Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#71665}
parent 6b5f4208
......@@ -4072,8 +4072,9 @@ Node* WasmGraphBuilder::LoadTransformBigEndian(
}
#endif
Node* WasmGraphBuilder::LoadLane(MachineType memtype, Node* value, Node* index,
uint64_t offset, uint8_t laneidx,
Node* WasmGraphBuilder::LoadLane(wasm::ValueType type, MachineType memtype,
Node* value, Node* index, uint64_t offset,
uint32_t alignment, uint8_t laneidx,
wasm::WasmCodePosition position) {
has_simd_ = true;
Node* load;
......@@ -4081,11 +4082,29 @@ Node* WasmGraphBuilder::LoadLane(MachineType memtype, Node* value, Node* index,
index =
BoundsCheckMem(access_size, index, offset, position, kCanOmitBoundsCheck);
// {offset} is validated to be within uintptr_t range in {BoundsCheckMem}.
uintptr_t capped_offset = static_cast<uintptr_t>(offset);
#if defined(V8_TARGET_BIG_ENDIAN) || defined(V8_TARGET_ARCH_S390_LE_SIM)
load = LoadMem(type, memtype, index, offset, alignment, position);
if (memtype == MachineType::Int8()) {
load = graph()->NewNode(mcgraph()->machine()->I8x16ReplaceLane(laneidx),
value, load);
} else if (memtype == MachineType::Int16()) {
load = graph()->NewNode(mcgraph()->machine()->I16x8ReplaceLane(laneidx),
value, load);
} else if (memtype == MachineType::Int32()) {
load = graph()->NewNode(mcgraph()->machine()->I32x4ReplaceLane(laneidx),
value, load);
} else if (memtype == MachineType::Int64()) {
load = graph()->NewNode(mcgraph()->machine()->I64x2ReplaceLane(laneidx),
value, load);
} else {
UNREACHABLE();
}
#else
MemoryAccessKind load_kind =
GetMemoryAccessKind(mcgraph(), memtype, use_trap_handler());
// {offset} is validated to be within uintptr_t range in {BoundsCheckMem}.
uintptr_t capped_offset = static_cast<uintptr_t>(offset);
load = SetEffect(graph()->NewNode(
mcgraph()->machine()->LoadLane(load_kind, memtype, laneidx),
MemBuffer(capped_offset), index, value, effect(), control()));
......@@ -4093,7 +4112,7 @@ Node* WasmGraphBuilder::LoadLane(MachineType memtype, Node* value, Node* index,
if (load_kind == MemoryAccessKind::kProtected) {
SetSourcePosition(load, position);
}
#endif
if (FLAG_trace_wasm_memory) {
TraceMemoryOperation(false, memtype.representation(), index, capped_offset,
position);
......@@ -4223,13 +4242,31 @@ Node* WasmGraphBuilder::StoreLane(MachineRepresentation mem_rep, Node* index,
index = BoundsCheckMem(i::ElementSizeInBytes(mem_rep), index, offset,
position, kCanOmitBoundsCheck);
// {offset} is validated to be within uintptr_t range in {BoundsCheckMem}.
uintptr_t capped_offset = static_cast<uintptr_t>(offset);
#if defined(V8_TARGET_BIG_ENDIAN) || defined(V8_TARGET_ARCH_S390_LE_SIM)
Node* output;
if (mem_rep == MachineRepresentation::kWord8) {
output =
graph()->NewNode(mcgraph()->machine()->I8x16ExtractLaneS(laneidx), val);
} else if (mem_rep == MachineRepresentation::kWord16) {
output =
graph()->NewNode(mcgraph()->machine()->I16x8ExtractLaneS(laneidx), val);
} else if (mem_rep == MachineRepresentation::kWord32) {
output =
graph()->NewNode(mcgraph()->machine()->I32x4ExtractLane(laneidx), val);
} else if (mem_rep == MachineRepresentation::kWord64) {
output =
graph()->NewNode(mcgraph()->machine()->I64x2ExtractLane(laneidx), val);
} else {
UNREACHABLE();
}
store = StoreMem(mem_rep, index, offset, alignment, output, position, type);
#else
MachineType memtype = MachineType(mem_rep, MachineSemantic::kNone);
MemoryAccessKind load_kind =
GetMemoryAccessKind(mcgraph(), memtype, use_trap_handler());
// {offset} is validated to be within uintptr_t range in {BoundsCheckMem}.
uintptr_t capped_offset = static_cast<uintptr_t>(offset);
store = SetEffect(graph()->NewNode(
mcgraph()->machine()->StoreLane(load_kind, mem_rep, laneidx),
MemBuffer(capped_offset), index, val, effect(), control()));
......@@ -4237,7 +4274,7 @@ Node* WasmGraphBuilder::StoreLane(MachineRepresentation mem_rep, Node* index,
if (load_kind == MemoryAccessKind::kProtected) {
SetSourcePosition(store, position);
}
#endif
if (FLAG_trace_wasm_memory) {
TraceMemoryOperation(true, mem_rep, index, capped_offset, position);
}
......
......@@ -316,7 +316,8 @@ class WasmGraphBuilder {
wasm::LoadTransformationKind transform, Node* index,
uint64_t offset, uint32_t alignment,
wasm::WasmCodePosition position);
Node* LoadLane(MachineType memtype, Node* value, Node* index, uint64_t offset,
Node* LoadLane(wasm::ValueType type, MachineType memtype, Node* value,
Node* index, uint64_t offset, uint32_t alignment,
uint8_t laneidx, wasm::WasmCodePosition position);
Node* StoreMem(MachineRepresentation mem_rep, Node* index, uint64_t offset,
uint32_t alignment, Node* val, wasm::WasmCodePosition position,
......
......@@ -442,8 +442,9 @@ class WasmGraphBuildingInterface {
void LoadLane(FullDecoder* decoder, LoadType type, const Value& value,
const Value& index, const MemoryAccessImmediate<validate>& imm,
const uint8_t laneidx, Value* result) {
result->node = BUILD(LoadLane, type.mem_type(), value.node, index.node,
imm.offset, laneidx, decoder->position());
result->node = BUILD(LoadLane, type.value_type(), type.mem_type(),
value.node, index.node, imm.offset, imm.alignment,
laneidx, decoder->position());
}
void StoreMem(FullDecoder* decoder, StoreType type,
......
......@@ -3977,7 +3977,7 @@ WASM_SIMD_TEST(S128Load64Zero) {
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_ARM
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
// TODO(v8:10975): Prototyping load lane and store lane.
template <typename T>
void RunLoadLaneTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
......@@ -4183,7 +4183,7 @@ WASM_SIMD_TEST_NO_LOWERING(S128Store64Lane) {
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 ||
// V8_TARGET_ARCH_ARM
// V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
#define WASM_SIMD_ANYTRUE_TEST(format, lanes, max, param_type) \
WASM_SIMD_TEST(S##format##AnyTrue) { \
......
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