| Index: src/arm64/lithium-codegen-arm64.cc
|
| diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
|
| index 29c13ac5833e2bf59dbb713c5f7f8529176b867d..74fa1a0779872919cd777803457fc992fa846e23 100644
|
| --- a/src/arm64/lithium-codegen-arm64.cc
|
| +++ b/src/arm64/lithium-codegen-arm64.cc
|
| @@ -5164,6 +5164,122 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoFillElements(LFillElements* instr) {
|
| + Register elements = ToRegister(instr->elements());
|
| + UseScratchRegisterScope temps(masm());
|
| + Register dst = temps.AcquireX();
|
| + CPURegister value;
|
| + if (instr->value()->IsDoubleRegister()) {
|
| + value = ToDoubleRegister(instr->value());
|
| + } else {
|
| + value = ToRegister(instr->value());
|
| + }
|
| + Register remain;
|
| + if (instr->from()->IsConstantOperand()) {
|
| + int64_t from = ToInteger32(LConstantOperand::cast(instr->from()));
|
| + int start_offset =
|
| + FixedDoubleArray::kHeaderSize -
|
| + kHeapObjectTag + (from << kPointerSizeLog2);
|
| + if (instr->to()->IsConstantOperand()) {
|
| + int64_t to = ToInteger32(LConstantOperand::cast(instr->to()));
|
| + int64_t fill_size = to - from;
|
| + ASSERT(fill_size >= 0);
|
| + __ Add(dst, elements, start_offset);
|
| + int even_fill_size = fill_size & ~1;
|
| + if (even_fill_size <= LFillElements::kMaxUnrolledSize) {
|
| + for (int count = 0; count < even_fill_size; count += 2) {
|
| + __ Stp(value, value, MemOperand(dst, count * kDoubleSize));
|
| + }
|
| + if ((fill_size & 1) != 0) {
|
| + __ Str(value, MemOperand(dst, (fill_size - 1) * kDoubleSize));
|
| + }
|
| + } else {
|
| + remain = temps.AcquireW();
|
| + __ Mov(remain, even_fill_size);
|
| + Label loop;
|
| + __ Bind(&loop);
|
| + __ Subs(remain, remain, 2);
|
| + __ Stp(value, value, MemOperand(dst, 2 * kRegisterSize, PostIndex));
|
| + __ B(ne, &loop);
|
| + if ((fill_size & 1) != 0) {
|
| + __ Str(value, MemOperand(dst));
|
| + }
|
| + }
|
| + return;
|
| + } else {
|
| + __ Add(dst, elements, start_offset);
|
| + remain = ToRegister(instr->to()).W();
|
| + ASSERT(instr->hydrogen()->to()->representation().IsInteger32());
|
| + if (from > 0) {
|
| + __ Sub(remain, remain, from);
|
| + }
|
| + }
|
| + } else {
|
| + remain = temps.AcquireW();
|
| + Register from = ToRegister(instr->from()).W();
|
| + ASSERT(instr->hydrogen()->from()->representation().IsInteger32());
|
| + if (instr->to()->IsConstantOperand()) {
|
| + int64_t to = ToInteger32(LConstantOperand::cast(instr->to()));
|
| + __ Mov(remain, to);
|
| + __ Sub(remain, remain, from);
|
| + } else {
|
| + Register to = ToRegister(instr->to()).W();
|
| + ASSERT(instr->hydrogen()->to()->representation().IsInteger32());
|
| + __ Sub(remain, to, from);
|
| + }
|
| + __ Add(dst, elements, FixedDoubleArray::kHeaderSize - kHeapObjectTag);
|
| + __ Add(dst, dst, Operand(from, SXTW, kPointerSizeLog2));
|
| + }
|
| +
|
| + Label even, loop, done;
|
| + __ Tbz(remain, 0, &even);
|
| + __ Sub(remain, remain, 1);
|
| + __ Str(value, MemOperand(dst, kRegisterSize, PostIndex));
|
| +
|
| + __ Bind(&even);
|
| + __ Cbz(remain, &done);
|
| +
|
| + __ Bind(&loop);
|
| + __ Subs(remain, remain, 2);
|
| + __ Stp(value, value, MemOperand(dst, 2 * kRegisterSize, PostIndex));
|
| + __ B(ne, &loop);
|
| + __ Bind(&done);
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoCopyElements(LCopyElements* instr) {
|
| + Label even, loop, done;
|
| + UseScratchRegisterScope temps(masm());
|
| + Register length = ToRegister(instr->length()).W();
|
| + ASSERT(instr->hydrogen()->length()->representation().IsInteger32());
|
| +
|
| + Register dst = temps.AcquireX();
|
| + Register src = temps.AcquireX();
|
| + __ Add(src, ToRegister(instr->src()),
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag);
|
| + __ Add(dst, ToRegister(instr->dst()),
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag);
|
| +
|
| + FPRegister value1 = double_scratch();
|
| + FPRegister value2 = temps.AcquireD();
|
| +
|
| + __ Tbz(length, 0, &even);
|
| + __ Sub(length, length, 1);
|
| + __ Ldr(value1, MemOperand(src, kRegisterSize, PostIndex));
|
| + __ Str(value1, MemOperand(dst, kRegisterSize, PostIndex));
|
| +
|
| + __ Bind(&even);
|
| + __ Cbz(length, &done);
|
| +
|
| + __ Bind(&loop);
|
| + __ Subs(length, length, 2);
|
| + __ Ldp(value1, value2, MemOperand(src, 2 * kRegisterSize, PostIndex));
|
| + __ Stp(value1, value2, MemOperand(dst, 2 * kRegisterSize, PostIndex));
|
| + __ B(ne, &loop);
|
| + __ Bind(&done);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
|
| Register ext_ptr = ToRegister(instr->elements());
|
| Register key = no_reg;
|
|
|