[wasm-simd][liftoff][arm] Prototype load lane
Prototype load lane instructions on ARM Liftoff. We had a helper function for load lane that was living in instruction-selector. Move it out to assembler-arm so we can reuse that in Liftoff. Bug: v8:10975 Change-Id: Ic6e15c23eb778fb94a882609be622d2ca1f61ddb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2614225 Commit-Queue: Zhi An Ng <zhin@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Cr-Commit-Position: refs/heads/master@{#72106}
This commit is contained in:
parent
ee3f5ba10b
commit
9db3cb75ba
@ -43,6 +43,7 @@
|
||||
#include "src/base/overflowing-math.h"
|
||||
#include "src/codegen/arm/assembler-arm-inl.h"
|
||||
#include "src/codegen/assembler-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/codegen/string-constants.h"
|
||||
#include "src/deoptimizer/deoptimizer.h"
|
||||
@ -5397,6 +5398,21 @@ Register UseScratchRegisterScope::Acquire() {
|
||||
return reg;
|
||||
}
|
||||
|
||||
LoadStoreLaneParams::LoadStoreLaneParams(MachineRepresentation rep,
|
||||
uint8_t laneidx) {
|
||||
if (rep == MachineRepresentation::kWord8) {
|
||||
*this = LoadStoreLaneParams(laneidx, Neon8, 8);
|
||||
} else if (rep == MachineRepresentation::kWord16) {
|
||||
*this = LoadStoreLaneParams(laneidx, Neon16, 4);
|
||||
} else if (rep == MachineRepresentation::kWord32) {
|
||||
*this = LoadStoreLaneParams(laneidx, Neon32, 2);
|
||||
} else if (rep == MachineRepresentation::kWord64) {
|
||||
*this = LoadStoreLaneParams(laneidx, Neon64, 1);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define V8_CODEGEN_ARM_ASSEMBLER_ARM_H_
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@ -48,6 +49,7 @@
|
||||
#include "src/codegen/arm/register-arm.h"
|
||||
#include "src/codegen/assembler.h"
|
||||
#include "src/codegen/constant-pool.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/numbers/double.h"
|
||||
#include "src/utils/boxed-float.h"
|
||||
|
||||
@ -1394,6 +1396,25 @@ class V8_EXPORT_PRIVATE V8_NODISCARD UseScratchRegisterScope {
|
||||
VfpRegList old_available_vfp_;
|
||||
};
|
||||
|
||||
// Helper struct for load lane and store lane to indicate which opcode to use
|
||||
// and what memory size to be encoded in the opcode, and the new lane index.
|
||||
class LoadStoreLaneParams {
|
||||
public:
|
||||
bool low_op;
|
||||
NeonSize sz;
|
||||
uint8_t laneidx;
|
||||
// The register mapping on ARM (1 Q to 2 D), means that loading/storing high
|
||||
// lanes of a Q register is equivalent to loading/storing the high D reg,
|
||||
// modulo number of lanes in a D reg. This constructor decides, based on the
|
||||
// laneidx and load/store size, whether the low or high D reg is accessed, and
|
||||
// what the new lane index is.
|
||||
LoadStoreLaneParams(MachineRepresentation rep, uint8_t laneidx);
|
||||
|
||||
private:
|
||||
LoadStoreLaneParams(uint8_t laneidx, NeonSize sz, int lanes)
|
||||
: low_op(laneidx < lanes), sz(sz), laneidx(laneidx % lanes) {}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -511,41 +511,9 @@ void InstructionSelector::VisitAbortCSAAssert(Node* node) {
|
||||
Emit(kArchAbortCSAAssert, g.NoOutput(), g.UseFixed(node->InputAt(0), r1));
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Helper struct for load lane and store lane to indicate which opcode to use
|
||||
// and what memory size to be encoded in the opcode, and the new lane index.
|
||||
struct LoadStoreLaneParams {
|
||||
bool low_op;
|
||||
NeonSize sz;
|
||||
uint8_t laneidx;
|
||||
LoadStoreLaneParams(uint8_t laneidx, NeonSize sz, int lanes)
|
||||
: low_op(laneidx < lanes), sz(sz), laneidx(laneidx % lanes) {}
|
||||
};
|
||||
|
||||
// The register mapping on ARM (1 Q to 2 D), means that loading/storing high
|
||||
// lanes of a Q register is equivalent to loading/storing the high D reg, modulo
|
||||
// number of lanes in a D reg. This function decides, based on the laneidx and
|
||||
// load/store size, whether the low or high D reg is accessed, and what the new
|
||||
// lane index is.
|
||||
LoadStoreLaneParams GetLoadStoreLaneParams(MachineRepresentation rep,
|
||||
uint8_t laneidx) {
|
||||
if (rep == MachineRepresentation::kWord8) {
|
||||
return LoadStoreLaneParams(laneidx, Neon8, 8);
|
||||
} else if (rep == MachineRepresentation::kWord16) {
|
||||
return LoadStoreLaneParams(laneidx, Neon16, 4);
|
||||
} else if (rep == MachineRepresentation::kWord32) {
|
||||
return LoadStoreLaneParams(laneidx, Neon32, 2);
|
||||
} else if (rep == MachineRepresentation::kWord64) {
|
||||
return LoadStoreLaneParams(laneidx, Neon64, 1);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InstructionSelector::VisitStoreLane(Node* node) {
|
||||
StoreLaneParameters params = StoreLaneParametersOf(node->op());
|
||||
LoadStoreLaneParams f = GetLoadStoreLaneParams(params.rep, params.laneidx);
|
||||
LoadStoreLaneParams f(params.rep, params.laneidx);
|
||||
InstructionCode opcode =
|
||||
f.low_op ? kArmS128StoreLaneLow : kArmS128StoreLaneHigh;
|
||||
opcode |= MiscField::encode(f.sz);
|
||||
@ -563,8 +531,7 @@ void InstructionSelector::VisitStoreLane(Node* node) {
|
||||
|
||||
void InstructionSelector::VisitLoadLane(Node* node) {
|
||||
LoadLaneParameters params = LoadLaneParametersOf(node->op());
|
||||
LoadStoreLaneParams f =
|
||||
GetLoadStoreLaneParams(params.rep.representation(), params.laneidx);
|
||||
LoadStoreLaneParams f(params.rep.representation(), params.laneidx);
|
||||
InstructionCode opcode =
|
||||
f.low_op ? kArmS128LoadLaneLow : kArmS128LoadLaneHigh;
|
||||
opcode |= MiscField::encode(f.sz);
|
||||
|
@ -2362,7 +2362,17 @@ void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
|
||||
Register addr, Register offset_reg,
|
||||
uintptr_t offset_imm, LoadType type,
|
||||
uint8_t laneidx, uint32_t* protected_load_pc) {
|
||||
bailout(kSimd, "loadlane");
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register actual_src_addr = liftoff::CalculateActualAddress(
|
||||
this, &temps, addr, offset_reg, offset_imm);
|
||||
TurboAssembler::Move(liftoff::GetSimd128Register(dst),
|
||||
liftoff::GetSimd128Register(src));
|
||||
*protected_load_pc = pc_offset();
|
||||
LoadStoreLaneParams load_params(type.mem_type().representation(), laneidx);
|
||||
NeonListOperand dst_op =
|
||||
NeonListOperand(load_params.low_op ? dst.low_fp() : dst.high_fp());
|
||||
TurboAssembler::LoadLane(load_params.sz, dst_op, load_params.laneidx,
|
||||
NeonMemOperand(actual_src_addr));
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i8x16_swizzle(LiftoffRegister dst,
|
||||
|
Loading…
Reference in New Issue
Block a user