| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index ffa25eb60efc819ce6db15ff48530ed648a58858..6458099cc93f7ea048a67e51518d6e4dbddf3f6c 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -642,6 +642,8 @@ void MacroAssembler::PopSafepointRegisters() {
|
|
|
|
|
| void MacroAssembler::PushSafepointRegistersAndDoubles() {
|
| + // Number of d-regs not known at snapshot time.
|
| + ASSERT(!Serializer::enabled());
|
| PushSafepointRegisters();
|
| sub(sp, sp, Operand(DwVfpRegister::NumAllocatableRegisters() *
|
| kDoubleSize));
|
| @@ -652,6 +654,8 @@ void MacroAssembler::PushSafepointRegistersAndDoubles() {
|
|
|
|
|
| void MacroAssembler::PopSafepointRegistersAndDoubles() {
|
| + // Number of d-regs not known at snapshot time.
|
| + ASSERT(!Serializer::enabled());
|
| for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); i++) {
|
| vldr(DwVfpRegister::FromAllocationIndex(i), sp, i * kDoubleSize);
|
| }
|
| @@ -690,6 +694,8 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
|
|
|
|
|
| MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
|
| + // Number of d-regs not known at snapshot time.
|
| + ASSERT(!Serializer::enabled());
|
| // General purpose registers are pushed last on the stack.
|
| int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize;
|
| int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
|
| @@ -878,10 +884,15 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
|
|
|
| // Optionally save all double registers.
|
| if (save_doubles) {
|
| - DwVfpRegister first = d0;
|
| - DwVfpRegister last =
|
| - DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1);
|
| - vstm(db_w, sp, first, last);
|
| + // Check CPU flags for number of registers.
|
| + // 16 regs => Z==1, 32 regs => Z==0.
|
| + mov(ip, Operand(ExternalReference::cpu_features()));
|
| + ldr(ip, MemOperand(ip));
|
| + and_(ip, ip, Operand(1u << VFP32DREGS), SetCC);
|
| +
|
| + vstm(db_w, sp, d16, d31, ne);
|
| + sub(sp, sp, Operand(16 * kDoubleSize), LeaveCC, eq);
|
| + vstm(db_w, sp, d0, d15);
|
| // Note that d0 will be accessible at
|
| // fp - 2 * kPointerSize - DwVfpRegister::kNumRegisters * kDoubleSize,
|
| // since the sp slot and code slot were pushed after the fp.
|
| @@ -941,10 +952,16 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
|
| // Calculate the stack location of the saved doubles and restore them.
|
| const int offset = 2 * kPointerSize;
|
| sub(r3, fp, Operand(offset + DwVfpRegister::kNumRegisters * kDoubleSize));
|
| - DwVfpRegister first = d0;
|
| - DwVfpRegister last =
|
| - DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1);
|
| - vldm(ia, r3, first, last);
|
| +
|
| + // Check CPU flags for number of registers.
|
| + // 16 regs => Z==1, 32 regs => Z==0.
|
| + mov(ip, Operand(ExternalReference::cpu_features()));
|
| + ldr(ip, MemOperand(ip));
|
| + and_(ip, ip, Operand(1u << VFP32DREGS), SetCC);
|
| +
|
| + vldm(ia_w, r3, d0, d15);
|
| + vldm(ia_w, r3, d16, d31, ne);
|
| + add(r3, r3, Operand(16 * kDoubleSize), LeaveCC, eq);
|
| }
|
|
|
| // Clear top frame.
|
|
|