Commit 22e06c7b authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][x64][liftoff] Implement store lane

Factor out the code sequence into macro-assembler functions to be reused
by Liftoff.

Bug: v8:10975
Change-Id: I82e253c94e09bf62197e7de87359d0e3956d2dcc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2643662
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72300}
parent 53cb6654
......@@ -2222,6 +2222,26 @@ void TurboAssembler::I16x8Q15MulRSatS(XMMRegister dst, XMMRegister src1,
Pxor(dst, kScratchDoubleReg);
}
void TurboAssembler::S128Store32Lane(Operand dst, XMMRegister src,
uint8_t laneidx) {
if (laneidx == 0) {
Movss(dst, src);
} else {
DCHECK_GE(3, laneidx);
Extractps(dst, src, laneidx);
}
}
void TurboAssembler::S128Store64Lane(Operand dst, XMMRegister src,
uint8_t laneidx) {
if (laneidx == 0) {
Movlps(dst, src);
} else {
DCHECK_EQ(1, laneidx);
Movhps(dst, src);
}
}
void TurboAssembler::Abspd(XMMRegister dst) {
Andps(dst, ExternalReferenceAsOperand(
ExternalReference::address_of_double_abs_constant()));
......
......@@ -599,6 +599,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void I16x8Q15MulRSatS(XMMRegister dst, XMMRegister src1, XMMRegister src2);
void S128Store32Lane(Operand dst, XMMRegister src, uint8_t laneidx);
void S128Store64Lane(Operand dst, XMMRegister src, uint8_t laneidx);
void Abspd(XMMRegister dst);
void Negpd(XMMRegister dst);
......
......@@ -4000,12 +4000,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
uint8_t lane = i.InputUint8(index + 1);
if (lane == 0) {
__ Movss(operand, i.InputSimd128Register(index));
} else {
DCHECK_GE(3, lane);
__ Extractps(operand, i.InputSimd128Register(index), lane);
}
__ S128Store32Lane(operand, i.InputSimd128Register(index), lane);
break;
}
case kX64S128Store64Lane: {
......@@ -4013,12 +4008,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
uint8_t lane = i.InputUint8(index + 1);
if (lane == 0) {
__ Movlps(operand, i.InputSimd128Register(index));
} else {
DCHECK_EQ(1, lane);
__ Movhps(operand, i.InputSimd128Register(index));
}
__ S128Store64Lane(operand, i.InputSimd128Register(index), lane);
break;
}
case kX64Shufps: {
......
......@@ -2382,6 +2382,13 @@ void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
NeonMemOperand(actual_src_addr));
}
void LiftoffAssembler::StoreLane(Register dst, Register offset,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint8_t lane,
uint32_t* protected_store_pc) {
bailout(kSimd, "store lane");
}
void LiftoffAssembler::emit_i8x16_swizzle(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
......
......@@ -1673,6 +1673,13 @@ void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
}
}
void LiftoffAssembler::StoreLane(Register dst, Register offset,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint8_t lane,
uint32_t* protected_store_pc) {
bailout(kSimd, "store lane");
}
void LiftoffAssembler::emit_i8x16_swizzle(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
......
......@@ -2785,6 +2785,13 @@ void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
}
}
void LiftoffAssembler::StoreLane(Register dst, Register offset,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint8_t lane,
uint32_t* protected_store_pc) {
bailout(kSimd, "store lane");
}
void LiftoffAssembler::emit_i8x16_shuffle(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs,
......
......@@ -879,6 +879,9 @@ class LiftoffAssembler : public TurboAssembler {
inline void LoadLane(LiftoffRegister dst, LiftoffRegister src, Register addr,
Register offset_reg, uintptr_t offset_imm, LoadType type,
uint8_t lane, uint32_t* protected_load_pc);
inline void StoreLane(Register dst, Register offset, uintptr_t offset_imm,
LiftoffRegister src, StoreType type, uint8_t lane,
uint32_t* protected_store_pc);
inline void emit_i8x16_shuffle(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs, const uint8_t shuffle[16],
bool is_swizzle);
......
......@@ -2667,9 +2667,33 @@ class LiftoffCompiler {
}
void StoreLane(FullDecoder* decoder, StoreType type,
const MemoryAccessImmediate<validate>& imm, const Value& index,
const Value& value, const uint8_t laneidx) {
unsupported(decoder, kSimd, "simd load lane");
const MemoryAccessImmediate<validate>& imm,
const Value& _index, const Value& _value, const uint8_t lane) {
if (!CheckSupportedType(decoder, kWasmS128, "StoreLane")) return;
LiftoffRegList pinned;
LiftoffRegister value = pinned.set(__ PopToRegister());
LiftoffRegister full_index = __ PopToRegister(pinned);
Register index = BoundsCheckMem(decoder, type.size(), imm.offset,
full_index, pinned, kDontForceCheck);
if (index == no_reg) return;
uintptr_t offset = imm.offset;
pinned.set(index);
index = AddMemoryMasking(index, &offset, &pinned);
DEBUG_CODE_COMMENT("store lane to memory");
Register addr = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
LOAD_INSTANCE_FIELD(addr, MemoryStart, kSystemPointerSize);
uint32_t protected_store_pc = 0;
__ StoreLane(addr, index, offset, value, type, lane, &protected_store_pc);
if (env_->use_trap_handler) {
AddOutOfLineTrap(decoder->position(),
WasmCode::kThrowWasmTrapMemOutOfBounds,
protected_store_pc);
}
if (FLAG_trace_wasm_memory) {
TraceMemoryOperation(true, type.mem_rep(), index, offset,
decoder->position());
}
}
void CurrentMemoryPages(FullDecoder* /* decoder */, Value* /* result */) {
......
......@@ -8,6 +8,7 @@
#include "src/base/platform/wrappers.h"
#include "src/codegen/assembler.h"
#include "src/codegen/cpu-features.h"
#include "src/codegen/machine-type.h"
#include "src/heap/memory-chunk.h"
#include "src/wasm/baseline/liftoff-assembler.h"
#include "src/wasm/simd-shuffle.h"
......@@ -2397,6 +2398,25 @@ void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
}
}
void LiftoffAssembler::StoreLane(Register dst, Register offset,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint8_t lane,
uint32_t* protected_store_pc) {
Operand dst_op = liftoff::GetMemOp(this, dst, offset, offset_imm);
if (protected_store_pc) *protected_store_pc = pc_offset();
MachineRepresentation rep = type.mem_rep();
if (rep == MachineRepresentation::kWord8) {
Pextrb(dst_op, src.fp(), lane);
} else if (rep == MachineRepresentation::kWord16) {
Pextrw(dst_op, src.fp(), lane);
} else if (rep == MachineRepresentation::kWord32) {
S128Store32Lane(dst_op, src.fp(), lane);
} else {
DCHECK_EQ(MachineRepresentation::kWord64, rep);
S128Store64Lane(dst_op, src.fp(), lane);
}
}
void LiftoffAssembler::emit_i8x16_shuffle(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs,
......
......@@ -4300,10 +4300,6 @@ template <typename T>
void RunStoreLaneTest(TestExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode store_op, WasmOpcode splat_op) {
FLAG_SCOPE(wasm_simd_post_mvp);
if (execution_tier == TestExecutionTier::kLiftoff) {
// Not yet implemented.
return;
}
constexpr int lanes = kSimd128Size / sizeof(T);
constexpr int mem_index = 16; // Store to mem index 16 (bytes).
......
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