| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index dc93aea3461da251a785470be020995d790024b0..e4a14af7e4556258ed847393dbaa0b8c1170a8cf 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -2433,6 +2433,48 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoLoadKeyedFastDoubleElement(
|
| + LLoadKeyedFastDoubleElement* instr) {
|
| + Register elements = ToRegister(instr->elements());
|
| + bool key_is_constant = instr->key()->IsConstantOperand();
|
| + Register key = no_reg;
|
| + DwVfpRegister result = ToDoubleRegister(instr->result());
|
| + Register scratch = scratch0();
|
| +
|
| + int shift_size =
|
| + ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
|
| + int constant_key = 0;
|
| + if (key_is_constant) {
|
| + constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| + if (constant_key & 0xF0000000) {
|
| + Abort("array index constant value too big.");
|
| + }
|
| + } else {
|
| + key = ToRegister(instr->key());
|
| + }
|
| +
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size) +
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag)
|
| + : Operand(key, LSL, shift_size);
|
| + __ add(elements, elements, operand);
|
| + if (!key_is_constant) {
|
| + __ add(elements, elements,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + }
|
| +
|
| + if (instr->hydrogen()->RequiresHoleCheck()) {
|
| + // TODO(danno): If no hole check is required, there is no need to allocate
|
| + // elements into a temporary register, instead scratch can be used.
|
| + __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
|
| + __ cmp(scratch, Operand(kHoleNanUpper32));
|
| + DeoptimizeIf(eq, instr->environment());
|
| + }
|
| +
|
| + __ vldr(result, elements, 0);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
| LLoadKeyedSpecializedArrayElement* instr) {
|
| Register external_pointer = ToRegister(instr->external_pointer());
|
| @@ -2453,9 +2495,10 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
| if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS ||
|
| elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - DwVfpRegister result(ToDoubleRegister(instr->result()));
|
| - Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
|
| - : Operand(key, LSL, shift_size));
|
| + DwVfpRegister result = ToDoubleRegister(instr->result());
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size))
|
| + : Operand(key, LSL, shift_size);
|
| __ add(scratch0(), external_pointer, operand);
|
| if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
|
| __ vldr(result.low(), scratch0(), 0);
|
| @@ -2464,7 +2507,7 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
|
| __ vldr(result, scratch0(), 0);
|
| }
|
| } else {
|
| - Register result(ToRegister(instr->result()));
|
| + Register result = ToRegister(instr->result());
|
| MemOperand mem_operand(key_is_constant
|
| ? MemOperand(external_pointer, constant_key * (1 << shift_size))
|
| : MemOperand(external_pointer, key, LSL, shift_size));
|
| @@ -3243,6 +3286,48 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoStoreKeyedFastDoubleElement(
|
| + LStoreKeyedFastDoubleElement* instr) {
|
| + DwVfpRegister value = ToDoubleRegister(instr->value());
|
| + Register elements = ToRegister(instr->elements());
|
| + Register key = no_reg;
|
| + Register scratch = scratch0();
|
| + bool key_is_constant = instr->key()->IsConstantOperand();
|
| + int constant_key = 0;
|
| + Label not_nan;
|
| +
|
| + // Calculate the effective address of the slot in the array to store the
|
| + // double value.
|
| + if (key_is_constant) {
|
| + constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| + if (constant_key & 0xF0000000) {
|
| + Abort("array index constant value too big.");
|
| + }
|
| + } else {
|
| + key = ToRegister(instr->key());
|
| + }
|
| + int shift_size = ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS);
|
| + Operand operand = key_is_constant
|
| + ? Operand(constant_key * (1 << shift_size) +
|
| + FixedDoubleArray::kHeaderSize - kHeapObjectTag)
|
| + : Operand(key, LSL, shift_size);
|
| + __ add(scratch, elements, operand);
|
| + if (!key_is_constant) {
|
| + __ add(scratch, scratch,
|
| + Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
|
| + }
|
| +
|
| + // Check for NaN. All NaNs must be canonicalized.
|
| + __ VFPCompareAndSetFlags(value, value);
|
| +
|
| + // Only load canonical NaN if the comparison above set the overflow.
|
| + __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs);
|
| +
|
| + __ bind(¬_nan);
|
| + __ vstr(value, scratch, 0);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoStoreKeyedSpecializedArrayElement(
|
| LStoreKeyedSpecializedArrayElement* instr) {
|
|
|
|
|