[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:
parent
7ab3fff72f
commit
b76d561ebc
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user