Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 7f6c60d2af60103b3fa0edf8e0a212ea5415bfb7..cfa00ca5c090c99cc1ea77714308576971cc96a4 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -642,19 +642,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(); |
} |
@@ -690,7 +690,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); |
} |
@@ -821,15 +821,62 @@ 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); |
} |
} |
+static int min(int a, int b) { |
+ return a < b ? a : b; |
+} |
+ |
+ |
+void MacroAssembler::Vldm(BlockAddrMode am, |
+ Register base, |
+ const DwVfpRegister first, |
+ const DwVfpRegister last, |
+ Condition cond) { |
+ ASSERT(CpuFeatures::IsEnabled(VFP2)); |
+ ASSERT_LE(first.code(), last.code()); |
+ ASSERT(am == da_w || am == ia_w || am == db_w || am == ib_w); |
+ |
+ int low_code = first.code(); |
+ int high_code; |
+ do { |
+ // Emit vldm for up to 16 register at a time. Writeback updates base. |
+ high_code = min(low_code + 16 - 1, last.code()); |
+ vldm(am, base, DwVfpRegister::from_code(low_code), |
+ DwVfpRegister::from_code(high_code), cond); |
+ low_code += 16; |
+ } while (high_code < last.code()); |
+} |
+ |
+ |
+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 == da_w || am == ia_w || am == db_w || am == ib_w); |
+ |
+ int low_code = first.code(); |
+ int high_code; |
+ do { |
+ // Emit vstm for up to 16 register at a time. Writeback updates base. |
+ high_code = min(low_code + 16 - 1, last.code()); |
+ vstm(am, base, DwVfpRegister::from_code(low_code), |
+ DwVfpRegister::from_code(high_code), cond); |
+ low_code += 16; |
+ } while (high_code < last.code()); |
+} |
+ |
+ |
void MacroAssembler::EnterFrame(StackFrame::Type type) { |
// r0-r3: preserved |
stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); |
@@ -879,10 +926,10 @@ 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. |
} |
@@ -939,11 +986,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. |