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

PPC/S390: Introduce MultiPush/Pop of doubles and/or Simd registers

When pushing/popping registers, we need a way in PPC and S390
to detect if Simd registers need to be pushed or not.

On PPC Simd registers are separate from FP registers, hence we
need to push them both. If Simd is not available then we push
an empty space in place of Simd registers.

On S390 the Simd and FP registers are shared. If Simd is available
then we only push them and not the FPs, else we push FP registers
as well as an empty space the size of FPs as the stack needs to look
like as if Simds were saved too.

We also need to check if we are generating builtins or
call is being made at runtime. We cannot use `SupportsWasmSimd128`
when generating builtin as `CpuFeatures` are turned off, so we need
to emit the `if/else` manually for checking the value of
`SupportsWasmSimd128`.


Change-Id: Id149c6578db9c2f92d903fd871d85c648d43ce70
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2958963Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#75188}
parent 2b0b06f3
......@@ -2445,27 +2445,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
NumRegs(simd_regs));
__ MultiPush(gp_regs);
__ MultiPushDoubles(fp_regs);
// V8 uses the same set of fp param registers as Simd param registers.
// As these registers are two different sets on ppc we must make
// sure to also save them when Simd is enabled.
// Check the comments under crrev.com/c/2645694 for more details.
Label push_empty_simd, simd_pushed;
__ Move(ip, ExternalReference::supports_wasm_simd_128_address());
__ LoadU8(ip, MemOperand(ip), r0);
__ cmpi(ip, Operand::Zero()); // If > 0 then simd is available.
__ ble(&push_empty_simd);
__ MultiPushV128(simd_regs);
__ b(&simd_pushed);
__ bind(&push_empty_simd);
// kFixedFrameSizeFromFp is hard coded to include space for Simd
// registers, so we still need to allocate space on the stack even if we
// are not pushing them.
__ addi(
sp, sp,
Operand(-static_cast<int8_t>(base::bits::CountPopulation(simd_regs)) *
kSimd128Size));
__ bind(&simd_pushed);
__ MultiPushF64AndV128(fp_regs, simd_regs);
// Pass instance and function index as explicit arguments to the runtime
// function.
......@@ -2478,20 +2458,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
__ mr(r11, kReturnRegister0);
// Restore registers.
Label pop_empty_simd, simd_popped;
__ Move(ip, ExternalReference::supports_wasm_simd_128_address());
__ LoadU8(ip, MemOperand(ip), r0);
__ cmpi(ip, Operand::Zero()); // If > 0 then simd is available.
__ ble(&pop_empty_simd);
__ MultiPopV128(simd_regs);
__ b(&simd_popped);
__ bind(&pop_empty_simd);
__ addi(
sp, sp,
Operand(static_cast<int8_t>(base::bits::CountPopulation(simd_regs)) *
kSimd128Size));
__ bind(&simd_popped);
__ MultiPopDoubles(fp_regs);
__ MultiPopF64AndV128(fp_regs, simd_regs);
__ MultiPop(gp_regs);
}
// Finally, jump to the entrypoint.
......
......@@ -2478,24 +2478,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
NumRegs(fp_regs));
__ MultiPush(gp_regs);
// Check if machine has simd enabled, if so push vector registers. If not
// then only push double registers.
Label push_doubles, simd_pushed;
__ Move(r1, ExternalReference::supports_wasm_simd_128_address());
__ LoadU8(r1, MemOperand(r1));
__ LoadAndTestP(r1, r1); // If > 0 then simd is available.
__ ble(&push_doubles, Label::kNear);
// Save vector registers, don't save double registers anymore.
__ MultiPushV128(fp_regs);
__ b(&simd_pushed);
__ bind(&push_doubles);
// Simd not supported, only save double registers.
__ MultiPushDoubles(fp_regs);
// kFixedFrameSizeFromFp is hard coded to include space for Simd
// registers, so we still need to allocate extra (unused) space on the stack
// as if they were saved.
__ lay(sp, MemOperand(sp, -(NumRegs(fp_regs) * kDoubleSize)));
__ bind(&simd_pushed);
__ MultiPushF64OrV128(fp_regs);
// Pass instance and function index as explicit arguments to the runtime
// function.
......@@ -2508,19 +2491,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
__ mov(ip, r2);
// Restore registers.
__ Move(r1, ExternalReference::supports_wasm_simd_128_address());
__ LoadU8(r1, MemOperand(r1));
Label pop_doubles, simd_popped;
__ LoadAndTestP(r1, r1); // If > 0 then simd is available.
__ ble(&pop_doubles, Label::kNear);
// Pop vector registers, don't pop double registers anymore.
__ MultiPopV128(fp_regs);
__ b(&simd_popped);
__ bind(&pop_doubles);
// Simd not supported, only pop double registers.
__ lay(sp, MemOperand(sp, NumRegs(fp_regs) * kDoubleSize));
__ MultiPopDoubles(fp_regs);
__ bind(&simd_popped);
__ MultiPopF64OrV128(fp_regs);
__ MultiPop(gp_regs);
}
// Finally, jump to the entrypoint.
......
......@@ -470,6 +470,66 @@ void TurboAssembler::MultiPopV128(RegList dregs, Register location) {
addi(location, location, Operand(stack_offset));
}
void TurboAssembler::MultiPushF64AndV128(RegList dregs, RegList simd_regs,
Register location) {
bool generating_bultins =
isolate() && isolate()->IsGeneratingEmbeddedBuiltins();
MultiPushDoubles(dregs);
if (generating_bultins) {
// V8 uses the same set of fp param registers as Simd param registers.
// As these registers are two different sets on ppc we must make
// sure to also save them when Simd is enabled.
// Check the comments under crrev.com/c/2645694 for more details.
Label push_empty_simd, simd_pushed;
Move(ip, ExternalReference::supports_wasm_simd_128_address());
LoadU8(ip, MemOperand(ip), r0);
cmpi(ip, Operand::Zero()); // If > 0 then simd is available.
ble(&push_empty_simd);
MultiPushV128(simd_regs);
b(&simd_pushed);
bind(&push_empty_simd);
// We still need to allocate empty space on the stack even if we
// are not pushing Simd registers (see kFixedFrameSizeFromFp).
addi(sp, sp,
Operand(-static_cast<int8_t>(NumRegs(simd_regs)) * kSimd128Size));
bind(&simd_pushed);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPushV128(simd_regs);
} else {
addi(sp, sp,
Operand(-static_cast<int8_t>(NumRegs(simd_regs)) * kSimd128Size));
}
}
}
void TurboAssembler::MultiPopF64AndV128(RegList dregs, RegList simd_regs,
Register location) {
bool generating_bultins =
isolate() && isolate()->IsGeneratingEmbeddedBuiltins();
if (generating_bultins) {
Label pop_empty_simd, simd_popped;
Move(ip, ExternalReference::supports_wasm_simd_128_address());
LoadU8(ip, MemOperand(ip), r0);
cmpi(ip, Operand::Zero()); // If > 0 then simd is available.
ble(&pop_empty_simd);
MultiPopV128(simd_regs);
b(&simd_popped);
bind(&pop_empty_simd);
addi(sp, sp,
Operand(static_cast<int8_t>(NumRegs(simd_regs)) * kSimd128Size));
bind(&simd_popped);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPopV128(simd_regs);
} else {
addi(sp, sp,
Operand(static_cast<int8_t>(NumRegs(simd_regs)) * kSimd128Size));
}
}
MultiPopDoubles(dregs);
}
void TurboAssembler::LoadRoot(Register destination, RootIndex index,
Condition cond) {
DCHECK(cond == al);
......
......@@ -271,6 +271,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void MultiPushV128(RegList dregs, Register location = sp);
void MultiPopV128(RegList dregs, Register location = sp);
void MultiPushF64AndV128(RegList dregs, RegList simd_regs,
Register location = sp);
void MultiPopF64AndV128(RegList dregs, RegList simd_regs,
Register location = sp);
// Calculate how much stack space (in bytes) are required to store caller
// registers excluding those specified in the arguments.
int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
......
......@@ -701,6 +701,60 @@ void TurboAssembler::MultiPopV128(RegList dregs, Register location) {
AddS64(location, location, Operand(stack_offset));
}
void TurboAssembler::MultiPushF64OrV128(RegList dregs, Register location) {
bool generating_bultins =
isolate() && isolate()->IsGeneratingEmbeddedBuiltins();
if (generating_bultins) {
Label push_doubles, simd_pushed;
Move(r1, ExternalReference::supports_wasm_simd_128_address());
LoadU8(r1, MemOperand(r1));
LoadAndTestP(r1, r1); // If > 0 then simd is available.
ble(&push_doubles, Label::kNear);
// Save vector registers, don't save double registers anymore.
MultiPushV128(dregs);
b(&simd_pushed);
bind(&push_doubles);
// Simd not supported, only save double registers.
MultiPushDoubles(dregs);
// We still need to allocate empty space on the stack as if
// Simd rgeisters were saved (see kFixedFrameSizeFromFp).
lay(sp, MemOperand(sp, -(NumRegs(dregs) * kDoubleSize)));
bind(&simd_pushed);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPushV128(dregs);
} else {
MultiPushDoubles(dregs);
lay(sp, MemOperand(sp, -(NumRegs(dregs) * kDoubleSize)));
}
}
}
void TurboAssembler::MultiPopF64OrV128(RegList dregs, Register location) {
bool generating_bultins =
isolate() && isolate()->IsGeneratingEmbeddedBuiltins();
if (generating_bultins) {
Label pop_doubles, simd_popped;
LoadAndTestP(r1, r1); // If > 0 then simd is available.
ble(&pop_doubles, Label::kNear);
// Pop vector registers, don't pop double registers anymore.
MultiPopV128(dregs);
b(&simd_popped);
bind(&pop_doubles);
// Simd not supported, only pop double registers.
lay(sp, MemOperand(sp, NumRegs(dregs) * kDoubleSize));
MultiPopDoubles(dregs);
bind(&simd_popped);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPopV128(dregs);
} else {
lay(sp, MemOperand(sp, NumRegs(dregs) * kDoubleSize));
MultiPopDoubles(dregs);
}
}
}
void TurboAssembler::LoadRoot(Register destination, RootIndex index,
Condition) {
LoadU64(destination,
......
......@@ -176,6 +176,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void MultiPushV128(RegList dregs, Register location = sp);
void MultiPopV128(RegList dregs, Register location = sp);
void MultiPushF64OrV128(RegList dregs, Register location = sp);
void MultiPopF64OrV128(RegList dregs, Register location = sp);
// Calculate how much stack space (in bytes) are required to store caller
// registers excluding those specified in the arguments.
int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
......
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