Chromium Code Reviews| Index: src/arm/macro-assembler-arm.cc |
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
| index dc1dc1da9b68de5ce5753500fe4155ca951a00fb..5a1ed55d80fd14f15b0059cfcae193415890dc20 100644 |
| --- a/src/arm/macro-assembler-arm.cc |
| +++ b/src/arm/macro-assembler-arm.cc |
| @@ -643,19 +643,19 @@ void MacroAssembler::PopSafepointRegisters() { |
| void MacroAssembler::PushSafepointRegistersAndDoubles() { |
| PushSafepointRegisters(); |
| - sub(sp, sp, Operand(DwVfpRegister::kNumAllocatableRegisters * |
| + sub(sp, sp, Operand(DwVfpRegister::NumAllocatableRegisters() * |
| kDoubleSize)); |
| - for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; i++) { |
| + for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); i++) { |
| vstr(DwVfpRegister::FromAllocationIndex(i), sp, i * kDoubleSize); |
| } |
| } |
| void MacroAssembler::PopSafepointRegistersAndDoubles() { |
| - for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; i++) { |
| + for (int i = 0; i < DwVfpRegister::NumAllocatableRegisters(); i++) { |
| vldr(DwVfpRegister::FromAllocationIndex(i), sp, i * kDoubleSize); |
| } |
| - add(sp, sp, Operand(DwVfpRegister::kNumAllocatableRegisters * |
| + add(sp, sp, Operand(DwVfpRegister::NumAllocatableRegisters() * |
| kDoubleSize)); |
| PopSafepointRegisters(); |
| } |
| @@ -691,7 +691,7 @@ MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { |
| MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { |
| // General purpose registers are pushed last on the stack. |
| - int doubles_size = DwVfpRegister::kNumAllocatableRegisters * kDoubleSize; |
| + int doubles_size = DwVfpRegister::NumAllocatableRegisters() * kDoubleSize; |
| int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; |
| return MemOperand(sp, doubles_size + register_offset); |
| } |
| @@ -822,15 +822,63 @@ void MacroAssembler::Vmov(const DwVfpRegister dst, |
| DoubleRepresentation value(imm); |
| // Handle special values first. |
| if (value.bits == zero.bits) { |
| - vmov(dst, kDoubleRegZero, cond); |
| + vmov(dst, DwVfpRegister::ZeroReg(), cond); |
| } else if (value.bits == minus_zero.bits) { |
| - vneg(dst, kDoubleRegZero, cond); |
| + vneg(dst, DwVfpRegister::ZeroReg(), cond); |
| } else { |
| vmov(dst, imm, scratch, cond); |
| } |
| } |
| +void MacroAssembler::Vldm(BlockAddrMode am, |
|
Rodolph Perfetta
2012/12/12 14:29:15
Do you intend to support all addressing modes for
hans
2012/12/12 17:58:47
Yes, that sounds like a good idea. Done.
|
| + Register base, |
| + const DwVfpRegister first, |
| + const DwVfpRegister last, |
| + Condition cond) { |
| + ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| + ASSERT_LE(first.code(), last.code()); |
| + ASSERT(am == ia_w); |
| + |
| + const int first_code = first.code(); |
|
Rodolph Perfetta
2012/12/12 14:29:15
const should start with a k
hans
2012/12/12 17:58:47
I think that's for compile-time constants only.
|
| + const int last_code = last.code(); |
| + const int count = last_code - first_code + 1; |
| + |
| + if (count <= 16) { |
| + vldm(am, base, first, last, cond); |
| + } else { |
| + // Since we are increasing the address, load the first registers first. |
| + ASSERT(first_code < 16 && last_code >= 16); |
| + vldm(am, base, first, d15, cond); |
| + vldm(am, base, d16, last, cond); |
| + } |
| +} |
| + |
| + |
| +void MacroAssembler::Vstm(BlockAddrMode am, |
| + Register base, |
| + const DwVfpRegister first, |
| + const DwVfpRegister last, |
| + Condition cond) { |
| + ASSERT(CpuFeatures::IsEnabled(VFP2)); |
| + ASSERT_LE(first.code(), last.code()); |
| + ASSERT(am == db_w); |
| + |
| + const int first_code = first.code(); |
|
Rodolph Perfetta
2012/12/12 14:29:15
const should start with a k.
hans
2012/12/12 17:58:47
Ditto.
|
| + const int last_code = last.code(); |
| + const int count = last_code - first_code + 1; |
| + |
| + if (count <= 16) { |
| + vstm(am, base, first, last, cond); |
| + } else { |
| + // Since we are decreasing the address, write the last registers first. |
| + ASSERT(first_code < 16 && last_code >= 16); |
| + vstm(am, base, d16, last, cond); |
| + vstm(am, base, first, d15, cond); |
| + } |
| +} |
| + |
| + |
| void MacroAssembler::EnterFrame(StackFrame::Type type) { |
| // r0-r3: preserved |
| stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); |
| @@ -880,10 +928,11 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
| if (save_doubles) { |
| DwVfpRegister first = d0; |
| DwVfpRegister last = |
| - DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1); |
| - vstm(db_w, sp, first, last); |
| + DwVfpRegister::from_code(DwVfpRegister::NumAvailableRegisters() - 1); |
| + Vstm(db_w, sp, first, last); |
| // Note that d0 will be accessible at |
| - // fp - 2 * kPointerSize - DwVfpRegister::kNumRegisters * kDoubleSize, |
| + // fp - 2 * kPointerSize - |
| + // DwVfpRegister::NumAvailableRegisters() * kDoubleSize, |
| // since the sp slot and code slot were pushed after the fp. |
| } |
| @@ -940,11 +989,12 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, |
| if (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)); |
| + sub(r3, fp, Operand(offset + DwVfpRegister::NumAvailableRegisters() * |
| + kDoubleSize)); |
| DwVfpRegister first = d0; |
| DwVfpRegister last = |
| - DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1); |
| - vldm(ia, r3, first, last); |
| + DwVfpRegister::from_code(DwVfpRegister::NumAvailableRegisters() - 1); |
| + Vldm(ia_w, r3, first, last); |
| } |
| // Clear top frame. |