| Index: src/arm/macro-assembler-arm.cc
|
| diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
|
| index a3379d59f54297975a57ba03e7a93a009984d7a3..7df0c0a1ff0514457fb37754902cc6072f789503 100644
|
| --- a/src/arm/macro-assembler-arm.cc
|
| +++ b/src/arm/macro-assembler-arm.cc
|
| @@ -773,6 +773,23 @@ void MacroAssembler::Strd(Register src1, Register src2,
|
| }
|
|
|
|
|
| +void MacroAssembler::VFPEnsureFPSCRState(Register scratch) {
|
| + // If needed, restore wanted bits of FPSCR.
|
| + Label fpscr_done;
|
| + vmrs(scratch);
|
| + tst(scratch, Operand(kVFPDefaultNaNModeControlBit));
|
| + b(ne, &fpscr_done);
|
| + orr(scratch, scratch, Operand(kVFPDefaultNaNModeControlBit));
|
| + vmsr(scratch);
|
| + bind(&fpscr_done);
|
| +}
|
| +
|
| +void MacroAssembler::VFPCanonicalizeNaN(const DwVfpRegister value,
|
| + const Condition cond) {
|
| + vsub(value, value, kDoubleRegZero, cond);
|
| +}
|
| +
|
| +
|
| void MacroAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
|
| const DwVfpRegister src2,
|
| const Condition cond) {
|
| @@ -1983,7 +2000,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| Register scratch4,
|
| Label* fail,
|
| int elements_offset) {
|
| - Label smi_value, maybe_nan, have_double_value, is_nan, done;
|
| + Label smi_value, store;
|
| Register mantissa_reg = scratch2;
|
| Register exponent_reg = scratch3;
|
|
|
| @@ -1997,68 +2014,28 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| fail,
|
| DONT_DO_SMI_CHECK);
|
|
|
| - // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
|
| - // in the exponent.
|
| - mov(scratch1, Operand(kNaNOrInfinityLowerBoundUpper32));
|
| - ldr(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
|
| - cmp(exponent_reg, scratch1);
|
| - b(ge, &maybe_nan);
|
| -
|
| - ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
|
| -
|
| - bind(&have_double_value);
|
| - add(scratch1, elements_reg,
|
| - Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
|
| - str(mantissa_reg, FieldMemOperand(
|
| - scratch1, FixedDoubleArray::kHeaderSize - elements_offset));
|
| - uint32_t offset = FixedDoubleArray::kHeaderSize - elements_offset +
|
| - sizeof(kHoleNanLower32);
|
| - str(exponent_reg, FieldMemOperand(scratch1, offset));
|
| - jmp(&done);
|
| -
|
| - bind(&maybe_nan);
|
| - // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise
|
| - // it's an Infinity, and the non-NaN code path applies.
|
| - b(gt, &is_nan);
|
| - ldr(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
|
| - cmp(mantissa_reg, Operand::Zero());
|
| - b(eq, &have_double_value);
|
| - bind(&is_nan);
|
| - // Load canonical NaN for storing into the double array.
|
| - uint64_t nan_int64 = BitCast<uint64_t>(
|
| - FixedDoubleArray::canonical_not_the_hole_nan_as_double());
|
| - mov(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64)));
|
| - mov(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32)));
|
| - jmp(&have_double_value);
|
| + vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
|
| + // Force a canonical NaN.
|
| + if (emit_debug_code()) {
|
| + vmrs(ip);
|
| + tst(ip, Operand(kVFPDefaultNaNModeControlBit));
|
| + Assert(ne, "Default NaN mode not set");
|
| + }
|
| + VFPCanonicalizeNaN(d0);
|
| + b(&store);
|
|
|
| bind(&smi_value);
|
| + Register untagged_value = scratch1;
|
| + SmiUntag(untagged_value, value_reg);
|
| + FloatingPointHelper::ConvertIntToDouble(
|
| + this, untagged_value, FloatingPointHelper::kVFPRegisters, d0,
|
| + mantissa_reg, exponent_reg, scratch4, s2);
|
| +
|
| + bind(&store);
|
| add(scratch1, elements_reg,
|
| - Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag -
|
| - elements_offset));
|
| - add(scratch1, scratch1,
|
| Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
|
| - // scratch1 is now effective address of the double element
|
| -
|
| - FloatingPointHelper::Destination destination;
|
| - destination = FloatingPointHelper::kVFPRegisters;
|
| -
|
| - Register untagged_value = elements_reg;
|
| - SmiUntag(untagged_value, value_reg);
|
| - FloatingPointHelper::ConvertIntToDouble(this,
|
| - untagged_value,
|
| - destination,
|
| - d0,
|
| - mantissa_reg,
|
| - exponent_reg,
|
| - scratch4,
|
| - s2);
|
| - if (destination == FloatingPointHelper::kVFPRegisters) {
|
| - vstr(d0, scratch1, 0);
|
| - } else {
|
| - str(mantissa_reg, MemOperand(scratch1, 0));
|
| - str(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes));
|
| - }
|
| - bind(&done);
|
| + vstr(d0, FieldMemOperand(scratch1,
|
| + FixedDoubleArray::kHeaderSize - elements_offset));
|
| }
|
|
|
|
|
|
|