[wasm-simd][liftoff] Push/pop SIMD registers

On most architectures, FP registers overlap with SIMD registers. A FP
register holding a double can later be used to hold a 128-bit SIMD
value. So, when pushing or popping used registers, we need to push the
full width of the SIMD register.

In ia32 and x64, we change the
instruction from movsd to movdqu, and increment the offset by
kSimd128Size.

For arm64, we change the size of register when building
the CPURegList.

For arm, no change is needed, due to the way FP registers are paired up
to form a single SIMD register (rather than overlap).

Note for ports: PushRegisters and PopRegisters needs to be modified
similarly for mips/mips64. ppc and s390 does not implement these
methods, no change needed.

Bug: v8:9909
Change-Id: If29f1b30d7eface305a0d07a4bc551c151a77a01
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1994383
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65710}
This commit is contained in:
Ng Zhi An 2020-01-10 13:31:53 -08:00 committed by Commit Bot
parent 7ab3fff72f
commit b76d561ebc
3 changed files with 13 additions and 13 deletions

View File

@ -76,7 +76,7 @@ inline CPURegList PadRegList(RegList list) {
inline CPURegList PadVRegList(RegList list) {
if ((base::bits::CountPopulation(list) & 1) != 0) list |= fp_scratch.bit();
return CPURegList(CPURegister::kVRegister, kDRegSizeInBits, list);
return CPURegList(CPURegister::kVRegister, kQRegSizeInBits, list);
}
inline CPURegister AcquireByType(UseScratchRegisterScope* temps,

View File

@ -1814,15 +1814,15 @@ void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
LiftoffRegList fp_regs = regs & kFpCacheRegList;
unsigned num_fp_regs = fp_regs.GetNumRegsSet();
if (num_fp_regs) {
AllocateStackSpace(num_fp_regs * kStackSlotSize);
AllocateStackSpace(num_fp_regs * kSimd128Size);
unsigned offset = 0;
while (!fp_regs.is_empty()) {
LiftoffRegister reg = fp_regs.GetFirstRegSet();
movsd(Operand(esp, offset), reg.fp());
Movdqu(Operand(esp, offset), reg.fp());
fp_regs.clear(reg);
offset += sizeof(double);
offset += kSimd128Size;
}
DCHECK_EQ(offset, num_fp_regs * sizeof(double));
DCHECK_EQ(offset, num_fp_regs * kSimd128Size);
}
}
@ -1831,9 +1831,9 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
unsigned fp_offset = 0;
while (!fp_regs.is_empty()) {
LiftoffRegister reg = fp_regs.GetFirstRegSet();
movsd(reg.fp(), Operand(esp, fp_offset));
Movdqu(reg.fp(), Operand(esp, fp_offset));
fp_regs.clear(reg);
fp_offset += sizeof(double);
fp_offset += kSimd128Size;
}
if (fp_offset) add(esp, Immediate(fp_offset));
LiftoffRegList gp_regs = regs & kGpCacheRegList;

View File

@ -1556,15 +1556,15 @@ void LiftoffAssembler::PushRegisters(LiftoffRegList regs) {
LiftoffRegList fp_regs = regs & kFpCacheRegList;
unsigned num_fp_regs = fp_regs.GetNumRegsSet();
if (num_fp_regs) {
AllocateStackSpace(num_fp_regs * kStackSlotSize);
AllocateStackSpace(num_fp_regs * kSimd128Size);
unsigned offset = 0;
while (!fp_regs.is_empty()) {
LiftoffRegister reg = fp_regs.GetFirstRegSet();
Movsd(Operand(rsp, offset), reg.fp());
Movdqu(Operand(rsp, offset), reg.fp());
fp_regs.clear(reg);
offset += sizeof(double);
offset += kSimd128Size;
}
DCHECK_EQ(offset, num_fp_regs * sizeof(double));
DCHECK_EQ(offset, num_fp_regs * kSimd128Size);
}
}
@ -1573,9 +1573,9 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
unsigned fp_offset = 0;
while (!fp_regs.is_empty()) {
LiftoffRegister reg = fp_regs.GetFirstRegSet();
Movsd(reg.fp(), Operand(rsp, fp_offset));
Movdqu(reg.fp(), Operand(rsp, fp_offset));
fp_regs.clear(reg);
fp_offset += sizeof(double);
fp_offset += kSimd128Size;
}
if (fp_offset) addq(rsp, Immediate(fp_offset));
LiftoffRegList gp_regs = regs & kGpCacheRegList;