| Index: runtime/vm/assembler_ia32.cc
|
| diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
|
| index 240c2cfc7d0cf2d8d44562b1a0ec59921f1007cc..956b07b8a35babcdc05db42f11e2069813e5d8d3 100644
|
| --- a/runtime/vm/assembler_ia32.cc
|
| +++ b/runtime/vm/assembler_ia32.cc
|
| @@ -1534,21 +1534,41 @@ void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
|
| }
|
|
|
|
|
| -// TODO(srdjan): Add XMM registers once they are used by the compiler.
|
| 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;
|
| +
|
| +
|
| +static const intptr_t kNumberOfVolatileRegisters =
|
| + kNumberOfVolatileCpuRegisters + kNumberOfVolatileXmmRegisters;
|
| +
|
| +
|
| void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
|
| enter(Immediate(0));
|
|
|
| - // Preserve volatile registers.
|
| + // Preserve volatile CPU registers.
|
| for (intptr_t i = 0; i < kNumberOfVolatileCpuRegisters; i++) {
|
| pushl(volatile_cpu_registers[i]);
|
| }
|
|
|
| + // Preserve all XMM registers except XMM0
|
| + subl(ESP, Immediate((kNumberOfXmmRegisters - 1) * kDoubleSize));
|
| + // 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) {
|
| + XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
|
| + movsd(Address(ESP, offset), xmm_reg);
|
| + offset += kDoubleSize;
|
| + }
|
| +
|
| ReserveAlignedFrameSpace(frame_space);
|
| }
|
|
|
| @@ -1557,9 +1577,19 @@ void Assembler::LeaveCallRuntimeFrame() {
|
| // ESP might have been modified to reserve space for arguments
|
| // and ensure proper alignment of the stack frame.
|
| // We need to restore it before restoring registers.
|
| - leal(ESP, Address(EBP, -kNumberOfVolatileCpuRegisters * kWordSize));
|
| + leal(ESP, Address(EBP, -kNumberOfVolatileRegisters * kWordSize));
|
| +
|
| + // Restore all XMM registers except XMM0
|
| + // 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) {
|
| + XmmRegister xmm_reg = static_cast<XmmRegister>(reg_idx);
|
| + movsd(xmm_reg, Address(ESP, offset));
|
| + offset += kDoubleSize;
|
| + }
|
| + addl(ESP, Immediate(offset));
|
|
|
| - // Restore volatile registers.
|
| + // Restore volatile CPU registers.
|
| for (intptr_t i = kNumberOfVolatileCpuRegisters - 1; i >= 0; i--) {
|
| popl(volatile_cpu_registers[i]);
|
| }
|
|
|