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

PPC: fix scratch register usage during V128 push and pop

This CL fixes macro-asm to take in scratch registers as arguments.

Change-Id: Ib6070c9a9df050ce201d36027a0be44c77a54ba3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3773875
Commit-Queue: Milad Farazmand <mfarazma@redhat.com>
Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/main@{#81832}
parent 983f0c1c
......@@ -2938,7 +2938,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
simd_regs.Count());
__ MultiPush(gp_regs);
__ MultiPushF64AndV128(fp_regs, simd_regs);
__ MultiPushF64AndV128(fp_regs, simd_regs, ip, r0);
// Push the Wasm instance as an explicit argument to the runtime function.
__ Push(kWasmInstanceRegister);
......@@ -2954,7 +2954,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
__ mr(r11, kReturnRegister0);
// Restore registers.
__ MultiPopF64AndV128(fp_regs, simd_regs);
__ MultiPopF64AndV128(fp_regs, simd_regs, ip, r0);
__ MultiPop(gp_regs);
// After the instance register has been restored, we can add the jump table
......@@ -2980,7 +2980,8 @@ void Builtins::Generate_WasmDebugBreak(MacroAssembler* masm) {
// them after the runtime call.
__ MultiPush(WasmDebugBreakFrameConstants::kPushedGpRegs);
__ MultiPushF64AndV128(WasmDebugBreakFrameConstants::kPushedFpRegs,
WasmDebugBreakFrameConstants::kPushedSimd128Regs);
WasmDebugBreakFrameConstants::kPushedSimd128Regs, ip,
r0);
// Initialize the JavaScript context with 0. CEntry will use it to
// set the current context on the isolate.
......@@ -2989,7 +2990,8 @@ void Builtins::Generate_WasmDebugBreak(MacroAssembler* masm) {
// Restore registers.
__ MultiPopF64AndV128(WasmDebugBreakFrameConstants::kPushedFpRegs,
WasmDebugBreakFrameConstants::kPushedSimd128Regs);
WasmDebugBreakFrameConstants::kPushedSimd128Regs, ip,
r0);
__ MultiPop(WasmDebugBreakFrameConstants::kPushedGpRegs);
}
__ Ret();
......
......@@ -70,7 +70,8 @@ int TurboAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
return bytes;
}
int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register scratch1,
Register scratch2, Register exclusion1,
Register exclusion2, Register exclusion3) {
int bytes = 0;
......@@ -80,18 +81,21 @@ int TurboAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
bytes += list.Count() * kSystemPointerSize;
if (fp_mode == SaveFPRegsMode::kSave) {
MultiPushF64AndV128(kCallerSavedDoubles, kCallerSavedSimd128s);
MultiPushF64AndV128(kCallerSavedDoubles, kCallerSavedSimd128s, scratch1,
scratch2);
bytes += kStackSavedSavedFPSizeInBytes;
}
return bytes;
}
int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
int TurboAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register scratch1,
Register scratch2, Register exclusion1,
Register exclusion2, Register exclusion3) {
int bytes = 0;
if (fp_mode == SaveFPRegsMode::kSave) {
MultiPopF64AndV128(kCallerSavedDoubles, kCallerSavedSimd128s);
MultiPopF64AndV128(kCallerSavedDoubles, kCallerSavedSimd128s, scratch1,
scratch2);
bytes += kStackSavedSavedFPSizeInBytes;
}
......@@ -440,7 +444,7 @@ void TurboAssembler::MultiPushDoubles(DoubleRegList dregs, Register location) {
}
}
void TurboAssembler::MultiPushV128(Simd128RegList simd_regs,
void TurboAssembler::MultiPushV128(Simd128RegList simd_regs, Register scratch,
Register location) {
int16_t num_to_push = simd_regs.Count();
int16_t stack_offset = num_to_push * kSimd128Size;
......@@ -450,7 +454,7 @@ void TurboAssembler::MultiPushV128(Simd128RegList simd_regs,
if ((simd_regs.bits() & (1 << i)) != 0) {
Simd128Register simd_reg = Simd128Register::from_code(i);
stack_offset -= kSimd128Size;
StoreSimd128(simd_reg, MemOperand(location, stack_offset), ip);
StoreSimd128(simd_reg, MemOperand(location, stack_offset), scratch);
}
}
}
......@@ -468,13 +472,14 @@ void TurboAssembler::MultiPopDoubles(DoubleRegList dregs, Register location) {
addi(location, location, Operand(stack_offset));
}
void TurboAssembler::MultiPopV128(Simd128RegList simd_regs, Register location) {
void TurboAssembler::MultiPopV128(Simd128RegList simd_regs, Register scratch,
Register location) {
int16_t stack_offset = 0;
for (int16_t i = 0; i < Simd128Register::kNumRegisters; i++) {
if ((simd_regs.bits() & (1 << i)) != 0) {
Simd128Register simd_reg = Simd128Register::from_code(i);
LoadSimd128(simd_reg, MemOperand(location, stack_offset), ip);
LoadSimd128(simd_reg, MemOperand(location, stack_offset), scratch);
stack_offset += kSimd128Size;
}
}
......@@ -483,6 +488,7 @@ void TurboAssembler::MultiPopV128(Simd128RegList simd_regs, Register location) {
void TurboAssembler::MultiPushF64AndV128(DoubleRegList dregs,
Simd128RegList simd_regs,
Register scratch1, Register scratch2,
Register location) {
MultiPushDoubles(dregs);
#if V8_ENABLE_WEBASSEMBLY
......@@ -494,11 +500,11 @@ void TurboAssembler::MultiPushF64AndV128(DoubleRegList dregs,
// 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.
Move(scratch1, ExternalReference::supports_wasm_simd_128_address());
LoadU8(scratch1, MemOperand(scratch1), scratch2);
cmpi(scratch1, Operand::Zero()); // If > 0 then simd is available.
ble(&push_empty_simd);
MultiPushV128(simd_regs);
MultiPushV128(simd_regs, scratch1);
b(&simd_pushed);
bind(&push_empty_simd);
// We still need to allocate empty space on the stack even if we
......@@ -508,7 +514,7 @@ void TurboAssembler::MultiPushF64AndV128(DoubleRegList dregs,
bind(&simd_pushed);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPushV128(simd_regs);
MultiPushV128(simd_regs, scratch1);
} else {
addi(sp, sp,
Operand(-static_cast<int8_t>(simd_regs.Count()) * kSimd128Size));
......@@ -519,17 +525,18 @@ void TurboAssembler::MultiPushF64AndV128(DoubleRegList dregs,
void TurboAssembler::MultiPopF64AndV128(DoubleRegList dregs,
Simd128RegList simd_regs,
Register scratch1, Register scratch2,
Register location) {
#if V8_ENABLE_WEBASSEMBLY
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.
Move(scratch1, ExternalReference::supports_wasm_simd_128_address());
LoadU8(scratch1, MemOperand(scratch1), scratch2);
cmpi(scratch1, Operand::Zero()); // If > 0 then simd is available.
ble(&pop_empty_simd);
MultiPopV128(simd_regs);
MultiPopV128(simd_regs, scratch1);
b(&simd_popped);
bind(&pop_empty_simd);
addi(sp, sp,
......@@ -537,7 +544,7 @@ void TurboAssembler::MultiPopF64AndV128(DoubleRegList dregs,
bind(&simd_popped);
} else {
if (CpuFeatures::SupportsWasmSimd128()) {
MultiPopV128(simd_regs);
MultiPopV128(simd_regs, scratch1);
} else {
addi(sp, sp,
Operand(static_cast<int8_t>(simd_regs.Count()) * kSimd128Size));
......
......@@ -559,12 +559,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void MultiPushDoubles(DoubleRegList dregs, Register location = sp);
void MultiPopDoubles(DoubleRegList dregs, Register location = sp);
void MultiPushV128(Simd128RegList dregs, Register location = sp);
void MultiPopV128(Simd128RegList dregs, Register location = sp);
void MultiPushV128(Simd128RegList dregs, Register scratch,
Register location = sp);
void MultiPopV128(Simd128RegList dregs, Register scratch,
Register location = sp);
void MultiPushF64AndV128(DoubleRegList dregs, Simd128RegList simd_regs,
Register scratch1, Register scratch2,
Register location = sp);
void MultiPopF64AndV128(DoubleRegList dregs, Simd128RegList simd_regs,
Register scratch1, Register scratch2,
Register location = sp);
// Calculate how much stack space (in bytes) are required to store caller
......@@ -576,12 +580,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Push caller saved registers on the stack, and return the number of bytes
// stack pointer is adjusted.
int PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
int PushCallerSaved(SaveFPRegsMode fp_mode, Register scratch1,
Register scratch2, Register exclusion1 = no_reg,
Register exclusion2 = no_reg,
Register exclusion3 = no_reg);
// Restore caller saved registers from the stack, and return the number of
// bytes stack pointer is adjusted.
int PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
int PopCallerSaved(SaveFPRegsMode fp_mode, Register scratch1,
Register scratch2, Register exclusion1 = no_reg,
Register exclusion2 = no_reg,
Register exclusion3 = no_reg);
......
......@@ -941,7 +941,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
DCHECK(fp_mode_ == SaveFPRegsMode::kIgnore ||
fp_mode_ == SaveFPRegsMode::kSave);
// kReturnRegister0 should have been saved before entering the stub.
int bytes = __ PushCallerSaved(fp_mode_, kReturnRegister0);
int bytes = __ PushCallerSaved(fp_mode_, ip, r0, kReturnRegister0);
DCHECK(IsAligned(bytes, kSystemPointerSize));
DCHECK_EQ(0, frame_access_state()->sp_delta());
frame_access_state()->IncreaseSPDelta(bytes / kSystemPointerSize);
......@@ -955,7 +955,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
DCHECK(fp_mode_ == SaveFPRegsMode::kIgnore ||
fp_mode_ == SaveFPRegsMode::kSave);
// Don't overwrite the returned value.
int bytes = __ PopCallerSaved(fp_mode_, kReturnRegister0);
int bytes = __ PopCallerSaved(fp_mode_, ip, r0, kReturnRegister0);
frame_access_state()->IncreaseSPDelta(-(bytes / kSystemPointerSize));
DCHECK_EQ(0, frame_access_state()->sp_delta());
DCHECK(caller_registers_saved_);
......
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