Commit 5e9e9af8 authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

s390: [wasm-simd] Add support for Simd128 moves and swaps

Change-Id: Ib13c5cd2230d29321b9502e85f9ac035e2618250
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2078313Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#66486}
parent eb4baaaf
......@@ -3740,9 +3740,15 @@ void TurboAssembler::LoadFloat32ConvertToDouble(DoubleRegister dst,
ldebr(dst, dst);
}
void TurboAssembler::LoadSimd128(Simd128Register dst, const MemOperand& mem) {
DCHECK(is_uint12(mem.offset()));
vl(dst, mem, Condition(0));
void TurboAssembler::LoadSimd128(Simd128Register dst, const MemOperand& mem,
Register scratch) {
if (is_uint12(mem.offset())) {
vl(dst, mem, Condition(0));
} else {
DCHECK(is_int20(mem.offset()));
lay(scratch, mem);
vl(dst, MemOperand(scratch), Condition(0));
}
}
// Store Double Precision (64-bit) Floating Point number to memory
......@@ -3772,9 +3778,15 @@ void TurboAssembler::StoreDoubleAsFloat32(DoubleRegister src,
StoreFloat32(scratch, mem);
}
void TurboAssembler::StoreSimd128(Simd128Register src, const MemOperand& mem) {
DCHECK(is_uint12(mem.offset()));
vst(src, mem, Condition(0));
void TurboAssembler::StoreSimd128(Simd128Register src, const MemOperand& mem,
Register scratch) {
if (is_uint12(mem.offset())) {
vst(src, mem, Condition(0));
} else {
DCHECK(is_int20(mem.offset()));
lay(scratch, mem);
vst(src, MemOperand(scratch), Condition(0));
}
}
void TurboAssembler::AddFloat32(DoubleRegister dst, const MemOperand& opnd,
......@@ -4180,13 +4192,17 @@ void TurboAssembler::SwapFloat32(DoubleRegister src, MemOperand dst,
}
void TurboAssembler::SwapFloat32(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadFloat32(scratch_0, src);
LoadFloat32(scratch_1, dst);
StoreFloat32(scratch_0, dst);
StoreFloat32(scratch_1, src);
DoubleRegister scratch) {
// push d0, to be used as scratch
lay(sp, MemOperand(sp, -kDoubleSize));
StoreDouble(d0, MemOperand(sp));
LoadFloat32(scratch, src);
LoadFloat32(d0, dst);
StoreFloat32(scratch, dst);
StoreFloat32(d0, src);
// restore d0
LoadDouble(d0, MemOperand(sp));
lay(sp, MemOperand(sp, kDoubleSize));
}
void TurboAssembler::SwapDouble(DoubleRegister src, DoubleRegister dst,
......@@ -4207,13 +4223,17 @@ void TurboAssembler::SwapDouble(DoubleRegister src, MemOperand dst,
}
void TurboAssembler::SwapDouble(MemOperand src, MemOperand dst,
DoubleRegister scratch_0,
DoubleRegister scratch_1) {
DCHECK(!AreAliased(scratch_0, scratch_1));
LoadDouble(scratch_0, src);
LoadDouble(scratch_1, dst);
StoreDouble(scratch_0, dst);
StoreDouble(scratch_1, src);
DoubleRegister scratch) {
// push d0, to be used as scratch
lay(sp, MemOperand(sp, -kDoubleSize));
StoreDouble(d0, MemOperand(sp));
LoadDouble(scratch, src);
LoadDouble(d0, dst);
StoreDouble(scratch, dst);
StoreDouble(d0, src);
// restore d0
LoadDouble(d0, MemOperand(sp));
lay(sp, MemOperand(sp, kDoubleSize));
}
void TurboAssembler::SwapSimd128(Simd128Register src, Simd128Register dst,
......@@ -4228,17 +4248,22 @@ void TurboAssembler::SwapSimd128(Simd128Register src, MemOperand dst,
Simd128Register scratch) {
DCHECK(!AreAliased(src, scratch));
vlr(scratch, src, Condition(0), Condition(0), Condition(0));
LoadSimd128(src, dst);
StoreSimd128(scratch, dst);
LoadSimd128(src, dst, ip);
StoreSimd128(scratch, dst, ip);
}
void TurboAssembler::SwapSimd128(MemOperand src, MemOperand dst,
Simd128Register scratch_0,
Simd128Register scratch_1) {
LoadSimd128(scratch_0, src);
LoadSimd128(scratch_1, dst);
StoreSimd128(scratch_0, dst);
StoreSimd128(scratch_1, src);
Simd128Register scratch) {
// push d0, to be used as scratch
lay(sp, MemOperand(sp, -kSimd128Size));
StoreSimd128(d0, MemOperand(sp), ip);
LoadSimd128(scratch, src, ip);
LoadSimd128(d0, dst, ip);
StoreSimd128(scratch, dst, ip);
StoreSimd128(d0, src, ip);
// restore d0
LoadSimd128(d0, MemOperand(sp), ip);
lay(sp, MemOperand(sp, kSimd128Size));
}
void TurboAssembler::ResetSpeculationPoisonRegister() {
......
......@@ -417,7 +417,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void LoadDouble(DoubleRegister dst, const MemOperand& opnd);
void LoadFloat32(DoubleRegister dst, const MemOperand& opnd);
void LoadFloat32ConvertToDouble(DoubleRegister dst, const MemOperand& mem);
void LoadSimd128(Simd128Register dst, const MemOperand& mem);
void LoadSimd128(Simd128Register dst, const MemOperand& mem,
Register scratch);
void AddFloat32(DoubleRegister dst, const MemOperand& opnd,
DoubleRegister scratch);
......@@ -449,7 +450,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void StoreFloat32(DoubleRegister dst, const MemOperand& opnd);
void StoreDoubleAsFloat32(DoubleRegister src, const MemOperand& mem,
DoubleRegister scratch);
void StoreSimd128(Simd128Register src, const MemOperand& mem);
void StoreSimd128(Simd128Register src, const MemOperand& mem,
Register scratch);
void Branch(Condition c, const Operand& opnd);
void BranchOnCount(Register r1, Label* l);
......@@ -782,19 +784,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SwapFloat32(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapFloat32(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapFloat32(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
void SwapFloat32(MemOperand src, MemOperand dst, DoubleRegister scratch);
void SwapDouble(DoubleRegister src, DoubleRegister dst,
DoubleRegister scratch);
void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
DoubleRegister scratch_1);
void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch);
void SwapSimd128(Simd128Register src, Simd128Register dst,
Simd128Register scratch);
void SwapSimd128(Simd128Register src, MemOperand dst,
Simd128Register scratch);
void SwapSimd128(MemOperand src, MemOperand dst, Simd128Register scratch_0,
Simd128Register scratch_1);
void SwapSimd128(MemOperand src, MemOperand dst, Simd128Register scratch);
// Cleanse pointer address on 31bit by zero out top bit.
// This is a NOP on 64-bit.
......
......@@ -2246,16 +2246,28 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kS390_Push:
if (instr->InputAt(0)->IsFPRegister()) {
LocationOperand* op = LocationOperand::cast(instr->InputAt(0));
if (op->representation() == MachineRepresentation::kFloat64) {
__ lay(sp, MemOperand(sp, -kDoubleSize));
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(kDoubleSize /
kSystemPointerSize);
} else {
DCHECK_EQ(MachineRepresentation::kFloat32, op->representation());
__ lay(sp, MemOperand(sp, -kSystemPointerSize));
__ StoreFloat32(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(1);
switch (op->representation()) {
case MachineRepresentation::kFloat32:
__ lay(sp, MemOperand(sp, -kSystemPointerSize));
__ StoreFloat32(i.InputDoubleRegister(0), MemOperand(sp));
break;
case MachineRepresentation::kFloat64:
__ lay(sp, MemOperand(sp, -kDoubleSize));
__ StoreDouble(i.InputDoubleRegister(0), MemOperand(sp));
frame_access_state()->IncreaseSPDelta(kDoubleSize /
kSystemPointerSize);
break;
case MachineRepresentation::kSimd128: {
__ lay(sp, MemOperand(sp, -kSimd128Size));
__ StoreSimd128(i.InputDoubleRegister(0), MemOperand(sp),
kScratchReg);
frame_access_state()->IncreaseSPDelta(kSimd128Size /
kSystemPointerSize);
break;
}
default:
UNREACHABLE();
break;
}
} else {
__ Push(i.InputRegister(0));
......@@ -2285,10 +2297,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (op->representation() == MachineRepresentation::kFloat64) {
__ StoreDouble(i.InputDoubleRegister(0),
MemOperand(sp, slot * kSystemPointerSize));
} else {
DCHECK_EQ(MachineRepresentation::kFloat32, op->representation());
} else if (op->representation() == MachineRepresentation::kFloat32) {
__ StoreFloat32(i.InputDoubleRegister(0),
MemOperand(sp, slot * kSystemPointerSize));
} else {
DCHECK_EQ(MachineRepresentation::kSimd128, op->representation());
__ StoreSimd128(i.InputDoubleRegister(0),
MemOperand(sp, slot * kSystemPointerSize),
kScratchReg);
}
} else {
__ StoreP(i.InputRegister(0),
......@@ -4197,17 +4213,29 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
}
} else if (source->IsFPRegister()) {
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsFPRegister()) {
DoubleRegister dst = g.ToDoubleRegister(destination);
__ Move(dst, src);
MachineRepresentation rep = LocationOperand::cast(source)->representation();
if (rep == MachineRepresentation::kSimd128) {
if (destination->IsSimd128Register()) {
__ vlr(g.ToSimd128Register(destination), g.ToSimd128Register(source),
Condition(0), Condition(0), Condition(0));
} else {
DCHECK(destination->IsSimd128StackSlot());
__ StoreSimd128(g.ToSimd128Register(source),
g.ToMemOperand(destination), kScratchReg);
}
} else {
DCHECK(destination->IsFPStackSlot());
LocationOperand* op = LocationOperand::cast(source);
if (op->representation() == MachineRepresentation::kFloat64) {
__ StoreDouble(src, g.ToMemOperand(destination));
DoubleRegister src = g.ToDoubleRegister(source);
if (destination->IsFPRegister()) {
DoubleRegister dst = g.ToDoubleRegister(destination);
__ Move(dst, src);
} else {
__ StoreFloat32(src, g.ToMemOperand(destination));
DCHECK(destination->IsFPStackSlot());
LocationOperand* op = LocationOperand::cast(source);
if (op->representation() == MachineRepresentation::kFloat64) {
__ StoreDouble(src, g.ToMemOperand(destination));
} else {
__ StoreFloat32(src, g.ToMemOperand(destination));
}
}
}
} else if (source->IsFPStackSlot()) {
......@@ -4217,8 +4245,12 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
LocationOperand* op = LocationOperand::cast(source);
if (op->representation() == MachineRepresentation::kFloat64) {
__ LoadDouble(g.ToDoubleRegister(destination), src);
} else {
} else if (op->representation() == MachineRepresentation::kFloat32) {
__ LoadFloat32(g.ToDoubleRegister(destination), src);
} else {
DCHECK_EQ(MachineRepresentation::kSimd128, op->representation());
__ LoadSimd128(g.ToSimd128Register(destination), g.ToMemOperand(source),
kScratchReg);
}
} else {
LocationOperand* op = LocationOperand::cast(source);
......@@ -4226,9 +4258,14 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
if (op->representation() == MachineRepresentation::kFloat64) {
__ LoadDouble(temp, src);
__ StoreDouble(temp, g.ToMemOperand(destination));
} else {
} else if (op->representation() == MachineRepresentation::kFloat32) {
__ LoadFloat32(temp, src);
__ StoreFloat32(temp, g.ToMemOperand(destination));
} else {
DCHECK_EQ(MachineRepresentation::kSimd128, op->representation());
__ LoadSimd128(kScratchDoubleReg, g.ToMemOperand(source), kScratchReg);
__ StoreSimd128(kScratchDoubleReg, g.ToMemOperand(destination),
kScratchReg);
}
}
} else {
......@@ -4278,13 +4315,23 @@ void CodeGenerator::AssembleSwap(InstructionOperand* source,
} else if (source->IsFloatStackSlot()) {
DCHECK(destination->IsFloatStackSlot());
__ SwapFloat32(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
kScratchDoubleReg);
} else if (source->IsDoubleStackSlot()) {
DCHECK(destination->IsDoubleStackSlot());
__ SwapDouble(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg, d0);
kScratchDoubleReg);
} else if (source->IsSimd128Register()) {
UNREACHABLE();
Simd128Register src = g.ToSimd128Register(source);
if (destination->IsSimd128Register()) {
__ SwapSimd128(src, g.ToSimd128Register(destination), kScratchDoubleReg);
} else {
DCHECK(destination->IsSimd128StackSlot());
__ SwapSimd128(src, g.ToMemOperand(destination), kScratchDoubleReg);
}
} else if (source->IsSimd128StackSlot()) {
DCHECK(destination->IsSimd128StackSlot());
__ SwapSimd128(g.ToMemOperand(source), g.ToMemOperand(destination),
kScratchDoubleReg);
} else {
UNREACHABLE();
}
......
......@@ -2222,12 +2222,21 @@ void InstructionSelector::EmitPrepareArguments(
int num_slots = 0;
int slot = 0;
#define INPUT_SWITCH(param) \
switch (input.location.GetType().representation()) { \
case MachineRepresentation::kSimd128: \
param += kSimd128Size / kSystemPointerSize; \
break; \
case MachineRepresentation::kFloat64: \
param += kDoubleSize / kSystemPointerSize; \
break; \
default: \
param += 1; \
break; \
}
for (PushParameter input : *arguments) {
if (input.node == nullptr) continue;
num_slots += input.location.GetType().representation() ==
MachineRepresentation::kFloat64
? kDoubleSize / kSystemPointerSize
: 1;
INPUT_SWITCH(num_slots)
}
Emit(kS390_StackClaim, g.NoOutput(), g.TempImmediate(num_slots));
for (PushParameter input : *arguments) {
......@@ -2235,12 +2244,10 @@ void InstructionSelector::EmitPrepareArguments(
if (input.node) {
Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node),
g.TempImmediate(slot));
slot += input.location.GetType().representation() ==
MachineRepresentation::kFloat64
? (kDoubleSize / kSystemPointerSize)
: 1;
INPUT_SWITCH(slot)
}
}
#undef INPUT_SWITCH
DCHECK(num_slots == slot);
}
}
......
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