| Index: src/arm/code-stubs-arm.cc
|
| ===================================================================
|
| --- src/arm/code-stubs-arm.cc (revision 7683)
|
| +++ src/arm/code-stubs-arm.cc (working copy)
|
| @@ -364,136 +364,6 @@
|
| }
|
|
|
|
|
| -class FloatingPointHelper : public AllStatic {
|
| - public:
|
| -
|
| - enum Destination {
|
| - kVFPRegisters,
|
| - kCoreRegisters
|
| - };
|
| -
|
| -
|
| - // Loads smis from r0 and r1 (right and left in binary operations) into
|
| - // floating point registers. Depending on the destination the values ends up
|
| - // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
|
| - // floating point registers VFP3 must be supported. If core registers are
|
| - // requested when VFP3 is supported d6 and d7 will be scratched.
|
| - static void LoadSmis(MacroAssembler* masm,
|
| - Destination destination,
|
| - Register scratch1,
|
| - Register scratch2);
|
| -
|
| - // Loads objects from r0 and r1 (right and left in binary operations) into
|
| - // floating point registers. Depending on the destination the values ends up
|
| - // either d7 and d6 or in r2/r3 and r0/r1 respectively. If the destination is
|
| - // floating point registers VFP3 must be supported. If core registers are
|
| - // requested when VFP3 is supported d6 and d7 will still be scratched. If
|
| - // either r0 or r1 is not a number (not smi and not heap number object) the
|
| - // not_number label is jumped to with r0 and r1 intact.
|
| - static void LoadOperands(MacroAssembler* masm,
|
| - FloatingPointHelper::Destination destination,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Label* not_number);
|
| -
|
| - // Convert the smi or heap number in object to an int32 using the rules
|
| - // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
|
| - // and brought into the range -2^31 .. +2^31 - 1.
|
| - static void ConvertNumberToInt32(MacroAssembler* masm,
|
| - Register object,
|
| - Register dst,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| - DwVfpRegister double_scratch,
|
| - Label* not_int32);
|
| -
|
| - // Load the number from object into double_dst in the double format.
|
| - // Control will jump to not_int32 if the value cannot be exactly represented
|
| - // by a 32-bit integer.
|
| - // Floating point value in the 32-bit integer range that are not exact integer
|
| - // won't be loaded.
|
| - static void LoadNumberAsInt32Double(MacroAssembler* masm,
|
| - Register object,
|
| - Destination destination,
|
| - DwVfpRegister double_dst,
|
| - Register dst1,
|
| - Register dst2,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - SwVfpRegister single_scratch,
|
| - Label* not_int32);
|
| -
|
| - // Loads the number from object into dst as a 32-bit integer.
|
| - // Control will jump to not_int32 if the object cannot be exactly represented
|
| - // by a 32-bit integer.
|
| - // Floating point value in the 32-bit integer range that are not exact integer
|
| - // won't be converted.
|
| - // scratch3 is not used when VFP3 is supported.
|
| - static void LoadNumberAsInt32(MacroAssembler* masm,
|
| - Register object,
|
| - Register dst,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Register scratch3,
|
| - DwVfpRegister double_scratch,
|
| - Label* not_int32);
|
| -
|
| - // Generate non VFP3 code to check if a double can be exactly represented by a
|
| - // 32-bit integer. This does not check for 0 or -0, which need
|
| - // to be checked for separately.
|
| - // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
|
| - // through otherwise.
|
| - // src1 and src2 will be cloberred.
|
| - //
|
| - // Expected input:
|
| - // - src1: higher (exponent) part of the double value.
|
| - // - src2: lower (mantissa) part of the double value.
|
| - // Output status:
|
| - // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
|
| - // - src2: contains 1.
|
| - // - other registers are clobbered.
|
| - static void DoubleIs32BitInteger(MacroAssembler* masm,
|
| - Register src1,
|
| - Register src2,
|
| - Register dst,
|
| - Register scratch,
|
| - Label* not_int32);
|
| -
|
| - // Generates code to call a C function to do a double operation using core
|
| - // registers. (Used when VFP3 is not supported.)
|
| - // This code never falls through, but returns with a heap number containing
|
| - // the result in r0.
|
| - // Register heapnumber_result must be a heap number in which the
|
| - // result of the operation will be stored.
|
| - // Requires the following layout on entry:
|
| - // r0: Left value (least significant part of mantissa).
|
| - // r1: Left value (sign, exponent, top of mantissa).
|
| - // r2: Right value (least significant part of mantissa).
|
| - // r3: Right value (sign, exponent, top of mantissa).
|
| - static void CallCCodeForDoubleOperation(MacroAssembler* masm,
|
| - Token::Value op,
|
| - Register heap_number_result,
|
| - Register scratch);
|
| -
|
| - private:
|
| - static void LoadNumber(MacroAssembler* masm,
|
| - FloatingPointHelper::Destination destination,
|
| - Register object,
|
| - DwVfpRegister dst,
|
| - Register dst1,
|
| - Register dst2,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - Label* not_number);
|
| -};
|
| -
|
| -
|
| void FloatingPointHelper::LoadSmis(MacroAssembler* masm,
|
| FloatingPointHelper::Destination destination,
|
| Register scratch1,
|
| @@ -651,30 +521,21 @@
|
| }
|
|
|
|
|
| -void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
|
| - Register object,
|
| - Destination destination,
|
| - DwVfpRegister double_dst,
|
| - Register dst1,
|
| - Register dst2,
|
| - Register heap_number_map,
|
| - Register scratch1,
|
| - Register scratch2,
|
| - SwVfpRegister single_scratch,
|
| - Label* not_int32) {
|
| - ASSERT(!scratch1.is(object) && !scratch2.is(object));
|
| - ASSERT(!scratch1.is(scratch2));
|
| - ASSERT(!heap_number_map.is(object) &&
|
| - !heap_number_map.is(scratch1) &&
|
| - !heap_number_map.is(scratch2));
|
| +void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm,
|
| + Register int_scratch,
|
| + Destination destination,
|
| + DwVfpRegister double_dst,
|
| + Register dst1,
|
| + Register dst2,
|
| + Register scratch2,
|
| + SwVfpRegister single_scratch) {
|
| + ASSERT(!int_scratch.is(scratch2));
|
|
|
| - Label done, obj_is_not_smi;
|
| + Label done;
|
|
|
| - __ JumpIfNotSmi(object, &obj_is_not_smi);
|
| - __ SmiUntag(scratch1, object);
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ vmov(single_scratch, scratch1);
|
| + __ vmov(single_scratch, int_scratch);
|
| __ vcvt_f64_s32(double_dst, single_scratch);
|
| if (destination == kCoreRegisters) {
|
| __ vmov(dst1, dst2, double_dst);
|
| @@ -686,20 +547,20 @@
|
| // | s | exp | mantissa |
|
|
|
| // Check for zero.
|
| - __ cmp(scratch1, Operand(0));
|
| - __ mov(dst2, scratch1);
|
| - __ mov(dst1, scratch1);
|
| + __ cmp(int_scratch, Operand(0));
|
| + __ mov(dst2, int_scratch);
|
| + __ mov(dst1, int_scratch);
|
| __ b(eq, &done);
|
|
|
| // Preload the sign of the value.
|
| - __ and_(dst2, scratch1, Operand(HeapNumber::kSignMask), SetCC);
|
| + __ and_(dst2, int_scratch, Operand(HeapNumber::kSignMask), SetCC);
|
| // Get the absolute value of the object (as an unsigned integer).
|
| - __ rsb(scratch1, scratch1, Operand(0), SetCC, mi);
|
| + __ rsb(int_scratch, int_scratch, Operand(0), SetCC, mi);
|
|
|
| // Get mantisssa[51:20].
|
|
|
| // Get the position of the first set bit.
|
| - __ CountLeadingZeros(dst1, scratch1, scratch2);
|
| + __ CountLeadingZeros(dst1, int_scratch, scratch2);
|
| __ rsb(dst1, dst1, Operand(31));
|
|
|
| // Set the exponent.
|
| @@ -709,26 +570,52 @@
|
|
|
| // Clear the first non null bit.
|
| __ mov(scratch2, Operand(1));
|
| - __ bic(scratch1, scratch1, Operand(scratch2, LSL, dst1));
|
| + __ bic(int_scratch, int_scratch, Operand(scratch2, LSL, dst1));
|
|
|
| __ cmp(dst1, Operand(HeapNumber::kMantissaBitsInTopWord));
|
| // Get the number of bits to set in the lower part of the mantissa.
|
| __ sub(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord), SetCC);
|
| __ b(mi, &fewer_than_20_useful_bits);
|
| // Set the higher 20 bits of the mantissa.
|
| - __ orr(dst2, dst2, Operand(scratch1, LSR, scratch2));
|
| + __ orr(dst2, dst2, Operand(int_scratch, LSR, scratch2));
|
| __ rsb(scratch2, scratch2, Operand(32));
|
| - __ mov(dst1, Operand(scratch1, LSL, scratch2));
|
| + __ mov(dst1, Operand(int_scratch, LSL, scratch2));
|
| __ b(&done);
|
|
|
| __ bind(&fewer_than_20_useful_bits);
|
| __ rsb(scratch2, dst1, Operand(HeapNumber::kMantissaBitsInTopWord));
|
| - __ mov(scratch2, Operand(scratch1, LSL, scratch2));
|
| + __ mov(scratch2, Operand(int_scratch, LSL, scratch2));
|
| __ orr(dst2, dst2, scratch2);
|
| // Set dst1 to 0.
|
| __ mov(dst1, Operand(0));
|
| }
|
| + __ bind(&done);
|
| +}
|
|
|
| +
|
| +void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
|
| + Register object,
|
| + Destination destination,
|
| + DwVfpRegister double_dst,
|
| + Register dst1,
|
| + Register dst2,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + SwVfpRegister single_scratch,
|
| + Label* not_int32) {
|
| + ASSERT(!scratch1.is(object) && !scratch2.is(object));
|
| + ASSERT(!scratch1.is(scratch2));
|
| + ASSERT(!heap_number_map.is(object) &&
|
| + !heap_number_map.is(scratch1) &&
|
| + !heap_number_map.is(scratch2));
|
| +
|
| + Label done, obj_is_not_smi;
|
| +
|
| + __ JumpIfNotSmi(object, &obj_is_not_smi);
|
| + __ SmiUntag(scratch1, object);
|
| + ConvertIntToDouble(masm, scratch1, destination, double_dst, dst1, dst2,
|
| + scratch2, single_scratch);
|
| __ b(&done);
|
|
|
| __ bind(&obj_is_not_smi);
|
| @@ -2440,6 +2327,8 @@
|
| // Save the left value on the stack.
|
| __ Push(r5, r4);
|
|
|
| + Label pop_and_call_runtime;
|
| +
|
| // Allocate a heap number to store the result.
|
| heap_number_result = r5;
|
| GenerateHeapResultAllocation(masm,
|
| @@ -2447,7 +2336,7 @@
|
| heap_number_map,
|
| scratch1,
|
| scratch2,
|
| - &call_runtime);
|
| + &pop_and_call_runtime);
|
|
|
| // Load the left value from the value saved on the stack.
|
| __ Pop(r1, r0);
|
| @@ -2458,6 +2347,10 @@
|
| if (FLAG_debug_code) {
|
| __ stop("Unreachable code.");
|
| }
|
| +
|
| + __ bind(&pop_and_call_runtime);
|
| + __ Drop(2);
|
| + __ b(&call_runtime);
|
| }
|
|
|
| break;
|
|
|