PPC: Push the full q register before lazy compile

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.

Port 3b302d5cfe

Original Commit Message:

    If a lazy compilation happens in between 2 Wasm calls, we need to save
    the full Q register, since we can have live v128 values.

R=zhin@chromium.org, joransiu@ca.ibm.com, junyan@redhat.com, midawson@redhat.com
BUG=
LOG=N

Change-Id: Icdd0a6d38225a866b61651ff406598c144c25ebf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2667952
Reviewed-by: Junliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#72492}
This commit is contained in:
Milad Fa 2021-02-02 13:33:44 -05:00 committed by Commit Bot
parent 2e9b0e90c2
commit d913f0461d
3 changed files with 44 additions and 0 deletions

View File

@ -2402,8 +2402,17 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
Register::ListOf(r3, r4, r5, r6, r7, r8, r9, r10);
constexpr RegList fp_regs =
DoubleRegister::ListOf(d1, d2, d3, d4, d5, d6, d7, d8);
constexpr RegList simd_regs =
Simd128Register::ListOf(v1, v2, v3, v4, v5, v6, v7, v8);
__ 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.
if (CpuFeatures::SupportsWasmSimd128()) {
__ MultiPushV128(simd_regs);
}
// Pass instance and function index as explicit arguments to the runtime
// function.
@ -2416,6 +2425,9 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
__ mr(r11, kReturnRegister0);
// Restore registers.
if (CpuFeatures::SupportsWasmSimd128()) {
__ MultiPopV128(simd_regs);
}
__ MultiPopDoubles(fp_regs);
__ MultiPop(gp_regs);
}

View File

@ -429,6 +429,21 @@ void TurboAssembler::MultiPushDoubles(RegList dregs, Register location) {
}
}
void TurboAssembler::MultiPushV128(RegList dregs, Register location) {
int16_t num_to_push = base::bits::CountPopulation(dregs);
int16_t stack_offset = num_to_push * kSimd128Size;
subi(location, location, Operand(stack_offset));
for (int16_t i = Simd128Register::kNumRegisters - 1; i >= 0; i--) {
if ((dregs & (1 << i)) != 0) {
Simd128Register dreg = Simd128Register::from_code(i);
stack_offset -= kSimd128Size;
li(ip, Operand(stack_offset));
StoreSimd128(dreg, MemOperand(location, ip), r0, kScratchSimd128Reg);
}
}
}
void TurboAssembler::MultiPopDoubles(RegList dregs, Register location) {
int16_t stack_offset = 0;
@ -442,6 +457,20 @@ void TurboAssembler::MultiPopDoubles(RegList dregs, Register location) {
addi(location, location, Operand(stack_offset));
}
void TurboAssembler::MultiPopV128(RegList dregs, Register location) {
int16_t stack_offset = 0;
for (int16_t i = 0; i < Simd128Register::kNumRegisters; i++) {
if ((dregs & (1 << i)) != 0) {
Simd128Register dreg = Simd128Register::from_code(i);
li(ip, Operand(stack_offset));
LoadSimd128(dreg, MemOperand(location, ip), r0, kScratchSimd128Reg);
stack_offset += kSimd128Size;
}
}
addi(location, location, Operand(stack_offset));
}
void TurboAssembler::LoadRoot(Register destination, RootIndex index,
Condition cond) {
DCHECK(cond == al);

View File

@ -298,6 +298,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void MultiPushDoubles(RegList dregs, Register location = sp);
void MultiPopDoubles(RegList dregs, Register location = sp);
void MultiPushV128(RegList dregs, Register location = sp);
void MultiPopV128(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,