Chromium Code Reviews| Index: src/arm/code-stubs-arm.cc |
| diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc |
| index bce0c518ab5c690baf1d11a3653b3abbd18eb073..1d429c8fc2650b82f8bc84c20119e416f88c2edb 100644 |
| --- a/src/arm/code-stubs-arm.cc |
| +++ b/src/arm/code-stubs-arm.cc |
| @@ -409,6 +409,7 @@ class FloatingPointHelper : public AllStatic { |
| Register heap_number_map, |
| Register scratch1, |
| Register scratch2, |
| + Register scratch3, |
| DwVfpRegister double_scratch, |
| Label* not_int32); |
| @@ -612,6 +613,7 @@ void FloatingPointHelper::LoadNumberAsInteger(MacroAssembler* masm, |
| Register heap_number_map, |
| Register scratch1, |
| Register scratch2, |
| + Register scratch3, |
| DwVfpRegister double_scratch, |
| Label* not_int32) { |
| if (FLAG_debug_code) { |
| @@ -619,14 +621,88 @@ void FloatingPointHelper::LoadNumberAsInteger(MacroAssembler* masm, |
| Heap::kHeapNumberMapRootIndex, |
| "HeapNumberMap register clobbered."); |
| } |
| - Label is_smi, done; |
| + Label is_smi; |
| + Label done; |
| + Label not_in_int32_range; |
| + |
| __ JumpIfSmi(object, &is_smi); |
| __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kMapOffset)); |
| __ cmp(scratch1, heap_number_map); |
| __ b(ne, not_int32); |
| __ ConvertToInt32( |
| - object, dst, scratch1, scratch2, double_scratch, not_int32); |
| + object, dst, scratch1, scratch2, double_scratch, ¬_in_int32_range); |
| __ jmp(&done); |
| + |
| + __ bind(¬_in_int32_range); |
| + if (CpuFeatures::IsSupported(VFP3)) { |
| + CpuFeatures::Scope scope(VFP3); |
|
Søren Thygesen Gjesse
2011/03/10 14:20:30
Should we not support non-vfp here? VFP instructio
Karl Klose
2011/03/11 09:27:39
Done, see comment below.
|
| + __ vldr(double_scratch, FieldMemOperand(object, HeapNumber::kValueOffset)); |
|
Rodolph Perfetta
2011/03/10 14:36:44
Use Ldrd, it will be faster (no transfer VFP-ARM)
Karl Klose
2011/03/11 09:27:39
I decided to use two ldr instructions to avoid put
|
| + __ vmov(scratch1, scratch2, double_scratch); |
| + |
| + // Register scratch1 contains mantissa word, scratch2 contains |
| + // sign, exponent and mantissa. |
|
Rodolph Perfetta
2011/03/10 14:36:44
the and and mov could be rewritten as a Ubfx
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ and_(dst, scratch2, Operand(HeapNumber::kExponentMask)); |
| + __ mov(dst, Operand(dst, LSR, HeapNumber::kExponentShift)); |
| + __ sub(dst, dst, Operand(1023)); |
|
Søren Thygesen Gjesse
2011/03/10 14:20:30
1023 -> HeapNumber::kExponentBias
Karl Klose
2011/03/11 09:27:39
Done.
|
| + |
| + Label normal_exponent; |
| + // Express exponent as delta to 31. |
| + // If the delta is larger than 53, all bits would be shifted |
| + // away, which means that we can return 0. |
| + __ sub(dst, dst, Operand(31)); |
|
Søren Thygesen Gjesse
2011/03/10 14:20:30
You could combine this sub with the one before sub
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ cmp(dst, Operand(53)); |
|
Søren Thygesen Gjesse
2011/03/10 14:20:30
We have HeapNumber::kMantissaBits which is 52.
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ b(&normal_exponent, lt); |
| + __ mov(dst, Operand(0)); |
| + __ jmp(&done); |
| + |
| + __ bind(&normal_exponent); |
| + const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1; |
| + // Calculate shift. |
| + __ add(scratch3, dst, Operand(kShiftBase)); |
| + |
| + // Put implicit 1 before the mantissa part in scratch2 and |
| + // shift the mantissa bits to the correct position. |
| + __ orr(scratch2, |
| + scratch2, |
| + Operand(1 << HeapNumber::kMantissaBitsInTopWord)); |
| + |
| + // Save sign. |
| + Register sign = dst; |
| + __ and_(sign, scratch2, Operand(HeapNumber::kSignMask)); |
| + |
| + // Shift mantisssa bits in high word. |
| + __ mov(scratch2, Operand(scratch2, LSL, scratch3)); |
| + |
| + // Replace the shifted bits with bits from the lower mantissa word. |
| + Label pos_shift, neg_shift; |
| + // scratch3 = 32 - scratch3. |
|
Rodolph Perfetta
2011/03/10 14:36:44
__ rsb(scratch3, scratch3, Operand(32), SetCC) can
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ mvn(scratch3, Operand(scratch3)); |
| + __ add(scratch3, scratch3, Operand(33)); |
| + __ cmp(scratch3, Operand(0)); |
| + __ b(&pos_shift, ge); |
| + |
| + // Negate scratch3. |
|
Rodolph Perfetta
2011/03/10 14:36:44
__ rsb(scratch3, scratch3, Operand(0)) will neaget
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ mvn(scratch3, Operand(scratch3)); |
| + __ add(scratch3, scratch3, Operand(1)); |
| + __ mov(scratch1, Operand(scratch1, LSL, scratch3)); |
| + __ jmp(&neg_shift); |
| + |
| + __ bind(&pos_shift); |
| + __ mov(scratch1, Operand(scratch1, LSR, scratch3)); |
| + |
| + __ bind(&neg_shift); |
|
Søren Thygesen Gjesse
2011/03/10 14:20:30
neg_shift -> shift_done?
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ orr(scratch2, scratch2, Operand(scratch1)); |
| + |
| + // Restore sign if necessary. |
|
Rodolph Perfetta
2011/03/10 14:36:44
__ cmp(sign, Operand(0));
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ tst(sign, sign); |
|
Rodolph Perfetta
2011/03/10 14:36:44
rsb again here.
Karl Klose
2011/03/11 09:27:39
Done.
|
| + __ mvn(scratch2, Operand(scratch2), LeaveCC, ne); |
| + __ add(scratch2, scratch2, Operand(1), LeaveCC, ne); |
| + __ mov(dst, scratch2); |
| + __ jmp(&done); |
| + } else { |
| + __ jmp(not_int32); |
| + } |
| + |
| __ bind(&is_smi); |
| __ SmiUntag(dst, object); |
| __ bind(&done); |
| @@ -3024,6 +3100,7 @@ void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, |
| Register right = r0; |
| Register scratch1 = r7; |
| Register scratch2 = r9; |
| + Register scratch3 = r4; |
| ASSERT(smi_operands || (not_numbers != NULL)); |
| if (smi_operands && FLAG_debug_code) { |
| @@ -3117,6 +3194,7 @@ void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, |
| heap_number_map, |
| scratch1, |
| scratch2, |
| + scratch3, |
| d0, |
| not_numbers); |
| FloatingPointHelper::LoadNumberAsInteger(masm, |
| @@ -3125,6 +3203,7 @@ void TypeRecordingBinaryOpStub::GenerateFPOperation(MacroAssembler* masm, |
| heap_number_map, |
| scratch1, |
| scratch2, |
| + scratch3, |
| d0, |
| not_numbers); |
| } |
| @@ -3572,13 +3651,10 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { |
| void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { |
| - Label not_numbers, call_runtime; |
| + Label call_runtime; |
| ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); |
| - GenerateFPOperation(masm, false, ¬_numbers, &call_runtime); |
| - |
| - __ bind(¬_numbers); |
| - GenerateTypeTransition(masm); |
| + GenerateFPOperation(masm, false, &call_runtime, &call_runtime); |
| __ bind(&call_runtime); |
| GenerateCallRuntime(masm); |