// Single word VFP register.
struct SwVfpRegister {
+ static const int kSizeInBytes = 4;
bool is_valid() const { return 0 <= code_ && code_ < 32; }
bool is(SwVfpRegister reg) const { return code_ == reg.code_; }
int code() const {
static const int kNumReservedRegisters = 2;
static const int kMaxNumAllocatableRegisters = kMaxNumRegisters -
kNumReservedRegisters;
+ static const int kSizeInBytes = 8;
// Note: the number of registers can be different at snapshot and run-time.
// Any code included in the snapshot must be able to run both with 16 or 32
Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX)));
// Copy the JS object part.
- __ CopyFields(r0, r4, r3.bit(), JSObject::kHeaderSize / kPointerSize);
+ __ CopyFields(r0, r4, d0, s0, JSObject::kHeaderSize / kPointerSize);
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
// r0: Newly allocated regexp.
// r5: Materialized regexp.
// r2: temp.
- __ CopyFields(r0, r5, r2.bit(), size / kPointerSize);
+ __ CopyFields(r0, r5, d0, s0, size / kPointerSize);
context()->Plug(r0);
}
__ bind(&allocated);
// Copy the content into the newly allocated memory.
- // (Unroll copy loop once for better throughput).
- for (int i = 0; i < size - kPointerSize; i += 2 * kPointerSize) {
- __ ldr(r3, FieldMemOperand(r1, i));
- __ ldr(r2, FieldMemOperand(r1, i + kPointerSize));
- __ str(r3, FieldMemOperand(r0, i));
- __ str(r2, FieldMemOperand(r0, i + kPointerSize));
- }
- if ((size % (2 * kPointerSize)) != 0) {
- __ ldr(r3, FieldMemOperand(r1, size - kPointerSize));
- __ str(r3, FieldMemOperand(r0, size - kPointerSize));
- }
+ __ CopyFields(r0, r1, double_scratch0(), double_scratch0().low(),
+ size / kPointerSize);
}
// Copies a fixed number of fields of heap objects from src to dst.
void MacroAssembler::CopyFields(Register dst,
Register src,
- RegList temps,
+ DwVfpRegister double_scratch,
+ SwVfpRegister single_scratch,
int field_count) {
- // At least one bit set in the first 15 registers.
- ASSERT((temps & ((1 << 15) - 1)) != 0);
- ASSERT((temps & dst.bit()) == 0);
- ASSERT((temps & src.bit()) == 0);
- // Primitive implementation using only one temporary register.
-
- Register tmp = no_reg;
- // Find a temp register in temps list.
- for (int i = 0; i < 15; i++) {
- if ((temps & (1 << i)) != 0) {
- tmp.set_code(i);
- break;
- }
+ int double_count = field_count / (DwVfpRegister::kSizeInBytes / kPointerSize);
+ for (int i = 0; i < double_count; i++) {
+ vldr(double_scratch, FieldMemOperand(src, i * DwVfpRegister::kSizeInBytes));
+ vstr(double_scratch, FieldMemOperand(dst, i * DwVfpRegister::kSizeInBytes));
}
- ASSERT(!tmp.is(no_reg));
- for (int i = 0; i < field_count; i++) {
- ldr(tmp, FieldMemOperand(src, i * kPointerSize));
- str(tmp, FieldMemOperand(dst, i * kPointerSize));
+ STATIC_ASSERT(SwVfpRegister::kSizeInBytes == kPointerSize);
+ STATIC_ASSERT(2 * SwVfpRegister::kSizeInBytes == DwVfpRegister::kSizeInBytes);
+
+ int remain = field_count % (DwVfpRegister::kSizeInBytes / kPointerSize);
+ if (remain != 0) {
+ vldr(single_scratch,
+ FieldMemOperand(src, (field_count - 1) * kPointerSize));
+ vstr(single_scratch,
+ FieldMemOperand(dst, (field_count - 1) * kPointerSize));
}
}
Label* gc_required);
// Copies a fixed number of fields of heap objects from src to dst.
- void CopyFields(Register dst, Register src, RegList temps, int field_count);
+ void CopyFields(Register dst,
+ Register src,
+ DwVfpRegister double_scratch,
+ SwVfpRegister single_scratch,
+ int field_count);
// Copies a number of bytes from src to dst. All registers are clobbered. On
// exit src and dst will point to the place just after where the last byte was