From 1a2dd1771293c0c938c8ae9844cd4cfcb5fd4dc3 Mon Sep 17 00:00:00 2001 From: Ryan Macnak Date: Wed, 15 Jun 2022 20:16:58 +0000 Subject: [PATCH] [vm, compiler] XMM0 is not just a scratch register on IA32. In particular, it can be live across write-barrier calls. TEST=ci Change-Id: I9383cc775315d76d0dc0052fa8f91daa233cb413 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248681 Reviewed-by: Alexander Markov Commit-Queue: Ryan Macnak --- runtime/vm/compiler/assembler/assembler_ia32.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc index b5f2b997429..b94cc03efea 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.cc +++ b/runtime/vm/compiler/assembler/assembler_ia32.cc @@ -2462,10 +2462,6 @@ static const intptr_t kNumberOfVolatileCpuRegisters = 3; static const Register volatile_cpu_registers[kNumberOfVolatileCpuRegisters] = { EAX, ECX, EDX}; -// XMM0 is used only as a scratch register in the optimized code. No need to -// save it. -static const intptr_t kNumberOfVolatileXmmRegisters = kNumberOfXmmRegisters - 1; - void Assembler::CallRuntime(const RuntimeEntry& entry, intptr_t argument_count) { ASSERT(!entry.is_leaf()); @@ -2491,12 +2487,12 @@ LeafRuntimeScope::LeafRuntimeScope(Assembler* assembler, __ pushl(volatile_cpu_registers[i]); } - // Preserve all XMM registers except XMM0 - __ subl(ESP, Immediate((kNumberOfXmmRegisters - 1) * kFpuRegisterSize)); + // Preserve all XMM registers. + __ subl(ESP, Immediate(kNumberOfXmmRegisters * kFpuRegisterSize)); // Store XMM registers with the lowest register number at the lowest // address. intptr_t offset = 0; - for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { + for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { XmmRegister xmm_reg = static_cast(reg_idx); __ movups(Address(ESP, offset), xmm_reg); offset += kFpuRegisterSize; @@ -2526,13 +2522,13 @@ LeafRuntimeScope::~LeafRuntimeScope() { // We need to restore it before restoring registers. const intptr_t kPushedRegistersSize = kNumberOfVolatileCpuRegisters * target::kWordSize + - kNumberOfVolatileXmmRegisters * kFpuRegisterSize; + kNumberOfXmmRegisters * kFpuRegisterSize; __ leal(ESP, Address(EBP, -kPushedRegistersSize)); - // Restore all XMM registers except XMM0 + // Restore all XMM registers. // XMM registers have the lowest register number at the lowest address. intptr_t offset = 0; - for (intptr_t reg_idx = 1; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { + for (intptr_t reg_idx = 0; reg_idx < kNumberOfXmmRegisters; ++reg_idx) { XmmRegister xmm_reg = static_cast(reg_idx); __ movups(xmm_reg, Address(ESP, offset)); offset += kFpuRegisterSize;