Commit 33d956e7 authored by Milad Fa's avatar Milad Fa Committed by V8 LUCI CQ

S390[liftoff]: Implement simd load and extend ops

Change-Id: I86f34d698bf34590359a980282fa60d6501a6da9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3469628Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#79157}
parent 1025bf26
...@@ -6054,16 +6054,16 @@ void TurboAssembler::I16x8Q15MulRSatS(Simd128Register dst, Simd128Register src1, ...@@ -6054,16 +6054,16 @@ void TurboAssembler::I16x8Q15MulRSatS(Simd128Register dst, Simd128Register src1,
V(16x8, vlbrrep, LoadU16LE, 1) \ V(16x8, vlbrrep, LoadU16LE, 1) \
V(8x16, vlrep, LoadU8, 0) V(8x16, vlrep, LoadU8, 0)
#define LOAD_SPLAT(name, vector_instr, scalar_instr, condition) \ #define LOAD_SPLAT(name, vector_instr, scalar_instr, condition) \
void TurboAssembler::LoadAndSplat##name##LE(Simd128Register dst, \ void TurboAssembler::LoadAndSplat##name##LE( \
const MemOperand& mem) { \ Simd128Register dst, const MemOperand& mem, Register scratch) { \
if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { \ if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { \
vector_instr(dst, mem, Condition(condition)); \ vector_instr(dst, mem, Condition(condition)); \
return; \ return; \
} \ } \
scalar_instr(r1, mem); \ scalar_instr(scratch, mem); \
vlvg(dst, r1, MemOperand(r0, 0), Condition(condition)); \ vlvg(dst, scratch, MemOperand(r0, 0), Condition(condition)); \
vrep(dst, dst, Operand(0), Condition(condition)); \ vrep(dst, dst, Operand(0), Condition(condition)); \
} }
LOAD_SPLAT_LIST(LOAD_SPLAT) LOAD_SPLAT_LIST(LOAD_SPLAT)
#undef LOAD_SPLAT #undef LOAD_SPLAT
...@@ -6077,40 +6077,41 @@ LOAD_SPLAT_LIST(LOAD_SPLAT) ...@@ -6077,40 +6077,41 @@ LOAD_SPLAT_LIST(LOAD_SPLAT)
V(8x8U, vuplh, 0) \ V(8x8U, vuplh, 0) \
V(8x8S, vuph, 0) V(8x8S, vuph, 0)
#define LOAD_EXTEND(name, unpack_instr, condition) \ #define LOAD_EXTEND(name, unpack_instr, condition) \
void TurboAssembler::LoadAndExtend##name##LE(Simd128Register dst, \ void TurboAssembler::LoadAndExtend##name##LE( \
const MemOperand& mem) { \ Simd128Register dst, const MemOperand& mem, Register scratch) { \
if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { \ if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { \
vlebrg(kScratchDoubleReg, mem, Condition(0)); \ vlebrg(dst, mem, Condition(0)); \
} else { \ } else { \
LoadU64LE(r1, mem); \ LoadU64LE(scratch, mem); \
vlvg(kScratchDoubleReg, r1, MemOperand(r0, 0), Condition(3)); \ vlvg(dst, scratch, MemOperand(r0, 0), Condition(3)); \
} \ } \
unpack_instr(dst, kScratchDoubleReg, Condition(0), Condition(0), \ unpack_instr(dst, dst, Condition(0), Condition(0), Condition(condition)); \
Condition(condition)); \
} }
LOAD_EXTEND_LIST(LOAD_EXTEND) LOAD_EXTEND_LIST(LOAD_EXTEND)
#undef LOAD_EXTEND #undef LOAD_EXTEND
#undef LOAD_EXTEND #undef LOAD_EXTEND
void TurboAssembler::LoadV32ZeroLE(Simd128Register dst, const MemOperand& mem) { void TurboAssembler::LoadV32ZeroLE(Simd128Register dst, const MemOperand& mem,
Register scratch) {
vx(dst, dst, dst, Condition(0), Condition(0), Condition(0)); vx(dst, dst, dst, Condition(0), Condition(0), Condition(0));
if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) {
vlebrf(dst, mem, Condition(3)); vlebrf(dst, mem, Condition(3));
return; return;
} }
LoadU32LE(r1, mem); LoadU32LE(scratch, mem);
vlvg(dst, r1, MemOperand(r0, 3), Condition(2)); vlvg(dst, scratch, MemOperand(r0, 3), Condition(2));
} }
void TurboAssembler::LoadV64ZeroLE(Simd128Register dst, const MemOperand& mem) { void TurboAssembler::LoadV64ZeroLE(Simd128Register dst, const MemOperand& mem,
Register scratch) {
vx(dst, dst, dst, Condition(0), Condition(0), Condition(0)); vx(dst, dst, dst, Condition(0), Condition(0), Condition(0));
if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) { if (CAN_LOAD_STORE_REVERSE && is_uint12(mem.offset())) {
vlebrg(dst, mem, Condition(1)); vlebrg(dst, mem, Condition(1));
return; return;
} }
LoadU64LE(r1, mem); LoadU64LE(scratch, mem);
vlvg(dst, r1, MemOperand(r0, 1), Condition(3)); vlvg(dst, scratch, MemOperand(r0, 1), Condition(3));
} }
#define LOAD_LANE_LIST(V) \ #define LOAD_LANE_LIST(V) \
......
...@@ -399,18 +399,30 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -399,18 +399,30 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void LoadF64LE(DoubleRegister dst, const MemOperand& opnd, Register scratch); void LoadF64LE(DoubleRegister dst, const MemOperand& opnd, Register scratch);
void LoadF32LE(DoubleRegister dst, const MemOperand& opnd, Register scratch); void LoadF32LE(DoubleRegister dst, const MemOperand& opnd, Register scratch);
// Vector LE Load and Transform instructions. // Vector LE Load and Transform instructions.
void LoadAndSplat64x2LE(Simd128Register dst, const MemOperand& mem); void LoadAndSplat64x2LE(Simd128Register dst, const MemOperand& mem,
void LoadAndSplat32x4LE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadAndSplat16x8LE(Simd128Register dst, const MemOperand& mem); void LoadAndSplat32x4LE(Simd128Register dst, const MemOperand& mem,
void LoadAndSplat8x16LE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadAndExtend8x8ULE(Simd128Register dst, const MemOperand& mem); void LoadAndSplat16x8LE(Simd128Register dst, const MemOperand& me,
void LoadAndExtend8x8SLE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadAndExtend16x4ULE(Simd128Register dst, const MemOperand& mem); void LoadAndSplat8x16LE(Simd128Register dst, const MemOperand& mem,
void LoadAndExtend16x4SLE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadAndExtend32x2ULE(Simd128Register dst, const MemOperand& mem); void LoadAndExtend8x8ULE(Simd128Register dst, const MemOperand& mem,
void LoadAndExtend32x2SLE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadV32ZeroLE(Simd128Register dst, const MemOperand& mem); void LoadAndExtend8x8SLE(Simd128Register dst, const MemOperand& mem,
void LoadV64ZeroLE(Simd128Register dst, const MemOperand& mem); Register scratch);
void LoadAndExtend16x4ULE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadAndExtend16x4SLE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadAndExtend32x2ULE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadAndExtend32x2SLE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadV32ZeroLE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadV64ZeroLE(Simd128Register dst, const MemOperand& mem,
Register scratch);
void LoadLane8LE(Simd128Register dst, const MemOperand& mem, int lane, void LoadLane8LE(Simd128Register dst, const MemOperand& mem, int lane,
Register scratch); Register scratch);
void LoadLane16LE(Simd128Register dst, const MemOperand& mem, int lane, void LoadLane16LE(Simd128Register dst, const MemOperand& mem, int lane,
......
...@@ -3022,7 +3022,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -3022,7 +3022,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingMode mode = kMode_None; \ AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode); \ MemOperand operand = i.MemoryOperand(&mode); \
Simd128Register dst = i.OutputSimd128Register(); \ Simd128Register dst = i.OutputSimd128Register(); \
__ LoadAndSplat##type##LE(dst, operand); __ LoadAndSplat##type##LE(dst, operand, kScratchReg);
case kS390_S128Load64Splat: { case kS390_S128Load64Splat: {
LOAD_SPLAT(64x2); LOAD_SPLAT(64x2);
break; break;
...@@ -3044,7 +3044,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -3044,7 +3044,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingMode mode = kMode_None; \ AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode); \ MemOperand operand = i.MemoryOperand(&mode); \
Simd128Register dst = i.OutputSimd128Register(); \ Simd128Register dst = i.OutputSimd128Register(); \
__ LoadAndExtend##type##LE(dst, operand); __ LoadAndExtend##type##LE(dst, operand, kScratchReg);
case kS390_S128Load32x2U: { case kS390_S128Load32x2U: {
LOAD_EXTEND(32x2U); LOAD_EXTEND(32x2U);
break; break;
...@@ -3074,7 +3074,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -3074,7 +3074,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingMode mode = kMode_None; \ AddressingMode mode = kMode_None; \
MemOperand operand = i.MemoryOperand(&mode); \ MemOperand operand = i.MemoryOperand(&mode); \
Simd128Register dst = i.OutputSimd128Register(); \ Simd128Register dst = i.OutputSimd128Register(); \
__ LoadV##type##ZeroLE(dst, operand); __ LoadV##type##ZeroLE(dst, operand, kScratchReg);
case kS390_S128Load32Zero: { case kS390_S128Load32Zero: {
LOAD_AND_ZERO(32); LOAD_AND_ZERO(32);
break; break;
......
...@@ -2572,7 +2572,51 @@ void LiftoffAssembler::LoadTransform(LiftoffRegister dst, Register src_addr, ...@@ -2572,7 +2572,51 @@ void LiftoffAssembler::LoadTransform(LiftoffRegister dst, Register src_addr,
LoadType type, LoadType type,
LoadTransformationKind transform, LoadTransformationKind transform,
uint32_t* protected_load_pc) { uint32_t* protected_load_pc) {
bailout(kSimd, "Load transform unimplemented"); if (!is_int20(offset_imm)) {
mov(ip, Operand(offset_imm));
if (offset_reg != no_reg) {
AddS64(ip, offset_reg);
}
offset_reg = ip;
offset_imm = 0;
}
MemOperand src_op =
MemOperand(src_addr, offset_reg == no_reg ? r0 : offset_reg, offset_imm);
*protected_load_pc = pc_offset();
MachineType memtype = type.mem_type();
if (transform == LoadTransformationKind::kExtend) {
if (memtype == MachineType::Int8()) {
LoadAndExtend8x8SLE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Uint8()) {
LoadAndExtend8x8ULE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Int16()) {
LoadAndExtend16x4SLE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Uint16()) {
LoadAndExtend16x4ULE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Int32()) {
LoadAndExtend32x2SLE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Uint32()) {
LoadAndExtend32x2ULE(dst.fp(), src_op, r1);
}
} else if (transform == LoadTransformationKind::kZeroExtend) {
if (memtype == MachineType::Int32()) {
LoadV32ZeroLE(dst.fp(), src_op, r1);
} else {
DCHECK_EQ(MachineType::Int64(), memtype);
LoadV64ZeroLE(dst.fp(), src_op, r1);
}
} else {
DCHECK_EQ(LoadTransformationKind::kSplat, transform);
if (memtype == MachineType::Int8()) {
LoadAndSplat8x16LE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Int16()) {
LoadAndSplat16x8LE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Int32()) {
LoadAndSplat32x4LE(dst.fp(), src_op, r1);
} else if (memtype == MachineType::Int64()) {
LoadAndSplat64x2LE(dst.fp(), src_op, r1);
}
}
} }
void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src, void LiftoffAssembler::LoadLane(LiftoffRegister dst, LiftoffRegister src,
......
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