[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/+/2577820 Reviewed-by: Zhi An Ng <zhin@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Commit-Queue: Milad Fa <mfarazma@redhat.com> Cr-Commit-Position: refs/heads/master@{#71665}
This commit is contained in:
parent
6b5f420828
commit
c73f5c215b
@ -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) { \
|
||||
|
Loading…
Reference in New Issue
Block a user