Index: src/arm/macro-assembler-arm.cc |
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc |
index 918907b862ac49f20663660a577e49ada1baae9e..a87008680fc4d43f8523ba91af04add07301779f 100644 |
--- a/src/arm/macro-assembler-arm.cc |
+++ b/src/arm/macro-assembler-arm.cc |
@@ -1890,6 +1890,96 @@ void MacroAssembler::CheckFastSmiOnlyElements(Register map, |
} |
+void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
+ Register key_reg, |
+ Register receiver_reg, |
+ Register elements_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Register scratch4, |
+ Label* fail) { |
+ Label smi_value, maybe_nan, have_double_value, is_nan, done; |
+ Register mantissa_reg = scratch2; |
+ Register exponent_reg = scratch3; |
+ |
+ // Handle smi values specially. |
+ JumpIfSmi(value_reg, &smi_value); |
+ |
+ // Ensure that the object is a heap number |
+ CheckMap(value_reg, |
+ scratch1, |
+ isolate()->factory()->heap_number_map(), |
+ 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)); |
+ uint32_t offset = FixedDoubleArray::kHeaderSize + 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(0)); |
+ 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); |
+ |
+ bind(&smi_value); |
+ add(scratch1, elements_reg, |
+ Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
+ add(scratch1, scratch1, |
+ Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); |
+ // scratch is now effective address of the double element |
Rico
2011/10/05 08:39:19
scratch1
|
+ |
+ FloatingPointHelper::Destination destination; |
+ if (CpuFeatures::IsSupported(VFP3)) { |
+ destination = FloatingPointHelper::kVFPRegisters; |
+ } else { |
+ destination = FloatingPointHelper::kCoreRegisters; |
+ } |
+ |
+ Register untagged_value = receiver_reg; |
+ SmiUntag(untagged_value, value_reg); |
+ FloatingPointHelper::ConvertIntToDouble(this, |
+ untagged_value, |
+ destination, |
+ d0, |
+ mantissa_reg, |
+ exponent_reg, |
+ scratch4, |
+ s2); |
+ if (destination == FloatingPointHelper::kVFPRegisters) { |
+ CpuFeatures::Scope scope(VFP3); |
+ vstr(d0, scratch1, 0); |
+ } else { |
+ str(mantissa_reg, MemOperand(scratch1, 0)); |
+ str(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); |
+ } |
+ bind(&done); |
+} |
+ |
+ |
void MacroAssembler::CheckMap(Register obj, |
Register scratch, |
Handle<Map> map, |