| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index 249c22f77bf3176b3e23583f3c29f1c02c274681..48c26526c0b9659d2c63880bea1051bf264dceea 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -4344,6 +4344,125 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoFillElements(LFillElements* instr) {
|
| + Label end;
|
| + Register elements = ToRegister(instr->elements());
|
| + Register dst = scratch0();
|
| + ASSERT(instr->hydrogen()->to()->representation().IsInteger32());
|
| + ASSERT(instr->hydrogen()->from()->representation().IsInteger32());
|
| + int shift_size =
|
| + instr->value()->IsDoubleRegister() ? kDoubleSizeLog2 : kPointerSizeLog2;
|
| + // We will be able to skip the first test (which checks that we have at
|
| + // least one value to fill) if we know the number of values to copy.
|
| + bool skip_first_test = false;
|
| + Register remain;
|
| + if (instr->from()->IsConstantOperand()) {
|
| + int from = ToInteger32(LConstantOperand::cast(instr->from()));
|
| + int start_offset =
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag + (from << shift_size);
|
| + if (instr->to()->IsConstantOperand()) {
|
| + int to = ToInteger32(LConstantOperand::cast(instr->to()));
|
| + if (instr->scratch() == NULL) {
|
| + // Scratch is null, if to - from was small enough to unroll the loop.
|
| + int max = to - from;
|
| + if (instr->value()->IsDoubleRegister()) {
|
| + __ add(dst, elements, Operand(start_offset));
|
| + DoubleRegister value = ToDoubleRegister(instr->value());
|
| + for (int count = 0; count < max; count++) {
|
| + __ vstr(value, dst, count * kDoubleSize);
|
| + }
|
| + } else {
|
| + Register value = ToRegister(instr->value());
|
| + for (int count = 0; count < max; count++) {
|
| + __ str(value,
|
| + MemOperand(elements, start_offset + count * kPointerSize));
|
| + }
|
| + }
|
| + __ bind(&end);
|
| + return;
|
| + }
|
| + __ add(dst, elements, Operand(start_offset));
|
| + skip_first_test = true;
|
| + remain = ToRegister(instr->scratch());
|
| + __ mov(remain, Operand(to - from));
|
| + } else {
|
| + remain = ToRegister(instr->scratch());
|
| + Register to = ToRegister(instr->to());
|
| + if (from == 0) {
|
| + __ mov(remain, Operand(to), SetCC);
|
| + } else {
|
| + __ sub(remain, to, Operand(from), SetCC);
|
| + }
|
| + __ add(dst, elements, Operand(start_offset));
|
| + }
|
| + } else {
|
| + remain = ToRegister(instr->scratch());
|
| + Register from = ToRegister(instr->from());
|
| + if (instr->to()->IsConstantOperand()) {
|
| + int to = ToInteger32(LConstantOperand::cast(instr->to()));
|
| + __ rsb(remain, from, Operand(to), SetCC);
|
| + } else {
|
| + Register to = ToRegister(instr->to());
|
| + __ sub(remain, to, Operand(from), SetCC);
|
| + }
|
| + __ add(dst, elements,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + __ add(dst, dst, Operand(from, LSL, shift_size));
|
| + }
|
| + Label loop, done;
|
| + if (!skip_first_test) {
|
| + __ b(le, &done);
|
| + }
|
| + __ bind(&loop);
|
| + __ sub(remain, remain, Operand(1), SetCC);
|
| + if (instr->value()->IsDoubleRegister()) {
|
| + DoubleRegister value = ToDoubleRegister(instr->value());
|
| + __ vstr(value, dst, 0);
|
| + __ add(dst, dst, Operand(kDoubleSize));
|
| + } else {
|
| + Register value = ToRegister(instr->value());
|
| + __ str(value, MemOperand(dst, kPointerSize, PostIndex));
|
| + }
|
| + __ b(gt, &loop);
|
| + if (!skip_first_test) {
|
| + __ bind(&done);
|
| + }
|
| + __ bind(&end);
|
| +}
|
| +
|
| +
|
| +void LCodeGen::DoCopyElements(LCopyElements* instr) {
|
| + Label loop, done;
|
| + Register dst = ToRegister(instr->dst());
|
| + Register src = ToRegister(instr->src());
|
| + Register length = ToRegister(instr->length());
|
| + __ cmp(length, Operand::Zero());
|
| + __ add(src, src, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + __ add(dst, dst,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + __ b(eq, &done);
|
| + __ bind(&loop);
|
| + if (instr->hydrogen()->length()->representation().IsSmi()) {
|
| + __ sub(length, length, Operand(Smi::FromInt(1)), SetCC);
|
| + } else {
|
| + __ sub(length, length, Operand(1), SetCC);
|
| + }
|
| + if (IsFastSmiOrObjectElementsKind(instr->elements_kind())) {
|
| + Register value = scratch0();
|
| + __ ldr(value, MemOperand(src, kPointerSize, PostIndex));
|
| + __ str(value, MemOperand(dst, kPointerSize, PostIndex));
|
| + } else {
|
| + DoubleRegister value = double_scratch0();
|
| + __ vldr(value, src, 0);
|
| + __ vstr(value, dst, 0);
|
| + __ add(src, src, Operand(kDoubleSize));
|
| + __ add(dst, dst, Operand(kDoubleSize));
|
| + }
|
| + __ b(gt, &loop);
|
| + __ bind(&done);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
|
| // By cases: external, fast double
|
| if (instr->is_typed_elements()) {
|
|
|